RubyGoLightly Progress Report

I seem to have been missing in action for the best part of six months so
I thought it was about time I put together a progress report and pimped
the vapourware in hopes of finding some likeminded
miscreants/dilettantes to turn it into something more substantial.

There’re probably only a handful of people on here who’ll be interested
in what follows so I’ve marked it OT for those of you interested
exclusively in Ruby. Feel free to press delete, I won’t be offended :slight_smile:

== BACKGROUND ==

For those of you without long memories, a quick recap. At the tail-end
of last year Google released their Go language (http://www.golang.org)
onto an unsuspecting world. The brainchild of Rob Pike and Ken Thompson,
Go’s sort of a reworking of Limbo from Plan 9/Inferno with baked-in
concurrency and an inside-out approach to object orientation.

As those of you who’ve had the dubious pleasure of either sharing bar
space with me or sitting through one of my conference sessions on Ruby &
Unix, for all that Ruby’s my language of choice I still spend a fair
amount of time grubbing around in the C world. Love them or loathe them,
there are times when we all need systems-level languages to efficiently
solve certain kinds of problems.

The longterm goal of RubyGoLightly is to make Ruby a first-class citizen
in that sense, moving systems coding firmly and permanently into our
high-level world. I know it can be done as Ruby’s pretty much as
flexible as Lisp and Symbolics proved that an OS could be written in
Lisp with minimal dependence on assembly language. So the aspiration
isn’t so lousy even if I’m far from certain that I’m personally capable
of achieving it.

There is however one major roadblock to turning Ruby into a systems
language: existing runtimes just aren’t written that way. The closest we
have at present is JRuby, and even there if you want complete control
you still have to step outside of the Ruby mindset and hack Java, JVM
bytecode or probably even write JNI extensions in C.

Then there’s the question of an optimal Ruby runtime. There’s a lot of
implicit concurrency in the average Ruby program which to the best of my
knowledge isn’t being addressed by any of the existing implementations.
We live in a multicore world where it’s only natural that collection
enumerators etc. should be exploiting those cores for cheap scalability.
Admittedly writing concurrent systems in C can be a right pain in the
arse, and even in Java there are subtleties arising from the
architecture of the JVM so I’m not levelling criticism at anyone. It’s
just a fair observation that if I have four processor cores and a list
with 10K entries that map/reduce algorithms should use all four cores if
at all possible and return their results in approximately 1/3rd the time
of a naive sequential implementation.

Given that Intel are playing with 80+ core processors in the lab - and
that modern graphics cores have even more available horsepower via
OpenCL - there’s clearly an opportunity worth investigating.

Go does concurrency pretty well, especially considering that the runtime
is still in its infancy and will probably undergo considerable
optimisation in the future. It’s basically an implementation of Hoare’s
CSP so all the tricks that can be used in Occam etc. for clean
concurrency can be used in Go, and whilst it doesn’t yet support OpenCL
that’s just a matter of time and a sufficiently nasty itch being worth
scratching.

Another desirable trait for a Ruby runtime is decent browser
integration. I get really annoyed having to write heavyweight
client-side web code in JavaScript as to me it’s an ugly language. I’ve
probably never recovered from my painful experiences with NewtonScript
as I find the entire Self language family unbearable, and the same goes
for the slot-based GTK GUI stuff (sorry webGTK). Go has support for
Google’s Native Client so is ideal for injecting native code into web
content, including a Ruby runtime were it to exist. I love that idea.
Write your whole web app in Ruby, with identical abstractions.

The same thing could be achieved using a Ruby runtime written in
JavaScript (such as HotRuby) but to date that approach has stalled.
Basically writing any significant runtime platform is a significant cost
and taking anything beyond the complexity of a simple bytecode
interpreter means months of full-time hacking and serious cogitation.

The final thing in Go’s favour is that it can compile to native code for
bare metal - i.e. no OS at all, just a bootloader and an executable.
I’ve yet to play with that side of the language, but having written
assembler for embedded systems with no OS I would love to see a Ruby
runtime deployed in the same manner. From there it’s a short step to an
OS written in Ruby, and that means an OS any half-competent programmer
could understand in detail.

My colleague Romek and I have been boring people with that idea for
about five years now, and mad though it probably seems I still believe
it’s a goal worth pursuing.

Anyway, to recap: the world might be a better place with a Ruby runtime
that embraced pervasive concurrency in the runtime implementation, that
was platform agnostic, and that allowed systems-level coding to be
performed with the same ease we associate with Rails or even Sinatra. I
won’t pretend RubyGoLightly will tick all these boxes - right now it’s
an idea and ideas are by their nature transient. However it is certainly
a framework in which to explore whether such a Ruby is possible.

== GoLightly ==

There are two aspects to this project. One is the Ruby runtime, which
right now I have only the vaguest of ideas about how to implement. I’m
following a hunch that a Forth-like Threaded Interpreter might allow
optimisations that we’re not going to see with mainstream bytecode
interpreters and a lot of current effort is devoted to writing such a
Forth implementation. Although I hesitate to call it Forth given the
usual expectations of F79, F83, figForth or ANS94 compliance - none of
them particular of particular importance.

Threaded interpretation isn’t a million miles removed from the naive
view of Ruby’s object model so I’m hoping my current work will generate
insights relevant to that, however its main purpose is to drive design
of the GoLightly virtual machine which is an abstraction of the kind of
hardware I’m interested in seeing Ruby run on.

There’s an early branch of GoLightly on github
(http://github.com/feyeleanor/GoLightly) which exposes some basic
despatch loops (inlined bytecode and indirect function call) and a
preliminary model for SIMD-style opcodes for basic vector processing and
a supporting register model.

There are a few examples of hand-coded assembler in the tests to give a
feel for the machine language along with some micro-benchmarks for
anyone who fancies playing. GoLightly already copes with multiple
virtual processors, all working on their discrete problems but there’s a
lot of work yet to be done in inter-core communication, the memory
allocation model, and parallelising SIMD instructions.

One of the few things I dislike about Go as it currently stands - and
which alas is considered a strength by the core team so is unlikely to
change - is that the language doesn’t support a representation-agnostic
datatype suitable for holding bit-strings: basically numeric types
always convert their contents to suit the type to which they’re being
coerced, or else a panic occurs. Getting around this involves playing
games with pointers that make a fair amount of (void *) usage in C look
clear and reasonable. The justification is that this sort of thing
shouldn’t be encouraged (with which I happen to disagree anyway) and
that the extra pain is a bit of nudge to prevent it. I’ll keep raising
the issue with the core team every few weeks as I personally believe
maintainability is much more important than type safety: after all, we
can always write tests…

Anyway GoLightly is stalled whilst I evolve a reasonable API for
handling bitstring manipulations, which is proving a subtly intractable
problem. I’m hoping that hacking together a few languages will help me
figure out most of the implementation details which are currently
eluding me and then I’ll roll a bitstring library back into the Go core
library if the team will have it.

The unnamed Forth I’m currently working on is running into the same
problems, but I’m still hoping to get a reasonable build ready for
release on github over the summer. So far I have a good first cut of a
compile/execute/decompile model which supports dynamic coding and I hope
to reduce much of the Go code for implementing a core vocabulary to
GoLightly-style bytecode. These bytecodes (which are effectively unique
to the currently running system, so more a dynamic object code than a
formal bytecode) would themselves be a first-class element of the
language so that’s an interesting model for both a native code interface
and for allowing inline use of multiple languages.

== The Roadmap ==

From Forth to Ruby is one hell of a leap, and whilst I don’t doubt it
can be done in one step there are other problems I want to solve along
the way.

I definitely see a simple Lisp being in the mix as I’ve always felt
there is an equivalence between Forth and Lisp which goes unremarked: I
guess there aren’t that many people who’ve hacked with both, let alone
who’ve written runtimes for both. Lisp will be the testbed for doing
standard function call stack allocations and a few other aspects of
implementing a high-level language which Forth skirts. Common Lisp it
most definitely won’t be though (or Arc for that matter).

From there I want to get a Scheme working, mostly to figure out how to
handle tail-call recursion efficiently. It could be that this will be a
specific compiler optimisation required separately for each supported
language, but I’d really prefer it to work at the object code level so
that it’s applied across all compiled code automatically. Go uses
relatively small stacks to improve concurrent performance compared to
pThreads and whilst GoLightly threads are currently specced to use their
own user-space threads I’d like to move beyond that in the future so
tail call culling will be essential to not swamping the runtime stack.

After Scheme I’m hoping to implement a simple Logo system to get a
handle on the interfaces offered by Google’s Native Client etc. - it’s a
bit of a gratuitous diversion as Logo is hardly a mainstream language,
but the underlying structure is similar enough to Lisp that I think it
will be an easy build and there’s been some interesting work in
Logo-land to do with multi-threaded graphics which might have
interesting tie-ins with OpenCL.

Much of the impetus to start hacking on RubyGoLightly is thanks to
TinyRb, a really sweet subset of Ruby running on a Lua-style VM. Once
I’ve solved the main runtime problems addressed by the Lisp arc of
languages I plan to write a runtime interpreter for the TinyRb bytecode
so its compiled form can run natively in GoLightly. My gut instinct is
that this will be a great starting point for runtime optimisations that
apply to a richer subset of Ruby.

At LSRC last year I showed off some of the code from a port of SQLite to
Ruby that I was working on at the time. That project got put on hold
when I started RubyGoLightly but given that SQLite is a really sweet
engine and internally uses a register based VM it’d be easy to port to
GoLightly and provide something like CoreData out of the box.

There could be a few steps after this: for one thing I’ve this gut
feeling that doing a dirty implementation of Io could be instructive,
though I can’t really explain way. Something to do with the method
passing semantics. A roadmap’s no good if it doesn’t allow for
interesting detours :slight_smile:

However the ultimate destination is RubyGoLightly, the Ruby runtime that
scratches the itch of using Ruby as a systems language. No promises
about where or when, and very few about how… but I promise to check in
with another status report in a few months that will hopefully be more
insightful.

In the meantime, happy hacking,

Ellie

Eleanor McHugh
Games With Brains
http://feyeleanor.tel

raise ArgumentError unless @reality.responds_to? :reason

On 07/03/2010 12:57 AM, Eleanor McHugh wrote:

I seem to have been missing in action for the best part of six months
so I thought it was about time I put together a progress report and
pimped the vapourware in hopes of finding some likeminded
miscreants/dilettantes to turn it into something more substantial.

There’re probably only a handful of people on here who’ll be
interested in what follows so I’ve marked it OT for those of you
interested exclusively in Ruby. Feel free to press delete, I won’t be
offended :slight_smile:

Elli, thank you for the elaborate report! I am not sure I get every
detail (mostly because I do not know Go and a few other languages you
mention). If I understand you properly your plan is to create various
language runtimes in Go - each one to help explore a particular class of
problems that need to be solved for the Ruby runtime that you want to
build eventually. Did I get that right?

Cheers

robert

On Sat, Jul 3, 2010 at 4:27 AM, Eleanor McHugh
[email protected] wrote:

I seem to have been missing in action for the best part of six months so I thought it was about time I put together a progress report and pimped the vapourware in hopes of finding some likeminded miscreants/dilettantes to turn it into something more substantial.

There’re probably only a handful of people on here who’ll be interested in what follows so I’ve marked it OT for those of you interested exclusively in Ruby. Feel free to press delete, I won’t be offended :slight_smile:

Fascinating stuff. I’ve always wanted to play around with Go, but have
been putting it off because I’m dabbling in too many languages
already. (My long term plan, though, is to use it to write a modal
text editor with an embedded scheme as its scripting language.
Basically a vim clone but using a real language to extend itself. Go
seems like an excellent choice of language to write the core in.)

martin

On 3 Jul 2010, at 14:00, Robert K. wrote:

Elli, thank you for the elaborate report! I am not sure I get every detail (mostly because I do not know Go and a few other languages you mention). If I understand you properly your plan is to create various language runtimes in Go - each one to help explore a particular class of problems that need to be solved for the Ruby runtime that you want to build eventually. Did I get that right?

Spot on Robert :slight_smile:

Ellie

Eleanor McHugh
Games With Brains
http://feyeleanor.tel

raise ArgumentError unless @reality.responds_to? :reason

On 3 Jul 2010, at 15:49, Martin DeMello wrote:

Basically a vim clone but using a real language to extend itself. Go
seems like an excellent choice of language to write the core in.)

I still find myself missing Ruby conveniences such as proper exception
handling and first-class meta-programming support, but it’s a remarkably
productive language compared to C(++) or Java. It’s also got a nice
simple testing framework that includes benchmarking support which I may
port to Ruby at some point - it’s much simpler than all the TDD/BDD
tools (which is probably why I like it).

There are a couple of Scheme implementations in Go which might fit the
needs of your editor, but if they don’t then let me know and I’ll see if
the GoLightly Scheme can be turned into a scripting engine.

Ellie

Eleanor McHugh
Games With Brains
http://feyeleanor.tel

raise ArgumentError unless @reality.responds_to? :reason

On 07/03/2010 04:49 PM, Martin DeMello wrote:

Basically a vim clone but using a real language to extend itself. Go
seems like an excellent choice of language to write the core in.)

yemacs? SCNR

robert

On Sun, Jul 4, 2010 at 1:45 PM, Robert K.
[email protected] wrote:

There’re probably only a handful of people on here who’ll be interested
yemacs? SCNR
not a huge fan of elisp either (:

martin

On Sun, Jul 4, 2010 at 7:26 PM, Eleanor McHugh
[email protected] wrote:

I still find myself missing Ruby conveniences such as proper exception handling and first-class meta-programming support, but it’s a remarkably productive language compared to C(++) or Java. It’s also got a nice simple testing framework that includes benchmarking support which I may port to Ruby at some point - it’s much simpler than all the TDD/BDD tools (which is probably why I like it).

There are a couple of Scheme implementations in Go which might fit the needs of your editor, but if they don’t then let me know and I’ll see if the GoLightly Scheme can be turned into a scripting engine.

Will do :slight_smile: Trying to decide between OCaml and Go right now for the core
engine.

martin

On Jul 2, 2010, at 5:57 PM, Eleanor McHugh wrote:

I seem to have been missing in action for the best part of six months so I thought it was about time I put together a progress report and pimped the vapourware in hopes of finding some likeminded miscreants/dilettantes to turn it into something more substantial.
[snip]

However the ultimate destination is RubyGoLightly, the Ruby runtime that scratches the itch of using Ruby as a systems language. No promises about where or when, and very few about how… but I promise to check in with another status report in a few months that will hopefully be more insightful.

Perhaps this will be of some interest?

http://github.com/brixen/gor

It is the Go language running on the rubinius VM.

cr

On Jul 6, 2010, at 2:31 PM, Louis-Philippe wrote:

vapourware in hopes of finding some likeminded miscreants/dilettantes to

http://github.com/brixen/gor

It is the Go language running on the rubinius VM.

Heh. :slight_smile:

Follow/watch the project and see if anything happens. It only hurts a
little.

cr

so many vaporwares with so little time on hands… which ones should I
choose!

2010/7/6 Chuck R. [email protected]

An eminently entertaining post! I think there’s even a few areas
you’ve added since we had a chance to talk last!

Seriously though…I think I’m starting to understand what you really
want from Ruby: real systems-level programming without a lot of weird
dynlang/VM encumbrances and a consistent but transparent abstraction
of platform-specifics. C with fewer “types”, higher-level APIs, and no
requirement for explicit memory-management. I’m in :slight_smile:

On Fri, Jul 2, 2010 at 5:57 PM, Eleanor McHugh

On 6 Jul 2010, at 19:56, Chuck R. wrote:

It is the Go language running on the rubinius VM.
Thanks for the link :slight_smile:

Ellie

Eleanor McHugh
Games With Brains
http://feyeleanor.tel

raise ArgumentError unless @reality.responds_to? :reason

On 8 Jul 2010, at 10:05, Charles Oliver N. wrote:

An eminently entertaining post! I think there’s even a few areas
you’ve added since we had a chance to talk last!

Glad you enjoyed it :slight_smile:

The basic roadmap’s been coalescing for a few years now based on my
experiences with implementing various languages and some VM design work
I did in the late 90s but the thought of tackling a project on this
scale in C or C++ was always too painful given I’d be writing all the
proofs of concept on my own. Just by having GC, CSP-style concurrency
and a reasonable hash table core data type Go’s already solved me months
of effort, and whilst it lacks Ruby’s handy meta-programming features it
has a few neat tricks of its own which make it quick to write and easy
to debug. I guess it’s the hammer I’ve been after for this particular
job…

Anyway as you can probably tell most of my current effort’s going into
the VM side of things and I’m keeping the details of that fairly close
to my chest for the time being so as not to raise any false hopes: a lot
of the ideas I’m playing with are a bit (?) mad and a nagging voice in
the back of my head keeps suggesting that mainstream VMs must work the
way they do for a good reason. However there’s a reasonable chance I’ll
be speaking at Strange Loop about GoLightly and VM design in general,
and if that goes ahead it’s possible I’ll have the next major release of
GoLightly on github around then.

Seriously though…I think I’m starting to understand what you really
want from Ruby: real systems-level programming without a lot of weird
dynlang/VM encumbrances and a consistent but transparent abstraction
of platform-specifics. C with fewer “types”, higher-level APIs, and no
requirement for explicit memory-management. I’m in :slight_smile:

Well that’s the dream.

The alternative is the nightmare vision laid out in my Plumber’s Guide
sessions: loading libc and pretending you’re a C programmer :wink:

Ellie

Eleanor McHugh
Games With Brains
http://feyeleanor.tel

raise ArgumentError unless @reality.responds_to? :reason