Collection of closures are saved with wrong parameter [duplicate] - groovy

In a loop I create 4 closures and add them to a list:
closureList = []
for (int i=0; i<4; i++) {
def cl = {
def A=i;
}
closureList.add(cl)
}
closureList.each() {print it.call()println "";};
This results in the following output:
4
4
4
4
But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?

Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.
You can either, change the loop into a closure based call:
closureList = (0..<4).collect { i ->
{ ->
def a = i
}
}
closureList.each { println it() }
Or create an extra variable that gets re-set every time round the loop, and use that:
closureList = []
for( i in (0..<4) ) {
int j = i
closureList << { ->
def a = j
}
}
closureList.each { println it() }
In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect

Related

Return two numbers in Q Sharp (Q#) (Quantum Development Kit)

So, basically, I did the tutorial to create a random number on the website of Microsoft Azure and now I am trying to add some functionalities, including their suggestion add a minimum number.
The initial code to generate just one number, max, is:
operation SampleRandomNumberInRange(max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
#EntryPoint()
operation SampleRandomNumber() : Int {
// let declares var which don't change during computation
let max = 50;
Message($"Sampling a random number between 0 and {max}: ");
return SampleRandomNumberInRange(max);
}
Everything works well. Now, I want to generate two numbers so I would like to create a function TwoSampleRandomNumbersInRange but I can't figure out how to make the function return a result such as "Int, Int", I tried a few things including the follow:
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
for idxBit in 1..BitSizeI(min) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output >= min and output <= max);
return output;
}
To generate two numbers, I tried this:
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : Int, Int {
//code here
}
...but the syntax for the output isn't right.
I also need the output:
set output = ResultArrayAsInt(bits);
to have two numbers but ResultArrayAsInt, as the name says, just returns an Int. I need to return two integers.
Any help appreciated, thanks!
The return of an operation has to be a data type, in this case to represent a pair of integers you need a tuple of integers: (Int, Int).
So the signature of your operation and the return statement will be
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : (Int, Int) {
// code here
return (integer1, integer2);
}
I found the answer to my own question, all I had to do was:
operation SampleRandomNumberInRange(min: Int, max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output >= min and output <= max);
return output;
}
#EntryPoint()
operation SampleRandomNumber() : Int {
// let declares var which don't change during computation
let max = 50;
let min = 10;
Message($"Sampling a random number between {min} and {max}: ");
return SampleRandomNumberInRange(min, max);
}
}

Eager interpolation with just a closure behaves like a lazy one?

As part of learning Groovy, I'm trying to explore all intricate possibilities provided by string interpolation.
One of my little experiments gave results that don't make sense to me, and now I'm wondering whether I've completely misunderstood the basic concepts of lazy and eager interpolation in Groovy.
Here's the code I ran:
def myVar1 = 3
// An eager interpolation containing just a closure.
def myStr = "${{->myVar1}}"
print ("Just after the creation of myStr\n")
print (myStr as String)
myVar1 += 1 // Bump up myVar1.
print ("\nJust after incrementing myVar1\n")
print (myStr as String)
Here's the output I got:
Just after the creation of myStr
3
Just after incrementing myVar1
4
Clearly, the closure has been invoked a second time. And the only way the closure could have been re-executed is by the containing interpolation getting re-evaluated. But then, the containing interpolation is, by itself, not a closure, though it contains a closure. So then, why is it getting re-evaluated?
This is how GString.toString() method is implemented. If you take a look at the source code of GString class, you will find something like this:
public String toString() {
StringWriter buffer = new StringWriter();
try {
writeTo(buffer);
}
catch (IOException e) {
throw new StringWriterIOException(e);
}
return buffer.toString();
}
public Writer writeTo(Writer out) throws IOException {
String[] s = getStrings();
int numberOfValues = values.length;
for (int i = 0, size = s.length; i < size; i++) {
out.write(s[i]);
if (i < numberOfValues) {
final Object value = values[i];
if (value instanceof Closure) {
final Closure c = (Closure) value;
if (c.getMaximumNumberOfParameters() == 0) {
InvokerHelper.write(out, c.call());
} else if (c.getMaximumNumberOfParameters() == 1) {
c.call(out);
} else {
throw new GroovyRuntimeException("Trying to evaluate a GString containing a Closure taking "
+ c.getMaximumNumberOfParameters() + " parameters");
}
} else {
InvokerHelper.write(out, value);
}
}
}
return out;
}
Notice that writeTo method examines what the values passed for interpolation are, and in case of closure, it invokes it. This is the way GString handles lazy-evaluation of interpolated values.
Now let's take a look at a few examples. Let's assume we want to print a GString and interpolate a value returned by some method call. This method will also print something to the console, so we can see if the method call was triggered eagerly or lazily.
Ex.1: Eager evaluation
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def str = "${loadValue(var++)}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
This method returns value 1
Starting the loop...
1
1
1
1
1
Loop ended...
The default eager behavior. The method loadValue() was invoked before we have printed out str to the console.
Ex.2: Lazy evaluation
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def str = "${ -> loadValue(var++)}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
Starting the loop...
This method returns value 1
1
This method returns value 2
2
This method returns value 3
3
This method returns value 4
4
This method returns value 5
5
Loop ended...
In the second example, we take advantage of lazy evaluation. We define str with a closure that invokes loadValue() method and this invocation is executed when we explicitly print the str to the console (to be more specific - when the GString.toString() method gets executed).
Ex.3: Lazy evaluation and closure memoization
class GStringLazyEvaluation {
static void main(String[] args) {
def var = 1
def closure = { -> loadValue(var++)}
def str = "${closure.memoize()}"
println "Starting the loop..."
5.times {
println str
}
println "Loop ended..."
}
static Integer loadValue(int val) {
println "This method returns value $val"
return val
}
}
The output:
Starting the loop...
This method returns value 1
1
1
1
1
1
Loop ended...
And here is the example you most probably look for. In this example, we still take advantage of lazy evaluation thanks to the closure parameter. However, in this case, we use closure's memoization feature. The evaluation of the string is postponed to the first GString.toString() invocation and closure's result gets memorized, so the next time it gets called it returns the result instead of re-evaluating the closure.
What is the difference between ${{->myVar1}} and ${->myVar1}?
As it was mentioned earlier, GString.toString() method uses GString.writeTo(out) that checks if the given placeholder stores a closure for a lazy evaluation. Every GString instance store placeholder values in the GString.values array and it gets initialized during GString initialization. Let's consider the following example:
def str = "${myVar1} ... ${-> myVar1} ... ${{-> myVar1}}"
Now let's follow GString.values array initialization:
${myVar1} --> evaluates `myVar1` expression and copies its return value to the values array
${-> myVar1} --> it sees this is closure expression so it copies the closure to values array
${{-> myVar1}} --> evaluates `{-> myVar1}` which is closure definition expression in this case and copies its return value (a closure) to the values array
As you can see, in the 1st and 3rd example it did exactly the same - it evaluated the expression and stored it in the GString.values array of type Object[]. And here is the crucial part: the expression like {->something} is not a closure invocation expression. The expression that evaluates the closure is
{->myVar1}()
or
{->myVar1}.call()
It can be illustrated with the following example:
def str = "${println 'B'; 2 * 4} ${{ -> println 'C'; 2 * 5}} ${{ -> println 'A'; 2 * 6}.call()}"
println str
Values initialization is as follows:
${println 'B'; 2 * 4} ---> evaluates the expression which prints 'B' and returns 8 - this value is stored in values array.
${{ -> println 'C'; 2 * 5}} ---> evaluates the expression which is nothing else than creation of a closure. This closure is stored in the values array.
${{ -> println 'A'; 2 * 6}.call()}" ---> evaluates the expression which creates a closure and then calls it explicitely. It prints 'A' and returns 12 which is stored in the values array at the last index.
That is why after GString object initialization we end up with values array like:
[8, script$_main_closure1, 12]
Now, the creation of this GString caused a side effect - the following characters shown on the console:
B
A
This is because the 1st and the 3rd values evaluation invoked println method call.
Now, when we finally call println str which invokes GString.toString() method, all values get processed. When the interpolation process starts it does the following:
value[0] --> 8 --> writes "8"
value[1] --> script$_main_closure1 --> invoke script$_main_closure1.call() --> prints 'C' --> returns 10 --> 10 --> writes "10"
value[2] --> 12 --> writes "12"
That is why the final console output looks like this:
B
A
C
8 10 12
This is why in practice expressions like ${->myVar1} and ${{->myVar1}} are similar. In the first case GString initialization does not evaluate the closure expression and puts it directly to the values array, in the second example placeholder gets evaluated and the expression it evalutes creates and returns the closure which then gets stored in the values array.
Note on Groovy 3.x
If you try to execute the expression ${{->myVar1}} in Groovy 3.x you will end up with the following compiler error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during conversion: java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.groovy.parser.antlr4.AstBuilder.lambda$visitGstring$28(AstBuilder.java:3579)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.apache.groovy.parser.antlr4.AstBuilder.visitGstring(AstBuilder.java:3591)
at org.apache.groovy.parser.antlr4.AstBuilder.visitGstring(AstBuilder.java:356)
at org.apache.groovy.parser.antlr4.GroovyParser$GstringContext.accept(GroovyParser.java:4182)
at groovyjarjarantlr4.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:20)
at org.apache.groovy.parser.antlr4.AstBuilder.visit(AstBuilder.java:4287)
.....
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:565)
at org.codehaus.groovy.tools.FileSystemCompiler.compile(FileSystemCompiler.java:72)
at org.codehaus.groovy.tools.FileSystemCompiler.doCompilation(FileSystemCompiler.java:240)
at org.codehaus.groovy.tools.FileSystemCompiler.commandLineCompile(FileSystemCompiler.java:163)
at org.codehaus.groovy.tools.FileSystemCompiler.commandLineCompileWithErrorHandling(FileSystemCompiler.java:203)
at org.codehaus.groovy.tools.FileSystemCompiler.main(FileSystemCompiler.java:187)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:114)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:136)
1 error

