* Converting variants with only constant constructors to integers
@ 2010-06-07 18:07 Török Edwin
2010-06-07 18:25 ` [Caml-list] " W Dan Meyer
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Török Edwin @ 2010-06-07 18:07 UTC (permalink / raw)
To: caml-list
Hi,
What is the recommended way to convert a variant that has only constant
constructors to an integer? (an integer that is unique for each constant
constructor, preferably sequential in the order in which they are declared).
I found the following two possibilities, but I am not sure if these are
guaranteed to return the same results for future versions of OCaml or not:
let int_of_constant_variant a : int = Hashtbl.hash a;;
let int_of_constant_variant a : int =
let r = Obj.repr a in
assert (Obj.is_int r);
(Obj.magic r : int);;
for 'type t = A | C | B', both of these functions return 0,1, and 2 for
A,C, and B respectively.
Best regards,
--Edwin
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 18:07 Converting variants with only constant constructors to integers Török Edwin
@ 2010-06-07 18:25 ` W Dan Meyer
2010-06-07 18:45 ` bluestorm
[not found] ` <87sk4y7lc7.fsf@gmail.com>
2010-06-07 18:48 ` David Allsopp
2 siblings, 1 reply; 23+ messages in thread
From: W Dan Meyer @ 2010-06-07 18:25 UTC (permalink / raw)
To: Török Edwin; +Cc: caml-list
Török Edwin <edwintorok@gmail.com> writes:
> What is the recommended way to convert a variant that has only constant
> constructors to an integer? (an integer that is unique for each constant
> constructor, preferably sequential in the order in which they are declared).
In the first play you'd need to tell us, why would you need this, and
then maybe there are other solutions to your problem.
Most likely Marshal module from stdlib, will full-fill your requirements.
I can imagine you could use an association list, function with pattern
matching, code generation tool (based on CamlP4), etc.
The later would be needed if you have varied data structure, that change
frequently or it is too big to maintain it with just pattern matching.
>
> I found the following two possibilities, but I am not sure if these are
> guaranteed to return the same results for future versions of OCaml or not:
>
> let int_of_constant_variant a : int = Hashtbl.hash a;;
> let int_of_constant_variant a : int =
> let r = Obj.repr a in
> assert (Obj.is_int r);
> (Obj.magic r : int);;
There is no guarantee of these kind of unsafe casts at all (means using
Obj.magic). Especially Obj.magic should not be used in marshaling, but
most common patter is for type system tricks.
Wojciech
^ permalink raw reply [flat|nested] 23+ messages in thread
[parent not found: <87sk4y7lc7.fsf@gmail.com>]
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 18:07 Converting variants with only constant constructors to integers Török Edwin
2010-06-07 18:25 ` [Caml-list] " W Dan Meyer
[not found] ` <87sk4y7lc7.fsf@gmail.com>
@ 2010-06-07 18:48 ` David Allsopp
2010-06-07 19:46 ` Török Edwin
2 siblings, 1 reply; 23+ messages in thread
From: David Allsopp @ 2010-06-07 18:48 UTC (permalink / raw)
To: 'Török Edwin', caml-list
Török Edwin wrote:
> What is the recommended way to convert a variant that has only constant
> constructors to an integer? (an integer that is unique for each constant
> constructor, preferably sequential in the order in which they are
> declared).
type foo = A | B;;
external int_of_foo : foo -> int = "%identity";;
Which is another way of saying Obj.magic - but %identity is an OCaml
primitive, where Obj.magic is part of a restricted module so there is a
small semantic difference in terms of future support. The internal
representation of variants won't change until at least OCaml 4.0.0 -
there're simply far too many C bindings out there! foo_of_int obviously
can't be done quite so trivially written although having checked that the
int represents a valid constructor you can then use %identity in the same
way.
David
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 18:48 ` David Allsopp
@ 2010-06-07 19:46 ` Török Edwin
2010-06-07 19:56 ` bluestorm
0 siblings, 1 reply; 23+ messages in thread
From: Török Edwin @ 2010-06-07 19:46 UTC (permalink / raw)
To: David Allsopp, bluestorm; +Cc: caml-list
On 06/07/2010 09:48 PM, David Allsopp wrote:
> Török Edwin wrote:
>> What is the recommended way to convert a variant that has only constant
>> constructors to an integer? (an integer that is unique for each constant
>> constructor, preferably sequential in the order in which they are
>> declared).
>
> type foo = A | B;;
> external int_of_foo : foo -> int = "%identity";;
>
> Which is another way of saying Obj.magic - but %identity is an OCaml
> primitive, where Obj.magic is part of a restricted module so there is a
> small semantic difference in terms of future support. The internal
> representation of variants won't change until at least OCaml 4.0.0 -
> there're simply far too many C bindings out there! foo_of_int obviously
> can't be done quite so trivially written although having checked that the
> int represents a valid constructor you can then use %identity in the same
> way.
Thanks, that "%identity" looks exactly what I wanted.
I don't need a foo_of_int right now.
On 06/07/2010 09:45 PM, bluestorm wrote:
> 2010/6/7 W Dan Meyer <wojciech.meyer@googlemail.com
> <mailto:wojciech.meyer@googlemail.com>>
>> I can imagine you could use an association list, function with pattern
>> matching, code generation tool (based on CamlP4), etc.
>
> I wrote a type-conv (
> http://www.ocaml.info/home/ocaml_sources.html#type-conv ) generator for
> just that a few years ago :
> http://bluestorm.info/camlp4/ty_enum_to_int.ml.html
>
> Example use :
>
> type test = | A | B | C | D of bool with to_int
>
>
> Generated functions :
>
> let test_to_int = function | A -> 0 | B -> 1 | C -> 2 | D _ -> 3
>
> let test_of_int = function
> | 0 -> A
> | 1 -> B
> | 2 -> C
> | 3 -> failwith "can't convert to a constructor with parameters: D"
> | _ -> invalid_argument "test_of_int"
>
If I'll need a foo_of_int this sounds like a good solution, thanks.
Best regards,
--Edwin
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 19:46 ` Török Edwin
@ 2010-06-07 19:56 ` bluestorm
2010-06-07 22:51 ` W Dan Meyer
2010-06-08 11:28 ` Kaustuv Chaudhuri
0 siblings, 2 replies; 23+ messages in thread
From: bluestorm @ 2010-06-07 19:56 UTC (permalink / raw)
To: Török Edwin; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 389 bytes --]
Beware that "%identity" is an unsafe feature that breaks all safety
guarantees if used badly.
If you were, for example, to change your definition of "foo" (in a way not
always representable as integers, such as adding a constructor with
parameters), int_of_foo would become incorrect. The compiler wouldn't warn
you, and you could get pretty bad failures (segfaults). You're on your own.
[-- Attachment #2: Type: text/html, Size: 436 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 19:56 ` bluestorm
@ 2010-06-07 22:51 ` W Dan Meyer
2010-06-08 7:42 ` David Allsopp
2010-06-08 11:28 ` Kaustuv Chaudhuri
1 sibling, 1 reply; 23+ messages in thread
From: W Dan Meyer @ 2010-06-07 22:51 UTC (permalink / raw)
To: bluestorm; +Cc: Török Edwin, caml-list
bluestorm <bluestorm.dylc@gmail.com> writes:
> Beware that "%identity" is an unsafe feature that breaks all safety guarantees
> if used badly.
Yes %identity is another solution. Although as safe as Obj.magic.
Sorry about posting code in the previous post.
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 22:51 ` W Dan Meyer
@ 2010-06-08 7:42 ` David Allsopp
2010-06-08 7:59 ` bluestorm
0 siblings, 1 reply; 23+ messages in thread
From: David Allsopp @ 2010-06-08 7:42 UTC (permalink / raw)
To: 'W Dan Meyer', 'bluestorm'; +Cc: caml-list
W Dan Meyer wrote:
> bluestorm <bluestorm.dylc@gmail.com> writes:
>
> > Beware that "%identity" is an unsafe feature that breaks all safety
> > guarantees if used badly.
>
> Yes %identity is another solution. Although as safe as Obj.magic.
It's a bit pedantic but the %identity *primitive* is not the evil thing -
what is evil about Obj.magic is that it has an illegal type, namely 'a ->
'b. %identity constrained to a type like foo -> int is a safe use of it
(obviously with the side-condition that foo only has constant constructors,
as noted - but that's a local check, i.e. in your code, not your callers').
Incidentally, the general function for getting a unique integer for a
variant type with non-constant constructors isn't that bad either:
let int_of_gen x =
let x = Obj.repr x
in
if Obj.is_block x
then -1 * Obj.tag x - 1
else (Obj.magic x : int)
Naturally, any specific use should constrain the type of this function
beyond 'a -> int
David
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 7:42 ` David Allsopp
@ 2010-06-08 7:59 ` bluestorm
2010-06-08 9:14 ` David Allsopp
0 siblings, 1 reply; 23+ messages in thread
From: bluestorm @ 2010-06-08 7:59 UTC (permalink / raw)
To: David Allsopp; +Cc: W Dan Meyer, caml-list
[-- Attachment #1: Type: text/plain, Size: 934 bytes --]
>
> Incidentally, the general function for getting a unique integer for a
> variant type with non-constant constructors isn't that bad either:
>
> let int_of_gen x =
> let x = Obj.repr x
> in
> if Obj.is_block x
> then -1 * Obj.tag x - 1
> else (Obj.magic x : int)
>
I consider that version much better. You could also write it in a more
restrictive way :
let to_int x =
let repr = Obj.repr x in
if Obj.is_int repr
then (Obj.obj repr : int)
else invalid_arg "to_int";;
The good point about those is that they check that the memory representation
is compatible before casting (while the "%identity" does not). They're
safer. Of course, they still break parametricity if used polymorphically, so
as you said type should be constrained.
I still would prefer the more direct pattern-matching definition : it may
require code generation not to be tedious, but the generated code is an
honourable OCaml citizen.
[-- Attachment #2: Type: text/html, Size: 1282 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 7:59 ` bluestorm
@ 2010-06-08 9:14 ` David Allsopp
2010-06-08 9:36 ` Luc Maranget
0 siblings, 1 reply; 23+ messages in thread
From: David Allsopp @ 2010-06-08 9:14 UTC (permalink / raw)
To: 'bluestorm'; +Cc: 'W Dan Meyer', caml-list
Gabriel Scherer wrote:
> Incidentally, the general function for getting a unique integer for a
> variant type with non-constant constructors isn't that bad either:
>
> let int_of_gen x =
> let x = Obj.repr x
> in
> if Obj.is_block x
> then -1 * Obj.tag x - 1
> else (Obj.magic x : int)
>
> I consider that version much better. You could also write it in a more
restrictive way :
>
> let to_int x =
> let repr = Obj.repr x in
> if Obj.is_int repr
> then (Obj.obj repr : int)
> else invalid_arg "to_int";;
(that doesn't quite do the same thing but I don't think that was your point)
My "problem" is that for each specific case where it's only constant
constructors, I can't help but feel guilty that code will execute for the
conversion of a value to the same value (%identity is a no-op most of the
time). It's not that everything has to be pointlessly micro-optimised, but
you know what I mean?
> The good point about those is that they check that the memory
representation is compatible
> before casting (while the "%identity" does not). They're safer. Of course,
they still break
> parametricity if used polymorphically, so as you said type should be
constrained.
> I still would prefer the more direct pattern-matching definition : it may
require code
> generation not to be tedious, but the generated code is an honourable
OCaml citizen.
Of course, if you have the following:
type t = A | B | C
let int_of_t = function
A -> 0
| B -> 1
| C -> 2
Then in fact I believe that the compiler already converts that to a
hashtable lookup instead of a sequence of jumps so it would be fairly
reasonable (and easy) to have the compiler spot that the match is exactly a
conversion to the tag value and so remove the match completely (and given
that the compiler already has two different strategies for match clauses,
it's not even that inconsistent). camlp4 of course solves the generation
problem (but there's no need to tell you that!!)
David
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 9:14 ` David Allsopp
@ 2010-06-08 9:36 ` Luc Maranget
2010-06-08 9:45 ` David Allsopp
0 siblings, 1 reply; 23+ messages in thread
From: Luc Maranget @ 2010-06-08 9:36 UTC (permalink / raw)
To: David Allsopp; +Cc: 'bluestorm', caml-list, 'W Dan Meyer'
> Of course, if you have the following:
>
> type t = A | B | C
> let int_of_t = function
> A -> 0
> | B -> 1
> | C -> 2
>
> Then in fact I believe that the compiler already converts that to a
> hashtable lookup instead of a sequence of jumps..
The compiler does not convert the above code to 'hashtable lookup'.
--Luc
PS>
To have a look at produced code.
* put your (Caml) code in some file say a.ml;
* compile as ocamlopt -S a.ml
* look at a.s
You can also use various options, such as -dlambda or -dcmm, to
see intermediate stages of the compilation process.
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 9:36 ` Luc Maranget
@ 2010-06-08 9:45 ` David Allsopp
2010-06-08 9:51 ` Luc Maranget
2010-06-08 10:21 ` Dario Teixeira
0 siblings, 2 replies; 23+ messages in thread
From: David Allsopp @ 2010-06-08 9:45 UTC (permalink / raw)
To: luc.maranget; +Cc: 'bluestorm', caml-list, 'W Dan Meyer'
Luc Maranget wrote:
> Of course, if you have the following:
> >
> > type t = A | B | C
> > let int_of_t = function
> > A -> 0
> > | B -> 1
> > | C -> 2
> >
> > Then in fact I believe that the compiler already converts that to a
> > hashtable lookup instead of a sequence of jumps..
>
> The compiler does not convert the above code to 'hashtable lookup'.
Is there a point where the compiler does do a table lookup for matches
rather than jumps or have I clearly just dreamt that? :o)
David
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 9:45 ` David Allsopp
@ 2010-06-08 9:51 ` Luc Maranget
2010-06-08 10:21 ` David Allsopp
2010-06-08 10:21 ` Dario Teixeira
1 sibling, 1 reply; 23+ messages in thread
From: Luc Maranget @ 2010-06-08 9:51 UTC (permalink / raw)
To: David Allsopp; +Cc: caml-list
> Luc Maranget wrote:
> > Of course, if you have the following:
> > >
> > > type t = A | B | C
> > > let int_of_t = function
> > > A -> 0
> > > | B -> 1
> > > | C -> 2
> > >
> > > Then in fact I believe that the compiler already converts that to a
> > > hashtable lookup instead of a sequence of jumps..
> >
> > The compiler does not convert the above code to 'hashtable lookup'.
>
> Is there a point where the compiler does do a table lookup for matches
> rather than jumps or have I clearly just dreamt that? :o)
>
>
> David
As far as I know the compiler always output jumps for matches.
Those jumps can be conditional jumps, or indirect jumps.
For instance in the case of your code, ther will be two condional jumps
(ocamlopt)
With a bigger example, say
| A -> 0
...
| Z -> 25
It is likely that you get a table of addresses indexed by constructor
numbers.
--
Luc
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 9:51 ` Luc Maranget
@ 2010-06-08 10:21 ` David Allsopp
0 siblings, 0 replies; 23+ messages in thread
From: David Allsopp @ 2010-06-08 10:21 UTC (permalink / raw)
To: luc.maranget; +Cc: caml-list
Luc Maranget wrote:
> > Luc Maranget wrote:
> > > Of course, if you have the following:
> > > >
> > > > type t = A | B | C
> > > > let int_of_t = function
> > > > A -> 0
> > > > | B -> 1
> > > > | C -> 2
> > > >
> > > > Then in fact I believe that the compiler already converts that to
> > > > a hashtable lookup instead of a sequence of jumps..
> > >
> > > The compiler does not convert the above code to 'hashtable lookup'.
> >
> > Is there a point where the compiler does do a table lookup for matches
> > rather than jumps or have I clearly just dreamt that? :o)
> >
> >
> > David
>
> As far as I know the compiler always output jumps for matches.
>
> Those jumps can be conditional jumps, or indirect jumps.
> For instance in the case of your code, ther will be two condional jumps
> (ocamlopt)
>
> With a bigger example, say
> | A -> 0
> ...
>
> | Z -> 25
>
> It is likely that you get a table of addresses indexed by constructor
> numbers.
I think that's probably what I was getting muddled with - I didn't realise
that the compiler doesn't do that all the time for constant constructors,
though.
David
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 9:45 ` David Allsopp
2010-06-08 9:51 ` Luc Maranget
@ 2010-06-08 10:21 ` Dario Teixeira
1 sibling, 0 replies; 23+ messages in thread
From: Dario Teixeira @ 2010-06-08 10:21 UTC (permalink / raw)
To: luc.maranget, David Allsopp; +Cc: 'W Dan Meyer', caml-list
Hi,
> > The compiler does not convert the above code to 'hashtable lookup'.
>
> Is there a point where the compiler does do a table lookup
> for matches rather than jumps or have I clearly just dreamt that? :o)
I think Luc's objection was to the use of the word "hash" in "hashtable".
Using the word "hashtable" for an indexed lookup table is technically
correct if you consider the trivial hash function (the identity function);
this may be what David meant. Nevertheless, in most people's minds an
hashtable conjures images of a non-trivial mapping, which I'm quite sure
is not what the compiler generates...
Cheers,
Dario Teixeira
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-07 19:56 ` bluestorm
2010-06-07 22:51 ` W Dan Meyer
@ 2010-06-08 11:28 ` Kaustuv Chaudhuri
2010-06-08 11:40 ` bluestorm
1 sibling, 1 reply; 23+ messages in thread
From: Kaustuv Chaudhuri @ 2010-06-08 11:28 UTC (permalink / raw)
To: caml-list caml-list; +Cc: bluestorm
2010/6/7 bluestorm <bluestorm.dylc@gmail.com>:
> If you were, for example, to change your definition of "foo" (in a way not
> always representable as integers, such as adding a constructor with
> parameters), int_of_foo would become incorrect. The compiler wouldn't warn
> you, and you could get pretty bad failures (segfaults). You're on your own.
%identity will never cause a seg fault.
% ocaml
Objective Caml version 3.12.0+dev25 (2010-05-20)
# external intify : 'a -> int = "%identity" ;;
external intify : 'a -> int = "%identity"
# intify "hello, world" ;;
- : int = 70165942419644
# intify [10; 20] ;;
- : int = 70165942402044
# intify 4.2 ;;
- : int = 70165942392140
# intify 322L ;;
- : int = 70165942379652
# intify 322L ;;
- : int = 70165942369800
Obviosly if you write code that depends on such values, then your code
is most likely broken:
# let x = [10; 20] ;;
val x : int list = [10; 20]
# intify x ;;
- : int = 70165942003824
# Gc.compact () ;;
- : unit = ()
# intify x ;;
- : int = 70165941843960
-- Kaustuv
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 11:28 ` Kaustuv Chaudhuri
@ 2010-06-08 11:40 ` bluestorm
2010-06-08 14:37 ` Jacques Garrigue
0 siblings, 1 reply; 23+ messages in thread
From: bluestorm @ 2010-06-08 11:40 UTC (permalink / raw)
To: Kaustuv Chaudhuri; +Cc: caml-list caml-list
[-- Attachment #1: Type: text/plain, Size: 739 bytes --]
You're right : that's true in the "int" case and I hadn't considered it.
But if you use the same trick for ('a -> float) or other types you can get a
segfault :
# external floatify : 'a -> float = "%identity";;
external floatify : 'a -> float = "%identity"
# floatify 0;;
Segmentation fault
Also there are other problems with "intify" that may be worse than segfaults
: your application running with nonsense data and failing at an arbitrary
later point. Though ocaml doesn't fail (in the current implementation, it
would be unwise to assume that the GC/runtime will never check this), you
get strange behavior with those integers-wich-are-not-integers :
# let x = intify (1,2);;
val x : int = 70246988845964
# x * 1 - x;;
- : int = 1
[-- Attachment #2: Type: text/html, Size: 1018 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 11:40 ` bluestorm
@ 2010-06-08 14:37 ` Jacques Garrigue
2010-06-08 18:22 ` Kaustuv Chaudhuri
0 siblings, 1 reply; 23+ messages in thread
From: Jacques Garrigue @ 2010-06-08 14:37 UTC (permalink / raw)
To: bluestorm; +Cc: Kaustuv Chaudhuri, caml-list caml-list
Of course intify can cause a segmentation fault!
# let arr = Array.of_list [intify 1.0; 0];;
Segmentation fault
You can even have one with Obj.repr.
# let arr = Array.of_list [Obj.repr 1.0; Obj.repr 1];;
Segmentation fault
Only use these things once you understand the details of internal
representations...
Jacques Garrigue
On Tue, Jun 8, 2010 at 8:40 PM, bluestorm <bluestorm.dylc@gmail.com> wrote:
> You're right : that's true in the "int" case and I hadn't considered it.
> But if you use the same trick for ('a -> float) or other types you can get a
> segfault :
> # external floatify : 'a -> float = "%identity";;
> external floatify : 'a -> float = "%identity"
> # floatify 0;;
> Segmentation fault
> Also there are other problems with "intify" that may be worse than segfaults
> : your application running with nonsense data and failing at an arbitrary
> later point. Though ocaml doesn't fail (in the current implementation, it
> would be unwise to assume that the GC/runtime will never check this), you
> get strange behavior with those integers-wich-are-not-integers :
> # let x = intify (1,2);;
> val x : int = 70246988845964
> # x * 1 - x;;
> - : int = 1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 14:37 ` Jacques Garrigue
@ 2010-06-08 18:22 ` Kaustuv Chaudhuri
2010-06-09 1:34 ` Jacques Garrigue
2010-08-23 14:36 ` Damien Doligez
0 siblings, 2 replies; 23+ messages in thread
From: Kaustuv Chaudhuri @ 2010-06-08 18:22 UTC (permalink / raw)
To: Jacques Garrigue; +Cc: bluestorm, caml-list caml-list
On Tue, Jun 8, 2010 at 4:37 PM, Jacques Garrigue
<garrigue@math.nagoya-u.ac.jp> wrote:
> Of course intify can cause a segmentation fault!
>
> # let arr = Array.of_list [intify 1.0; 0];;
> Segmentation fault
This may be splitting hairs, but the reason that fails is that
Array.of_list's ad hoc polymorphism heuristic assumes that if the
first element of the list is allocated, then all elements are
allocated. Merely changing the order works.
# Array.of_list [Obj.repr 0 ; Obj.repr 1.0] ;;
- : Obj.t array = [|<abstr>; <abstr>|]
Which one of Obj.repr of Array.of_list to blame, if that's the right
word, is not that relevant to any code a sane person might write.
-- Kaustuv
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 18:22 ` Kaustuv Chaudhuri
@ 2010-06-09 1:34 ` Jacques Garrigue
2010-08-23 14:36 ` Damien Doligez
1 sibling, 0 replies; 23+ messages in thread
From: Jacques Garrigue @ 2010-06-09 1:34 UTC (permalink / raw)
To: kaustuv.chaudhuri; +Cc: caml-list
From: Kaustuv Chaudhuri <kaustuv.chaudhuri@inria.fr>
> On Tue, Jun 8, 2010 at 4:37 PM, Jacques Garrigue
> <garrigue@math.nagoya-u.ac.jp> wrote:
>> Of course intify can cause a segmentation fault!
>>
>> # let arr = Array.of_list [intify 1.0; 0];;
>> Segmentation fault
>
> This may be splitting hairs, but the reason that fails is that
> Array.of_list's ad hoc polymorphism heuristic assumes that if the
> first element of the list is allocated, then all elements are
> allocated. Merely changing the order works.
>
> # Array.of_list [Obj.repr 0 ; Obj.repr 1.0] ;;
> - : Obj.t array = [|<abstr>; <abstr>|]
>
> Which one of Obj.repr of Array.of_list to blame, if that's the right
> word, is not that relevant to any code a sane person might write.
No, this is not an heuristic, but a compilation method based on the
assumption that values of the same type have the same representation.
This is enforced by the compiler, but by using the Obj module, which
is out of the safe realm, you can break this invariant.
So, from the point of view of the ocaml specification, Obj.repr is
clearly to blame (and defined as unsafe to start with).
Jacques Garrigue
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Caml-list] Converting variants with only constant constructors to integers
2010-06-08 18:22 ` Kaustuv Chaudhuri
2010-06-09 1:34 ` Jacques Garrigue
@ 2010-08-23 14:36 ` Damien Doligez
1 sibling, 0 replies; 23+ messages in thread
From: Damien Doligez @ 2010-08-23 14:36 UTC (permalink / raw)
To: Kaustuv Chaudhuri; +Cc: caml-list caml-list
Hi Kaustuv,
On 2010-06-08, at 20:22, Kaustuv Chaudhuri wrote:
>> Of course intify can cause a segmentation fault!
>>
>> # let arr = Array.of_list [intify 1.0; 0];;
>> Segmentation fault
>
> This may be splitting hairs, but the reason that fails is that
> Array.of_list's ad hoc polymorphism heuristic assumes that if the
> first element of the list is allocated, then all elements are
> allocated. Merely changing the order works.
Then again, good old addition has the same kind of problem with
intify.
$ ocaml
Objective Caml version 3.12.0
# external intify : 'a -> int = "%identity";;
external intify : 'a -> int = "%identity"
# let x = 1 + intify (1, 2);;
val x : int = 2147734445
# Gc.minor ();;
ocamlrun(11589) malloc: *** mmap(size=184834061894270976) failed (error code=12)
*** error: can't allocate region
-- Damien
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2010-08-23 14:36 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-07 18:07 Converting variants with only constant constructors to integers Török Edwin
2010-06-07 18:25 ` [Caml-list] " W Dan Meyer
2010-06-07 18:45 ` bluestorm
[not found] ` <87sk4y7lc7.fsf@gmail.com>
[not found] ` <4C0D3B0F.4060502@gmail.com>
2010-06-07 18:32 ` Török Edwin
2010-06-07 18:50 ` W Dan Meyer
2010-06-07 18:48 ` David Allsopp
2010-06-07 19:46 ` Török Edwin
2010-06-07 19:56 ` bluestorm
2010-06-07 22:51 ` W Dan Meyer
2010-06-08 7:42 ` David Allsopp
2010-06-08 7:59 ` bluestorm
2010-06-08 9:14 ` David Allsopp
2010-06-08 9:36 ` Luc Maranget
2010-06-08 9:45 ` David Allsopp
2010-06-08 9:51 ` Luc Maranget
2010-06-08 10:21 ` David Allsopp
2010-06-08 10:21 ` Dario Teixeira
2010-06-08 11:28 ` Kaustuv Chaudhuri
2010-06-08 11:40 ` bluestorm
2010-06-08 14:37 ` Jacques Garrigue
2010-06-08 18:22 ` Kaustuv Chaudhuri
2010-06-09 1:34 ` Jacques Garrigue
2010-08-23 14:36 ` Damien Doligez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox