
Ooh Ooh My Turn Why Lisp? (2008) - bootload
http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why-lisp.html
======
krupan
"The question is where will we be in five years, the answer is using Common
Lisp, because of language features" says the author in the comments. This was
8 years ago.

Kind of rude of me to take that potshot, but it's there. I've been reading
these "Why Lisp?" Arguments for years and yet it still remains pretty niche.
The longer this goes on the more I am unable tell Lisp advocates apart from
Perl advocates. They both sound like write-only languages. They make a lone
programmer feel very productive and Free, but it results in essentially
unmaintainable code. I've written and attempted to maintain much more Perl
than Lisp, many years ago, so please tell me if I'm wrong.

~~~
Frondo
Heh, yeah. Lisp has powerful features, I'm sure, but something that's always
stumped me is, if that power mattered for delivering better code, would we
have to strain so hard to find examples of why it's better?

Paul Graham's viaweb story, well, that's great, but why wasn't there a whole
cohort of super-powered startups winning the day with lisp in the original dot
com boom? Why are there so few big wins with lisp? The "lisp is powerful"
story just doesn't seem like the whole story, when there are so few successes
on the ground compared to C, C++, Python, Perl, PHP, Ruby, VB, you name it.

~~~
gkya
You confuse powerful with popular. Many startups don't need powerful tools,
other than a CRUD framework and JQuery. Also, existence and abundance of
libraries is a factor, and Lisp didn't get much love from the OSS web folks
til recently.

~~~
Frondo
Well, no, I'm not confusing powerful and popular. I'm asking why, for all
lisp's power, there's almost no examples of that power actually doing anyone
any good.

Is it because most projects don't need something powerful? The benefits of
that power aren't actually that great compared to the rest of the lisp
baggage?

We have this trope of the smug lisp weenie and there's definitely a whiff of
high wizardry around lisp, but who's actually shipping anything with it?

~~~
snaky
> doing anyone any good

There's a difference between doing and talking about. Compare an amount of
noise from Rust crowd to anything useful being done in Rust.

