2012-11-06 34 views
11

Trong Scala (2.9.2) Tôi cố gắng để tạo ra một chức năng cung cấp một số giá trị khác khi truy cậpScala bởi các thông số tên với nhiều danh sách đối số và tách lạng bộ

() => Any 

Tôi nghĩ rằng tôi đã làm thành công này thông qua một theo tên/giải pháp currying:

def byName(theValue : => Any)() : Any = theValue 
val myHolder = byName(myValue)_ 

Vì vậy, chủ sở hữu của tôi là đúng loại. Tuy nhiên tôi thấy rằng trong quá trình tạo hàm curried này, tham số name được đánh giá. Nếu tôi làm như sau thay vào đó, nó hoạt động như dự định:

def byName(theValue : => Any) : Any =() => theValue 
val myHolder = byName(myValue) 

Tôi kết luận một số phần của quy trình currying là tham chiếu danh sách tham số đầu tiên và kích hoạt đánh giá. Ai có thể xác nhận rằng và/hoặc giải thích lý do tại sao hoặc nếu có bất kỳ hướng dẫn xung quanh bằng cách sử dụng các thông số tên với nhiều danh sách tham số?

Trả lời

3

Điều này có vẻ giống như một lỗi đối với tôi. Tôi có thể kích hoạt hành vi kỳ lạ này trong scala 2.9.1, nhưng không phải trong scala 2.10 RC1 vì vậy tôi đoán điều này đã được cố định tại một số điểm.

Trong scala 2.9.1:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_27). 
Type in expressions to have them evaluated. 
Type :help for more information. 
scala> def byName(theValue : => Any)() : Any = theValue 
byName: (theValue: => Any)()Any 
scala> def myValue: String = { println("Computing myValue"); "hello" } 
myValue: String 
scala> val myHolder = byName(myValue)_ 
Computing myValue 
myHolder:() => Any = <function0> 
scala> myHolder() 
res0: Any = hello 

Trong scala 2.10-RC1:

Welcome to Scala version 2.10.0-RC1 (Java HotSpot(TM) Client VM, Java 1.6.0_27). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> def byName(theValue : => Any)() : Any = theValue 
byName: (theValue: => Any)()Any 
scala> def myValue: String = { println("Computing myValue"); "hello" } 
myValue: String 
scala> val myHolder = byName(myValue)_ 
myHolder:() => Any = <function0> 
scala> myHolder() 
Computing myValue 
res0: Any = hello 
+0

Tôi tin rằng lỗi là: https://issues.scala-lang.org/browse/SI-302 – Steve

+0

Cũng được phát hiện. Từ các ý kiến ​​có vẻ như nó đã được sửa trong scala 2.10-M4. –

+0

Hoàn hảo - cảm ơn bạn đã làm rõ. –

2

Những vấn đề đang https://issues.scala-lang.org/browse/SI-302https://issues.scala-lang.org/browse/SI-5610

Cá nhân, tôi tìm thấy những gì tại là hành vi "cũ" trực quan hơn: Ứng dụng một phần nghĩa là một cái gì đó được áp dụng.

Hoặc như Odersky đã có nó:

Không, đó là cách mở rộng eta được định nghĩa. Bạn không chỉ quấn một lambda xung quanh biểu thức, bạn đánh giá những gì bạn có thể đầu tiên.

Nhưng ngược lại, sẽ dễ dàng hơn trong việc đánh giá hơn là đưa ra một cú pháp để tạm ngưng.

+0

Có, nhưng "áp dụng" nghĩa là gì trong ngữ cảnh của tham số theo tên? Điều gì sẽ xảy ra nếu bạn vượt qua một Function0 như một tham số, sẽ "áp dụng" có nghĩa là hàm này phải được đánh giá háo hức? Câu trả lời tự nhiên là không, và tôi sẽ nghĩ rằng nó là hợp lý để có cùng một kết luận cho một tham số theo tên. Tóm lại, tôi có xu hướng đồng ý với các lý lẽ phản đối của Matt Hellige: https://issues.scala-lang.org/browse/SI-302?focusedCommentId=39676&page=com.atlassian.jira.plugin.system.issuetabpanels: comment-tabpanel # comment-39676 –

+0

Thông số kỹ thuật theo tên gọi nó là "sử dụng". Đối với tôi, f (myValue) trông giống như việc sử dụng myValue, bất kể kết quả của expr. Nếu f bị quá tải là f (v: V) và f (v: => V), bạn không thể biết bằng cách tìm một myValue bằng tên được đánh giá và chuyển đến f đầu tiên. (Nhưng tôi không chống lại sự thay đổi về ngữ nghĩa một cách độc hại, nhưng đối với tôi, thông số cũ không điên rồ và phản trực giác như những người khó hiểu khác.) –

+0

Hmm - cả hai bên đều có ý nghĩa gì đó. Cảm ơn ý kiến ​​của bạn. –

Các vấn đề liên quan