Sloop: Sublanguage for Object Orientation with Prototypes
The first sublanguage
I implemented is one for prototype-based object orientation, called Sloop.
Sloop was developed in a fully TDD-style and can be found in my darcs
repository.
To show its look and feel, we can implement the canonical example of
object orientation, an account.
Account = sloop {
self.balance = 0
def_deposit { |v| self.balance += v }
def_withdraw { |v| self.balance -= v }
def_inspect { "#(an account with $#{balance})" }
}
In Sloop, everything is a first-class object, even methods (unlike
Ruby, where only Method objects are first-class). Instead of
def_inspect, I also could have written:
self.inspect = Sloop::Method.new { "#(an account with $#{balance})" }
However, the syntactic sugar with def_name is
nicer to read and closer to ordinary Ruby.
Look how this code is used:
my_account = Account.clone
p my_account
puts "Depositing $10"
my_account.deposit 10
p my_account
On running, you see the expected output:
#(an account with $0)
Depositing $10
#(an account with $10)
The example however can’t fully show the flexibility of the Sloop
object system. Have a look at the Circles and Ellipses
example.
As you can see, a Circle really is an Ellipse, but they have
different implementations! In fact, since we can change the “class” of
objects at run-time, we even could cast Ellipses with the same radii
transparently into a Circle (the question is “when?”).
The Sloop object system allows for a lot of other powerful things that
don’t fit into this article (and after all, it’s still in
development). For now, I refer you to the source and unit tests.
(You may be curious about the condition mechanism, for example.)
NP: Spiritualized—I Think I’m in Love
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
Off to Munich and Essen
Vacation time has come again, and I’m off to
Munich from Sunday till Tuesday, and in
Essen from Wednesday till Sunday. Probably.
As usual, unlikely to have network in Munich (well, maybe some open
WLAN is strong enough by now), and unlikely to have lots of time
anyway. Mail and IRC usage will be reduced, tumblelogging probably
interrupted.
If you got something important, or want to meet me, you’ll figure how
you can contact me.
Happy holiday. Maybe I’ll get some writing for the blog done.
NP: Spiritualized—Electricity
Side-effects in real life
Two years ago today, I’d flip my
LSB.
Since I’m doing a lot of purely functional programming these days,
it’s not as easy like that this year:
import Control.Monad.State
data Guy = Guy { name :: String, age :: Integer }
introduce guy =
concat ["Hey, I'm ", name guy,
", and I'm ", show $ age guy, " years old."]
getOlder :: State Guy ()
getOlder = modify (\guy -> guy { age = (age guy) + 1 })
main =
let guy = (Guy "chris" 18) in do
print $ introduce guy
print $ introduce $ execState getOlder $ guy
Facts: Nineteen is a
centered triangular number, centered hexagonal number, and an
octahedral number. Every positive integer is the sum of at most
nineteen fourth powers. Nineteen is a Heegner number and a strictly
non-palindromic number…


NP: Ton Steine Scherben—Heute Nacht
MonetDB XQuery
XQuery is an XML technique that
unfortunately doesn’t get as much attention as it deserves.
Part of the reason is that there are not many XQuery implementations,
many use Java, some have ugly licenses and others are incomplete. One
that’s written in C with libxml2, Mozilla-licensed and pretty complete
is MonetDB XQuery, based upon the
MonetDB RDBMS.
A special thing about MonetDB is that it is not inherently SQL-based,
but supports several front-ends, among them SQL, but also XQuery.
Queries in both languages get translated into MIL (MonetDB Interpreter
Language), respective MAL (MonetDB Assembler Language) for version 5,
which doesn’t yet support XQuery, however.
MonetDB and the XQuery front-end compile (almost) out of the box, but
contain huge .c-files (up to 5 megabytes) due to code-generation
techniques. Be sure to have enough free RAM when you want to compile
it.
XQuery is a nice language (unlike it’s totally evil bastard brother,
XQueryX), reminding of languages like
OCaml, Links or XDuce. It’s probably what XSLT always should have
been.
I also think XQuery would make a great templating language (I used to
template websites with XSLT for years, which can be pretty painful at
times.), especially given virtual XML views. (I’m sure one can
implement those with MonetDB, but I didn’t try yet.) XQuery templates
would allow well-formed XML output by definition and generally ease
development.
Unfortunately, most XQuery engines, MonetDB inclusive, are pretty much
database-like. MonetDB provides a few helpers to automatically add
XML documents you use to its database, but they will be “shredded”
into relations nevertheless. This is probably a speed problem if you
want to apply one-shot XQuery programs on a large set of documents.
If you can store the data in MonetDB anyway, however, I could imagine
neat tricks given a light HTTP to XQuery wrapper. MonetDB doesn’t
support XUpdate at the moment, so XQuery-based web applications would
be read-only for now.
XQuery certainly is a thing that deserves more investigation.
NP: Bob Dylan—Like A Rolling Stone
Halbjahreszeugnis 12/2
Pünktlich nach Schützen kommen jetzt dann die Sommerferien, und
heute gabs natürlich Zeugnisse:
| Zeugnis des Gymnasiums 2005/2006 12/2 |
| Verhalten | gut |
| Mitarbeit | sehr gut |
| Sprachlich-literarisch-künstlerisches Aufgabenfeld |
| Deutsch | gut | 10 |
| Englisch | sehr gut | 13 |
| Bildende Kunst | gut | 11 |
| Gesellschaftswissenschaftliches Aufgabenfeld |
| Geschichte/Gemeinschaftskunde | gut | 10 |
| Ethik | befriedigend | 8 |
| Mathematisch-naturwissenschaftliches Aufgabenfeld |
| Mathematik | gut | 12 |
| Chemie | gut | 11 |
| Biologie | sehr gut | 14 |
| Sport | befriedigend | 5 |
| Wahlbereich |
| Informatik | sehr gut | 15 |
| Besondere Lernleistung: Landwirtschaft gestern und heute |
| Seminarkurs | sehr gut | 13 |
| Durchschnitt (Hauptfächer doppelt gewertet) |
| Durchschnitt | 2.0 | 11.471 |
Dieses Jahr also marginal schlechter als letztes (11.471
gegenüber 11.867), aber das ist man im zweiten Halbjahr eigentlich
immer.
Sport war scheiße, wird eben geklammert.
Außerdem hab ich noch einige ungebloggte Quotes gefunden:
Kann man auch nur 30€ zahlen und nicht in die Schule gehen?
Magdad Fenster auf!
Kannsch au bei uns komma.
[Relilehrerin:] Ich glaube nur, was ich sehe.
Die Katholische Kirche beledigt den menschlichen Verstand.
Wenn ich ein Buch lese, merke ich gar nicht, wie mich mein
Freund fickt.
NP: Dead Moon—In The Altitudes