Jonathan S. Shapiro wrote:
> Question: is non-allocation sufficiently important enough that it should
> be part of the in-language type system, or is the use-case for it rare
> enough that we should handle it in a static checker?
>
> But the subjective evidence from other languages that *do* have
> effect types is that they very rapidly become an impediment to
> usability, and I am very concerned that this might happen in BitC.
>
> So the question is not whether this check is good and useful. The
> question is whether it is so *overridingly* useful that it should be
> done by the compiler and imposed on every programmer.

I would say that such checks must be performed as a separate pass.
A framework for effect checking can make use of the types produced by
the compiler and run several passes to check different properties.
If the analysis can be on the whole program, the source code need not be
changed. Even if separate compilation is required, the individual
analyses might require some form of declare annotations or comments with
special meaning to achieve it. In either case, I don't think that an
everyday programmer should be concerned about alloc/noalloc for every
program he writes.

> Effects *are* (unfortunately) necessary in order to write correctly
> initializable programs. If that were not true, I would not have included
> them in the type system.

Effect types are necessary to write correct initializers that involve
expansive expressions: that is, expressions other than literals,
functions, and application of constructors and certain primitive
functions.

You have talked about this before, but I don't understood the need for
complex initializers correctly. Here, I mean requirement, rather than
convenience. For example, effect typing was used to achieve sound typing
of ML in the presence of state. But, Wright showed that a much simpler
`value restriction' is sufficient to address almost all of useful cases.

I ask this because, if complex initializers are a matter of convenience, 
they might lead to a bigger inconvenience with respect to tracking the 
effect types.

For example, in the definition:

define (f fn1 fn2 x)
     (f1 x)
     (fn2 x)
     #t))

the type of f is:

f: (forall (('a 'b 'c '%e '%e1 '%e2 ((<= '%e1 '%e) (<= '%e2 '%e)))
      ('%e (fn (('%e1 (fn ('a) 'b))
                ('%e2 (fn ('a) 'c))
                'a) bool)))

The unsolved effect constraints can add up for larger functions. I think
that this is the source of complexity in languages that support region
typing, for example.

We have also talked about effect variables propagating into type 
classes, etc. While it is possible to reduce the number of effect 
parameters on a type class by making all methods share the effect 
variable, we are sacrificing completeness here.

If the analysis is whole program, or if we are conservative about
functions defined in other modules, the effect typing can still be
abstract to the programmer. However, if we require complex initializers,
we would like to call library procedures defined in other modules.

Ocaml allows arbitrary initializer expressions at top-level. However, it
does not have effect typing. I think Ocaml achieves sound initialization
by imposing an ordering on the top-level definitions based on the order
in which modules are presented to the compiler.

I am actually not proposing that effect typing is a bad thing. I think
that it is extremely good for static analysis/verification. But, it
seems better separate from the compiler. Users can think about effects
for analysing the program, not for its construction. If we can adopt a
simpler solution for initialization, I think it will be easier for
programmers, particularly coming from C-world.

Swaroop.
_______________________________________________
bitc-dev mailing list
bitc-dev@coyotos.org
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to