ruby lambda-calculus lambda

Llamar/aplicar lambda frente a llamada de función: la sintaxis en Ruby es diferente. ¿Por qué?



lambda-calculus (3)

Soy un poco nuevo para Ruby y sigo tratando de entender algunos de los principios del diseño del lenguaje. Si lo hago bien, la llamada de expresión lambda en Ruby debe ser con llaves cuadradas, mientras que la llamada a la función "regular" es con llaves "regulares" / redondas.

¿Hay alguna razón especial por la que la sintaxis sea diferente? O, en otras palabras, ¿por qué debería la persona que llama saber si llaman a una función o aplican una expresión lambda?


Las llamadas de método de Ruby regulares usan () no llaves que son para bloques. Si no le gusta [] para llamar a un lambda, siempre puede usar el método de call .

Ejemplo:

>> by_two = lambda { |x| x * 2 } #=> #<Proc:0x0000000101304588@(irb):1> >> by_two[5] #=> 10 >> by_two.call(5) #=> 10

Editar

En la versión más nueva de Ruby también:

>> by_two.(5) #=> 10

En cuanto a por qué no puedes hacer by_two(5) , cuando Ruby ve una palabra clave primero intenta resolverlo como una variable local y si eso falla como método.


Porque en Ruby, los métodos no son lambdas (como, por ejemplo, en JavaScript).

Los métodos siempre pertenecen a objetos, se pueden heredar (mediante subclasificación o mixins), se pueden sobrescribir en la clase de objeto y se puede asignar un bloque (que es un lambda). Ellos tienen su propio alcance para las variables. Ejemplo de definición de método:

a = :some_variable def some_method # do something, but not possible to access local variable a end # call with: some_method

Sin embargo, lambdas / procs son cierres simples, tal vez almacenados en una variable, nada más:

a = :some_variable some_lambda = lambda{ # do something, access local variable a if you want to } # call with: some_lambda[]

Ruby combina ambos enfoques con una sintaxis poderosa, por ejemplo, pasar bloques:

def some_method_with_block(a) # do something, call given block (which is a lambda) with: yield(a) ? 42 : 21 end # example call: some_method_with_block(1) do |x| x.odd? end #=> 42


Si quieres corchetes, puedes hacer

by_two = lambda { |x| x * 2 } by_two.(5) # => 10

Tenga en cuenta el . entre by_two y (5) .