| Anonymous | Login | Signup for a new account | 2013-05-22 04:19 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||||
| 0005361 | OCaml | OCaml general | public | 2011-09-26 01:27 | 2012-01-25 23:12 | ||||||
| Reporter | Pascal Cuoq | ||||||||||
| Assigned To | |||||||||||
| Priority | normal | Severity | feature | Reproducibility | always | ||||||
| Status | confirmed | Resolution | open | ||||||||
| Platform | OS | OS Version | |||||||||
| Product Version | 3.12.1 | ||||||||||
| Target Version | Fixed in Version | ||||||||||
| Summary | 0005361: Syntax to specify that a custom type is never a float | ||||||||||
| Description | Consider the following module: let f (a: Z.t array) = a.(7) where Z.t is the custom type of integers as implemented by http://forge.ocamlcore.org/projects/zarith/ [^] You may expect function f to be compiled to: _camlT__f_1030: subl $12, %esp L100: movl -4(%eax), %ebx shrl $9, %ebx cmpl $15, %ebx jbe L101 movl 28(%eax), %eax addl $12, %esp ret L101: call _caml_ml_array_bound_error (this is on IA32 but the target architecture is not relevant to this discussion) Unfortunately, in order to obtain the code above, it is necessary to cheat: $ svn diff z.ml*p Index: z.mlip =================================================================== --- z.mlip (revision 43) +++ z.mlip (working copy) @@ -41,7 +41,8 @@ (** {1 Types} *) -type t +type abst +type t = private A | B of abst (** Type of integers of arbitrary length. *) exception Overflow Index: z.mlp =================================================================== --- z.mlp (revision 43) +++ z.mlp (working copy) @@ -16,7 +16,8 @@ *) -type t +type abst +type t = private A | B of abst exception Overflow Without the above unsafe changes, the code generated for f is: _camlT__f_1030: subl $12, %esp L101: movl %eax, %ecx movl -4(%ecx), %eax movl %eax, %ebx andl $255, %ebx cmpl $254, %ebx je L100 shrl $9, %eax cmpl $15, %eax jbe L102 movl 28(%ecx), %eax addl $12, %esp ret .align 4 L100: shrl $10, %eax cmpl $15, %eax jbe L102 L103: movl _caml_young_ptr, %eax subl $12, %eax movl %eax, _caml_young_ptr cmpl _caml_young_limit, %eax jb L104 leal 4(%eax), %eax movl $2301, -4(%eax) fldl 56(%ecx) fstpl (%eax) addl $12, %esp ret L104: call _caml_call_gc L105: jmp L103 L102: call _caml_ml_array_bound_error The code is polluted by the possibility that a Z.t value might be a float, but the fact that this appears to be possible is only an artifact of Z.t's implementation as abstract type with C functions to operate on. If Z.t was an ML type, then there would be a choice: either export its constructors, making it clear that it is not an alias for float, or not export its constructors, and compile modules M that depend on Z into generic code that will keep working if Z.t is ever changed to be an alias to float. This argument conflates what Z's programmer wants to show to M's programmer with what he wants to show to M's programmer's compiler, but fair is fair. Unfortunately, there is no such alternative for custom types implemented as abstract type + C functions. The only way I see to provide this information is to provide too much information, in the form of fake, unsafe constructors that do not reflect the actual layout of the type. Feature wish: a syntax to specify (only) that a custom type is never a float. Alternately, in native compilation, the compiler could look through programmer-opaque interfaces for the actual implementation of abstract types. There is already no separate compilation to speak of because the compiler already looks for small functions to inline through interfaces that are opaque to the programmer, so there wouldn't be any loss here. Z's programmer would still have to write fake constructors in its module, but he wouldn't have to show them in the module's interface. He would only have to be careful not to pattern-match values of type Z.t in one module. | ||||||||||
| Tags | No tags attached. | ||||||||||
| Attached Files | |||||||||||
Notes |
|
|
(0006131) ertai (developer) 2011-09-26 07:24 |
The alternative solution (making the native compiler, see through abstraction) seems more appealing to me. |
|
(0006173) gerd (reporter) 2011-10-23 14:40 |
Addition to the alternate solution: What about providing a special opaque type "non_float" in Pervasives (or maybe Obj), so module implementors can write: type t = non_float. |
|
(0006450) garrigue (manager) 2011-12-21 14:39 |
Sorry for the slow answer. If I am not confused, you can already tell the compiler that a type is not a float by writing: type t = private unit Of course you may need some magic to have the system believe you. And I do hope there are no bad side-effects. |
|
(0006732) lefessan (developer) 2012-01-19 14:13 |
I think there are two different problems here: 1/ when a type is manifest in the implementation, but becomes abstract in the interface; 2/ when a type is abstract from the beginning; (1) could be solved by keeping some more information in the .cmx, about types, as it is already done for constant propagation and inlining. I think a patch would be welcome, just to get an idea of the complexity of doing that. (2) could be solved using "private", but I am not completely sure ("private unit" might lead the compiler to believe the GC should not scan such values in the stack, which could be dangerous). Adding "non_float" is also dangerous, as the typer could unify different types equal to that one. Maybe an annotation on the type would be better, once such annotations are available. |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2011-09-26 01:27 | Pascal Cuoq | New Issue | |
| 2011-09-26 07:24 | ertai | Note Added: 0006131 | |
| 2011-10-23 14:40 | gerd | Note Added: 0006173 | |
| 2011-12-21 14:39 | garrigue | Note Added: 0006450 | |
| 2012-01-19 14:13 | lefessan | Note Added: 0006732 | |
| 2012-01-19 14:13 | lefessan | Assigned To | => lefessan |
| 2012-01-19 14:13 | lefessan | Status | new => confirmed |
| 2012-01-25 23:12 | lefessan | Assigned To | lefessan => |
| Copyright © 2000 - 2011 MantisBT Group |