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
Related
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.
I am trying to implement a Rich enumeration in Scala, where my enumeration would also have to implement for example a trait.
This work fine, however when I tried to iterate the enumerations, the Enumeration.values returns a ValueSet, which is a collection of Enumeration.Value
Is there a simple way to implement this feature, without going to macros and sealed traits are suggested from Travis Brown Iteration over a sealed trait in Scala? ?
Enumeration in scala can be done relatively easy with an Enumeration class. Below is an example of it.
trait Num {
def echo
}
object Status extends Enumeration {
case class StatusVal(code: Int, name: String) extends Val with Num {
override def echo {
println("Number: " + name)
}
}
val ONE = StatusVal(1, "One")
val TWO = StatusVal(2, "Two")
val THREE = StatusVal(2, "Three")
}
Status.values foreach (s => s.asInstanceOf[Num].echo)
You may have to convert first:
Enumeration and mapping with Scala 2.10
I guess both answers there are relevant, but I'd totally forgotten mine.
This thread
https://groups.google.com/d/msg/scala-internals/8RWkccSRBxQ/snNuzjJakhkJ
might mark the start of the long road to the enum replacement. It contains a few divergent (pun alert) opinions on usage.
Early stop on the road:
https://stackoverflow.com/a/4346618/1296806
Have you tried implicit conversions? Remember to keep the scope tight:
// I have deliberated stolen #cyrillk example :).
// Just add this line to the body os Status (Enumeration Object)
implicit def valueToNum(v: Value): Num = v.asInstanceOf[Num]
Value will be implicit cast to Num, so:
Status.values foreach (s => s.echo) // works!
Working Example
Chek out a Better example by Sean Ross.
I'm trying to use Scala 2.10 reflection to find the most derived type of a method argument. For example, consider this program:
import reflect.runtime.universe._
object ReflectionTest {
def checkType[A : TypeTag](item: A) {
println("typeOf[A]: " + typeOf[A])
}
def main(args: Array[String]) {
val a = Array(1, "Hello")
for (item <- a) checkType(item)
}
}
Here a has type Array[Any] so each item being sent to checkType has type Any. As a result, checkType outputs
typeOf[A]: Any
typeOf[A]: Any
This makes sense to me since the TypeTag is generated by the compiler at the point of the call (where all it knows about the type is that it is Any). What I want, however, is to determine the actual type of each item. I'd like output something along the lines of
Int
String
I have looked over the documentation here
http://docs.scala-lang.org/overviews/reflection/overview.html
but the samples don't seem to cover this case and I find the discussion there of Environments, Universes, and Mirrors difficult to penetrate. It seems like what I'm trying to do should be fairly simple but perhaps I'm approaching it completely wrong.
Most obvious solution would be to use the class:
def checkType[A](item: A) {
println("typeOf[A]: " + item.getClass)
}
But if you want to work with Type, then some additional work is needed:
def checkType[A](item: A) {
val mirror = runtimeMirror(this.getClass.getClassLoader)
println("typeOf[A]: " + mirror.classSymbol(item.getClass).toType)
}
I usually use Scala with SLF4J through the Loggable wrapper in LiftWeb. This works decently well with the exception of the quite common method made up only from 1 chain of expressions.
So if you want to add logging to such a method, the simply beautiful, no curly brackets
def method1():Z = a.doX(x).doY(y).doZ()
must become:
def method1():Z = {
val v = a.doX(x).doY(y).doZ()
logger.info("the value is %s".format(v))
v
}
Not quite the same, is it? I gave it a try to solve it with this:
class ChainableLoggable[T](val v:T){
def logInfo(logger:Logger, msg:String, other:Any*):T = {
logger.info(msg.format(v, other))
v
}
}
implicit def anyToChainableLogger[T](v:T):ChainableLoggable[T] = new ChainableLoggable(v)
Now I can use a simpler form
def method1():Z = a.doX(x).doY(y).doZ() logInfo(logger, "the value is %s")
However 1 extra object instantiation and an implicit from Any starts to look like a code stink.
Does anyone know of any better solution? Or maybe I shouldn't even bother with this?
Scala 2.10 has just a solution for you - that's a new feature Value Class which allows you to gain the same effect as the implicit wrappers provide but with no overhead coming from instantiation of those wrapper classes. To apply it you'll have to rewrite your code like so:
implicit class ChainableLoggable[T](val v : T) extends AnyVal {
def logInfo(logger:Logger, msg:String, other:Any*) : T = {
logger.info(msg.format(v, other))
v
}
}
Under the hood the compiler will transform the logInfo into an analogue of Java's common "util" static method by prepending your v : T to it's argument list and updating its usages accordingly - see, nothing gets instantiated.
That looks like the right way to do it, especially if you don't have the tap implicit around (not in the standard library, but something like this is fairly widely used--and tap is standard in Ruby):
class TapAnything[A](a: A) {
def tap(f: A => Any): A = { f(a); a }
}
implicit def anything_can_be_tapped[A](a: A) = new TapAnything(a)
With this, it's less essential to have the info implicit on its own, but if you use it it's an improvement over
.tap(v => logger.info("the value is %s".format(v)))
If you want to avoid using implicits, you can define functions like this one in your own logging trait. Maybe not as pretty as the solution with implicits though.
def info[A](a:A)(message:A=>String) = {
logger.info(message(a))
a
}
info(a.doX(x).doY(y).doZ())("the value is " + _)
Is it possible to get the name of a scala variable at runtime?
E.g. is it possible to write a function getIntVarName(variable: Int): String behaving as follows?
val myInt = 3
assert("myInt" === getIntVarName(myInt))
For what you need to do, It seems to me that runtime is not required, since you already have your myInt variable defined at compile time. If this is the case, you just need a bit of AST manipulation via a macro.
Try
package com.natalinobusa.macros
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
object Macros {
// write macros here
def getName(x: Any): String = macro impl
def impl(c: Context)(x: c.Tree): c.Tree = {
import c.universe._
val p = x match {
case Select(_, TermName(s)) => s
case _ => ""
}
q"$p"
}
}
Be aware that macro's must be compiled as a separate subproject, and cannot be part of the same project where the macro substitution has to be applied. Check this template on how to define such a macro sub-project: https://github.com/echojc/scala-macro-template
scala> import Macros._
import Macros._
scala> val myInt = 3
myInt: Int = 3
scala> "myInt" == getName(myInt)
res6: Boolean = true
You can use scala-nameof to get a variable name, function name, class member name, or type name. It happens at compile-time so there's no reflection involved and no runtime dependency needed.
val myInt = 3
assert("myInt" === nameOf(myInt))
will compile to:
val myInt = 3
assert("myInt" === "myInt")
Basically, it can't be done.
The JVM offers nothing by way of a Method handle (remember, Scala properties are encoded as methods in bytecode to support the uniform access principle). The closest you can get is to use reflection to find a list of methods defined on a particular class - which I appreciate doesn't help with your particular need.
It is possible to implement this as a Scala feature, but it would require a compiler plugin to grab the relevant symbol name from the AST and push it into code as a string literal, so not something I could demonstrate in a short code snippet :)
The other naming problem that often comes up in reflection is method parameters. That one at least I can help with. I have a work-in-progress reflection library here that's based on the compiler-generated scala signature as used by scalap. It's nowhere near being ready for serious use, but it is under active development.
Scala doesn't yet have much more than Java in terms of metadata like this. Keep an eye on the Scala Reflection project, but I doubt that will offer access to local variables anytime soon. In the meantime, consider a bytecode inspector library like ASM. Another big caveat: local variable names are lost during compilation, so you'd need to compile in "debug" mode to preserve them.
I don't think it's possible to get the name of a variable, but you can try it with objects:
object Test1 {
def main(args: Array[String]) {
object MyVar {
def value = 1
}
println(MyVar.getClass)
}
}
This prints: class Test1$MyVar$2$. So you can get 'MyVar' out of it.
This can be achieved with Scala 3 Macros (does it at compile time).
Create a Macro object (this must be in a separate file):
import scala.quoted.{Expr, Quotes}
object NameFromVariable :
def inspectCode(x: Expr[Any])(using Quotes): Expr[String] =
val name = x.show.split("""\.""").last
Expr(name)
Then you need an inline method in your class.
inline def getIntVarName(inline x: Any): Any = ${ NameFromVariable.inspectCode('x) }
And use this method, like:
val myInt = 3
assert("myInt" === getIntVarName(myInt))
See the official documentation: https://docs.scala-lang.org/scala3/guides/macros/macros.html