[bitc-dev] Mutability inference
Jonathan S. Shapiro
shap at eros-os.org
Tue Jun 20 09:00:12 EDT 2006
Thinking about your note, I agree that the cases are more general than I
initially thought, but perhaps not so general as you are saying. I
wasn't fully convinced that maybe-mutable could be fully eliminated by
this -- I just thought that this might help. It would be very useful to
get an enumeration of all the places where maybe-mutable is introduced
at the moment.
In either case, I don't think that deep mutability is needed in general.
Here is why:
First, this only arises for let bindings and lambda arguments.
Second, we do not do type inference for structure fields, and we should
not normally do mutability inference for these. This means that given
(set! struct.field value)
we are not required to infer the mutability of "field" (which, in any
case, would emerge from the declared field type). In particular, this
means that we don't need to deal with (set! a.fst value).
Third, for the same reason, we don't need to inference across deref.
Given 'a^' the target type is already determined from 'a'.
So I think this reduces us to locations consisting of IDENT and
(compositions of) array and vector.
My personal opinion is that if we *only* do inference for
(set! IDENT x)
this will get the vase majority of the real cases. It might be pleasant
to also attempt to deal with
(let ((v (vector ...)))
(set! v[4] value))
but this is more than a little tricky because of nesting:
(let ((v (vector ...)))
(set! v[4][5] value))
I am not sure if we should bother inferring mutability in this case --
we need to unify it when present in the declaration, but I'm not sure
that we should infer it. My main concern is that in the vector(or array)
element inference there really is nothing available in the resolver
phase that we can mark, because there is no corresponding AST.
Here is what I propose:
1. Let's go ahead and infer **top level** mutability only. That is,
we will *only* infer in the presence of
(set! IDENT v)
this is very useful independent of anything else.
2. We can then figure out if the rest is worthwhile. I think this
should be guided by first enumerating the places where you
currently insert maybe-mutable. I suspect that you were very
liberal, and that we may want to cut this back.
On Mon, 2006-06-19 at 22:28 -0400, Swaroop Sridhar wrote:
> Jonathan S. Shapiro wrote:
> > I'm no longer convinced that maybe-mutable was the right thing.
> >
> > First, it seems to me that this only applies for surface mutability.
>
> This is not true. I introduce a may-be type wherever I am uncertain.
> For example, consider:
>
> (let ((vec (vector #t #f #t))
> ;; vec: (maybe (vector (maybe bool)))
>
> ...
> (set! vecp[2] 25)
> ;; vec: (maybe (vector (mutable bool)))
>
> ...
> )
>
>
> > Second, it only applies for locations consisting (solely) of
> > identifiers.
>
> No, it applies for all locations, as described by the above example.
>
> In fact, in order support to things like:
>
> (define (vec (vector #t #f #t)
>
> (set! vecp[2] 25)
>
> I am _not_ clearing all maybes at top level. _Only_ the maybes around a
> polymorphic type variable are cleared. All further passes including the
> pretty printer treat maybe-mutables as if it were immutable.
>
>
> > Therefore, I wonder if this should not be handled in the resolver
> > processing of SET!. When we see:
> >
> > (SET! <ident-pattern> expr)
> >
> > we should set a flag ID_IS_MUTATED on the defining occurrence.
>
> I like your scheme, but this analysis must be deep over all location
> expressions. Let me think about this a little more.
>
> Swaroop.
More information about the bitc-dev
mailing list