In Scala we can define functions/methods inside other functions/methods in same class, and those functions are locally scoped to the functions/methods they are defined to, unable to access outside of from the function they are defined inside. Would that make those locally defined functions private access specifier in Scala?
=> is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).
In scala, functions are first class values. You can store function value, pass function as an argument and return function as a value from other function. You can create function by using def keyword. You must mention return type of parameters while defining function and return type of a function is optional.
public, private and protected are the three access modifiers used in Scala. Include the keywords private/protected/public in the definition of class, object or package to enforce the corresponding scope. If none of these keywords are used, then the access modifier is public by default.
A method is a function defined in a class and available from any instance of the class. The standard way to invoke methods in Scala (as in Java and Ruby) is with infix dot notation, where the method name is prefixed by the name of its instance and the dot ( . )
This chapter takes you through the Scala access modifiers. Members of packages, classes or objects can be labeled with the access modifiers private and protected, and if we are not using either of these two keywords, then access will be assumed as public. These modifiers restrict accesses to the members to certain regions of code.
Public: There is no public keyword in Scala. The default access level (when no modifier is specified) corresponds to Java’s public access level.We can access these anywhere. Writing code in comment? Please use ide.geeksforgeeks.org , generate link and share the link here.
Function name in Scala can have characters like +, ~, &, –, ++, \, / etc. parameter_list: In Scala, comma-separated list of the input parameters are defined, preceded with their data type, within the enclosed parenthesis. return_type: User must mention return type of parameters while defining function and return type of a function is optional.
A private member is visible only inside the class or object that contains the member definition. In Scala, the access (new Inner). f () is illegal because f is declared private in Inner and the access is not from within class Inner.
Those functions are basically local variables, and as such don't have access modifiers. There's no real need to give them modifiers since the method inside which they are defined is the only place where they can be accessed, and they're only used in a very small part of your application. I suppose they are private by default, if you take private to mean that they can only be accessed in the lowest scope they are in.
As @Luis Miguel Mejía Suárez and @Mario Galic pointed out, these local/nested functions get turned into private (final) methods in the same class. So in a way, yes, they are private
(to the class they are in, not the enclosing method), but you cannot actually access them from other methods in the same class without using reflection or something else.
Executing scalac -Xshow-phases
outputs compiler phases and the following seems interesting
lambdalift 17 move nested functions to top level
For example, running scalac -Xprint:lambdalift
on
class O {
def f() = {
def nested() = 42
nested()
}
}
outputs on my machine with Scala 2.13.2 something like
class O {
def f(): Int = nested();
private def nested(): Int = 42;
}
where we see nested method became private member method of the enclosing class. You could try exploring what happens for inner functions using the same technique.
On language level according to Scala specification there are only the following access modifiers
https://scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#modifiers
<no modifier>
private
private[C]
private[this]
protected
protected[C]
protected[this]
So on language level the answer for your question is that there is no access modifier specific for nested methods.
On implementation level there are plenty of modifiers and flags (some of them are access modifiers)
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/Flags.scala
PROTECTED
PRIVATE
LOCAL
SEALED
METHOD
...
We can peep on compiler if we create an annotation
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
@compileTimeOnly("enable macro paradise")
class printMethodModifiers extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro PrintMethodModifiersMacro.impl
}
object PrintMethodModifiersMacro {
def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
val traverser = new Traverser {
override def traverse(tree: Tree): Unit = {
tree match {
case q"${mods: Modifiers} def $_[..$_](...$_): $_ = $_" =>
println(s"tree=$tree, mods.flags=${mods.flags}")
case _ => ()
}
super.traverse(tree)
}
}
traverser.traverse(annottees.head)
q"..$annottees"
}
}
and use it to traverse the tree of class
@printMethodModifiers
class O {
def f() = {
def nested() = 42
nested()
}
}
//Warning:scalac: tree=def <init>() = {
// super.<init>();
// ()
//}, mods.flags=0
//Warning:scalac: tree=def f() = {
// def nested() = 42;
// nested()
//}, mods.flags=0
//Warning:scalac: tree=def nested() = 42, mods.flags=0
So when macro annotations are expanded in typer
phase there is no difference in flags for methods and nested methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With