Martin Fowler says “Lisp is probably the strongest example of expressing DSLs directly in the language itself.”
The example problem posed in that article is to read and parse some sort of log of service call records:
#123456789012345678901234567890123456789012345678901234567890 SVCLFOWLER 10101MS0120050313......................... SVCLHOHPE 10201DX0320050315........................ SVCLTWO x10301MRP220050329.............................. USGE10301TWO x50214..7050329...............................
Rainer Joswig came up with a nice little Lisp solution, which boils down to this:
(defmapping service-call "SVCL" (04 18 customer-name) (19 23 customer-id) (24 27 call-type-code) (28 35 date-of-call-string))) (defmapping usage "USGE" (04 08 customer-id) (09 22 customer-name) (30 30 cycle) (31 36 read-date)))
Which I think looks perfectly natural to any Lisp programmer.
You can see exactly the same sort of process at work in the Practical Common Lisp chapter on parsing MP3 files:
(define-binary-class id3-tag () ((identifier (iso-8859-1-string :length 3)) (major-version u1) (revision u1) (flags u1) (size id3-tag-size) (frames (id3-frames :tag-size size)))) (define-tagged-binary-class id3-frame () ((id (frame-id :length 3)) (size u3)) (:dispatch (find-frame-class id)))
(I finally sat down and read my hardcover copy of Practical Common Lisp; I was very impressed. The design and coding is elegant, the exposition was extremely lucid, and the practical chapters are engaging. Thumbs up.)
You can see that there are some benefits to writing your DSL in your host language as opposed to in XML.
[Oops. I just saw that Bill Clementson already posted about this very same thing.]
Posted by jjwiseman at July 06, 2005 12:07 PMWhile Lisp macrology is nice for the obvious reason that Lisp eschews the distinction between surface syntax and abstract syntax, a language that retains the distinction but still has a programmable parser is also very nice. I'm referring, of course, to Objective Caml and its camlp4 parsing and pretty-printing system. On a small scale, you see campl4 used to do things like embed parsers and lexers directly in source code. On a somewhat larger scale, that of a full-blown, albeit modest, DSL, there's the example of Graydon Hoare's One-Day Compilers.
The example of Practical Common Lisp's binary-file parsing macros is indeed a very good one—so good that I intend to rewrite them as camlp4 syntax extensions for O'Caml for a project I'm working on.
Posted by: Paul Snively on July 6, 2005 12:51 PMIt may interest some people reading Planet Lisp to know (in case it hasn't already been posted) that APress/Bookpool are having a sale where you can get Practical Common Lisp (and other APress books) for half price.
-- Nate
Posted by: Nate on July 7, 2005 05:21 AMForth is also quite good at this sort of metaprogramming. I seem to be continually drawn to languages (such as forth and lisp) that are good at metaprogramming/dsl evolution. Curiously, they both have elegant fundamental language definitions that will fit on less than a sheet of paper.
Posted by: David Mercer on July 7, 2005 04:36 PMWhat discussion about dsl and lisp would be complete w/o "A Universal Scripting Framework or Lambda: the ultimate 'little language'": http://www.cc.gatech.edu/fac/Olin.Shivers/ll.ps
Posted by: mds on July 10, 2005 11:42 PM