Re: Metalanguages in environments where code is data.

Larry Wall (lwall@netlabs.com)
Wed, 9 Nov 1994 19:43:16 GMT

In article <id.QQFE1.XIE@nmti.com> peter@nmti.com (Peter da Silva) writes:
: In article <39bo03$d4e@csnews.cs.colorado.edu>,
: Tom Christiansen <tchrist@mox.perl.com> wrote:
: > :-> In gnu.misc.discuss, peter@nmti.com (Peter da Silva) writes:
: > :It has the same problem as AREXX and Python, in that it's a procedural
: > :and algebraic language,
:
: > For some things, that's just fine. I'm suppose that you think their
: > opposite must be the soi-disant data-driven or object-oriented programming
: > styles.
:
: I'm not talking about coding styles at all. I'm talking about a basic
: capability common to all Lisp-derived languages that there's no syntactic
: distinction between code and data. This makes it *easy* to define a
: metalanguage that's declarative, or embedded, or object-oriented, or
: what have you. You bring up the example of makefiles... converting a
: Makefile to Tcl (I'll use Tcl instead of Lisp or Scheme because I'm
: rusty in Lisp) is a simple mechanical *local* translation:
:
: CFLAGS=-O -g
: OBJS=main.o frob.o
: LIBS=-lreadline
:
: frob: $(OBJS)
: $(CC) $(CFLAGS) $(OBJS) -o frob $(LIBS)
:
: Becomes:
:
: source makefile.tcl
:
: set CFLAGS "-O -g"
: set OBJS "main.o frob.o"
: set LIBS "-lreadline"
:
: rule frob "${OBJS}" {
: shell "${CC} ${CFLAGS} ${OBJS} -o frob ${LIBS}"
: }
:
: make

You can do it almost exactly the same in Perl, except there's no
need to "eval" the final argument to "rule".

use Make;

$CFLAGS = "-O -g";
$OBJS = "main.o frob.o";
$LIBS = "-lreadline";

rule "frob", $OBJS, sub {
system "$CC $CFLAGS $OBJS -o frob $LIBS";
};

make;

: I doubt that a clean Scheme version would be much, if any, more complex.
: As you can see, the resulting Tcl makefile is just as readable and
: maintainable as the original. Why look, Tcl is now a declarative language!
: Nope... but the metalanguage put together from this subset of Tcl *is*.
: What was your other example? Oh, an embedded language. OK... here's how
: I'd do that:
:
: source runoff.tcl
: runoff {
: Here you can have your running text,
: isolated from the rest of the world,
: safely quoted,
: with embedded Tcl commands like [exec date]
: handily sucked into the code,
: with no effort expended whatsoever.
: I know this is little harder in lisp itself
: because I used a similar technique
: in an adventure program back in 1979 or 1980,
: in Lisp 1.5
: on the PDP-11.
: }
: flush
:
: In Perl you'd have to define some new encapsulation method for the procedural
: fragments associated with each rule of the makefile. Probably using HERE
: documents, I guess. You'd have to write some sort of parser for the running
: text. You're no longer using the SAME language in each place, and you're
: putting a lot more demands on the new language designer that the designer of
: a metalanguage doesn't have.

You're saying something that used to be true.

: I'm interested in the Perl way of getting something like the same result,
: though, so I'm feeding this back to comp.lang.perl.

This'll look pretty familiar... :-)

use Runoff;
runoff qq{
Here you can have your running text,
isolated from the rest of the world,
safely quoted,
with embedded Perl commands like ${\`date`}
handily sucked into the code,
with no effort expended whatsoever.
I know this is little harder in lisp itself
because I used a similar technique
in an adventure program back in 1979 or 1980,
in Lisp 1.5
on the PDP-11.
};
flush;

Larry