static Void main()
{
m := |Obj->Void| { echo(it)}
}
This dies with the error Invalid use of "it" outside of it-block . What am I doing wrong? Since I didn't specify a name for the parameter, shouldn't it have worked?
kaushikSat 16 Jan 2010
IDK if I am qualified to answer this but .. here goes...
it blocks are basicaly used in conjuction with method invocation. It's a convinient(and less-noisy) way to invoke a function that takes a closure with one parameter ..
For eg., In you code if you had a function like this..
Void func(|Obj| code){
//body
}
You can invoke it in a regular way like this
func |Obj obj|{
echo(obj)
}
.. or you can use it blocks to do it more elegantly like this..
func{
echo(it) //it is just obj
}
..but you cannot use both these as..
func|Obj obj|{
echo(it) //this won't compile.. since you already gave the parameter a name 'obj'
}
Hope that answers your question
furySat 16 Jan 2010
Yeah, but I didn't name the parameter in the example above.Even if I change the code to:
They omit a function signature and are declared only with curly braces
So I don't think your example is a valid (supported) closure declaration.
furySat 16 Jan 2010
I noticed that. However, this doesn't seem like valid syntax either:
m := { echo(it) }
alexlamslSat 16 Jan 2010
I don't have the compiler with me right now, but how about:
|Obj| m := { echo(it) }
OT - the last bullet point in that section of the docs:
...outside of its constructor
Is that intentional formatting around its? :-O
furySat 16 Jan 2010
Doesn't work. It says: Expected expression, not "{"
alexlamslSat 16 Jan 2010
I'm afraid this is out of my hands then :-/
Let's wait for the masters to wake up and enlighten us both.
kaushikSat 16 Jan 2010
m := |Obj| { echo(it) } m(20) it still gives the same error. Is it unusable with closures?
As far as I know, it blocks can be used only with method invocations. Why would you want to have "it", when you have already named it. why not just use
m := |Obj o|{
echo(o)
}
I believe that it blocks were introduced to simplify "invocation" of certain kinds of methods rather than simplifying the closures declaration itself.. But yeah.. Lets wait for the masters to enlighten all 3 of us
brianSat 16 Jan 2010
Closures use the |...| {...} syntax.
It-blocks have special restrictions:
they cannot use the |...| syntax
they must be appended to a method which takes a function of 1 or more params
they cannot use the return statement
they have the implicit it parameter
alexlamslSun 17 Jan 2010
they must be appended to a method which takes a function of 1 or more params
Would it be a good idea to add that point to the docs as well?
mslSun 17 Jan 2010
they must be appended to a method which takes a function of 1 or more params
What happens with a method that takes 2 (or more) args if you cannot use the |...| syntax to specify them?
DanielFathSun 17 Jan 2010
I think it tries to take the leftmost argument.
brianSun 17 Jan 2010
Functions can accept fewer args than the declaration - see Func Arity
DanielFathSun 17 Jan 2010
So, I was right. When you try to use it-block on a function that takes multiple parameters (like map.each |Obj value, Obj key|) it will take the leftmost argument (in this case value).
brianSun 17 Jan 2010
So, I was right. When you try to use it-block on a function that takes multiple parameters (like map.each |Obj value, Obj key|) it will take the leftmost argument (in this case value).
Exactly, in many cases the Fantom API will provide more arguments then you need but you can still use an it-block to use just the first value:
fansh> ["a", "b", "c"].each { echo(it) }
a
b
c
fansh> ["a", "b", "c"].findAll { it <= "b" }
[a, b]
fansh>
fury Sat 16 Jan 2010
Suppose I have this code:
This dies with the error Invalid use of "it" outside of it-block . What am I doing wrong? Since I didn't specify a name for the parameter, shouldn't it have worked?
kaushik Sat 16 Jan 2010
IDK if I am qualified to answer this but .. here goes...
it blocks are basicaly used in conjuction with method invocation. It's a convinient(and less-noisy) way to invoke a function that takes a closure with one parameter ..
For eg., In you code if you had a function like this..
You can invoke it in a regular way like this
.. or you can use it blocks to do it more elegantly like this..
..but you cannot use both these as..
Hope that answers your question
fury Sat 16 Jan 2010
Yeah, but I didn't name the parameter in the example above.Even if I change the code to:
it still gives the same error. Is it unusable with closures?
alexlamsl Sat 16 Jan 2010
From the docs
So I don't think your example is a valid (supported) closure declaration.
fury Sat 16 Jan 2010
I noticed that. However, this doesn't seem like valid syntax either:
alexlamsl Sat 16 Jan 2010
I don't have the compiler with me right now, but how about:
OT - the last bullet point in that section of the docs:
Is that intentional formatting around
its
? :-Ofury Sat 16 Jan 2010
Doesn't work. It says: Expected expression, not "{"
alexlamsl Sat 16 Jan 2010
I'm afraid this is out of my hands then :-/
Let's wait for the masters to wake up and enlighten us both.
kaushik Sat 16 Jan 2010
As far as I know, it blocks can be used only with method invocations. Why would you want to have "it", when you have already named it. why not just use
I believe that it blocks were introduced to simplify "invocation" of certain kinds of methods rather than simplifying the closures declaration itself.. But yeah.. Lets wait for the masters to enlighten all 3 of us
brian Sat 16 Jan 2010
Closures use the
|...| {...}
syntax.It-blocks have special restrictions:
|...|
syntaxreturn
statementit
parameteralexlamsl Sun 17 Jan 2010
Would it be a good idea to add that point to the docs as well?
msl Sun 17 Jan 2010
What happens with a method that takes 2 (or more) args if you cannot use the
|...|
syntax to specify them?DanielFath Sun 17 Jan 2010
I think it tries to take the leftmost argument.
brian Sun 17 Jan 2010
Functions can accept fewer args than the declaration - see Func Arity
DanielFath Sun 17 Jan 2010
So, I was right. When you try to use it-block on a function that takes multiple parameters (like
map.each |Obj value, Obj key|
) it will take the leftmost argument (in this case value).brian Sun 17 Jan 2010
Exactly, in many cases the Fantom API will provide more arguments then you need but you can still use an it-block to use just the first value: