Arc Forumnew | comments | leaders | submitlogin
4 points by krapp 2159 days ago | link | parent

But why should an empty list be falsy? An empty list can be as valid a form of list as a non-empty one. It also seems to me that an empty list shouldn't be nil, since to me, nil should mean "undefined", and an empty list is well defined as an empty list.

Would disambiguation here really make Arc programs less terse? Is that a decision that should be enforced by the language or left to the author?



3 points by akkartik 2159 days ago | link

In my example above, making an empty list truthy would cause this change:

    (def map1 (f xs)
    "Returns a list containing the result of function 'f' applied to every element of 'xs'."
   -  (if xs
   +  (if (~empty? xs)
        (cons (f car.xs)
              (map1 f cdr.xs))))
We can argue how important this is, but disambiguation does definitely make Arc programs less terse.

-----

3 points by shawn 2159 days ago | link

Two points.

- the assumption baked into this argument is that cdr of an empty list returns an empty list. Switching nil to #f and letting empty list be truthy avoids this problem.

- Good names are important. ~empty? isn't really a fair characterization. Lumen uses (some? xs). There is also another way: Update `no` to be (or (is x nil) (empty x)), and then use (~no xs).

-----

2 points by akkartik 2159 days ago | link

First option makes sense.

Second option, part a: I actually find `~empty?` clearer than `some` in this case. Also `some` means something different in Arc.

Second option, part b: wait, then `(if xs ...)` would sometimes not do the opposite of `(if (no xs) ...)`!

-----

2 points by rocketnia 2159 days ago | link

For what it's worth, my approach here is pattern-matching. In Lathe Comforts for Racket I implement a macro `expect` which expands to Racket's `match` like so:

  (expect subject pattern else
    then)
  ->
  (match subject
    [pattern then]
    [_ else])
If Arc came with a similar pattern-matching DSL and `expect`, we could write this:

  (def map1 (f xs)
    (expect xs (cons x xs) ()
      (cons (f x) (map1 f xs))))
The line "expect xs (cons x xs) ()" conveys "If xs isn't a cons cell, finish with an empty list. Otherwise, proceed with x and xs bound to its car and cdr."

-----

1 point by i4cu 2159 days ago | link

I agree; an empty list is a value. And when you consider interop with other langs, they will infer it to be some object too, where predicates will see it as a value not the lack of one.

-----