

The Art of Lisp and Writing (2003) - enduser
http://dreamsongs.com/ArtOfLisp.html

======
enduser
Choice quotes:

"Lisp is a medium for working with a computation until it is in balance with
its external and internal requirements. At that point it can be decorated with
performance-enhancing declarations and perhaps additionally modularized. In
this it is more like an artist's medium than what many think of as a
programming language."

"Writing a beautiful text takes sitting before a medium that one can revise
easily, and allowing a combination of flow and revision to take place as the
outlines and then the details of the piece come into view. Changes are made as
features of the writing emerge—first the noise, then the sense, the force, and
then the meaning—and the work of the writer is to continually improve the work
until it represents the best words in the best order. Great writing is never
accomplished through planning followed by implementation in words, because the
nature of the word choices, phrasings, sentence structures, paragraph
structures, and narrative structures interact in ways that depend of each
other, and the only possible plan that can be made with which a writer can
"reason" about the piece is the piece itself."

"The difference between Lisp and Java, as Paul Graham has pointed out, is that
Lisp is for working with computational ideas and expression, whereas Java is
for expressing completed programs. As James [Gosling] says, Java requires you
to pin down decisions early on. And once pinned down, the system which is the
set of type declarations, the compiler, and the runtime system make it as hard
as it can for you to change those assumptions, on the assumption that all such
changes are mistakes you're inadvertently making. There are, of course, many
situations when making change more difficult is the best thing to do: Once a
program is perfected, for example, or when it is put into light-maintenance
mode. But when we are exploring what to create given a trigger or other
impetus—when we are in flow—we need to change things frequently, even while we
want the system to be robust in the face of such changes."

~~~
seanmcdirmid
As someone who writes academically and writes code in the form of research
prototypes, I really have to disagree to some extent with RPG and PG. Code is
code, it doesn't have to be elegant, it doesn't have to be read, and using a
less elegant language (like say C#) can be liberating compared to one where
more elegance is possible (say Scala). The architecture you are working on
floats around in your head regardless, becoming more beautiful, and the
language that it is expressed in is just a detail...it is easy enough to throw
the code away and start again once it becomes too unwieldy and you need to
take your design to the next level.

But then RPG also wrote "worse is better."

~~~
klibertp
> As someone who writes academically [...] code [...] doesn't have to be read
> [...] it is easy enough to throw the code away and start again

That pretty much sums up the difference between academia and the so called
"real world".

~~~
jbooth
Yet LISP has much less traction in the real world than it does in academia.

~~~
lispm
not really

------
michaelwww
"Lisp is the language of loveliness. With it a great programmer can make a
beautiful, operating thing, a thing organically created and formed through the
interaction of a programmer/artist and a medium of expression that happens to
execute on a computer."

It's this kind of statement that makes me suspect Lisp is not very practical.
I'm not programming for the sake of programming to create something that
"happens to execute on a computer." There are other artistic endeavors for my
free time that are more interesting than a lovely computer language.

~~~
enduser
That's like saying that a walker allows you to traverse a floor more
"practically" than dancing.

~~~
michaelwww
So in your estimation all other computer languages are walkers compared to the
beautiful dance of Lisp? I'm curious, maybe I really do need to learn Lisp.

~~~
enduser
That is my estimation. If you don't need performance or macros, Python and
Ruby may give you a similar development experience. However, neither of those
languages AFAIK allows you to redefine (let alone recompile to native code)
functions at runtime.

~~~
Jimmy
Ruby is an extremely dynamic language, where you can redefine almost anything
at runtime:

    
    
      def f()
        puts "f1"
      end
    
      f()
    
      if true
        def f()
          puts "true"
        end
      else
        def f()
          puts "false"
        end
      end
    
      f()
    

This outputs:

    
    
      f1
      true
    

As for native code, apparently MacRuby [1] compiles to native code, although
I've never used it, so I don't know the details of that claim.

Can you give an example where redefining a function at runtime is a useful
feature to have? I don't mean this as a challenge, I'm just curious. I like
the extreme flexibility that dynamic languages provide, but it seems like the
most dynamic features are mainly useful for library writers.

[1] [http://stackoverflow.com/questions/1972388/is-it-possible-
to...](http://stackoverflow.com/questions/1972388/is-it-possible-to-compile-
ruby-to-byte-code-as-with-python)

~~~
Munksgaard
I don't think this is what enduser means. Lisp is the only language i know of
where you can run a function such as

    
    
      (defun foo ()
        (progn (format t "~a~%" (read-line))
               (foo)))
    

and then, while it is recursing, change the function to

    
    
      (defun foo ()
        (progn (format t "~a and john~%" (read-line))
               (foo)))
    

recompile it, and have the behavior of your program change, _while it is
running_. This is part of what makes lisp excellent for rapid prototyping. I'd
give more examples, but I'm lazy, and it's been properly described elsewhere.

~~~
Groxx
Seems pretty simple to me in Ruby.

    
    
      $ irb
      >> def go
       >   puts "what"
       >   debugger
       >   go
       > end
      >> go
      "what"
      # stops on debugger line
      >> Object.module_eval "def go; puts 'wat'; end"
      >> continue
      "wat"
    

There are of course other ways to do that, I just picked a simple one. You can
break at lines / statements in files, so you don't need to include that
"debugger" line. You can do something other than Object.module_eval. You can
use something like Pry that would make this simpler and give you in-line
source code, even after editing (IIRC). You can use something like Hijack to
modify any running Ruby process - when you disconnect, your modified code will
still be running.

Lisp _is not special_ in what it is capable of. Period. It's special because
a) it's very old, and b) it's _tuned_ for these features, in its own unique,
minimalistic way.

Yes, not all languages can do this (though you can do crazy things with GDB /
debuggers in general, including using it as a REPL for compiled languages
(really! it's not hard!)). But Lisp / the Lisp family are _not even remotely_
the only ones which can.

~~~
Munksgaard
That is indeed very handy, but I would argue that there's a difference between
running a program in a debugger and running it normally.

With regards to the rest of your post: macros and data-as-code.

Have you read this
[http://www.paulgraham.com/diff.html](http://www.paulgraham.com/diff.html) ?

~~~
Groxx
"What _Made_ Lisp Different" \- all true. All intended as past tense. I never
see claims that Lisp is unique because it has GC, for instance.

Looking at the 'setf' macro, since you have to use 'defsetf', I don't see the
difference between that and something in Ruby where you could do (errors
aside):

    
    
      class Object
        def defsetf(name)
          $setf[self.class] = name
        end
      end
      def setf(class, *args)
        class.send($setf[class], *args)
      end
      class Whatever
        defsetf :set_something
        def set_something; end
      end
      
      # elsewhere...
      setf Whatever, instance, value
    

Adding arbitrarily-complex ways to let you specify how to transform the
arguments to a call is as easy as accepting a lambda instead of a symbol,
recursive setf-ing[1] is just a lookup on the arguments and then nesting
lambdas. I might be missing some deeper realization here though - defsetf
seems pretty simple. Certainly the _use_ could be complex, but I see nothing
that implies that its _implementation_ is unachievable, even with nearly-
identical syntax, so what remains is library support and community. Again -
specialization, not unique attribute of the language.

As to "data-as-code", I think you mean the other way around? If not, eval. If
yes, Ruby's reflection is I think insufficient without heavy modification like
e.g. running a ruby interpreter in ruby to read its own source code and
"reflect" with the AST that generates (though this is possible[2]). This is
one spot where Lisp-likes certainly _excel_ to a degree few outsiders achieve,
but I'm sure I've seen outsiders, they're just not as fluent or efficient at
running it. But few outsiders have real interest in optimizing it, or people
label them as yet another Lisp-like, making the point sort of moot since it's
part of the definition of being Lisp-like (to many).

\--

Macros in particular come up often, but I don't see anything really
interesting about them. If you have the full AST available (a rarity, I'll
admit), then it seems like a strict subset of runtime modification - it's just
a self-eliminating runtime modification, done ahead of time for speed
purposes. Except for maybe C-style macros, which (via a horrible syntax) can
generate _anything_ , not just valid code, which isn't always possible.

[1]: (setf (sqrt something) number) => (set-sqrt something number) => (setf
something (* number number)) in here:
[http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h...](http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html)
found via here: [http://stackoverflow.com/questions/267862/what-makes-lisp-
ma...](http://stackoverflow.com/questions/267862/what-makes-lisp-macros-so-
special)

[2]: [https://www.ruby-forum.com/topic/1108988](https://www.ruby-
forum.com/topic/1108988)

~~~
lispm
> Macros in particular come up often, but I don't see anything really
> interesting about them.

Well, the experience of most advanced Lisp uses is totally different.

------
dschiptsov
_Ignorance more frequently begets confidence than does knowledge._ such a good
summary of Java (and now Javascript) madness.)

