#1197 passing closure as |->|

vkuzkokov Mon 6 Sep 2010

In F4 Fantom IDE JIRA I found issue dedicated to compiler's behavior on passing closure as last argument or generating with-call. That issue offers two examples.

Example 1:

class A 
{ 
  static Int test(|->| f) { 0 }

  static Void main(Str[] args) 
  { 
    test { } // error: Invalid args test(|->sys::Void|), not () 
  } 
}

Example 2:

class A 
{ 
  static Void test(|->|? f := null) { 0 } 

  static Void main(Str[] args) 
  { 
    test { } // error: Cannot apply it-block to Void expr 
  }
}

Both examples will pass closures to function if we change signature from |->| to |Obj->| (actually, any number of positive arguments of any types will do). Adding explicit type test |->| { } will help as well.

This might be justified by the fact that it won't make sense within these closures. But I would rather expect closures where it is forbidden in case inferred function type has no arguments.

brian Mon 6 Sep 2010

test { } // error: Cannot apply it-block to Void expr

The issue here that technically that is compiled as:

test().with(|it| { })

vkuzkokov Mon 6 Sep 2010

The issue here that technically that is compiled as:

test().with(|it| { })

The point here is that { } wasn't passed as argument (neither required, nor optional). The fact that { } can't be passed as |->| is not much obvious.

The question here is: can closure with no explicit type be passed as function with no args if this closure doesn't reference it?

brian Tue 7 Sep 2010

The question here is: can closure with no explicit type be passed as function with no args if this closure doesn't reference it?

You can use an it-block anytime a function type is required with at least parameter. The first parameter is bound to the keyword it. However if the function type doesn't have parameters, then you can't use an it-block (since there is nothing for it to bind too).

Example:

Void a(|Int, Int| f) { f(3, 2) }
Void b(|Int| f) { f(2) }
Void c(|->| f) { f() }

Void main() 
{
  a { echo(it) }   // will print 3
  b { echo(it) }   // will print 2
  c { echo(it) }   // compile time error
}

Login or Signup to reply.