what does the brackets after function name do when calling a function in scala? - scala

When reading some scala code, i see something like fooString
but I couldn't find anything that expalins this sort of commands when calling a function.
I know we should define the parameter and expected return type in scala when defining a function or class. Consider this code:
def socketTextStream(
hostname: String,port: Int
): ReceiverInputDStream[String] = withNamedScope("socket text stream") {
socketStream[String](hostname, port, SocketReceiver.bytesToLines)
}
what [String] after "socketStream" do here and I wonder why there is another function( withNamedScope) after "=" here.

First, def socketTextStream(hostname: String, port: Int): ReceiverInputDStream[String] is declaring a method called socketTextStream which receives two inputs (host & port) and returns a ReceiverInputDStream which is a generic class, and in this case the result will be parameterized with the type String.
Then, = withNamedScope("socket text stream") { .. } means that the implementation of that method is call other method (withNamedScope) that takes a String (presumably a name) as its first argument, and a block (probably a by name parameter) as its second argument.
In this case, the two arguments are on separated parameters lists, which is called currying.
Finally, socketStream[String](hostname, port, SocketReceiver.bytesToLines) (which is the body of the block) is calling another method socketStream which is a polymorphic / generic method.
The [String] part is specifying that the type parameter of that method, is String. Maybe this information is redundant or maybe it is used to force an specific implicit, without the definition of such method is hard to tell.
Anyways, all here is basic syntax and structures of the language, all covered by the tour (which many people highlight for being too brief and just covering the basis of the language). Thus, I would recommend you to check more resources before continue with reading code.

Related

Why SAM rule doesn't work on parameterless method

// ok
val sam0: MySamWithEmptyParameter = () => 100
// doesn't work
// val sam1: MySamWithParameterless = () => 100
trait MySamWithEmptyParameter {
def receive(): Int
}
trait MySamWithParameterless {
def receive: Int
}
Why sam1 fails to override the receive method? The scalac compile both of traits to same code.
abstract trait TestSAM$MySamWithEmptyParameter extends Object {
def receive(): Int
};
abstract trait TestSAM$MySamWithParameterless extends Object {
def receive(): Int
};
SI-10555 talks exactly about this. This was a simple design decision to only support an explicit empty parameter list, even though the two compile down to an empty parameter list anyway.
The relevant part of the Specification says (emphasis mine):
the method m must have a single argument list;
This is indeed a bit awkward as eta expansion does work for methods with an empty parameter list.
Edit
Contacted the guys at Lightbend. Here is a response by Adrian Moors, Scala team lead:
The original reason was to keep the spec simple, but perhaps we should revisit. I agree it’s surprising that it works for def a(): Int, but not in your example.
Internally, methods that don’t define an argument list at all, and those that do (even if empty) are treated differently.
This has led to confusion/bugs before — to name just one: https://github.com/scala/scala-dev/issues/284.
In 2.13, we’re reworking eta-expansion (it will apply more aggressively, but ()-insertion will happen first). We’ve been back and forth on this, but the current thinking is:
0-ary methods are treated specially: if the expected type is sam-equivalent to Function0, we eta-expand; otherwise, () is inserted (in dotty, you are required to write the () explicitly, unless the method is java-defined) — I’m still not sure about whether we should ever eta-expand here
for all other arities, a method reference is eta-expanded regardless of the expected type (if there’s no type mismatch, this could hide errors when you refactor a method to take arguments, but forget to apply them everywhere. However, since functions are first-class values, it should be easy to construct them by simplify referring to a method value).
The upshot is that we can deprecate method value syntax (m _), since it’s subsumed by simply writing m. (Note that this is distinct from placeholder syntax, as in m(, _).)
(See also the thread around this comment: https://github.com/lampepfl/dotty/issues/2570#issuecomment-306202339)

Scala method definition with `functionName` : `dataType` = `functionName`

I have come across this new method definition. Need explanation what exactly happens here.
Parent trait
sealed trait Generic{
def name : String = name // what is the body of this function call?
def id : Int = id
def place : String = place
}
Child case classes
case class Capital(
countryName : String,
override val id: Int,
override val place:String
) extends Generic
warning: method place in trait Generic does nothing other than call itself recursively I get this warning message is there anything wrong in using these types of methods?
How exactly compiler treat these type of function calls def name : String = name?
Is it this call treats its body as its method name?
You are providing default implementations in the trait that are infinite loops, very much like in the following example:
def infiniteLoop: Unit = infiniteLoop
This is arguably the most useless and dangerous code that you could possibly put in a method of a trait. You could only make it worse by making it non-deterministic. Fortunately, the compiler gives you a very clear and precise warning:
warning: method place in trait Generic does nothing other than call itself recursively
"Is there anything wrong in using these types of methods"?: having unproductive infinite loops in your code is usually considered wrong, unless your goal is to produce as much heat as possible using computer hardware.
"How exactly compiler treat these type of function calls"?: Just like any other tail recursive function, but additionally it outputs the above warning, because it sees that it is obviously not what you want.
"Is it this call treats its body as its method name?": The body of each method declaration is what follows the =-sign. In your case, the otherwise common curly braces around the function body are omitted, and the entire function body consists only of the recursive call to itself.
If you don't want to have any unnecessary infinite loops around, simply leave the methods unimplemented:
sealed trait Generic{
def name: String
def id: Int
def place: String
}
This also has the additional advantage that the compiler can warn you if you forget to implement one of these methods in a subclass.
Ok, so in your trait you define methods body via recursion. Means that these methods, if not overridden (and they should not as soon as you have defined them somehow), will call itself recursively till StackOverflowError happens. For example, you did not override name method in Capital, so in this case you get StackOverflowError at runtime:
val c = Capital("countryName", 1, "place")
c.name
So, you are warned, that you have recursive definition. Trait is sealed, so at least it cannot be overridden in other places, but anyway, such definition is something like put mines on your road and rely on your memory, that you will not forget about them (and anybody else will be care enough to check trait definition before extending)

Scala - How to get a wrapped method's name? [duplicate]

I have a function foo which takes another function (say bar) as a parameter. Is there a way to get the function name of bar as a string inside foo?
No. See the difference between methods and functions. Methods aren't passed as parameters under the hood - they are expanded into function objects when being passed to some other method/function. These function objects are instances of anonymous, compiler-generated classes , and have no name (or, at least, being anonymous classes, have some mangled name which you could access using reflection, but probably don't need).
So, when you do:
def foo() {}
def bar(f: () => Unit) {}
bar(foo)
what actually happens in the last call is:
bar(() => foo())
Theoretically, though, you could find the name of the method that the function object you're being passed is wrapping. You could do bytecode introspection to analyze the body of the apply method of the function object f in method bar above, and conclude based on that what the name of the method is. This is both an approximation and an overkill, however.
I've had quite a dig around, and I don't think that there is. toString on the function object just says eg <function1>, and its class is a synthesised class generated by the compiler rather that something with a method object inside it that you might query.
I guess that if you really needed this there would be nothing to stop you implementing function with something that delegated but also knew the name of the thing to which it was delegating.

Scala - get function name

I have a function foo which takes another function (say bar) as a parameter. Is there a way to get the function name of bar as a string inside foo?
No. See the difference between methods and functions. Methods aren't passed as parameters under the hood - they are expanded into function objects when being passed to some other method/function. These function objects are instances of anonymous, compiler-generated classes , and have no name (or, at least, being anonymous classes, have some mangled name which you could access using reflection, but probably don't need).
So, when you do:
def foo() {}
def bar(f: () => Unit) {}
bar(foo)
what actually happens in the last call is:
bar(() => foo())
Theoretically, though, you could find the name of the method that the function object you're being passed is wrapping. You could do bytecode introspection to analyze the body of the apply method of the function object f in method bar above, and conclude based on that what the name of the method is. This is both an approximation and an overkill, however.
I've had quite a dig around, and I don't think that there is. toString on the function object just says eg <function1>, and its class is a synthesised class generated by the compiler rather that something with a method object inside it that you might query.
I guess that if you really needed this there would be nothing to stop you implementing function with something that delegated but also knew the name of the thing to which it was delegating.

When do I have to specify type <T> for IEnumerable extension methods?

I'm a bit confused about the use of all the IEnumerable<T> extension methods, intellisense is always asking for <T>, but I don't think it's necessary to specify <T> at all times.
Let's say I have the following:
List<Person> people = GetSomePeople();
How is this:
List<string> names = people.ConvertAll<string>(p=>p.Name).Distinct<string>().ToList<string>();
different from this:
List<string> names = people.ConvertAll<string>(p=>p.Name).Distinct().ToList();
I think the two lines of code above are sxactly the same, now the question:
How do I know when to specify <T> and when to skip it?
The simplest way is obviously to omit it and see if it compiles.
In practice, you can omit type parameters wherever they are inferred; and they can normally be inferred when they are used in the type of a method parameter than you specify. They cannot be inferred if they're used only in the return type of the method. Thus, for example, for Enumerable.Select<T>, T will be inferred from the type of first argument (which is of type IEnumerable<T>). But for Enumerable.Empty<T>(), will not be inferred, because it's only used in return type of the method, and not in any arguments (as there are none).
Note that the actual rules are more complex than that, and not all arguments are inferable. Say you have this method:
void Foo<T>(Func<T, T> x);
and you try to call it with a lambda:
Foo(x => x);
Even though T is used in type of argument here, there's no way to infer the type - since there are no type specifications in the lambda either! As far as compiler is concerned, T is the same type x is, and x is of type T...
On the other hand, this will work:
Foo((int x) => x);
since now there is sufficient type information to infer everything. Or you could do it the other way:
Foo<int>(x => x);
The specific step-by-step rules for inference are in fact fairly complicated, and you'd be best off reading the primary source here - which is C# language specification.
This feature is known as type inference. In your example, the compiler can automatically determine the generic argument type implicitly for you because in the method call to ConvertAll, the parameter lambda returns a string value (i.e. Name). So you can even remove the <string> part of ConvertAll call. The same is with Distict(), as ConvertAll returns a List<string> and the compiler can declare the generic argument for you.
As for you answer, when the compiler can determine the type itself, the generic argument is redundant and unnecessary. Most of the times, the only place where you need to pass the generic argument is the declaration, like, List<string> list = new List<string>();. You can substitute the first List<string> with var instead or when you are using templates as parameters in lambdas too.