Justo después de las 02:40 en ShadowofCatron 's Scala Tutorial 3 video, se señaló que los paréntesis a continuación del nombre de un thunk son opcionales . "¿Buh?" dijo mi cerebro de programación funcional, ya que el valor de una función y el valor que evalúa cuando se aplica son cosas completamente diferentes.¿Por qué Scala aplica los thunk automáticamente, a veces?
Así que escribí lo siguiente para probar esto. Mi proceso de pensamiento se describe en los comentarios.
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
}
}
Para tener claro el problema, este programa Esquema (y el volcado de la consola que sigue) muestra lo que esperaba el programa Scala hacer.
(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
Después de llegar a este sitio para preguntar acerca de esto, me encontré con this answer que me ha dicho cómo solucionar lo anterior Scala programa:
val b = f _ // Hey Scala, I mean f, not f()
Pero el guión bajo 'toque' solo se necesita a veces. Cuando llamo al runThunk(f)
, no se requiere ninguna pista. Pero cuando 'alias' f to b con un val
luego lo aplica, no funciona: la aplicación ocurre en el val
; e incluso lazy val
funciona de esta manera, por lo que no es el punto de evaluación el que causa este comportamiento.
Todo eso me deja con la pregunta:
¿Por qué Scala veces se aplican automáticamente cuando thunks evaluación de las mismas?
¿Es que, como sospecho, escriba inferencia? Y si es así, ¿no debería un sistema de tipos permanecer fuera de la semántica del lenguaje?
¿Es esta una buena idea? ¿Los programadores de Scala aplican thunks en lugar de referirse a sus valores con mucha más frecuencia que hacer que los parens sean opcionales es mejor en general?
Ejemplos escritos usando Scala 2.8.0RC3, DrScheme 4.0.1 en R5RS.
+1 una pregunta excelentemente escrita. – Dario