Scala and Adding New Syntax

One interesting thing about some languages is their support for adding new syntax. While all languages have the ability to add new functions or types some have specific properties that make it easy to add what looks like new built-in syntax.

Scala is an Object Oriented language. You can declare classes and objects, do inheritance and composition, and all the other things you might expect from an OO language. Scala is also a Functional language because functions are first-class citizens (also called a functor). And when I say Scala is an OO language I really mean it: everything is an Object. Even functions are Objects. (Chew on that one for a bit.)

Scala also supports the idea of optional parenthesis for method calls that only take a single argument (Note: This applies to method calls on object only. Not to functions.). This ends up being for a very practical reason. Take the following example:

1 + 2

This is a very nice way to write an addition operation. In reality what’s happening is:

1.+(2)

1 is an object and + is a method on that object that takes a single parameter. Applying the previous rule we get to remove the dot and the the parenthesis. Which allows us to write our previous example 1 + 2.

The good news is they bring this consistency to the language as a whole, so any method call can optionally use the dot. Any call to a method that only takes a single parameter can exclude the parenthesis around its arguments. These features make it pretty easy to emulate the built-in syntax of a language.

Your Own While Loop

Let’s say I want to write my own while loop:

def mywhile(condition: => Boolean)(command: => Unit) {
if (condition) {
command
mywhile(condition)(command)
}
}

var x = 1
mywhile(x < 100000) {
println(x)
x += 1
}

As you can see, I end up calling mywhile the same as I would call a built-in while. This is implemented as a tail-recursive function. If the condition is met, the command is executed. The function then recurses, calling itself to continue. x < 100000 is an anonymous function that returns a boolean expression.

Your Own Do...While Loop

A while loop can be built using just a single function. What if you want to create a do...while loop instead? In this case you can make use of the OO/functional hybrid.


class Repeater(command: => Unit){
final def aslongas(condition: => Boolean) {
command
if (condition) aslongas(condition)
}
}

def mydo(command: => Unit): Repeater = {
new Repeater(command)
}

var x = 0
mydo {
x += 1
println(x)
} aslongas (x < 100000)

In this case I use recursion again to do the looping. But I use an Object to bind the command to and an aslongas method to run that command and check the looping condition. I use a function mydo to bootstrap an instance of the Repeater class. Scala gives us the ability to use functions and objects when they make sense.

Why Should You Care?

Ok, so you're not going to write your own while loops. The language has them built-in already. But what this allows you to see is how you can add new "syntax". That ability makes it quite convenient and easy to write higher-order syntax to solve application specific problems or to create DSLs.

Update: Changed the until name to 'aslongas' since it really wasn't until the condition was met.

14 thoughts on “Scala and Adding New Syntax”

  1. “And when I say Scala is an OO language I really mean it: everything is an Object.”

    Not true. For a practical example, classes aren’t objects (see Smalltalk). Chew on that one.

  2. You didn’t talk about “Automatic Type-Dependent Closure Construction” once in this article! At least by name; a long, confusing name at that :).

    You did explain it, though.

  3. Using until in the do / while example doesn’t quite read right. It does not loop *until* x < 100000. If so, it would quit on the first iteration.

  4. @Floyd, that is true. The naming was a bit arbitrary. While is taken, I guess something like ‘aslongas’ would work. The other way to make it ‘until’ would be to negate the condition in the Repeater and then switch it to until(x >= 10000). That would be more semantically appropriate I guess.
    Thanks for the comment.

  5. @Grant, I didn’t talk about ‘Automatic Type-Dependent Closure Construction’ because I don’t know what that is. The rest I didn’t talk about because I didn’t see this as a post on all the details of scala really. Thanks for the comments.

  6. Geoff: Regarding the posts focus, understood. I was very focused on Scala, and I wish you had decomposed your code down the details about how closures are created, why you can’t create 2 of them automatically, and so on, in addition to the excellent detail you had already provided.

  7. @anony, Good point, some languages choose to make classes first-class objects so they can be meta-programmed at runtime. You point out Smalltalk, Ruby does the same thing. Generally that’s only an interesting thing in dynamically typed languages though because statically typed languages don’t give you the tools to manipulate those classes and then call them in any normal way.

    Smalltalk and Ruby are dynamically typed, message passing languages. Scala is a statically typed (and compiled) language, so classes as objects probably wouldn’t offer any value.

    Thanks for the comment.

  8. Re: Automatic Type-Dependent Closure Construction, I was trying to give you hard time for not including a big, confusing term. Like I said, you did describe it.

    I only found it because I was trying to find out how you create closures (a lambda doesn’t evaluate its body) in Scala and came upon this:

    http://www.scala-lang.org/node/138

  9. @Grant, that link is hilarious. This whole post started with me solving a problem from the Scala by Example book. Then that page has the exact implementation that I did … except it took me like 2 hours to figure it out. So much for my original work. :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>