* [Caml-list] Managing a polymorphic environment
@ 2004-08-12 14:46 Diego Olivier Fernandez Pons
2004-08-12 15:06 ` Jean-Baptiste Rouquier
2004-08-12 17:05 ` brogoff
0 siblings, 2 replies; 7+ messages in thread
From: Diego Olivier Fernandez Pons @ 2004-08-12 14:46 UTC (permalink / raw)
To: caml-list
Bonjour,
Here is an other type related problem :
I would like to have an environment that associates strings to values
let x = ...
Env.add x "the number of elements in the knapsack"
let c = ...
Env.add c "the total cost of the knapsack"
The idea is of course to be able to pretty-print the result
# Env.print_int x;;
the number of elements in the knapsack is 10 - : unit = ()
# Env.print_float c
the total cost of the knapsack is 100.0 - : unit = ()
Env data structure can be based on equallity only since the user is
supposed to add comments only for the most important variables. The
simplest idea is once more hashing all variables. But one would like
to avoid collisions.
Any suggestion ?
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
2004-08-12 14:46 [Caml-list] Managing a polymorphic environment Diego Olivier Fernandez Pons
@ 2004-08-12 15:06 ` Jean-Baptiste Rouquier
2004-08-12 15:19 ` Diego Olivier Fernandez Pons
2004-08-12 17:05 ` brogoff
1 sibling, 1 reply; 7+ messages in thread
From: Jean-Baptiste Rouquier @ 2004-08-12 15:06 UTC (permalink / raw)
To: caml-list
Quoting Diego Olivier Fernandez Pons <Diego.FERNANDEZ_PONS@etu.upmc.fr>:
> let x = ...
> Env.add x "the number of elements in the knapsack"
> let c = ...
> Env.add c "the total cost of the knapsack"
>
>
> The idea is of course to be able to pretty-print the result
>
> # Env.print_int x;;
> the number of elements in the knapsack is 10 - : unit = ()
> # Env.print_float c
> the total cost of the knapsack is 100.0 - : unit = ()
I'm finishing a lib to handle configuration files, which meets the same kind of
problem : one would like pretty print (and read back) the values, but handle
them in type safe way inside the programme.
I'm using objects and I think it can solve your problem : have a class Env.foo
that has a virtual method print (and any other method to implement the functions
you want in Env), and have classes foo_int and foo_float that inherit from it.
Then your code will be written
let x = new foo_int 10 "the number of elements in the knapsack"
Env.add x (*x is coerced to foo, we forget it's an int*)
let c = new foo_float "the total cost of the knapsack"
Env.add c
x#print
c#print
I can send you my code if you want more details.
Jean-Baptiste.
http://perso.ens-lyon.fr/jean-baptiste.rouquier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
2004-08-12 15:06 ` Jean-Baptiste Rouquier
@ 2004-08-12 15:19 ` Diego Olivier Fernandez Pons
0 siblings, 0 replies; 7+ messages in thread
From: Diego Olivier Fernandez Pons @ 2004-08-12 15:19 UTC (permalink / raw)
To: caml-list
Bonjour,
You are breaking type transparency (or have I misunderstood ?).
Otherwise you can always encapsulate your types (in a module) and
generate a unique integer (with a reference incremented every time you
call the generating function)
> let x = new foo_int 10 "the number of elements in the knapsack"
> Env.add x (*x is coerced to foo, we forget it's an int*)
> let c = new foo_float "the total cost of the knapsack"
> Env.add c
>
> x#print
> c#print
let say Env is a set with hashed keys
Env.add : 'a -> unit
type color = Blue | White | Red
let print_color = function x ->
let message = Env.get_string (Hashtbl.hash x) in
match x with
| Blue -> print_string message ^ "blue"
| etc.
# print_color;;
- color -> unit = <fun>
let x = Blue
Env.add x
print_color x
-- Here the problem is 'let' --
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
2004-08-12 14:46 [Caml-list] Managing a polymorphic environment Diego Olivier Fernandez Pons
2004-08-12 15:06 ` Jean-Baptiste Rouquier
@ 2004-08-12 17:05 ` brogoff
2004-08-13 8:06 ` Diego Olivier Fernandez Pons
1 sibling, 1 reply; 7+ messages in thread
From: brogoff @ 2004-08-12 17:05 UTC (permalink / raw)
To: Diego Olivier Fernandez Pons; +Cc: caml-list
Howdy,
I'm sure I'm completely misunderstanding your problem, but how about
referring to the environment variables by by strings and attaching properties to
them, using the property list trick that Xavier described here a few years
ago
http://caml.inria.fr/archives/200105/msg00175.html
Then we get something like this
# let x = intern "x";;
val x : atom = {name = "x"; properties = []}
# let c = intern "c";;
val c : atom = {name = "c"; properties = []}
# let int_property = (new_property() : int property);;
val int_property : int property = {contents = None}
# let string_property = (new_property() : string property);;
val string_property : string property = {contents = None}
# let float_property = (new_property() : float property);;
val float_property : float property = {contents = None}
# put_property x int_property 10;;
- : unit = ()
# put_property x string_property "the number of elements in the knapsack";;
- : unit = ()
# put_property c float_property 100.0;;
- : unit = ()
# put_property c string_property "the total cost of the knapsack";;
- : unit = ()
# let print_int a = Printf.printf "%s is %d\n" (get_property a string_property)
(get_property a int_property);;
val print_int : atom -> unit = <fun>
# print_int x;;
the number of elements in the knapsack is 10
- : unit = ()
# print_int c;;
Exception: Not_found.
# let print_float a = Printf.printf "%s is %g\n" (get_property a
string_property) (get_property a float_property);;
val print_float : atom -> unit = <fun>
# print_float c;;
the total cost of the knapsack is 100
- : unit = ()
# print_float x;;
Exception: Not_found.
I think you can modify the basic approach to be slightly more suitable to your
task, but that comes pretty close.
-- Brian
On Thu, 12 Aug 2004, Diego Olivier Fernandez Pons wrote:
> Bonjour,
>
> Here is an other type related problem :
>
> I would like to have an environment that associates strings to values
>
> let x = ...
> Env.add x "the number of elements in the knapsack"
> let c = ...
> Env.add c "the total cost of the knapsack"
>
>
> The idea is of course to be able to pretty-print the result
>
> # Env.print_int x;;
> the number of elements in the knapsack is 10 - : unit = ()
> # Env.print_float c
> the total cost of the knapsack is 100.0 - : unit = ()
>
>
> Env data structure can be based on equallity only since the user is
> supposed to add comments only for the most important variables. The
> simplest idea is once more hashing all variables. But one would like
> to avoid collisions.
>
>
> Any suggestion ?
>
> Diego Olivier
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
2004-08-12 17:05 ` brogoff
@ 2004-08-13 8:06 ` Diego Olivier Fernandez Pons
2004-08-13 10:12 ` Diego Olivier Fernandez Pons
0 siblings, 1 reply; 7+ messages in thread
From: Diego Olivier Fernandez Pons @ 2004-08-13 8:06 UTC (permalink / raw)
To: brogoff; +Cc: caml-list
Bonjour,
> I'm sure I'm completely misunderstanding your problem, but how about
> referring to the environment variables by by strings and attaching
> properties to them, using the property list trick that Xavier
> described here a few years ago
What I had in mind is basing the environment in the polymorphic
physical equality (==) - and therefor I said the environment was
expected to be small and hence could use an equality based set
representation
module Env = struct
type 'a t = ('a * string) list
let empty : 'a t = []
let add : 'a -> string -> 'a t -> 'a t = fun x s l -> (x, s) :: l
let rec get_string : 'a -> 'a t -> string = fun x l ->
match l with
| [] -> ""
| (y, s) :: tail -> if x == y then s else get_string x tail
end
# let env = Env.empty;;
val env : 'a Env.t = []
# let x = 5;;
val x : int = 5
# let y = 3;;
val y : int = 3
# let env = Env.add x "x" env;;
val env : int Env.t = [(5, "x")]
# let env = Env.add y "y" env;;
val env : int Env.t = [(3, "y"); (5, "x")]
# Env.get_string x env;;
- : string = "x"
# Env.get_string y env;;
- : string = "y"
The problem is to make Env forget it is typed because the
polymorphic parameter 'a captures the first instanciated type
(int in my example) even if (==) is polymorphic.
I solve it below with some magic.
My code seems - at least to me - correctly typed. Why isn't 'a Env.t
'totally' polymorphic or is it polymorphic in a 'more general' sense ?
It does not seem able to raise a runtime error, does it ?
module Env = struct
type t
let empty : t = Obj.magic []
let add : 'a -> string -> t -> t = fun x s l ->
let l' : ('a * string) list = Obj.magic l in
let l'' = (x, s) :: l' in
let l''' : t = Obj.magic l'' in
l'''
let rec get_string : 'a -> t -> string = fun x l ->
let l' : ('a * string) list = Obj.magic l in
match l' with
| [] -> ""
| (y, s) :: _ when x == y -> s
| _ :: tail ->
let tail' : t = Obj.magic tail in
get_string x tail'
end
module Env :
sig
type t
val empty : t
val add : 'a -> string -> t -> t
val get_string : 'a -> t -> string
end
Example :
# let env = Env.empty;;
val env : Env.t = <abstr>
# let x = 5;;
val x : int = 5
# let y = 3.0;;
val y : float = 3.
# let env = Env.add x "an int" env;;
val env : Env.t = <abstr>
# let env = Env.add y "a float" env;;
val env : Env.t = <abstr>
# Env.get_string x env;;
- : string = "an int"
# Env.get_string y env;;
- : string = "a float"
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
2004-08-13 8:06 ` Diego Olivier Fernandez Pons
@ 2004-08-13 10:12 ` Diego Olivier Fernandez Pons
0 siblings, 0 replies; 7+ messages in thread
From: Diego Olivier Fernandez Pons @ 2004-08-13 10:12 UTC (permalink / raw)
To: caml-list; +Cc: brogoff
Bonjour,
Diego Olivier Fernandez Pons wrote :
> The problem is to make Env forget it is typed because the
> polymorphic parameter 'a captures the first instanciated type (int
> in my example) even if (==) is polymorphic.
The first problem is that it doesn't work. (==) reduces to (=) for
simple types
let x = 5
let y = 5
let env = Env.add x "x" env
let env = Env.add y "y" env
# Env.get_string x env ;;
- : string = "y"
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Managing a polymorphic environment
@ 2004-08-13 14:20 Jean-Baptiste Rouquier
0 siblings, 0 replies; 7+ messages in thread
From: Jean-Baptiste Rouquier @ 2004-08-13 14:20 UTC (permalink / raw)
To: caml-list
>The first problem is that it doesn't work. (==) reduces to (=) for
>simple types
>
>let x = 5
>let y = 5
>let env = Env.add x "x" env
>let env = Env.add y "y" env
>
># Env.get_string x env ;;
>- : string = "y"
Because it's the same internal representation : "5" is stored in one word,
exactly the same word for all the values storing "5". int isn't boxed, there are
no pointers involved here. So (==) and (=) have no choice but being the same
operation on int.
You have to box your type if you want to distinguish between x and y. And once
they are boxed, why not adding the description in this type ? There are several
choices: trivial tuple type, property lists, objects...
Then, since you look for efficiency and thus want to work on int or float, you
need conversion functions between this boxed type (which makes (==) work as you
want) and int / float (more efficient). You need two distinct types.
For instance here you will also need a fonction 'a result -> 'a, and
complex_computation will have type int -> int -> int.
>># type 'a result = 'a * string;;
>># let new_result (a:'a) description = ((a,description) : 'a result);;
>>val new_result : 'a -> string -> 'a result = <fun>
>># let print_int ((a,d): int result) = Printf.printf "%s is %d\n%!" d a;;
>>val print_int : int result -> unit = <fun>
>># let print_float = ...
>># let x = new_result 10 "the number of elements in the knapsack";;
>>val x : int result = ...
>># print_int x;;
>>the number of elements in the knapsack is 10
>>- : unit = ()
>
>
>Here is the problem of this approach
>
># let complex_computation = fun x y -> x + y
>val complex_computation : int -> int -> int = <fun>
>
>let x = simple_computation () and
> y = simple_computation ()
>
>let z = complex_computation x y
>
>Now I want to add a comment to x to print intermediate results and
>check the first computation is correct. In your approach, this lifts x
>: int on x : int result. But what will then be the type of
>complex_computation ?
Jean-Baptiste.
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-08-13 14:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-12 14:46 [Caml-list] Managing a polymorphic environment Diego Olivier Fernandez Pons
2004-08-12 15:06 ` Jean-Baptiste Rouquier
2004-08-12 15:19 ` Diego Olivier Fernandez Pons
2004-08-12 17:05 ` brogoff
2004-08-13 8:06 ` Diego Olivier Fernandez Pons
2004-08-13 10:12 ` Diego Olivier Fernandez Pons
2004-08-13 14:20 Jean-Baptiste Rouquier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox