
The Nature of Lisp (2006) - taheris
http://www.defmacro.org/ramblings/lisp.html
======
Slackwise
This was the page that made me finally grasp why Lisp and s-expressions are
relevant. After reading this about a year ago, I ended up picking up a Clojure
book and now I'm enamored with s-expressions. I feel late to the party.

The last time I tried to learn Lisp (prior to reading this) was in like 2003/4
from some CLISP tutorial that scared me away from having nothing but math
examples and zero explanation of the philosophy or design. It felt like an
esoteric and purely academic language, and I brushed it off as not worth my
time. (I was never really put off by the parens, and now I love them. Never
understood that aspect of Lisp discourse. Once you learn ParEdit[1] you don't
want to go back.)

Now I link this page whenever I want to explain to someone why there are "all
these parens". It's dated, though, and associating s-expressions with JSON and
JavaScript would probably be a more contemporary approach. Maybe I should
rewrite this article for a modern developer audience.

[1]: [http://danmidwood.com/content/2014/11/21/animated-
paredit.ht...](http://danmidwood.com/content/2014/11/21/animated-paredit.html)
"GIFs of ParEdit in action"

~~~
frou_dh
There's a "lisp parens lol" thing among programmers that's so intellectually
lazy. I once interviewed someone who I noticed had explicitly mentioned Lisp
on their resume, and when as an aside I asked what their thoughts on Lisp
development were, all they could muster was "Oh god the parens hyuck hyuck".

~~~
mbrock
Other languages tend to get a free pass, but I take every chance I get to
whine about JavaScript's three kinds of parens that I have to keep track of
manually, and the convention of putting nearly every closing paren on its own
line, wasting kilometers of space.

~~~
oldmanjay
Yeah that screen space, truly a limited resource. You should cram everything
together and don't forget to be extra clever in the middle of the dense
unreadable forest of sigils as well. It was hard to write, it should be hard
to read.

~~~
bad_user
While I agree that in programming we should break our code in logical
paragraphs, just like in prose, such conventions (placing closing brackets on
their own line) are detrimental for that purpose. For me this doesn't have
anything to do with wasting vertical space, as it has to do with aesthetics.

I'm not really speaking for LISP, but in my projects what really bothers me
are people that don't have common sense when indenting / formatting their code
and so they start using IDE or build plugins, using common conventions and
formatters that will never be able to understand the meaning of the code being
formatted, making a total mess of other people' carefully crafted code. And we
go round and round on this.

------
brandmeyer
One of the aspects of the data-is-code and code-is-data duality that always
bugged me surrounds security. Ever since we started embedded macro languages
into documents, there have been classes of security problems around them. Even
before the web there were macro viruses in abundance, and running spreadsheets
with macros embedded in them is still a dangerous proposition today.

How does Lisp deal with the modern Writable Xor Executable philosophy? Or does
it? Can a lispy program that exposes its lispyness to its users be secure
(emacs, I'm looking at you)?

~~~
raphaelss
Just like every other language.

You either

\- Expose the entire language and then there's not much you can do to prevent
something harmful.

\- Expose a subset of the language perhaps through parsing for harmful
patterns or by somehow making potentially harmful functions unreachable.

\- Expose a more restricted language (scripting like c/lua) that you control
and know its full capabilities.

The only difference I can think of is that it's easier to write flexible and
dynamically modifiable software in lisp than in most mainstream languages.

~~~
seiji
The end result has been years of (practical) research going into an actually
safe, actually sandboxed, actually secure cross-platform platform:
[https://developer.chrome.com/native-
client](https://developer.chrome.com/native-client)

~~~
brandmeyer
I raise my right eyebrow of incredulity at the "actually secure" claim,
considering that even Chrome regularly falls in contests like Pwn2Own.

~~~
seiji
Well, native client isn't chrome itself. Chrome has to deal with dumb OS
issues and platform interop. Native Client is more of a complete
data/instruction sandbox: [https://developer.chrome.com/native-
client/faq#security-and-...](https://developer.chrome.com/native-
client/faq#security-and-privacy)

Plus, they are taking their time (years and years and years) to get it working
properly before driving public adoption.

------
chinpokomon
I started trying to learn FP this last year. I started trying to understand
Clojure and then watched the SCIP lectures and worked through the problems in
the book with the class. At this point, I think I _get_ LISP.

What I don't get is how I build an application using LISP. From the article,
the todo list wasn't really a list, it was a todo function call that took
tasks as arguments unless there was a missing quote. That seems to be a point
missed by the author. With the macro, he was able to format the tasks
themselves, but after applying the macro you'd still be left with a todo
function and done arguments. I don't see where that gets called.

LISP seems to work best as an evolving environment. I can see where a LISP
machine could be powerful for defining your own DSL as you try to parse
through some data. I also saw the power in how you abstract the problem,
really taking advantage of code reuse in a powerful way. I don't see how you
write an application.

Is there some resource or there that can help me bridge this gap? I feel like
this is like trying to use Mathematica to write a program. Mathematica is
great for calculating as LISP seems great for processing data, but I'm stuck
in seeing how I can utilize it for anything beyond a contained process. At
least with Clojure or F#, I could still use Java or C# for the entry point and
call into an FP block of code for calculations and processing. How would I do
something with Haskell or Scheme?

~~~
karamazov
Eventually, some of your code will make a call to IO: reading from or writing
to disk, responding to a web query, updating a DB, drawing something on the
screen, etc, etc.

For example, you could put up a web server written entirely in Scheme or some
other dialect. This would process and respond to queries entirely in Scheme,
including some sort of engine for generating and serving html. Hacker News
itself is an example of this: it's written in a lisp dialect called Arc.

Incidentally, Haskell is functional, but it isn't a lisp.

~~~
chinpokomon
Yeah, I know that about Haskell, but my question was about FP in general. I
didn't know that about HN. I'll just have to keep looking I guess.

~~~
codygman
> I could still use Java or C# for the entry point and call into an FP block
> of code for calculations and processing.

If you post an example of this to Github (or similar) I can help you replace
the Java or C# entry point with a Clojure or F# entry point.

------
roneesh
I've read and heard the commonly echoed sentiments about Macros being used to
build a language for your application. I'm a bit confused in how this is
philosophically different than just writing domain specific classes and
functions? Can someone point to an example where the syntax allowed by Ruby or
JS produced obfuscated code and a LISP macro produced something really simple
comparatively?

~~~
AnimalMuppet
It's the difference between introducing new nouns and verbs, and introducing
new grammar.

With new classes, I add new nouns (Circle, for example). With functions, I add
new verbs (move, for example). And I can add adjectives and adverbs
(attributes and arguments). This lets me build a "new language" (for handling
shapes, in my example).

But macros let you go much further. They let you change the syntax, so that
instead of saying "shape.move(newCoords)", you can say "move shape newCoords",
for example, _even though that was not legal syntax in the language you 're
writing in_. That's where it really becomes _a new language_ \- not just new
words.

But if you've got "good enough" syntax in the language you're writing in, you
might not see that as particularly useful. That is, the less impoverished your
out-of-the-box implementation language syntax is, the less you need macros.
(Most of the examples say "it's awkward to write this; I can write a macro to
make it easier". Well, that's great and all, but awkwardness of writing
something that I don't write very often in the first place does not make me
want to run out and adopt a macro language.)

------
AnimalMuppet
Lisp syntax looks _really_ good after you try doing the same thing in XML...

~~~
spacemanmatt
...shades of Spring application.xml

------
TheMagicHorsey
With macros being so easy to write, and so idiomatic to the way the language
is used, isn't it very difficult to understand a Lisp codebase that you are
unfamiliar with?

While I like Lisp a lot for my own projects (well Racket in Dr. Racket to be
specific), I don't feel very comfortable trying to understand other people's
code.

Other languages like Go, for example, seem a lot more tractable when you have
to grok a large foreign codebase.

~~~
mbrock
Do you have concrete examples of this difficulty?

I very often find it difficult to understand code in non-Lisp languages, too.
For example, you may think you know Ruby, but that has nothing to do with
understanding Rails or its myriad metalinguistic tricks.

Abstractions are often difficult to understand, and require explanations.
Introducing a new abstraction, regardless of implementation language, puts the
burden on you to define it with clarity, to document its purpose and meaning,
and so on.

Lisp macros let you define abstractions in a certain way that's quite
powerful. Fortunately, Lisp systems also tend to have good provisions for
online documentation, and make available macro-expansion facilities that
immediately explain exactly what a given macro is doing.

------
ExpiredLink
> _Lisp is a way to escape mediocrity and to get ahead of the pack. Learning
> Lisp means you can get a better job today, because you can impress any
> reasonably intelligent interviewer with fresh insight into most aspects of
> software engineering. It also means you 're likely to get fired tomorrow
> because everyone is tired of you constantly mentioning how much better the
> company could be doing if only its software was written in Lisp. Is it worth
> the effort? Everyone who has ever learned Lisp says yes. The choice, of
> course, remains yours._

