Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 5034 days ago | link | parent

definitely food for thought, thanks :)

  Me: "Don't give me two different names with subtle variations,
  give me one strong name."
  You: "The difference between 'testify and 'conversionify isn't subtle.."
Yeah I wasn't talking about your previous suggestions. I was talking about eq vs eql vs equal, or about string vs coerce 'string. I was talking about subtle variations in names.

Yes I still use eq. It's useful in some cases, no question, but not so often that it merits thinking about what to call it. If I were creating a runtime from scratch, I'd give it a long name, like pointer-equal or something. If I find a better use for the name I'll override it without hesitation.

Names that take up prime real estate are like defaults. Having a bunch of similar-sounding, equally memorable words that do almost the same thing is akin to having large, noisy menus of preferences. They make the language less ergonomic, they make it harder to fit into people's heads. "What does upcase do to a list again? Does it use this coerce or that one?"

If the default doesn't work for someone of course they'll make their own up. This is lisp. They're empowered. I don't need to consider that case. My job as a language designer is to be opinionated and provide strong defaults.

I'm only arguing the general case for coercions. It's possible that we need multiple kinds of coersions in specific cases, and that these need to have prime real estate as well.



1 point by rocketnia 5033 days ago | link

Okay, agreed on pretty much all accounts. ^^

---

If I were creating a runtime from scratch, I'd give [is] a long name, like pointer-equal or something.

Yeah, I think it's a bit unfortunate that 'iso has a longer name than 'is. I've thought about calling them '== and '=== instead, or even '== and 'is for maximum brevity, but those are more confusing in the sense you're talking about, in that their names would be interchangeable. I can't think of a good, short name for 'iso that couldn't be mistaken for the strictest kind of equality available. "Isomorphic," "equivalent," "similar," and maybe even "congruent" could work, but "iso" is about as far as they can be abbreviated.

...Well, maybe "qv" would work. XD It has no vowels though. Thinking about Inform 7 and rkts-lang makes me strive for names that are at least pronounceable; I remember Emily Short mentioning on her blog about how a near-English language is easier for English typers to type even when it's verbose, and rkts posting here about how it's nice to be able to speak about code verbally. I think it's come up a few times in discussions about the name 'cdr too. ...And I'm digressing so much. XD;;;;

---

I'm only arguing the general case for coercions.

This is the one spot I don't know I agree with, but only because I don't know what you mean. What's this "general case" again?

-----

1 point by evanrmurphy 5033 days ago | link

How about id for is and is for iso? :)

Update: After reading over the ancestor comments more carefully, I guess this wouldn't address akkartik's concern. Nonetheless, I kind of like id.

> "Isomorphic," "equivalent," "similar," and maybe even "congruent" could work

Also keep in mind the words "alike", "same" and "exact".

-----

4 points by akkartik 5033 days ago | link

id could also mean the mathematical identity function, which arc calls idfn probably because it's a lisp-1 and we want to be able to create locals called id.

Hmm, how about if id was a low-level beast that converted any object into a say ptr type that contained its address. Now instead of (is a b) you'd say:

  (iso id.a id.b)
That seems to me about the right level of verbosity for doing the things is does that iso can't do.

-----

2 points by rocketnia 5033 days ago | link

I agree with that! :)

In Java, everything uses equals() where it can, but then it's not easy to get == behavior when it matters. Technically you can use a wrapper:

  public final class Id
  {
      private Object x;
      public Id( Object x ) { this.x = x; }
      
      public int hashCode() { return System.identityHashCode( x ); }
      public boolean equals( Object obj )
          { return obj instanceof Id && ((Id)obj).x == x; }
  }
I'm digressing, but it would be so much nicer if every object kept a hard reference to its Id wrapper. That way the Id could be used as a WeakHashMap key.[1] Weak tables are one place where comparing keys for anything but reference identity makes no sense. XD

Back in terms of (iso id.a id.b), this would have the observable effect that (iso id.id.a id.id.a) would be true for all a.

