3

Example of Scala's "call be name":

def giveMeName(b: => String)

Java result:

public class some.package.CallByNameEx {
    public void giveMeName(scala.Function0<java.lang.String>);
    public some.package.CallByNameEx();
}

Example of Java's Functional Interface API:

void giveMeName(Supplier<String> b)

Java result:

public class some.package.SupplyEx {
    public some.package.SupplyEx();
    void giveMeName(java.util.function.Supplier<java.lang.String>);
}

Is there any major difference in how they get evaluated internally considering the javap result of both the above cases were almost identical

As per my current understanding, they both sort of use closures and evaluates the expression lazily. Please correct me if the understanding is wrong.

Jose Da Silva Gomes
  • 3,814
  • 3
  • 24
  • 34
6harat
  • 542
  • 6
  • 18

2 Answers2

2

You got it right, the call-by-name syntax is pretty much a shorthand allowing you to avoid the additional bureaucracy of dealing with passing a Function0 around.


Internally, b: => String will be represented by Function0 - just like b: () => String would be.

The difference is that by using the call-by-name, you can simply ignore the implementation detail of using Function0.

Let's see how it would look like with b: () => String:

def giveMeName(b: () => String): String = b.apply()

and the same again using call-by-name:

def giveMeName(b: => String): String = b

Pay attention to how nicely the boilerplate apply() call can be avoided.

So, it's a syntactic sugar, but not for Java's Functional Interfaces, but for Scala's native Function0

I wrote a bit more about that here: http://4comprehension.com/leveraging-lambda-expressions-for-lazy-evaluation-in-java/

Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
1

Can it be considered syntactic sugar? Yes, arguably. Of Java8's Functional Interface API? No.

Let's go by the definition in http://wiki.c2.com/?SyntacticSugar:

Features added to a language or other formalism to make it sweeter for humans, but which do not affect the expressiveness of the formalism (compare chrome). Used esp. when there is an obvious and trivial translation of the sugar feature into other constructs already present in the notation.

So Scala features can only be syntactic sugar for other Scala features, not for Java ones. In this case, def giveMeName(b: => String) is translated something like into def giveMeName(b: () => String). The "arguably" part is that translating the declaration is not enough: you need to translate all calls as well, and that the method is marked so you can't pass something of type () => String to def giveMeName(b: => String).

Is there any major difference in how they get evaluated internally considering the javap result of both the above cases were almost identical

In the result you show there's nothing to evaluate, and they will still be "almost identical" if you replace Supplier<String> by List<String>. Does that mean that call-by-name is syntactic sugar for List? Of course not.

But Scala () => String is semantically equivalent to Supplier<String> (which is not something you can see from javap), and because => String is equivalent to () => String

they both sort of use closures and evaluates the expression lazily

If "they" are the APIs you show, no, neither use closures themselves. You can pass closures to both (or not-closures).

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487