Languages From Hell -- Jolt (aka A.)

"Mark Hopkins" <mark@omnifest.uwm.edu>
Wed, 12 Oct 1994 09:01:17 GMT

          From comp.compilers

Related articles
Languages From Hell -- Jolt (aka A.) mark@omnifest.uwm.edu (Mark Hopkins) (1994-10-12)
Re: Languages From Hell -- Jolt (aka A.) hbaker@netcom.com (1994-10-14)
| List of all articles for this month |
Newsgroups: comp.compilers
From: "Mark Hopkins" <mark@omnifest.uwm.edu>
Keywords: design
Organization: Compilers Central
Date: Wed, 12 Oct 1994 09:01:17 GMT

      This is a language which has had a long history in development but hasn't
seen the light of day until now. Its history is as bizarre as the language
itself is -- filled with numerous serendipities and synchronicities.


      Anyway... it all started back in 1987 I read an article by Backus
condemning the Imperative languages and bringing up the idea of Functional
Programming. All the criticisms totally flew in the face of my experience,
actually contradicting it, so it was my intent to definitevely refute Backus
with the creation of a purely functional programming language with an
imperative syntax and semantics -- an imperative functional language. I
already had something specific in mind and it has turns out to be a completion
of Landin's abortive attempt to the same kind of thing in 1965. It also turns
out to be a completion of Landin's SECD machine.


      A precursor to its design is the C-BC interpreter (a major extension to
UNIX BC) released last year. The interpreter is based on an abstract machine
which happened to bear a remarkable resemblance to none other than Landin's
SECD machine. This led to the eventual formulation of the Regular Infinite
Lambda Calculus, and the SEQCD machine (the details of which may be found in
comp.lang.functional).


      An interesting question arose: what kind of notation does one use to
represent infinite lambda expressions? Well, that's where the story gets
interesting.


      A few weeks back, as you'll recall, the thread "Languages from Hell"
was started. As it turned out, that was also the day I came up with the idea
for a practical joke: to design a language so bizarre and reactionary that it
would make even C look like a purist's dream in comparison. The name was
christened in honor of the reactionary soft drink: it has twice as much of
what you don't want in it.


      In a twist of irony, it turned out that this design for the language
EXACTLY matched what's needed for the front end to the SEQCD machine. So in
one fell swoop, all these projects converged into one and each completed the
other, and as a result, the original project dating from 1987 just falls out
for free.


      Thus it is with pride that I announce the creation of a new language
called JOLT, with the release of a SEQCD JOLT interpreter set for the near
future. This is the first of several generations of JOLT (or in its
abbreviated form: A.).


      What follows is a brief description of a more complete version of JOLT.
The call-return mechanism is not currently present.


      JOLT is a purely functional language which provides a front-end for the
Infinite Lambda Calculus. Its syntax is Imperative and includes the
while loop, goto statement and assignment statement. Yet, all of this is
syntatic sugaring for the Lambda Calculus. Their respective behaviors,
though consistent with the behavior of imperative languages, are only
epiphenomena arising from the interpretation of the Lambda Calculus itself.


      JOLT is thus simultaneously a language with variables and an assignment
statement, and is declarative. Side-effects are purely epiphenomenal.
Even though it has gotos, it has no control structures, again, except as
epiphenomena.


      Among other things one of its features is that every sequence of statements
ends in an evaluation of an expression (which is defined to be the sequence's
value) and that a goto label takes on the value of the sequence it labels.


      The C-like statements
                                                  return
                                                  break
                                                  continue
                                                  goto X


all take on the values of the labels they refer to. So


                                        if (return) Y = goto X;


is a possible statement. What it does is return from the procedure
call, carry out the rest of the sequence after the procedure call until the
top-level sequence (the program) is completed, and then comes back with the
resulting value. If the value is non-zero, it resumes at the goto label X
ultimately to the end of the program again and comes back with the result and
assigns it to the variable Y. Then it goes on to the following statement.


      Writing a parser for JOLT will turn out to be a nightmare for anyone using
YACC or (for that matter) any automated parser utility. This is because for
all practical purposes the language defined by a transformational syntax
a' la Chomsky of Linguistics fame.


      The language, you see, does not actually have any statements (except,
again, as epiphenomena). Everything is an expression, and "statements" are
just expressions with holes in them. When the "statement" is evaluated, the
hole is given the value of the sequence following the "statement". Some
places will make use of expressions with holes in them. For instance, the
while expression has the syntax:


                                          while (E1) E2 E3


where E2 is an expression with a hole. It evaluates to the conditional
expression (which has a C-like syntax):


                                      x: (E1)? E2': E3


where E2' is the result of substituting a "goto x" in the hole in the
expression E2. Of course, it's entirely possible that E2, itself, could
take on the form:


                                        E2: while (E4) E5 ()


(the parentheses won't actually be necessary, but help emphasize the hole) so
that the entire expression will effectively be a nested loop, evaluating
to the following:


                              x: (E1)? goto y: E3
                              y: (E4)? E5': goto x


where E5' is the result of substituting "goto y" in the hole in E5.


      As you can see, this language can get pretty bizarre.


      From another point of view, what distinguishes this language is that it
consists entirely of gotos. As you can see above, the while loop is just
a syntatic sugaring for an expression containing gotos. JOLT is so
unstructured at its most basic level that even assembly language looks like a
high-level programming language next to it.


      Being functional and imperative A. is pretty much everything you want and
-- even better -- pretty much everything you don't want, too. It even has
the lambda operator in it. It was purposely designed to aggrivate people and
to aggrivate the purist community by sticking a thorn in their side in the
form of a language looking like their worst nightmare and yet behaving like
their most erotic dreams. Its design started out as a practical joke, and
it's with pride that I state here that A has retained a large portion of its
legacy.


      This is a A. code fragment (actually, it's a complete program):


                  X = 0; Y = 1; while (X < N) ( X++, Y *= 2; ) Y;


The second argument of the while expression is an expression with a hole in
it. Explicitly it looks like this:


                                              X++; Y *= 2; ()


Other possibilities may arise, though, and this is what gives JOLT its
bizarre flavor. One can have any of the following in the body of the
while loop:
                                      X++; Y *= 2; ()
                                      X++; Y *= 2; -- equivalent to the previous expression
                                      X++; Y = () * 2; Y
                                      X = () + 1; Y = Y * 2; Y


and so on. Expanding the while loop above in full results in the
infinite lambda term:


                  let X = 0 in let Y = 1 in q
                  q: X < N? ( let X = X + 1 in let Y = Y * 2 in q ): Y


which when fully written out takes the form:


                  let X = 0 in let Y = 1 in
                        X < N? (
                            let X = X + 1 in let Y = Y * 2 in
                                  X < N? (
                                        let X = X + 1 in let Y = Y * 2 in
                                              X < N? (
                                                  ...
                                              ): Y
                                  ): Y
                        ): Y


This can be evaluated using the SEQCD machine. What this machine will do --
and this is quite miraculous -- is that it will effectively create two
variables, X and Y, initializing them to 0 and 1. Then it will traverse the
loop labeled by q overwriting the values of X and Y with their updated values
on each pass, and the loop will terminate discarding the variables and
returning the resulting value of Y. That's actually demonstrated at the end
of the SEQCD article.
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.