[1] Thanks to the hard reference to the Id from its x, the Id itself wouldn't be collected until its x was unreachable too. A Id without such an anchor would potentially be garbage-collected much earlier than its x, and the WeakHashMap entry would be lost. ...Anyway, some of this could be solved by changing the design of WeakHashMap. :)

-----

1 point by evanrmurphy 5033 days ago | link

I like this! Would the id of a primitive just return itself?

  id.4 ; evaluates to 4 or the address where this 4 is stored?

-----

3 points by akkartik 5033 days ago | link

I think all we need is that it be a stable value when literal objects are interned. So id.4 would probably never change, and (id "a") would change in common lisp because it creates new strings each time.

-----

1 point by rocketnia 5033 days ago | link

The name "is" is just so perfect though. What we're talking about is the difference between "the same regardless of who and why you ask" and "the same if you ask the type designer." When I see something like "is" that plainly communicates sameness, I assume it's the no-matter-what version. On the other hand, saying things are "similar" doesn't entail they're identical; they might only be identical enough.

I do like "alike." It's short, and it suggests it has something to say about non-identical arguments. It's better than "like," because (like x y) could be interpreted as "x likes y" or "cause x to like y."

-----

1 point by akkartik 5033 days ago | link

"The name 'is' is just so perfect though."

To stretch my analogy to breaking point, that's like saying I wish we could build a hundred yards into the ocean, it would make such fine waterfront property :) Some things are 'prime' but not real estate.

Ok that is probably not clear. I think I'd use is or iso, but not both.[1] iso is perfect because it is short and precise and conjures up the right image. I'll probably never find a use for is. That's ok. Good names minimize cognitive overhead, but there's still some overhead. The best name is the one you don't need, and there's enough good names that we don't have to microoptimize.

---

I'm not sure which variant is "the same regardless of who and why you ask". In common lisp there's 30 years of rationalizations why this is 'intuitive':

  * (eq "a" "a")
  nil
Yet arc chose otherwise:

  arc> (is "a" "a")
  t
So clearly it's not "the same regardless of who you ask".

If you created syntax for hash-table literals you may want this to be true:

  (is {a: 0} {a: 0})
So the semantics of is are actually quite fungible. If pointer equality is a low level beast that requires knowing internal details let's not put it on a pedestal and give it a prime name.

(Again I'm less certain than I seem.)

[1] I think isa is fine though it's so similar in form because it's different enough from iso in behavior.

-----

1 point by rocketnia 5033 days ago | link

I'm not sure which variant is "the same regardless of who and why you ask".

By "the same regardless of who and why you ask," I mean something at least as picky as "the same regardless of what algorithm you try to use to distinguish them." Notice that the pickiest equality operator in a language is the only one that can satisfy that description; any pickier one would be an algorithm (well, a black-box algorithm) that acted as a counterexample.

I think 'eqv? is this operator in standard Scheme and 'eq? is this operator in any given Scheme implementation (but I dunno, maybe it's more hackish than that in practice). Meanwhile, I think 'is acts as this operator in a "standard" subset of Arc in which strings are considered immutable. (A destructive algorithm can distinguish nonempty mutable strings.) I avoid string mutation in Arc for exactly this reason.

---

So the semantics of is are actually quite fungible.

Yeah, especially once you get down to a certain point where nothing but 'is itself would allow you to compare things, then 'is is free to be however picky it wants to be. A minimally picky 'is would solve the halting problem when applied to closures, so something has to give. :)

The least arbitrary choice is to leave out 'is altogether for certain types, like Haskell does, but I dunno, for some reason I'm willing to sacrifice things like string mutation to keep 'is around. I mean, I think it's for the sake of things like cyclic data structures, uninterned symbols, and weak references, but I don't think those things need every type to have 'is.... Interesting. I might be changing my mind on this. ^_^

-----

1 point by akkartik 5033 days ago | link

In general coerce is more useful than a bunch of specific coercion functions (say of the form srctype->desttype). Specific cases like testify may need multiple coercion functions, though.

-----