I just noticed that Scala has macros, but I have never seen any code that uses them. They also seem quite different from C preprocessor macros and the like. Reading through the overview of macros, it didn't look like they offer anything that wasn't previously possible in Scala. Under the motivation heading, there is a list of things that macros enable:
Language virtualization (overloading/overriding semantics of the
original programming language to enable deep embedding of DSLs),
Program reification (providing programs with means to inspect their
own code),
Self-optimization (self-application of domain-specific
optimizations based on program reification),
Algorithmic program
construction (generation of code that is tedious to write with the
abstractions supported by a programming language).
Later on in the menu, there are experimental macro features, such as type macros, quasiquotes, untyped macros and even more. Clearly there is a demand for this!
All these seem like nice features for people who build very sophisticated libraries with strong understanding of Scala. But do macros offer something for the average Scala developer too? Will using macros make my Scala code better?
As an "average" Scala developer, you will most likely not write macros yourself, unless you have very good reason.
Macros are a method of compile time meta programming, that is to say you program programs. For example, a def-macro—which is part of Scala 2.10 albeit still "experimental"—looks like a regular method, but whenever you call that method in your code, the compiler will replace that call with whatever that macro hidden behind that method will produce (a new code fragment).
A very simple example. Incorporate the date when your project was compiled into the code:
import java.util.Date
import reflect.macros.Context
import language.experimental.macros
object CompileTime {
def apply(): Date = macro applyImpl
def applyImpl(c: Context)(): c.Expr[Date] = {
import c.universe._
val now = System.currentTimeMillis() // this is executed during compilation!
val nowExpr = c.Expr[Long](Literal(Constant(now)))
val code = reify(new Date(nowExpr.splice))
c.Expr(code.tree)
}
}
Using that macro (the following code must be compiled separately from the macro code above):
object MacroTest extends App {
println(s"This project was compiled on ${CompileTime()}")
}
(If you run that multiple times, you see that the compile time is indeed constant)
So in short, macros offer a functionality which was not available in any previous Scala version. You can do things with macros you cannot do otherwise (often you can write similar things using runtime reflection, but macros are checked at compile time).
As a user you will however be exposed more and more to libraries which incorporate macros, because they can provide powerful constructs which are fully type safe. For example, automatic serialisers for JSON from a case class can be realised with macros, because the macro can inspect the type of your case class and build the correct program structure (AST) to read and write that case class, with no danger of runtime failure.
Some random links
https://github.com/retronym/macrocosm
http://www.warski.org/blog/2012/12/starting-with-scala-macros-a-short-tutorial/
Related
Is the reason a val variable can be used to contain a function definition is because functions are first class citizens where they can be contained in variables?
In Scala damn near everything is an expression. From a practical perspective what that means is pretty much every bit of syntactically correct Scala code that you can write evaluates to an object that can you can do more Scala on. Examples of things you can do to these objects are: call a method on it, pass it to a function, or store it in a val. Expressions can be thought of in contrast to statements, which are just instructions to the computer to do something. An example of the use of statements in Scala are import commands. The heavy prevalence of expressions in Scala are a deliberate design choice intended to make the language more flexible and extensible.
I have a factory that should return an implementation depending on the name.
val moduleMap = Map(Modules.moduleName -> new ModuleImpl)
def getModule(moduleName: String): Module =
moduleMap.get(moduleName) match {
case Some(m) => m
case _ =>
throw new ModuleNotFoundException(
s"$moduleName - Module could not be found.")
}
In order for each call to the "getModule" method not to create an instance, there is a map in which all the modules must be initialized in bootstrap class.
I would like to get rid of the need to do this manually(also all classes have a distinctive feature).
List of options that came to my mind:
Reflection(we can use Scala Reflection API or any thrid-party
library)
Automated process.
Need to initialize immediately at startup.
Reflection is a pain.
Metaprogramming(ScalaMeta) + Reflection
Macros only change the code, the execution happens later.
Can we move initialization process to compile time?
I know that compiler can optimize and replace code, next fragment before compilation
val a = 5 + 5
after compilation compiler change that piece to 10, can we use some directives or another tools to evaluate and execute some code at compile time and use only final value?
Do you use any framework or you write your own? I answered similar question about Guice here. You can use it without Guice as well: instead of Module you will have your Factory, which you need to initialize from somewhere, and during initialization, you will fill your map using reflection
In general I think it is the easiest approach. Alternatively, you can write macros, which just replaces part of reflective initialization, but not sure that it will give you some profit (if I understand your question right, this initialization will happen just once at startup).
I do not see how scalameta can help you? Probably, only in case if all your implementations are in source tree available to you, so you can analyze it and generate initialization (similar to macros)? Probably, this would add such plus as easier search for implementation, but will add minus: will work only on implementations in your sources.
Your example of compile-time optimization is not applicable. In your example, you talk about compile-time constant (even with arithmetic it could be a problem, see this comment), but in your question you need specific run-time behavior. So compile time could be only code generation from macros or based on scalameta from my point of view.
We are pretty familiar with implicits in Scala for now, but macros are pretty undiscovered area (at least for me) and, despite the presence of some great articles by Eugene Burmako, it is still not an easy material to just dive in.
In this particular question I'd like to find out if there is a possibility to achieve the analogous to the following code functionality using just macros:
implicit class Nonsense(val s: String) {
def ##(i:Int) = s.charAt(i)
}
So "asd" ## 0 will return 'a', for example. Can I implement macros that use infix notation? The reason to this is I'm writing a DSL for some already existing project and implicits allow making the API clear and concise, but whenever I write a new implicit class, I feel like introducing a new speed-reducing factor. And yes, I do know about value classes and stuff, I just think it would be really great if my DSL transformed into the underlying library API calls during compilation rather than in runtime.
TL;DR: can I replace implicits with macros while not changing the API? Can I write macros in infix form? Is there something even more suitable for this case? Is the trouble worth it?
UPD. To those advocating the value classes: in my case I have a little more than just a simple wrapper - they are often stacked. For example, I have an implicit class that takes some parameters, returns a lambda wrapping this parameters (i.e. partial function), and the second implicit class that is made specifically for wrapping this type of functions. I can achieve something like this:
a --> x ==> b
where first class wraps a and adds --> method, and the second one wraps the return type of a --> x and defines ==>(b). Plus it may really be the case when user creates considerable amount of objects in this fashion. I just don't know if this will be efficient, so if you could tell me that value classes cover this case - I'd be really glad to know that.
Back in the day (2.10.0-RC1) I had trouble using implicit classes for macros (sorry, I don't recollect why exactly) but the solution was to use:
an implicit def macro to convert to a class
define the infix operator as a def macro in that class
So something like the following might work for you:
implicit def toNonsense(s:String): Nonsense = macro ...
...
class Nonsense(...){
...
def ##(...):... = macro ...
...
}
That was pretty painful to implement. That being said, macro have become easier to implement since.
If you want to check what I did, because I'm not sure that applies to what you want to do, refer to this excerpt of my code (non-idiomatic style).
I won't address the relevance of that here, as it's been commented by others.
I know programmers are supposed to wrap their code in an application object:
object Hello extends App {
println("Hello, World")
}
It is required in Eclipse, if I ever want to get any output. However, when I tried to write some code (very casually) in Emacs, I write like this:
class Pair[+T](val first: T, val second: T)
trait Friend[-T] {
def befriend(someone: T)
}
def makeFriendWith(s: Student, f: Friend[Student]) {
f.befriend(s)
}
It seems like there is no universal object or class that wraps over the function makeFriendWith. Is Scala like JavaScript, everything is attached to a global object? If not, what is this function attached to?
Also why can this work in console (I complied it with scala command and it worked) but does not work in Eclipse? What's the use of the Application object?
Scala doesn't have top-level defs, but your script can be run by either the REPL or the scala script runner.
The precise behavior of your script depends on which way you run it.
The REPL can run scripts line-by-line or whole hog. (Compare :paste and :paste -raw versus :load or -i init.script and the future option -I init.script.)
There is an issue about sensitive scripting. The script runner should realize if you're trying to run an App.
There is another effort to make scripting a compiler phase that is easily customized. Scroll to Scripter.scala for code comments about its current heuristics.
In short, your defs must be wrapped in a top-level entity, but exactly how that happens is context-dependent.
There was a recent effort to make an alternative baked-in wrapping scheme available for the REPL.
None of this is mandated by the language spec, any more than special rules pertaining to sbt build files are defined by the language.
You can define methods like this only in the console, which (behind the scenes) automatically wraps them in an anonymous class for you.
Outside of the console, there's no such luxury.
As a JVM language, Scala cannot truly create any top-level entities other than classes and interfaces.
It does, however, have the notion of a "package object" which creates the illusion of value entites (val, var and def) not enclosed in a class or trait.
See http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html for information on package objects.
You can run code like this directly in Eclipse: use Scala worksheet. IntelliJ IDEA Scala plugin supports it as well.
In groovy one can do:
class Foo {
Integer a,b
}
Map map = [a:1,b:2]
def foo = new Foo(map) // map expanded, object created
I understand that Scala is not in any sense of the word, Groovy, but am wondering if map expansion in this context is supported
Simplistically, I tried and failed with:
case class Foo(a:Int, b:Int)
val map = Map("a"-> 1, "b"-> 2)
Foo(map: _*) // no dice, always applied to first property
A related thread that shows possible solutions to the problem.
Now, from what I've been able to dig up, as of Scala 2.9.1 at least, reflection in regard to case classes is basically a no-op. The net effect then appears to be that one is forced into some form of manual object creation, which, given the power of Scala, is somewhat ironic.
I should mention that the use case involves the servlet request parameters map. Specifically, using Lift, Play, Spray, Scalatra, etc., I would like to take the sanitized params map (filtered via routing layer) and bind it to a target case class instance without needing to manually create the object, nor specify its types. This would require "reliable" reflection and implicits like "str2Date" to handle type conversion errors.
Perhaps in 2.10 with the new reflection library, implementing the above will be cake. Only 2 months into Scala, so just scratching the surface; I do not see any straightforward way to pull this off right now (for seasoned Scala developers, maybe doable)
Well, the good news is that Scala's Product interface, implemented by all case classes, actually doesn't make this very hard to do. I'm the author of a Scala serialization library called Salat that supplies some utilities for using pickled Scala signatures to get typed field information
https://github.com/novus/salat - check out some of the utilities in the salat-util package.
Actually, I think this is something that Salat should do - what a good idea.
Re: D.C. Sobral's point about the impossibility of verifying params at compile time - point taken, but in practice this should work at runtime just like deserializing anything else with no guarantees about structure, like JSON or a Mongo DBObject. Also, Salat has utilities to leverage default args where supplied.
This is not possible, because it is impossible to verify at compile time that all parameters were passed in that map.