Sadly, you should really read this subsequent blog post:

http://smallcultfollowing.com/babysteps/blog/2013/01/15/lifetime-notation-redux/

It turns out that this syntax is ambiguous without introducing a whitespace
dependency. I think it might still be worth it, but I know that a lot of
people tend to shy away from such things on principle.


On Tue, Jan 22, 2013 at 2:01 PM, Dean Thompson
<[email protected]>wrote:

> Looking at Niko's blog post
>
>
> http://smallcultfollowing.com/babysteps/blog/2012/12/30/lifetime-notation/
>
> We do, to my eye, get a huge improvement if we both tweak the notation and
> also augment the ref deconstruction syntax to indicate the resulting
> pointer
> timeline.
>
> Doing this with Niko's preferred option 8 gives us:
>
>     pure fn each(&self, f: fn(&(&{self}K, &{self}V)) -> bool) {
>         match *self {
>           Leaf => (),
>           Tree(_, ref{self} left, ref{self} key,
>                ref{self} maybe_value, ref{self} right) => {
>             left.each(f);
>             match *maybe_value {
>                 Some(ref{self} value) => {
>                     f(&(key, value));
>                 }
>                 None => ()
>             };
>             right.each(f);
>         }
>     }
>
>
> FWIW, Niko's ${foo}bar notation helps my mental "parser" a great deal,
> because it
> makes foo look like a modifier to me. When I see &foo/bar, my mind fights
> to make
> it a pointer to foo with a strange trailing bar.
>
> Dean
>
>
> On 1/22/13 9:23 AM, "Graydon Hoare" <[email protected]> wrote:
>
> >On 22/01/2013 6:55 AM, Dean Thompson wrote:
> >
> >> I'm looking at some code that Niko Matsakis updated in
> >> https://github.com/stevej/rustled/commits/master/red_black_tree.rs
> >>
> >>   pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) {
> >>     match *self {
> >>       Leaf => (),
> >>       Tree(_, ref left, ref key, ref maybe_value, ref right) => {
> >>         let left: &self/@RBMap<K,V> = left;
> >>         let key: &self/K = key;
> >>         let maybe_value: &self/Option<V> = maybe_value;
> >>         let right: &self/@RBMap<K,V> = right;
> >>         left.each(f);
> >>         match *maybe_value {
> >>             Some(ref value) => {
> >>                 let value: &self/V = value;
> >>                 f(&(key, value));
> >>             }
> >>             None => ()
> >>         };
> >>         right.each(f);
> >>       }
> >>     }
> >>   }
> >>
> >> I understand this code reasonably well. I greatly value the attention
> >> to safety in Rust, and I appreciate the value of pointer lifetimes in
> >> maintaining that safety.
> >>
> >> My gut reaction, though, is that this code is almost as intimidating
> >> as Haskell. Even more worrisome to me, I think most mainstream
> >> programmers would find the *explanation* of this code intimidating.
> >
> >I agree that the cognitive load on this code sample is high. This is the
> >main risk we took (aside from "potential unsoundness", which I didn't
> >really think to be a big risk, judging from Niko's comfort with the
> >semantics) when adopting first class region pointers: that the resulting
> >types would be too complex to understand, and/or require too much
> >chatter when writing out in full.
> >
> >To my eyes the matter is not yet entirely clear. It's complex but it's
> >not quite "impossibly complex"; if you made all the '&self/' symbols
> >into just '&' it would be, I think, not so bad. Compare if you like to
> >the associated bits of code from libc++ required to implement
> >roughly-equivalent "iterate through the treemap" sort of functionality:
> >
> >
> >_LIBCPP_INLINE_VISIBILITY
> >__tree_iterator& operator++() {
> >    __ptr_ = static_cast<__node_pointer(
> >        __tree_next(
> >            static_cast<__node_base_pointer>(__ptr_)));
> >    return *this;
> >}
> >
> >template <class _NodePtr>
> >_NodePtr
> >__tree_next(_NodePtr __x) _NOEXCEPT
> >{
> >    if (__x->__right_ != nullptr)
> >        return __tree_min(__x->__right_);
> >    while (!__tree_is_left_child(__x))
> >        __x = __x->__parent_;
> >    return __x->__parent_;
> >}
> >
> >template <class _NodePtr>
> >inline _LIBCPP_INLINE_VISIBILITY
> >bool
> >__tree_is_left_child(_NodePtr __x) _NOEXCEPT
> >{
> >    return __x == __x->__parent_->__left_;
> >}
> >
> >template <class _NodePtr>
> >inline _LIBCPP_INLINE_VISIBILITY
> >_NodePtr
> >__tree_min(_NodePtr __x) _NOEXCEPT
> >{
> >    while (__x->__left_ != nullptr)
> >        __x = __x->__left_;
> >    return __x;
> >}
> >
> >And keep in mind that there is no memory-safety in that code: if I
> >invalidate a C++ map while iterating, I just get a wild pointer
> >dereference and crash. If I rewrote it in terms of shared_ptr<> it'd be
> >even chattier.
> >
> >> Who is our target audience for Rust? Graydon has said it is
> >> "frustrated C++ developers", but how sophisticated and how "brave"
> >> are we thinking they will be?
> >
> >The target audience is frustrated C++ developers, same as always. If
> >they balk at the syntax for lifetime-bounds on borrowed pointers, then
> >yes, we've blown the cognitive budget, and have failed.
> >
> >It is not clear to me yet that that's true. But it's a risk. One we're
> >all aware of and worried about.
> >
> >> How intimidating do we think Rust is today? Am I just overreacting
> >> to unfamiliarity?
> >
> >I don't know. It's a very hard thing to measure. I know of lots of
> >languages that have failed for this reason. It's a major hazard.
> >
> >> How can we calibrate our "intimidation factor" before language
> >> decisions start getting harder to change?
> >
> >If you search our mailing list, IRC logs or meeting minutes for
> >"cognitive budget", "cognitive load" or "cognitive burden" you will see
> >we have always been keenly aware of this risk and treat it as a primary
> >constraint when doing design work. It's a leading reason why many
> >features have been removed, simplified, minimized or excluded from
> >consideration.
> >
> >> Do we want (and is it feasible) to define a simpler subset of the
> >> language that beginners are encouraged to stick to and that most
> >> libraries don't force clients away from?
> >
> >Personal opinion: no. That just makes the issue even more confusing. The
> >way to approach this is head-on, by looking at the things that cause the
> >most confusion and trying to make them cause less.
> >
> >Thanks for bringing this up. I'm interested to hear others' opinions on
> >whether we're past a reasonable limit of comprehensibility. It's a hard
> >thing to hear, but better to hear now than later, if true.
> >
> >-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
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to