?

Log in

No account? Create an account
Previous Entry Share Next Entry
Why I love Scala, part 837
device
jducoeur
I decided yesterday that the OP Compiler's configuration file was becoming an unspeakable pain in the ass. It's a huge XML file that represents essentially all the semantics of the SCA: what the branches are, the Kingdom/Principality/Barony hierarchy, what awards each one contains, and so on. I have little taste for writing a DTD, so it's just a big block of XML, and when I make a mistake it can be a bear to track it down.

So I decided to switch to instead hardcoding the configuration into the code itself. For a one-off program, this seems entirely reasonable; moreoever, it's increasingly idiomatic Scala. (Scala's native build system essentially uses a little DSL program to define your build, so you have access to full Scala. Scala tries to be script-friendly, and that sometimes means that code is better than config.)

I've spent the morning fiddling with that, and gradually improving it, and the results are just lovely. For example, here is the listing for the Kingdom of Artemisia (the bits that are relevant to our OP so far, anyway):
        Kingdom("Artemisia",
          awards = Seq(
            "Golden Feather of Artemisia",
            "Grace of Artemisia",
            "Griffin's Heart",
            "Griffin's Talon",
            "Lady of the Papillon",
            "LUST",
            "Maple Leaf of Artemisia",
            "Pillar of Artemisia"
          ),
          
          children = Seq(
            Barony("Arn Hold", awards = Seq(
              "Moose Combatant of Arn Hold"
            )),
            
            Barony("Loch Salaan", awards = Seq(
              "Bannthegn",
              "Crystal of the Salt Wastes",
              Award("Devoted and Unique Company of Keepers", "Devoted & Unique Company of Keepers"),
              "Falcon of Loch Salaan"
            ))
          )
        )
That's compiled code, that builds the data structures representing the Kingdom. While it isn't *quite* the absolute minimum number of keystrokes to express the concepts, it's pretty damned close. And it's about as readable as I could hope for.

What makes it really spiffy-keen, though, is that it's much more strongly-typed than it looks. (Scala is strongly typed to its core, with type inference that most languages can only envy.) So those lists of strings above, that give the names of the awards? Those aren't actually strings as far as the calling code is concerned. Instead, the compiler knows that it expects a Seq[AwardInfo] for the awards parameter. And I have the following implicit converter in scope:
implicit def string2AwardInfo(name:String) = AwardInfo(AwardName(name, Gender.Unknown))
That is to say, "When you are looking for an AwardInfo object, and what you find is a String, this is how to convert it into an AwardInfo". So each of those lines actually turns into an AwardInfo to get passed around. (And yes, the Eclipse plugin is smart enough to highlight these and provide tooltips about the conversion.) This way, I can just write a string for the "simple" cases where I just have a name, but give an explicit Award() listing (which is itself a special sort of function call, with lots of optional parameters) when I have more information to convey such as alternate spellings. (As in the DUCKs above.) That level of strong typing means that I get code as concise as most dynamic languages, but errors still usually get caught in the editor within a second of my typing them.

I don't think I can explain to a non-programmer the sheer delight of code like this, and the way it hits me on an aesthetic level. Think of it like sculpture, though. Most languages hand me basically a big hammer, and the result is that my programs come out rough and chunky -- you can sort of see what it's supposed to look like, but have to squint a bit. Scala, by contrast, gives me a whole assortment of chisels to work with, so that I can produce programs like this: finely detailed, with nothing extra to get in the way of its proper Platonic form. I spent the morning sculpting, and it is just *delightful* to get something pretty as a result...

  • 1
OK, I have got to get back to learning Scala. I've seen config done that way in Python, but obviously without the strong-typing goodness.

I commend it -- the language has come a long way in the past few years, and is awfully splufty. (The Eclipse plugin is still a tad more sluggish than I'd like, but I put up with it for the power it provides.)

I strongly recommend starting with the recent book "Scala for the Impatient". I'm in the middle of it and quite enjoying it as my out-and-about Kindle reading. It's aimed at someone like you or I, with a solid grounding in all the basics (it assumes you know essentially all of Java's concepts), and wanting a flying introduction to what makes Scala interesting. So it's nicely efficient and quite a bit of fun.

And of course, even that doesn't get into the most recent coolnesses -- the new release introduces all sorts of power in reflection and macros and stuff. But the book is a fine place to start...

I think the co-evolution of languages and language-aware editors in general is under-appreciated.

  • 1