New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Syntax to specify that a custom type is never a float #5361
Comments
Comment author: ertai The alternative solution (making the native compiler, see through abstraction) seems more appealing to me. |
Comment author: gerd Addition to the alternate solution: What about providing a special opaque type "non_float" in Pervasives (or maybe Obj), so module implementors can write: |
Comment author: @garrigue Sorry for the slow answer. type t = private unit Of course you may need some magic to have the system believe you. |
Comment author: @lefessan I think there are two different problems here: (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. |
Comment author: @mshinwell Removing the float array hack would presumably solve this problem. |
With |
Original bug ID: 5361
Reporter: Pascal Cuoq
Status: confirmed (set by @lefessan on 2012-01-19T13:13:30Z)
Resolution: open
Priority: normal
Severity: feature
Version: 3.12.1
Category: typing
Related to: #7485
Monitored by: @protz mehdi
Bug 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.
The text was updated successfully, but these errors were encountered: