Estoy modelando un lenguaje de programación por diversión, y la sintaxis está fuertemente influenciada por Scala, específicamente las definiciones de funciones.
Me he encontrado con un problema de diseño porque mi lenguaje no diferencia entre las funciones definidas a través de la def
sintaxis (métodos de clase) y las funciones anónimas asignadas a los valores (creados usando =>
): elimina las diferencias tanto en la implementación como en el comportamiento .
El resultado es que las siguientes dos definiciones significan lo mismo:
def square(x: Int) = x*x
val square = (x: Int) => x*x
No hay ninguna razón para usar esta última forma (asignación de función anónima inmediata) en cualquier situación normal; simplemente es posible usarla en lugar de la def
forma.
¿Tener una sintaxis duplicada para definir funciones con nombre dañaría la ortogonalidad del lenguaje o algún otro aspecto del diseño?
Prefiero esta solución porque permite definiciones cortas e intuitivas de métodos y funciones con nombre (vía def
), y definiciones cortas de funciones anónimas (usando =>
).
Editar: Scala hace diferenciar entre los dos - anónimo funciones no son las mismas que con los métodos definidos def
en Scala. Sin embargo, las diferencias son relativamente sutiles: vea las publicaciones que he vinculado antes.
fuente
However, assigning existing functions
parece faltar el final de la oraciónval
notación?fun
para definir una función recursiva.def
es. Es solo un efecto secundario del hecho de que una función anónima, digamos,(x : Int) => x + 1
es un objeto, y los objetos pueden asignarse a valores conval f = ...
. Los diseñadores del lenguaje habrían tenido que salir de su camino para no permitir la sintaxis. No es lo mismo que hacer un esfuerzo explícito para admitir dos sintaxis diferentes que hacen (aproximadamente) lo mismo.Respuestas:
Creo que tener dos construcciones que signifiquen lo mismo pero se vean diferentes debería mantenerse al mínimo en un idioma. Cualquier duplicación aumenta lo difícil que es leer (y por lo tanto escribir / modificar código) en su idioma. Eliminar toda duplicación es inevitable en un lenguaje que puede crear construcciones arbitrarias (por ejemplo, la equivalencia de iteración frente a recursión).
Entonces, en este caso, creo que podría diseñarse mejor aquí. Una sola forma de definir funciones tiene más sentido para mí. En este caso, parece que las dos afirmaciones de escala que tiene realmente tienen implicaciones ligeramente diferentes, lo que de nuevo probablemente no sea un buen diseño (probablemente sea mejor tener algo claro que indique cuáles son las diferencias, como una palabra clave).
De hecho, puede aplicar este principio no solo a las funciones con nombre, sino a cualquier función. ¿Por qué hay alguna diferencia en la definición de funciones con nombre y funciones anónimas? En Lima , las funciones siempre se definen así:
fn[<arguments>: <statements>]
. Si usted quiere que sea "llamado" se puede asignar a una variable:var x = fn[<arguments: <statements>]
y si quieres pasarlo a otra función anónima:function[fn[<arguments: <statements>]]
. Si lo quieres izar, hazlo constanteconst var x = fn[<arguments: <statements>]
. La forma única hace obvio que significan lo mismo.fuente
const
causa la elevación, pero tiene mucho sentido. En JSfunction myFunc
provoca la elevación, perovar myFunc =
no lo hace, lo cual es quizás un poco menos intuitivo porque de lo contrario se comportan de la misma manera.function fnName()...
forma crea una constante, que es lo que hace que la elevación sea algo válido que ver con ella. Javascript hace que las cosas sean bastante confusas cuando usas el formulario,var fn = function anotherFnName()...
ya que eso hace que el nombreanotherFnName
no se levante, incluso si es claramente constante.Lo que has publicado es scala válido y funciona bien.
Dado que la duplicación no ha causado problemas con scala (que yo sepa), voy a decir que tampoco será un problema para su idioma.
fuente
He encontrado una diferencia fundamental entre lambdas y
def
métodos en Scala: que todavía no estoy seguro de si quiero implementar. Tengo que investigar más al respecto y luego informaré sobre mi decisión.Esencialmente, solo los métodos pueden
return
, y cuando la palabra clave se usa desde una lambda, en realidad regresa del método que lo abarca.Como he dicho, no estoy seguro de si quiero esto. Pero podría ser justificación suficiente para esta sintaxis. O tal vez demasiado peligroso porque las diferencias sutiles pueden causar daño inesperadamente.
Detalles
fuente