Arc Forumnew | comments | leaders | submit | thaddeus's commentslogin
2 points by thaddeus 3681 days ago | link | parent | on: Pluralize no longer supports lists

Something like marginalia[1] might prove to be better than the arcfn docs. Not only because the docs would be fully integrated with the source code, but because it would also solve the multiple dialects problem. i.e. If some given code can be tagged with a dialect name then automation could also apply a dialect filter.

Of course this would probably be quite a bit of an undertaking.

1. &


2 points by akkartik 3681 days ago | link

The crux is colocating the rendered docs online with the repo. Would marginalia help us use github's hosting with github pages, managing branches, etc? If it does I think I'd be willing to go on a significant undertaking.


2 points by thaddeus 3681 days ago | link

Marginalia is clojure specific so I expect it will not help other than to provide ideas.

To create an arc equivalent you probably need build an arc library which provides some code inspection/dissection capabilities and ideally also be able to attach metadata to any given function or macro. With such a library you then build a script to auto generate the docs.

As for GitHub syncing; well no, I'm guessing users would need to trigger the script and then check in the updated docs.

This is still better for a few reasons...1. developers can generate docs, locally, that are in sync with the code base they are actually using (checked out or branched). 2. Even if the online docs gets out of sync for a while you're still only a script trigger away for updating all outstanding changes.

The alternative is what you just went through; having someone remind you to do the work manually as an after-thought, which I've only seen happen once.


2 points by thaddeus 3718 days ago | link | parent | on: Pg is "going to check out of HN"

I've had bad experiences with some of the people in Clojure's community

When arc advances enough to appease you, it will also be appealing to others; then when a larger community develops around arc you will start to have bad experiences. That's the nature of mass appeal.

Even pg noticed the quality of HN's content and community degraded with popularity, which is why he's adding the pending change discussed (amongst others).

And let's all be honest, if arc solved half the problems Clojure handles, I doubt you would notice much of a difference between the languages. After all they are already very similar.


2 points by akkartik 3718 days ago | link

By Steve Yegge's analysis, clojure is conservative and arc is pretty liberal.


2 points by thaddeus 3718 days ago | link

If you were to draw a line with liberal being at one end and conservative on the other, then plot various languages on that line you'll find arc and clojure would be close together as opposed to far apart.

Even Yegge's post would seem[1] to confirm this with his own data:

  Assembly language: Batshit liberal.
  Perl, Ruby, PHP, shell-script: Extremist liberal.
  JavaScript, Visual Basic, Lua: Hardcore liberal.
  Python, Common Lisp, Smalltalk/Squeak: Liberal.
  C, Objective-C, Scheme: Moderate-liberal.
  C++, Java, C#, D, Go: Moderate-conservative.
  Clojure, Erlang, Pascal: Conservative.
  Scala, Ada, OCaml, Eiffel: Hardcore conservative.
  Haskell, SML: Extremist conservative.
And as I suggested, if arc were to advance and cover off some of the things Clojure does already, then they would move closer on that plot.

1. Arc not present I approximate with scheme. Note that those categories are wonky and divisions wouldn't plot evenly.


2 points by akkartik 3718 days ago | link

Yeah, our differing analysis is because:

1. I assume arc to be like lisp. Many of the things that need a new interpreter atop scheme (lisp-1, quasiquote, unhygienic macros) are borrowings from lisp. The only major scheme-ism arc retains is call/cc. Am I missing anything?

2. I actually think arc is more batshit liberal than traditional lisp. Perhaps I'm reading too much into the absence of a module system, but I consider it a deliberate omission.

3. You're assuming that there's only one way to build out the missing infrastructure, and that is to be more like clojure. I'm skeptical of that.


2 points by thaddeus 3718 days ago | link

Yeah, I can see how one could draw a little larger of a distinction between Arc and Clojure using the conservative/liberal categories, but even so I'm not convinced it even stands up as a good overall measure for similarity/differences (even if it's a good one). So setting that one criteria aside for a moment, I look at Arc and Clojure and here's what I also see:

- They are both Lisps with dynamic type handling, prefix notation, strings as sequences, heavy use of hash-maps, a large number of functions and macros with similar names doing the same things.

- The syntax's are so similar you could pretty much swap out color scheme templates (in fact I initially used the arc textmate bundle for Clojure).

- They both depend upon pre-existing language for compilation. Clojure drops into java, Arc drops into scheme.

- The online comparisons between them are more frequent than arc and any other language.

I could go on, but I think you get the point.

And while I know you could create a list to show differences I'm simply saying that overall they are very similar which was my initial claim.

As for "having to be more like Clojure" to advance, well no, but I'm pretty sure that it's more likely than any other unstated options. Here's what I do see to support this:

- pg himself has stated Clojure is bringing LISP back into popularity and recommended clojure for use over other languages. (,

- There are many posts on the arc forum showing/suggesting Clojure like features. I don't see this kind of thing happening for arc and say erlang or any other language. (examples:,,,,, etc etc...)


2 points by akkartik 3718 days ago | link

Ok, I'm convinced :) By pg's comments in particular.

(There's a lot of red herrings in your comment, though. That they look the most similar syntactically isn't too surprising, and it's irrelevant that erlang can't compete, or that they build on an existing language, etc. You're measuring position to compare trajectories.)

In any case, it feels quite delusional to compare arc to clojure at the moment :)

Let me ask you this: if you have clojure why do you care about arc? Genuinely curious.


2 points by thaddeus 3718 days ago | link

> “There's a lot of red herrings in your comment, though. That they look the most similar syntactically isn't too surprising, and it's irrelevant that erlang can't compete, or that they build on an existing language…

I realize many of my arguments have holes in them when viewed independently, but when put together those “soft arguments” contribute to painting an overall picture that supports my claim better than had I not given them. Albeit the "they build on an existing language" is pretty weak overall.

> “You're measuring position to compare trajectories

Position is not something you can measure it's something you can map/use. That aside, I don’t believe what it is I think you intended to say is true. I used position to substantiate the claim of similarity, I used trends to substantiate the trajectory (i.e. the last half of my reply, what people are saying and what they are doing are trends).

> "if you have Clojure why do you care about arc?"

I like both languages. I don’t use Arc because its unfinished and unusable for the things I need to do. I often get the sense that when I promote Clojure on the Arc forum that people get defensive and wonder why I'm even around, but remember I am only saying what pg himself is:

  > Would you recommend Arc to modern startups in general?
  PG: No, I don't think so, not in its current state.
  > Why not?
  PG: It's still missing some things that most people take for granted.
  > Are there any Lisps you would recommend.. ?
  PG: Clojure is probably the best bet...

I like the arc language and I like the community. I view arc as unfinished and look forward to giving it a shot when it is, but until then I am going to continue to be realistic about the current state and promote Clojure as an option.


2 points by akkartik 3717 days ago | link

"I used trends to substantiate the trajectory, i.e. the last half of my reply, what people are saying and what they are doing are trends."

If you think arc is whatever pg says it is, then what we are saying and doing here is irrelevant :)

If you think arc is whatever we're saying and doing here, the things we take from clojure seem a tiny minority compared to the sum total of conversations. I'd say arc starts out kinda like clojure, but is looking to steal ideas from all sorts of languages including erlang.


I tried to phrase my question very carefully to avoid seeming defensive about something I don't care about. So let me just come out and say it: I have no problem with you talking about clojure all you want here. If you did, maybe I'd get to talk to you more! :) Arc is indeed absolutely unfinished, no disagreement there either.

Maybe what I'm actually defensive about is the prospect of any two languages becoming more and more similar. That just seems bad, nothing good can come of it. I'd rather see arc and clojure evolve in different directions and give me more ideas and more data about how good those ideas are.

Copying ideas and creating hybrids is totally fine, that's what we are good at. But then the hybrid starts at the intersection of its influences and sets off on a whole different trajectory.

So let me rephrase my question: is there something you miss from arc in clojure that has you wishing for a superset?

(The answer may take time to emerge from the subconscious. At least it has for me in similar questions.)


2 points by thaddeus 3717 days ago | link

My comments are a targeted response to statements made in a specific comment ( I think you're treating the conversation in this thread as you treat this forum; as some place to mingle languages and abstract all ideas. That's fine if you want to do that, but I'll suggest you'll be more effective if you follow the thread and consider context when responding.

And I'm suggesting more care be taken in this regard, because it leads to you being offended (i.e. "If you think arc is whatever pg says it is, then what we are saying and doing here is irrelevant...") on statements that should be considered only in relation to the thread. It also leads to unintentional attacks such as "In any case, it feels quite delusional to compare arc to clojure ...". I don't think you realize you suggested I'm being delusional by adding that comment... Arc and Clojure are both modern lisps that have eliminated the overuse of brackets, so really is it delusional to suggest these two languages are more similar than not? Am I creating some injustice by telling someone, that's already leaning towards Clojure, that these languages are very similar anyway?

I'm going to end this thread here as I think it has already gone off the rails.



2 points by akkartik 3717 days ago | link

Sorry I'm causing offense. It was indeed utterly unintentional, and fwiw, I actually was never in the slightest conscious of feeling offended by anything in this thread. I'm entirely the offender and not an offended party.

I didn't mean to trigger associations like "injustice". When I said "delusional to compare arc to clojure" I was trying to be self-deprecating. Arc is just a toy, clojure is real. You're absolutely right in your defense of clojure.


2 points by thaddeus 3717 days ago | link

Not to worry, I've known you long enough now to know you're not mean spirited or intending offence. Hopefully I didn't get too grumpy, but I needed to put and end the thread because I could see we had different ideas on what the thread was even about.


2 points by thaddeus 3719 days ago | link | parent | on: Pg is "going to check out of HN"

I don't think pg will let arc die [1], but I still will suggest moving on to Clojure.



3 points by thaddeus 3751 days ago | link | parent | on: Is there a repository of Arc libraries?

There's a library directory for Anarki which seems to be a common place for the user submitted libraries.


2 points by shader 3741 days ago | link

Indeed. I've put several libraries there myself.

I might be interested in working on something like packages.el for emacs that supports grabbing arc libs directly from github.

Dependency management may be somewhat tricky, but we could leave that up to the library creators to manage. Or work on yet another package system...


Very cool.

I would prefer sticking with the highlighting of syntactic categories, while being able keyboard toggle which category I want highlighted.


2 points by thaddeus 3802 days ago | link | parent | on: The trouble with arc's if statement

  These parentheses weren't decorative though, 
  they exposed the structure of the code, and they are a
  minimal price to pay for extra clarity.
Well clarity is dependant upon the reader and, more specifically, how the reader reads.

My path to clarity is as follows: I first scan code at a high level, often referred to as speed reading[1] where I find having more parentheses simply gets in the way. The second is using fixation[2] where I stare at a small block of code. With both Arc and Clojure I have no trouble moving from scanning to fixation then to understanding (clarity). It could be that the author struggles with his/her reading method. Chances are the author learned with traditional L.I.S.P (Lots of Infuriatingly Stupid Parentheses) and therefore the newer lisp dialects are working against his/her read training. I however started with Arc & Clojure and I therefore experience the same lack of clarity when reading the traditional LISP dialects. To each their own.




3 points by steeleduncan 3802 days ago | link

Original blogger here. Apologies about the lack of indentation, I'm not sure how I missed that, it is a markdown conversion thing.

The point I was making in the blog is expressed more eloquently in [1], but to summarise: the difference between LISP and the countless languages that have risen and fallen during LISP's lifetime is that LISP directly represents the parse tree. By disposing of those parentheses in the (if ) statement, Arc has introduced the need to count the terms in the list to understand the sense of the code, in other words to parse it. Clearly the same is true of Python, C++, Haskell and many other languages I respect, but by placing a barrier between the code and the parse tree, Arc has abandoned the principle that makes LISP a global, rather than a local, minimum in the history of programming languages, and I think this is a mistake.



3 points by rocketnia 3802 days ago | link

It sounds like what you like to see are s-expressions that fit these patterns:

  homogeneous list of any number of X
  fixed-length heterogeneous list of (X Y Z)
  expression... which fits one of these patterns:
    call to X with args Y
Arc and Clojure make this more complicated by adding more cases, and I'll highlight Clojure's cases here:

  map from X to Y
  homogeneous vector of any number of X
  vector alternating between X and Y, with no excess (like a map)
  call to 'cond with args alternating between (expression) and
    (expression), with no excess
  call to 'case with args starting with (expression), followed by
    alternations between (anything) and (expression), perhaps with
    (expression) as excess
  function body which might begin with a docstring and/or a metadata map
  destructuring syntaxes
Between Arc and Clojure, I'm pretty sure Arc is intrinsically harder to auto-indent, because it doesn't distinguish between different cases using different kinds of brackets. Racket's a great example of what I mean; parens are used when the subsequent lines should be indented like function arguments, and square brackets are used otherwise.

For structured editing -- what you pursue -- we probably want even more static structure than what we want for auto-indentation.

I don't want to prod you to spend your time writing tools for niche languages or designing niche languages of your own, if that's not what you already want to do, but I'd like to ask what kinds of hypothetical languages you would like best....

Would you be eager to work with a lisp-like language where the AST has a few built-in notions of homogeneous lists, heterogeneous tuples, function calls, etc.? For instance, Lark defines an alternative to s-expressions that's more tailored to the ways the syntax is actually used (

On the other hand, would you be eager to work with a language where the AST has an endless variety of possible cases, which can be extended by any programmer who wants to write an editor widget? Racket does something related to this, because it has an expressive pattern language for writing macros, and macros written this way generate good parse errors automatically (

Personally, I've been kinda dreaming about both of these approaches to structured editing for a long time, but I'm still working on the run-time and link-time semantics of my language designs, so I've been unambitious when it comes to editing-time semantics. :)


2 points by thaddeus 3802 days ago | link

Fair enough, you're not saying anything wrong here, but I still do not agree. This really this is about the trade offs each of us are willing to make.

i.e Programmatically[1] yes you might need to count terms, but for code readability I do not count the terms I let code indentation guide me.

I can certainly see how this code indentation factor may be seen as too free in form or structure to be appealing to many, but having less parentheses is a huge readability/enjoyability win. A win that, at least for me, leads to huge gains in productivity.

Also, you do have the option to pretend the token count is even:

  (def example (x)
    (if (is x 1) "One"
        (is x 2) "Two"
        'else  "OOPS"))
It's up to you. In my mind power & flexibility are the big draws to LISP. If I wanted to be directed by the language as opposed to empowered by it I would just use C.

1. Once I've had to create a custom macro where I might have had to count the terms, but it's a rare event.


2 points by akkartik 3802 days ago | link

Welcome! I can see how lispers wouldn't like the arc approach, but I don't see how it makes arc more like non-lisps. What traditional language requires counting positions? I usually associate that with lisps.


2 points by thaddeus 3847 days ago | link | parent | on: Hylang: python via lisp

Ah, I missed that post and article. Thanks.


2 points by thaddeus 3847 days ago | link | parent | on: Hylang: python via lisp

I'm curious- has there been any work done towards an arc variant of this? Or even one that compiles to python?


2 points by thaddeus 3862 days ago | link | parent | on: A follow-up on the pipe operator

I like it. Can this be added into anarki?


2 points by akkartik 3862 days ago | link


I've also extracted the _ handling into a new function called (ugh) functionize. And I've fixed zap to show how you can make other functions "_ aware".

But like I said, this isn't as valuable in arc since you already have the [.. _ ..] syntax. All it permits is more widespread ssyntax use. You can say _.x instead of [_ x], and you can chain ssyntax around obstacles.

I found the idea interesting because it asks the question: do we need [.. _ ..] syntax, or can we eliminate the need for this reader macro just with a few simple changes to the functions where we most often use it?


4 points by rocketnia 3862 days ago | link

This is a horrible change. I didn't respond to the original post because of "Thumper's rule," and I couldn't rebut thaddeus in time to stop you. :(


== Problems with functionize in general ==

The functionize-based utilities are discontinuous about the way they detect underscores: The body can use _ three times, or two times, or one time, but as soon as it uses _ zero times, it means something completely different. Thanks to this, I can break several layers of code by making a single local edit. But will I? Yes:

The 'treemem function detects occurrences of _ without regard for quoting or local scopes. So if I use an _ to activate one functionize-based utility, then I'll accidentally activate all the other functionize-based utilities which surround that one. If I want to avoid refactoring several layers of code each time I edit, I pretty much have two options:

- I can avoid putting an _ anywhere in my code, in which case this functionize feature won't be very useful to me.

- I can make sure to activate each and every functionize utility as soon as I use it, in which case they would have been better off as 'let variants. For instance, I might settle on the idiom (zap (do '_ ...) foo), but it would be more convenient to say (zaplet orig foo ...).


== Problems in Arc ==

Your Anarki commit is one of those things that is "guaranteed to break all your code." Personally, I like using the pattern (zap [map [...] _] args), which now breaks since the _ activates zap's automatic function wrapper. It seems you would want me to write (zap (map [...] _) args) instead, but for compatibility with Rainbow, Jarc, etc., I think I'll define a macro (itfn ...) and write (zap (itfn:map (itfn:...) it) args). Effectively, I'll be recreating the [...] functionality in the way I like.

Meanwhile, Arc already covers a lot of the functionality of Clojure's -> and ->> operators using (aand ...). If you still miss -> or ->>, I recommend just implementing an 'aand variant that doesn't short-circuit on nil. Call it 'ado or something.

Here's how to use 'aand/'ado with the examples from that thread you linked to (

  (-> (range) [map [* _ _] _] [filter even? _] [take 10 _] [reduce + _])
  (-> 5 [+ _ 3] [/ 2 _] [- 1 _])
  (ado (range) (map [* _ _] it) (filter even? it) (take 10 it) (reduce + it))
  (aand 5 (+ it 3) (/ 2 it) (- 1 it))

== Considerations in Wart ==

Clojure's -> and ->> operators are not infix, and that might be good for their indentation. I'm not really sure.

  (-> (...)
  (...) ->
    (...) ->
      ...) ->
    -> (...)
    -> (...
    -> (...)
On the other hand, I like that you can potentially use infix to combine things like -> and ->> into one chain:

    -> (...)
    ->> (...
    -> (...)


1 point by akkartik 3862 days ago | link

Just spotted your comment while I'm working on something else. Haven't digested it all, but judging from the first five words -- feel free to revert! It was definitely intended as an experiment, and I'm not attached to it. I may well do so myself later today if you don't get to it first.


1 point by akkartik 3862 days ago | link

Ok, done reading now, and you're right, I'll revert it.

I can only defend myself against the wart section :) In wart the pipe operator can only take two args and is intended to be used in infix. I use a non-infix transform for more args, and for prefix mode in general:

My weak defense for the rest: functionize and the _ syntax was only intended for tiny expressions.


2 points by rocketnia 3861 days ago | link

"I can only defend myself against the wart section :) In wart the pipe operator can only take two args and is intended to be used in infix. I use a non-infix transform for more args, and prefix mode in general"

Oh, so you're pursuing both options at once. I look forward to you figuring out what kind of indentation you prefer here. :) My "considerations about wart" section was only wishy-washy anyway.


"For the rest, my weak defense is that functionize and the _ syntax is only intended for tiny expressions."

In Penknife, when I used the a'b operator as sugar for (b a), I found I ended up with a few really long lines of a.b.c'd'e.f, so it kinda suffered from its own success. ^_^ My a'b is the same as your (a -> b._), and it exactly corresponds to your no-underscore special case, (a -> b), so I expect you to have the same issue.

I suspect these syntaxes actually have a special tendency to let sugar accumulate, driving them away from the ideal "tiny expressions" case. Specifically, they make it possible to inject new code without breaking apart the surrounding sugar first:

  a.b.f.c.d                  # before refactoring
  a.b."foo".c.d              # illegal
  a.b -> (_ "foo") -> _.c.d  # legal? (not quite the example you gave)
  a.b'[itfn:it].c.d    # Penknife code of similar generality
Fortunately for wart, its infix operators allow whitespace in between, which possibly means you can write these long expressions on multiple lines. (That wasn't the case in Penknife.)


1 point by akkartik 3861 days ago | link

"I look forward to you figuring out what kind of indentation you prefer here. :)"

Here's my current thinking:

"these syntaxes actually have a special tendency to let sugar accumulate, driving them away from the ideal "tiny expressions" case."

Definitely. The wart example you gave is indeed legal, but the actual _ expression is still simple, even though the chain is long.

It seems nested expressions often work fine because each macro only wraps its arg and leaves the rest to the inside.

  (zap (map car._ _) (list list.1 list.2)
  => (zap (fn(_) (map car._ _)) ..)
  => (zap (fn(_) (map (fn(_) car._) _)) ..)
But that's less readable than when you have the [] delimiting scopes.

Some other concrete examples I came up with of the problems you pointed out:

  (zap (cons? & (fn(_) ..)) ..)  # broken by nested scope
  (zap (cons? & (fn(x) (+ '_ car.x)) ..)  # broken by quoting


1 point by akkartik 3861 days ago | link

It's out, and I'm not putting it back or anything, but FWIW:

  (mac functionize (expr)
    (if (and (treemem '_ ssexpand.expr)
             (~caris expr 'make-br-fn)
             (~caris expr 'fn))
      `(fn(_) ,expr)

  arc> (= x '((1) (2) (3)))
  arc> (zap [map [car _] _] x)
  arc> x
  (1 2 3)
This idea was in the wart version from the start ( but I didn't mention it for simplicity, and then totally forgot to carry it over into anarki.

It's still pretty hacky though, and has more in common with C's macros than with lisp's.


2 points by thaddeus 3864 days ago | link | parent | on: Why should zero be truthy?

> But I'm also happy if we don't have booleans at all, because then "Is this nil?" can just be a special case of "Is this a list?"

However, you do lose the ability to cleanly interop with other languages or transforms.