14

I somehow found the call() method is on every function. Using this method I could change my if (callback != null) callback() to callback?.call().

So I tried to find the implementation and document of call(), but I couldn't. Is it just built-in method? What will be the implementation of this method? Function.apply() will be called inside it?

wurikiji
  • 327
  • 3
  • 12

1 Answers1

21

All Dart functions (objects which has a function type rather than an class/interface type) have a call method.

The call method has the same function type as the function itself, and it behaves exactly the same when you call it. You could even say that calling a function is implicitly calling its call method. And, not by coincidence, the specification actually does say that: If you write the function invocation e1(e2, e3), then the compiler checks if e1 has call method, and if so converts it to the method invocation e1.call(e2, e3).

Other Dart objects may have a call method too. It's just a normal method for interface types, but if class C has a call method like int call(int x) => ..., and c has type C, then c(e2, e3) is also converted to c.call(e2, e3). It has to be a call method, not just a call getter returning a function.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
lrn
  • 64,680
  • 7
  • 105
  • 121
  • 1
    For future reference, the Dart Language Specification, version 2.10 gives the details in 17.15.5. I was looking too. – Josef.B May 05 '21 at 00:05
  • Calling a function through "call" is slow. Wonders. – mezoni Jun 07 '21 at 09:27
  • 1
    That probably depends on what else your are doing. A quick benchmark I wrote up shows no significant difference between doing `f(i)` and `f.call(i)` when `f` has a function type. https://dartpad.dev/c42130fcee303bc7a342ebeef36429a6?null_safety=true – lrn Jun 07 '21 at 12:13
  • I think it even depends on what you are doing. Dart is a better Java, intentionally built for speed. It doesn't have reflection or anything dynamic like Java or Javascript. It compiles down to the same exact thing. – Michael Bushe Mar 16 '22 at 05:54
  • As far as I understand, the aforementioned spec section 17.15.5 explains how `e()` may get translated to `e.call()`, which is unrelated. The fact that every `Function` has a `.call` method is actually specified in 20.5 "Function Types". – Mr. Wonko Dec 07 '22 at 17:43