2016-11-30 52 views
7

我明白像Haskell這樣的純函數語言的吸引力,你可以跟蹤使用monad的磁盤I/O等副作用。什麼是副作用?爲什麼內存分配不是副作用?

爲什麼不是所有的系統調用都被認爲是副作用?例如,Haskell中的堆內存分配(這是自動的)不被跟蹤。堆棧分配可能是一個副作用,雖然我不確定它會有用。這些都會改變整個系統的狀態。

那麼,什麼是副作用,什麼不是什麼,繪製的線在哪裏?它只是在什麼是最「有用的」?還是有更多的理論基礎?

+6

我認爲最簡單的答案是,如果分配是一個副作用,很少有東西會是「純」的,這種概念的有用性會降低。純度沒有一個通用的嚴格定義。我可以想象一種語言將*分配視爲副作用並通過類型系統進行管理,這對於具有少量內存的系統(即嵌入式系統)可能非常有用,但我不知道任何這種語言目前。 –

+3

如果你想控制它發生的時間,內存分配是一個副作用。請參閱IORef/STRef/FunPtr包裝。只是如果它自動發生,那麼你可以相信你的編譯器是聰明的,所以Haskell不會強迫你擔心它。 –

+0

@AlexisKing作爲偶爾需要爲嵌入式系統編寫代碼的人,這將是一種非常有趣的語言,可以看到實現。我認爲它可以作爲Haskell中的DSL編寫,但作爲獨立語言編譯非常有效,它會很酷。 – bheklilr

回答

11

當推理這些事情時,它必須在理論層面和語言規範層面上,而不是在硬件上如何實際完成。

編程語言實際上並不是一個實際的實現,所以除非您想到內存分配和系統調用作爲語言的一部分的C og C++,這是由系統原語處理的更高級語言,它不是部分的語言。如果它不是語言的一部分,它不能成爲副作用。

現在一個實際的機器代碼永遠不會是純粹的,因爲傳遞參數和接收返回值的方式都是通過變異來存儲在寄存器或堆棧中。我們在所有現代編程中使用的大多數概念都被轉換爲算術,標誌,跳轉和內存訪問。除NOP外,每個CPU指令都會改變機器。一個只包含NOP的程序不是很有用。

+1

所有好的答案,我想我把Haskell的規範與它的實現混爲一談。謝謝。 現在我想知道是否有任何低級彙編/ C語言,它們指定分配等副作用語義。 – relevate

+2

CPU指令評估也有一個硬件實現,所以NOP可以(同樣沒有幫助)說變異指令指針寄存器。 –

+0

@thatotherguy是的,但除了NOP之外,除了程序計數器之外,其他的指令都會發生變化。 – Sylwester

7

堆棧分配和堆分配都不是你可以在Haskell中「做」或觀察到的事情。因此,不能算作副作用。從某種意義上說,加熱CPU也是一樣,這無疑是運行純Haskel代碼的可識別的物理效應。

Haskell在當代硬件和操作系統上的某些實現會在運行代碼的過程中分配堆棧/堆,但它不能從代碼中觀察到。

+0

「恰巧在當代硬件和操作系統上Haskell的某些實現將在運行你的代碼的過程中分配堆棧/堆」 - 以及如何! – jberryman

相關問題