Live data from Hacker News

Anarki – Community-managed fork of the Arc dialect of Lisp

github.com

31–40 of 45 posts

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#31
post #3

What are the core features that differentiate Arc from other lisp dialects?

To me, one of the most fundamental features of Arc is taking the unification of code and data much further. I don't know of other Lisps that do this! K is another language that does. arc> (= l '(1 2 3)) (1 2 3) arc> (= f [+ _ 1]) # arc> (map l '(0 1 2)) (1 2 3) arc> (map f '(0 1 2)) (1 2 3)

Kind of like pattern matching in Elixir?

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#32
post #29
post #24

Earlier quoted context omitted.

that's confusing as hell. there's a reason this didn't take off (Besides the competition from clojure)

I don't like the Arc language because it's dynamically typed and thus inherently unsafe (see other threads for this sort of discussion.) But I like this particular feature. If you think about it, an array is a mathematical function, or map, from indices to values. So it makes sense to be able to apply it to indices to get the respective values.

In that sense, map just composes its two arguments.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#33
post #32
post #29

Earlier quoted context omitted.

I don't like the Arc language because it's dynamically typed and thus inherently unsafe (see other threads for this sort of discussion.) But I like this particular feature. If you think about it, an array is a mathematical function, or map, from indices to values. So it makes sense to be able to apply it to indices to get the respective values.

In that sense, map just composes its two arguments.

That's cool! I'm a mathematician and so inclined to (over-)abstract programming, but it had never occurred to me to think of it that way.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#34
post #13

Earlier quoted context omitted.

Yes, or like Scheme.

I don't really get why you'd ever want a Lisp-2. Is there an argument/explanation somewhere that I could read up on? (I've used Clojure and JS, which also seems like a "Lisp"-1 in that you can just put fns into variables and call them like 1st class fns, I just don't get why the distinction is in any way positive rather than confusing, and in Lisp-2s you now need to dereference everything all the time, like in Ruby).

A Lisp-2 can treat function bindings specially at the compiler level.

In addition to the simplified hygiene, one consideration is that Lisp dialects typically have mutable variables. But the ANSI-Lisp-style labels and flet forms bind functions immutably. Thus a compiler never has to suspect that a local function will change.

In TXR Lisp, developed a way to combine Lisp-2 and Lisp-1 into a single dialect, to get the best of both with almost no downsides. In a nutshell, the square bracket syntax performs Lisp-1 style evaluation: [a b c] means expand/evaluate a, b, c in the same mannner, and then treat the value of a as a callable object which receives the values of b c.

Furthermore, any arguments of [...] which are symbolic (after macro-expansion) are treated in a combined namespace which contains both function and variable bindings. When the symbol is global, if it has both kinds of bindings, preference is given to the variable.

This [a b c] is a sugar for (dwim a b c), which is a special operator that is recognized properly by the macro expander, interpreter and compiler, including the various shadowing corner cases between macro and ordinary bindings.

Thus, there is no reason to have to choose between Lisp-1 and Lisp-2.

However, the implementation is a bit more complicated than just Lisp-2 alone, never mind Lisp-1.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#35

Earlier quoted context omitted.

I don't really get why you'd ever want a Lisp-2. Is there an argument/explanation somewhere that I could read up on? (I've used Clojure and JS, which also seems like a "Lisp"-1 in that you can just put fns into variables and call them like 1st class fns, I just don't get why the distinction is in any way positive rather than confusing, and in Lisp-2s you now need to dereference everything all the time, like in Ruby).

Yes, JavaScript also has a single namespace, like a Lisp-1. The advantage of a Lisp-2 is that it makes macro writing easier; you can include calls to known functions in the expansion without having to deal with the possibility that those names have been shadowed.

POSIX shell is dual-namespace, OTOH.

A variable foo, referenced as $foo, has nothing do with a function foo called as "foo args ...".

Imagine how stupid it would be if assigning a variable called ls prevented the ls command from working.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#36
post #13

Earlier quoted context omitted.

Yes, or like Scheme.

I don't really get why you'd ever want a Lisp-2. Is there an argument/explanation somewhere that I could read up on? (I've used Clojure and JS, which also seems like a "Lisp"-1 in that you can just put fns into variables and call them like 1st class fns, I just don't get why the distinction is in any way positive rather than confusing, and in Lisp-2s you now need to dereference everything all the time, like in Ruby).

