2015-07-01 38 views
3

This是怎麼.empty方法聲明中scala.collection.mutable.Map對象斯卡拉11.5:可變的Collection.empty方法是否違反了Scala的零參數命名約定?

def empty[A, B]: Map[A, B] 

不應該在該方法具有空括號,這樣的嗎?

def empty[A, B](): Map[A, B] 

上Scala的naming conventions提示頁面,不用說了吧明確,即忽略上一個0元數法的括號是純粹的功能代碼的慣例,幷包括空括號意味着該方法具有副作用影響。 (我想我遇到了一個更加明確的錯誤消息。)

可變的.empty方法有副作用,因爲您可以將單獨調用的結果區分爲.empty。它不應該得到空的圓括號,即使它在immutable.Map的隊友不?

關於我自己的代碼,是否有一個特殊的命名約定,我應該遵循從0-arity方法創建和返回一個可變對象?

回答

6

No. scala.collection.mutable.Map.empty[A, B]沒有任何副作用。每次調用它時,它都會返回一個新的mutable.Map[A, B]

mutable.Map#empty(性狀本身的方法)也返回相同類型的新的空的mutable.Map。它不清空集合(就像它可能會出現的那樣),所以沒有副作用。如果您不確定,請參閱the source

+0

我的理解是,如果將第二次調用替換爲第一次調用結果的變量時,程序結果發生變化,則函數執行副作用。每次調用'.empty'時,必須有所不同,這是必要的,以便稍後可以修改一個空映射而不會影響另一個。還是我遵循一個非標準的「副作用」命名約定? :)我基本上從_ [Scala的函數式編程](http://www.manning.com/bjarnason/FPWS_CH01.pdf),_ p。 10. –

+4

@benkovitz我認爲你會混淆「無副作用」與「引用透明」? –

+0

@ChrisMartin謝謝!事實上,我沒有區分他們。我已經被功能編程倡導者反覆地責罵到,創建相同但不等於「.equal」的對象是一種副作用,我認爲這個想法是有價值的。事實上,對象身份有時會在我的Scala程序中弄髒決定論。有沒有一些約定創建對象,甚至不打算保持'.equal' [不計數](http://stackoverflow.com/questions/31151616/do-the-mutable-collection-empty-methods-violate-scalas -zero-argument-naming-con/31151649?noredirect = 1#comment50341805_31156148)作爲副作用? –

1

這對JVM來說都是一團糟。

在像EQ/NE和System.identityHashCode,甚至創造新的不變對象操作的存在具有可觀察到的副作用(即在JVM的腸子深增加一些計數器,以便在接下來的對象將有不同的引用hashCode)。因此,在JVM域中,除了返回一個新對象之外,什麼都不做的函數會被視爲副作用。如果返回的對象是可變的,則無論如何,引用透明度都會從窗口中消失,即使可變對象自身產生的函數被認爲是無副作用的。

如果你真的迂腐一下,有沒有無副作用的JVM返回非原語的功能。

scala> import scala.collection.immutable._ 
scala> SortedSet.empty[Int] eq SortedSet.empty[Int] 
res4: Boolean = false 
+0

事實上,我認爲真正的計算機中的任何東西都無法無副作用,因爲每個操作都需要時間,每個新創建的對象都會減少可用內存的數量等,甚至連Haskell都無法逃脫。我認爲Scala中有哪些副作用是「計數」的,哪個是「不計數」的。由於'.empty'創建的對象並不意味着保留'.equal',我猜想_that_會被視爲一種副作用。顯然不是? –

+0

我還沒有看到這明確闡述了任何地方,但我的解釋是,如果你有一個方法返回一個可變的對象,參考透明度明顯地出去了窗口。但是*創建可變對象的函數仍然被認爲是「無副作用」,因爲它不會做任何事情,而是產生返回值。 如果你想爭論純度,你絕對不應該考慮在JVM上的方法肯定是eq,ne,System.identityHashCode和所有其他低級方法。 –

相關問題