Arc Forumnew | comments | leaders | submitlogin
Iso
2 points by cacplate 3170 days ago | 5 comments
Is there a reason to create iso only for list comparison? I think I don't fully understand the logic behind is and iso.

Could someone explain it to me?



3 points by akkartik 3170 days ago | link

Are you reading the tutorial or anarki or something else? Arc started out defining iso just for lists, but the name ('isomorphic') was evocative enough that we ended up extending it to arbitrary aggregates, including tables.

  arc> (iso (obj 'a 'b) (obj 'a 'b))
  t  ; nil in arc 3.1
Hopefully we're still following the original vision, and it was just an oversight that iso doesn't support tables in arc 3.1. The interpretation is that is is for primitives when you care about fast comparison, and iso is for aggregates and arbitrary user-defined types. Since arc's tagged types are just lists, supporting lists and tables ensures iso will continue to support any user-defined types.

Over time my personal opinion (and that of some others here, but I'll let them speak for themselves) has diverged from the tutorial. I think it's useful to have one strong default operator that usually "does what you want", which is to make equal-looking things equal. So I advocate using iso everywhere unless you explicitly want to compare pointers.

-----

3 points by rocketnia 3168 days ago | link

No offense, but I'd like to give your comment an awful lot of errata:

Those objects you're creating will have the cons list (quote a) as a key. Non-atomic keys are full of gotchas because Arc's tables use use Racket's 'equal? for key comparison, rather than using 'is or 'iso. This means tables care whether a list ends in the symbol 'nil or the Racket empty list (), which is a detail that's otherwise invisible in Arc.

(If you want the symbol 'a as a key, the code is (obj a 'b).)

Arc's tagged types are not lists, and 'iso can support lists without supporting tagged types. (Personally, I wouldn't want 'iso to dig around in my tagged types anyway. I like pretending the data inside is encapsulated, except where my code absolutely needs to access it.)

Finally, does 'iso actually support tables in Anarki? I can't try it out right now, but I don't see any code for this when I search GitHub.

-----

2 points by akkartik 3168 days ago | link

Errata gratefully accepted :) I blame interference from wart. I was running anarki while I wrote this comment, but clearly I wasn't running it enough.

"Finally, does 'iso actually support tables in Anarki? I can't try it out right now, but I don't see any code for this when I search GitHub."

It's in a defextend clause (https://github.com/arclanguage/anarki/blob/becefed840/arc.ar...) followed immediately by support for tagged types.

  (defextend iso (x y) (isa x 'table)
    (and (isa x 'table)
         (isa y 'table)
         (is (len keys.x) (len keys.y))
         (all
           (fn ((k v))
             (iso y.k v))
           tablist.x)))

  ; default impl for tagged types
  (defextend iso (a b) ($.vector? a)
    (iso ($.vector->list a)
         ($.vector->list b)))
Does the 'default impl' trigger your gag reflex? :)

-----

2 points by rocketnia 3168 days ago | link

Oops, I assumed Github's search would show me every occurrence in every file, like a recursive grep. No such luck, I guess. :-p So you got me.

While that's a reasonably useful default behavior for 'iso on tagged types, I'm not particularly happy to see it.

Arc provides very few helper utilities for working with tagged types--basically just the axioms 'annotate, 'type, and 'rep, plus 'isa and 'coerce--and the documented purpose of tagged types is for user-defined types. I came to Arc from a more OO-like background and saw this as a good way to control access to the implementation details of my types. Unless you explicitly called 'rep, you didn't get more coupling than you bargained for. This gave 'rep almost an "unsafe" reputation for me.

If 'iso gets to access the rep at will, then I may have been programming in Arc less robustly than I expected: Either each of my types should have come with an 'iso extension to reinforce my encapsulation, or I should have considered 'iso "unsafe" and used it less often. Not that I could have known this at the time! :)

But it's not a big deal. I do deep comparison operations sparingly enough as it is, and I don't know if my soft encapsulation technique actually matters because I rarely saw anyone else following similar guidelines. (I've rarely seen anyone using 'annotate at all, actually, and I think it's been a common complaint that 'annotate is basically 'cons with fewer utilities built up around it. That's a plus for me, I guess, lol.)

A good example of me considering an operation "unsafe" is earlier in this thread, where I discouraged the use of compound values as table keys. It just so happens Arc's table key comparison breaks the encapsulation of tagged types as well. :)

-----

2 points by dido 3168 days ago | link

Equality is actually a rather complicated thing. The way I understand it 'is' is an object equality predicate, roughly equivalent to Scheme's 'eqv?' for most data types. The 'iso' function on the other hand sounds like it was intended to be a structural equivalence primitive (which is what isomorphism means in mathematics), which should roughly have the semantics of Scheme's 'equal?'. Arc 3.1 defined iso only for lists, but it seems that just about every other third-party implementation including my own Arcueid extended it to arbitrary other objects such as tables.

-----