Apply method usage

I am seeing different usages of apply method, to name few

array accessing element
method invocations
constructors
etc…

Every time, I see a new patterns, I need to take a wild guess or take the assumption as guaranteed that apply method is triggered somehow.

But, are not there a set of specific rules which confirm the where to use and where not use the apply method

Not sure what your question is.

If it is about the rules of syntactic sugar, then any expression of the form foo(bar) is either calling a method foo or calling the apply method on foo.
They look the same because the idea is that you should think of apply as calling (applying) a function.

If you are asking when or not use apply when design new classes, then ask yourself: “is this operation the most fundamental one of this type? Does it make sense to think that instances of this class are like functions from X to Y?”

In any case, AFAIK, there is no standard rule about when or not using apply; Some people like to write concise and elegant code, thus foo(bar) looks nice for them. Some others prefer longer but more descriptive names, thus they would rather foo.baz(bar)

1 Like

hmm, that is where it is getting more complicated as to when to use and when not to use since there are no standard rules . And, to complicate it more, since it is not mentioned explicitly as in foo(bar) rather than foo.apply(bar).
Would you mind listing me some common patters where the apply is used frequently - some of them I listed here

  • Function invocations
  • Accessing Element from Array

Would you mind listing me some common patters where the apply is used frequently.

Only one, and you already mentioned it: “Function invocation”.
The thing is that in a functional language you can think of many things as functions.

  • An Array[T] is basically a (partial) function from Int to T.
  • A companion object of some type T is, usually, a function from C to T (where C are the types of the constructor parameters).
  • A Set[T] is basically a function from T to Boolean.
  • A Map[K, V] is basically a (partial) function from K to V.
  • etc.

So, as I said before if you can think of a class as a function then apply would be a valid choice.
In any case, if you still find it confusing, you can totally decide not to use it, again as I said, many people would prefer that.
Also, for what I have seen, except for companion objects (and the partially apply type trick, but that is an advanced use case you shouldn’t care for now) most people do not write custom apply methods. And the ones in the stdlib are pretty straight forward and known.

A simple use of apply is to define it on an Object. This lets you call the Object as if the object itself was a function.

object Greet {

  • def apply(name: String): String = {*
  • “Hello %s”.format(name)*
  • }*
    }

Greet(“Sam”)

Below are the different usages of apply() functions,

1) Automatic Apply Functions for Case Class Companion Objects

Suppose we have Person class as follows,

case class Person(name: String, age: Integer, favColor: String)

We can call create object of this class as follows,

val p0 = new Person(“Frank”, 23, “Blue”)

  •      OR*
    

val p0 = Person.apply(“Frank”, 23, “Blue”)

2) Using Apply() as a clever class builder

case class Company(name: String)

class Person(val name: String) {}

object Person {

  • def apply(name: String): Company = new Company(name)*
    }
    val c = Person(“Bob”)

3) Apply Functions are used for Anonymous Functions

val func = (x: String) => “hello %s”.format(x)
func(“world”)

4) Put an apply function in a class (not an object!)

class Amazing {

  • def apply(x: String) = “Amazing %s!”.format(x)*
    }
    val amazing = new Amazing()
    amazing(“world”)