If it has closures, can I assume that I can use many of strong functional style techniques on there?
Yes, Smalltalk has closures. The following code creates a closure that returns the sum of its two arguments:
sum := [ :a :b | a + b ].
Closures are objects that can be instantiated, passed around and manipulated. To evaluate a closure you send value, value:, value:value:, ...
sum value: 1 value: 2.
Closures are prominently used with collections to iterate, filter, map, ... all values of a collection:
aCollection select: [ :each | each isOdd ].
aCollection inject: 0 into: [ :each :result | each + result ].
Furthermore, they are used for control structures like loops:
[ iterator hasNext ]
whileTrue: [ iterator next ].
1 to: 10 do: [ :each | ... ].
Also conditionals are implemented using closures:
condition
ifTrue: [ do this ]
ifFalse: [ do that ]
Pharo has them:
all VMs have closure support required
for latest images
makeAdder := [ :x | [ :y | x + y ]].
add2 := makeAdder value: 2.
add2 value: 3.
Returns 5.
But notice that
makeCounter := [ :init | [ init := init + 1. init ]].
won't work (Cannot store into ->init …), like (for example) in CL:
CL-USER> ((lambda (init) (lambda () (incf init))) 0)
#<COMPILED-LEXICAL-CLOSURE #xC7A495E>
CL-USER> (funcall *)
1
CL-USER> (funcall **)
2
CL-USER> (funcall ***)
3
If I'm not mistaken, this used to work before the new closure compiler was introduced. I'm not sure why it doesn't work with the new compiler.
Related
I need to write the equivalent of lists:foldl/3 for binary trees.
Every node is represented as:
[Value, LeftNode, RightNode]
So a tree with a root 2 and leaves 1 and 3 would look like this:
[2, [1, [], []], [3, [], []]]
Later I want to use that function to perform operations, such as summing up all positive values in that tree etc.
This is the function I wrote:
tree_foldl(_, Acc, []) -> Acc;
tree_foldl(Fun, Acc, [V, L, R]) ->
X1 = tree_foldl(Fun, Fun(V, Acc), L),
X2 = tree_foldl(Fun, Fun(L, X1), R),
X2.
the problem is that it's not truly generic, and when we have, let's say a tree with only a root, e.g.:
[2, [], []]
it calls both Fun(2, 0) and Fun([], 2) and when trying to sum up the values in the second case it tries to do [] + 2, which is an invalid expression. It also would break on more complicated cases.
I would greatly appreciate any help with fixing this function. Thank you.
First of all, you should use tuples as nodes in this case instead of lists. Lists are linked lists between their elements while tuples use contiguous memory (you can access a single element of a tuple without processing the leading elements of structure).
There's no need for Fun(L, X1):
tree_foldl(_, Acc, []) -> Acc;
tree_foldl(Fun, Acc, [V, L, R]) ->
Acc0 = Fun(V, Acc),
Acc1 = tree_foldl(Fun, Acc0, L),
Acc2 = tree_foldl(Fun, Acc1, R),
Acc2.
If the node is empty, do nothing, else run the Fun on the node and recurse on both subtrees.
I'm trying to break out of a nested foreach loop using 2 lists of sorted turtles.
But instead of just leaving the inner loop, netlogo breaks out of the whole procedure.
I have a code like the one below (this one is made up, but has exactly the same structure):
to do-something
let xturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles
;; construct an ordered set
foreach xturtles [ the-xturtle ->
ask the-xturtle [
let xage birthday
let yturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles with [birthday < xage]
;; construct a second ordered set
foreach yturtles [ the-yturtle ->
let breakout-condition? false
ask the-yturtle [
if (hidden? ) [
set breakout-condition? true
]
]
if breakout-condition? [ stop ]
]
]
]
end
However, when the stop condition is reached, netlogo breaks out of the whole procedure, instead of continuing with the outer loop (the xturtles loop)?
Is that the expected behavior? If so, what is a good practice in this case?
Thanks!
Felix
It looks even nesting the stop within an extra ask procedure in the same procedure doesn't help. However, if you need a quick fix I think you can replace the second foreach loop with a standalone procedure that contains the stop as a workaround. For example, this procedure follows a similar format to yours and the same problem comes up- as soon as stop is called the broader foreach is exited.
to nest-foreach-example
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
foreach ys [
y ->
ask turtles [
if y > x [
stop
]
]
print word x y
]
]
end
This prints out 11.
However, if you make a custom procedure to take the place of your "y" foreach loop, it works (with or without the ask turtles):
to nest-foreach-example-turtles
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
for-y x ys
]
end
to for-y [ x_ ys ]
foreach ys [
y ->
ask turtles [
if y > x_ [
stop
]
]
print word x_ y
]
end
Outputs:
11
21
22
31
32
33
41
42
43
44
I am trying to make a 2-dimensional matrix from a functor that creates each element, and store it as a flat Vec (each row concatenated).
I used nested map (actually a flat_map and a nested map) to create each row and concatenate it. Here is what I tried:
fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
where
F: Fn(usize, usize) -> T,
{
(0..m).flat_map(|y| (0..n).map(|x| f(x, y))).collect()
}
fn main() {
let v = make(5, 5, |x, y| x + y);
println!("{:?}", v);
}
Unfortunately, I get an error during compilation:
error[E0597]: `y` does not live long enough
--> src/main.rs:5:45
|
5 | (0..m).flat_map(|y| (0..n).map(|x| f(x, y))).collect()
| --- ^ - - borrowed value needs to live until here
| | | |
| | | borrowed value only lives until here
| | borrowed value does not live long enough
| capture occurs here
How does one use closures in nested maps? I worked around this issue by using a single map on 0..n*m, but I'm still interested in the answer.
In your case the inner closure |x| f(x,y) is a borrowing closure, which takes its environment (y and f) by reference.
The way .flat_map(..) works, it forbids you to keep a reference to y, which is not from the outer scope. Thus we need to have your closure take its environment by value, which is not a problem for y being a usize which is Copy:
(0..m).flat_map(|y| (0..n).map(move |x| f(x, y))).collect()
However, now another problem arises:
error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
--> src/main.rs:5:36
|
1 | fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
| - captured outer variable
...
5 | (0..m).flat_map(|y| (0..n).map(move |x| f(x,y))).collect()
| ^^^^^^^^ cannot move out of captured outer variable in an `FnMut` closure
Here, we are trying to move f as well into the closure, which is definitely not possible (unless m is 1, but the compiler cannot know that).
Since f is a Fn(usize, usize) -> T, we could just as well explicitly pass a & reference to it, and & references are Copy:
fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
where
F: Fn(usize, usize) -> T,
{
let f_ref = &f;
(0..m)
.flat_map(|y| (0..n).map(move |x| f_ref(x, y)))
.collect()
}
In this case, the closure takes its environment by value, and this environment is composed of y and f_ref, both of them being Copy, everything is well.
Adding to Levans's excellent answer, another way of defining the function would be
fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
where
F: Fn(usize, usize) -> T + Copy,
{
(0..m).flat_map(|y| (0..n).map(move |x| f(x, y))).collect()
}
Since we know that |x, y| x + y is a Copy type, f would get copied for every callback that flat_map invokes. I would still prefer Levans's way as this would not be as efficient as copying a reference.
I have a function that will parse the results of a DataReader, and I don't know how many items are returned, so I want to use a while..do loop to iterate over the reader, and the outcome should be a list of a certain type.
(fun(reader) ->
[
while reader.Read() do
new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
])
This is what I tried, but the warning I get is:
This expression should have type 'unit', but has type 'CityType'. Use 'ignore' to discard the result of the expression, or 'let'
to bind the result to a name.
So what is the best way to iterate over a DataReader and create a list?
you can use list comprehension:
[
while reader.Read() do
let d = new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
yield d
]
Here is one more example:
/// The squares of the first 10 integers
let squaresOfOneToTen = [ for x in 0..10 -> x*x ]
or
let squaresOfOneToTen = [ for x in 0..10 do yield x*x ]
You can also do it for sequences and arrays:
seq {
for i=1 to 9 do
for j=1 to 9 do
yield (i,j,i*j)
}
[| for i=1 to 100 do yield i*i |]
you can also yield a sub sequence in a sequence(yield!), here is an example using Project Euler 31.
Just to provide some additional information that may explain what is going on here - there are two ways of creating lists in F# and in both cases, you're writing something in square braces [ ... ] (which may be a bit confusing at first!)
List literals are used when you have a few expressions (known number of explicitly written expressions) and want to create a list containing the results of evaluating these expressions. For example:
[ 1; 2; 3; ] // list of constant expressions
[ 1+1; 2+2; 3+3 ] // creates list [ 2; 4; 6 ]
List comprehensions are used when you have some code that does something and generates list of elements (by producing elements during the calculation). This is what Yin Zhu uses in his answer. Some examples are:
[ yield 1; ] // generates singleton list [ 1 ]
[ yield 1; yield 2; ] // generates list with two elements
[ for x in 1 .. 10 do // iterates loop 10 times
yield x * x ] // ... generates element during every iteration
Advanced features
You can also use yield! to generate multiple elements at once:
[ yield! [ 1; 2 ] // generates a list containing [ 1; 2; 3; 4 ]
yield! [ 3; 4 ] ]
This can be used for writing recursive functions, so you could rewrite your code using recursion instead of loop (this would be useful if you needed to keep some state, but as your code looks currently, while is perfectly fine!)
let rec loop reader =
[ if reader.Read() then
yield new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1),
StateName=(reader.GetString 2))
yield! loop reader ]
This is a pattern that often appears in list comprehensions, so it is useful to know about it :-).
The following is a erlang function. I don't understand how lists:map function is used here.
Could someone please explain?
% perform M runs with N calls to F in each run.
% For each of the M runs, determine the average time per call.
% Return, the average and standard deviation of these M results.
time_it(F, N, M) ->
G = fun() -> F(), ok end,
NN = lists:seq(1, N),
MM = lists:seq(1, M),
T = lists:map(
fun(_) ->
T0 = now(), % start timer
[ G() || _ <- NN ], % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N % average time per call
end,
MM
),
{ avg(T), std(T) }.
Thanks.
also, I don't know the proper syntax when using this function. For example, I have a dummy() function take 1 parameter. I get an error while trying to time the dummy function.
moduleName:time_it(moduleName:dummy/1, 10, 100).
the above would evaluate to illegal expression.
Actually, now with the correct syntax, the function can be invoked correctly with:
moduleName:time_it(fun moduleName:dummy/1, 10, 100).
However, it will throw a exception saying invoking dummy function without passing any parameter. I think this line is the villain, [ G() || _ <- NN ], I have no idea how to fix it.
map is used here to execute the function
T0 = now(), % start timer
[ G() || _ <- NN ], % make N calls to F
1.0e-6*timer:now_diff(now(), T0)/N % average time per call
for each element of MM. map will return a new list of the same size, where each element of the new list is the result of applying the above function to the corresponding element of MM.
You can invoke time_it like:
moduleName:time_it(fun moduleName:dummy/1, 10, 100).
The purpose of lists:map in the time_it function is just to run the inner function M times. When you see this pattern:
L = lists:seq(1,M),
lists:map(fun(_)-> Foo() end, L)
It just means call Foo() again and again M times, and return the results of each call in a list. It actually makes a list of integers [1,2,3,...N] and then calls Foo() once for each member of the list.
The author of time_it does this same trick again, because time_it needs to call the function you give it N*M times. So inside the outer loop that runs M times they use a different technique to run the inner loop N times:
L = lists:seq(1,N),
[Foo() || _ <- L]
This has exactly the same result as the code above, but this time Foo is called N times.
The reason you are having trouble using time_it with your dummy function is that time_it takes a function with 0 parameters, not 1. So you need to make a dummy function and call it like this:
dummy() ->
%% do something here you want to measure
ok.
measure_dummy() ->
time_it(fun someModule:dummy/0, 10, 100).
If you have a function moduleName:dummy/1 you can do one of the following
If you can edit time_it/3, then make it call F(constant_parameter) instead of F(). I assume this is the case.
Otherwise, call M1:time_it(fun() -> M2:dummy(constant_parameter) end, N, M).
dummy will not be called directly, but only by F inside time_it.
results(N, F) when N >= 0 -> results(N, F, []).
results(0, _, Acc) -> lists:reverse(Acc);
results(N, F, Acc) -> results(N-1, F, [F() | Acc]).
repeat(0, F) -> ok;
repeat(N, F) when N > 0 ->
F(),
repeat(N-1, F).
With these:
T = results(M, fun () ->
T0 = now(),
repeat(N, G),
1.0e-6 * timer:now_diff(now(), T0)/N
end)
Make sense, now?