Why variables setted inside Enum.each is not saved? - enums

I'm trying to set a value to a variable inside a function in Enum.each, but at the end of loop, variable is empty and I don't know exactly why this behaviour.
Code:
base = "master"
candidates = ["stream", "pigeons", "maters"]
return = []
Enum.each(candidates, fn candidate ->
cond do
String.length(base) == String.length(candidate) ->
return = return ++ [candidate]
true ->
true
end
end)
IO.inspect return
At this example, return is expected to be ["stream", "maters"], but instead, it is only an empty list: []
My question is why this happens.

When dealing with languages like Elixir, it is better to think in terms of "values" and "names" instead of "variables".
The reason you cannot do what you want is that Elixir has "lexical scoping".
When you assign to a "variable", you create a new value in the inner scope. You never change the "value" of a "name" defined in the outer scope.
(you probably can get what you want with Enum.filter/2, but I'm guessing this is just an illustrative example)
EDIT:
As of today, Elixir will allow you to write something like this:
if condition_that_evals_to_false do
x = 1
else
x = 2
end
IO.inspect x # => 2
```
But this will be deprecated in Elixir 1.3

Any reason why you don't just filter?
Anyways it seems like you're trying to mutate the value of return which is not possible with Elixir.
base = "master"
candidates = ["stream", "pigeon", "maters"]
result = Enum.filter(candidates, fn(candidate) ->
length(candidate) == length(base)
end
IO.inspect result
Edit: I'd also like to add that based on your logic, all of the candidates would be returned

Not sure, since I've never worked with the language, but a couple things spring to mind:
String.length(base) == String.length(candidate) can be equivalent to true, which is already a pattern in your set.
It could also be a scope issue with the return variable. It could be that the local return is hiding the global return. You could check this by outputting return every iteration. Each iteration the return should contain a single entry.

This is a bug. From Elixir's documentation:
Note: due to a bug in the 0.12.x series, cond‘s conditions actually
leak bindings to the surrounding scope. This should be fixed in
0.13.1.
You should use filtering like #{Christopher Yammine} suggested.

Related

How to check if a value of an array is empty

I am writing a chess program and has to see whether certain value are empty. I tried
aPiece is an array of CommandButtons. cmdSquare is a control array of shapes.
Private aPiece(63) As CommandButton
...
For p = 0 To 63
If IsEmpty(aPiece(p)) Then
aPiece(p).Left = cmdSquare(p).Left
aPiece(p).Top = cmdSquare(p).Top
End If
Next p
All variable are declared and is seem to be IsEmpty function which is not working.
The IsEmpty method only returns meaningful information for variants. Since the array contains objects, you need to check like this:
If aPiece(p) Is Nothing Then
However, this seems like only part of the answer. The above logic is saying "If there is no piece in my array then update it's location". That doesn't make sense to me and will generate an error. You also need to add Not like below:
For p = 0 To 1
If Not aPiece(p) Is Nothing Then
aPiece(p).Left = cmdSquare(p).Left
aPiece(p).Top = cmdSquare(p).Top
End If
Next p
It depends on the datatype of aPiece. If it is a variant and you haven't assigned a value to it, IsEmpty will return true. However, if it is a String, Date, Integer, etc. those are automatically initialized (String will be an empty string, Integer will be 0) so IsEmpty will return false.
A pretty good reference is this page: IsEmpty Function - Visual Basic 6.0

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.

Overwrite a variable without repeating the name

Is there a method to overwrite variable without copying its name? For example, when I want to change my_var = '3' to an integer, I must do something like this:
my_var = my_var.to_i
Is there way to do this without copying variable's name? I want to do something like this:
my_var = something_const.to_i
For numbers there exists +=, -= etc, but is there universal way to do this for all methods ?
There is no way to covert a string to an integer like that, without repeating the variable name. Methods such as String#upcase! and Array#flatten! work by mutating the object; however, it is not possible to define such a method like String#to_i! because we are converting the object to an instance of a different class.
For example, here is a (failed) attempt to define such a method:
# What I want to be able to do:
# my_var = "123"
# my_var.to_i! # => my_var == 123
class String
def to_i!
replace(Integer(self))
end
end
my_var = "123"
my_var.to_i! # TypeError: no implicit conversion of Fixnum into String
...And even if this code were valid, it would still offer no performance gain since a new object is still being created.
As for your examples of += and -=, these are in fact simply shorthand for:
x += 1
# Is equivalent to:
x = x + 1
So again, there is no performance gain here either; just slightly nicer syntax. A good question to ask is, why doesn't ruby support a ++ operator? If such an operator existed then it would offer performance gain... But I'll let you research for yourself why this is missing from the language.
So to summarise,
is there universal way to do this for all methods?
No. The special operators like +=, -=, |= and &= are all predefined; there is no "generalised" version such as method_name=.
You can also define methods that mutate the object, but only when appropriate. Such methods are usually named with a !, are called "bang-methods", and have a "non-bang" counterpart. On String objects, for example, there is String#capitalize! (and String#capitalize), String#delete! (and String#delete), String#encode! (and String#encode), .... but no String#to_i! for the reasons discussed above.

Returning multiple ints and passing them as multiple arguements in Lua

I have a function that takes a variable amount of ints as arguments.
thisFunction(1,1,1,2,2,2,2,3,4,4,7,4,2)
this function was given in a framework and I'd rather not change the code of the function or the .lua it is from. So I want a function that repeats a number for me a certain amount of times so this is less repetitive. Something that could work like this and achieve what was done above
thisFunction(repeatNum(1,3),repeatNum(2,4),3,repeatNum(4,2),7,4,2)
is this possible in Lua? I'm even comfortable with something like this:
thisFunction(repeatNum(1,3,2,4,3,1,4,2,7,1,4,1,2,1))
I think you're stuck with something along the lines of your second proposed solution, i.e.
thisFunction(repeatNum(1,3,2,4,3,1,4,2,7,1,4,1,2,1))
because if you use a function that returns multiple values in the middle of a list, it's adjusted so that it only returns one value. However, at the end of a list, the function does not have its return values adjusted.
You can code repeatNum as follows. It's not optimized and there's no error-checking. This works in Lua 5.1. If you're using 5.2, you'll need to make adjustments.
function repeatNum(...)
local results = {}
local n = #{...}
for i = 1,n,2 do
local val = select(i, ...)
local reps = select(i+1, ...)
for j = 1,reps do
table.insert(results, val)
end
end
return unpack(results)
end
I don't have 5.2 installed on this computer, but I believe the only change you need is to replace unpack with table.unpack.
I realise this question has been answered, but I wondered from a readability point of view if using tables to mark the repeats would be clearer, of course it's probably far less efficient.
function repeatnum(...)
local i = 0
local t = {...}
local tblO = {}
for j,v in ipairs(t) do
if type(v) == 'table' then
for k = 1,v[2] do
i = i + 1
tblO[i] = v[1]
end
else
i = i + 1
tblO[i] = v
end
end
return unpack(tblO)
end
print(repeatnum({1,3},{2,4},3,{4,2},7,4,2))

Ruby: Assign output of a function only if it does not return nil

When programming in Ruby I quite often have assignments like the following
test = some_function if some_function
With that assignments I want to assign the output of a function, but if it returns nil I want to keep the content of the variable. I know there are conditional assignments, but neither ||= nor &&= can be used here. The shortest way I found to describe the statement above is
test = (some_function or test)
Is there a better / shorter way to do this?
I don't think there's anything better than the last snippet you showed but note that or is used for flow control, use || instead:
test = some_function || test
It's usually better to assign new values to new names, the resulting code is easier to understand and debug since variables/symbols have the same value throughout the scope:
some_different_and_descriptive_name_here = some_function || test
I'd just add parentheses
(a = b) unless b.nil?
(a = b) if b
being inferior because if b is false then a remains as before
Keep in mind that this evaluates b twice, so if b is a function with side-effects (such as changing variables outside of its scope or printing) it will do that twice; to avoid this you must use
temp = b; (a = temp) unless temp.nil?
(which can, of course, be split into)
temp = b
(a = temp) unless temp.nil?

Resources