Groovy find the last iteration inside a cloure?

In groovy how to find the last iteration inside the closure.
def closure = { it->
//here I need to print last line only
}
new File (file).eachLine{ closure(it)}
Need to find inside the closure iteration.
Update 1:
Instead of reading a file, In Common How can i find the last iteration inside the closure ?
def closure = { it->
//Find last iteration here
}
I guess you need eachWithIndex:
def f = new File('TODO')
def lines = f.readLines().size()
def c = { l, i ->
if(i == lines - 1) {
println "last: $i $l"
}
}
f.eachWithIndex(c)
Of course in case of big files you need to count lines efficiently.

Iterate and print content of groovy closures

In a loop I create 4 closures and add them to a list:
closureList = []
for (int i=0; i<4; i++) {
def cl = {
def A=i;
}
closureList.add(cl)
}
closureList.each() {print it.call()println "";};
This results in the following output:
4
4
4
4
But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?
Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.
You can either, change the loop into a closure based call:
closureList = (0..<4).collect { i ->
{ ->
def a = i
}
}
closureList.each { println it() }
Or create an extra variable that gets re-set every time round the loop, and use that:
closureList = []
for( i in (0..<4) ) {
int j = i
closureList << { ->
def a = j
}
}
closureList.each { println it() }
In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect

Groovy: Detecting when being passed arrays

The function f in the following code simply attempts to print out it's arguments and how many it receives. However, it expands array parameters (but not arraylists) as illustrated on the line f(x) // 3. Is there anyway to get f not to expand array parameters, or alternatively at the very least detect that it has happened, and perhaps correct for it. The reason for this is because my "real" f function isn't as trivial and instead passes it's parameters to a given function g, which often isn't a variable parameter function which instead expects an array directly as an argument, and the expansion by f mucks that up.
def f = {
Object... args ->
print "There are: ";
print args.size();
println " arguments and they are: ";
args.each { println it };
println "DONE"
}
def x = new int[2];
x[0] = 1;
x[1] = 2;
f(1,2); // 1
f([1,2]); // 2
f(x); // 3
I doubt there is any clean solution to this, as it behaves as Java varargs. You may test the size of the array inside the closure, or, as in Java, use a method overload:
public class Arraying {
public static void main(String[] args) {
// prints "2"
System.out.println( concat( new Object[] { "a", "b" } ) );
// prints "a". Commenting the second concat(), prints "1"
System.out.println( concat( "a" ) );
// prints "3"
System.out.println( concat( "a", "b", "c" ) );
}
static String concat(Object... args) {
return String.valueOf(args.length);
}
static String concat(Object obj) { return obj.toString(); }
}
If you comment the concat(Object obj) method, all three methods will match the concat(Object... args).
You can use a label for the argument as follow:
def f = {
Object... args ->
print "There are: ";
print args.size();
println " arguments and they are: ";
args.each { println it };
println "DONE"
}
def x = new int[2];
x[0] = 1;
x[1] = 2;
f(1,2); // 1
f([1,2]); // 2
f(a:x); // <--- used label 'a', or anything else
then the output is:
There are: 2 arguments and they are:
1
2
DONE
There are: 1 arguments and they are:
[1, 2]
DONE
There are: 1 arguments and they are:
[a:[1, 2]]
DONE

Resources