Только после 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 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 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)
, никакой подсказки не требуется. Но когда я 'alias' f to b с val
, то примените его, это не сработает: приложение происходит в val
; и даже lazy val
работает таким образом, так что это не точка оценки, вызывающая такое поведение.
Все это оставляет мне вопрос:
Почему Scala иногда автоматически применяет thunks при их оценке?
Это, как я подозреваю, введите вывод? И если да, то не должна ли система типов оставаться вне семантики языка?
Это хорошая идея? Программисты Scala применяют thunks, а не ссылаются на их значения намного чаще, чем делает опциональный parens лучше в целом?
Примеры, написанные с использованием Scala 2.8.0RC3, DrScheme 4.0.1 в R5RS.