To a certain extent it's just syntax sugar. It's relatively easy to implement a lisp-1 with a macro in a lisp-2 and vice versa.

At this point I'm so used to lisp-2 that I make all sorts of silly mistakes when I program in a lisp-1. In English, a word could be a noun or a verb depending on its position in a sentence, so there is a parallel there. Whether or not it's a good thing is a matter of taste.

The only clearly objective difference is that lisp-1 is simpler, which is probably why most lisps created in the past 30 or so years are lisp-1s.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#37
post #17

Earlier quoted context omitted.

If I understand it correctly, Lisp-2 is a way (not the only way!) of maintaining more intuitive semantics in the face of macros. If I write the following: (your-macro (let ((x (foo y)) (bar x)))) I probably don't want the meaning of FOO or BAR to be up for grabs based on the expansion of YOUR-MACRO, and certainly not LET. Lisp-1s often have hygienic macros to deal with this concern, but not always.

Completing your thought (please let me know if I misunderstood you) Y _is_ up for grabs because what you wrote might macroexpand to for example (let ((y 5)) (let ((x (foo y))) (bar x))). Where your comments falls down is that all the Lisp-2s I know allow the "function definition" of a symbol to be overriden in a similar way, e.g., in Common Lisp the macro might expand to (flet ((bar (arg) (* 5 arg))) (let ((x (foo y)…

Where your comment falls down is that in a Lisp-1, every let is also a flet.

Also, of course, you must use gensyms for any locally bound identifier, whether it is a let or flet. Nobody said that Lisp-2 allows for labels and flets without having to use gensyms; nobody in their right mind is going to lexically bind identifiers in macro-generated code that don't use gensymed names (other than in cases when there is no possible capture).

Lisp-2 addresses (in a good-enough-beats-perfect way) the following problem: the programmer's code wrongly capturing references that the macro would like to use.

The macro wants to generate some (foo ...) call to a function in the global environment. But, oops, in a Lisp-1, a user's local variable foo takes this. In a Lisp-1, the user would have to have a local function by that name.

If global functions have reasonably descriptive names, and local functions are used sparingly, the potential for a clash is low.

We can have a warning when a local function shadows a global one; it won't be too much of a nuisance since global functiions tend to use descriptive names, and local functions are relatively rare compared to local variables.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#38
post #13

Earlier quoted context omitted.

Yes, or like Scheme.

I don't really get why you'd ever want a Lisp-2. Is there an argument/explanation somewhere that I could read up on? (I've used Clojure and JS, which also seems like a "Lisp"-1 in that you can just put fns into variables and call them like 1st class fns, I just don't get why the distinction is in any way positive rather than confusing, and in Lisp-2s you now need to dereference everything all the time, like in Ruby).

A lot of the comments mention reasons. In my experience, once you get used to a lisp-2 programming in a lisp-1 feels limiting: you can’t just write

    (def str “foo”)
In Clojure, because you’ll shadow the builtin definition of str (which leads to really weird bugs). But, this means that there’s one more thing to think about when naming your variables.

Additionally, I think we’re pretty used to “separate namespaces” for nouns and verbs in normal languages: it’s fairly rare, for example, for the word “run” to be ambiguous between its noun use and it’s verb use, in the context of a sentence.

Re: Anarki – Community-managed fork of the Arc dialect of Lisp

#40
post #3

Earlier quoted context omitted.

To me, one of the most fundamental features of Arc is taking the unification of code and data much further. I don't know of other Lisps that do this! K is another language that does. arc> (= l '(1 2 3)) (1 2 3) arc> (= f [+ _ 1]) # arc> (map l '(0 1 2)) (1 2 3) arc> (map f '(0 1 2)) (1 2 3)

No offense, but I found your example code really confusing. For the benefit of people familiar with Common Lisp: * (= ...) is assignment, not equality testing * (map list index-list) is equivalent to (loop for index in index-list collecting (nth index list)), or in a more FP style (mapcar (rcurry #'nth list) index-list) * (map function list) is equivalent to (mapcar function list) I think your example would have been…

Thank you the map makes more sense now.

And looks like an easy trap for misreading code ...

Post reply on HN