4

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?

virtualeyes
  • 11,147
  • 6
  • 56
  • 91
  • possible duplicate of [Why can't I write println "Hello world" in Scala?](http://stackoverflow.com/questions/3617491/why-cant-i-write-println-hello-world-in-scala) – Debilski Apr 09 '12 at 11:47
  • @Debilski - This is a "How do I" question, which elicited some excellent, if frightening, hacks. [The other question](http://stackoverflow.com/questions/3617491/why-cant-i-write-println-hello-world-in-scala) is a "Why can't I", whose answer gives an excellent explanation of the underlying issue. I vote against closing. – leedm777 Apr 09 '12 at 14:03
  • @dave: You’re correct. It should have been closed long before those frightening hacks could’ve been posted. – Debilski Apr 09 '12 at 14:22
  • and yet, it shouldn't be closed because the question is targeted at println itself and not just parens-less invocation. – virtualeyes Apr 09 '12 at 14:37
  • @virtualeyes: Maybe. But on the other hand, a question like ‘Isn’t “echo” a much better suited command than “println”, what do you think?’ might easily get a ‘not constructive’ tag. – Debilski Apr 09 '12 at 14:48
  • 1
    true, but then again, it might also get a, "why am I typing 7 chars all the time when I can express the same intent in 4 chars?" – virtualeyes Apr 09 '12 at 14:59

5 Answers5

11
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"
Luigi Plinge
  • 50,650
  • 20
  • 113
  • 180
  • interesting, a bit much, however ;-) Straight "echo(foo)" is fine, as would be println(foo) if I didn't have to type the whole thing out (IDE autocomplete, select from list is actually slower than just hammering it out, btw) – virtualeyes Apr 09 '12 at 14:21
  • 1
    Why not `cout<<"Hello world"`? – Debilski Apr 09 '12 at 22:51
  • 1
    now the only problem is to figure out how to type `∊` faster than typing the brackets. – Jus12 Apr 10 '12 at 06:55
5

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!"
Debilski
  • 66,976
  • 12
  • 110
  • 133
4

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.

huynhjl
  • 41,520
  • 14
  • 105
  • 158
  • right, I actually started out with an implicit prior to cloning println from PreDef. See my updated alternative – virtualeyes Apr 09 '12 at 14:22
3

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.

Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169
  • Thanks, don't see the danger here. I'm not delegating anything, there's zero overhead, just a method in a base package object. If in future Scala/Java goes with something other than Console.println(), there's a whopping 1 place to make a change. As for considering other languages based on my desire for a println alternative, not sure what to say. Scala completely & utterly rocks, should I use PHP instead of Scala based on the fact that they use echo? ;-) – virtualeyes Apr 09 '12 at 12:07
  • @virtualeyes A chance of JVM breaking a backward compatibility approximates to zero. There's a much higher chance of some people working with your code not getting what's going on until they learn your customizations over standard APIs. There's even a decent chance that you yourself will have troubles understanding that code after some time. Also after getting used to your own APIs you'll find it much harder to understand the code that you didn't write. And definitely things like that won't be much appreciated by the team if you'll ever have to work in one. – Nikita Volkov Apr 09 '12 at 17:17
  • @virtualeyes Of other languages you could consider Haskell if you're looking for a functional static language with great syntax, Python if you're looking for a popular language with nice syntax (or Jython if you target JVM). There's also a newborn Kotlin which is kind of improved and simplified Scala - since it's a product of JetBrains it will definitely become popular and will have a superb IDE support. The languages I've just named dominate over Scala in the respective areas. I would never advice even touching PHP. – Nikita Volkov Apr 09 '12 at 17:28
  • yes, the team aspect is a good point, as well as Java interop/familiarity/convention. Normally I wouldn't care, but println statements are such a common development task that I'm willing to experiment with the shorter form, echo. Goes without saying that I'm a one-man-show, design to database to code, so bothering team members won't be an issue (not now at any rate) – virtualeyes Apr 09 '12 at 17:38
  • Sure, there are plenty of excellent languages, so what? Because I prefer echo over println does not mean I should drop Scala. The nice thing about Scala is that you have free reign to do as you please, like Ruby, but with compiler checked code, IMO, the best of both worlds. Agreed Kotlin, looks to be an up-and-comer on the JVM, but they have a long way to go to catch Scala. A new language does not come without issues/problems/etc. (of course, Kotlin can snag every Scala feature in the book and avoid the pitfalls, benefit of being late to the party) – virtualeyes Apr 09 '12 at 17:45
  • @virtualeyes Any modern IDE and even editors like Sublimetext have a feature of templates - you can simply create a `pl` template which will unfold into a `println` statement and trigger it with three strokes (even less than it's needed for typing `echo`): `p-l-TAB`. I did so myself. Currently creating templates is a common approach to reducing typing in any language. – Nikita Volkov Apr 09 '12 at 17:52
  • Yes, the snippet idea was what I first thought of, new to Eclipse and have yet to dig in to that option. Obviously, println itself is not a lot of noise, far less than Console.println and System.out.println and other madness ;-) – virtualeyes Apr 09 '12 at 18:23
  • Interestingly, Python started requiring parentheses when they switched to version 3: instead of `print "x"` in Python 2 you have to write `print ("x")`. The reason being is that by working like any other function the language is more regular. – Luigi Plinge Apr 09 '12 at 18:40
  • 1
    you can pimp echo onto Any and get around the need for parens – virtualeyes Apr 09 '12 at 18:44
  • @virtualeyes: (Of course, it depends on the use case and the way you write development code, but) most uses of `println` can safely be replaced by some logging commands, most, if not all, of them being even a bit shorter. `debug`, `info`… ;) – Debilski Apr 09 '12 at 22:42
1

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
virtualeyes
  • 11,147
  • 6
  • 56
  • 91