Hacker News new | past | comments | ask | show | jobs | submit login

Everything isn't a scalar in the example you mentioned. sum() is a function and other things are numbers.

In lisp there is only rule, everything is a list and the first element of the list is a operation to the remainder of the list. This is basically the whole language.




>In lisp there is only rule, everything is a list

Well no. `print` is not a list. `4` is not a list. `(print 4)` is a list containing the scalars `print` and `4`. The mechanics of lisp then say "apply the thing in the first position to the remainder of the list", but that's just notation.

In python, `sum` is a function that can apply to a splatted sequence of scalars (note that it can also apply to a list, but this is different), so `sum(1,2,3,4,5)` works. It returns a scalar value.

In lisp, `+` is a function that can apply to a list. It returns a scalar. `(+ 1 2 3)` resolves to `6`, not `(6)`. This is no different than python (or C actually, for this example).

I understand lisp, I understand why "code is data" is a powerful tool. Your example is a bad one, it does not demonstrate why "code is data" is a powerful tool, because it does not actually demonstrate that code is data.


You seem to be suggesting

    (sum 1 2 3 4 5)
and

    sum(1, 2, 3, 4, 5)
are the same because they both return 15. That's just one way of looking at things. And that is true only if, that one is the only way of looking at things.

Structurally (sum 1 2 3 4 5) and sum(1 2 3 4 5) are NOT similar. They are not even close, in fact they represent opposite schools of thought.

There is a reason we are insisting on everything being list and them being uniform that way. That's because eventually we can use structures to modify themselves(recursion and macros).

Which is why Lisp's (sum 1 2 3 4 5) and Python's sum(1 ,2, 3, 4, 5) can't be judged on what they return alone, they have to judged on the structure they represent.

There is a interesting macro in Clojure named '-->'.

This basically helps:

    (task3
      (task2
        (task1 work)))
to be

    (--> work
         task1
         task2
         task3)
These sort of transformations are not easy with sum(1,2,3,4,5) kind of syntax or even possible in many cases.


    task3(task2(task1(work)))
can, with the function

    apply(data, *funs):
        return reduce(lambda d, f: f(d), [data] + funs)
be rewritten as

    apply(work, task1, task2, task3)
Its possible in exactly the same set of cases, namely those where each task takes a single argument/is provided as a partial.

I expect that `->` is implemented in clojure in much the same way (and [1] implies that, modulo some scaffolding and error checking, it is, although with a recursive, inlined impl of reduce)

[1]: https://github.com/clojure/clojure/blob/08e592f4decbaa08de57...


Sorry but again, using a workaround doesn't mean they are the same. When I mean same, I mean structurally.


But they are structurally the same that's my point. I can implement -> practically directly. There is no structural difference that you've demonstrated.

That is not idiomatic and common in Python didn't mean that there is some structural difference. Basically the transformations you're describing are doable with regex, which is the opposite of powerful.

What you've done is take code is data, which is powerful, and confuse that with "supports varags", which is less powerful, and claim that the second is unique and powerful when it is not unique, and not uniquely powerful.


sum(1, 2, 3) and (sum 1 2 3) are just different read/print notations that can map to exactly the same data structure and therefore "do" everything the same way.

The --> macro invocation would just look like -->(work, task1, task2, task3).

There are good reasons for considering f(x, y) to be a bad notation compared to (f x y); but this isn't one of them.


That was just an example. In general, those representations are not the same. Structurally.


They're only not the same when one is in Lisp and the other isn't.

E.g. you load "infix.cl" into your Common Lisp so that you then have the #I read macro that gives you #I( f(x, y) ), then they are the same. This just denotes (f x y). It would be suboptimal for that to be any other way:

https://www.cs.cmu.edu/Groups/AI/lang/lisp/code/syntax/infix...

Now let's think about how silly it is to try to write a let block using this syntax:

  (let ((a 1) (b 2)) (+ a b))
becomes

  #I(  let(a(1)(b(2)), +(a, b)) )
In the ((a 1) (b 2)) part the (a 1) becomes a(1). That then then looks like a function applied to the argument b(2). Things that should be on the same level aren't.

It's like using Roman numerals instead of decimal.

(f x y) is one size fits all; perhaps not optimal for anything in particular, just for everything.


This was exactly what I was trying to say. The list notation just fits perfectly with everything else just so nice. And though we could talk about the possibilities in the mathematical sense, its hard to many things you do in lisp in non lisp languages.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: