[Caml-list] Define parser and printer consistently
I'm going to define a parser and a printer for a simple grammar. Is there a way to define both of them in a single construct using some existing OCaml tool? For example, I have a keyword "function". The usual parser would contain a mapping like: "function" -> `Function and the straightforward printer would do: `Function -> "function" What is the best way to combine these definitions, so that duplication would be minimized? To be precise, avoiding duplication is not exactly what I need. I'm looking for something that would prevent making inconsistent changes to the parser and the printer. Dawid ___ 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
[Caml-list] Re: help with regular expression
On 12/06/2010 12:43 PM, zaid khalid wrote: > I want some help in writing regular expressions in Ocaml, as I know how to write it in informal way but in Ocaml syntax I can not. For example I want to write "a* | (aba)* ". > > Another question if I want the string to be matched against the regular expression to be matched as whole string not as substring what symbol I need to attach to the substring, i.e if I want only concrete strings accepted (like (" ", a , aa , aaa, aba, abaaba), but not ab or not abaa). > I also had problems with Str (regexp descriptions being unreadable, error-prone and hard to generate dynamically) and decided just to stop using Str. I have a tiny module [1] made with clarity in mind. It is pure OCaml. It defines operators like $$ to be used in regexp construction. This way syntax of the expressions is checked at compile time. Also, it is trivial to build them at run time. The whole "engine" is contained in a relatively short function HRegex.subwords_of_subexpressions, so I believe anybody can hack it without much effort. I haven't measured performance of this implementation. I expect it to be slow when processing long strings. It's just OK for my needs so far. Anyway, the important part is the module interface. It expresses my point of view on this topic. The code is available in a mercurial repository [2]. The exemple "a* | (aba)* " would become: open HRegex.Operators let rx = (!* !$ "a") +$ (!* !$ "aba") Dawid [1] http://hg.ocamlcore.org/cgi-bin/hgwebdir.cgi/hlibrary/hlibrary/raw-file/tip/HRegex.mli [2] http://hg.ocamlcore.org/cgi-bin/hgwebdir.cgi/hlibrary/hlibrary ___ 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
[Caml-list] Re: Smart ways to implement worker threads
> I find it odd that there is no Threaded_Queue module, a thread save > version of Queue with 2 extra functions: (...) > I use such a thread-safe queue a lot [1]. This is very simple yet universal enough. Honestly I can hardly remember using more elaborate constructs. Dawid [1] http://pfpleia.if.uj.edu.pl/projects/HLibrary/browser/HQueue.ml ___ 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
[Caml-list] Re: Binding and evaluation order in module/type/value languages
> It is not clear that this will work at all. > The semantics of ocaml (contrary to SML) is not defined in terms of > type generativity. > > This is great eureka to me. I thought that when the compiler refuses to unify some types it knows that they are incompatible (as the error message says). But now I think (as I currently understand non-generativity) that sometimes the compiler simply doesn't know if some types are equal and avoids unification of such types. The error message should be instead: "Cannot unify the following types, because I don't have any proof that they are equal (and I don't have looked for the proof really hard)..." So in order to have not unifiable phantom types one has to kind of trick the compiler and hide the fact that they are equal. Dawid ___ 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
[Caml-list] Binding and evaluation order in module/type/value languages
Thinking about the discussion in the recent thread "Phantom types" [1], I have created the following piece of code that aims to demonstrate binding and evaluation order that takes effect in all three levels of OCaml. My question is: what are the precise rules is the case of type language? I have impression that it is lazy and memoized evaluation. But this my guess looks suspicious. I don't intend this question to be about inner working of the compiler, but about the definition at the conceptual level. (* 1. Module language; side effect = create fresh record type; test = type equality test *) module type T = sig type t end module R (T:T) = struct type r = {lab : int} end module TF = struct type t = float end module TS = struct type t = string end module R1 = R(TF) module R2 = R(TF) module R3 = R(TS) let test12 (k : R1.r) (l : R2.r) = (k=l) (* pass => R1.r = R2.r *) let test13 (k : R1.r) (l : R3.r) = (k=l) (* pass => R1.r = R3.r *) (* Conclusion: RHS evaluated at the mapping definition point *) (* 2. Type language; side effect = create fresh record type; test = type equality test *) type 't r = {lab : int} type tf = float type ts = string type r1 = tf r type r2 = tf r type r3 = ts r let test12 (k : r1) (l : r2) = (k=l) (* pass => r1 = r2 *) let test13 (k : r1) (l : r3) = (k=l) (* fail => r1 ≠ r3 *) (* Conclusion: RHS evaluated some time after the mapping is applied; sort of memoization at the conceptual level *) (* 3. Value language; side effect = create fresh int; test = value equality test *) let r t = Oo.id (object end) let tf = 0. let ts = "A" let r1 = r tf let r2 = r tf let r3 = r ts let test12 = assert (r1 = r2) (* fail => r1 ≠ r2 *) let test13 = assert (r1 = r3) (* fail => r1 ≠ r3 *) (* Conclusion: RHS evaluated exactly at the point of mapping application *) Dawid [1] http://groups.google.com/group/fa.caml/browse_thread/thread/0df560ee78e0f75f# ___ 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
[Caml-list] Binding and evaluation order in module/type/value languages
Thinking about the discussion in the recent thread "Phantom types" [1], I have created the following piece of code that aims to demonstrate binding and evaluation order that takes effect in all three levels of OCaml. My question is: what are the precise rules is the case of type language? I have impression that it is lazy and memoized evaluation. But this my guess looks suspicious. I don't intend this question to be about inner working of the compiler, but about the definition at the conceptual level. (* 1. Module language; side effect = create fresh record type; test = type equality test *) module type T = sig type t end module R (T:T) = struct type r = {lab : int} end module TF = struct type t = float end module TS = struct type t = string end module R1 = R(TF) module R2 = R(TF) module R3 = R(TS) let test12 (k : R1.r) (l : R2.r) = (k=l) (* pass => R1.r = R2.r *) let test13 (k : R1.r) (l : R3.r) = (k=l) (* pass => R1.r = R3.r *) (* Conclusion: RHS evaluated at the mapping definition point *) (* 2. Type language; side effect = create fresh record type; test = type equality test *) type 't r = {lab : int} type tf = float type ts = string type r1 = tf r type r2 = tf r type r3 = ts r let test12 (k : r1) (l : r2) = (k=l) (* pass => r1 = r2 *) let test13 (k : r1) (l : r3) = (k=l) (* fail => r1 ≠ r3 *) (* Conclusion: RHS evaluated some time after the mapping is applied; sort of memoization at the conceptual level *) (* 3. Value language; side effect = create fresh int; test = value equality test *) let r t = Oo.id (object end) let tf = 0. let ts = "A" let r1 = r tf let r2 = r tf let r3 = r ts let test12 = assert (r1 = r2) (* fail => r1 ≠ r2 *) let test13 = assert (r1 = r3) (* fail => r1 ≠ r3 *) (* Conclusion: RHS evaluated exactly at the point of mapping application *) Dawid [1] http://groups.google.com/group/fa.caml/browse_thread/thread/0df560ee78e0f75f# ___ 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
[Caml-list] Re: Phantom types
> type 'a t = {l: float} > > Any thoughts ? I think the crucial question is when new record types are born. Here is my opinion: The "=" sign in the above type mapping definition is what I would call "delayed binding". "Early binding" would be equivalent to type tmp = {lab : float} type 'a s = tmp (evaluate the right-hand side first, then define the mapping). The "early binding" creates only one record type, so lab becomes ordinary record label. In the given example of the "delayed binding" the t becomes a machine producing new record types. Hence, the identifier l is not an ordinary record label. It is shared by whole family of record types. We can see it this way: # type 'a t = { la : float } ;; type 'a t = { la : float; } # {la = 0.};; - : 'a t = {la = 0.} So OCaml interpreter doesn't know the exact type of the last expression, but it is clever enough to give it a generalized type. We can use la to construct records of incompatible types: # type 'a t = { la : float } ;; type 'a t = { la : float; } # let yy = ({la = 0.} : int t) ;; val yy : int t = {la = 0.} # let xx = ({la = 0.} : string t);; val xx : string t = {la = 0.} # xx = yy;; Error: This expression has type int t but an expression was expected of type string t I suppose my jargon may be not mainstream, apologies. Dawid ___ 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
[Caml-list] Extending Set - strange behavior of abstract type
I tried to extend the standard Set module with new operations. I got error messages about type incompatibilities (the Set.S.t as exposed by my implementation and Set.S.t used by functions from the original Set). I have reduced my code to the following small example: module Set = struct module Make (Ord : Set.OrderedType) = struct module Set = Set.Make(Ord) include Set end end module OrdChar = struct type t = char let compare = compare end module Raw1 = Set.Make (OrdChar) module Raw2 = Set.Make (struct type t = char let compare = compare end) let aaa (aa : Raw1.t) (bb : Raw1.Set.t) = (aa = bb) let aaa (aa : Raw2.t) (bb : Raw2.Set.t) = (aa = bb) Only the last line results in an error: Error: This expression has type Raw2.Set.t but is here used with type Raw2.t All the rest of the code compiles correctly. It means that types Raw1.t and Raw1.Set.t can be unified. My question is: why these nearly identical statements results in different behavior of the type t? I'd really prefer Raw1 and Raw2 to be identical. I use ocaml 3.11.0. Dawid ___ 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
[Caml-list] Re: Module type of a structure returned by functor
I've found that I have more fundamental problem. What is the exact meaning of the following line? module type Foo = functor (X:X) -> sig val foo : X.t end (1) Foo is not a functor, but it is a type of some functors that map modules to modules (2) Foo is a mapping from modules to module types Currently I think that it (1) is true and (2) is false. Let me know if I'm wrong. It means that there is no easy way to get module type of what results from functor application. I think that the solution is to separately define signature of results of the functor and use "with type" clauses to recreate all result module types that are needed. This is not very bad, but I'm still wondering if "module type of..." of 3.12 will provide elegant solution for this. Dawid ___ 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
[Caml-list] Module type of a structure returned by functor
1. The following piece of code contains illegal constructs. These are functor applications marked with (* ? *). Basically, I need module type of what is produced by functor. My first question is: what is the proper, "canonical" workaround for unavailability of applications marked (* ? *) ? module type Big = sig type t type u end module type Small = sig type t end module type MakeEdge = functor (Big : Big) -> sig val foo : Big.t option end module MakeEdge = functor (Big : Big) -> struct let foo = None end module type Add_boilerplate = functor (Small:Small) -> sig type t end module Add_boilerplate = functor (Small:Small) -> struct type t = Small.t type u = t end module type ConvenientEdge = functor (Small:Small) -> MakeEdge (Add_boilerplate (Small)) (* ? *) module ConvenientEdge = functor (Small:Small) -> MakeEdge (Add_boilerplate (Small)) module SmallX = struct type t = int end module EdgeX = ConvenientEdge (SmallX) module type EdgeX = ConvenientEdge (SmallX) (* ? *) module Algorithm = functor (EdgeX : EdgeX) -> struct let doit = EdgeX.foo end 2. And the related question: why one can't do functor applications in module types as in above lines marked with (* ? *) ? Is there some theoretical reason? 3. Will the "module type of..." feature of 3.12 help with this? I can imagine e.g.: module type EdgeX = (module type of (ConvenientEdge (SmallX))) Dawid ___ 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
Re: [Caml-list] OCaml on AIX
Christoph Bauer pisze: Please try: $ cd asmrun $ cpp -DSYS_aix power-aix.S > power-aix.s $ as -u power-aix.s $ cd .. $ make opt Christoph Bauer Apparently I can go directly without preprocessor (and cpp I have on the AIX machine doesn't like asm syntax): $ cp power-aix.S power-aix.s $ as -u -o power-aix.o power-aix.s $ cd .. $ gmake opt So I get working native code. The remaining problem is that camlp4 crashes on some Unix call when preprocessing. I solved it by preprocessing all the code on another machine. Thank you for your help. Dawid ___ 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
Re: [Caml-list] Bytecode run on AIX - "unknown C primitive" error
unfortunatly I haven't a solution for the bytecode stuff. I only use ocaml with native compiled code. This works very well. Native code would also be sufficient (to save me from translating lot of code to C). The problem is that the assembler available on AIX doesn't unserstand power-aix.S: as -o power-aix.o power-aix.S Assembler: power-aix.S: line 103: 1252-023 The symbol .caml_garbage_collection is not defined. power-aix.S: line 103: 1252-087 The target of the branch instruction must be a relocatable or external expression. power-aix.S: line 457: 1252-023 The symbol caml_young_limit is not defined. power-aix.S: line 457: 1252-040 The specified expression is not valid. Make sure that all symbols are defined. Check the rules on symbols used in an arithmetic expression concerning relocation. .. (many similar messages) How have you obtained running ocamlopt? Dawid ___ 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
[Caml-list] Bytecode run on AIX - "unknown C primitive" error
I have installed part of this OCaml port http://home.arcor.de/chr_bauer/ocaml-aix.html on a computer running on AIX. It seems that everything built correctly except ocamlopt. So I have ocamlrun and standard library and this should be enough for bytecode to run. I have to build the bytecode on a different machine (because it's difficult to do on AIX). I believe this shouldn't induce any problems. Trivial bytecode executes correctly regardless where it is created. I set LIBPATH to point to ocaml/stublibs and try running some bytecode uning Unix module. This results in: Fatal error: unknown C primitive `unix_getsockopt_bool' If I compile simple "let _ = Unix.sleep 1" on the target machine, I get bytecode that causes ocamlrun to crash with: Illegal instruction (core dumped) Does anybody have an idea for workaround? Some understanding what's going on? I'm using AIX 5.3 Dawid ___ 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
[Caml-list] Linking mutually dependent modules for fun
I often get into trouble of cyclic dependencies when writing in OCaml. Perhaps, I'm still not enough mentally shifted from poor languages (for which circular design is quite natural). Of course OCaml has many tools to deal with this: functors (which, once introduced, spread like a disease), type variables and generalization (which sometimes deadly collide with the functorial way) and ugly global ref cells (which smell). Why not try some Pascal style then? ;) The following is what I got when studying OCaml's linking issues: A.mli: val flip : unit -> unit A.ml: let flip () = print_string "1"; B.flop () let _ = flip () B.mli: val flop : unit -> unit B.ml: let flop () = print_string "0"; A.flip () C.ml: let _ = print_endline "C" Compile: ocamlopt -c -S A.ml ocamlopt -c -S B.ml The resulting .o depends on existing cmx files, so we can reach fixpoint by doing it once more: ocamlopt -c -S A.ml The new compiled A happens to work with uinitialized B. Then use some helper module: ocamlopt -c -S C.ml ocamlopt -dstartup -ccopt --verbose C.cmx Modify a.startup.s to call camlA_entry instead of camlC__entry. as -o startup.o a.out.startup.s Verbose gcc invocation gave us proper linking command. Replace ...std_exit.o C.o /./stdlib.a ... with just ...std_exit.o A.o B.o /./stdlib.a ... And go! OK, I must admit that I don't know how to get startup code that would work in general. This one had wrong memory maps and no initialization of B... anyway it works. :) Dawid ___ 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
[Caml-list] Re: Incremental linking
Yes. "ocamlopt -pack" actually calls "ld -r" underneath to consolidate several compilation units in a single .cmx/.o file. "ld -r" will resolve references between these compilation units. I tried with this switch and indeed I can link a toy program by arbitrary intermediate steps. It works OK and is good news to me. Since today I thought that I have no way to generate the startup code quickly, but I came to the following solution: ocamlopt -o prog -dstartup --cc echo A.cmx B.cx C.cmx D.cmx as -o prog.startup.o prog.startup.s This way I have all the technical pieces working. Now I have to think how to automate this. :) Generally speaking, I'm somewhat surprised that linking time is an issue for Dawid. Modern Unix linkers are quite fast, and the additional link-time work that OCaml does is small. Let us know if you manage to narrow the problem. My interest in this comes from combination of few facts: all my calculations are done on a not very fresh machine, my code is a big tree of small modules and I normally work this way: 1. modify some module (usually at leaf position) 2. recompile everything to native code 3. run, look at the results and go to 1. I need therefore fast recompilation and fast linking (to stay focused on the work). I'm about to solve the problem of ocamlbuild spending all its time looking at unmodified modules. Then I wanted to make sure that it will be possible to mitigate the second bottleneck. This is why I'm happy to be able to do incremental linking. It's helpful that the ocamlopt itself is very fast. Dawid ___ 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
[Caml-list] Incremental linking
I have lot of modules and they are compiled to native code. So I have .cmx and .o files and want to link them faster. Is is possible to make linking an associative operation acting on modules? I would like to do something like the following: Knowing the correct partial order of modules (that compiler requires) I can create a tree that preserves that order. Leafs are modules. Other nodes of the tree correspond to a result of linking all descendant modules. Modules that are frequently recompiled are placed closer to the root. This way I expect to execute less linking operations during development. Documentation of ld says that files produced with --relocatable can be used as intermediate partially linked files. Can something like this be done with object code produced by ocamlopt? I don't know ocaml-specific details of linking, so maybe I overlook some obvoius obstacle? Dawid ___ 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
[Caml-list] Incremental linking
I have lot of modules and they are compiled to native code. So I have .cmx and .o files and want to link them faster. Is is possible to make linking an associative operation acting on modules? I would like to do something like the following: Knowing the correct partial order of modules (that compiler requires) I can create a tree that preserves that order. Leafs are modules. Other nodes of the tree correspond to a result of linking all descendant modules. Modules that are frequently recompiled are placed closer to the root. This way I expect to execute less linking operations during development. Documentation of ld says that files produced with --relocatable can be used as intermediate partially linked files. Can something like this be done with object code produced by ocamlopt? I don't know ocaml-specific details of linking, so maybe I overlook some obvoius obstacle? Dawid ___ 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
[Caml-list] Broken dumps from memprof patch?
I have compiled MinGW port of the comopiler (3.10) with memprof patch applied. I can produce heap dumps, but heapstats tool fails to load it. I had to change major_gc.c, the line: #include is replaced by a stub: int getpid() {return 8;} I had to tag all files in hp dir as precious (using hp/_tags file). Surprisingly I get no linking error with boot/stdlib.cma when doing the first step: make -f Makefile.nt world Gc.dump_heap successfully created a file while running bytecode. I had to remove labltk from OTHERLIBRARIES (in config/Makefile), otherwise bootstrap step results in: File "shell.ml", line 78, characters 15-27: Unbound value Mutex.create I got three executables: heapstats.exe, heapstats.opt and hp2ps.exe in root dir of the sources. 'make -f Makefile.nt install installopt' didn't install them. At first, threads.cmxa and friends were not built, because my make (using normal Cygwin) was unable to resolve a symbolic link (thread.ml to thread_posix.ml). I made a copy instead and it compiled. Trying to run heapstats on a fresh dump file (from toplevel loop) results in (the first line is my debug output): globals_map length = 469785344 Fatal error: exception Invalid_argument("String.create") Raised at file "hp/hPLoadHeap.ml", line 88, characters 20-37 The file is 320kB only, it can't contain 470MB of globals_map. Should I assume that bytecode produces broken heap dumps? Loading of a dump produced from native code went further: $ heapstats.opt -heap heap.dump.8.0 globals_map length = 115 info list element length = 1721 info list element length = 193024 Fatal error: exception End_of_file Raised at file "pervasives.ml", line 302, characters 15-26 Called from file "hp/hPLoadHeap.ml", line 118, characters 4-30 Called from file "hp/hPLoadHeap.ml", line 121, characters 14-21 Called from file "hp/hPLoadHeap.ml", line 173, characters 18-43 Called from file "hp/hPMain.ml", line 20, characters 16-38 Called from file "arg.ml", line 146, characters 12-33 Called from file "arg.ml", line 197, characters 8-27 Called from file "arg.ml", line 211, characters 4-32 Called from file "hp/hPMain.ml", line 10, characters 2-1023 Any ideas? Dawid ___ 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
[Caml-list] Re: Memory leak & slowdown
The overall memory usage grows significantly over time, but I don't know why. After it consumes several MB extra, it slows considerably and becomes unusable, so I have to fix this. I'm still unable to figure out what is the allocated memory, but I discovered few things: * there is available (somewhat hidden) version of memprof patch that works with 3.10.0: http://www.pps.jussieu.fr/~smimram/docs/ocaml-3.10.0-memprof.patch * It seems that I can't use gprof with OCaml programs in Windows I can roughly remember I had memory leaks some time ago if I allocated big arrays in expose event handler (with lablgtk2) - still have to verify this. Dawid ___ 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
[Caml-list] Re: Memory leak & slowdown
You might want to instrument the [caml_]register_global_root function and see how often it gets called. Is it possible to enable profiling in the compiler in Windows or Cygwin environment? Cygwin has gprof, but OCaml's configure script says 'no profiling'. Dawid ___ 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
[Caml-list] Memory leak & slowdown
I have an OCaml program using GTK running on Windows, using multiple threads. The overall memory usage grows significantly over time, but I don't know why. After it consumes several MB extra, it slows considerably and becomes unusable, so I have to fix this. Is it possible that this is related to GC compaction being turned off? Additional calls to Gc.compact seemingly don't help. The memory usage grows only when the main processing loop is working. After the function exists, the memory is not freed. Moreover, if I start it again, it 'reuses' the leaked memory. The second execution of the loop takes more memory only after it takes more time than the previous one. This made me thinking that it's just some container growing but not shrinking. So I checked my toplevel values with the objsize library, but I managed to trace down only a fraction of the allocated memory and the sizes I get don't grow. How to do memory profiling? The program can have about 10MB of useful data and 200MB of something I don't know. How to check what is this? Dawid ___ 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
Re: [Caml-list] (Not) corrupt output of printf
Weird ... I was going to suggeest it was because you weren't flushing the output after each print statement. This raises important question: Let's see the output as a sequence of bytes (there's no time). Assuming that the process exits normally and incompatible printing functions are not mixed: is there a guarantee (in OCaml library) that the flush operation doesn't affect the output? For me it's obvious that the output shouldn't depend on the presence of flush operations. If otherwise - needs to be explicitly stated. (Of course I'm not considering the one special flush action done when closing a stream, but it's tied to the closing function.) Dawid ___ 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
Re: [Caml-list] (Not) corrupt output of printf
This was actually a bug in GNOME Terminal... sorry for the noise. Dawid ___ 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
[Caml-list] Corrupt output of printf
I have a program, which output is produced only with Printf.printf . This inner part is executed by another one (outer) using Unix.system . The outer executable uses print_endline before and after the inner is run. From time to time the output of the inner program is corrupt. Printf.printf seemingly devours parts of single lines, as in these examples (all lines should have the same structure): 156 In: 5.483000, 1.50, 1.76 157 Sb: 5.008000, 1.494000, 1.50 158 In: 4.498000, 1.494000, 0.75 159160 Sb: 5.003000, 1.503000, 0.508000 Another one: 138 In: 5.00, 0.00, 0.253000 139 In: 5.001000, 1.000140 Sb: 5.50, 0.00, 0.00 141 Sb: 5.50, 1.00, 0.00 This isn't easily reproducible as it happens rarely; subsequent runs are OK. Could anybody find a possible cause of this behavior? Dawid ___ 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
Re: [Caml-list] What is a future of ocaml?
Few days ago I spent some time googling for any info in the subject and found nothing (except assigned feature requests in the tracer). Would be great to know what should be expected about OCaml in a long term. I understand that there's no manpower to push the core compiler forward faster. But it would be a solace to know that there are at least some optimistic plans with a broader horizon. (say, following is a collection of dreams :)) Is there any hope for a grand 'OCaml 4' release that would iron out the last ugly spots left in the language with some breaking changes? E.g.: Have immutable strings for everyday use and mutable byte arrays as buffers? Full support for revised syntax? (Error messages, documentation...) Make modules practically first-class by devising some standard way of automatic module to record conversion? Make record fields acting as projection functions? Could anybody explain why it's impossible to have type classes in OCaml? We have few very special operators like (=), is there any chance to make them less magic and work out anything that would satisfy basic needs for overloading? Dawid ___ 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
Re: [Caml-list] Toplevel - loading dependencies
in case you're doing so this way: ocamlc -o my.cma mod1.ml mod2.ml mod3.ml mod4.ml this will recompile everything, but you can use in your makefile: (...) then you don't recompile everything, only the modified module Yes, with ocamlbuild I need not to recompile everything, but it's slow traversing even nothing-to-be-done tree: Finished, 432 targets (411 cached) in 00:00:08. It takes already 8 seconds if nothing is touched. If I edit few files, it's worse: Finished, 432 targets (256 cached) in 00:00:49. I'm looking for alternatives. That's why I try with scripting: keep core libraries compiled and run outermost parts with an interpreter. Another idea is to change ocamlbuild to work dynamically: keep the dependency tree in memory and update it from time to time, watching files on disk. Dawid ___ 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
Re: [Caml-list] Toplevel - load cmo from given location
The problem is that it gives "Unbound module Enum" while no error about loading the cmo&cmi is shown. The #directory instruction is needed to find the .cmi. I see, so there are 2 problems: * why the failure to load cmi is silent in this case? * why the toplevel fails to check for cmi where the cmo is located? This looks as incorrect behaviour (the reference manual doesn't mention any exceptional rules for the #load directive). Dawid ___ 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
[Caml-list] Toplevel - loading dependencies
Another problem with loading modules in the toplevel: I need to use the module A. So I write: #load "A.cmo" to get a messsage "Reference to undefined global B" So I prepend a line: #load B.cmo and get another "undefined global". Then it repeats prohibitively many times. This is resolving dependencies by hand, one by one. The solution would be to have a special version of cmo that knows locations of all other cmo's it depends on. In special cases I could use cma archives, but this is only applicable when there is well defined and stable set of modules I need. But in practice the modules I use in ocaml scripts are constantly evolving. It leads to having multiple cma aggregates and maintaining their building description. Again, lots of work. If I put everything into one big cma, then I have to recompile it every small change. It takes so long time, that it would make no sense to use the interpreter at all. Could I ask ocamlbuild to produce proper loading preamble for my scripts? What is the right solution? Dawid ___ 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
[Caml-list] Toplevel - load cmo from given location
I've noticed stange behaviour: The following works OK (using #directory directive): #!/usr/bin/ocamlrun ocaml #directory "/home/dt2/Calc1/CalcEngine/src/_build/extlib/" #load "enum.cmo" open Enum But this version not (using the full path directly): #!/usr/bin/ocamlrun ocaml #load "/home/dt2/Calc1/CalcEngine/src/_build/extlib/enum.cmo" open Enum The problem is that it gives "Unbound module Enum" while no error about loading the cmo&cmi is shown. So: * if it finds correctly the enum.cmi: why "open Enum" doesn't work? * if the cmi is not found, why I see no message like "*Cannot find file */home/dt2/Calc1/CalcEngine/src/_build/extlib/enum.cmi*" - as chapter 9.4 of docs suggests? Does the toplevel check for the cmi in the same location as cmo? * (I tested this with the cmi file existing there as built by ocamlbuild) Dawid ___ 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
[Caml-list] Portable hash
I'm looking for a way to calculate hashes of values of variuos types. It has to be: 1. proper function (i.e. x=y => (hash x)=(hash y) ) 2. and should not change with a platform or compiler version. 3. It'd also help to have practically no collisions. For some time I needed not to move data across machines and what I have been (wrongly) using for this so far is: let hash x = Digest.string (Marshal.to_string x []) Recently I realized that it's incorrect as Marshal.to_string is not pure function and doesn't satisfy my first requirement. Indeed in some very rare cases I got different results from the same value. Only the 3rd point is satisfied very well. I have to change my function before I run into problems and I'm considering: 1) Small hashes: let hash x = |Hashtbl.hash_param large_int large_int x Does anybody know what are properies of | |Hashtbl.hash_param? I mean: is the implementation stable? Can I have good distribution when all the data is examined (large parameters)? Unfortunately it returns int of platform-dependent length (and even platform-depentent less significant bits of result?). How hard would it be to tailor it to, say, work always with 31 bits? || 2) To serialize values with Sexp: let hash to_sexp x = Digest.string (string_of_sexp (to_sexp x)) | |This way I have the stablility because I can just keep implementation of Sexp untouched. But the performance is going to be even worse than with my original solution.| Has anybody solved already this (or similar) problem? Dawid Toton ___ 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
Re: [Caml-list] Quantifier in the type
Hope this helps, Exactly what I wanted to know! Thanks! Dawid ___ 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
Re: [Caml-list] Quantifier in the type
Thanks for your answer; now I'll try to sate my point in a clear way, since you misunderstood all my questions. I put 'a in the interface: val fu : 'a -> 'a and int in the implementation: let fu x = x + 1 this interface doesn't reflect the implementation, ocaml will reject it in any way OK, it's all about this rejection, e.g. what does precisely mean 'to reflect the implementation'. So I have universal quantification: for any type 'a function fu can consume the argument. No it is not universal, imagine all the types that a user can create, you cannot handle them all (except maybe with the Obj module, but it's another question) I wanted this my sentence to be about the declatation in mli interface. My point is: the type in the declaration in mli implicitly contains universal quantifier. So my implementation doesn't comply with that universal quatification. And the message I get is following: Values do not match: val fu : int -> int is not included in val fu : 'a -> 'a Yes it doesn't match at all, the type of the implementation is int, nothing else. The error message uses plural: 'Value*s* do not match'. So this raises few questions: 1) Is (fun x -> x + 1) a value? 2) Is (x + 1) a value? 3) Is the whole line " val fu : 'a -> 'a " a value? 4) How many values are in my example? We have to find at least two, to understand the error message! An my conlcusion is that this is just silly, unimportant mistake: So the declaration of value in mli file is called simply a 'value'. Is it intentional? It is just the word in the English language to designate this thing. What do you mean saying 'this thing'? The point is: *which thing*? I thought that value and it's declaration are separate notions? Are they separate in OCaml or not? (Of course, everybody knows they have to be separate, that's why I'm asking about the word 'value'.) a value is handle by a identifier and has a type let ident = some_value in here ident and some_value are of some type So - according to your point of view - in my example there is only one value, which has identifier 'fu' and its type would be " 'a -> 'a " if the implementation was corrent. But, you remember, the error message was about *two* values. My reading of " val fu : 'a -> 'a " is: some partiular value vvv that belongs to set of values that satisfy "forall 'a : (vvv can be used with ('a -> 'a) type)" But if I write let (bar : 'a -> 'a ) = (fun x -> x + 1) I create a value that belongs to set "exists 'a : (vvv can be used with ('a -> 'a) type)" So it's the other quantifier. I think that the quantifier has to be part of type, since a type is set of values (and the quantifier plays important role when describing some of such sets). So my question is: since we see the same string " 'a -> 'a " that refers to different types in different contexts, what are the rules? How is type definition in OCaml translated to a type? type definition in OCaml are translated to actual types by inference. (fun x -> x + 1) will be easily infered to (int -> int) My question was what are the rules for putting universal and existential quantifers into types. So we have some type definition: 'a -> ('b -> 'c) How is it translated to a type? I have an idea that this piece of code can sometimes be not a type definition, but rather part of type equation. Let's take my previous example: let (bar : 'a -> 'a ) = ... This " 'a -> 'a " whould not define any type (so the problem of quantifiers would be irrelevant here), but RHS of some type equation. Still I'm not sure about what does this RHS contais (precisely). So: was I wrong thinking that existnetial quantifier is involved in this example? Dawid ___ 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
[Caml-list] Quantifier in the type
Just an elementary question. I put 'a in the interface: val fu : 'a -> 'a and int in the implementation: let fu x = x + 1 So I have universal quantification: for any type 'a function fu can consume the argument. So my implementation doesn't comply with that universal quatification. And the message I get is following: Values do not match: val fu : int -> int is not included in val fu : 'a -> 'a So the declaration of value in mli file is called simply a 'value'. Is it intentional? I thought that value and it's declaration are separate notions? My reading of " val fu : 'a -> 'a " is: some partiular value vvv that belongs to set of values that satisfy "forall 'a : (vvv can be used with ('a -> 'a) type)" But if I write let (bar : 'a -> 'a ) = (fun x -> x + 1) I create a value that belongs to set "exists 'a : (vvv can be used with ('a -> 'a) type)" So it's the other quantifier. I think that the quantifier has to be part of type, since a type is set of values (and the quantifier plays important role when describing some of such sets). So my question is: since we see the same string " 'a -> 'a " that refers to different types in different contexts, what are the rules? How is type definition in OCaml translated to a type? Dawid ___ 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
Re: [Caml-list] 'Compiler' module
Given that the sole objective of run-time compilation is performance and Python is vastly slower than OCaml, why are you the envy of Python's Compiler (to interpreted bytecode) module? From my point of view this is more about manipulating code at runtime and evaluating it (actually I'm not interested about performance). I think (as Zheng implied) you want asynchronous workflows from F#. Note that these also handle cleanup of resources. From what is currently available on web I see that it's equivalent to my current stop-gap solution using monads: (async {blah blah}) in F# can be translated to (lazy (blah blah)) in OCaml and Async.Run just uses some threads to do Lazy.force. Am I missing some difference? For a decent editor, you will need a lot more than that. I would certainly love to have such a thing but you also need access to the type checking phase to throwback type errors and having the data available in an efficient and accessible form would certainly be preferable. I see no reason for hypothetical Compiler.eval function couldn't give me full information about all errors. As for availability of resulting data: this is not obvious at the conceptual level. One possibile solution is to decide that the host invoking Compiler.eval has to treat resulting values as of abstract type. They might be subject to marshalling and so on. The other way is to have a module for manipulating data which type is known at runtime. Then Compiler.eval would return value of type TypedData.t = (Type.t, TypedData.abstract_type) The second approach would make the whole Compiler-module-thing more useful. Anyway, this is somewhat another story. RTTI would allow us to have clean implementation of marshalling. We could have (at no performance cost) Type.typeof operator that acts only on values of concrete type (if only camlp4 knew types...). I believe you can lex and parse OCaml using Camlp4 and then invoke the OCaml compiler with -dtypes to get the results of type checking. However, the latter is extremely inefficient. You really want the ability to restart the compiler from the end of the previous definition each time a file is edited. I hope the first dirty solution would be to use compiled modules as the context carrier. In case of a simple editor I'd have many tiny modules that correspond to compiled chunks of evolvong code. It would scale not so bad: compiler would have to load (log n) modules for n chunks processed. But I have no idea what would be the practical performance. Dawid ___ 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
[Caml-list] 'Compiler' module (was: embedding ocaml into a windows app: need gcc?)
I would like an OCaml support library that can compile and execute similar to JaveScript engines, but we don't have that in any practical form. I also need this and I'm thinking about something like this: module type Compiler = sig val parse : Context.t -> string -> (Context.t * AST.t) val get_type : Context.t -> AST.t -> Type.t; val eval : Context.t -> AST.t -> Context.t * (Type.t * MarshalledValueOrSomething.t) end Is it really so hard to have it in OCaml? I'm envy of Python's Compiler module. It could solve some of my problems, in particular for my 'parallel-like' evaluation ( http://www.nabble.com/'Nondeterministic'-evaluation-wrt-exceptions-td18653998.html ). After some experimentation I know that I need type information during code transformation. I want to create a sort of interpreter. That Compiler module would also enable me to have an editor with graphical representation of results intermixed with code (like Mathematica's notebook). Where to look for suitable pieces of code? AFAIK camlp4 modules can't tell me type of anything. Should I start digging in OCaml compiler sources? Dawid ___ 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
Re: [Caml-list] 'Nondeterministic' evaluation wrt exceptions
Thank you all for quick answers! Let me show an example of what I exactly mean. I start with a code: 1: let a = heavy 1 2: let b = heavy 2 3: let c = report (a + b) 4: let d = heavy 4 5: let e = heavy d Then I want to translate it automatically so that three applications of heavy are evaluated (lines 1, 2, 4). The addition a + b won't be evaluated untill a and b are successfully returned. It's easier to get only two heavy operations started at once: 0: type 'a future_t = 'a Lazy.t 1: let a = future heavy 1 2: let b = future heavy 2 3: let c = report ((force a) + (force b)) 4: let d = future heavy 4 5: let e = future heavy (force d) Computation of c hangs or throws an exception. Hence lines 4 an 5 are not executed. So I think I need some more invasive transformarion: 0: type 'a future_t = 'a Lazy.t 1: let a = future heavy 1 2: let b = future heavy 2 3: let c = lazy (report (force a) + (force b)) 4: let d = future heavy 4 5: let e = future heavy (force d) 6: let _ = force c In this case we have a problem: line 5 throws an exception, so report in line 3 is not executed even if first two heavy operations are finished. The function report could even contain some other heavy operations that need to be started as soon as possible. So I can conctruct a tree of deferred computations, but probably I can't force it to do as much as possible. Forcing is governed by total order. Let's consider: 7: let f = foo (force c) (force e) If one of arguments fails first, the other is not forced. This is bad. So I go to the original idea: thread the exception across everything. Wrap with variant instead of Lazy.t. 0: type 'a lifted_t = Exception | Value 'a 1: let a = start heavy 1 2: let b = start heavy 2 3: let c = bind2 (fun a b -> return (report (a+b))) a b 4: let d = start heavy 4 5: let e = bind1 (fun d -> start heavy d) d 7: let f = bind2 (fun c e -> return (foo c e)) c e Function 'start' starts calculation and returns Exception or returns Value result if it's available. bindX functions evaluate the function passed as a parameter if all arguments are Values. Is is easy to lift every heavy call to 'start heavy arg arg arg ...' - since in any case I have to distinguish heavy functions manually. I need to decide about granularity of bindX incrustation. I can have some modules marked as 'nondeterministic' and leave the other ones untouched. I could wrap into lifted_t all single values in 'nondeterministic' modules. This would mean placing bindX for every integer addition, every string concatenation... I need rules: where should I place bindX and return in the original code. At the moment I don't know. I have looked at the Lwt library - as far as I understand in my case the idea boils down to threading something across all expressions. Dawid ___ 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
[Caml-list] 'Nondeterministic' evaluation wrt exceptions
Let's look at my OCaml program as a poset of function applications. Some its elements throw exceptions. I need to evaluate all applications except of those that 'Follow' exception-throwing ones. This 'Follow' corresponds to the ordering in my poset. Unfortunately standard tools allow only to do this with 'Follow' corresponding to some total order. Could you give me some advice how to evaluate really all applications that precede throwing an exception? -- Full story I have many similar programs that do calculations for me. Some steps are very computationally heavy. Every such function do_heavy_thing starts another process (on other computer) and throws an exception that means "the result will be available later". Everything that relies on this result of do_heavy_thing cannot be evaluated. And it won't be because I don't catch the exception. So I run my programs repeatedly. I correct and extend them while heavy_thing is done somewhere else (usually for few days). do_heavy_thing checks for the result. If it's finished at the moment of execution, it downloads the data and returns. Then the data undergoes some cheap transformations and some next do_heavy_thing function can be called. Every time I execute the program I get some more useful output and "Fatal error: exception ..." message. So far this scheme worked very well. This is basically breaking the calculation at some point with respect to a total order (the order of source code). Some calculations should be done in parallel, since there are many of them. I solved this problem with run_many adapter: firstly collect a list of heavy calculations, then execute them as a one node in the total order of evaluation. Currently I hit the following problem: my new programs (call them 'Calcs') are too complex to apply the evasion with run_many. So my latest calculations are done one-by-one. This is so bad, that I can spend several days in order to solve this in a systematical way. These Calcs are managed by other set of OCaml tools. I have complete control over all the code. The tools already do tiny changes to Calcs with simple string operations, not real syntax extension. I hope some witty preprocessor can help. I have no idea what code the syntax extension should produce. My first guess is to wrap everything in type 'a wrapped = Exception | Value 'a and make all aplications evaluated. But this seems to be a big headache. Maybe this is well-known, already solved problem? Any ideas? Dawid ___ 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