I don't disagree with you on either point. In fact, when I first saw Cyclone's syntax I thought "Huh?? That looks completely wrong!" When I thought hard enough about it, I kind of figured where they must be coming from, but I wouldn't call it intuitive.

As I wrote somewhere, I think what I would like most (consistency be damned) is to

1. Write region pointers as *T, not &T, and hence write region patterns as *P
2. Write unsafe pointers as *unsafe.T (i.e., a special region)
3. Write by-ref bindings as `let (&x, &y) = pair`

I also like "by-ref by default" but I don't know a way to combine that with the ability to write patterns in let. I guess we could just let alt and let patterns have different defaults. So you'd write:

    let (&x, &y) = pair // by ref
    let (x, y) = pair // copies

    alt pair { (x, y) ... } // by ref
    alt pair { (copy x, copy y) ... } // copies

In that case, I guess we'd want to add a "move" binding. Probably these two would be equivalent:

    alt move pair { (move x, move y) ... } // moves

That begs the question of what the heck this means:

    alt move pair { (copy x, copy y) ... } // copies? moves?

Here there would never be a need to copy but I suppose we could copy nonetheless. Or else we just move even though they said copy.


Niko

On 6/12/12 1:41 PM, Graydon Hoare wrote:
On 12-06-11 3:02 PM, Niko Matsakis wrote:
On 6/10/12 11:30 AM, Patrick Walton wrote:
I like this. The only concern, as a comment pointed out, is that "*"
might be slightly confusing; maybe "ref" is better.

Yes, gasche stated that using a keyword like `copy` and a sigil like `*`
seemed inconsistent. I can see that, I suppose, though I think that
using a keyword like `ref` that appears nowhere else in the language
seems even more inconsistent, not to mention heavyweight (who wants to
write `let (ref x, ref y) = pair`?).

I assume that Cyclone's reasoning with `*x` was that—like other
patterns—it's the inverse of what you would do to create the value.

It's not the inverse; the expression and pattern forms are _the same_. That is, to eliminate a record {x:foo} we write a pattern {x:foo} and recover foo. To match a @foo expression, we write the pattern @foo. The operational inverse of @ is * and {x:foo} is .x. But we're not talking inverses.

What you're doing is proposing -- a bit of a stretch -- that a user's intuition is that for any expression E, they "effectively" wrote *P for some imaginary pointer P, and they can recover that pointer by matching against the written-the-same-way pattern *P. Which is ... mathematically tidy, certainly hits the correctness note, but it feels to me like a bit of a footgun. Somehow no matter how many times I read it, when I see:

  let *x = foo;

I expect this means that foo is a pointer and x is bound to the pointee. I know that makes no sense. I'll try to inhibit that reflex and see how it goes.

I'm also concerned about the perf implication of copying by default. I guess it might be ok if the implicit-copies warning is turned on by default. Which we'll get to. It might slow things down quite a bit until that time...

Still, this is important work and these objections are more like uneasy feelings than fixes for same. I'd say go ahead with it and see how it fares. Worst case we have to revisit.

-Graydon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to