On Tue, Dec 23, 2014 at 10:36 AM, Eric Northup <[email protected]>
wrote:


> Monomorphism restrictions aside, wouldn't a re-writing pass that removed
> all mutability constraints on local variables be correctness-preserving?
>

Only after inference, because removal of a mutability constraint might lead
to an erroneous assignment becoming permitted. E.g. something like

let readonly x = *initializer* in ... x := newValue ...


is an error, and we want it to produce a diagnostic. But once we confirm
that assignments are allowed, the main effect of mutability erasure would
be to *reduce* monomorphism constraints where a variable may have been
marked as mutable but never assigned. In addition, *deep* mutability
annotations can't be removed correctly.


> Or did you have a way to express the difference between "not mutable
> through this alias" and "not mutable by any alias" for function arguments,
> which would force callsites to have mutability restrictions for
> compatibility with callee's signatures?
>

We did *not* have a way to express this in v0, and it's clearly needed.
It's exactly the distinction I was talking about in my message of a few
minutes ago. And it seems to be a regrettably complicated distinction to
explain to programmers. But to answer your question, a procedure

f : 'a -> int


actually doesn't propagate mutability back into its caller. Any mutability
annotation on 'a can be erased without change. The case that *can't* correctly
be erased is:

f : ref (mutable 'a)


in that signature, the ref itself is mutability oblivious, but the *target* of
the ref is mutable, and that may actually be a semantic requirement of the
larger program. In generally, we don't attempt to do deep copy
compatibility in BitC at the moment. If nothing else, it would lead to a
huge proliferation of minor variations on types, which would likely lead to
a huge increase in the number of types we would need to instantiate (think
containers).

Same issue arises with

f : ref (immutable 'a)


but for real fun, consider:

f : ref (deeply immutable 'a)



> In C++11's "auto" type inference for local variables is terrifically
> useful, and the burden of writing
>
> const auto x = ...
>   vs
> auto x = ...
>
> seems minimal relative to the benefits to human readers.  Enough so that
> C++ code style reviewers at Google will ask for the "const" to be added in
> if the original author neglected it.  Google's C++ style guide, though,
> does prefer for much more verbosity about spelling out type names etc than
> scripting languages, so it may not be your preferred design point.
>

I think your making a valid point here, though I'd argue that the language
should be defaulting the other way. That is: I share your view about the
desirability of documentation, but since we want the majority of values to
be const I'd prefer to see us annotating the mutable ones explicitly rather
than the const ones.

Part of the reason this looks so appealing is that the places where C++
does inference are so restrictive. As much as I like the intuition you're
appealing to, it may not generalize well to other parts of the type system.

IMO, the single biggest advantage of auto in C++ is that it eliminates the
need to state some commonly used type names from the standard library that
have deep namespaces. There seems to be an unstated requirement in the C++
library standard that no iteration type name should fit on a Hollerith
card. :-) Ironically, the fact that (a) C++ *doesn't* do full local
inference, and (b) there are many integer types means that it's not so
useful for simple locals. E.g.

auto i = 1;


doesn't work.


> Multiple languages have added local type inference recently, seemingly
> without much disruption to their semantics.  That suggests that BitC could
> start out with requiring the explicit annotations and then later gain
> inference (if motivated by experience) off the critical path of developing
> the language.
>

Yes. And I'm actually heading in this direction for BitC, mainly because
inference in the presence of type-based overloading doesn't play nicely.

Actually, it turns out this was *nearly* true in BitC all along, because
the need to specify all of the types at a module interface (i.e. all of the
exported signatures) for the sake of separate compilation comes very close
to specifying the types anyway.


The one thing I'd throw in here, though, is that baking a style guideline
into the language seems like a bad idea if we don't have to do it. It seems
better to do as much inference as possible during the initial dev authoring
stage, and then right-click a mouse somewhere and say "now throw in what
the style guide demands for me".


shap
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to