Lambdas in Boo? - syntax

How do you deal with lambdas in boo? Is "callable" the same thing? How do you define a method that takes a lambda as a parameter?

Boo does support lambda expression syntax:
foo = {x|x+2}
seven = foo(5)
def TakeLambda(expr as callable(int) as int):
return expr(10)
twelve = TakeLambda(foo)
In this example, foo is a function that accepts a number x and returns x + 2. So calling foo(5) returns the number 7. TakeLambda is a function that accepts foo and evaluates it at 10.

Related

how to check if an argument is an integer and if not return nil

how would I write this in ruby " check if something is an integer, if not return nil. otherwise divide it by 2 and return the result. I
don't understand how to get it to check if it's not an integer and return nil. to write it in a function
def halve(x) x / 2 end
In Ruby, you can use instance_of? to check if the object is an instance of a given class and is_a? which returns true if the given class is the class of the object, or if the given class is one of the superclasses of the object.
In Ruby polymorphism or duck-typing is preferred, in this example, I would argue that one of those methods is a great choice too. IMHO is_a? is more idiomatic than instance_of? in Ruby but that depends on your specific use case.
def halve(x)
if x.is_a?(Integer)
x / 2.0
else
nil
end
end
Note that I change x / 2 to x / 2.0 because imagine x = 3 then x / 2 would return 1 but x / 2.0 will return 1.5. See the docs of Integer#/ for details.
def halve(x)
x.is_a?(Integer) ? x.fdiv(2) : nil
end
#is_a?(obj) returns true if the argument passed is the class of that object. You can also use #kind_of?(obj).
#fdiv(n) returns float. 1.fdiv(2) will return 0.5 (might be what you want) unlike 1 / 2 which returns 0.

Passing tuple returned by function to other function

Considering two functions
def bar()
return 1,2
end
def foo(a,b)
puts %{#{a},#{b}}
end
I would like to be able to call foo both with explicit parameters (e.g. foo(3,4)) as well as with parameters returned by bar (e.g. foo(bar)).
Unfortunately, the 2nd call produces an ArgumentError: "wrong number of arguments (given 1, expected 2)".
Declaring foo() to take a tuple (def foo(c); a,b = c; puts %{#{a},#{b}}; end) doesn't work either, because then the 1st call parameter raises the ArgumentError.
I thought of defining foo to take a Hash:
def foo(c)
a,b = c['a'],c['b']
puts %{#{a},#{b}}
end
but this makes the use with explicit parameters rather unhandy. Same with an Array.
What's the Ruby-esque way to solve this?
You need to splat the two-element array returned by bar: foo(*bar). That’s because foo has two arguments, each an element of the array returned by bar, not one argument that is that array.
Recall that the splat operator converts foo(*[1,2]) to foo(1,2).

Why do we call lambdas anonymous functions?

I named a lambda lamb:
lamb = lambda { |name| "hello #{name}"}
lamb.call("Steve") # => "hello Steve"
Since I gave the function a name, it is no longer anonymous. Why do we call it anonymous?
As pointed out already, whether you assign the lambda to a variable or not does not really change the fact that the lambda itself is not named. Look at the difference between how a method object behaves vs a lambda:
def test; end
mt = method(:test)
#=> #<Method: Object#test>
mt.arity
#=> 0
mt.name
#=> :test
l = -> {}
l.arity
#=> 0
l.name
NoMethodError: undefined method `name' for #<Proc:0x007faef08319f8#(irb):13 (lambda)>
As you can see, for a method the name is an inherent part of the method object, for a lambda it is not. What the lambda expression returns is an anonymous function that you then assign to a variable. This is not really different from assigning sum = 1 + 2, where the expression on the right has no inherent connection to the name its assigned to. This is also illustrated by the fact that it's perfectly possible to call a lambda without giving it a name first:
x = 1
->{x+1}.()
#=> 2
Lambdas/procs are only anonymous if they're unnamed, e.g.:
# anonymous lambda
[1,2,3].map(&lambda {|x| x * x})
# named lambda
square = lambda {|x| x * x}
[1,2,3].map(&square)
The lambda in your example is anonymous. "lamb" is not the name of your lambda, it is the name of a local variable whose value is an anonymous lambda method.
The variable does not name the lambda any more than x = 42 results in a named number.
Contrast this with methods in a class. They are named as part of adding them to a class or module.

Ruby and Lambda calculus

I'm trying to understand lambda calculus with procs and ruby. Here is some code:
puts -> x { -> y {x.call(y) } }
# => #<Proc:0x2a3beb0#C:/first-ruby.rb:1 (lambda)>
puts -> x { x + 2}.call(1)
# => 3
What does -> signify in above example? Is the call method passing the value to the caller, so in the first example, value y is passed to y and in the second example, 1 is passed to x? In the second example, why is 1 evaluated to x?
This is a shortcut for the pure lambda expression:
lmbd = -> arg{ something to do with arg } # With ->{} notation
lmbd = lambda { |arg| something to do with arg } # Standard notation
In your first example you invoke puts method with Proc(lambda) object, and that's why you see #<Proc:0x2a3beb0#C:/first-ruby.rb:1 (lambda)> in the output.
In the second example you invoke puts with lmbd.call(1) method, i.e. puts outputs the result of lambda calculation.
So, if you have lmbd variable which is lambda object, you can pass it like any argument and then get it's result by invoke lmbd.call():
lmbd = -> greeting{ puts "#{greeting}, lambda-expression!" }
def say_hello l, text
l.call(text)
end
say_hello lmbd, "Aloha" # => Aloha, lambda-expression!
What does -> signify in above example?
-> is part of the literal syntax for lambdas, just like, say, ' is part of the literal syntax for strings.
Is the .call method just passing the value from to caller,
The call method is the method, which, well, calls (or executes) the lambda. The arguments to the call method are bound to the parameters of the lambda.
so in first example value y is passed to y and in second example 1 is passed to x.
No, in the first example, y is passed to the outer lambda and bound to its x parameter. In the second example, 1 is passed to the lambda and bound to its x parameter.
In second example why how is 1 evaluated to x?
1 does not evalute to x. 1 is an immediate value, and in Ruby, immediate values always evaluate to themselves. 1 will always evaluate to 1, never to x or anything else.
Let's define a function using Ruby lambda.
def plus_two # no args here
->(x) {x + 2} # args go here
end
# assign a value
x = 1
# call it
plus_two.call(x)
# => 3
Your first example is a bit more complex but using this idea you should be able to come up with functional methods.
I'm studying Scala and functional programming is based upon these substitution principles.
Try doing some recursion using these.
It's like calling functions of functions n times.
What would be the base case then?
As for the Lambda Calculus https://github.com/mackorone/lambda/blob/master/intro.pdf
Try to keep things simple and show the steps rather than trying to figure out what a one liner is doing. Yes they are nice but if you can't read it you can't understand it.
Here's something I was just recently working on:
require 'date'
num = DateTime.now.to_time.utc.to_datetime.ajd - 2451545.0
#t = num / 36525.0
# the terms in reverse order form for the array
#l0_a = [1.0/-19880000.0,
1.0/-152990.0,
1.0/499310.0,
0.0003032028,
36000.76982779,
280.4664567]
# make an enumerator
#l0_e = #l0_a.each
# make a lambda to pass the enumerator to.
def my_lambda
->(x) {x.reduce {|acc, el| acc * #t + el} % 360}
end
puts my_lambda.call(#l0_e)
This is mean longitude of the sun formula using enumerator methods and of course a lambda.

Simple Currying in Ruby

I'm trying to do some currying in ruby:
def add(a,b)
return a+b
end
plus = lambda {add}
curry_plus = plus.curry
plus_two = curry_plus[2] #Line 24
puts plus_two[3]
I get the error
func_test.rb:24:in `[]': wrong number of arguments (1 for 0) (ArgumentError)
from func_test.rb:24:in `'
But if I do
plus = lambda {|a,b| a+ b}
It seems to work. But by printing plus after the assigning with lambda both ways return the same type of object. What have I misunderstood?
You're on the right track:
add = ->(a, b) { a + b }
plus_two = add.curry[2]
plus_two[4]
#> 6
plus_two[5]
#> 7
As others have pointed out, the plus lambda you defined doesn't take any arguments and calls the add method with no arguments.
lambda {|a,b| a+ b}
Creates a lambda which takes two arguments and returns the result of calling + on the first, with the second as its arguments.
lambda {add}
Creates a lambda which takes no arguments and calls add without arguments, which is an error of course.
To do what you want, you should do
plus = lambda {|x,y| add(x,y)}
or
plus = method(:add).to_proc
When you write lambda {add}, you're declaring a Proc that takes no arguments and, as its sole action, calls add with no arguments. It doesn't turn add into a Proc. On the other hand, lambda {|a,b| a + b} returns a Proc that takes two arguments and adds them together — since it takes arguments, it's valid to pass arguments to that one.
I think what you want is method(:add).to_proc.curry.

Resources