# Loop: A Compact JVM Language for Multi-Core

| by Dio Synodinos 2 Followers on Jul 05, 2012. Estimated reading time: 6 minutes |

As a programming language, Loop is compact JVM language influenced by Haskell, Scheme, Ruby and Erlang. It also tries to bring together the best features of functional programming  and OO languages, in a consistent and pragmatic manner.

Programs are compiled on-the-fly to optimized JVM bytecode and therefore suffer no performance penalty to interpretation; all while maintaining the quick, edit-and-run responsiveness of interpreted code.

The Loop file structure is:

module declaration

import declarations

functions & type definitions

free expressions


Here's an example of a loop program:

module mymodule

require othermod
require yet.another

class Pair ->
left: 0
right: 0

main ->
new Pair()   # comments may appear anywhere

# free expressions must appear last
print('mymodule is go!')


InfoQ had a small Q&A with the creator of loop, Dhanji R. Prasanna, who’s an ex-Google,  co-author of the JAX-RS spec and author of  “Dependency Injection: Design Patterns” by Manning:

InfoQ: How does loop compare with the rest of the JVM languages?

Dhanji: I don't want to do a nitty-gritty feature comparison, but I would say the philosophy of Loop is about providing a consistent, simple and joyful experience in coding. All features are designed with this comprehensive outlook in mind and a care for how features interact with each other, both syntactically and semantically. In other languages you sometimes have multiple ways to do the same thing, almost as a feature of the language, and many of these feel bolted-on. Whereas in Loop I've tried to narrow down the canonical ways of doing things so that they are concise and simple, and result in an attractive, comfortable syntax. It should be as easy to read code as to write it, and just as much fun.

One other point of distinction is that Loop compiles directly to JVM bytecode, but does so on-the-fly. Meaning that it behaves and *feels* like a scripting language (and REPL-esque, like a Lisp), but it actually performs considerably better than an interpreted language. I will let others run benchmarks, but so far in my quick tests, Loop is extremely fast. I have also put an emphasis on startup time, so it starts up nearly as fast as java itself allows; a fact that is often ignored by many modern JVM langs.

Loop also interoperates tightly with Java. It is really easy to call Java methods or instantiate Java objects from inside a Loop program. Lists, sets and maps are just java.util. members, but with several extensions (and similarly for Strings). This is different from some languages that balance two sets of data libraries in order to provide extensions.

And finally, Loop has built-in support for concurrency right from the start, with immutability and safe sharing of state as integral features.

InfoQ: You mention that many of loop's features are inspired by languages like Haskell, Scheme and Ruby. Would you like to give us a few examples?

Dhanji: Sure. It's always hard to address this because when you say "inspired by", people tend to think "is a copy of" and will look with a fine-toothed comb for deviation. The takeaway from my perspective is about syntax influences from these languages. In particular, the easy ones are pattern matching and "where" & "do" blocks from Haskell, the type system, modules, TCO and lexical constructs (closures) of Scheme, and ideas like symbols and free-form scripting from Ruby.

One syntactic example of this combined influence is the fact that you can call functions in postfix notation:

print(36)
# can be written as:
36.print()


... which makes them read like a Ruby method call, but in actual fact they are simply polymorphic (overloaded) functions. I find this very useful for improving the readability of some *particular kinds* of code, especially when "extending" the functionality existing Java objects. Of course, there is a balance to be struck, but I believe that will come as Loop matures.

The deeper, semantic influences of Haskell and Scheme (the latter in particular) are also present in the functional design of the language. One example is to get away from stateful, encapsulation-oriented design to a more stateless, declarative design. Like Scheme, Loop also features an impure superset for IO; but on the other hand enforces immutability whenever you deal with concurrency. The latter is the philosophical influence of Haskell.

Additionally the emphasis on making declarative code easier to write (and read) is also an influence from Haskell. I like the philosophy that code should read like a solution, rather than a laundry list of instructions; in other words, emphasizing the "what" rather than the "how" of the program, and Loop definitely follows this philosophy.

InfoQ: It seems that loop puts lots of emphasis on concurrency and provides a built-in message-passing abstraction. Would you like to explain to us how that compares with other popular concurrency technologies, either on the JVM (languages or frameworks) or beyond (eg. Erlang)?

Dhanji: This is a good question. There's a lot of prior art for this from Erlang. There are two primary methods for doing concurrency in Loop, they are both built into the language, and also useful in conjunction with each other:

- message-driven channels (an event-oriented abstraction over message-passing, queues and worker pools)

- software transactional memory (a lock-free, atomic, consistent scheme for sharing mutable state)

With the former the entire abstraction is taken care of for you. You set up any number of lightweight "channels" which can be configured to execute in parallel, to chew through large numbers of tasks; or to process a single task at a time (serially) in buckets. This actually provides a really easy way to create naturally *sharded* event queues. Since channels are lightweight you can create tens of thousands of them cheaply and use them to shard task execution, for example by username. There is also a lightweight, persistent local memory available to each such serial channel, making it easy to implement incremental task processing.

Loop also ensures that worker threads are evenly balanced over channels, using a configurable "fairness" factor. All of what I have described so far is available right out of the box. And on top of that one can further configure each channel to have its own dedicated worker pool, and so on.

I mentioned the lightweight persistent memory for serialized channels earlier--transactional memory on the other hand is a much more powerful construct, similar to "optimistic concurrency" used in databases, if you are familiar with that. The idea is that nothing ever locks, even when writing. This type of memory is optimized for extremely high read throughput and non-blocking write throughput. This is built right into the language grammar itself:

update(person) in @person ->
this.name: person.name,
this.age: person.age

Note the "in @person", telling Loop to transact on the @person cell.

In this method Im updating the @person "transactional cell" with new data from the argument to update(). The "this" pointer refers to the current cell which is in a transaction throughout this function. When the function completes, the changes to @person are visible atomically to all other threads, or not at all if the transaction fails (similar to a rollback). All other threads (even those not in a transaction) continue to see a consistent @person cell until the transaction executes and then immediately see the new person as a whole, with no locking or waiting. The neat thing here is that reader and writer threads *never* block.

This feature is still somewhat in alpha, as Im trying to get the semantics nailed down, but I feel along with the rich set of channels API it makes concurrent programming in Loop elegant, powerful and easy to understand.

You can contribute to loop on Github.

Style

## Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

## Get the most out of the InfoQ experience.

### Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

I am the same color as a Mercedes, the length of a Jaguar and the weight of a Porshe: then I mus be a great car !

Referencing popular language does not warrant quality.
What exactly is it suppose to bring ?

Man Serge, you sure are a one-trick pony.

Fortunately, I know where it is coming from.

As usual you have nothing of value to bring.
At least I asked a question.

Let's have another five language tomorrow for Dan.

Serge, you haven't had anything of value to bring for what...7, 8 years since the old Javalobby days. You just repeat the same old crap, over and over again...year after year.

New languages are always good by M Vleth

I like new languages since they most of time introduce some new ideas or in case of the JVM pushes its limits. That is not to say that every new language has a good change of surviving. I think the most promising languages are those with good tooling and libraries to back them up.

That's why I'm more looking at for instance Kotlin which already even in alpha state has great tooling but also leverages all the existing java frameworks and libraries.

Re: New languages are always good

This does not make sense, you can bring ideas without having a new language.

Plus many languages should not have been: Cobol, PL1, Ada, Javascript are coming to mind.

Not every idea is good, but I suppose you will say that even errors are good ? Kind of an autopromoting argument. As for Kotlin ??? No comment.

Re: New languages are always good by M Vleth

No, that's not what I'm saying. New languages give room to new ideas (new language features, constructs, etc) that might not be possible in current languages. They might be good enough for other languages to pick up, or they might not. So for instance javascript (since you blacklisted it) is one of those languages that helps promote higher order functions and some other functional programming related concepts. It did not invent it but certainly helped the acceptance of it and we are finally see this appear in Java8.

In this Loop case the emphasis on transactional memory approach is a nice one. Other languages might have this but that doesn't matter. What matters for instance is that you can't just incorporate this in the Java language, it would break way to much. And therefor this language might push an idea. We can all asses whether it's a good approach or not and thrive progress with that.

So it does make sense, whether you want to see it or go religious about it is a whole new debate ;-)

Re: New languages are always good

So everything is good for you ?

I suppose you also think that Hitler helped humanity ?

As far as Javascript, it slowed down robust app development on the web for many years.
Still today (even if it improved), it is a weak alternative to many other languages that are not available in browsers (why ?)

While I am all for experimenting, no all experiment should make it to the main stream, imagine if we did the same in the pharmacetical industry ?

No, not everything is bringing good, you might consider that a religion, but it is simple good sense.

Re: New languages are always good

Godwin's law apparently holds.

Also the process of selection works only if there are things to select from...

Re: New languages are always good

Yes but, programmers like oil is not an unlimited ressource.

Natural selection is a blind process, I would expect better from humans

Re: New languages are always good by M Vleth

Are you actually trying not to understand what others write or are you simply incapable?

I've thrown tons of 'mights' in there so you could understand my position, yet you continue to resort to absolutes. The absolutes are neither stated nor implied. I actually agree with you that not all languages should make it to mainstream, and that is what I and others are saying.

So, fine, let us call them 'experiments' if that makes everybody happy. It's good that people try to add with those experiments so we can learn from them.

Re: New languages are always good

So everything is good for you ?

en.wikipedia.org/wiki/Straw_man

I suppose you also think that Hitler helped humanity ?

Bringing up Hitler is such an infantile way to build a counter-argument. It works if you want to quote things out of context or to appeal to emotion. From a logical POV, if you really have to rely on such a thing to defend a point, either you do not fully understand the point, or you never had a valid point to begin with.

Re: New languages are always good

Yes but, programmers like oil is not an unlimited ressource.

Natural selection is a blind process, I would expect better from humans

Indeed, like bringing up Hitlerian Strawmans to programming language arguments. Natural selection should have taken care of that, but it didn't. So your expectations from humans is faulty (and faultily self-applicative in this particular case.)

Re: New languages are always good

The mentality here is everything is good.

My point is stop creating new things when the ones already there are excellent.

More means nothing if it does not improve significantly.

Re: New languages are always good

More means nothing if it does not improve significantly.

Makes sense - the most important part being "improve significantly". Minor improvements rarely justify the cognitive shift needed in learning new things, especially if we haven't yet hit a ceiling with the existing tools.

Re: New languages are always good

I suppose you also think that Hitler helped humanity ?

Oh dear. Fail.
Close

#### by

on

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

16 Discuss

Login to InfoQ to interact with what matters most to you.