Calling/Applying Lambda VS. Function Call - the Syntax in Ruby Is Different. Why

Calling/applying lambda vs. function call - the syntax in Ruby is different. Why?

Because in Ruby, methods are not lambdas (like, for example, in JavaScript).

Methods always belong to objects, can be inherited (by sub-classing or mixins), can be overwritten in an object's eigenclass and can be given a block (which is a lambda). They have their own scope for variables. Example method definition:

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

# call with:
some_method

However lambdas/procs are plain closures, maybe stored in a variable - nothing else:

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

# call with:
some_lambda[]

Ruby combines both approaches with a powerful syntax, for example, passing blocks:

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

Difference between lambda and def method_name in Ruby

Lambdas:

  • are variations of Procs,
  • can be converted to/from blocks,
  • do not begin a new closure scope (meaning you can access variables defined outside the scope of your lambda, unlike def),
  • can be passed around as variables.

I recommend checking out this article that explain procs, blocks, and lambdas.

Edit: This link is outdated. For future reference, try this article

Where and when to use Lambda?

It's true, you don't need anonymous functions (or lambdas, or whatever you want to call them). But there are a lot of things you don't need. You don't need classes—just pass all the instance variables around to ordinary functions. Then

class Foo
attr_accessor :bar, :baz
def frob(x)
bar = baz*x
end
end

would become

def new_Foo(bar,baz)
[bar,baz]
end

def bar(foo)
foo[0]
end
# Other attribute accessors stripped for brevity's sake

def frob(foo,x)
foo[0] = foo[1]*x
end

Similarly, you don't need any loops except for loop...end with if and break. I could go on and on.1 But you want to program with classes in Ruby. You want to be able to use while loops, or maybe even array.each { |x| ... }, and you want to be able to use unless instead of if not.

Just like these features, anonymous functions are there to help you express things elegantly, concisely, and sensibly. Being able to write some_function(lambda { |x,y| x + f(y) }) is much nicer than having to write

def temp(x,y)
x + f(y)
end
some_function temp

It's much bulkier to have to break off the flow of code to write out a deffed function, which then has to be given a useless name, when it's just as clear to write the operation in-line. It's true that there's nowhere you must use a lambda, but there are lots of places I'd much rather use a lambda.

Ruby solves a lot of the lambda-using cases with blocks: all the functions like each, map, and open which can take a block as an argument are basically taking a special-cased anonymous function. array.map { |x| f(x) + g(x) } is the same as array.map(&lambda { |x| f(x) + g(x) }) (where the & just makes the lambda "special" in the same way that the bare block is). Again, you could write out a separate deffed function every time—but why would you want to?

Languages other than Ruby which support that style of programming don't have blocks, but often support a lighter-weight lambda syntax, such as Haskell's \x -> f x + g x, or C#'s x => f(x) + g(x);2. Any time I have a function which needs to take some abstract behavior, such as map, or each, or on_clicked, I'm going to be thankful for the ability to pass in a lambda instead of a named function, because it's just that much easier. Eventually, you stop thinking of them as somehow special—they're about as exciting as literal syntax for arrays instead of empty().append(1).append(2).append(3). Just another useful part of the language.


1: In the degenerate case, you really only need eight instructions: +-<>[].,. <> move an imaginary "pointer" along an array; +- increment and decrement the integer in the current cell; [] perform a loop-while-non-zero; and ., do input and output. In fact, you really only need just one instruction, such as subleq a b c (subtract a from b and jump to c if the result is less than or equal to zero).

2: I've never actually used C#, so if that syntax is wrong, feel free to correct it.

Do ruby Proc/lambda have a 'this' function like javascript closure ?

this is not part of the concept of a function or closure in general. A function is simply a thing you can call with arguments; what does "current object" has to do with it? this existing in all functions in JavaScript comes from the peculiar way that methods work in that language.

In JavaScript, all functions have a concept of this because in JavaScript, there is no separation between methods and functions. Any function could potentially be used as a method; you can add a method to an object simply by assigning a function as an attribute of the object. Furthermore, in JavaScript, a function does not have an explicit parameter for the current object (unlike e.g. Python); so how does a method have access to its object? When you run a method call expression, it will pass the object that you called it on as an implicit this parameter to the function. However, if you get the function out using the attribute and call it manually just like any other function, this will be the global object (or in strict mode, undefined).

In other words, in JavaScript when you get a method out of an object by attribute, it is an "unbound method" -- it does not know the object it came from; and conversely when you put a function into an object as a method by attribute, that function did not need to know the object to start with -- the object will be passed to it magically by the method call syntax at the time it is called. You can also artificially supply the this argument to a function by using the .call() or .apply() methods on the function (obj.foo(x) is equivalent to obj.foo.call(obj, x)).

In Ruby, there is complete separation between methods and anonymous functions. Anonymous functions, created using lambda, proc, or Proc.new, etc. are data, and can be stored in variables. They are called with different syntax (call or []) than methods. Methods are defined using def, and you can't get it as data by simply writing its name (that will call it). It is possible to get a method out of an object using the method method on an object, giving the method name, and it returns a Method object. You can use a Method object like a Proc object, e.g. you can call call on it; you can even convert it to a Proc with to_proc. Unlike JavaScript, there is a distinction between bound methods (class Method) an unbound methods (class UnboundMethod). When you get a method out of an object, it is bound -- it knows its object; you can unbind it and bind it to another object if you want.

Also, in Ruby, you can't just take a Proc and just attach it to an object and make it a method, because methods have syntax (e.g. @some_var) that are not valid in Proc. To add a method to an object, you would use instance_exec and put the method definition (def) in the block.

So in short, the concept of this in closures deals with a unique situation in JavaScript not found in most languages. And in particular, the issue does not come up in Ruby because Ruby's objects' methods are bound methods, and also one cannot arbitrarily insert closures as methods.

P.S. others have commented on capturing the self from where a closure is defined into the closure. However, that's not what this in JavaScript is about at all.

What is the difference between a 'closure' and a 'lambda'?

A lambda is just an anonymous function - a function defined with no name. In some languages, such as Scheme, they are equivalent to named functions. In fact, the function definition is re-written as binding a lambda to a variable internally. In other languages, like Python, there are some (rather needless) distinctions between them, but they behave the same way otherwise.

A closure is any function which closes over the environment in which it was defined. This means that it can access variables not in its parameter list. Examples:

def func(): return h
def anotherfunc(h):
return func()

This will cause an error, because func does not close over the environment in anotherfunc - h is undefined. func only closes over the global environment. This will work:

def anotherfunc(h):
def func(): return h
return func()

Because here, func is defined in anotherfunc, and in python 2.3 and greater (or some number like this) when they almost got closures correct (mutation still doesn't work), this means that it closes over anotherfunc's environment and can access variables inside of it. In Python 3.1+, mutation works too when using the nonlocal keyword.

Another important point - func will continue to close over anotherfunc's environment even when it's no longer being evaluated in anotherfunc. This code will also work:

def anotherfunc(h):
def func(): return h
return func

print anotherfunc(10)()

This will print 10.

This, as you notice, has nothing to do with lambdas - they are two different (although related) concepts.

What is a lambda (function)?

Lambda comes from the Lambda Calculus and refers to anonymous functions in programming.

Why is this cool? It allows you to write quick throw away functions without naming them. It also provides a nice way to write closures. With that power you can do things like this.

Python

def adder(x):
return lambda y: x + y
add5 = adder(5)
add5(1)
6

As you can see from the snippet of Python, the function adder takes in an argument x, and returns an anonymous function, or lambda, that takes another argument y. That anonymous function allows you to create functions from functions. This is a simple example, but it should convey the power lambdas and closures have.

Examples in other languages

Perl 5

sub adder {
my ($x) = @_;
return sub {
my ($y) = @_;
$x + $y
}
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
return function (y) {
return x + y;
};
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Scheme

(define adder
(lambda (x)
(lambda (y)
(+ x y))))
(define add5
(adder 5))
(add5 1)
6

C# 3.5 or higher

Func<int, Func<int, int>> adder = 
(int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure =
(x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Swift

func adder(x: Int) -> (Int) -> Int{
return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = fn () => $a + $b;

echo $lambda();

Haskell

(\x y -> x + y) 

Java see this post

// The following is an example of Predicate : 
// a functional interface that takes an argument
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
return function(y)
return x + y
end
end
add5 = adder(5)
add5(1) == 6 -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Ruby

Ruby is slightly different in that you cannot call a lambda using the exact same syntax as calling a function, but it still has lambdas.

def adder(x)
lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby being Ruby, there is a shorthand for lambdas, so you can define adder this way:

def adder(x)
-> y { x + y }
end

R

adder <- function(x) {
function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6

Why does Ruby sometimes throw an error when a function is called with a space before the parentheses?

Using Ruby 2.6.3 I get the following warning when run with ruby -w.

test.rb:1: warning: parentheses after method name is interpreted as an argument list, not a decomposed argument

This is referring to Array Decomposition where you can unpack the elements of an Array argument into individual variables.

def bar((a,b))
puts "a: #{a}, b: #{b}"
end

# a: first, b: second
bar ['first', 'second', 'third']

What's wrong with def foo (i)? def foo i is legal; parenthesis around the arguments are optional. However def foo (i) is ambiguous. It can be interpreted as a single argument def foo(i) or an array decomposition def foo((i)).

Because this is ambiguous, different interpreters may have different... interpretations. /p>

Before filter, calling a method with param throws syntax error. Ruby

:check_user_validity is a symbol which is something like a string. You can't "run" a symbol with parentheses. You are effectively doing something like 'function_name'(...) which is invalid syntax.

before_filter or before_action works by passing it a function name (by using symbols) or function (by using proc/lambda) to be called later when a request is received.



Related Topics



Leave a reply



Submit