On Tue, May 09, 2017 at 02:11:41PM -0700, L. David Baron wrote:
> On Tuesday 2017-05-09 11:58 +0200, Emilio Cobos Álvarez wrote:
> > I think references help to encode that a bit more in the type system,
> > and help reasoning about the code without having to look at the
> > implementation of the function you're calling into, or without having to
> > rely on the callers to know that you expect a non-null argument.
> >
> > Personally, I don't think that the fact that they're not used as much as
> > they could/should is a good argument to prevent their usage, but I don't
> > know what's the general opinion on that.
>
> I have two general concerns about references:
>
> (1) When reading the calling code that calls a function taking a
> non-const reference, it's not obvious that the function might
> mutate the value, particularly in code that uses references
> rarely, or for types that are rarely passed as references.
Isn't it similarly non-obvious for code that takes non-const pointers
when the object isn't in the stack?
For example, if I have `void foo(Element*)`, which calls
`void bar(Element*)`, and both assume a non-null argument, I don't see
how potential mutation is more obvious there than `void foo(Element&)`
calling `void bar(Element&)`.
(Other people are concerned about non-const references used for
outparams. I think I'll be fine with the rule Nathan proposed in the
thread as a rule of thumb).
> (2) Code that mixes functions that take references and functions
> that take pointers, for the same time, is a mess, because you
> constantly have to worry about whether to write * or &.
I agree with this, though I don't think writing & or * is a big deal in
most cases.
> Thus, in Gecko, we generally use pointers or references per-type.
> XPCOM interfaces are passed by pointer. String classes are
> passed by reference. etc.
>
> I think per-type conventions for using references versus pointers
> helps with both (1) and (2), and I consider it part of Gecko style
> even if it's not well-documented.
The issue I have with per-type conventions is that it doesn't scale very
well, specially when you're writing new code (and more specially if
they're not documented in the style guide).
What should the convention be for `ServoStyleSet` (which is what
triggered this thread)? Who decides that, and based on which arguments?
> I'm also not sure how much references help with enforcing
> non-null-ness. People will just write a "*" whether or not their
> existing code guarantees a non-null pointer; at least that was my
> experience in the early days of Gecko. Perhaps we have better code
> review now... but I'm somewhat skeptical of that given that I think
> we've been relying on tests more and review less?
I'm not talking about enforcing non-null-ness, because as you've pointed
out, references don't necessarily do that.
I think the main benefit is at the time of both reading and reasoning
about the code. Using references allows you to quickly figure out what
kind of thing a function expects, handles, or returns, without having to
look at the function itself and potentially all the callers.
-- Emilio