Why can't I write println "Hello world" in Scala? - scala

I'm pretty new to Scala, but I thought that one of the strengths of the language was to remove the ceremony, like parenthesis and dots, that exists in for instance Java. So I was pretty confused when I discovered that I can write for instance
str1 equals str2
but not
println "Hello world"
I have surmised that it has something to do with that the first example has three "parts", but the second has only two, but I'm struggling to understand why it is so.

When there are only two parts, the expression is seen as method invocation. I.e. the only possibility for
println "Hello, world"
would be
println."Hello, world"
which of course does not make much sense here. (***** see below for an addition)
If you like, however, you can write Console println "Hello, World" to resolve the ambiguity.
It doesn’t look that ambigus in the string example, a string could hardly be a method name, but think of the following:
class B
val b = new B
object A {
def apply(myB: B) { print("apply") }
def b { print("b") }
}
Now, when writing A b, what do I get. How should it be interpreted? It turns out that:
A b // "b"
A.b // "b"
A(b) // apply
So, there is a clear rule what to do in a two part expression. (I hope nobody starts splitting hairs about apply and real method invocation…)
Addition
With the advent of dynamic classes, you can toy around a little and define the following
object println extends Dynamic {
def typed[T] = asInstanceOf[T]
def applyDynamic(name: String)(args: Any*) = Console.println(name)
}
And now look!, no parentheses:
println `Hello, world` // prints, "Hello, world"
Of course, please don’t do that in front of children or in real-life code.

You could rewrite your second example with three "parts", in which case it would compile without parentheses:
Predef println "Hello world"
(Just for illustration purposes -- #Debilski's answer is perfect!)

Related

Calling methods with parameters without using parentheses

I am using the following implicit class in order to call a function which would otherwise take parameters without having to write the parameters in brackets:
scala> implicit class Print(string: String) {
| def echo: Unit = Console.println(string)
| }
defined class Print
scala> "Hello world" echo
Hello world
However while this works, I don't really like how it looks and my goal is to get the method call in front of the input variable as I think it reads better.
Is there any simple way, without relying on external libraries, to be able to call a method before supplying the parameters and without needing brackets? Implicit classes are what I've been using so far but that doesn't have to be the final solution.
What I would like to type instead of "Hello world" echo:
scala> echo "Hello world"
Alternatives I have tried:
Object with apply method
Requires parentheses
object echo {
def apply(string: String): Unit = Console.println(string)
}
echo "Hello world" // Error: ';' or newline expected
extending Dynamic [see here]
Doesn't seem to work in my version of Scala
Special characters [see here]
Looks ugly and not what I am looking for
Scalaz [see here]
Looks to do basically what my implicit class solution does, and I don't want any external dependencies.
EDIT
This answer has been pointed to as a potential solution, but again it doesn't address my issue as it relies on Dynamic to achieve a solution. As previously mentioned, Dynamic does not solve my problem for a couple of reasons:
It behaves funnily
If you define a val and try to println that val, it gives you back the val's name and not its value (as pointed out by #metaphori):
object println extends Dynamic {
def typed[T] = asInstanceOf[T]
def selectDynamic(name: String) = Console.println(name)
}
val x = "hello"
println x // prints: x
The specific example linked to did not work when I tried to recreate it - it still gave the ';' or newline expected error
If I just misunderstood how to implement it then I would appreciate a scalafiddle demonstrating that this solution solves my problem and will happily concede that this question is a duplicate of the previously mentioned answer, but until then I do contest it.
AFAIK only way to do something similar to what you want is extending Dynamic like this:
object println extends Dynamic {
def typed[T] = asInstanceOf[T]
def selectDynamic(name: String) = Console.println(name)
}
and using it with:
println `Hello World`
edit: of course you need to enable related features either by adding compiler parameters -language:postfixOps and -language:dynamics or by importing scala.language.dynamics and scala.language.postfixOps
You cannot achieve
echo "str"
since Scala is not e.g. Ruby: it syntactically requires that function invocations use parentheses.
It is not a matter of semantics or how things are implemented or what techniques are used: here is the parser that complains.
The point is that x y is actually interpreted as x.y, which means that y must be a method.
Refer to the Scala Language Specification, section 6.6 Function Applications:
SimpleExpr ::= SimpleExpr1 ArgumentExprs
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
| [nl] BlockExpr
Exprs ::= Expr {‘,’ Expr}
I do not like the trick of #hüseyin-zengin since it leverages dynamic method invocations, and also does not work as expected:
val x = "hello"
println x // prints: x
To partially achieve what you like you need to use infix operator notation
object run { def echo(s: String) = println(s) }
run echo "hello" // OK
run.echo "hello" // error: ';' expected but string literal found.
You may also use a symbol to reduce "typing" overhead (though may be perceived weirdly):
object > { def echo(s: String) = println(s) }
> echo "hello" // OK

Why is this Scala code with assignment of a val in a parameter working?

object Main {
def main(args: Array[String])
{
val x = 10
print(x="Hello World")
print(x)
}
}
output : Hello World10
As we know, in Scala a val cannot be reassigned or changed, but here x is changing to
Hello World
while printing.
Explanation is kind of unexpected: print has a parameter named x. Using x = ... uses the named argument, therefore print(x="Hello World") is the same as print("Hello World").
See Scala Predef docs or Predef.scala source:
object Predef /*....*/ {
/*....*/
def print(x: Any) = Console.print(x)
/*....*/
}
Note: this was already discussed in Scala Internal mailing list:
Scala currently tries to be smart about treating "x = e" as a named argument or an assignment
... This can be surprising to the user ....
Proposal: we deprecate assignments in argument lists
There also exists an issue SI-8206 for this, the change was probably implemented in issue 426 for Scala 2.13.
Your code will still compile after deprecation, with the same meaning. The change will be no one (at least no one sufficiently familiar with the language specs / implementation) should expect it to be interpreted as assignment any more.

Map an instance using function in Scala

Say I have a local method/function
def withExclamation(string: String) = string + "!"
Is there a way in Scala to transform an instance by supplying this method? Say I want to append an exclamation mark to a string. Something like:
val greeting = "Hello"
val loudGreeting = greeting.applyFunction(withExclamation) //result: "Hello!"
I would like to be able to invoke (local) functions when writing a chain transformation on an instance.
EDIT: Multiple answers show how to program this possibility, so it seems that this feature is not present on an arbitraty class. To me this feature seems incredibly powerful. Consider where in Java I want to execute a number of operations on a String:
appendExclamationMark(" Hello! ".trim().toUpperCase()); //"HELLO!"
The order of operations is not the same as how they read. The last operation, appendExclamationMark is the first word that appears. Currently in Java I would sometimes do:
Function.<String>identity()
.andThen(String::trim)
.andThen(String::toUpperCase)
.andThen(this::appendExclamationMark)
.apply(" Hello "); //"HELLO!"
Which reads better in terms of expressing a chain of operations on an instance, but also contains a lot of noise, and it is not intuitive to have the String instance at the last line. I would want to write:
" Hello "
.applyFunction(String::trim)
.applyFunction(String::toUpperCase)
.applyFunction(this::withExclamation); //"HELLO!"
Obviously the name of the applyFunction function can be anything (shorter please). I thought backwards compatibility was the sole reason Java's Object does not have this.
Is there any technical reason why this was not added on, say, the Any or AnyRef classes?
You can do this with an implicit class which provides a way to extend an existing type with your own methods:
object StringOps {
implicit class RichString(val s: String) extends AnyVal {
def withExclamation: String = s"$s!"
}
def main(args: Array[String]): Unit = {
val m = "hello"
println(m.withExclamation)
}
}
Yields:
hello!
If you want to apply any functions (anonymous, converted from methods, etc.) in this way, you can use a variation on Yuval Itzchakov's answer:
object Combinators {
implicit class Combinators[A](val x: A) {
def applyFunction[B](f: A => B) = f(x)
}
}
A while after asking this question, I noticed that Kotlin has this built in:
inline fun <T, R> T.let(block: (T) -> R): R
Calls the specified function block with this value as its argument and returns
its result.
A lot more, quite useful variations of the above function are provided on all types, like with, also, apply, etc.

How to use Type calculated in Scala Macro in a reify clause?

I've been working with Scala Macros and have the following code in the macro:
val fieldMemberType = fieldMember.typeSignatureIn(objectType) match {
case NullaryMethodType(tpe) => tpe
case _ => doesntCompile(s"$propertyName isn't a field, it must be another thing")
}
reify{
new TypeBuilder() {
type fieldType = fieldMemberType.type
}
}
As you can see, I've managed to get a c.universe.Type fieldMemberType. This represents the type of certain field in the object. Once I get that, I want to create a new TypeBuilder object in the reify. TypeBuilder is an abstract class with an abstract parameter. This abstract parameter is fieldType. I want this fieldType to be the type that I've found before.
Running the code shown here returns me a fieldMemberType not found. Is there any way that I can get the fieldMemberType to work inside the reify clause?
The problem is that the code you pass to reify is essentially going to be placed verbatim at the point where the macro is being expanded, and fieldMemberType isn't going to mean anything there.
In some cases you can use splice to sneak an expression that you have at macro-expansion time into the code you're reifying. For example, if we were trying to create an instance of this trait:
trait Foo { def i: Int }
And had this variable at macro-expansion time:
val myInt = 10
We could write the following:
reify { new Foo { def i = c.literal(myInt).splice } }
That's not going to work here, which means you're going to have to forget about nice little reify and write out the AST by hand. You'll find this happens a lot, unfortunately. My standard approach is to start a new REPL and type something like this:
import scala.reflect.runtime.universe._
trait TypeBuilder { type fieldType }
showRaw(reify(new TypeBuilder { type fieldType = String }))
This will spit out several lines of AST, which you can then cut and paste into your macro definition as a starting point. Then you fiddle with it, replacing things like this:
Ident(TypeBuilder)
With this:
Ident(newTypeName("TypeBuilder"))
And FINAL with Flag.FINAL, and so on. I wish the toString methods for the AST types corresponded more exactly to the code it takes to build them, but you'll pretty quickly get a sense of what you need to change. You'll end up with something like this:
c.Expr(
Block(
ClassDef(
Modifiers(Flag.FINAL),
anon,
Nil,
Template(
Ident(newTypeName("TypeBuilder")) :: Nil,
emptyValDef,
List(
constructor(c),
TypeDef(
Modifiers(),
newTypeName("fieldType"),
Nil,
TypeTree(fieldMemberType)
)
)
)
),
Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
)
)
Where anon is a type name you've created in advance for your anonymous class, and constructor is a convenience method I use to make this kind of thing a little less hideous (you can find its definition at the end of this complete working example).
Now if we wrap this expression up in something like this, we can write the following:
scala> TypeMemberExample.builderWithType[String]
res0: TypeBuilder{type fieldType = String} = $1$$1#fb3f1f3
So it works. We've taken a c.universe.Type (which I get here from the WeakTypeTag of the type parameter on builderWithType, but it will work in exactly the same way with any old Type) and used it to define the type member of our TypeBuilder trait.
There is a simpler approach than tree writing for your use case. Indeed I use it all the time to keep trees at bay, as it can be really difficult to program with trees. I prefer to compute types and use reify to generate the trees. This makes much more robust and "hygienic" macros and less compile time errors. IMO using trees must be a last resort, only for a few cases, such as tree transforms or generic programming for a family of types such as tuples.
The tip here is to define a function taking as type parameters, the types you want to use in the reify body, with a context bound on a WeakTypeTag. Then you call this function by passing explicitly the WeakTypeTags you can build from universe Types thanks to the context WeakTypeTag method.
So in your case, that would give the following.
val fieldMemberType: Type = fieldMember.typeSignatureIn(objectType) match {
case NullaryMethodType(tpe) => tpe
case _ => doesntCompile(s"$propertyName isn't a field, it must be another thing")
}
def genRes[T: WeakTypeTag] = reify{
new TypeBuilder() {
type fieldType = T
}
}
genRes(c.WeakTypeTag(fieldMemberType))

Scala a better println

I often find myself doing things like:
println(foo)
when I'd like to do:
println foo
The compiler does not allow this.
Also, println is a mouthful, I really just want to say:
echo foo
So, in a base package object I created the echo version of println:
def echo(x: Any) = Console.println(x)
Easy enough, have echo application wide, great.
Now, how do I invoke echo without needing to wrap the Any to print in parens?
object ∊ {def cho(s: Any) {println(s)}}
∊cho "Hello world"
will save your fingers.
It works because ∊ is a math-symbol in the Unicode Sm set, hence counts as an operator in Scala, so doesn't require spaces when placed next to alphanumeric characters.
You could also
object echo {def -(s: Any) {println(s)}}
echo-"Hello world"
which works pretty well IMO.
YEARS LATER EDIT: another almost-solution, using StringContext:
implicit class PimpMyString(sc: StringContext) {
def echo(args: Any*) = println(sc.raw(args: _*))
}
echo"Hello World"
Define
trait ShortCuts {
def echo(x: Any) = Console.println(x)
def trace[T](x: T): T = { echo(x); x }
// ...
}
object ↬ extends ShortCuts
and use happily without parentheses:
↬ echo "hello!"
Scalaz has an enhanced Identity type that has a println method.
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> val foo = 1
foo: Int = 1
scala> foo println
1
If you don't want to depend on scalaz, you can create your own pimped identity and put an implicit for it in a package object.
What you're trying to achieve isn't possible in Scala.
The parentheses can only be dropped in so called point-free syntax, in which you must have a context object on the left side of the function so in your case you can only achieve the following, which kinda doesn't make any sense anyway:
Console println x
While I can see why you want to achieve this, probably considering simpler syntax constructs of other languages better, I would advice just to stick to the standard Scala way of doing things, so just use println(x) or consider other languages. Creating a delegating method for such a basic standard feature will definitely bring you only troubles in future managing of your projects - so definitely a "no-no" for the echo method.
There's an old saying for cases just like that: When in Rome, do as the Romans do.
An interesting set of responses here, ranging from, it can't be done, to, it can be done, with this symbol-dependent hack, or with this dependency (Scalaz)
#Nikita correctly points out that one can just as easily add a snippet to their IDE (if that's how you roll) that does the println "legwork". While that is true, you generally have to stop typing to do ctrl-p-r, or whatever key combo you decide to use, which breaks your flow, IMO. So in the spirit of creating a "better" println, here's my take:
Create a base package object that your sub packages (model, view, dao, etc.) will inherit from (your own PreDef basically)
package com
package object company {
// echo(foo)
def echo(x: Any) = Console.println(x)
// foo.echo
class AnyProvidesEcho(x: Any) { def echo = Console.println(x) }
#inline implicit def any2Echo(x: Any) = new AnyProvidesEcho(x)
}
Usage:
val list = List(1,2,3)
val string = "c'est beacoup mieux mit butter"
list foreach echo
echo(string)
string.echo