Arc Forumnew | comments | leaders | submitlogin
1 point by absz 6000 days ago | link | parent

You can use OO structure-access semantics with tagged unions: (tu 'slot-name) and (= (tu 'slot-name) new-value). That's not the interesting part of OO, of course :)

I thought about returning an error, but Arc seems to be a little calmer about such things: (is (car nil) (cdr nil) nil), for instance. Of course, (car 'sym) errors. ::shrug:: I'm not sure about this, and it might change.



3 points by rkts 5999 days ago | link

The purpose of a type system is to help find errors by failing early instead of letting bugs propagate through a system and show up in mysterious ways. Right now, you're actually making debugging harder because you're just wrapping bugs inside other bugs. Instead of figuring out why his binary tree turned into a cheeseburger, a programmer now has to determine (a) why his binary tree is nil (or why mutating it seems to have no effect), (b) which invariant he violated, and (c) what error caused the invariant to be violated.

Regarding (car nil) and (cdr nil), these return nil because it's sometimes convenient. For instance, here's a function that collects every other item in a list:

  (def foo (xs)
    (if xs
      (cons car.xs (foo cddr.xs))))
If (cdr nil) raised an error, we would have to check the cdr before we could recur:

  (def foo (xs)
    (if xs
      (cons car.xs (if cdr.xs (foo cddr.xs)))))
Not a huge difference, obviously, but a difference nevertheless. I can't see any comparable reason to return nil in your case.

-----

1 point by absz 5999 days ago | link

Fair enough, you've convinced me.

EDIT: Creation, reading (defcall), and writing (sref) all give errors if invariants are violated/nonexistent keys are accessed. Is there anything I missed?

-----