Сразу после 2:40 в ShadowofCatron * Scala Tutorial 3 video указано, что скобки следуют за именем thunk являются необязательными . «Буг?» сказал мой мозг по функциональному программированию, так как значение функции и значение, которое она оценивает при применении, совершенно разные вещи.
Поэтому я написал следующее, чтобы попробовать это. Мой мыслительный процесс описан в комментариях.
object Main {
var counter: Int = 10
def f(): Int = { counter = counter + 1; counter }
def runThunk(t: () => Int): Int = { t() }
def main(args: Array[String]): Unit = {
val a = f() // I expect this to mean "apply f to no args"
println(a) // and apparently it does
val b = f // I expect this to mean "the value f", a function value
println(b) // but it's the value it evaluates to when applied to no args
println(b) // and the application happens immediately, not in the call
runThunk(b) // This is an error: it's not println doing something funny
runThunk(f) // Not an error: seems to be val doing something funny
}
}
Чтобы понять проблему, эта программа Scheme (и следующий дамп консоли) показывает, что я ожидала от программы Scala.
(define counter (list 10))
(define f (lambda ()
(set-car! counter (+ (car counter) 1))
(car counter)))
(define runThunk (lambda (t) (t)))
(define main (lambda args
(let ((a (f))
(b f))
(display a) (newline)
(display b) (newline)
(display b) (newline)
(runThunk b)
(runThunk f))))
> (main)
11
#<procedure:f>
#<procedure:f>
13
Придя на этот сайт и спросив об этом, я наткнулся на этот ответ , в котором рассказывалось, как исправить вышеуказанную программу Scala:
val b = f _ // Hey Scala, I mean f, not f()
Но подчеркивание «подсказка» нужно только иногда . Когда я звоню runThunk(f)
, подсказка не требуется. Но когда я 'псевдоним' f к b с val
, а затем применить его, это не работает: приложение происходит в val
; и даже lazy val
работает таким образом, поэтому это не точка оценки, вызывающая такое поведение.
Это все оставляет меня с вопросом:
Почему Scala иногда автоматически применяет thunks при их оценке?
Это, как я подозреваю, вывод типа? И если да, то не должна ли система типов оставаться вне семантики языка?
Это хорошая идея? Программисты Scala применяют thunks вместо того, чтобы ссылаться на их значения гораздо чаще , что делает необязательные парены лучше в целом?
Примеры написаны с использованием Scala 2.8.0RC3, DrScheme 4.0.1 в R5RS.