簡體   English   中英

Scala有多純粹和懶惰?

[英]How pure and lazy can Scala be?

這只是“我想知道......”問題中的一個。

Scala具有不可變數據結構和(可選)惰性值等。

Scala程序與完全純粹(在函數編程意義上)和完全懶惰(或Ingo指出,它是否足夠非嚴格)的程序有多接近? 哪些價值觀不可避免地變得多變,什么評價不可避免地貪婪?

關於延遲 - 當前,將參數傳遞給方法默認是嚴格的:

def square(a: Int) = a * a

但是你使用call-by-name參數:

def square(a: =>Int) = a * a

但這並不是懶惰的,因為它只在需要時計算一次值:

scala> square({println("calculating");5})
calculating
calculating
res0: Int = 25

添加惰性方法參數已有一些工作,但尚未集成(下面的聲明應僅從上面打印"calculating"一次):

def square(lazy a: Int) = a * a

這是一個缺少的部分,雖然你可以使用本地懶惰的val來模擬它:

def square(ap: =>Int) = {
  lazy val a = ap
  a * a
}

關於可變性 - 沒有什么能阻止你編寫不可變數據結構並避免變異。 您也可以在Java或C中執行此操作。 實際上, 一些不可變數據結構依賴於惰性原語來實現更好的復雜邊界,但是懶惰原語也可以用其他語言模擬 - 以額外的語法和樣板為代價。

您總是可以在Scala中編寫不可變數據結構,延遲計算和完全純粹的程序。 問題是Scala編程模型也允許編寫非純程序,因此類型檢查器不能總是推斷程序的某些屬性(例如純度),它可以推斷出編程模型更具限制性。

例如,在用純表達式語言a * a在呼叫按姓名定義上述( a: =>Int )可被優化,以評估a僅一次,而不管該呼叫按姓名語義。 如果語言允許副作用,那么這種優化並不總是適用。

Scala可以像你喜歡的那樣純粹和懶惰,但是a)編譯器不會讓你對純度保持誠實,b)它需要一些額外的工作來使它變得懶惰。 對此沒什么太深刻的了; 如果你真的想要,你甚至可以編寫懶惰和純Java代碼(如果你敢,請看這里 ;在Java中實現懶惰需要大量嵌套的匿名內部類)。

純度

Haskell通過類型系統跟蹤雜質,而Scala選擇不采用這種方式,當你從一開始就沒有把它作為一個目標時(以及與完全不純的語言的互操作性),很難解決這類問題。像Java 該語言的主要目標)。

也就是說, 有些人認為在Scala的類型系統中記錄效果是可能的,也是值得的。 但我認為Scala中的純度最好被視為自律問題,並且您必須對所謂的第三方代碼的純度持懷疑態度。

怠惰

Haskell在默認情況下是懶惰的,但是可以通過在代碼中添加一些注釋來更嚴格... Scala是相反的:默認情況下是嚴格的,但是使用lazy關鍵字和by-name參數可以使它變得懶惰。

隨意保持不變。 另一方面,沒有副作用跟蹤,因此您無法強制執行或驗證它。

至於非嚴格性,這是交易......首先,如果你選擇完全不嚴格,你將放棄所有Scala的課程。 即使Scalaz在很大程度上也不是非嚴格的。 如果你願意自己構建一切,你可以使你的方法不嚴格,你的價值觀也很懶惰。

接下來,我想知道隱式參數是否可以是非嚴格的,或者將它們設置為非嚴格的后果是什么。 我沒有看到問題,但我可能是錯的。

但是,最重要的是,函數參數是嚴格的,閉包參數也是如此。

因此,雖然理論上可以完全不嚴格,但這將是非常不方便的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM