[LLVMdev] improving the ocaml binding's type safety

Gordon Henriksen gordonhenriksen at mac.com
Sat Mar 15 15:56:27 PDT 2008


On Mar 15, 2008, at 17:49, Erick Tryzelaar wrote:

> The other way is top down. This lets us extend our types, but  
> sacrifices some type safety, as we're saying that the arguments are  
> a superset of the variants. We can control this by limiting who can  
> create 't's:
>
> type 'a t
>
> type llvalue = [ `Value ]
> type llconstant = [ llvalue | `Constant ]
> type llglobalvalue = [ llvalue | `GlobalValue ]
> type llglobalvariable = [ llglobalvalue | `GlobalVariable ]
> type llfunction = [ llglobalvalue | `Function ]
>
> val value_name : [> `Value] t -> string
> val is_null : [> `Constant] t -> bool
> val is_declaration : [> `GlobalValue] t -> bool
> val is_global_constant : [> `GlobalVariable] t -> bool
> val is_var_arg : [> `Function] t -> bool


Ah, I get it now. type b = [ a | `B ] is idiomatic type theoretician  
for b t is a subclass of a t. This seems slightly a hack, using sum  
types to do exactly the opposite of what they're designed for. :)

I think you want to use the sum types for parameter typing; [>  
`GlobalValue ] is not compatible with llconstant.

> Bottom up. The advantage of this one is that we'll always be  
> typesafe since we're saying the arguments must be a subset of the  
> specified variants, and thus all the variants are closed. The  
> disadvantage is that if we want to add another type we have to edit  
> all the type definitions. This also means that we can't add another  
> library that subclasses from something and still use these functions:
>
> type 'a t
> type llfunction = [ `Function ]
> type llglobalvariable = [ `GlobalVariable ]
> type llglobalvalue = [ llfunction | llglobalvariable ]
> type llconstant = [ `Constant ]
> type llvalue = [ llconstant | llglobalvalue ]
>
> val value_name : [<  llvalue] t -> string
> val is_null : [<  llconstant] t -> bool
> val is_declaration : [< llglobalvalue] t -> bool
> val is_global_constant : [< llglobalvariable] t -> bool
> val is_var_arg : [< llfunction] t -> bool

I find this intensely more intuitive. The LLVM IR is closed and self- 
contained within the VMCore library (modulo a couple of private User  
subclasses in the bitcode libraries), so that's not a problem.

Clearly, these are syntactically very similar. With my above comment,  
the difference is literally > vs. <. Since the IR is closed, they're  
semantically similar as well. The extensible method is clearly  
preferable for extensible hierarchies, should we have cause to expose  
any methods on them. Passes are an example of this.

What do the respective type errors look like?

— Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080315/08a6f9a5/attachment.html>


More information about the llvm-dev mailing list