Hacker News new | comments | show | ask | jobs | submit login
Getting started with Scala's new macros (scalamacros.org)
16 points by richdougherty 1637 days ago | hide | past | web | 34 comments | favorite

Every now and then I look around for ways to write native Android apps with something other than Java, and the only reasonable answer is still Scala.

But its syntax is so ridiculous! What on earth were they thinking?!

Scala the language is not the problem, as it is consistent and the rules aren't really complicated. However, the culture around the language and the libraries are awful.

The problem with a language that has relaxed rules for syntax is that every complicated API ends up being a DSL. And you can do this with taste, or without taste.

Take SBT for instance. It is the standard build tool in Scala. SBT has many problems, the biggest one being that the chosen objective (type-safe DSL for project definitions) was the wrong problem to solve, with its second biggest problem being that it still relies on Maven. So instead of coming up with an alternative to the brokenness in Maven, the Scala folks that worked on SBT focused on only one of Maven's flaws (the XML config files, which were the least of everybody's problems).

And the DSL syntax in SBT is God-damn awful, with lines looking like this:

     libraryDependencies <+= sbtVersion(
       v => "com.github.siasia" %% "xsbt-web-plugin" % (v+"-0.2.10"))
The difference between this piece of shit and Ruby's Bundler is simply amazing. And newbies are exposed to this right from the beginning, as SBT is THE standard and as such every Scala library documents how to integrate with SBT ... in fact some libraries have such a dependency on SBT that integrating it with Maven or other build systems is a mystery (e.g. libraries that have a precompilation step).

So this is a language with a culture that (a) promotes cargo-culting through bad API design and (b) often breaks backwards compatibility.

Yes, Scala is currently the best alternative to Java for Android development, but I am hoping that Clojure can close the gap significantly.

The main drawback to Clojure is still the start-up time, but that's getting better. For example, the metadata elision introduced in Clojure 1.4.0 speeds things up a bit and makes a significant cut in Clojure’s heap use.

However, one thing that Clojure gives you that Scala cannot, is the ability to do REPL-driven Android development, i.e. sending code directly from your editor to a running application and seeing nearly instantaneous results.

One thing I hope will help Clojure significantly is that it has a Google Summer of Code student who is going to be working on improving the tooling support for Android and Clojure. This should make it much easier for Clojure developers to start creating Android applications.

Being able to use Clojure would be great, but as you said not a viable option yet. GC pressure is the biggest problem, and it's one that sadly won't get solved too soon.

I've also looked at kawa (scheme), I might try that.

If I am not mistaken, any JVM language that has immutable data structures and closures is probably going to generate a fair bit of garbage. I believe this also applies to using Scala functionally.

My understanding is that there is greater interest in making Clojure more suitable as a library and with a leaner runtime requirement. If you have a situation were you don't need a dynamic environment, having the option to compile functions to static methods instead of classes should result in a big performance increase.

I have only briefly looked at Kawa Scheme, but I have not had the time to do much with it beyond a "Hello, World!" sort of project. Mirah is another interesting option. It uses a Ruby-inspired syntax but requires no runtime library.

Yes, immutable data will generate garbage. The problem with Clojure is that it generates a ton of garbage during start up, which isn't the case with Scala.

I certainly welcome any improvements in Clojure.

I've looked at Mirah, but it's quite immature and has serious problems with Java generics because of Java's type erasure.

My understanding is that Clojure also relies heavily on some of the advanced Hotspot optimizations that aren't available in Dalvik so it's often much slower on Android than it is on the standard JVM.

Really? I haven't heard of that.

In my experience, most of the alternative compiled JVM languages, i.e. Scala, Clojure, Mirah, and JRuby, seem to run fairly comparable to each other once they have started. The biggest differentiator between them with respect to performance seems to be in the way of start time and heap overhead ranging from none (Mirah) to substantial (JRuby).

Naively written Clojure is going to run a lot slower than Scala because it's doing a lot more dynamic dispatch. With the right type annotations you can probably get them fairly close.

Afaik it's about Hotspot having a much, much better GC.

I'm not too optimistic about this either. It's already easy enough to write very cryptic Scala. The potential for well-intentioned obfuscation is huge here.

I know the academic PL people shit on Go, but I'm really enjoying it so far just for it's minimalistic pragmatism. I really hope the rumors of Go support for the Android development are true.

My money is on Kotlin for an improved but still manageable JVM language:


It is actually very regular. There are a few rules:

a.b(c) = a b c

( <expr> ) = { <expr> }

<id>: is right associative.

That's about it. Once you know these you can decode just about any Scala program.

[Update: formatting]

Not from what I've seen. There are a bunch of extra rules, an especially annoying set being those related to _

I agree that, when you're learning, the "_" can be annoying since it's basically overloaded (its meaning depends on the context).

Scala is very rich in features (how many other languages need a 800+ pages book to explain just the syntax + core features like collections?). Once I got to know them though, I would very much miss most of them (and frankly I'm a bit afraid of what would be my reaction if one day I'd need to come back to Java). But, it's certainly not a language you will be fluent in within just a couple of days. As I didn't have previous functional programming experience, I'd say it took me a 3-4 months till I have gotten a feel of how/when to use most of the core features.

Hint I wish someone told me: write custom recursive functions only when you're certain the problem can't be handled with a simple reduce/fold. Basically, try to use lots of maps (the 'map' function, not the data structure) and folds, as they can solve tons of problems in an elegant (-> readable) and easily parallelizable way. It's also harder to make bugs when programming this way.

I think needing a 800+ pages book to explain just the syntax is precisely the problem!

Can it even be parsed reasonably? C++ sure can't be, and Scala appears to have the same silly feature creep.

When I was working on Scala (5+ years ago), the syntax was still pretty rich but the parser was fairly concise. Martin is very good about designing consistent and fairly compact syntax; you get the richness from just a few rules that are easily expressed via recursive descent; there is a little bit of lexer madness for semicolon inference, but this isn't that big of a deal. Its definitely nowhere near C++ in terms of unparsability; one could probably write their own parser for Scala over a weekend or so (depending on their compiler skillz).

What do you mean by "Can it even be parsed reasonably"?

The size of the language seems to come in large part from the fact that it wants to be an OOP and a functional language at the same time, with providing rich and sometimes bleeding edge feature-set in both domains (plus, you've got built-in tools for common problems like XML/XPath handling being a part of syntax). When you combine those, the resulting size is enormous.

IMO, it's definitely not a language for everyone and probably won't replace Java in its core domain (JEE enterprisey apps) - but, for many harder problems, the rich feature set can be a blessing.

You could design a similarly powerful language without such a difficult syntax. C++ is notoriously difficult to parse.

I would love to see an example of that.

I would too. Unfortunately C++ is so entrenched it its domain now that any possible replacement is going to have to be more than just incrementally better. Languages like D and Rust and even Go could replace C++ in many of its applications but none so far seem to have gained much traction.

C++ famously needs parsers with about 7 passes.

Most other languages have sane single-pass parsers, like recursive descent.

There is a new book that is very good and to the point (the first 9 chapters are available free from Typesafe, the company that distributes the Scala/Akka/Play stack).

Scala for the Impatient: http://www.amazon.com/dp/0321774094/

how about Groovy? it's similar-ish with Java with less boilerplate. http://skillsmatter.com/podcast/home/groovy-android/

(disclaimer: i found the link from quick googling, never used it, but i'm quite familiar with Groovy)

It doesn't seem like a significant enough improvement over Java. Similarly to how Scala seems a significant, but highly dangerous improvement over Java.

Its Android support is also not any better than JRuby or Rhino, both of which I prefer as languages.

Do you mean the macros specifically, or Scala in general?

Scala in general, and the macros are an especially bad case.

Granted macros are a two edged sword complexity-wise, this implementation is no exception. I think this is generally true for macros in other languages though.

Scala's "self cleaning" reify/eval mechanism is practically free syntax-wise - even Lisp has special characters for quasiquoting and splicing.

From what I'm seeing the macros are almost hygienic, which I guess is more than one can say about Common Lisp. But what you're describing as "self cleaning" just confuses me.

Compare the implementation of this particular macro with those in Scheme, Clojure or even Boo.

Self-cleaning basically means that they have a absolutely minimal, unhygienic macro and implemented the method which enforces hygiene as a macro itself – pretty impressive imho.

Maybe this one helps a bit: http://news.ycombinator.com/item?id=3912885

There is also a more detailed talk on macros, although I'm not sure it is already on the Skillsmatter site. Here are the slides: http://scalamacros.org/talks/2012-04-18-ScalaDays2012.pdf and also http://scalamacros.org/talks/2012-04-28-MetaprogrammingInSca....

These are scala's macros? Lisp/clojure/scheme guys are probably laughing right now. I have nothing against scala but they really need to shoehorn every possible feature in the language?

Scala's feature-space is admittedly crowded, but there is a method to the madness.

Scala's core design is generally to use a small number of rules to create a wide range of possibilities; the macro design they've chosen fits right in.

At the cost of almost no extra syntax, a whole range of things that would have required compiler plugins, special language features, or been flat-out impossible are enabled. It's (probably) a cheap win in this case.

I agree, macros are a nice addition to the language and I would choose scala over java anytime. What bothers me is that scala has so much syntactic sugar one can die of diabetes just by looking at some source code.

Care to explain? I have not experienced that. From which language do you come from? It certainly has less syntactic sugar than Java...

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact