leah blogs

August 2006

29aug2006 · Sublanguages: Embedded general-purpose languages

In the past, Ruby often has been popularized as a language suitable for building DSLs (Domain Specific Languages). Its flexible syntax (e.g. mostly optional parentheses or newline as statement terminator) and language facilities like blocks or powerful run-time introspection and metaprogramming make this possible.

Domain specific languages are, nomen est omen, specific to a certain domain that in some ways deserves programmability. Therefore, while certain languages considered as DSLs are in fact Turing-complete (think of XSLT, sendmail.cf or TeX), they aren’t very suitable for general-purpose programming. For Rubyists, this is no problem, given that embedded DSLs implemented in Ruby often can use the full power of Ruby.

However, Ruby is powerful enough not only to implement embedded DSLs, but also to implement embedded general-purpose languages. I’ll name these sublanguages.

Why sublanguages, if you have Ruby?, the sceptic may ask. The reason is easy: while libraries implement functions, sublanguages implement programming paradigms.

Out of the box, Ruby already supports some programming paradigms pretty well. These are:

  • Class-based object oriented programming, since “everything” in Ruby is an object; this probably is Ruby’s main paradigm.

  • Functional programming with powerful and side-effect free methods in the core (e.g. due to Enumerable) and code as first-class objects (Proc).

  • Imperative programming due to modifyable variables, sequential execution and eager evaluation.

These three paradigms probably are the ones the creator of Ruby cared most about, which is why they are so well-supported by core Ruby. They also are the three most popular paradigms as of today.

However, due to Ruby’s flexibility, it is relatively easily possible to also implement other programming paradigms in Ruby. In a series of posts, I hope to present implementations of these:

  • Prototype-based object oriented programming, featuring object-orientation not by defining classes, but by cloning and refining objects. (Inspired by Self and Io).

  • Concurrent programming, with Erlang style processes and message passing.

  • Declarative logic programming, as seen in Prolog.

Please note that almost everything is possible to implement using Ruby with some ugly hacks. I’ll try to avoid these very hard to make the code suitable to a general public, and not only for academic use. It’s still very hard to encode these paradigms with reasonable speed compared to a proper native implementation. Wherever possible, I’ll try to make useful optimizations.

Code can be found at my darcs repositories.

NP: Spiritualized—Cool Waves

Copyright © 2004–2022