DSLs are still fun

Now the popularity of DSLs may have waned, but the fun surrounding them surely has not.
A while back James and I looked into implementing a DSL for modeling insurance products in Java that worked really nicely:

  • built on top of Java we’ve full access to all its goodies like the libraries and object system and containers
  • integrates with Eclipse to get code-completion and error-reporting and intelligent-debugging
  • open-source so we can tweak and bug-fix as needed

If that is your cup of tea, you might have a look at this super awesome tutorial on implementing a brainf*ck interpreter on top of the Racket programming language:
http://hashcollision.org/brainfudge/
Basically you get all the power of what Racket has to offer as a language, its libraries, it’s IDE, and the great users.
The article is sort of funny in that the first version of the DLS was deemed “too slow” at 37 second vs 16 second for the version running on the PyPy interpreter; so the author went about optimizing it with all sorts of tweaks that are might be inappropriate for an entry-level article, but for bragging rights… dropping its benchmark speed down to 1 second.

Javathcript

kybernetikos shared with me a link to his Lispy language implementation on Javascript:

Javathcript allows you to script your web pages in a simple lisp variant. Once you include Javathcript.js, any script tags in your document with type=”text/lisp” will be evaluated. It will also download lisp files (only from the original server), if you have a script tag that has a src attribute. Finally, you can also evaluate lisp code from javascript using Javathcript.eval(lispString).
While it is not an exact implementation of any pre-existing variant of lisp, if you know lisp most of it should be familiar. If you don’t you might find it useful to follow a tutorial, e.g. this one. There will be differences between this implementation and others, but there is also much that is common.

It has more features than are shared in the blurb.
Looks pretty neat; check it out!

Do Scheme implementors take hygiene seriously?

Even the vast majority of Scheme systems, the platform that has experimented the most with hygiene, provide unhygienic defmacro-style macros—presumably because not even Scheme implementors take hygiene very seriously.

— Let Over Lambda, Chapter 6
Hygiene is in the standard here.
(via Racket-users)

Racket on Racket?

There is a precedent for hosting other languages on top of Racket by compiling their syntax down to Racket. What got me thinking other languages on Racket was Shriram’s P4P article, and also to some degree a discussion surrounding Gambit’s SIX. It got me wondering…
Would PLT have anything to gain from providing a non-parenthesized language created specifically for Racket? What I mean is take Racket, remove the stuff too hard to do without parens, and offer that up as an “official” Racket language. This is not the same as implementing Java on Racket.
How difficult would it be to “come up with” such a language? I’m totally ignorant regarding language design. Would it be interesting… or boring and a waste of time?

A Proposal Against Parentheses in Racket

P4P:

This document proposes an alternate syntax for Racket. It reduces the parenthetical burden, makes the language appear more traditional, and respects indentation, though not in the way you think. It does all this while retaining the essence of Racket syntax, and even offering a high degree of tool reuse.

(via Racket-users)

Calling Java Under Cygwin

While trying to set up Clojure under Cygwin I found that doing mixed-mode between Cygwin and Java isn’t very happy due to the ‘;’ vs ‘:’ in the classpath.
This post (via this post) provided an obfuscated Ruby program to take care of that for you… thanks!

#!/bin/ruby
# Slightly obfuscated cygwin + windows java wrapper, automate cygpath
cpi = ARGV.index("-cp") + 1
cp = ARGV[cpi] if cpi
XBCP = "-Xbootclasspath/a:"
xbcpi = ARGV.index{|i|i=~/^#{XBCP}.*/}
xbcp = ARGV[xbcpi] if xbcpi
if cp or xbcpi
  def convert_paths(paths)
    paths = paths.gsub(':', ';').split(';')
    paths.map{|p|`cygpath -aw #{p}`.strip}.join ';'
  end
  ARGV[cpi] = convert_paths(cp) if cp
  ARGV[xbcpi] = XBCP + convert_paths(xbcp.sub(XBCP, '')) if xbcp
end
java = '/cygdrive/c/Program Files/Java/jdk1.6.0_18/bin/java'
cmd = .concat ARGV
def e(s); "\"#{s.strip.gsub('"','\"')}\""; end
exec(cmd.map{|a|e a}.join(' '))