Void process(|Int -> Bool |[] functions)
{
functions.each |Int fun -> Bool, Int index|
{
echo(fun)
}
}
is giving me:
/Users/cbeust/fan/curry.fan(25,21): Unexpected type literal
This corresponds to the "Int" right after each.
What am I missing?
-- Cedric
brianTue 24 Jun 2008
The type specification for a function is |A, B, C->R| - you can't have more than one return type. In your case if iterating a list of functions typed as |Int->Bool|, then you probably want:
Void process(|Int->Bool|[] functions)
{
functions.each | |Int->Bool| fun, Int index |
{
echo(fun)
}
}
The |...| always wraps the function type, they aren't optional.
Let me know if that works - there might still be some parser bugs related to nesting of function types. You might be required to put a space between the two pipes in the closure (or maybe not).
cbeustTue 24 Jun 2008
Yes, that fixes it, thanks Brian.
I am a bit confused by the rules regarding closure declarations. Sometimes, the formal parameter is inside and sometimes, it's outside:
| Int -> Bool | f
| Int f -> Bool |
What's the rule?
-- Cedric
brianTue 24 Jun 2008
In this example |Int -> Bool | f, f is not a formal parameter - it is the parameter typed by |Int->Bool|, just like Str f is a parameter called f typed as Str. So the formals of a function signature are never outside.
A function type does not require the formal parameter names - they are optional. Consider these local variable declarations:
However a closure must specify a parameter name for each of its parameters. So there is a subtle difference between a function signature and a closure signature. Your original example is a little confusing because you have a closure whose first parameter is a function type:
||Int->Bool| fun, Int index| // ok
||Int f->Bool| fun, Int index| // ok
||Int->Bool| fun, Int| // not ok
||Int->Bool|, Int index| // not ok
Does that make sense? Because everything is wrapped inside |...| it tends to be much easier to read than C like function signatures once you get the hang of it.
cbeustTue 24 Jun 2008
Yes, this makes sense, thanks. For some reason, your description is exactly the understanding that I have but I failed to apply it to my own example. I'll blame the jet lag.
I agree that the || notation clarifies things quite a bit.
Groovy started this way and then they started playing with alternate syntaxes: removing the first | and then finally removing both and using -> to separate the closure parameters from its body. I think all these approaches are reasonably readable, so I don't have any preference. For the record, they removed the first bar because they noticed that it always happened right after an opening brace, which is not a problem in Fan.
cbeust Tue 24 Jun 2008
The following code:
is giving me:
This corresponds to the "Int" right after each.
What am I missing?
-- Cedric
brian Tue 24 Jun 2008
The type specification for a function is
|A, B, C->R|
- you can't have more than one return type. In your case if iterating a list of functions typed as|Int->Bool|
, then you probably want:The
|...|
always wraps the function type, they aren't optional.Let me know if that works - there might still be some parser bugs related to nesting of function types. You might be required to put a space between the two pipes in the closure (or maybe not).
cbeust Tue 24 Jun 2008
Yes, that fixes it, thanks Brian.
I am a bit confused by the rules regarding closure declarations. Sometimes, the formal parameter is inside and sometimes, it's outside:
What's the rule?
-- Cedric
brian Tue 24 Jun 2008
In this example
|Int -> Bool | f
, f is not a formal parameter - it is the parameter typed by|Int->Bool|
, just likeStr f
is a parameter called f typed asStr
. So the formals of a function signature are never outside.A function type does not require the formal parameter names - they are optional. Consider these local variable declarations:
However a closure must specify a parameter name for each of its parameters. So there is a subtle difference between a function signature and a closure signature. Your original example is a little confusing because you have a closure whose first parameter is a function type:
Does that make sense? Because everything is wrapped inside
|...|
it tends to be much easier to read than C like function signatures once you get the hang of it.cbeust Tue 24 Jun 2008
Yes, this makes sense, thanks. For some reason, your description is exactly the understanding that I have but I failed to apply it to my own example. I'll blame the jet lag.
I agree that the || notation clarifies things quite a bit.
Groovy started this way and then they started playing with alternate syntaxes: removing the first | and then finally removing both and using -> to separate the closure parameters from its body. I think all these approaches are reasonably readable, so I don't have any preference. For the record, they removed the first bar because they noticed that it always happened right after an opening brace, which is not a problem in Fan.
-- Cedric