Arc Forumnew | comments | leaders | submitlogin
3 points by akkartik 4012 days ago | link | parent

You're right about blocks, so let's just focus on single-line 'if's. I can't think of a single non-lisp that allows adjacent condition and action without an intervening token. C and Java require parens, Go and Perl require curlies, Python requires the colon, Ruby requires a newline or semi-colon.

  if (condition) action;     # C, Java
  if condition { action; }   # Go, Perl
  if condition: action       # Python
  if condition; action; end  # Ruby
The 'else' token is a further separator. Never in these languages will you ever have two either-or expressions side by side. They're separated by either 'else' or 'else if' or 'elif'. Perl and Ruby even sometimes use 'if' as a separator.

  action if condition        # Perl, Ruby
Am I missing any counter-examples? I think the biggest error in this article is to blame Arc, when it's just extending the logic all lisps have always had. If you permit such adjacencies as (if condition action) and (cond ((condition action))), then Arc's choices don't seem so unreasonable.

(Though Clojure's mixture of Arc 'if' and optional types is a whole new level of unholiness.)



3 points by rocketnia 4011 days ago | link

"Though Clojure's mixture of Arc 'if' and optional types is a whole new level of unholiness."

Is this what you meant instead? "Though Clojure's 'let', which mixes Arc's 'withs' with type hints, is a whole new level of unholiness."

Even so, I think Clojure's 'let doesn't actually have any[1] added complexity when it comes to type hints. It might look like the list is bunched into groups of either two or three depending on whether a type hint is present...

  (let [^String x "x string"
        y 2]
    (body-goes-here))
...but that's not a quality of 'let. That's a quality of the ^ syntax. An occurrence of ^ consumes the next two s-expressions, just like ' consumes the next one s-expression:

http://tryclj.com/

  > '[^String foo "foo"]
  [foo "foo"]
  > (count '[^String foo "foo"])
  2
  > '[^String]
  java.lang.RuntimeException: Unmatched delimiter: ]
  > '^String foo
  foo
  > (meta '^String foo)
  (:tag String)
So the bindings of a 'let are consistently bunched into groups of two s-expressions, just like Arc's 'withs.

[1] Of course, the type hints are actually used for optimization at some point, so the complexity of parsing them has to go somewhere. This is exactly as complex as destructuring: Arc's 'withs syntax supports destructuring, but it doesn't need special-case destructuring logic because it just translates down to 'fn. As it happens, Clojure's 'let syntax also supports destructuring, and it probably uses the same general technique.

-----

2 points by akkartik 4011 days ago | link

Yes! Turns out I didn't notice the switch from if to let.

I have to say, though, I have no sympathy for the argument that it's still groups of two s-expressions. As a reader it's still more onerous to have to mentally group:

  ^a b
compared to:

  'a
So the presence or absence of parsing complexity feels irrelevant.

-----

2 points by fallintothis 4012 days ago | link

I can't think of a single non-lisp that allows adjacent condition and action without an intervening token.

I mean, isn't this requirement mostly because those languages are infix anyway? Parsing gets easier with explicit ways of separating things. I could easily imagine shift/reduce conflicts or what-have-you cropping up when you try to eliminate the requirement for, say, parentheses around conditionals in Java.

For example, in some hypothetical infix language that doesn't require conditional separators (parens, braces, then, etc.), would

  if x==10-x ...
be

  if (x == 10) -x ... // maybe this language doesn't use the "return" keyword,
                      // so the conditional is returning negative ten.
or

  if (x == (10 - x)) ...
?

Because Lisps use s-expressions, "intervening tokens" (per se) are unnecessary. As you say, Arc's choices don't seem so unreasonable, considering that.

-----

2 points by akkartik 4012 days ago | link

Yeah, that's a good point. Non-lisps use keywords and punctuation for readability and to make parsing tractable, and the two reasons are often hard to separate in any single design decision.

To summarize my position: I have some sympathy for the specific argument that multi-branch 'if's are harder to read in lisp than in traditional languages[1]. But this affects any arrangement of parens, whether traditional 'cond' or arc 'if'.

[1] I see I said so to you before, at the end of http://www.arclanguage.org/item?id=16838.

-----