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
