#1194 Disallow () call operator on non-func types

vkuzkokov Thu 2 Sep 2010

First of all I'd expect to see

a(b)  =>  a.call(b)

in the list of shortcuts on Expressions page.

I found out that expression fn(5) works for Func exclusively if fn is local variable. Other classes should use (fn)(5).

Calling fn(5) if fn is a field doesn't work for both. I think it's because calling fields looks really weird.

I'm not sure whether these facts were discussed on forum but I believe they have to be reflected in docs.

katox Thu 2 Sep 2010

These topics are somewhat related - 895 and 592.

brian Thu 2 Sep 2010

Also just to be clear, you can't create your own class with a call method and then use it like a Func. I think in Scala you can do this with anything that has apply. So call is not actually a shortcut, its a special built-in syntax only for functions.

vkuzkokov Thu 2 Sep 2010

class A {
  Int call(Str s) { s.size }
  static Void main() {
    echo( A()("sdf") )  // compiles and outputs 3
  } 
}

Apparently, I can.

brian Thu 2 Sep 2010

Promoted to ticket #1194 and assigned to brian

Well that is interesting, I'm really surprised that works.

I am going to consider that a bug and open a ticket to have that result in a compiler error.

Although before I do that, is there any votes for allowing that behavior? I can definitely see where it might be useful, but personally I think the power to abuse that feature doesn't make it worthwhile.

helium Thu 2 Sep 2010

I vote for removing this feature.

yachris Fri 3 Sep 2010

This looks WAY WAY WAY too much like C++'s "operator()" thing, which is powerful(ish), but really confusing and ugly.

It's basically cleverness for cleverness's sake... it certainly isn't obvious when looking at code. And it's not getting rid of any substantial amounts of syntax.

I vote against.

tcolar Fri 3 Sep 2010

Against that too.

ivan Mon 6 Sep 2010

Really hard for me to decide whether I like it or not. After short thinking I found two cases when this feature probably can be useful:

  1. Overriding methods on instance level
    foo.doSomething = ShootInTheLeg(...)

    The same effect can be achieved by using Funcs, but this one above may be more safe, because there won't be any closures to another scope.

  2. Adding listeners for operations:
    foo.doSomething.addListener(listener)
    foo.doSomething(a, b)

Also I don't see any potential confusions for tooling support, resolving whether this is a method call or calling call method from field is the same level of complexity as deciding if foo.bar { ... } is calling method bar with closure arg, or calling method with of field bar.

Also this feature can be considered as named Func type, so I can declare:

mixin StrToInt { abstract Int call(Str int) }

and use it in places where I need this function. But there's one disadvantage - I can't pass it instead of Func to anywhere, for example I can't write [,].each(myStrToInt)

So my vote is +0.25

yachris Mon 6 Sep 2010

Sorry to be dense (*shut up* :-) but I don't understand #1 at all... could you give a concrete example?

For #2, is

foo.doSomething.addListener(listener)
foo.doSomething(a, b)

supposed to be something like an aspect? That is, is this setting up the listener to be called before (or after, or around) the doSomething call?

From my small amount of time spent with AspectJ, that's an awfully big can of worms to open.

brian Mon 6 Sep 2010

I'm going to say the safest thing for now is to make it an error. Although clever, I dislike how Scala uses () for indexed access in lists and such. The thing about this feature is we can always change our mind and allow it later (but not vise versa)

helium Mon 6 Sep 2010

Well, you can view an array as a function from the index to the value stored at that index, so that's perfectly valid. Back in the days when I programmed in BASIC array access was done with parenthesis, too, so it's somewhat familiar.

brian Wed 8 Sep 2010

Renamed from Calling call for local variable to Disallow () call operator on non-func types

brian Wed 8 Sep 2010

Ticket resolved in 1.0.55

The compiler will now report an error if you attempt to use () call operator on a non-function type.

changeset

Login or Signup to reply.