Block does not recognise variable at first time - ruby

y = lambda { z }
z = 9
y.call
=> NameError: undefined local variable or method `z' for main:Object
y = lambda { z }
y.call
=> 9
I thought the idea of having a block was defer the execution of the piece of code inside the block. Can you explain this?

lambda creates what's known as a lexical closure, which means it captures a reference to the enclosing environment and can use variables that are in scope at the time the closure is created.
y = lambda { z } # Woops! There's no variable named `z`!
It doesn't matter if you create a variable named z after creating the closure; the idea of the closure is that it captures the environment at that particular moment.
In theory, you could hope for an error when you create that lambda, because it's possible to analyze it and determine that a variable will be dereferenced which has not been defined. Ruby doesn't work that way, however; it is only when code is being evaluated that you get an error for attempting to access an undefined variable.
When you create a second closure, a few lines later, that one does capture an environment in which z exists:
y = lambda { z } # This closure is broken and can't be fixed
z = 9
y = lambda { z } # This is a new closure, and `z` is accessible within it
I thought the idea of having a block was defer the execution of the piece of code inside the block.
Sort of, but it's not the same as simply copying and pasting the code from the lambda and evaluating it when you call it. evaling a string would do that:
y = "z"
z = 9
eval(y)
# => 9
Again, the idea of a closure is that it captures both the code and the environment.

In the first line, when the block is created, there simply is no z yet that could be "catched" by the block yet. When you write y = lambda { z } the second time, there is a z.
The block takes a kind of snapshot of the surrounding variables. And in this case, no variable named z was present the first time.

When you define a lambda, it gets a closure, consisting of references to all the variables in scope at the time of definition. The lambda always has access to the current value of each variable it has "closed over", but newly defined variables aren't added to the closure retroactively. So when you do this:
x = 5
y = lambda { x + z }
z = 7
the lambda y has access to the value of x, but not z, because only x was in existence at the time you defined the lambda. But if you do this:
x = 5
z = 0
y = lambda { x + z }
z = 7
y.call
# => 12
then all will be well.

undefined local variable or method 'z' for main:Object comes when local variables are not created. local variables created by only assignment operation.
your first y = lambda { z } couldn't bind z as z is defined after this lambda definition.
the below works :
y = lambda { z }
y.call
=> 9
as you defined z = 9 before 2nd lambda definition.

Related

Confusing julia behavior. #everywhere macro changes the scope of local variables to global

I just encountered a very confusing julia behavior. I always thought that variables defined inside a function remain local to that function. But in the following example, the scope changes.
I define a simple function as below
using Distributed
addprocs(2)
function f()
#everywhere x = myid()
#everywhere println("x = ", x)
end
Executing the following code
f()
gives the result
x = 1
From worker 2: x = 2
From worker 3: x = 3
But since x is defined inside the function, I would expect the variable x to be not defined outside the function. However, upon executing the following code
x
I get the result
1
Even more confusing is the execution of the following code
#fetchfrom 3 x
which again gives
1
This is super confusing behavior. First, how does x become available outside the function? Second, why are all the processors/cores returning the same value of x? Thank you for your help.

Introspecting _ENV from coroutines

NB: I am using Lua version 5.3.
This question is motivated by Exercise 25.1 (p. 264) of Programming in Lua (4th ed.). That exercise reads as follows:
Exercise 25.1: Adapt getvarvalue (Listing 25.1) to work with different coroutines (like the functions from the debug library).
The function getvarvalue that the exercise refers to is copied verbatim below.
-- Listing 25.1 (p. 256) of *Programming in Lua* (4th ed.)
function getvarvalue (name, level, isenv)
local value
local found = false
level = (level or 1) + 1
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(level, i)
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(level, "f").func
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue("_ENV", level, true)
if env then
return "global", env[name]
else -- no _ENV available
return "noenv"
end
end
Below is my enhanced version of this function, which implements the additional functionality specified in the exercise. This version accepts an optional thread parameter, expected to be a coroutine. The only differences between this enhanced version and the original getvarvalue are:
the handling of the additional optional thread parameter;
the special setting of the level parameter depending on whether the thread parameter is the same as the running coroutine or not; and
the passing of the thread parameter in the calls to debug.getlocal and debug.getinfo, and in the recursive call.
(I have marked these differences in the source code through numbered comments.)
function getvarvalue_enhanced (thread, name, level, isenv)
-- 1
if type(thread) ~= "thread" then
-- (thread, name, level, isenv)
-- (name, level, isenv)
isenv = level
level = name
name = thread
thread = coroutine.running()
end
local value
local found = false
-- 2
level = level or 1
if thread == coroutine.running() then
level = level + 1
end
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(thread, level, i) -- 3
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(thread, level, "f").func -- 3
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue_enhanced(thread, "_ENV", level, true) -- 3
if env then
return "global", env[name]
else
return "noenv"
end
end
This function works reasonably well, but I have found one strange situation1 where it fails. The function make_nasty below generates a coroutine for which getvarvalue_enhanced fails to find an _ENV variable; i.e. it returns "noenv". (The function that serves as the basis for nasty is the closure closure_B, which in turn invokes the closure closure_A. It is closure_A that then yields.)
function make_nasty ()
local function closure_A () coroutine.yield() end
local function closure_B ()
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nasty = make_nasty()
print(getvarvalue_enhanced(nasty, "_ENV", 2))
-- noenv
In contrast, the almost identical function make_nice produces a coroutine for which getvarvalue_enhanced succeeds in finding an _ENV variable.
function make_nice ()
local function closure_A () coroutine.yield() end
local function closure_B ()
local _ = one_very_much_non_existent_global_variable -- only difference!
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nice = make_nice()
print(getvarvalue_enhanced(nice, "_ENV", 2))
-- upvalue table: 0x558a2633c930
The only difference between make_nasty and make_nice is that, in the latter, the closure closure_B references a non-existent global variable (and does nothing with it).
Q: How can I modify getvarvalue_enhanced so that it is able to locate _ENV for nasty, the way it does for nice?
EDIT: changed the names of the closures within make_nasty and make_nice.
EDIT2: the wording of Exercise 25.3 (same page) may be relevant here (my emphasis):
Exercise 25.3: Write a version of getvarvalue (Listing 25.1) that returns a table with all variables that are visible at the calling function. (The returned table should not include environmental variables; instead it should inherit them from the original environment.)
This question implies that there should be a way to get at the variables that are merely visible from a function, whether the function uses them or not. Such variables would certainly include _ENV. (The author is one of Lua's creators, so he knows what he's talking about.)
1 I am sure that someone with a better understanding of what is going on in this example will be able to come up with a less convoluted way to elicit the same behavior. The example I present here is the most minimal form I can come up with of the situation I found by accident.
local function inner_closure () coroutine.yield() end
local function outer_closure ()
inner_closure()
end
The function make_nasty below generates a coroutine for which getvarvalue_enhanced fails to find an _ENV variable; i.e. it returns "noenv"
That's a correct behavior.
The closure outer_closure has upvalue inner_closure but doesn't have upvalue _ENV.
This is how lexical scope works.
It's OK that some closures don't have _ENV upvalue.
In your example the closure inner_closure isn't defined inside the body of outer_closure.
inner_closure is not nested in outer_closure.
It's impossible.
If a closure doesn't make any use of the global environment _ENV, then it doesn't have that upvalue whatsoever.
A function like
local something = 20
local function noupval(x, y)
return x * y
end
Doesn't need or have any upvalues, not even to the global environment.
This question implies that there should be a way to get at the variables that are merely visible from a function, whether the function uses them or not.
There really isn't though. You can easily confirm this by looking at the output of luac -p -l <your_code.lua>, more precisely at the upvalues of each function.
If anything, I think using the word visible is somewhat misleading there. Visibility really only matters when creating a closure, but once it has been closed, that closure only has a set of upvalues which it can access.
Exercise 25.3: Write a version of getvarvalue (Listing 25.1) that returns a table with all variables that are visible at the calling function. (The returned table should not include environmental variables; instead it should inherit them from the original environment.)
You may have misunderstood that exercise; the way I understand it is something like this:
local upvalue = 20
local function foo()
local var = upvalue -- Create 1 local and access 1 upvalue
type(print) == "function" -- Access _ENV so it becomes an upvalue
return getvarvalue_enhanced()
end
and the above would return {var = 20, upvalue = 20, _ENV = <Proxy table to _ENV>}
After all, it asks specifically about the calling function, not one you pass as a parameter.
This doesn't change the fact that you still only get _ENV if you access it though. If you don't use any globals, the function won't have any reference to _ENV whatsoever.

Binding vs Assignment

I've read a number of articles on the difference between assignment and binding, but it hasn't clicked yet (specifically in the context of an imperative language vs one without mutation).
I asked in IRC, and someone mentioned these 2 examples illustrate the difference, but then I had to go and I didn't see the full explanation.
Can someone please explain how/why this works in a detailed way, to help illustrate the difference?
Ruby
x = 1; f = lambda { x }; x = 2; f.call
#=> 2
Elixir
x = 1; f = fn -> x end; x = 2; f.()
#=> 1
I've heard this explanation before and it seems pretty good:
You can think of binding as a label on a suitcase, and assignment as a
suitcase.
In other languages, where you have assignment, it is more like putting a value in a suitcase. You actually change value that is in the suitcase and put in a different value.
If you have a suitcase with a value in it, in Elixir, you put a label on it. You can change the label, but the value in the suitcase is still the same.
So, for example with:
iex(1)> x = 1
iex(2)> f = fn -> x end
iex(3)> x = 2
iex(4)> f.()
1
You have a suitcase with 1 in it and you label it x.
Then you say, "Here, Mr. Function, I want you to tell me what is in this suitcase when I call you."
Then, you take the label off of the suitcase with 1 in it and put it on another suitcase with 2 in it.
Then you say "Hey, Mr. Function, what is in that suitcase?"
He will say "1", because the suitcase hasn't changed. Although, you have taken your label off of it and put it on a different suitcase.
After a while, I came up with the answer that is probably the best explanation of the difference between “binding” and “assignment”; it has nothing in common with what I have written in another answer, hence it’s posted as a separate answer.
In any functional language, where everything is immutable, there is no meaningful difference between terms “binding” and “assignment.” One might call it either way; the common pattern is to use the word “binding,“ explicitly denoting that it’s a value bound to a variable. In Erlang, for instance, one can not rebound a variable. In Elixir this is possible (why, for God’s sake, José, what for?)
Consider the following example in Elixir:
iex> x = 1
iex> 1 = x
The above is perfectly valid Elixir code. It is evident, one cannot assign anything to one. It is neither assignment nor binding. It is matching. That is how = is treated in Elixir (and in Erlang): a = b fails if both are bound to different values; it returns RHO if they match; it binds LHO to RHO if LHO is not bound yet.
In Ruby it differs. There is a significant difference between assignment (copying the content,) and binding (making a reference.)
Elixir vs Ruby might not be the best contrast for this. In Elixir, we can readily "re-assign" the value of a previously assigned named variable. The two anonymous-function examples you provided demonstrate the difference in how the two languages assign local variables in them. In Ruby, the variable, meaning the memory reference, is assigned, which is why when we change it, the anonymous function returns the current value stored in that memory-reference. While in Elixir, the value of the variable at the time the anonymous function is defined (rather than the memory reference) is copied and stored as the local variable.
In Erlang, Elixir's "parent" language, however, variables as a rule are "bound." Once you've declared the value for the variable named X, you are not allowed to alter it for the remainder of the program and any needed alterations would need to be stored in new named variables. (There is a way to reassign a named variable in Erlang but it is not the custom.)
Binding refers to particular concept used in expression-based languages that may seem foreign if you're used to statement-based languages. I'll use an ML-style example to demonstrate:
let x = 3 in
let y = 5 in
x + y
val it : int = 8
The let... in syntax used here demonstrates that the binding let x = 3 is scoped only to the expression following the in. Likewise, the binding let y = 5 is only scoped to the expression x + y, such that, if we consider another example:
let x = 3 in
let f () =
x + 5
let x = 4 in
f()
val it : int = 8
The result is still 8, even though we have the binding let x = 4 above the call to f(). This is because f itself was bound in the scope of the binding let x = 3.
Assignment in statement-based languages is different, because the variables being assigned are not scoped to a particular expression, they are effectively 'global' for whatever block of code they're in, so reassigning the value of a variable changes the result of an evaluation that uses the same variable.
The easiest way to understand the difference, would be to compare the AST that is used by the language interpreter/compiler to produce machine-/byte-code.
Let’s start with ruby. Ruby does not provide the AST viewer out of the box, so I will use RubyParser gem for that:
> require 'ruby_parser'
> RubyParser.new.parse("x = 1; f = -> {x}; x = 2; f.()").inspect
#=> "s(:block, s(:lasgn, :x, s(:lit, 1)),
# s(:lasgn, :f, s(:iter, s(:call, nil, :lambda), 0, s(:lvar, :x))),
# s(:lasgn, :x, s(:lit, 2)), s(:call, s(:lvar, :f), :call))"
The thing we are looking for is the latest node in the second line: there is x variable inside the proc. In other words, ruby expects the bound variable there, named x. At the time the proc is evaluated, x has a value of 2. Hence the the proc returns 2.
Let’s now check Elixir.
iex|1 ▶ quote do
...|1 ▶ x = 1
...|1 ▶ f = fn -> x end
...|1 ▶ x = 2
...|1 ▶ f.()
...|1 ▶ end
#⇒ {:__block__, [],
# [
# {:=, [], [{:x, [], Elixir}, 1]},
# {:=, [], [{:f, [], Elixir}, {:fn, [], [{:->, [], [[], {:x, [], Elixir}]}]}]},
# {:=, [], [{:x, [], Elixir}, 2]},
# {{:., [], [{:f, [], Elixir}]}, [], []}
# ]}
Last node in the second line is ours. It still contains x, but during a compilation stage this x will be evaluated to it’s currently assigned value. That said, fn -> not_x end will result in compilation error, while in ruby there could be literally anything inside a proc body, since it’ll be evaluated when called.
In other words, Ruby uses a current caller’s context to evaluate proc, while Elixir uses a closure. It grabs the context it encountered the function definition and uses it to resolve all the local variables.

Confused on how to use lambda in ruby for select

I'm working with ruby and I'm just learning lambdas. I have an array of objects and I want to select certain objects from the array based of different conditions like so:
result = array.select{|ar| ar.number > 4}
I want to put the arguments of the select into a lambda expression i.e. I want to put |ar| ar.number > 4 into a lambda expression. I've tried a few things including:
result = array.select{lambda{|g| g.number > 4}}
But this doesn't work.
I've also tried this:
l = lambda {g.number > 4}
result = array.select{|g| l}
and that also doesn't work. Also I need to pass my lambda express to a function so I don't think the first way I did it would have worked. How would I do this?
Enumerable#select takes a block, not a lambda. So, you need to pass it a block.
Thankfully, there is an operator which will convert a lambda or proc (and in fact anything which responds to to_proc) to a block: the unary prefix & operator, which is only valid in argument lists (where it converts a proc to a block) and in parameter lists (where it converts a block to a proc).
So, if you have a lambda l, you can pass it as a block to method foo like so:
foo(&l)
Your second problem is that your lambda doesn't take any arguments, but the block passed to select takes one argument, so you need to create your lambda with one argument:
l = lambda {|el| el.number > 4 }
# I prefer this syntax, though:
l = -> el { el.number > 4 }
Putting all that together, we have:
result = array.select(&l)
To pass a lambda (or a proc) to a method as a block, you have to use the special &syntax:
result = array.select &mylambda
Also, your lambda (or proc) must specify the name for parameters it will receive and use. Thus:
l = lambda { |g| g.number > 4}
result = array.select &l
A clean way to do this is to use Ruby's "stabby" lambda syntax:
l = ->(ar) { ar.number > 4 }
result = array.select(&l)
The more "traditional" way to define a lambda is as such:
l = lambda { |ar| ar.number > 4 }
result = array.select(&l)
Note that you don't strictly need to use a lambda; you could also use a proc*:
p = proc { |ar| ar.number > 4 }
result = array.select(&p)
* The main difference between proc and lambda is that lambda will throw an error when passed too few or too many arguments, while proc will ignore it. Another subtle difference is that the return statement inside a proc will cause execution to return both from the closure and the enclosing method (if any).

Confusion about CoffeeScript variable scope

I am trying to understand how CoffeeScript variables are scoped.
According to the documentation:
This behavior is effectively identical to Ruby's scope for local
variables.
However, I found out that it works differently.
In CoffeeScript
a = 1
changeValue = -> a = 3
changeValue()
console.log "a: #{a}" #This displays 3
In Ruby
a = 1
def f
a = 3
end
puts a #This displays 1
Can somebody explain it, please?
Ruby's local variables (starting with [a-z_]) are really local to the block they are declared in. So the Ruby behavior you posted is normal.
In your Coffee example, you have a closure referencing a. It's not a function declaration.
In your Ruby example, you don't have a closure but a function declaration. This is different. The Ruby equivalent to your Coffee is:
a = 1
changeValue = lambda do
a = 3
end
changeValue()
In closures, local variables present when the block is declared are still accessible when the block is executed. This is (one of the) powers of closures!
The a variable being used inside the changeValue function is the global a variable. That CoffeeScript will be compiled into the following JavaScript:
var a, changeValue;
a = 1;
changeValue = function() {
return a = 3;
};
changeValue();
console.log("a: " + a);
In order for changeValue to not alter the a variable (i.e. use a local variable), you would either need to have an argument to the function named a (which would create a as a variable local to that function) or declare a as a local variable inside the function using var a = 3; (not sure what the CoffeeScript for that would be, I'm not a CoffeeScript guy).
Some examples of JavaScript variable scope.

Resources