Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

rant: LISP is non-functional!

275 views
Skip to first unread message

Xah Lee

unread,
Mar 4, 2012, 5:24:16 AM3/4/12
to
Dear lispers, brace yourselfs, because stinging damnation is coming
forthwith!

the more i learn about Common Lisp, the more i think it's one fuckedup
soup. (setf, rotatef, are recent examples)

also, the more i code in lisp (elisp), the more i find it non-
functional. Only the outer programer skeleton can be comfortably
functional. Innards of functions usually cannot be.

lots, lots, of mutations built-in in the lang in a way that forces you
to be non-functional. Quick 1 minute typing:

• destructive sort.

• setq setq setq.

• tons of global vars, not just for emacs environment such as buffer,
mode states, etc, which are arguably necessary. But, for things like
“match-string”.

• lisp's list, of cons, is one DAMNATION. Along with it comes rampant
use of pop, push. Any non-trivial coding in lisp is fucking like perl
now, except that dealing with list and nested list in perl is actually
much more easier than in lisp.

there's a good solution to lisp's non-functional ways.

BAN lispers from using list or cons. Everything should be vector/array
instead.

everytime a cons is involved, lispers should get a electric shock.

that will immediately fix majority of lisp's non-functional programing
in practice.

though, i'll have to say, the more i read about Clojure, the better it
seems. It is very functional, the savior of the lisp name.

yours truely,

Xah

Tim Bradshaw

unread,
Mar 4, 2012, 5:45:48 AM3/4/12
to
Xah Lee <xah...@gmail.com> wrote:

> there's a good solution to lisp's non-functional ways.
>

Indeed, and it is as you said: use a functional language if you are hung up
on functional programming. Lisp is a language for getting stuff done, not
for purists.

Chiron

unread,
Mar 4, 2012, 6:26:40 AM3/4/12
to
On Sun, 04 Mar 2012 02:24:16 -0800, Xah Lee wrote:

> the more i learn about Common Lisp, the more i think it's one fuckedup
> soup. (setf, rotatef, are recent examples)

That being the case, don't use it. How hard is that?



--
Three may keep a secret, if two of them are dead.
-- Benjamin Franklin

Alex Mizrahi

unread,
Mar 4, 2012, 11:25:29 AM3/4/12
to
> BAN lispers from using list or cons. Everything should be vector/array
> instead.

BAN Xah Lee from posting to USENET. He has absolutely no idea what he is
talking about.

Vectors and arrays used in Lisp are mutable, there is simply no way to
use them in functional way.

Unlike lists which work well with functional programming style.

There are immutable analogs of arrays, but I bet you have no fucking
idea how they work.

Chiron

unread,
Mar 4, 2012, 12:31:22 PM3/4/12
to
On Sun, 04 Mar 2012 02:24:16 -0800, Xah Lee wrote:

> BAN lispers from using list or cons. Everything should be vector/array
> instead.

Xah - you're talking about a language whose name is short for "list
processing." Like it or not, lists are a part of the language. If you
want to get rid of lists, use a different language.

You're not going to convince many people to eliminate lists from lisp.

Why do you even say things like this? I don't understand. It's
something like wanting to remove strong typing from Java. If you don't
like strong typing, don't use Java. If you don't like lists, don't use
lisp.

WTF, Xah?

--
Mystics always hope that science will some day overtake them.
-- Booth Tarkington

Antsan

unread,
Mar 4, 2012, 1:34:21 PM3/4/12
to
I didn't know Lisp was supposed to be purely functional. And I also didn't know that using lists somehow made functional programming impossible. This is even more puzzling to me, as I never ever used a modifying function on a list, as I see no reason to do that - as opposed to modifying arrays.

WJ

unread,
Mar 4, 2012, 3:20:17 PM3/4/12
to
You never used push, pop, or sort?

Antsan

unread,
Mar 4, 2012, 3:49:50 PM3/4/12
to
Oh, I take that one back.

Tim Bradshaw

unread,
Mar 4, 2012, 6:34:57 PM3/4/12
to
"WJ" <w_a_...@yahoo.com> wrote:

> You never used push, pop, or sort?

push and pop do not modify lists. for instance:

(let ((l '(1 2 3))) (let ((m l)) (pop l) m))

Ariel Badichi

unread,
Mar 4, 2012, 7:36:46 PM3/4/12
to
PUSH and POP may modify lists. For instance:

(let ((list (list 1 2 3)))
(let ((list-2 list))
(push 1.5 (rest list))
list-2))

Ariel

Kaz Kylheku

unread,
Mar 4, 2012, 8:00:18 PM3/4/12
to
Bzzt: push and pop don't modify lists. They modify places.
(Of course, they can modify a list if you make a lsit place their
target, e.g. (pop (cdr list)) or (push 42 (third list))).

I.e. push and pop show that not only is functional programming possible
on lists, but also a kind of imperative programming that never destroys
lists.

(Let us coin a new word: "funperative programming". This is a style whereby
mutations are restricted to local variables, and data structures that
are guarnateed not to be shared because they were locally allocated in
the same scope. Functions written in funperative style appear functional
to outsiders, but have pragmatic innards.)

Maybe Antsan has a non-destructive sort routine which returns a newly allocated
sorted list. This is easy to write "funperatively": copy-list followed by sort.

namekuseijin

unread,
Mar 5, 2012, 12:08:40 AM3/5/12
to
except vectors by nature are an imperative data-structure. Not so with lists. You may check with the haskell guys for this.

But yeah, older lisps like elisp and CL (the culmination of several older lisps) are pretty imperative in nature. Scheme, Qi and Clojure are much better in this respect.

Tim Bradshaw

unread,
Mar 5, 2012, 2:36:10 AM3/5/12
to
On 2012-03-05 00:36:46 +0000, Ariel Badichi said:

> PUSH and POP may modify lists. For instance:
>
> (let ((list (list 1 2 3)))
> (let ((list-2 list))
> (push 1.5 (rest list))
> list-2))

Yes, I am aware of that. To be more precise they modify a place.
However I rather doubt this is what the original claim meant. In
particular something like this:

(defun rev (l)
(loop with r = '()
until (null l)
do (push (pop l) r)
finally (return r)))

mutates no list structure.

Frode V. Fjeld

unread,
Mar 5, 2012, 2:56:20 AM3/5/12
to
namekuseijin <nameku...@gmail.com> writes:

> Scheme, Qi and Clojure are much better in this respect.

I suppose this is some sort of pun on the "worse is better" article.

--
Frode V. Fjeld

Kaz Kylheku

unread,
Mar 5, 2012, 3:00:24 AM3/5/12
to
However, these toys have many small parts that can come loose.
Not suitable for children under 3.

Tamas Papp

unread,
Mar 5, 2012, 3:10:02 AM3/5/12
to
On Mon, 05 Mar 2012 01:00:18 +0000, Kaz Kylheku wrote:

> (Let us coin a new word: "funperative programming". This is a style
> whereby mutations are restricted to local variables, and data structures
> that are guarnateed not to be shared because they were locally allocated
> in the same scope. Functions written in funperative style appear
> functional to outsiders, but have pragmatic innards.)

This is the style I have been drifting to lately in CL, because I
found it very practical. Thanks for giving it a name!

Best,

Tamas

Larry Coleman

unread,
Mar 5, 2012, 9:11:58 AM3/5/12
to
On Monday, March 5, 2012 12:08:40 AM UTC-5, namekuseijin wrote:
> except vectors by nature are an imperative data-structure. Not so with lists. You may check with the haskell guys for this.
>
Haskell has vectors and lists. Vectors are immutable; functions that appear to change elements actually return copies. Lists are also immutable. Haskell does have cons, but it's spelled ":".

Kaz Kylheku

unread,
Mar 5, 2012, 9:45:34 AM3/5/12
to
Oh really?

Try translating (cons 1 (cons 'a "b")) into Haskell.

Then see if you still think that : is cons.

Didier Verna

unread,
Mar 5, 2012, 10:22:51 AM3/5/12
to
Conceptually, it is. cons is the canonical[1] list constructor in
Lisp, and in Haskell, it is indeed (:). What you're pointing out is
orthogonal to canonical construction. What you're pointing out is that
Haskell lists need to be homogeneous and proper (because of typing).


Footnotes:
[1] meaning: given one object, there is only one way to build it with the
canonical constructor.

--
Resistance is futile. You will be jazzimilated.

Scientific site: http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com

Kaz Kylheku

unread,
Mar 5, 2012, 10:57:52 AM3/5/12
to
On 2012-03-05, Didier Verna <did...@lrde.epita.fr> wrote:
> Kaz Kylheku <k...@kylheku.com> wrote:
>
>> On 2012-03-05, Larry Coleman <all.are...@gmail.com> wrote:
>
>>> Haskell has vectors and lists. Vectors are immutable; functions that appear
>>> to change elements actually return copies. Lists are also immutable. Haskell
>>> does have cons, but it's spelled ":".
>>
>> Oh really?
>>
>> Try translating (cons 1 (cons 'a "b")) into Haskell.
>>
>> Then see if you still think that : is cons.
>
> Conceptually, it is. cons is the canonical[1] list constructor in
> Lisp, and in Haskell, it is indeed (:). What you're pointing out is
> orthogonal to canonical construction. What you're pointing out is that
> Haskell lists need to be homogeneous and proper (because of typing).

It's not orthogonal at all. Construction means that I can take a piece
of metal, and a piece of plastic and screw or glue them together
without the world blowing up because the types are different.

Barry Margolin

unread,
Mar 5, 2012, 11:50:36 AM3/5/12
to
In article <jj1qda$e34$1...@dont-email.me>, Tim Bradshaw <t...@tfeb.org>
wrote:
It modifies the local variable R, which is non-functional.

But who cares? No one ever claimed Lisp was a pure functional language,
so how is saying that it's not functional supposed to be damning?

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Tim Bradshaw

unread,
Mar 5, 2012, 12:09:56 PM3/5/12
to
On 2012-03-05 16:50:36 +0000, Barry Margolin said:

> It modifies the local variable R, which is non-functional.

Yes, of course. I wasn't claiming push/pop were functiononal, just
that they don't mutate list structure in the way I think WJ thought
they did (and of course, I'm only guessing at what he thought since he
didn't, for instance, include setf which mutates a place in just the
same way push/pop do).

>
> But who cares? No one ever claimed Lisp was a pure functional language,
> so how is saying that it's not functional supposed to be damning?

Yes. "If you want a pure functional language, go and use a pure
functional language rather than complaining that Lisp isn't one" is the
message, I think. But people do seem to like hanging out in newsgroups
complaining, as far as I can tell: probably because it helps them avoid
doing real work, which is important, of course.

--tim

Tim Bradshaw

unread,
Mar 5, 2012, 12:08:43 PM3/5/12
to
On 2012-03-05 16:50:36 +0000, Barry Margolin said:

> It modifies the local variable R, which is non-functional.

Yes, of course. I wasn't claiming push/pop were functiononal, just
that they don't mutate list structure in the way I think WJ thought
they did (and of course, I'm only guessing at what he thought since he
didn't, for instance, include setf which mutates a place in just the
same way push/pop do).

>
> But who cares? No one ever claimed Lisp was a pure functional language,
> so how is saying that it's not functional supposed to be damning?

Marco Antoniotti

unread,
Mar 5, 2012, 11:03:33 PM3/5/12
to
Let's call it "fun programming". CL coding is done in "fun programming" style. (As opposed to WJ's "boring programming")

Cheers
--
MA

Kaz Kylheku

unread,
Mar 6, 2012, 1:40:41 PM3/6/12
to
On 2012-03-05, Barry Margolin <bar...@alum.mit.edu> wrote:
> In article <jj1qda$e34$1...@dont-email.me>, Tim Bradshaw <t...@tfeb.org>
> wrote:
>
>> On 2012-03-05 00:36:46 +0000, Ariel Badichi said:
>>
>> > PUSH and POP may modify lists. For instance:
>> >
>> > (let ((list (list 1 2 3)))
>> > (let ((list-2 list))
>> > (push 1.5 (rest list))
>> > list-2))
>>
>> Yes, I am aware of that. To be more precise they modify a place.
>> However I rather doubt this is what the original claim meant. In
>> particular something like this:
>>
>> (defun rev (l)
>> (loop with r = '()
>> until (null l)
>> do (push (pop l) r)
>> finally (return r)))
>>
>> mutates no list structure.
>
> It modifies the local variable R, which is non-functional.

Modifying a local variable, inside a function from which no lexical closure has
escaped, isn't a side effect.

Given this rev, and a functional one, can you tell which is which without
looking, white box, at the source code? If rev has a side effect, it must be
externally observable.

If we treat the function as a black box, and we cannot tell whether or not it
has some property, then it doesn't have that property.

Calling it nonfunctional is therefore religion, not science. Religions ascribe
properties to objects (inanimate or other) that they cannot be shown to have.

Kaz Kylheku

unread,
Mar 6, 2012, 1:43:36 PM3/6/12
to
On 2012-03-05, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2012-03-05 16:50:36 +0000, Barry Margolin said:
>
>> It modifies the local variable R, which is non-functional.
>
> Yes, of course. I wasn't claiming push/pop were functiononal, just

Can you tell that the function contains push and pop by experiments involving
calling the compiled code?

If not, then it doesn't actually contain push and pop.

RG

unread,
Mar 6, 2012, 2:00:34 PM3/6/12
to
In article <201203061...@kylheku.com>,
To expand on what Kaz said (which is entirely correct), this:

(let ((x ...))
...
(setf x)
...
)

is formally equivalent to this:

(let ((x ...))
...
(let ((x ...))
...
))

In fact, a good compiler will emit identical code for both.


? (defun f1 (x) (let ((x (cons x x))) x))
F1
? (defun f2 (x) (setf x (cons x x)) x)
F2
? (disassemble 'f1)
;;; (defun f1 (x) (let ((x (cons x x))) x))
L0
[0] (leaq (@ (:^ L0) (% rip)) (% fn))
[7] (cmpl ($ 8) (% nargs))
[10] (jne L73)
[12] (pushq (% rbp))
[13] (movq (% rsp) (% rbp))
[16] (pushq (% arg_z))

;;; (let ((x (cons x x))) x)
[17] (movq (% arg_z) (% arg_y))
[20] (subq ($ 13) (@ #xD8 (% rcontext)))
[28] (movq (@ #xD8 (% rcontext)) (% temp0))
[35] (cmpq (@ #xE0 (% rcontext)) (% temp0))
[42] (ja L46)
[44] (uuo-alloc)
L46
[46] (andb ($ #xF0) (@ #xD8 (% rcontext)))
[54] (movq (% arg_y) (@ 5 (% temp0)))
[58] (movq (% arg_z) (@ -3 (% temp0)))
[62] (movq (% temp0) (% arg_z))
[65] (pushq (% arg_z))
[66] (leaveq)
[67] (retq)

;;; #<no source text>
L73
[73] (uuo-error-wrong-number-of-args)
NIL
? (disassemble 'f2)
;;; (defun f2 (x) (setf x (cons x x)) x)
L0
[0] (leaq (@ (:^ L0) (% rip)) (% fn))
[7] (cmpl ($ 8) (% nargs))
[10] (jne L77)
[12] (pushq (% rbp))
[13] (movq (% rsp) (% rbp))
[16] (pushq (% save0))
[18] (movq (% arg_z) (% save0))

;;; (setf x (cons x x))
[21] (subq ($ 13) (@ #xD8 (% rcontext)))
[29] (movq (@ #xD8 (% rcontext)) (% temp0))
[36] (cmpq (@ #xE0 (% rcontext)) (% temp0))
[43] (ja L47)
[45] (uuo-alloc)
L47
[47] (andb ($ #xF0) (@ #xD8 (% rcontext)))
[55] (movq (% save0) (@ 5 (% temp0)))
[59] (movq (% save0) (@ -3 (% temp0)))
[63] (movq (% temp0) (% save0))

;;; #<no source text>
[66] (movq (% save0) (% arg_z))
[69] (popq (% save0))
[71] (leaveq)
[72] (retq)
L77
[77] (uuo-error-wrong-number-of-args)
NIL
?

Tim Bradshaw

unread,
Mar 6, 2012, 2:46:57 PM3/6/12
to
Kaz Kylheku <k...@kylheku.com> wrote:

> Can you tell that the function contains push and pop by experiments involving
> calling the compiled code?
>
not that function, but I can write things using push and pop which do have
side-effects, which is, of course, what I meant.

namekuseijin

unread,
Mar 6, 2012, 3:03:01 PM3/6/12
to
On Monday, March 5, 2012 11:45:34 AM UTC-3, Kaz Kylheku wrote:
> On 2012-03-05, Larry Coleman <all.are...@gmail.com> wrote:
> > On Monday, March 5, 2012 12:08:40 AM UTC-5, namekuseijin wrote:
> >> except vectors by nature are an imperative data-structure. Not so with lists. You may check with the haskell guys for this.
> >>
> > Haskell has vectors and lists. Vectors are immutable; functions that appear
> > to change elements actually return copies. Lists are also immutable.

http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Vector_Tutorial#Impure_Arrays

"Arrays can be created and operated on in a mutable fashion -- using destructive updates, as in an imperative language. Once all operations are complete, the mutable array can be "frozen" to a pure array, which changes its type.

Mutable arrays plus freezing are quite useful for initializing arrays from data in the outside world."

from the ugly, mean, side-effectuful world.

> Haskell
> > does have cons, but it's spelled ":".
>
> Oh really?
>
> Try translating (cons 1 (cons 'a "b")) into Haskell.
>
> Then see if you still think that : is cons.

haskell doesn't need to try to emulate a record with lists.

Yash Tulsyan

unread,
Mar 21, 2012, 3:04:41 PM3/21/12
to
On a somewhat related note, I actually think Lisp's lack of purity is
one of it's strengths. Why? Well, from looking at examples of purely
functional languages (and Lisps that try too hard to imitate them,
e.g. Clojure), I find that, though they might be interesting from a
purely academic point of view, they have the B&D nature insofar as they
force a functional style on the user. This is anathema to me; I want
some random luser to be able to violate the Rules of Functional
Programming if they want to. In fact, I think that not only is purity a
straitjacket, Lisp wasn't designed for it in the first place. Lisp is a
multiparadigm language and should be treated as such.

I don't know; just some thoughts that float into my head when people
claim that Lisp is "a functional programming language"

--Yash
0 new messages