Let's look at only one product implemented in Lisp, by only one vendor, and
it's users in only one industry -
[http://allegrograph.com/healthcare/](http://allegrograph.com/healthcare/).
Pfizer, Mayo Clinic, GSK, Novartis - should we stop with that 'doing anyone
any good' mantra?

~~~
Frondo
The thing is, I'm trying to ask, if lisp is super-powerful and a secret weapon
(the general sense of the claims) why isn't the real world littered with
examples of companies who seriously out-competed using Lisp?

So far all people can do is say "no, SOMEONE is using Lisp!"

Well, great, but that's not the claim from the Lisp community.

The claim is that Lisp is powerful, so powerful that it's a secret weapon. Why
is there so little evidence of that power being meaningful in actual
competition?

~~~
gkya
The competition you're referring to is an economical one that's based on the
product. For any product which is a software application (whatever UI should
it sport, native, web based, remotely hosted, etc.), it's commercial success
is tied to its features and UX. For something like Amazon or Google, it's not
all that important if it's written in Lisp or BCPL or Prolog or whatnot,
that's irrelevant in the competition among products.

Lisp's competition is on a technical level with other programming languages,
and it's target audience is programmers. It can only help allowing easier
development of technology, more fluid continuity from idea to product, robust
and helpful debugging tools.

So writing a search engine in Lisp won't necessarily mean that you'll be one
step ahead of Google in search business in terms of end product, you still
need to come up with a better idea or better UX if you want to compete them,
and other factors like advertising, conversion etc are in the play too. But
with Lisp you may need less development resources to produce the product than
you'd need with C++ or Java.

------
hellofunk
I'm of the opinion that there is only one lisp right now with some serious
potential to dominate in the future, and that is Racket. Why? For one very
simple reason: unlike all other lisps, there is serious, ongoing, and lengthy
research into _correctly_ bringing a static type-checking process to the
language. Clojure's core.typed doesn't count here, as it is full of
significant holes that invalidate its entire point -- though, those holes are
very possibly getting filled in the coming years as they attempt to refactor
core.typed following the Racket model. But the Racket team is doing something
with lisp that is true to its core, not just with types, but with many other
features as well.

Interesting piece of trivia: this website you are reading right now is built
on top of Racket.

~~~
mordocai
It might be good to point out to you that the general industry cares very
little about things like this.

Racket could have literally the most advanced and robust type system out of
all programming languages in existence, and still be used by the same amount
of people as today and have a hard time convincing anyone else to use it.

What makes a language popular from what I have seen are libraries, frameworks,
and community.

Edit: Racket has all of the above, so obviously there are other factors as
well.

~~~
galdosdi
The general industry is in fact starting to care about static typing; I've
seen it happening lately. The last batch of hot languages included a lot of
untyped languages like Python, Ruby, and JS. But the latest batch of rising
star languages are typed, eg Go, Rust, Scala. And C/C++, C#, and Java are
still all going strong.

People are no longer buying the myth that the benefits of static typing can
only be gained at the expense of heaps of boilerplate. The gospel is slowly
spreading.

~~~
hellofunk
Don't forget Apple's new flagship language, Swift.

------
asimuvPR
The post linked has another interesting post in the comments:
[http://www.defmacro.de/?p=13](http://www.defmacro.de/?p=13) . Its about an
interview McCarthy gave in the year 2000 to infoQ.

------
einhverfr
It's a nice perspective. Very practical and down to earth. There is another
side though, and that is that learning to think of code as data is extremely
empowering and translates well when working with a fairly large set of other
languages (Perl, Python, Ruby, and now even Java). Learning Lisp turns you
into a better programmer.

~~~
agentgt
I like Scheme/Lisp but I don't know if I buy the whole "learning Lisp turns
you into a better programmer". Maybe more knowledgeable but not necessarily a
better a developer.

In some ways learning a really flexible language like Lisp can turn you even
into a really bad developer. I say "developer" instead of "programer" because
I want to emphasize working with others and thus sharing code with others. Of
course this is based on some past observations working with MIT grads and
various other academia so take my opinion with a grain of salt.

IMO the language that really changed everything for me was the ML family of
languages and maybe C. I would say knowing C and ML is more worthwhile than
Lisp (Lisp is not exactly hard to learn anyway... the basics that is).

~~~
ohyes
I'm biased, but there's a big difference between "learning lisp" (well enough
to transliterate that python program) and really getting the code as data
concept.

I'd say that learning X really well is always a positive because whenever you
learn something in depth you can then apply the concepts elsewhere. And there
are still lisp-only concepts, so learning lisp is positive. ML is good too.
Also spending time with a well designed concurrent language is beneficial.

~~~
agentgt
With Lisp I get the data thing but with ML you learn almost everything is a
language.

I can't really explain it but the whole variant/ADT pattern matching really
forces to make you think of your problem domain as a specification or language
(e.g. DSL). It is one of the reason why I think so many compilers are written
in ML (that and the toolset is awesome for it).

~~~
ohyes
Having looked up variants just now, I can definitely see how it would be
useful. It seems (to me) to fall into the same category of macro-like things
that enhance the expressiveness of the language. I think the most important
point is the idea of lifting the programming language into the problem domain.
When you can do this in a clean way, the result is a very readable solution
that you can reason about.

~~~
AnimalMuppet
I think there's a difference, though. With ML (IIUC), you build a language on
top of ML that is a set of functions (and the data structures they operate on)
that make it easy to express the program.

With Lisp macros, though, you change the _syntax_ of Lisp. You take things
that were not valid Lisp syntax, and you make them valid for your program.

So ML "language building" is in terms of _semantics_ , but in Lisp, it's _both
semantics and syntax_. (Again, IIUC).

------
catnaroek
> object identity for everything but numbers and characters

Since when is this supposed to be a selling point? Not having compound values
(not the same thing as compound objects!) is a pain.

~~~
oconnore
You seem to be very confused. This is referring to #'eq (which is why #'eql
exists). What lack of compound values are you lamenting? Lisp has built in
classes, structs, arrays, lists, and maps. What is missing?

> An implementation is permitted to make ``copies'' of characters and numbers
> at any time. The effect is that Common Lisp makes no guarantee that eq is
> true even when both its arguments are ``the same thing'' if that thing is a
> character or number.

[http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.h...](http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm#eq)

~~~
catnaroek
> Lisp has built in classes

Objects aren't compound values. Objects are compound, well, _objects_. And
pointers to objects are primitive, indivisible values - not compound!

> lists

Racket and ML have lists. Lisp has mutable linked data structures, built out
of `cons` cells, whose value at any given point in time may be a list. But the
value itself isn't first-class, because you can only bind the identity of the
cons cell to a variable.

~~~
oconnore
Contiguous memory structs:
[http://www.lispworks.com/documentation/HyperSpec/Body/m_defs...](http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm)

Contiguous memory vectors (multi-dimensional arrays, too!):
[http://www.lispworks.com/documentation/HyperSpec/Body/t_smp_...](http://www.lispworks.com/documentation/HyperSpec/Body/t_smp_ve.htm)

Native hash tables:
[http://www.lispworks.com/documentation/HyperSpec/Body/f_mk_h...](http://www.lispworks.com/documentation/HyperSpec/Body/f_mk_has.htm)

~~~
catnaroek
> Contiguous memory

I wasn't talking about the memory representation of anything. A first-class
value is something that a variable may denote. In ML, if the variable `xs`
denotes the list `[1,2,3]` within a given environment, it will always do so.
In Lisp, I can mutate the cons cells out of which `(list 1 2 3)` is built, so
what is actually bound to the variable is the object identity of the first
`cons` cell. Not a list value!

~~~
oconnore
Oh. You have a strange way of phrasing your critiques, but you're right, it's
all in IO/IORef.

~~~
catnaroek
I wanted to formulate my observation in very general terms, rather than
mention specific facilities of other programming languages. I also wanted to
avoid suggesting a connection with static types or effect segregation. The
main benefit of values over objects is that using values leads to designs that
have less moving parts, and thus are easier to understand, modify, extend and
test.

------
nurettin
For UI application programming You can do without FP language features. Hell,
you can even do without smart pointers checked arrays or GC.

But you cannot do without a decent desktop or web development experience. I
got involved with pretty large desktop applications written in delphi. The
design-time, the debugger, native compilation without having to install some
msvc runtime, deriving and combining visual components, it just gives a smooth
experience for desktop apps. If lisp has such well thought-out frameworks, I
would jump ship just to get at the language features it offers.

~~~
junke
Would you pay for it?

[http://www.lispworks.com/products/capi.html](http://www.lispworks.com/products/capi.html)

~~~
nurettin
I did buy frameworks for work, and this does look OK, but coding gui by hand
is not something our developers can handle in large scales.

~~~
junke
It seems that there is an interface builder.

[http://www.lispworks.com/documentation/lcl50/clwug/clw-216.h...](http://www.lispworks.com/documentation/lcl50/clwug/clw-216.html)

~~~
mark_l_watson
CAPI is pretty nice. Years ago, LispWorks gave me free licenses in return for
my doing some cleanup on their documentation. LispWorks is very good, but my
licenses are for what is now a very old version, so I now use SBCL and
sometimes Clozure. For industrial settings, LispWorks and also Franz are very
good products. I used Franz products on a medical large data project several
years ago, and their support was nothing short of amazing. That said, on the
same project we had an issue with SBCL and we simply paid one of the
maintainers to promptly fix the issue.

Sometimes it just takes spending some money.

------
mark_l_watson
Classic Kenny!

Common Lisp used to be much of my programming world also.

------
ww520
I want to see people's list of reasons for why not lisp.

Edit: Ok, this is not trolling. I quite liked Lisp and actually had
implemented a version of common lisp from scratch based the Guy Steele's CL
reference back in the undergrad time. I just found that beyond academic and a
few Emacs packages, I didn't use Lisp at all, for one reason or the other. I
just want to hear people's reason for not picking Lisp for their work.

~~~
ubertaco
I've tried on a few occasions to really like Lisp. I love it's simplicity and
recursiveness. The "code as data, data as code" thing is really cool.

But I love static typing. Not only for "safety-net" reasons, where the
compiler lets you know that you've broken stuff, but also for documentation
reasons (I don't have to guess at the shape of each "c" in "cs" in "(mapcar
some-fun cs)", I can just look at its type and know its shape), and I _really_
like it when that type system lets me be more expressive, like in MLs (where I
can pattern-match by the various members of an ADT and destructure them as I
go).

I also find that idiomatic Lisp likes to nest things too much to be _really_
readable for me. If I don't have types to tell me how the data's being
transformed, at least give me named functions and well-named variables instead
of very-deeply-nested anonymous functions everywhere.

And finally, I've never been completely convinced that macros are a great
idea. They're far too easily abused to create "the Scala problem" of having
code in language X that is still unrecognizable to someone else who also
writes in language X.

~~~
joshmarlow
I totally agree with you here; statically typed languages (OMG OCaml) are
great for making code very readable/documented, IMHO. I just have so much more
confidence in my code when the compiler has my back.

Another commenter pointed this out, but Typed Racket is a Racket variant
(which is a scheme-ish variant) that implements "gradual typing". I've played
with it here and there and am about to dive in again.

[https://docs.racket-lang.org/ts-guide/](https://docs.racket-lang.org/ts-
guide/)

------
unpop-opinion
Okay, I've spent a lot of time writing Common Lisp and even more time reading
about Common Lisp, and to be honest, I'm just a little tired of the cult
around it. People who know it well gloat about how great Common Lisp is, which
_just so happens_ to make them look great too. And people who _don 't_ know
Common Lisp all talk about the little Common Lisp they know, because they
don't want to seem like they aren't in on it, and because they don't know
better.

Let's talk about this fabled exchange between Norvig and McCarthy, where
McCarthy asks if Python can gracefully manipulate code as data, and Norvig
said no, and supposedly a thousand words were said in the ensuing silence.

Here's the thing; a thousand words _weren 't_ said. I don’t know what Tilton
thinks was said there, but it certainly wasn’t a one sided silence in which
only McCarthy’s side gets to smugly smirk as if it proves anything.

Let’s talk about code as data, shall we? What enables that? Of course, it’s
the s-expressions and prefix notation. So let’s write a macro. But we won’t
want to write a macro that simply sits at the beginning of an s-expression and
takes in a bunch of arguments, because then we could just write a function.
No, we want to do a transformation on the code that creates a domain-specific
language, because that’s the power of macros, right?

So the very first thing you do with your macro powers, and pretty much the
_only_ useful thing you _can_ do, is break s-expressions. Once the first macro
is written you can no longer assume that inputs to macros will be
s-expressions with the function at the beginning and arguments following.
Every future macro must account for every previous macro. The more you use the
capability to manipulate code as data gracefully, the less graceful it
becomes.

And, in my opinion, far more damningly, macros make your program harder to
reason about. Before macros, a reader could assume that the first thing in the
s-expression was operating on everything else in the s-expression. But no
longer. We can’t even assume that sub-s-expressions in the s-expression are
evaluated first.

This isn’t a hypothetical problem. Common Lisp programmers spend a ton of time
talking about how to write macros so that they’re not going to come back and
bite you in the butt when they get used in an unexpected situation. And the
reason is, nobody really knows how to do it.

So, with a great deal of respect for McCarthy based on his many other
achievements, I have to say I don’t care about macros, and actually think
we’re better off without them. First-class functions are a much more coherent,
consumable way of using code-as-data.

Most of the features of Common Lisp I actually want are in other languages
now. Garbage collection? REPLs? First-class functions? Higher-order functions?
They’re all in other languages now. Python, for example has all those things.

And to be honest, other languages have done a lot better things with the
functional programming aspects of Common Lisp. McCarthy gets credit for
inventing a lot of stuff, but we don’t fly Wright-brothers style planes today
and we shouldn’t use Common Lisp just because it was first to have those
things. More sophisticated type systems make lambdas more powerful (and
incidentally, a lot of the problems with macros can be seen as type problems).

People on this thread are claiming, “Learning Common Lisp turns you into a
better programmer”. But I tend to think that learning _functional programming_
is the part that people are referring to, and frankly, there are better
languages in which to learn functional programming. Haskell, Standard ML, or
OCaml would be a better choice.

And sure, there are other features that only Common Lisp has, but nobody is
talking about those. Restarts? I’d love to see more people experimenting with
those. Then again, Erlang has a way better threading model than anything else
and much more sophisticated pattern matching. Scheme has call/cc. Standard ML
has a powerful type system. Haskell has functional purity. Prolog has
unification. A great many of these are more interesting than restarts.

I don’t hate Common Lisp; if nothing else, Common Lisp has a few very solid
implementations out there and lots of existing libraries that make it a very
useful tool. There are some programs which I wouldn’t consider writing in
another language. I just don’t really think it’s the be-all and end-all of
programming languages any more, and I’m kind of tired of the cult that has
formed around it.

EDIT: s/Lisp/Common Lisp/g because not everyone takes “Lisp” to just mean
“Common Lisp”.

~~~
catnaroek
> So the very first thing you do with your macro powers, and pretty much the
> only useful thing you can do, is break s-expressions. Once the first macro
> is written you can no longer assume that inputs to macros will be
> s-expressions with the function at the beginning and arguments following.
> Every future macro must account for every previous macro. The more you use
> the capability to manipulate code as data gracefully, the less graceful it
> becomes.

You should check out Racket's macro system. It's a lot more sophisticated than
Common Lisp's. Common Lisp macros are to C (e.g., gensym is a macro-level
malloc, you need to manually destructure S-expressions, etc.) as Racket macros
are to ML and Haskell (syntax objects are aware of which variables are in
scope, so automatic fresh name generation is possible; user-defined syntax
classes and patterns let you process arbitrarily complicated structures in a
sane way, etc.). If you like the idea of metaprogramming, but `defmacro` left
you with a bad taste in the mouth, Racket is totally the language for you.

> First-class functions are a much more coherent, consumable way of using
> code-as-data.

First-class functions are easier to use than macros, but they are not “code as
data”. Furthermore, “code as data” itself is only true with a caveat: the full
version is ”code in an object language is data in the metalanguage”, which is
obvious to anyone who has written a compiler. Of course, macros make it easy
to use Lisp as its own metalanguage, but there's still a phase distinction
between macro-expansion time and when the generated code is actually used.

> And to be honest, other languages have done a lot better things with the
> functional programming aspects of Common Lisp.

Common Lisp is a ridiculously powerful language, but it isn't a functional
language. It fails to meet the zeroth nonnegotiable requirement in a practical
functional language, namely, a notion of compound value:
[https://news.ycombinator.com/item?id=12199981](https://news.ycombinator.com/item?id=12199981)

~~~
unpop-opinion
> You should check out Racket's macro system. It's a lot more sophisticated
> than Common Lisp's. Common Lisp macros are to C (e.g., gensym is a macro-
> level malloc, you need to manually destructure S-expressions, etc.) as
> Racket macros are to ML and Haskell (syntax objects are aware of which
> variables are in scope, so automatic fresh name generation is possible;
> user-defined syntax classes and patterns let you process arbitrarily
> complicated structures in a sane way, etc.).

Agreed. I did play around with this part of Racket quite a bit and I'm
convinced that it's the best system if I wanted to create a domain-specific
language. But it still runs into the problem where you're defining a new
language with new syntax, which forces you to define even more new language
with more syntax in order to make that language useful. It's the best way to
build a DSL

But given we already have a pretty good multi-purpose language with a lot of
work put into it (Racket) the number of situations where it's worthwhile to
create an equally-well-thought-out DSL is pretty low. Racket makes it _easier_
, but it's still not _easy_. Add to this the fact that other people are going
to write half-assed DSLs in my code, the net tradeoff is still usually
negative, even with Rackets clearly superior macro system.

> Furthermore, “code as data” itself is only true with a caveat: the full
> version is ”code in an object language is data in the metalanguage”, which
> is obvious to anyone who has written a compiler.

Uh, I've written a compiler and that's not obvious.

If you want to disagree with me on what "code as data" means, you're welcome
to do so. As long as you understood what I said I don't care which words got
me there.

> Common Lisp is a ridiculously powerful language, but it isn't a functional
> language. It fails to meet the zeroth nonnegotiable requirement in a
> practical functional language, namely, a notion of compound value:
> [https://news.ycombinator.com/item?id=12199981](https://news.ycombinator.com/item?id=12199981)

How about we assume when I said "functional programming" I'm using the
Wikipedia definition[1].

[1]
[https://en.wikipedia.org/wiki/Functional_programming](https://en.wikipedia.org/wiki/Functional_programming)

~~~
catnaroek
> Racket makes it easier, but it's still not easy. Add to this the fact that
> other people are going to write half-assed DSLs in my code, the net tradeoff
> is still usually negative, even with Rackets clearly superior macro system.

You have a point there. In any case, metaprogramming shouldn't be an everyday
activity.

> If you want to disagree with me on what "code as data" means, you're welcome
> to do so.

What I mean by “code in an object language is data in the metalanguage” is
that, in the (meta)language in which you're writing a compiler or interpreter,
the (object language) program that you're processing is represented as a data
structure (say, as a syntax tree). It's just a triviality, I'm not saying
anything really deep.

From this point of view, it should be clear that a macro system is essentially
a language-integrated facility for writing compiler plugins.

> How about we assume when I said "functional programming" I'm using the
> Wikipedia definition[1].

My definition of functional programming is “using (procedures that compute)
mathematical functions whenever possible”. A mathematical function is a
mapping from values to values, so if a language doesn't have a good notion of
(possibly compound) value, then you're going to run into trouble writing
procedures that compute mathematical functions.

EDIT: The Wikipedia definition essentially agrees with me.

“In computer science, functional programming is a programming paradigm—a style
of building the structure and elements of computer programs—that _treats
computation as the evaluation of mathematical functions_ [emphasis mine] and
avoids changing-state and mutable data.”

And a mathematical function is a mapping from values (in a domain) to values
(in a codomain). Again, quoting Wikipedia[0]:

“A function can be defined by any mathematical condition relating each
argument (input value) to the corresponding output value.”

[0]
[https://en.wikipedia.org/wiki/Function_(mathematics)#Specify...](https://en.wikipedia.org/wiki/Function_\(mathematics\)#Specifying_a_function)

~~~
unpop-opinion
> What I mean by “code in an object language is data in the metalanguage” is
> that, in the metalanguage in which you're writing a compiler or interpreter,
> the object language program that you're processing is represented as a data
> structure (say, as a syntax tree). It's just a triviality, I'm not saying
> anything really deep.

I understood what you were saying, and didn't ask for an explanation. I just
don't see why you felt the need to correct me on my calling first=class
functions "code as data" and substitute your own definition that had nothing
to do with what I was saying.

> My definition of functional programming is “using (procedures that compute)
> mathematical functions whenever possible”. A mathematical function is a
> mapping from values to values, so if a language doesn't have a good notion
> of (possibly compound) value, then you're going to run into trouble writing
> procedures that compute mathematical functions.

Again, I didn't ask what your definition was, because it wasn't relevant to
the conversation.

You're basically interrupting me to tell me I'm not using the same definitions
of words as you are, and it's not particularly endearing. If you don't
understand what I'm saying, I'll be happy to explain. If you do, however,
understand what I'm saying well enough to correct me on my usage of the
English language, then my usage of the language has been clear enough for my
goals, so I wouldn't be interested in your corrections even if they
represented HN's common usage (which they don't).

~~~
catnaroek
> I just don't see why you felt the need to correct me on my calling
> first=class functions "code as data"

Because first-class functions aren't “code as data”. When you have a first-
class function, the only thing you can do with it is call it. If it were a
data structure, you could analyze its constituent parts.

> You're basically interrupting me to tell me I'm not using the same
> definitions of words as you are,

The Wikipedia article you linked says:

“In computer science, functional programming is a programming paradigm—a style
of building the structure and elements of computer programs—that _treats
computation as the evaluation of mathematical functions_ [emphasis mine] and
avoids changing-state and mutable data.”

The emphasized part is just what I said. That a mathematical function is a
mapping from values to values is unquestionable - it's not something I'm
saying, it's a mathematical fact. So if you can't express compound values,
you're limited to a world where mathematical functions can only manipulate
primitive values.

~~~
unpop-opinion
> Because first-class functions aren't “code as data”. When you have a first-
> class function, the only thing you can do with it is call it. If it were a
> data structure, you could analyze its constituent parts.

There are lots of ways in which you can treat a first class function as data,
even if it can't be treated 100% equivalently to data in every single
situation. You can, for example, pass it to other functions like data. Sure,
most languages don't let you inspect the internals, but that's only one way of
treating code as data.

> The emphasized part is just what I said. That a mathematical function is a
> mapping from values to values is unquestionable - it's not something I'm
> saying, it's a mathematical fact. So if you can't express compound values,
> you're limited to a world where mathematical functions can only manipulate
> primitive values.

I said, "And to be honest, other languages have done a lot better things with
the functional programming aspects of Common Lisp." Common Lisp isn't a
_purely_ functional language, but it does have functional aspects. Note in the
article I quoted, that Common Lisp is the first language listed in the
"prominent programming languages which support functional programming such as"
section.

You're literally not even disagreeing with me, you're just defining
"functional programming language" as "purely functional programming language",
when I literally never even called Common Lisp a functional programming
language.

Insisting on your definitions instead of trying to understand what I said
doesn't make me want to engage with you further.

~~~
catnaroek
> There are lots of ways in which you can treat a first class function as
> data, even if it can't be treated 100% equivalently to data in every single
> situation. You can, for example, pass it to other functions like data.

Strictly speaking, you can't pass functions as data. You can only pass thunks
that, when forced, yield functions. A thunk is data, but a function is a
computation. Computations are “too active” to be stored or passed around
unthunked. The technical details are here:
[http://www.cs.bham.ac.uk/~pbl/cbpv.html](http://www.cs.bham.ac.uk/~pbl/cbpv.html),
[http://www.cs.bham.ac.uk/~pbl/papers/](http://www.cs.bham.ac.uk/~pbl/papers/).
(I am not the owner of the website, just in case.)

> Sure, most languages don't let you inspect the internals, but that's only
> one way of treating code as data.

What are the others?

> You're literally not even disagreeing with me, you're just defining
> "functional programming language" as "purely functional programming
> language",

How did you conclude that? I never said anything of the sort. What I said is
“functional programming is programming with procedures that compute
mathematical functions whenever possible”. Pure functional programming imposes
further requirements, like effect segregation (as in Haskell) or even the
total absence of effects (obviously unsuitable for a general-purpose
language). FWIW, I'd count ML, Racket, Clojure and Erlang as functional
languages.

> when I literally never even called Common Lisp a functional programming
> language.

You said Common Lisp has “functional aspects”. Well, closures make a language
higher-order, but so do Java-style objects! For a language to be called
“functional”, however, it has to make functional programming actually
pleasant. I showed one fundamental limitation of Common Lisp in this regard:
you can't define functions that take or return compound values, because Common
Lisp doesn't have compound values in the first place.

------
tempodox
A great read. Few words, and everything relevant mentioned.

------
platz
> most Common Lisp implementations are native compiled. ... isn't it nice to
> compile down to the metal?

Is just the interpreter native or does cl compile your app to native as well?

~~~
pmalynin
SBCL compiles to native. In fact thats how you check if the function was tail-
optimized -- it will have a JMP opcode instead of CALL

~~~
ohyes
To add to this, Most of them compile to native. I think the exception is
CLISP. Certain implementations have both because compiling was costly at one
point.

------
oconnor663
> he simply asked if Python could gracefully manipulate Python code as data

Have there been any big LISP macro code injection vulnerabilities in the wild?

~~~
Johnny_Brahms
As the other comment says, that doesn't really make sense. However, I have had
to debug a codebase where lisps unhygienic macros led to extremely weird
errors. The second time that happened in a big project I decided that schemes
hygienic macros are superior. The extra cruft writing them is worth it. I have
literally spent weeks debugging weird macro errors introduced years after the
macro was first written.

~~~
wtbob
You're not wrong: simple macros can be written poorly. Macros which don't
properly use GENSYM should be rejected in review. Also, it's entirely possible
to write a hygienic macro implementation with DEFMACRO: nothing stops a team
from doing that (or using one off-the-shelf).

But sometimes you do need the full power of DEFMACRO, and it's not possible to
write DEFMACRO with DEFINE-SYNTAX. So one tool enables you to do anything you
need, and the other only some of what you need. I know what I prefer.

~~~
Johnny_Brahms
Let's agree to agree then :) I much prefer Racket's macros. Their version of
syntax-case is a bit simplified compared to the one shipped with other schemes
like guile and chez.

If you want to see where you can go by (ab)using racket macros, watch this:
[https://www.youtube.com/watch?v=WQGh_NemRy4](https://www.youtube.com/watch?v=WQGh_NemRy4)

------
cheez
Did Kenny ever release his educational software?

~~~
tsuru
It appears so, yes: [http://tiltonsalgebra.com/#](http://tiltonsalgebra.com/#)

~~~
cheez
This is amazing. Kenny, please fix the fonts.

------
hahooooo
Is there any advantage in using a functional language when programming non-
mathematically related code?

I see how it can help write Neural Networks, AI, financial code, etc. But if
you know Python,Ruby,PHP,Java and Lisp (well), why would you choose to write a
blog, webstore, webmail client or social media* app (which probably is about
90% of what people actually do) in Lisp over the four three?

I'll tell you why I would chose the first four:

1\. Large community. 2\. Many more libraries. 3\. Easier to hire.

*Except for (perhaps) a small spam-block/feed ai module

~~~
nv-vn
Yes. Functional programming (although it isn't necessarily a trait of Lisp)
has, in fact, little relation to math (despite what many people believe). It's
also very far removed from the field of AI right now (not for any particular
reason, but there's no more specific reason to switch to Lisp for AI than
there is for desktop or web apps). The reason you'd use Lisp is quite simple
-- it saves time and makes programming easier. Macros are the biggest time
saver in the world, and you don't realize how much time you waste writing
repetitive code until you get to use them.

As for your 3 reasons in favor of the other languages, I think the first means
almost nothing at all. Lisp is much easier (once you grasp it) than many other
languages, so I think the fact that you'll get less answers on StackOverflow
is irrelevant. As for the second reason, as long as you have one library that
works for what you want -- say some library for writing web servers -- it
doesn't really matter after that. There's rarely any reason to reinvent the
wheel here, and there's always someone that attempted such a common task
before you. Just because you don't have 3,000 different choices like in Java,
doesn't mean that you won't find high-quality code for what you need to do (in
fact, I'd argue that Lisp code has a much higer quality on average than Java
code). As for hiring, I think Paul Graham has already given the best comments
on this. Simply put, a good programmer can be taught to write good Lisp, even
if they don't know it by the time you hire them.

------
cwmma
The whole manipulating code as date just always seems like such a rich target
for exploitation like that ruby yaml bug from a while ago [0]. It seems like a
features that would be great if your code never needs data from anywhere else
but as soon as you gave data coming in from other sources it would be a bit of
a nightmare.

0: [http://blog.codeclimate.com/blog/2013/01/10/rails-remote-
cod...](http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-
execution-vulnerability-explained/)

