Re: [Caml-list] Binding the Lua library [was: adding a scripting language to an ocaml program]

2010-07-06 Thread Guillaume Yziquel

Paolo Donadeo a écrit :


So I wrote the binding to some basic functions and a stress test
designed to reveal memory leaks of the binding. The test passed and so
I consider the code quite stable, but I had to stop the development
due to the chronic lack of time and due to a specific problem: I don't
know how to handle the impedance mismatch between the two garbage
collectors.


Yes. This kind of issue is tough. I also had it in the OCaml-R code. And 
the solution is far from perfect, but works. I do not know about Lua, 
though.



And again: how to translate (read: how to bind) in OCaml functions like these:

void *lua_newuserdata (lua_State *L, size_t size); [4]
or
void *lua_touserdata (lua_State *L, int index); [5]

Is Obj.magic the only possible way? It's ugly and, of course,
"Obj.magic is not part of the OCaml language", but in this case you
use a cast in C, so why not cast a spell in OCaml?


You might want to check out the code sample I published here (at the 
bottom).


http://ocaml.janestreet.com/?q=node/59

Unfortunately, using this recursive subtyping trick (which can be 
extended to more sophisticated recursive subtyping between more than 2 
type systems) raises issues in the presence of OCaml classes: The 
compiler goes in an infinite loop when doing type inference. The issue 
should be solved in 3.12.


It's not yet used in the OCaml-R binding because of compiler infinite 
loop problem. But it is used in my (unpublished) Python binding.



If anyone is interested in my prototype I could clean up the source,
remove comments in Italian and publish it on GitHub or OCamlCore.


I'm always interested in language bindings... And I think a few other 
people are interested in an Lua binding.



And, of course, any ideas or help on the garbage collector(s) issue are welcome.


I do not know much about Lua's GC. My experience (for R, Python and 
Java) is that it's doable. The first shot is often imperfect and 
inefficient becauses GCs are not designed in the spirit of being binded. 
(R's API only provides a cumbersome stack-based mechanism to interact 
with R's GC, which is wholly inadequate).


I guess that with more available time, it is indeed possible to do clean 
tricks in order to get the GCs to cooperate efficiently... (I have a few 
tricks in mind for R that will have to wait.)


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] adding a scripting language to an ocaml program

2010-07-06 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :


I do not have much time available on this one, and I currently have 
other interests. But if someone is interested in the code, please email 
me to see what is possible to do...


I mean: privately.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] adding a scripting language to an ocaml program

2010-07-06 Thread Guillaume Yziquel

Thomas Fischbacher a écrit :


The last thing I remember is that Guillaume had contacted me about
wanting to re-write it, but not much seems to have happened on that
front so far.


Well, things have happened on this front so far. And a few people have 
the code that I've written. Unfortunately, for rather awkward reasons, I 
am not in a position to release it. But hope to be in the rather not 
distant future.


It's basically a rewrite. It works, but isn't fully featured yet. I 
believe memory management is done properly. There are also some C 
varargs functions in the Python API that have been properly binded with 
the libavr library (or something called like that). A (yet basic) syntax 
extension allows to write things like:


module X = python module mypython module

It does introspection and dumps the OCaml code needed to access values 
of the module. I've been hitting type inference issues in Python for 
this. But there is some work (like shedskin) to capitalise in order to 
make the syntax extension more interesting when it comes to typing.


And there's a Debian package, also.

Do not hold your breath on this code, as a release might take a while.

But if someone is willing to carve out of shedskin the code needed to do 
type inference and bind it to OCaml, that would be a nice contribution 
to the syntax extension.


I do not have much time available on this one, and I currently have 
other interests. But if someone is interested in the code, please email 
me to see what is possible to do...


All the best,

Guillaume Yziquel.
--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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 with libstdc++.so

2010-06-28 Thread Guillaume Yziquel
Hello.

I've been trying to compile a library with C++. With something like:

ocamlc -verbose -a -dllib dllmystuff_stubs.so -dllib libstdc++ -o myStuff.cma 
myStuff.cmo

However, on Debian systems, there is a libstdc++.so.5 and a libstdc++.so.6 
file. No 
libstdc++.so file. So the -dllib libstdc++ option doesn't locate properly the 
library. How do you 
manage to have more control over the name of the library without resorting to 
using an ugly 
symlink in /usr/lib/ocaml/stublibs?

All the best,

Guillaume Yziquel.

___
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] Sending compiler into an infinite loop or stack overflow.

2010-04-16 Thread Guillaume Yziquel

Hello.

Here is a compiler infinite loop / stack overflow error. In the 
toplevelm yuo get the following, but using ocamlc, you get an infinite loop.



yziq...@seldon:~$ ocaml
Objective Caml version 3.11.2

# type untyped;;
type untyped
# type -'a typed = private untyped;;
type 'a typed = private untyped
# type -'typing wrapped = private sexp
  and +'a t = 'a typed wrapped
  and sexp = private untyped wrapped;;
type 'a wrapped = private sexp
and 'a t = 'a typed wrapped
and sexp = private untyped wrapped
# class type ['a] s3 = object 
val underlying : 'a t

  end;;
class type ['a] s3 = object val underlying : 'a t end
# class ['a] s3object r : ['a] s3 = object
val underlying = r
  end;;
Fatal error: exception Stack_overflow


I've tracked it down it down on some other but similar code to the Ctype 
module.



Objective Caml Debugger version 3.11.1

(ocd) start
Loading program... done.
`start not meaningful in outermost frame.
(ocd) step 6516537
Time : 6516537 - pc : 392692 - module Ctype
134   let name = match path with Path.Pident id -> <|b|>Ident.name id
(ocd) run
Time : 6516782
Program end.
Uncaught exception: Stack_overflow
(ocd) 


Unfortunately, I'm getting quite lost in the compiler source code, so 
I'd appreciate some background information on how to deal with this issue.


All the best,

Guillaume Yziquel.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-03-01 Thread Guillaume Yziquel

David Allsopp a écrit :

Guillaume Yziquel wrote:

Stéphane Glondu a écrit :


Why don't you just declare 'a t to be synonym for obj in the
implementation of your module, declare them as abstract in its
interface, and export the specially typed identities f and g?


Because subtyping seems more efficient than applying a noop function.


I wholeheartedly agree that doing this in the type system is much cleaner than 
using noop/coercion functions but I don't think that there's any difference in 
terms of efficiency. If the noop/coercion functions are correctly coded then 
they will be of the form:

external foo_of_bar : bar -> foo = "%identity"

in *both* the .ml and .mli file for the module in question. I'm virtually 
certain that ocamlopt eliminates calls to the %identity primitive.


yziq...@seldon:~$ grep magic /usr/lib/ocaml/obj.mli
external magic : 'a -> 'b = "%identity"

So far so good.


Moreover, having conversion functions is not really handy, from a
syntactic point of view: It's quite convenient to write something like

let f : string -> obj :> string -> float t = blah blah blah...

than doing the explicit, runtime, casting in the definition of f.


Agreed - this is where your approach is really neat!


I'm not so sure how far we can push the idea. You can, in one ':>', do 
subtyping at every type in the type 'a -> 'b -> 'c. This is quite handy. 
But I'll have to check in which way this can be integrated in the 
calling conventions of, say, Python.



I then tried to go the whole way, and get rid of conversion functions
altogether.


Being pedantic, what you mean is getting rid of *coercion* functions; 
*conversion* functions could never eliminated


OK.


This is tremendously clean - as long as the types are clearly documented! The problem is 
that ocamldoc doesn't let you "document" coercions (by which I mean that having 
a conversion function provides means for the documentation of that particular usage).


Thank you. The ocamldoc problem isn't really a problem, I believe. You 
just have to write it cleanly in bold letters.


What is more a problem is the fact that inferred .mli files tend to 
leave out the contravariance on tau:


http://caml.inria.fr/mantis/view.php?id=4988

And hence drops part of the subtyping facility.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-03-01 Thread Guillaume Yziquel

Stéphane Glondu a écrit :

Guillaume Yziquel a écrit :

Because subtyping seems more efficient than applying a noop function.
And this code might run really often, so I do not like very much the
idea of having noop functions running really often.


FWIW, I don't think you have any penalty if you declare your identities
as externals like Obj.{repr,obj,magic}. Yuk, some might say... but we
are in the context of bindings to other languages anyway.


Yuk indeed. The subtyping was also a way to avoid Obj.magic in the first 
place and keep doing things cleanly.


I'm not so sure about runtime penalty in this context.


Moreover, having conversion functions is not really handy, from a
syntactic point of view: It's quite convenient to write something like

let f : string -> obj :> string -> float t = blah blah blah...

than doing the explicit, runtime, casting in the definition of f.


It's more convenient for me write letters and parentheses than the
symbol ":>" :-)


That's a matter of taste, I guess :-)


IIUC, these conversion function are not to be used often, are they? What
you want is the equivalent of Obj.{repr,obj}, but for values of some
other language, right?


Yes, for the values of some other language.

It depends: they are to be used often for people wanting to make 
bindings of R / Python code. (Even tough I plan to use syntax extensions 
to ease the pain, something like 'module Nltk = python module nltk'. But 
that's a long term perspective.


For people using the binded code, subtyping shouldn't be necessary.


Are you planning to leak your "tau", "typed" and "untyped" types out of
the module? If so, inferred types are likely to refer to those, which
might be very confusing (unless you resort to a lot of type
annotations). If not, you'll have to use explicitly the coercion
functions outside of the module anyway.


Yes.

I'm not satisfied with this. (Renaming 'tau' to 'wrapped' would be 
better, I guess).


But somehow, I believe that it's an OCaml issue rather than an issue 
with my approach. I mean, why should it be impossible to *express* in 
the .mli file something like type 'a t = private obj and obj = private 
'a t without resorting to extra intermediary types and contravariant 
phantom types? Couldn't we just dump the type inequations and 
co/contra-variance information (which would require another syntax for 
types, I guess)?


But there's another problem for weirder typings that would need 3 
different categories of types (R ?). 2 conversion functions is OK. 6 
conversion functions is clearly a pain... And concerning R's quirky type 
system, I'm probably optimistic with the number 3.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-03-01 Thread Guillaume Yziquel

Stéphane Glondu a écrit :

Guillaume Yziquel a écrit :

# type untyped;;
type untyped
# type 'a typed = private untyped;;
type 'a typed = private untyped
# type -'typing tau = private obj
  and 'a t = 'a typed tau
  and obj = private untyped tau;;
type 'a tau = private obj
and 'a t = 'a typed tau
and obj = private untyped tau
# let f : 'a t -> obj = fun x -> (x : 'a t :> obj);;
val f : 'a t -> obj = 
# let g : obj -> 'a t = fun x -> (x : obj :> 'a t);;
val g : obj -> 'a t = 
# 


Why don't you just declare 'a t to be synonym for obj in the
implementation of your module, declare them as abstract in its
interface, and export the specially typed identities f and g?


Because subtyping seems more efficient than applying a noop function. 
And this code might run really often, so I do not like very much the 
idea of having noop functions running really often.


Moreover, having conversion functions is not really handy, from a 
syntactic point of view: It's quite convenient to write something like


let f : string -> obj :> string -> float t = blah blah blah...

than doing the explicit, runtime, casting in the definition of f. 
Haven't tried the line above, so do not quote me on this, but using 
covariance and contravariance can make your code cleaner, with less 
parentheses.


What happened is that I was (am currently) doing only the 'a t :> obj 
subtyping in OCaml-R, and I also have a R.cast function to cast from obj 
to 'a t.


I thought this solution was cleaner than having two conversion functions.

I then tried to go the whole way, and get rid of conversion functions 
altogether.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-28 Thread Guillaume Yziquel

Goswin von Brederlow a écrit :


Doing 'a t = private underlying allows you to create a type inference
barrier. However, you also want to be able to cast from underlying to
'a t, when you get the result of a function in R or Python, for
instance.

So that's exactly the use case you mentionned above.


Why not supply conversion functions that do any additional checks to
ensure the conversion is a valid one? Consider the following:


Because that's exactly what I try to avoid. R and Python are already
slow enough and dynamically type-checked at every corner. I'm not
happy to add another type-checking layer.


But if you do not check then someone can convert a float q into w and
back into int q. That would hide the error in the conversion until such
a time as the type is later used in some function that does check the
type. I would rather have those checks than go hunting for the real
error for hours.


Yes and no.

In some sense, when you do bindings of C code, you do have to be 
careful. There's no reason that it should be different for binding 
Python code or R code.


I mean, having a slick binding without dynamic type checks is, from my 
point of view, a good thing.


But this subtyping is for the person binding R or Python code.

The user of the binded code should not see any subtyping. That's the 
goal: having a good framework to do the bindings. Not exposing low level 
R or Python details the the OCaml coder using the bindings.



I've been looking all over at this issue, but simply cannot find a way
out. While experimenting on this, I've stumbled on a number of quirky
issues with the type system.

First one: http://ocaml.janestreet.com/?q=node/26

Second one:


# type 'a q = ;;
type 'a q = < m : 'a >
# let f : 'a q -> 'a q = fun x -> x;;
val f : 'a q -> 'a q = 
# let o = object method m : 'a. 'a -> 'a = fun x -> x end;; val o :
< m : 'a. 'a -> 'a > = 
# f o;;
Error: This expression has type < m : 'a. 'a -> 'a >
   but an expression was expected of type 'b q
   The universal variable 'a would escape its scope
#

All these issues seem to be somehow related, in a way I'm not yet able
to articulate clearly.


# class ['a] foo = object method map (f : 'a -> 'b) = ((Obj.magic 0) : 'b foo) 
end;;
class ['a] foo : object method map : ('a -> 'a) -> 'a foo end

As I recently learned there seems to be no way to make that actualy
produce a 'b foo. I think that hits the same problem.

MfG
Goswin


Will have a look at that when I find the time.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-27 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Guillaume Yziquel a écrit :

Andreas Rossberg a écrit :

On Feb 27, 2010, at 14:11, Guillaume Yziquel wrote:

# type q = private w and w = private q;;
type q = private w
and w = private q
# let f (x : q) = (x : q :> w);;
val f : q -> w = 
# let f (x : q) = (x : w);;
Error: This expression has type q but an expression was expected of 
type w

#


Interesting, but these are vacuous type definitions. In fact, I would 
call it a bug that the compiler does not reject them (it does when 
you remove at least one of the "private"s).


In any case, I don't quite understand how this pathological behaviour 
is supposed to help, because the types are uninhabited anyway.


From OCaml world exclusively, yes, they are uninhabited. I'm using C 
code to populate these types. [...]


you then have an interesting way to type Python code that you want to 
bring to OCaml.


That's the purpose.


Got it!

Hope it may be useful for others:


Here's a cleaner version, without the object type system:


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.2

# type untyped;;
type untyped
# type 'a typed = private untyped;;
type 'a typed = private untyped
# type -'typing tau = private obj
  and 'a t = 'a typed tau
  and obj = private untyped tau;;
type 'a tau = private obj
and 'a t = 'a typed tau
and obj = private untyped tau
# let f : 'a t -> obj = fun x -> (x : 'a t :> obj);;
val f : 'a t -> obj = 
# let g : obj -> 'a t = fun x -> (x : obj :> 'a t);;
val g : obj -> 'a t = 
# 


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-27 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Andreas Rossberg a écrit :

On Feb 27, 2010, at 14:11, Guillaume Yziquel wrote:

# type q = private w and w = private q;;
type q = private w
and w = private q
# let f (x : q) = (x : q :> w);;
val f : q -> w = 
# let f (x : q) = (x : w);;
Error: This expression has type q but an expression was expected of 
type w

#


Interesting, but these are vacuous type definitions. In fact, I would 
call it a bug that the compiler does not reject them (it does when you 
remove at least one of the "private"s).


In any case, I don't quite understand how this pathological behaviour 
is supposed to help, because the types are uninhabited anyway.


From OCaml world exclusively, yes, they are uninhabited. I'm using C code 
to populate these types. [...]


you then have an interesting way to type Python code that you want to 
bring to OCaml.


That's the purpose.


Got it!

Hope it may be useful for others:


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.2


The rectypes option is not necessary here.


# type -'a tau = private q and 'a w = < m : 'a > tau and q = private < > tau;;
type 'a tau = private q
and 'a w = < m : 'a > tau
and q = private <  > tau


We're using the < m : 'a > :> < > subtyping with contravariant 
polymorphism to get q :> < > tau :> < m : 'a > tau = 'a w.


The converse is rather easy: 'a w = < m : 'a > tau :> q.


# let f : 'a w -> q = fun x -> (x : 'a w :> q);;
val f : 'a w -> q = 
# let g : q -> 'a w = fun x -> (x : q :> 'a w);;
val g : q -> 'a w = 


So this subtyping type checks correctly.


# let h : 'a w -> q = fun x -> x;;
Error: This expression has type 'a w = < m : 'a > tau
   but an expression was expected of type q
# 


And the two types are not equivalent. As this opens the way to correctly 
typing dynamic languages bindings for OCaml (at least in my humble point 
of view), I'd like to know what the bug/feature


type q = private w and w = private q with q != w

will become in the future.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-27 Thread Guillaume Yziquel

Andreas Rossberg a écrit :

On Feb 27, 2010, at 14:11, Guillaume Yziquel wrote:

# type q = private w and w = private q;;
type q = private w
and w = private q
# let f (x : q) = (x : q :> w);;
val f : q -> w = 
# let f (x : q) = (x : w);;
Error: This expression has type q but an expression was expected of 
type w

#


Interesting, but these are vacuous type definitions. In fact, I would 
call it a bug that the compiler does not reject them (it does when you 
remove at least one of the "private"s).


It does indeed reject them without the private keyword, even with the 
rectypes option. I'd appreciate a statement from someone of the OCaml 
team as to whether this is a bug or a feature. Because I intend to use 
this feature in my code.


In any case, I don't quite 
understand how this pathological behaviour is supposed to help, because 
the types are uninhabited anyway.


From OCaml world exclusively, yes, they are inhabited. I'm using C code 
to populate these types.


Say you have what I would like to have, i.e.


type 'a t = private obj and obj = private 'a t


then you could have an


external get_value : string -> obj = "my_get_value"


you could then retrieve a value for a Python function and another as its 
argument. They are both obj, but you could subtype them respectively to 
a (string -> int) t and to a string t.


Suppose you also have defined an


external eval : ('a -> 'b) t -> 'a t -> 'b t = "my_eval"


you then have an interesting way to type Python code that you want to 
bring to OCaml.


That's the purpose.

I've been looking all over at this issue, but simply cannot find a way 
out. While experimenting on this, I've stumbled on a number of quirky 
issues with the type system.


First one: http://ocaml.janestreet.com/?q=node/26


That's indeed a slight oversight in the design of the module type 
system. (FWIW, this is possible in SML.)


Very probably. It seems that the author, 'skweeks', comes from the SML 
world.



Second one:


# type 'a q = ;;
type 'a q = < m : 'a >
# let f : 'a q -> 'a q = fun x -> x;;
val f : 'a q -> 'a q = 
# let o = object method m : 'a. 'a -> 'a = fun x -> x end;; val o : < 
m : 'a. 'a -> 'a > = 

# f o;;
Error: This expression has type < m : 'a. 'a -> 'a >
  but an expression was expected of type 'b q
  The universal variable 'a would escape its scope


This example would require full impredicative polymorphism, because you 
would need to instantiate 'a q with a polymorphic type.


Yes.

The ML type 
system does not support that, because it generally makes type inference 
undecidable.


Could you sum up, in a nutshell, the argument that concludes to 
undecidability of such a type system?


But see e.g. Le Botlan & Remy's work on ML^F for a more 
powerful approach than what we have today.


Thanks.


/Andreas


Still looking for workarounds... I've still got a few ideas to develop, 
but I'va got a feeling that I'm running short on oil, here...


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-27 Thread Guillaume Yziquel

Goswin von Brederlow a écrit :

Guillaume Yziquel  writes:


My goal is to implement a type inference barrier.

You can do


type 'a q = private w

and from the type inference point of view, int q and float q are two
distinct types, that you can subtype to a common type.

What I want is also to have the reverse, i.e.


type w = private 'a q

But that doesn't work out this way because of the fact that 'a is unbound.


But then int q :> w :> float q and float q :> w :> int q. That would
make the whole thing somewhat pointless. Everyone could convert the type
to anything. I guess it would protect from accidentally passing the
wrong 'a q while allowing purposefully to pass any 'a q.


Exactly. It's the situation you have when you're trying to do OCaml 
binding of libraries written in dynamic languages: You want to have type 
inference on the side of semantics, hence a typing reflecting this. Bt 
you also want to type lower-level details about objects. This last 
sentence is not so true with Python, for instance, but with R, it is 
(despite the argument I had with Simon Urbanek on the r-devel@ mailing 
list).


You want to have an 'a t type with 'a reflecting the corresponding 
typing in OCaml. And an 'underlying' type representing the low-level value.


Doing 'a t = private underlying allows you to create a type inference 
barrier. However, you also want to be able to cast from underlying to 'a 
t, when you get the result of a function in R or Python, for instance.


So that's exactly the use case you mentionned above.


Why not supply conversion functions that do any additional checks to
ensure the conversion is a valid one? Consider the following:


Because that's exactly what I try to avoid. R and Python are already 
slow enough and dynamically type-checked at every corner. I'm not happy 
to add another type-checking layer.



module M : sig
  type w = Int of int | Float of float


Ugly. (IMHO)


  type 'a q = private w
  val add : 'a q -> 'a q -> 'a q
  val print : w -> unit
  val as_int : w -> int q
  val as_float : w -> float q


Ugly. (IMHO)


end = struct


I've been looking all over at this issue, but simply cannot find a way 
out. While experimenting on this, I've stumbled on a number of quirky 
issues with the type system.


First one: http://ocaml.janestreet.com/?q=node/26

Second one:


# type 'a q = ;;
type 'a q = < m : 'a >
# let f : 'a q -> 'a q = fun x -> x;;
val f : 'a q -> 'a q = 
# let o = object method m : 'a. 'a -> 'a = fun x -> x end;; 
val o : < m : 'a. 'a -> 'a > = 

# f o;;
Error: This expression has type < m : 'a. 'a -> 'a >
   but an expression was expected of type 'b q
   The universal variable 'a would escape its scope
# 


All these issues seem to be somehow related, in a way I'm not yet able 
to articulate clearly.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-27 Thread Guillaume Yziquel

Andreas Rossberg a écrit :

On Feb 27, 2010, at 02:52, Guillaume Yziquel wrote:


I've been struggling to have a type system where I could do the 
following subtyping:


'a t1 :> t2  and  t2 :> 'a t1


Hm, what do you mean? Subtyping ought to be reflexive and antisymmetric 
(although the latter is rarely proved for most type systems), which 
means that your two inequations will hold if and only if 'a t1 = t2, 
regardless of recursive types.


/Andreas


Antisymmetric?


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.2

# type q = private w and w = private q;;
type q = private w
and w = private q
# let f (x : q) = (x : q :> w);;
val f : q -> w = 
# let f (x : q) = (x : w);;
Error: This expression has type q but an expression was expected of type w
# 


Not exactly, it seems.

My goal is to implement a type inference barrier.

You can do


type 'a q = private w


and from the type inference point of view, int q and float q are two 
distinct types, that you can subtype to a common type.


What I want is also to have the reverse, i.e.


type w = private 'a q


But that doesn't work out this way because of the fact that 'a is unbound.

You can move around this specific problem by using contravariant 
polymorphism, as is done in my previous email, but somehow, you cannot 
have a recursive subtyping from 'a q to w and from w back to 'a q. There 
always seem to be something wrong, with a problematic more or less 
analoguous to adjoint functors in category theory.


Hence my last email.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursive subtyping issue

2010-02-26 Thread Guillaume Yziquel

Hello.

I've been struggling to have a type system where I could do the 
following subtyping:


'a t1 :> t2  and  t2 :> 'a t1

So I've tried to do the following:


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.2

# #rectypes;;
# module Q = struct
type -'a e
type 'a q = private w
and w = w e
and 'a r = 'a q e
  end;;
module Q :
  sig type -'a e type 'a q = private w and w = w e and 'a r = 'a q e end


It almost seems to work:


# let f x = (x : Q.w Q.e :> 'a Q.q Q.e);;
val f : Q.w Q.e -> 'a Q.q Q.e = 
# let f' x = (x : Q.w :> 'a Q.r);;
val f' : Q.w -> 'a Q.r = 
# let g x = (x : 'a Q.q :> Q.w);;
val g : 'a Q.q -> Q.w = 


We can subtype from 'a Q.q to Q.w and from Q.w to 'a Q.r. So I now only 
need to equate 'a Q.r with 'a Q.q in one way or another...


I therefore tried the following, unsuccessfully:


# module W = struct
type -'a e = ('a -> unit) q
and 'a q = private w
and w = w e
and 'a r = 'a q e
  end;;
Error: The type abbreviation q is cyclic
# 


What's going wrong? And how can one get to do the proposed recursive 
subtyping?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping var_args, or C ... in ocaml?

2010-02-19 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Florent Monnier a écrit :

Le dimanche 14 février 2010 23:46:10, Guillaume Yziquel a écrit :
I mean, it seems that varargs means on the receiving end "the number 
of arguments you'r giving me, as a function, is not limited", whereas 
on the sending end, you hard-code the number of arguments in your C 
code.


Is there a way to map an OCaml list to an ellipsis? Or is it a C 
limitation?


Yes, as long as I know, for this you should use these kind of tools:
http://sourceware.org/libffi/
http://www.gnu.org/software/libffcall/avcall.html
http://www.nongnu.org/cinvoke/


Phew! These tools are quite tough to handle! (I just tried to use 
avcall.h on this ellipsis.)


Got it.

The correct code is:


CAMLprim value ocamlpython_py_tuple_pack (value ml_len, value ml_pyobjs) {

  av_alist argList;
  PyObject * retVal;
  av_start_ptr(argList, &PyTuple_Pack, PyObject*, &retVal);

  #if defined(__s390__) || defined(__hppa__) || defined(__cris__)
  #define av_Py_ssize_t av_long
  #else
  #define av_Py_ssize_t av_int
  #endif

  av_Py_ssize_t(argList, Pyoffset_val(ml_len));
  while (ml_pyobjs != Val_emptylist) {
av_ptr(argList, PyObject*, Pyobj_val(Field(ml_pyobjs, 0)));
ml_pyobjs = Field(ml_pyobjs, 1);
  }

  av_call(argList);
  return(Val_owned_pyobj(retVal));
}


Hope that will be useful to people wishing to wrap up varargs (though 
it's probably a bad idea, since the stack is limited...)


Python function calls are now possible by constructing the argument tuple.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: Embedding OCaml - manual not up to date.

2010-02-16 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Hi.

The manual is not up to date when it comes to embedding OCaml code into 
C code.


http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#toc134

Specifically the section

18.7.5  Embedding the Caml code in the C code

and the piece of compilation code I'm having trouble with is the following:

ocamlopt -output-obj -o camlcode.o unix.cmxa other .cmx and 
.cmxa files

cc -o myprog C objects and libraries \
   camlcode.o -L/usr/local/lib/ocaml -lunix -lasmrun


This code complains about missing symbols from pervasives.

So I adapt it by compiling with pervasives.cmx, and I get


ocamlopt -output-obj -o camlcode.o pervasives.cmx
ld: /usr/lib/ocaml/pervasives.o: No such file: No such file or directory
File "caml_startup", line 1, characters 0-1:
Error: Error during linking
make: *** [camlcode.o] Erreur 


But I cannot find pervasives.o anywhere.


Well I found it in stdlib.a, but looking back at the thread started by 
Aaron Bohannon mid-december


http://caml.inria.fr/pub/ml-archives/caml-list/2009/12/3375527140f0de987a9dc6d2553990c8.en.html

it seems to me that there is little need for the -output-obj option, as 
shown in the manual. Why not document the embedding by simply compiling 
the C code tha provides the main function, which itself calls 
caml_startup, and then linking it with the .cmx with ocamlopt? Why the 
need for -output-obj, libasmrun.a, etc...?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Embedding OCaml - manual not up to date.

2010-02-16 Thread Guillaume Yziquel

Hi.

The manual is not up to date when it comes to embedding OCaml code into 
C code.


http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#toc134

Specifically the section

18.7.5  Embedding the Caml code in the C code

and the piece of compilation code I'm having trouble with is the following:


ocamlopt -output-obj -o camlcode.o unix.cmxa other .cmx and .cmxa files
cc -o myprog C objects and libraries \
   camlcode.o -L/usr/local/lib/ocaml -lunix -lasmrun


This code complains about missing symbols from pervasives.

So I adapt it by compiling with pervasives.cmx, and I get


ocamlopt -output-obj -o camlcode.o pervasives.cmx
ld: /usr/lib/ocaml/pervasives.o: No such file: No such file or directory
File "caml_startup", line 1, characters 0-1:
Error: Error during linking
make: *** [camlcode.o] Erreur 


But I cannot find pervasives.o anywhere.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping var_args, or C ... in ocaml?

2010-02-14 Thread Guillaume Yziquel

Richard Jones a écrit :

On Mon, Feb 15, 2010 at 12:13:17AM +0100, Guillaume Yziquel wrote:

Richard Jones a écrit :

On Sun, Feb 14, 2010 at 11:46:10PM +0100, Guillaume Yziquel wrote:


However I'm still confused what you are trying to do here.  If you're
trying to bind the above, maybe look first at PyCaml?


Well, somehow, PyCaml seems to never have wanted to work with me.

I tried Art Yerkes' version, Thomas Fishbacher's version, Henrik 
Stuart's version, and Yoann Padioleau's merge of these versions. Somehow 
things always seem wrong. I get a segfault with Yoann Padioleau's 
version due to the layout of the Python table function (WTF!? BTW).


So I'm rewriting a Python embedding.

http://yziquel.homelinux.org/gitweb/?p=ocaml-python.git;a=shortlog;h=refs/heads/yziquel
http://yziquel.homelinux.org/debian/pool/main/o/ocaml-python/
http://yziquel.homelinux.org/topos/api/ocaml-python/Python.html

Sample session:


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;  to load a package
  #list;;   to list the available packages
  #camlp4o;;to load camlp4 (standard syntax)
  #camlp4r;;to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();; to force that packages will be reloaded
  #thread;; to enable threads

- : unit = ()
# #require "python.interpreter";;
/usr/lib/ocaml/python: added to search path
/usr/lib/ocaml/python/python.cma: loaded
/usr/lib/ocaml/python/oCamlPython.cmo: loaded
# open Python;;
# let dolfin = Module.import "dolfin";;
val dolfin : Python.pymodule Python.t = 
# let dictionary = Module.get_dict dolfin;;
val dictionary : Python.dict Python.t = 
# let keys = Dict.keys dictionary;;
val keys : string list Python.t = 
# let key_list = list_from keys;;
val key_list : string Python.t list =
  [; ; ; ; ; ; ; ;
   ; ; ; ; ; ; ; ;
   ; ; ; ; ; ...]
# let string_list = List.map string_from key_list;;
val string_list : string list =
  ["restriction"; "gt"; "precedence"; "TrialFunctions"; "ale"; "as_tensor";
   "cross"; "__path__"; "shape"; "PETScFactory"; "has_mpi"; "down_cast";
   "differentiation"; "Mesh"; "has_scotch"; "rot"; "has_slepc"; "DOLFIN_PI";
   "begin"; "le"; "outer"; "VectorElement"; "parameters"; "ln";
   "uBLASVector"; "uBLASDenseMatrix"; "tr"; "Assembler"; "terminal";
   "UnitCube"; "lt"; "CRITICAL"; "hermite"; "derivative"; "logger";
   "uBLASDenseFactory"; "norm"; "MPI"; "info"; "triangle"; "R1"; "R2";

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping var_args, or C ... in ocaml?

2010-02-14 Thread Guillaume Yziquel

Richard Jones a écrit :

On Sun, Feb 14, 2010 at 11:46:10PM +0100, Guillaume Yziquel wrote:

Not the case.

[etc]

It would help if you were to be more specific about the function that
you're trying to bind.


http://docs.python.org/c-api/arg.html

There's quite a few there...

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping var_args, or C ... in ocaml?

2010-02-14 Thread Guillaume Yziquel

Richard Jones a écrit :

On Sun, Feb 14, 2010 at 04:46:20PM +0100, Guillaume Yziquel wrote:

Hello.

I'm currently looking at:

http://docs.python.org/c-api/arg.html

and I would like to know how to wrap up C functions with va_list of with 
an ellipsis. Is this documented somewhere, or has someone already done 
something like this?


It really depends on the function and how it will be used.  It
might translate to any of:

(1) A collection of functions implementing different aspects of the C
function.  eg. The open(2) function in Unix is really a varargs
function, and depending on whether you want to open a file for input,
output, create, etc. you'd probably be better off with different
functions in OCaml.  (Unix.openfile does _not_ do this ...)


Not the case.


(2) A simple list, eg. for a C function that takes a NULL-terminated
list of strings.


Could be.


(3) A variant list of variants, or option labels, eg. for a C function
that takes 'type, value'(s), such TIFFSetField in
libtiff. (http://www.remotesensing.org/libtiff/man/TIFFSetField.3tiff.html)


No.


(4) Something very specialized, eg. the 'printw' function in ncurses
is like printf and so would need quite a tricky implementation in
OCaml.  (Probably best to use ksprintf to convert to a string in OCaml
and then pass printw ("%s", str) in C).


I do not think so.


In libguestfs where we autogenerate bindings we avoided varargs
altogether, because it's hard to map such a concept to all the
different languages we support.


True.

But, I mean, from the point of view of the ABI, there's not much 
trickery in the concept. It looks that it is C that is not mapping the 
concept to its fullest potential.


I mean, it seems that varargs means on the receiving end "the number of 
arguments you'r giving me, as a function, is not limited", whereas on 
the sending end, you hard-code the number of arguments in your C code.


Is there a way to map an OCaml list to an ellipsis? Or is it a C limitation?

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping var_args, or C ... in ocaml?

2010-02-14 Thread Guillaume Yziquel

Hello.

I'm currently looking at:

http://docs.python.org/c-api/arg.html

and I would like to know how to wrap up C functions with va_list of with 
an ellipsis. Is this documented somewhere, or has someone already done 
something like this?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] [ANN] OCaml-R binding for the R language.

2010-02-12 Thread Guillaume Yziquel

This post is to announce the 0.2 release of OCaml-R.

OCaml-R is a binding embedding the R interpreter into Objective Caml code.

Home page: http://home.gna.org/ocaml-r/
Download page: http://download.gna.org/ocaml-r/
Deb packages: http://yziquel.homelinux.org/debian/pool/main/o/ocaml-r/
Tutorial: http://home.gna.org/ocaml-r/gettingstarted.en.html
OCamlDoc API: http://yziquel.homelinux.org/topos/api/ocaml-r/index.html
  http://home.gna.org/ocaml-r/refdoc/index.html

The goal of OCaml-R is to provide adequate integration of the R 
interpreter into Objective Caml, and a framework suitable to bind R 
library into OCaml code.


Version 0.2 is a near-complete rewrite of the 0.1 version by Maxence 
Guesdon, with an incompatible API. Main features are:


- Safe handling of R default environment variables at compile time, 
following what is done in littler.

- R Signal handlers do not conflict with OCaml code.
- Integration with findlib, enabling the #require "R.interpreter" to 
initialise statically the R interpreter. Compiling with 'ocamlfind 
ocamlopt -package R.interpreter' also initialises the R interpreter at 
compile-time, so to speak.

- Some (most?) functionalities of the R standalone library are wrapped.
- Low-level binding, in the sense that you construct low-level R calls 
to execute them. You can also parse R code to execute it, if you wish.

- R exceptions are chained back to Objective Caml.
- R's garbage collector is chained with OCaml's garbage collector. This 
is done rather inefficiently for the moment (freeing n R values in 
O(n^2) time complexity), and we expect to bring this down to O(n) with a 
thin garbage collecting layer in the future.
- We provide a double typing scheme, with some subtyping features. A 
first typing mimics the dynamic typing of the R language, while a second 
typing, for the end-user, aims at providing a static typing of R values 
and functions. (This can be bettered).
- S3 classes are supported (static typing is however still 
unsatisfying). S4 classes are not yet supported. Help welcome.
- Some basic R datatypes, such as dataframes, are wrapped, and a 
framework to wrap the standard library has been put in place.
- Basic data structures can be converted back and forth between OCaml 
and the R interpreter.
- Ability to inspect (read-only) the inner structure of R values, which 
is quite convenient: you get to know rather quickly what a given piece 
of R code returns, which you need to know to type R code statically in 
order to bind it to OCaml.
- Not thread-safe at all. At least, not more than R is... Lwt-style 
multithreading of R code could be possible, modulo some simple and deep 
(i.e. below R API) changes in the R evaluation functions. POSIX 
threading a single R thread with multiple OCaml threads is not yet 
possible, but is within reach.

- Doesn't interact well the R "Defaults" package.

While most of the code sticks or could stick to the R API, or at least 
to the public part of the R headers, there are some functionalities 
which are outright out of the scope of the R API. Some of these 
functionalities are for convenience only (i.e. inspecting internals of R 
values), while others are crucial to the binding (chaining R exceptions 
to OCaml).


Hopefully, this lays down a foundation on which one could import R 
functionalities, libraries and packages to OCaml.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] define incompatible type

2010-02-12 Thread Guillaume Yziquel

David Allsopp a écrit :

David Rajchenbach-Teller wrote:

 Hi Grégoire,
 It's not directly possible in OCaml, but there are at least three methods

for doing what you

want.

The first one is to wrap your integers behind a constructor, e.g.




You can also use (post OCaml 3.11.0) private types if you want to be able to
use the ID values as integers but only explicitly.


Private types is indeed the way to go.

For instance, imagine that you have value wrapping C pointers. You may 
want to declare something like:



type pointer
type type_1 = private pointer
type type_2 = private pointer


When you write your code, you essentially use only types type_1 and 
type_2. The type inference system won't look into the "private" part of 
the type, so the type checker will cough on something like



function (x : type_1) (y : type_2) -> x = y


But, you can subtype (i.e. use :> to tell the typechecker to use the 
private declaration). And this will be valid OCaml:



function (x : type_1) (y : type_2) -> (x :> pointer) = (y :> pointer)


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] debugging in toplevel

2010-02-10 Thread Guillaume Yziquel

Hi.

I've been working on Yoann Padioleau's version of ocaml-python bindings.

I unfortunately get the following error:


yziq...@seldon:~$ ocaml
Objective Caml version 3.11.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;  to load a package
  #list;;   to list the available packages
  #camlp4o;;to load camlp4 (standard syntax)
  #camlp4r;;to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();; to force that packages will be reloaded
  #thread;; to enable threads

- : unit = ()
# #require "python";;
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/str.cma: loaded
/usr/lib/ocaml/python: added to search path
/usr/lib/ocaml/python/pycaml.cma: loaded
Exception: Invalid_argument "index out of bounds".
# 


How do you debug something like this? ocamldebug and #trace do not seem 
to be very useful. What would you recommend doing to debug this toplevel 
error?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] The need to specify 'rec' in a recursive function defintion

2010-02-09 Thread Guillaume Yziquel

Gerd Stolpmann a écrit :

Am Dienstag, den 09.02.2010, 22:58 +0100 schrieb Guillaume Yziquel:

Gerd Stolpmann a écrit :

Am Dienstag, den 09.02.2010, 15:50 -0500 schrieb Saptarshi Guha:

Besides the different way of defining "let" and "let rec" there are also
differences in typing.


Well, at least you can have new effects. Look for "polymorphic
recursion".


You mean something like this?

http://alaska-kamtchatka.blogspot.com/2009/05/polymorphic-recursion.html

With the following code


type length = { length : 'a . int -> 'a vec -> int }

let length v =
  let rec f = { length = fun n l -> match l with
Nil -> n
  | Zerops  -> f.length (2 * n) ps
  | One (_, ps) -> f.length (1 + 2 * n) ps
  } in f.length 0 v


you get to use a function, here f.length, in two different contexts for 
type inference, allowing it to be used with multiple types? 'a * 'a 
instead of 'a? Am I getting this post right?


But then, this seems to go into rather elaborate constructions 
(existential types with OCaml records), which are quite remote from the 
simple 'let rec' issue we were talking about.


Is it possible to have polymorphic recursion with vanilla 'let rec' 
invocations? Or am I getting you wrong?


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] The need to specify 'rec' in a recursive function defintion

2010-02-09 Thread Guillaume Yziquel

Gerd Stolpmann a écrit :

Am Dienstag, den 09.02.2010, 15:50 -0500 schrieb Saptarshi Guha:

Besides the different way of defining "let" and "let rec" there are also
differences in typing.


Which ones?


Gerd


--
     Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] The need to specify 'rec' in a recursive function defintion

2010-02-09 Thread Guillaume Yziquel

Saptarshi Guha a écrit :

Hello,
 I was wondering why recursive functions need to be specified with
"rec". According to Practical Ocaml, to "inform the compiler that the function
exists". But when entering the function definition, can't the compiler note that
the function is being defined so that when it sees the function calling itself,
it wont say "Unbound value f"?


Essentially, the fact that "rec" means anything is mostly due to the 
fact that you want to be able to redefine stuff.



let f = fun x -> x + 1

let f x = f (f x)


is valid in ocaml, and you're function f is the function that adds 2.

whereas


let rec f x = f (f x)


has a completely different meaning.

If you avoided the use of rec, saying "if unbound, assume rec", then the 
line


let f x = f (f x)

has two entirely different meaning, depending on whether f is defined 
before or not.


That would be quite a chaotic feature.


Wouldn't one of way of detecting a recursive function would be to see
if the indeed the function calls itself?


No. Because you never know if you intended to call the function 
recursively, or if you intended to call an homonymous function you 
defined before.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] camlp4

2010-02-09 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Tiphaine Turpin a écrit :

Andy Ray a écrit :

What should one do?
  

Complaining on the list about lack of camlp4 documentation is a good
start :-). To help you decide (and increase the pressure on the Ocaml
team), I would like to mention some of the difficulties that I
encountered when trying to understand camlp4 as a user:


-2- A good hands-on introduction, to be read in conjunction with 
up-to-date camlp4 code:


http://martin.jambon.free.fr/extend-ocaml-syntax.html


http://ambassadortothecomputers.blogspot.com/search/label/camlp4

is also a good link, covering the essentials to get started with camlp4, 
I think.



--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Re: How to wrap around C++?

2010-02-08 Thread Guillaume Yziquel

Luca de Alfaro a écrit :

Thank you very much!  I follow the general lines, but...


* Wrap your OCaml includes in 'extern "C" { ... }"


Here, I am not sure what you mean.  You mean,

extern "C" {
#include 
...
}

?


See the code in my email:


  /* Including OCaml system. */
  #define CAML_VALUE value
  extern "C" {
#include 
#include 
#include 
#include 
#include 
#include 
#include 
  }


on one hand, and


extern "C" CAML_VALUE _wrap_tokenizer_tokenize (CAML_VALUE ocaml_arg1, 
CAML_VALUE ocaml_arg2)
{
  CAMLparam0();
  SWIG_CAMLlocal1(caml_result);
  tokenizer *arg1 = (tokenizer *) 0 ;
  std::string *arg2 = 0 ;
  CAMLxparam1(ocaml_arg1);
  CAMLxparam1(ocaml_arg2);
  std::list< word > result;
  
  arg1 = *((tokenizer * *) Data_custom_val(ocaml_arg1)); 
  {

std::string arg2_str(String_val(ocaml_arg2), 
caml_string_length(ocaml_arg2));
arg2 = &arg2_str;
  }
  result = (arg1)->tokenize((std::string const &)*arg2);
  {
caml_result = caml_alloc_custom(&custom_swigtype_ocaml_operations, sizeof 
(void *), 0 ,1);
*((void **) Data_custom_val(caml_result)) = new std::list< word >((const 
std::list< word > &)result);
  }
  CAMLreturn(caml_result);
}


on the other...


* Export all your stub functions with C linkage (extern "C")


Ok, evidently, I need to learn this extern "C" construct.


Yes. It's essentially here to cope with C++ name mangling.


* Compiling is tricky, since the OCaml compiler driver doesn't know what
to do with C++.  The Swig documentation[1] has a workaround for this,
useful even if you don't use Swig.


Why would the Ocaml compiler driver need to know what to do with C++?


Because it knows how to compile C, but doesn't know how to compile C++.


The C++ I need to link to is rather huge, and I will need to compile it with
its own build setup.


Compile your C++ on one hand as you usually would. No issue there. You 
could even wrap a .so file generated from C++ code without knowing 
anything about the source code of the .so file. OK, except headers, and 
vendor info and version info of your C++ compiler.


But, you have to compile the C glue as above with extern "C" and the 
trick I gave you in the Makefile, which btw come from the Swig website.



Once that is built, I need to compile the stubs, the Ocaml, and link the
three together (Ocaml, stubs, and C++), in native mode, but  why would the
Ocaml compiler need to deal with C++?


The OCaml compiler does not deal with C++. It only knows about C.

It's the C stub that need to:

-1- be linked in OCaml code, and therefore, no C++ name mangling 
exported from these C stubs, hence the export "C".


-2- be linked with C++ code. Hence the C++ code within the Extern "C" 
brackets.



Another question: I could also try to do the vice-versa, and use Ocaml as
libraries from C++.  Has anybody tried doing this?  Is it easy to do?


I would stick with embedding C++ code into OCaml than the reverse. It's 
likely that you'd get more answers this way.



Luca


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Re: How to wrap around C++?

2010-02-08 Thread Guillaume Yziquel

Luca de Alfaro a écrit :

I am trying another approach... it might make more sense for me to embed the
Ocaml into C++.


This is not the way you'll get the most help out of this list. People 
are more familiar with making C bindings. Making C++ bindings is rather 
close to it.



I have read the instructions, and it seems feasible, except that I have a
few questions:

   - All I need to pass, as arguments, are int, float, string, and arrays of
   these.  Any example of how to deal with the arrays?


You need to construct them from C side, and it's more a pain than taking 
C structs and wrapping them into OCaml.


The manual describes the structure of OCaml values rather precisely. 
There are also some pages by Richard Jones on his blog which explain 
rather nicely the internals of OCaml values. One advice: stick to the 
macros provided. Do not try to construct manually, say, OCaml strings on 
the C side. Use caml_copy_string and friends.



   - How can I return arrays, in a way that C or C++ understands?  How can I
   return tuples, i.e., how can I return multiple values from Ocaml to C?


These are documented in the manual and in Richard Jones' blog.

For couples, you can do


value couple = caml_alloc(2, 0);
Store_field(couple, 0, my_ocaml_val);
Store_field(couple, 1, my_other_ocml_val);


For arrays, you'll have seamless integration by using Bigarrays.


   - Finally, do I need to worry about the Ocaml garbage collector, if I
   call Ocaml from C/C++?  Will it run every now and then? How can the garbage
   collector know whether a value returned by an Ocaml function is still being
   used in C/C++?  How can I tell it that it is no longer used?


Essentially, the garbage collector will run potentially each time you 
allocate an OCaml value. caml_copy_string? the GC may run.


You have to register values being used on the C side as a GC root. It's 
easier and more documented to do it the other way round by calling C++ 
from OCaml.



The problem I am trying to solve seems to be a can of worms from whichever
angle I take it...


No.

The solution I proposed with Swig is very verbose, but it is a clean 
solution if you do it manually.


You have Makefile compilation instructions to compile C++ with OCaml 
(the main issue with C++ and the extern "C" is essentially the name 
mangling of symbols provided by your C++ object files. All the rest is 
pretty similar to C. This is really the *main* point).


You have at the end of my last email and example of how to construct an 
object and feed it back to OCaml. It may not be really clean, it lacks 
finalisers, but these last two points are stuff that you're going to 
have to deal with anyway if you're going with the OCaml/C interface. 
Look up "custom blocks" and finalisation in the OCaml manual section 
concerning the C interface.



Luca


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] How to wrap around C++?

2010-02-08 Thread Guillaume Yziquel
   CAML_VALUE x = 0, y = 0; \
CAMLxparam2 (x, y)

  #define SWIG_CAMLlocal3(x, y, z) \
CAML_VALUE x = 0, y = 0, z = 0; \
CAMLxparam3 (x, y, z)

  #define SWIG_CAMLlocal4(x, y, z, t) \
CAML_VALUE x = 0, y = 0, z = 0, t = 0; \
CAMLxparam4 (x, y, z, t)

  #define SWIG_CAMLlocal5(x, y, z, t, u) \
CAML_VALUE x = 0, y = 0, z = 0, t = 0, u = 0; \
CAMLxparam5 (x, y, z, t, u)

  #define SWIG_CAMLlocalN(x, size) \
CAML_VALUE x [(size)] = { 0, /* 0, 0, ... */ }; \
CAMLxparamN (x, (size))



  /* Declarations for custom block operations. */

  /* For more information of Objective Caml custom blocks,
   * consult the Objective Caml manual, section 18.9. */

  static struct custom_operations custom_swigtype_ocaml_operations = {
"org.homelinux.yziquel.ocaml.swig",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default
  };



#define SWIGVERSION 0x010340 
#define SWIG_VERSION SWIGVERSION



#define SWIG_as_voidptr(a) (void *)((const void *)(a)) 
#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) 



  #include "freeling.h"


#include 


#if defined(__GNUC__)
#  if __GNUC__ == 2 && __GNUC_MINOR <= 96
# define SWIG_STD_NOMODERN_STL
#  endif
#endif


#include 
#include 


  #include 


  #include 

extern "C" CAML_VALUE _wrap_new_tokenizer (CAML_VALUE ocaml_arg1)
{
  CAMLparam0();
  SWIG_CAMLlocal1(caml_result);
  std::string *arg1 = 0 ;
  CAMLxparam1(ocaml_arg1);
  tokenizer *result = 0 ;
  
  {

std::string arg1_str(String_val(ocaml_arg1), 
caml_string_length(ocaml_arg1));
arg1 = &arg1_str;
  }
  result = (tokenizer *)new tokenizer((std::string const &)*arg1);
  {
caml_result = caml_alloc_custom(&custom_swigtype_ocaml_operations, sizeof 
(void *), 0, 1);
*((void **) Data_custom_val(caml_result)) = (void *)result;
  }
  CAMLreturn(caml_result);
}

extern "C" CAML_VALUE _wrap_tokenizer_tokenize (CAML_VALUE ocaml_arg1, 
CAML_VALUE ocaml_arg2)
{
  CAMLparam0();
  SWIG_CAMLlocal1(caml_result);
  tokenizer *arg1 = (tokenizer *) 0 ;
  std::string *arg2 = 0 ;
  CAMLxparam1(ocaml_arg1);
  CAMLxparam1(ocaml_arg2);
  std::list< word > result;
  
  arg1 = *((tokenizer * *) Data_custom_val(ocaml_arg1)); 
  {

std::string arg2_str(String_val(ocaml_arg2), 
caml_string_length(ocaml_arg2));
    arg2 = &arg2_str;
  }
  result = (arg1)->tokenize((std::string const &)*arg2);
  {
caml_result = caml_alloc_custom(&custom_swigtype_ocaml_operations, sizeof 
(void *), 0 ,1);
*((void **) Data_custom_val(caml_result)) = new std::list< word >((const 
std::list< word > &)result);
  }
  CAMLreturn(caml_result);
}



--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] camlp4 unbound value

2010-02-08 Thread Guillaume Yziquel

Hi. This is for camlp4 gurus:

I've been using a modified version of Mauricio Fernandez' relational 
algebra camlp4 extension for postgresql. (I'm trying to adapt it to 
another database system, so I've functorised a bit of the original code).


You can find the modified code and a Debian package at:

http://yziquel.homelinux.org/debian/pool/main/o/ocaml-relational/
http://yziquel.homelinux.org/gitweb?p=ocaml-relational.git;a=summary

My question is the following: Relational.Conv_Postgresql.encode_int is 
properly defined, and available from the toplevel, and yet considered 
unbound in the camlp4-generated code.


How can this be?



yziq...@seldon:~$ ocaml
Objective Caml version 3.11.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;  to load a package
  #list;;   to list the available packages
  #camlp4o;;to load camlp4 (standard syntax)
  #camlp4r;;to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();; to force that packages will be reloaded
  #thread;; to enable threads

- : unit = ()
# #thread;;
/usr/lib/ocaml/threads: added to search path
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/threads/threads.cma: loaded
# #camlp4o;;
/usr/lib/ocaml/dynlink.cma: loaded
/usr/lib/ocaml/camlp4: added to search path
/usr/lib/ocaml/camlp4/camlp4o.cma: loaded
Camlp4 Parsing version 3.11.1

# #require "relational.postgresql";;
/usr/lib/ocaml/pcre: added to search path
/usr/lib/ocaml/pcre/pcre.cma: loaded
/usr/lib/ocaml/netsys: added to search path
/usr/lib/ocaml/netsys/netsys.cma: loaded
/usr/lib/ocaml/netstring: added to search path
/usr/lib/ocaml/netstring/netstring.cma: loaded
/usr/lib/ocaml/netstring/netstring_mt.cmo: loaded
/usr/lib/ocaml/netstring/netstring_top.cmo: loaded
/usr/lib/ocaml/netstring/netaccel.cma: loaded
/usr/lib/ocaml/netstring/netaccel_link.cmo: loaded
/usr/lib/ocaml/relational: added to search path
/usr/lib/ocaml/relational/relational.cma: loaded
/usr/lib/ocaml/postgresql: added to search path
/usr/lib/ocaml/postgresql/postgresql.cma: loaded
/usr/lib/ocaml/relational/pa_relational.cmo: loaded
/usr/lib/ocaml/relational/pa_relational_postgresql.cmo: loaded
# TABLE user users COLUMN id SERIAL AUTO PRIMARY KEY END;;
Error: Unbound value Relational.Conv_Postgresql.encode_int
# module X = Relational.Conv_Postgresql;;
module X :
  sig
val encode_string : string -> string
val decode_string : string -> string
val decode_bool : string -> bool
val encode_bool : bool -> string
val encode_int : int -> string
val decode_int : string -> int
val encode_float : float -> string
val decode_float : string -> float
val encode_nullable : ('a -> string) -> 'a option -> string
val decode_timestamp : string -> float
val decode_timestampz : string -> float
val encode_timestamp : float -> string
val encode_timestampz : float -> string
val decode_time : string -> float
val decode_timez : string -> float
val encode_time : float -> string
val encode_timez : float -> string
val decode_date : string -> Relational.Types.date
val encode_date : Relational.Types.date -> string
  end
# Relational.Conv_Postgresql.encode_int;;
- : int -> string = 
# 


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] camlp4

2010-02-06 Thread Guillaume Yziquel

Tiphaine Turpin a écrit :

Andy Ray a écrit :

What should one do?
  

Complaining on the list about lack of camlp4 documentation is a good
start :-). To help you decide (and increase the pressure on the Ocaml
team), I would like to mention some of the difficulties that I
encountered when trying to understand camlp4 as a user:


I fully agree. I've been working on understanding Camlp4 recently to 
handle one of Mauricio Fernandez' library on relational algebras.


You can, eventually, if you take time, get to understan how everything 
works out. But that involves a lot of trial and error, and I still 
believe I do not have the full picture in mind.


I'd just keep two things in mind concerning camlp4:

-1- It's not hugely different from Camlp5. It is different, but not 
hugely, at least from the newcommer's point of view. So my advice is 
simply to work on an existing camlp4 extension, and to try groking with 
existing camlp5 documentation, while doing trials and errors the whole 
way long. It is painful, but it's doable.


-2- A good hands-on introduction, to be read in conjunction with 
up-to-date camlp4 code:


http://martin.jambon.free.fr/extend-ocaml-syntax.html

Now, if someone, or a group of people, has the courage to update 
Martin's page to the current camlp4, that would be hugely helpful: I'm 
pretty sure there's quite a lot of people willing to use camlp4 that are 
simply laid back by the lack of documentation.


Concerning the functorial design of the source code of camlp4, I fully 
agree with Tiphaine. It is probably a good design choice, and when you 
get to study it closely, it is quite remarkably done. However, a *huge* 
pain to read and to navigate through.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] mlsize_t and size_t.

2010-02-03 Thread Guillaume Yziquel

Hi.

I've been wanting to wrap a size_t value to ocaml. I therefore have a 
few questions about this:


-1- What is the rationale that makes OCaml uses an mlsize_t instead of 
size_t? On Linux platforms, it seems that both are unsigned long ints.


-2- would a 'type size = private nativeint' do the trick?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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 debugging.

2010-01-23 Thread Guillaume Yziquel

Hello.

I've been trying to reuse the mlgame codebase, and I've encountered a 
weird issue. When linked into native code or into bytecode, the library 
works fine, and the system exits with a 0 errorlevel.


However, when trying to #require the package from the toploop, I get the 
following error.



yziq...@seldon:~/git/mlgame$ ocaml
Objective Caml version 3.11.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;  to load a package
  #list;;   to list the available packages
  #camlp4o;;to load camlp4 (standard syntax)
  #camlp4r;;to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();; to force that packages will be reloaded
  #thread;; to enable threads

- : unit = ()
# #require "mlgame";;
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/bigarray.cma: loaded
/usr/lib/ocaml/sdl: added to search path
/usr/lib/ocaml/sdl/sdl.cma: loaded
/usr/lib/ocaml/sdl/sdlloader.cma: loaded
/usr/local/lib/ocaml/3.11.1/mlgame: added to search path
/usr/local/lib/ocaml/3.11.1/mlgame/mlgame.cma: loaded
[Debug][Video] Driver: x11 Hardware: false HWBlit: false HWBlitCK: 
false WHBlitAlpha: false HWFill: false Mem: 0

# Fatal error: exception Sys_blocked_io
yziq...@seldon:~/git/mlgame$ 


I am wondering how to use a debugger with libraries in the toplevel. As 
/usr/bin/ocaml is bytecode and that the exception is raised from OCaml 
and not from C code, I do not have a backtrace:



yziq...@seldon:~$ gdb --args ocamlrun /usr/bin/ocaml
GNU gdb (GDB) 7.0-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show 
copying"

and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/ocamlrun...(no debugging symbols 
found)...done.

(gdb) run
Starting program: /usr/bin/ocamlrun /usr/bin/ocaml
[Thread debugging using libthread_db enabled]
Objective Caml version 3.11.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;  to load a package
  #list;;   to list the available packages
  #camlp4o;;to load camlp4 (standard syntax)
  #camlp4r;;to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();; to force that packages will be reloaded
  #thread;; to enable threads

- : unit = ()
# #require "mlgame";;
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/bigarray.cma: loaded
/usr/lib/ocaml/sdl: added to search path
/usr/lib/ocaml/sdl/sdl.cma: loaded
/usr/lib/ocaml/sdl/sdlloader.cma: loaded
/usr/local/lib/ocaml/3.11.1/mlgame: added to search path
/usr/local/lib/ocaml/3.11.1/mlgame/mlgame.cma: loaded
[New Thread 0x734c0910 (LWP 32029)]
[Debug][Video] Driver: x11 Hardware: false HWBlit: false HWBlitCK: 
false WHBlitAlpha: false HWFill: false Mem: 0

# Fatal error: exception Sys_blocked_io
[Thread 0x734c0910 (LWP 32029) exited]

Program exited with code 02.
(gdb) bt
No stack.
(gdb) 


My humble guess is that there is a IO conflict with the toplevel's 
interactive write/read on stdin/stdout, but I'd like to know how to 
trace that.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] porter's stemmer implementation

2010-01-17 Thread Guillaume Yziquel

Yoann Padioleau a écrit :

On Jan 16, 2010, at 11:01 PM, Grégoire Seux wrote:

There is one in nltk, a very complete python library for NLP and there is
ocamlpython to link ocaml and python code. As the stemmer interface is
very simpler (string -> string), it's very easy to use ocamlpython to do that.

open Pycaml

module Py = Python 
let modul = Py.cpr (Pycaml.pyimport_importmodule "nltk_ocaml")

let dict = Py.cpr (Pycaml.pymodule_getdict modul)

let stem s = 
  let py_str = Pycaml.pystring_fromstring s in

  let f = Py.cpr (Pycaml.pydict_getitemstring(dict, "stem")) in
  let args = Py.cpr (Pycaml.pytuple_fromsingle py_str) in
  let res = Py.cpr (Pycaml.pyeval_callobject (f,args)) in
  Pycaml.guarded_pystring_asstring res


I'm afraid I do not understand where you get your Python module from and 
you Py.cpr value from. I get from the Debian pycaml package:


# #require "pycaml";;
/usr/lib/ocaml/unix.cma: loaded
/usr/lib/ocaml/pycaml: added to search path
/usr/lib/ocaml/pycaml/pycaml.cma: loaded
# module X = Python;;
Error: Unbound module Python
# module X = Pycaml.Python;;
Error: Unbound module Pycaml.Python
# module X = Pycaml;;
module X :
  sig
type funcptr = Pycaml.funcptr
type pyobject = Pycaml.pyobject
type funcent = funcptr * int * int
type pymodule_func =
  Pycaml.pymodule_func = {
  pyml_name : string;
  pyml_func : pyobject -> pyobject;
  pyml_flags : int;
  pyml_doc : string;
}
type pyobject_type =
  Pycaml.pyobject_type =
TupleType
  | StringType
  | IntType
  | FloatType
  | ListType
  | NoneType
  | CallableType

Where did you get your pycaml from?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] GPL with linking exception?

2010-01-17 Thread Guillaume Yziquel

Stefano Zacchiroli a écrit :

On Sun, Jan 17, 2010 at 05:47:10PM +0100, Guillaume Yziquel wrote:

Well, you create a bytecode executable under GPL. You therefore
include the OCaml bytecode runtime.


Uh? Why "therefore"?


Because I was indeed thinking of -custom when talking about "executable"...


If you just distribute the bytecode (no -custom compilation involved),
you will be not distributing the OCaml runtime with it, just your own
program compiled to bytecode.


Is it the only issue with the GPL? If that's the only issue, then it's 
perfectly fine with me...


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] GPL with linking exception?

2010-01-17 Thread Guillaume Yziquel

Dario Teixeira a écrit :

Hi,


My question about GPL is mostly the following: Can you
distribute GPL bytecode files? Do you have any issues when
'linking' the runtime with the GPL bytecode?

Or are there other issues preventing from releasing GPL OCaml code?


If you want a waterproof lawyerly response you should consider contacting
an organisation like the Software Freedom Law Center [1].  Nevertheless,
IMHO I see no obstacle in using the GPL with Ocaml code, and there are
in fact plenty of Ocaml projects using this license.  Could you elaborate
on why you feel that the GPL could in theory prevent the release of Ocaml
code?


Well, you create a bytecode executable under GPL. You therefore include 
the OCaml bytecode runtime. You'd be distributing part of the bytecode 
runtime under the GPL, and I somehow feel there's a fish in doing so.


This is just a question I'm asking myself. I do not have a hard opinion 
on that. Im just asking to collect advice from people on this list who 
might have wondered the same kind of things. That's all.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] C++ parser

2010-01-17 Thread Guillaume Yziquel

Kihong Heo a écrit :

Dear all.

Is there anybody knowing about existing C++ parser that is not so big?

I've already know EDG and ELSA.
But they are so big and hard to see. 
I don't want a perfect C++ parser.

If it can parse common and simple C++, that's OK.


The perfect C++ parser: GCC XML. I thing that there is an OCaml binding 
to it.


Otherwise, depending on what you want to do, there is Swig. It parses 
only C++ declarations.



I need your advice.


For a new project, I'd use GCC XML.


Thank you.
--
Kihong Heo.


All the best,

--
     Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] GPL with linking exception?

2010-01-17 Thread Guillaume Yziquel

Dario Teixeira a écrit :

Hi,


I've been looking around on the net to see if I could find
a GPL3 + linking exception copyright notice lying around. I
only found LGPL + linking exception.

Does anyone know what to write for GPL3 + linking
exception? Is it even possible, or is only LGPL + linking
exception possible?


IANALNDIPOOTV (I am neither a lawyer nor do I play one on TV), but I'm
under the impression that the  linking exception only makes sense to
appease the requirements of LGPL.  The LGPL requires that the main binary
may be used with an updated version of the LGPL library, which in most
cases implies some form of dynamic linking.  However, this conflicts
with the most common way of building Ocaml programs, where all Ocaml
libraries are statically linked into the main executable.  Hence the
need for a linking exception, which relaxes the LGPL requirement.  If,
on the other hand, the library is GPL, then all source code is available
(library + main), which renders this point moot.

Best regards,
Dario Teixeira


I acknowledge that you are not a lawyer, nor that you play one on TV.

To my understanding the LGPL requires that you be able to replace the 
LGPL'd library by another library (including an updated version of the 
library). To this extent, it (very roughly and very quickly) imposes 
conditions on the stub code interfacing the two libraries, and you need 
to be able to reproduce the compilation steps. Very roughly... I'm not a 
lawyer either. Nor do I play one on TV.


I do not believe (but I may be mistaken) that this conflicts with the 
static linkage of the main executable. But if you have the ocaml runtime 
getting linked in some way or the other, then the LGPL becomes somehow 
not very handy. Is this the main reason?


My question about GPL is mostly the following: Can you distribute GPL 
bytecode files? Do you have any issues when 'linking' the runtime with 
the GPL bytecode?


Or are there other issues preventing from releasing GPL OCaml code?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] GPL with linking exception?

2010-01-17 Thread Guillaume Yziquel

Hello.

I've been looking around on the net to see if I could find a GPL3 + 
linking exception copyright notice lying around. I only found LGPL + 
linking exception.


Does anyone know what to write for GPL3 + linking exception? Is it even 
possible, or is only LGPL + linking exception possible?


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Controlling module loading order.

2010-01-15 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Gerd Stolpmann a écrit :

Hi Guillaume,

if you want to control from findlib that a certain function is invoked,
the usual way to do it is to put a .cmo/.cmx file into the "archive"
variables. The problem is that the linker drops all unused modules
from .cma/.cmxa archives, and as a consequence the initialization code
of these modules is not executed. So you could make R.interpreter
a .cmo/.cmx - in this case the module is always initialized.


Thank you so much!


Just a complementary remark: when using a .cmo instead of a .cma, one 
should ship a .o file in place of the .a file. For the sake of exhaustivity.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-11 Thread Guillaume Yziquel

ygrek a écrit :

On Sat, 09 Jan 2010 20:36:07 +0100
Guillaume Yziquel  wrote:

So if I want to call R code that multithreads with OCaml, I should write 
something like



  enter_blocking_section();
  PROTECT(e = R_tryEval(Sexp_val(sexp_list), R_GlobalEnv, &error));
  UNPROTECT(1);
  leave_blocking_section();

Am I correct?


I bet no. It is not safe to access block ocaml value
inside blocking_section. In this particular case Sexp_val(v) is Field
(v,0) whis in turn is v[0] or *v. So you read the pointer, then in
another thread GC moves things around and old copy of the pointed
value is overwritten, then you read the value through 
the old pointer and get garbage.

Put Sexp_val call before caml_enter_blocking_section().


OK. Thanks



--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Controlling module loading order.

2010-01-11 Thread Guillaume Yziquel

Gerd Stolpmann a écrit :

Hi Guillaume,

if you want to control from findlib that a certain function is invoked,
the usual way to do it is to put a .cmo/.cmx file into the "archive"
variables. The problem is that the linker drops all unused modules
from .cma/.cmxa archives, and as a consequence the initialization code
of these modules is not executed. So you could make R.interpreter
a .cmo/.cmx - in this case the module is always initialized.


Thank you so much!


The other workaround is to provide an init function in R.interpreter
like

let init() = ()

By calling this function the user references the interpreter, and all
the initialization code is executed.


That's exactly what I want to avoid.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-11 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

So if I want to call R code that multithreads with OCaml, I should write
something like


 enter_blocking_section();
 PROTECT(e = R_tryEval(Sexp_val(sexp_list), R_GlobalEnv, &error));
 UNPROTECT(1);
 leave_blocking_section();

Am I correct?


Yes, but the functions have now a caml_ prefix.

Make sure that there is no interaction whatsoever with ocaml's runtime
system (e.g. ocaml value allocation) between the two calls.


I will have interaction, because I plan to be able to make R call OCaml 
code (not in the foreseeable future). But it's just a question of 
wrapping the call back to Ocaml with a


caml_leave_blocking_section()
callingOCamlcode()
caml_enter_blocking_section()

construct. As far as I've understood.


Note also that in case you need to use some caml value after the leave
call you have to declare it with a CAMLparam macro as it may move
during the blocking section even if the stub itself doesn't allocate.


Very helpful. Thanks a lot.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-11 Thread Guillaume Yziquel

Gerd Stolpmann a écrit :


Would it be legitimate to include CAMLlocal2 inside the error-handling 
braces?


No. You would start a new context for local roots, and there is no way
to end it (CAMLreturn ends the context).

There are the macros Begin_roots and End_roots that should be used in
this case, e.g.

if (error) {
  value ml_error_call = Val_unit;
  value ml_error_message = Val_unit;

  Begin_roots2(ml_error_call, ml_error_message);
  ...
  End_roots();

  raise_with_arg(...)
}


End_roots before caml_raise_with_arg? Why not after?

I mean, you do not do a CAMLreturn before a caml_raise_with_args, so why 
should't this be the same for End_roots()?



The macros are only documented in memory.h.

So far I know, raising an exception from within Begin_roots/End_roots is
not allowed.


It seems to me that the major issue is how caml_local_roots gets 
restored. With the CAMLparam/CAMLreturn macros, this is done by storing 
its original value in caml__frame and restoring it via CAMLreturn.


As it is written in memory.h


Your function may raise an exception or return a [value] with the
[CAMLreturn] macro.


I assume that caml_local_roots gets restored by a mechanism in the 'try' 
of the 'try / with' construct after the siglongjmp of caml_raise.


Therefore it should be OK to use caml_raise_with_args before End_roots().

Am I right, or is this plainly wild guessing?

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-09 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

Section 2) of this paper also has a very gentle and readable
introduction to the gc :

http://portal.acm.org/citation.cfm?id=141130


Thanks for the link.


Another thing you need to know, if you have long running pieces of C
code that don't interact with ocaml's runtime system, is the two
functions :

caml_enter_blocking_section
caml_leave_blocking_section

They are explained in this message  :

http://caml.inria.fr/pub/ml-archives/caml-list/2001/06/58d7a7e8747056c3842e53b4e9454f44.en.html


OK.

So if I want to call R code that multithreads with OCaml, I should write 
something like



  enter_blocking_section();
  PROTECT(e = R_tryEval(Sexp_val(sexp_list), R_GlobalEnv, &error));
  UNPROTECT(1);
  leave_blocking_section();


Am I correct?

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-09 Thread Guillaume Yziquel

Richard Jones a écrit :


Why is this a problem?  Because you might in your C code have some
value on the stack.  'value' is (or can be) a pointer.  The OCaml
garbage collector can move pointed-to-objects around, firstly from the
minor heap to the major heap, secondly when compacting the major heap.
So your C value (pointer) *could* become an invalid pointer if what it
was pointing to got moved.


Yes, I understood the nature of the problem.


The way to avoid this small chance is to register the value with the
garbage collector, which is essentially what the CAMLparam* and
CAMLlocal* macros do.  So if the GC needs to move that object, it will
update the pointer for you.

If your function never allocates (and never calls anything which
allocates), then you don't need to register values, because no
allocation => they can't be moved.  [In fact there are some other
exceptions as well where you can prove that an allocation won't move
your pointer, eg. if you only allocate one thing and immediately
return the value.]


I've been looking at the pcre bindings, and these bindings make minimal 
usage of CAMLparam, CAMLlocal and CAMLreturn.


For instance, here is the piece of code that executes R code ad catches 
errors. I've tried to follow guidelines available on the net, and 
inspired myself from pcre.



CAMLprim value r_eval_sxp (value sexp_list) {
  CAMLparam0();
  CAMLlocal2(ml_error_call, ml_error_message);
  SEXP e;
  int error = 0;
  PROTECT(e = R_tryEval(Sexp_val(sexp_list), R_GlobalEnv, &error));
  UNPROTECT(1);
  if (error) {
ml_error_call = Val_sexp(error_call);
error_call = NULL;
ml_error_message = caml_copy_string(error_message);
error_message = NULL;
value error_result = caml_alloc_small(2, 0);
Store_field(error_result, 0, ml_error_call);
Store_field(error_result, 1, ml_error_message);
raise_with_arg(*caml_named_value("OCaml-R generic error"), error_result);
  }
  CAMLreturn(Val_sexp(e));
}


Do you see GC / allocation / threading problems with it?

Would it be legitimate to include CAMLlocal2 inside the error-handling 
braces?



You might find my series on the garbage collector interesting if you
want to look into this further:

http://rwmj.wordpress.com/?s=ocaml+internals


These are very interesting. Could not find part 6, though...


Also if you are calling C functions which don't allocate from OCaml
code, you might want to read about noalloc:

http://camltastic.blogspot.com/2008/08/tip-calling-c-functions-directly-with.html


Two comments on this:

-1- I remember a post by Jon Harrop concerning external mathematical 
functions such as the exponential in Pervasives. He was arguing that it 
could be done directly from the .ml file by using such "tags". Where can 
I find a list of all these tags for external functions? There's "float", 
but are there others?


-2- If I understand this post well, the following function


CAMLprim value init_r (value argv, value sigs) {

  /* -1- argv is an OCaml array of strings, which gives the command line
 arguments used to invoke the R interpreter. Code segfaults if
 the array does not contain a first element, which is the name of
 the program, typically "R", or "OCaml-R". Other arguments typically
 are "--vanilla", "--slave"...

 -2- sigs is an OCaml int. When set to 0, R signal handlers are not
 removed. When set to, say, 1, R signal handlers are removed. It is
 very useful to remove signal handlers when embedding R. */

  int length = Wosize_val(argv);
  char* argv2[length];
  int i;

  // We duplicate the OCaml array into a C array.
  for (i=0; i= 2.3.1. */
  if (Int_val(sigs)) R_SignalHandlers = 0;

  // This is the libR.so function.
  i = Rf_initEmbeddedR(length, argv2);

  // Returns 1 if R is correctly initialised.
  return Val_int(i);
}


could be called with "noalloc"?

By the way, here's a question I've been wondering about this section. 
Rule 3: When I have a Abstract_tag block used to wrap a pointer in the C 
heap, it seems to me that you can just do it with a Field(v,0)= 
assignment. Do you need Store_field for that?


This is to do with the Remembered Set.  See part 5 of the above
series.


The remembere set, in this context, explains why I would need 
Store_field when dealing with pure OCaml world. When wrapping pointers 
to the C heap in abstract blocks, I do not see the point of Store_field, 
and it seems to me that Field= assignment is fine. Am I mistaken?


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-09 Thread Guillaume Yziquel

David Allsopp a écrit :

Guillaume Yziquel:


So, no allocation of OCaml values (or in place modification, either, I
guess) implies no need for CAMLparam/CAMLreturn stuff?


Chapter 18 of the manual in Section 18.5 describes pretty much everything you need to know about writing safe stubs that work with the garbage collector.  


Yes. It is all I need to know to write safe stubs. But it does not 
answer the question above. It does state that you do not need 
registration of the result value if there's no allocation going on 
between the moment result get its value and the return statement. But it 
does not say when you can avoid CAMLparam macros.


By the way, here's a question I've been wondering about this section. 
Rule 3: When I have a Abstract_tag block used to wrap a pointer in the C 
heap, it seems to me that you can just do it with a Field(v,0)= 
assignment. Do you need Store_field for that?



I want to understand them so that I can abstract away in some other file
/ .so, some rather usual constructs involving OCaml structures. I think
it is smarter to take some time doing this, with detailed comments all
over, than repeating the same mistakes over and over (or worse:
wondering if you made mistakes) when doing C bindings.


Having written a few C stubs myself, I'd also highly recommend just following 
the manual and not worrying about what the macros do - if you want/need to 
improve allocation performance then you can use the lower-level interface for 
allocation (but that still involves CAMLparamn/CAMLreturn). I usually find that 
tricks like this (think Obj.magic) mean that when something goes wrong, there's 
always a niggling thought in the back of your mind that it's the trick which 
has broken everything when in fact it's something blindly obvious but you waste 
hours double-checking the tricks!


Yes, but it's also quite a pain not to optimise the binding when you're 
trying to bind a columnar database that compiles SQL to its own language 
and tat tries to make the best use of CPU cache. You tend to feel guilty...



In the ideal world, the C written for C stubs would be parsed by a camlp4-like 
pre-processor which would automatically insert the expansion of those macros 
where required. If you have CAMLparamn and CAMLreturn on functions which don't 
strictly need them then you're only creating a few more local roots than are 
strictly necessary which isn't likely to hurt that much...


Maybe. I'm not so sure about that...


David


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-08 Thread Guillaume Yziquel

Basile STARYNKEVITCH a écrit :


Why do these functions not follow the usual CAMLparam/CAMLreturn macro 
stuff?


Because they are written by the Ocaml guys (Damien knows really well the 
Ocaml garbage collector; he wrote it). And also, because these 
particular functions do not do any allocation of Ocaml values (either 
directly or indirectly).


So, no allocation of OCaml values (or in place modification, either, I 
guess) implies no need for CAMLparam/CAMLreturn stuff?



My advice for people coding C code for ocaml is the following:

1. *always* use the CAMLparam/CAMLreturn/... macros.

2. if you dare not using them for some very few functions (because they 
don't allocate, ...) add a big fat comment with a warning inside.


Regards


I want to understand them so that I can abstract away in some other file 
/ .so, some rather usual constructs involving OCaml structures. I think 
it is smarter to take some time doing this, with detailed comments all 
over, than repeating the same mistakes over and over (or worse: 
wondering if you made mistakes) when doing C bindings.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2010-01-08 Thread Guillaume Yziquel

Damien Doligez a écrit :


On 2009-12-31, at 00:30, Guillaume Yziquel wrote:


#include 
#include 
#include "../mylib/mylib.h"
CAMLprim value
my_print_stub(value v) {


 CAMLparam1(v);  /* is missing here, for garbage
collection purposes. */


   char* str = (char*)String_val( v );


 /* You do not need the right-hand side (char*) casting. */


   my_print( str );
   return Val_unit;
}


If you use CAMLparam1, you must use CAMLreturn instead of return.


Yes. Indeed. Didn't see it.

However, I had a look at

https://yquem.inria.fr/caml/svn/ocaml/version/3.09/byterun/sys.c

and more specifically at the function


CAMLprim value caml_sys_exit(value retcode)
{
#ifndef NATIVE_CODE
  caml_debugger(PROGRAM_EXIT);
#endif
  exit(Int_val(retcode));
  return Val_unit;
}


or the function


CAMLprim value caml_sys_close(value fd)
{
  close(Int_val(fd));
  return Val_unit;
}


Why do these functions not follow the usual CAMLparam/CAMLreturn macro 
stuff?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Controlling module loading order.

2010-01-08 Thread Guillaume Yziquel

Hi.

I've been reimpleminting the OCaml-R binding, and implemented a simple 
wrapper around the Quantmod package in R:


http://yziquel.homelinux.org/gitweb/?p=ocaml-r.git;a=tree
http://yziquel.homelinux.org/gitweb/?p=ocamlr-quantmod.git;a=tree

Testing these modules from the toplevel is quite fine. However, when 
compiling stuff using these pieces of code, I have issues with the way 
the modules are loaded, since the order in which they are loaded has 
side-effects: Initialisation of the R interpreter in the good case, 
segfaults in the bad case...


For instance, the META file of OCaml-R:


   1 name = "R"
   2 version = "0.2"
   3 description = "R bindings for OCaml"
   4 requires = "unix"
   5 archive(byte) = "r.cma"
   6 archive(native) = "r.cmxa"
   7 
   8 package "interpreter" (

   9   version = "0.2"
  10   description = "Embedded R interpreter"
  11   requires = "R"
  12   archive(byte) = "oCamlR.cma"
  13   archive(native) = "oCamlR.cmxa"
  14 )


The stub functions are in package "R", and package "R.interpreter" 
contains a module with and empty signature, whose side-effects are to 
initialise the R interpreter through an application of the functor



  19 module Interpreter (Env : Environment) : Interpreter = struct
  20 
  21   let () = init ~name: Env.name

  22 ~argv: Env.options
  23 ~env:  Env.env
  24 ~sigs: Env.signal_handlers
  25 ()
  26 
  27 end


My issue concerns the Quantmod wrapper: How can I make sure that when 
the Quantmod module is loaded, the OCamlR module of the "R.interpreter" 
findlib package gets loaded before?


Currently the ocamlbuild _tags file for ocamlr-quantmod is


   1 : pkg_R.interpreter, pkg_CRAN-zoo


But that doesn't seem to do the trick...

My question is: do I have to put a line like "module X = OCamlR" in 
quantmod.ml, or is there a way to load OCamlR beforehand just by 
tweaking the build process, order of modules when linking, etc...


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Dynamically loaded BSS not initialised to 0.

2010-01-08 Thread Guillaume Yziquel

Richard Jones a écrit :


Problem solved: This is in fact a symbol collision problem on the symbol 
'box'. There's one in libncurses, which is loaded by ocamlrun.


Good ol' ELF loading model ...  Uli wrote a really good introduction
to writing DSOs which everyone should read:

http://people.redhat.com/drepper/dsohowto.pdf


Indeed, it's very very good. Thanks a lot for this pointer.


The issue of symbol scope is covered there too, although I don't think
it can help in this case.  One or other of the libraries is just going
to have to change the visibility of that symbol.


Yes. This has been done on the MonetDB side. They're going to make 'box' 
locally static, and to rename it...



In ncurses it's a
public symbol, but if I understand the code correctly, in MonetDB it's
just an accidentally leaked global variable (not part of the API).  So
MonetDB could control the visibility of that symbol using a linker
script.


Yes, they probably could, but it seems to me that they have other 
priorities for now.



We use linker scripts extensively in libvirt to control which
clients can see which sets of symbols, eg:

http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/libvirt_public.syms;hb=HEAD
http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/libvirt_private.syms;hb=HEAD

In answer to your original question, initialization of the BSS is the
job of the loader (ld-linux.so(8)).  OCaml just calls dlopen(3), which
calls into some extremely well-tested code, so it was always going to
be unlikely that BSS initialization was the problem.

Rich.


Thanks. I was quite sure that the loader was doing a proper job. I 
wasn't sure however that OCaml was calling dlopen, and I was wondering 
at the time if the linking scheme used by OCaml depended or not on 
whether we're dealing with OCaml bytecode or OCaml native code. In this 
context I was wondering if the BSS was initialised to 0, since on some 
hardware, it's not necessarily the case (it seems... I would not bet my 
hand on this).


I now know better.

Anyway, it was an interesting bug: I'm growing fond of assembly.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Dynamically loaded BSS not initialised to 0.

2010-01-03 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Hello.

I encountered a rather weird issue. A binding of mine works fine when 
bundled as a .cmxa, but fails when bundled as a .cma. I'm running a 
Linux Debian amd64.


I've tracked down the issue to the following point: it seems that when 
the BSS (uninitialised data section) of libmonetdb5.so is dynamically 
loaded, it doesn't get initialised to 0. And the code in libmonetdb5.so 
relies on the fact that BSS gets initialised to 0 when dynamically loaded.


So: is ocaml failing to initialise memory to 0 when limonetdb5.so is 
dynamically loaded?


Problem solved: This is in fact a symbol collision problem on the symbol 
'box'. There's one in libncurses, which is loaded by ocamlrun.


Thanks to Csaba Halasz (Jester01 on ##asm) for help with binary debugging.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Dynamically loaded BSS not initialised to 0.

2010-01-03 Thread Guillaume Yziquel

Hello.

I encountered a rather weird issue. A binding of mine works fine when 
bundled as a .cmxa, but fails when bundled as a .cma. I'm running a 
Linux Debian amd64.


I've tracked down the issue to the following point: it seems that when 
the BSS (uninitialised data section) of libmonetdb5.so is dynamically 
loaded, it doesn't get initialised to 0. And the code in libmonetdb5.so 
relies on the fact that BSS gets initialised to 0 when dynamically loaded.


To reproduce my problem, do the following:

You need to have the following Debian packages installed for MonetDB.

libmonetdb-client-dev
libmonetdb-client1
libmonetdb-dev-dbg
libmonetdb1-dbg
libmonetdb5-server-dev-dbg
libmonetdb5-server5-dbg
libmonetdb5-sql-dev
libmonetdb5-sql2
monetdb-client
monetdb5-server-dbg

The *-dbg packages are packages I've changed and recompiled with the -g 
option. They are available from my website:


http://yziquel.homelinux.org/debian/pool/main/m/

The key signing the repo is located at

http://yziquel.homelinux.org/debian/yziquel-debian-packages.asc

and you just have to do

cat yziquel-debian-packages.asc | sudo apt-key add -

and include the following lines:


deb http://yziquel.homelinux.org/debian stable   main
deb-src http://yziquel.homelinux.org/debian stable   main
deb http://yziquel.homelinux.org/debian testing  main
deb-src http://yziquel.homelinux.org/debian testing  main
deb http://yziquel.homelinux.org/debian unstable main
deb-src http://yziquel.homelinux.org/debian unstable main


The rest of the MonetDB packages can be found here:

http://monetdb.cwi.nl/downloads/Debian/

and the monetdb5 binding is here:

http://yziquel.homelinux.org/gitweb/?p=ocaml-monetdb5.git;a=tree

(click on snapshot to download one).

Now here is why I believe that the BSS is not properly initialised. The 
code in which I have my segfault is the following one, function findBox. 
Line 330 of:


http://monetdb.cvs.sourceforge.net/viewvc/monetdb/MonetDB5/src/mal/mal_box.mx?revision=1.100&view=markup

There is this line:


if (box[i] != NULL && idcmp(name, box[i]->name) == 0) {


I've followed machine code instructions step by step there, with ddd.

In native code, box[i] == NULL. Evaluation stops there (i.e. box[i] != 
NULL is false). Everything is perfect.


In bytecode, box[i] != NULL because BSS is not initialised to 0... And 
it then tries to access box[i]->name, and segfaults.


For the record, you have:


  211 typedef struct BOX {
  212   MT_Lock lock;   /* provide exclusive access */
  213   str name;
  214   MalBlkPtr sym;
  215   MalStkPtr val;
  216   int dirty;  /* don't save if it hasn't been changed */
  217 } *Box, BoxRecord;


and


  263 #define MAXSPACES 64  /* >MAXCLIENTS+ max modules !! */
  264 Box box[MAXSPACES];


For the disassembled code, you can have a look at:

http://sourceforge.net/mailarchive/message.php?msg_name=4B3ED073.3050203%40citycable.ch

I've also tried running ltrace to see how dynamic loading happens for 
the bytecode monetdb5.cma:


http://yziquel.homelinux.org/monetdb_sql.byte.ltrace

But it gives ma 95% of ocaml related lines, and the end is concerned 
only with ml_monetdb_sql. I'd like to see how the 'box' symbol gets 
loaded in BSS, but do not know how to do that.


So: is ocaml failing to initialise memory to 0 when limonetdb5.so is 
dynamically loaded?


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping C code using pthread.

2009-12-30 Thread Guillaume Yziquel

Jake Donham a écrit :

On Sun, Dec 27, 2009 at 1:33 PM, Guillaume Yziquel
 wrote:


If someone knows how to use gdb on a bytecode executable to locate the
segfault in MonetDB's .so file, I'd be quite happy to know.


You can just gdb ocamlrun, then run with the bytecode file as
argument. (Assuming you are not building in -custom mode.)


Thanks Jake.

For the record, here is the last mail I sent on the MonetDB users 
mailing list on this topic:


http://sourceforge.net/mailarchive/forum.php?thread_name=4B3BDC5E.10801%40citycable.ch&forum_name=monetdb-users

I encountered a weird issue while running gdb --args ocamlrun, which 
doesn't appear in native code. Here is the binded C source code in which 
gdb steps into: Line 330 of mal_box.mx, available at


http://monetdb.cvs.sourceforge.net/viewvc/monetdb/MonetDB5/src/mal/mal_box.mx?revision=1.101&view=markup

You got this function


  322 Box
  323 findBox(str name)
  324 {
  325   int i;
  326 
  327 	mal_set_lock(mal_contextLock, "findBox");
  328 
  329 	for (i = 0; i < MAXSPACES; i++)

  330   if (box[i] != NULL && name && idcmp(name, box[i]->name) == 0) {
  331 #ifdef DEBUG_MAL_BOX
  332   stream_printf(GDKout, "found the box '%s' %d\n", name, 
i);
  333 #endif
  334   mal_unset_lock(mal_contextLock, "findBox");
  335   return box[i];
  336   }
  337   mal_unset_lock(mal_contextLock, "findBox");
  338 #ifdef DEBUG_MAL_BOX
  339   stream_printf(GDKout, "could not find the box '%s' \n", name);
  340 #endif
  341   return 0;
  342 
  343 }


And gdb complains with bytecode OCaml. Segfault.


(gdb) run
Starting program: /usr/bin/ocamlrun test/monetdb_sql.byte
[Thread debugging using libthread_db enabled]
[New Thread 0x2f670910 (LWP 23863)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x2f670910 (LWP 23863)]
0x2c66c42c in findBox (name=0x2aaab7ac6a37 "time") at mal_box.c:89
89if (box[i] != NULL && idcmp(name, box[i]->name) == 0) {
(gdb) backtrace
#0  0x2c66c42c in findBox (name=0x2aaab7ac6a37 "time") at mal_box.c:89
#1  0x2c66c54a in openBox (name=0x2aaab7ac6a37 "time") at mal_box.c:107
#2  0x2aaab7ac03b4 in MTIMEprelude () at mtime.c:2147
#3  0x2c67e7f6 in runMALsequence (cntxt=0x2c981000, mb=0x669348, 
startpc=1, stoppc=0, stk=0x2f66fb80, env=0x0, pcicaller=0x0) at 
mal_interpreter.c:3260
#4  0x2c67443a in runMAL (cntxt=0x2c981000, mb=0x669348, startpc=1, 
mbcaller=0x0, env=0x0, pcicaller=0x0)
at mal_interpreter.c:272
#5  0x2c6738b7 in MALengine (c=0x2c981000) at mal_session.c:580
#6  0x2c671fdb in malBootstrap () at mal_session.c:37
#7  0x2c662fa5 in mal_init () at mal.c:61
#8  0x2b91ef60 in ?? () from /usr/lib/libembeddedsql5.so
#9  0x2b39b73a in start_thread () from /lib/libpthread.so.0
#10 0x2b67c69d in clone () from /lib/libc.so.6
#11 0x in ?? ()
(gdb) print i
$1 = 0
(gdb) print box[i]
$2 = (Box) 0x0
(gdb) print name
$3 = (str) 0x2aaab7ac6a37 "time"
(gdb)


But in native code, it works quite well:


(gdb) break findBox
Function "findBox" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (findBox) pending.
(gdb) run
Starting program: /home/yziquel/git/ocaml-monetdb5/test/monetdb_sql.native 
[Thread debugging using libthread_db enabled]
[New Thread 0x2f467910 (LWP 15910)]
[Switching to Thread 0x2f467910 (LWP 15910)]

Breakpoint 1, findBox (name=0x2aaab78bda37 "time") at mal_box.c:86
86mal_set_lock(mal_contextLock, "findBox");
(gdb) info locals
i = 10922
(gdb) step
88for (i = 0; i < MAXSPACES; i++)
(gdb) info locals
i = 10922
(gdb) step
89if (box[i] != NULL && idcmp(name, box[i]->name) == 0) {
(gdb) info locals
i = 0
(gdb) print i
$1 = 0
(gdb) print box[i]
$2 = (Box) 0x0
(gdb) step
88for (i = 0; i < MAXSPACES; i++)
(gdb) print name
$3 = (str) 0x2aaab78bda37 "time"
(gdb)


What's weird is the context seems to be exactly the same: i=0, box[i]=0, 
and name="time".


The segfault happens, as I believe, when doing the comparison

box[i] != NULL

I'm quite baffled by a segfault on such an expression, as box[i] seems 
to be valid memory. Enlightenment would be highly appreciated.


For some context, there are some pthreads going on and some dynamic 
loading. But it hardly seems to be the issue.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] problem creating .cma library

2009-12-30 Thread Guillaume Yziquel

roua...@softwarerealisations.com a écrit :

Hi everyone.


Hi.


I am using ocaml 3.11.0 with the MingW toolchain on windows (vista).


Cannot help you much there.


Now I create the mylib_stub.c file which contains the marshalling code
between the libmylib.dll library and ocaml.  This file contains the
following C code:

===
#include 
#include 
#include "../mylib/mylib.h"

CAMLprim value
my_print_stub(value v) {


  CAMLparam1(v);  /* is missing here, for garbage
 collection purposes. */


char* str = (char*)String_val( v );


  /* You do not need the right-hand side (char*) casting. */


my_print( str );

return Val_unit;
}



When I finaly build the test ocaml app which is supposed to use the
mylib.cma library, ocamlc tells me:

 "Unbound module Mylib"


Firs of all, mylib.cma is simply an archive of OCaml modules. It may 
contain multiple modules, and might not contain a module called Mylib.


You have to ensure that mylib.cmo is included in mylib.cma. Moreover, 
when you create mylib.cma, you also need a compiled interface, i.e. a 
mylib.cmi file. It's an interface for mylib.cmo. Without it, there's no 
description of module Mylib in mylib.cma.



The command used to compile the test app is

 ocamlc -verbose mylib.cma -c Main.ml


You've got something fundamentally wrong here:

Out of main.ml (lower case for the the first letter), you first create a 
main.cmo file. And also a main.mli file with ocamlc -i. You compile the 
main.mli file to main.cmi. Then you create the mylib.cma archive from 
main.cmo and main.cmi.


And mylib.cma will contain the module Main. Not the module Mylib.


The Main.ml file contains the following code:

===
open Mylib

let main () =
my_print "my_print = ok"


main ()
===


Here, you're declaring the submodule Mylib of the module Main. Also 
known as Main.Mylib. Not as Mylib.



Is there a way to verify that the .cma library was created correctly?


There are some tools, such as ocamldumpobj and ocamlobjinfo. Forgot 
which one applies to .cmas.



I had to install flexlink for ocaml to get the dll linking to work on
windows.


Can't help you here.


Kind regards
Rouan.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping C code using pthread.

2009-12-27 Thread Guillaume Yziquel

ygrek a écrit :

On Sun, 27 Dec 2009 13:19:36 +0100
Guillaume Yziquel  wrote:

In fact, my trouble is that when things are compiled to native code, it 
works fine. However, things get screwed up when compiled to bytecode, 
resulting in a segfault.


Are pthreads compatible with OCaml bytecode?


I believe so. Could you post some code and instructions how to build for 
investigation?


I'm working on it. Will look at ocamlforge for this purpose.

I now think, however, that it's not a thread issue. MonetDB loads 
dynamically at startup some other libraries for its own low-level 
language, MAL (for MonetDB Assembly Language). I believe this kind of 
dynamic loading works fine in native code, but doesn't in bytecode.


I've got no issues in native code at all... Only with bytecode.

Haven't located the place in MonetDB where this dynamic loading happens, 
so it's just conjectures for now.


If someone knows how to use gdb on a bytecode executable to locate the 
segfault in MonetDB's .so file, I'd be quite happy to know.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping C code using pthread.

2009-12-27 Thread Guillaume Yziquel

ygrek a écrit :

On Fri, 25 Dec 2009 21:57:21 +0100
Guillaume Yziquel  wrote:


Hello.

I'm currently trying to wrap up together a C interface for the MonetDB5 
database system. I'm getting quite a lot of segfaults (a lot of which 
come from MonetDB itself), and I'm therefore wondering the following 
about pthreads and OCaml:


The server is started via a pthread:

pthread_create(&sqlthread, NULL, start_sql_server, (void *) server);

and I would like to know what kind of things I should look at with 
C-side pthreads in order to avoid segfaults...


How does the OCaml code gets executed? Via callbacks from this thread?
If so, have a look at http://caml.inria.fr/mantis/view.php?id=4702


Thanks for the pointer.

No this is not the case. In fact, it's a library that starts an embedded 
database server in its own pthread. Completely distinct from OCaml.


In fact, my trouble is that when things are compiled to native code, it 
works fine. However, things get screwed up when compiled to bytecode, 
resulting in a segfault.


Are pthreads compatible with OCaml bytecode?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping C code using pthread.

2009-12-25 Thread Guillaume Yziquel

Hello.

I'm currently trying to wrap up together a C interface for the MonetDB5 
database system. I'm getting quite a lot of segfaults (a lot of which 
come from MonetDB itself), and I'm therefore wondering the following 
about pthreads and OCaml:


The server is started via a pthread:

pthread_create(&sqlthread, NULL, start_sql_server, (void *) server);

and I would like to know what kind of things I should look at with 
C-side pthreads in order to avoid segfaults...


All the best,

--
     Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: React switch with newly created events.

2009-12-23 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

However, it may happen (and it does happen) that as soon as this new
React.event is created, an event is fired before the React.E.switch has been
executed to replace the old event by the new event.


You are creating a new update cycle inside another update cycle and
this is disallowed. No primitives are allowed to update in an update
cycle (to be precise unless the primitive does not belong to the
dependency graph of the update cycle).


No, this is not the case. There's only one update cycle. I was confused 
and sked the question too quickly. It works perfectly...


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] React switch with newly created events.

2009-12-23 Thread Guillaume Yziquel

Hello.

I've recently been working again of React, and I have the following 
question. Current code is below.


I'm creating an event with React.E.switch, that creates a new event 
through the schedule function, and this new events replaces the old 
event. React.E.switch is used for this replacement.


React.E.switch initial_event (React.E.map begin function () -> schedule 
(rescheduler ()) end tick)


However, it may happen (and it does happen) that as soon as this new 
React.event is created, an event is fired before the React.E.switch has 
been executed to replace the old event by the new event.


This is due to Lwt concurrency.

I therefore have two potential solutions:

-1- clutter my code with mutexes to synchronise the whole stuff, with 
the disadvantage that there is not, to my knowledge, to execute a 
function just after the React.E.switch function has effectively switched 
events.


-2- look for a way in React to do it within React only. Which would mean 
to somehow implement within React a way to switch to a newly created 
event, without race conditions.


What would you do in this context?

Here's the code:


let reschedule ?attach:(f = begin fun x -> x end) start rescheduler =
  (* The let define tick in E.fix define is the proper way to
 implement recursive events. define has type React.event ->
 (React.event * React.event) and its argument is a placeholder
 for the event at time t-dt. *)
  let attach initial_event =
let define tick =
  (* Here is something I worry about: It is possible that the event created
 with the schedule function is fired before it is attached to the 
switched
 event, hence losing an event, and stalling the whole regular event. *)
  let tick' = React.E.switch initial_event (React.E.map
begin function () -> schedule (rescheduler ()) end tick) in
  tick', tick'
in f (React.E.fix define) in
  schedule ~attach:attach start

let regular_schedule ?attach:(f = begin fun x -> x end) start period =
  reschedule ~attach:f start (fun () -> Calendar.add (Calendar.now ()) period)


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Re: Recursion on React.events.

2009-12-10 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

Unfortunately, it seems to me that Daniel's module is fairly low-level in
the sense that it implements the bare mechanics and semantics of FRP.


Yes, react is low-level and will remain. The rationale is that I want
the client of the module to be able to decide the application
structure. This makes react more flexible and easier to embed were you
need to.


That's perfect. You should perhaps think of creating a Convenience 
submodule where some useful patterns could be thrown in by third 
parties. After having been 'moderated' by you, of course.



I could have decided that react has a global queue and every primitive
update has to go through that queue (for the client this would have
simplified the feedback of primitives into the reactive system). But
then the module is not thread-safe and you get compositional problems
when you want to integrate two libraries
using react in a threaded environment. I could have decided that the
reactive engine runs on its own thread but maybe you don't want to use
threads etc.


No no no! Indeed, it's much better as it is today.


For example with the current design two part of a program may use
react as they wish internally without any problem even on different
threads as long as their signals and events don't interact. With the
current structure it also means that a library designer using react
has to make sure the way he design should play nice with other part
defining their own primitive events.


Yes, indeed. But that's also the tricky part where some useful 
constructs would indeed be... useful.



So yes it means a little bit more work and understanding for the
client. But I think it pays to have a reactive engine that doesn't
impose too much on you. The client always knows better the abstraction
he's after and the setting in which it has to implement it. But if a
consistent and compositional pattern of use emerges I'm always willing
to support it directly in the library.


All to true. But that would be the purpose of a Convenience submodule 
(once you get constructive feedback).



For example, make a parser of the Asterisk Manager Interface
with React around OCamlNet's Uq_engine module proved to be quite tricky, in
a similar way as the issue that started this thread (here, I had no event,
but in the Asterisk parser, I had doubled events, and I solved it in a very
very ugly way).


Note that as we discussed I highly suspect you used the wrong
abstraction there (events vs. signals).


Very possibly. I will have to get back to it one day to make it clean. 
Now that I know where to find the documentation for E.fix, it's only a 
question of *cough* time *cough*.



It's true that I may not completely understand how React works, as Daniel 
stated it before (a bit better now)


Btw this was not intended to be offensive. It was to say the reactive
engine has a well defined way to work that should be respected (the
update cycle) so don't try to trick around too much with it when you
cannot achieve want you want.


Yes. It's also here where I worry about a few things concerning Lwt:

In Lwt, you have a monadic way to do context switches for multithreading 
withing a single real thread. So if you use Lwt inside the update cycle, 
you could well jump out of the update cycle with a Lwt context switch. 
As long as you do not encounter a Lwt construct within definition of 
signals and events, you can be pretty sure that the update cycle will go 
through to its end without using Lwt inside an event/signal. But at the 
same time, it seems that the monadic way Lwt is built avoids us such 
problems. But I may be mistaken.


This issue can be interesting and important.

'a Lwt.t represents the type of a promise of something of type 'a, 
essentially. So you could use in parallel processing: Imagine that 'a 
Remote.t represents the type of something computed on a remote computer. 
You could use type 'a Remote.t Lwt.t to represent the promise of a 
computation of 'a done on a remote computer. It therefore could make 
sense to have a single computer in charge of receiving React.events with 
a unique update cycle, and transfering the computation to other 
computers, represented as non-primary 'a Remote.t Lwt.t React.signal-s. 
Using S.fix, one could also feed events to such a signal, using S.fix to 
bind the t-dt Lwt.t value of the signal to the t value of the same signal.


That may seem quite involved, but conceptually, it could be a clean way 
to type rather efficiently parallel computations. When binding such 
signals, you could also implement code mobility, marshaling features to 
take care of the work load of multiple computers.


So the compatibility of Lwt and React seems to me a worthwile question 
if one wants to use OCaml for high availability, reactive, parallel 
computations. And in this context, making E/S.switch easy to use woul

[Caml-list] Re: Recursion on React.events.

2009-12-10 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

Maybe I was looking in the wrong place, but I haven't found "the second case
of the semantics of E.switch" on your website. In fact, the way I learned
about React.E.switch was from the .mli-style webpage on your website, and by
trial and error.


Here :

http://erratique.ch/software/react/doc/React.E.html#VALswitch

Second bullet.


I think you should really make a direct link to this page from either

http://erratique.ch/software/react/doc/React.html

or

http://erratique.ch/software/react/doc/index.html

because I've been on your website quite a few times, and it's the first 
time I see this page. (Which is really useful).



One thing that really troubles me, is that I do not understand why define
returns a couple of two identical element. And the typing of E.fix is rather
confusing:


val fix : ('a React.event -> 'a React.event * 'b) -> 'b


Yes it's confusing. It's here to allow to define mutually recursive
definitions and still expose them to the outside world. It is also
usefull if you have other values that depend on the delayed value and
you want to expose them to the outside world. There are example of
this in the breakout.ml example.

[snip] I tried to rexeplain E.fix and S.fix but I came up with what's
written in their documentation sorry.

Daniel


Same comment for E.fix as for E.switch. I have never seen its 
documentation before. It's much much clearer now.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: Recursion on React.events.

2009-12-09 Thread Guillaume Yziquel
x () =
let (e, set_e) = React.E.create () in
Lwt_mutex.lock task_mutex >>= fun () ->
task_channel := Some {schedule = date; trigger = set_e;};
Lwt_unix.write write_control_fd "X" 0 1 >>= function
| 1 -> Lwt.return e | _ -> assert false in
  Lwt_main.run (aux ())

let regular_schedule start period =
  (* The let define tick in E.fix define is the proper way to
 implement recursive events. define has type React.event ->
 (React.event * React.event) and its argument is a placeholder
 for the event at time t-dt. *)
  let define tick =
let tick' = React.E.switch (schedule start) (React.E.map begin function () 
->
  schedule (Calendar.add (Calendar.now ()) period) end tick) in
tick', tick'
  in
  React.E.fix define


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: Recursion on React.events.

2009-12-09 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

Daniel Bünzli's module is great, but sometimes a bit rough
to get by, specifically on examples such as this one.


I would just like to point out that this has nothing to do with the
module per se but understanding frp in general and this is the reason
why I went to great length to document the semantics for each of the
combinators I provide --- something most frp libraries won't bother to
do, leaving you with testing or looking into the implementation for
understanding things when tricky simulateneity issues arise.


I appreciate the documentation effort you put up. Really.


Thus to understand why your event didn't work you could have done the
following. Provided you understand the notations given here :

http://erratique.ch/software/react/doc/React#sem


I do. I've done quite a lot of maths after all, and this doesn't 
frighten me.



Since we have [schedule st]_st = Some (), by the semantics of E.map we
have [ee]_st = Some ev. Thus we are in the second case of the semantics
of E.switch (see doc) and the semantics of the switch reduces to the
semantics of ev, i.e.


Maybe I was looking in the wrong place, but I haven't found "the second 
case of the semantics of E.switch" on your website. In fact, the way I 
learned about React.E.switch was from the .mli-style webpage on your 
website, and by trial and error.



Pure equational reasoning, it's not that hard, or is it ?


Less than semi-algebraic geometry.

More seriously, the point was not understanding why it failed. I came to 
the same conclusions from empirical evidence. The point was how to 
overcome it.


And while I do not doubt that your documentation is rather explicit, I 
was nevertheless confused by your fixed point operators, and thus rather 
reluctant to use them.


The example on your website:

let history ?(eq = ( = )) s = 
  let push v = function 
| [] -> [ v ] 
| v' :: _ as l when eq v v' -> l
| l -> v :: l  
  in
  let define h = 
let h' = S.l2 push s h in 
h', h'

  in
  S.fix [] define


One thing that really troubles me, is that I do not understand why 
define returns a couple of two identical element. And the typing of 
E.fix is rather confusing:



val fix : ('a React.event -> 'a React.event * 'b) -> 'b


Why do we return a 'b type with E.fix?

While the webpage mentions this dependence on the value at t-dt, it's 
quite hard to infer from the use of the fix point operator in the 
example how it's really supposed to behave and to be called.


Clarifying these issues would be welcome.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Re: Recursion on React.events.

2009-12-09 Thread Guillaume Yziquel

Richard Jones a écrit :

On Wed, Dec 09, 2009 at 03:53:36PM +0800, Daniel Bünzli wrote:

Daniel Bünzli's module is great, but sometimes a bit rough
to get by, specifically on examples such as this one.

I would just like to point out that this has nothing to do with the
module per se but understanding frp in general [...]


Personally I've yet to read any comprehensible introduction to FRP.
I'm interested in whether FRP can be used to write Gtk interfaces with
reduced code complexity.  Apparently it can, but I've no idea how.

Rich.


Concerning documentation, Daniel's documentation is pretty good, and 
it's all that's been necessary to get me going. You should try having a 
look at it.


I have little experience with Gtk, but I've written an Eliom web 
application using the ExtJS framework for windowing in browsers. In some 
sense, it's more complex than a Gtk application, because you have to 
manage lots of users, sessions, et ceteræ.


Moreover the Eliom module was keeping track of the state of an Asterisk 
server, and initiating phone calls.


I must say that using React was the only way to write the application 
cleanly and in a minimum amount of time.


I was basically using signals for:

-1- proxying persistent information such as user data and configuration 
in the SQLite database


-2- parsing the output of the text-based Asterisk Manager Interface

-3- keeping track of the state of the Asterisk server, and interacting 
with it (making phone calls, when the phone hangs up, when a call could 
not be made, etc...)


-4- Keeping track of the IP of users of the web application coming from 
Ocsigen, and reconciliation with the IP of the softphones as registered 
by Asterisk (this allowed to avoid using passwords on the LAN)


-5- Keeping track of the history of the phone calls made by agent, and 
feed it back to the administrator's web session


-6- Doing all the "real-time" AJAX interaction for updating tables, 
windowing, et ceteræ.


Doing it in a FRP way allowed to focus on the semantics, and moreover 
React update cycles integrate nicely with Lwt as used by Ocsigen. So you 
can do really cool stuff with it. It took me roughly one and half to two 
weeks from scratch (including learning the ExtJS library, 
troubleshooting the Asterisk Manager Interface, et ceteræ), with quite a 
lot of other concurrent obligations to handle.


So yes, FRP is really cool.

Unfortunately, it seems to me that Daniel's module is fairly low-level 
in the sense that it implements the bare mechanics and semantics of FRP. 
For real world application, you have to be quite nifty with tricky 
details about update cycles. For example, make a parser of the Asterisk 
Manager Interface with React around OCamlNet's Uq_engine module proved 
to be quite tricky, in a similar way as the issue that started this 
thread (here, I had no event, but in the Asterisk parser, I had doubled 
events, and I solved it in a very very ugly way).


It's true that I may not completely understand how React works, as 
Daniel stated it before (a bit better now), but, for instance, the 
React.E.switch or React.S.switch is something that you'll be using a 
lot. And I feel the need for higher-level functions to deal with it, 
even though I do not have yet a precise idea of which such functions.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: Recursion on React.events.

2009-12-08 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Hello.

I've been dabbling with recursive definition of React events.

Suppose I have a function called schedule of type

val schedule : Calendar.t -> unit React.event

which throws out an event at the specified time or date.

I've been trying to create a regular_schedule function that throws 
events at a regular pace. Daniel Bünzli's module is great, but sometimes 
a bit rough to get by, specifically on examples such as this one.


So I came up with a recursive definition of such a React.event:


let rec regular_schedule start_time period =
  React.E.switch React.E.never begin React.E.map
begin fun () -> regular_schedule (Calendar.add (Calendar.now ()) 
period) period end

begin schedule start_time end
  end


First question:

It almost works, in the sense that if you insert a print_endline after 
the fun (), well, it indeeds prints stuff on stdin at the specified 
pace. However, somehow, the event as a whole behaves as React.E.never. 
So it doesn't work. I guess it has to do with the way React.switch works 
synchronously, but I really do not get it.


OK. The following piece of code works out, but it seems to me that using 
a React.E.select in this position is a rather ugly hack.


let rec regular_schedule start period =
  let waiting_for = schedule start in
  React.E.switch React.E.never begin React.E.map
begin fun () -> React.E.select [waiting_for; regular_schedule
  (Calendar.add (Calendar.now ()) period) period]
end waiting_for
  end



Second question:

Is there somehow a notion of 'tail recursion' for such constructs?


I gave some thought to it, and it seems quite plausible that what is 
done in the first place is analoguous to tail recursion. And that using 
React.E.select breaks the tail recursion. Am I offtrack?



All the best,


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Recursion on React.events.

2009-12-08 Thread Guillaume Yziquel

Hello.

I've been dabbling with recursive definition of React events.

Suppose I have a function called schedule of type

val schedule : Calendar.t -> unit React.event

which throws out an event at the specified time or date.

I've been trying to create a regular_schedule function that throws 
events at a regular pace. Daniel Bünzli's module is great, but sometimes 
a bit rough to get by, specifically on examples such as this one.


So I came up with a recursive definition of such a React.event:


let rec regular_schedule start_time period =
  React.E.switch React.E.never begin React.E.map
begin fun () -> regular_schedule (Calendar.add (Calendar.now ()) period) 
period end
begin schedule start_time end
  end


First question:

It almost works, in the sense that if you insert a print_endline after 
the fun (), well, it indeeds prints stuff on stdin at the specified 
pace. However, somehow, the event as a whole behaves as React.E.never. 
So it doesn't work. I guess it has to do with the way React.switch works 
synchronously, but I really do not get it.


Second question:

Is there somehow a notion of 'tail recursion' for such constructs?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Wrapping sigsetjmps/siglongjmps in OCaml.

2009-11-29 Thread Guillaume Yziquel

Hello.

I'm having some problems wrapping up the API for the R interpreter, 
namely because R seems to be using sigsetjmps and siglongjmps 
everywhere: that's how looping is implemented, for instance. (At least 
that's how I understand the source code).


So I was wondering: what's the "best" way to wrap up such jumps in OCaml 
code? It may be that the jumps would happen in one single C function. Or 
it may be, due to a rather restrictive API for R, that I may have to 
reimplement some C code entirely in OCaml. In which case, the jumps 
would go over OCaml code.


How would you deal with that?


Here's the LONGJMP:

SETJMP and LONGJMP are just macros to sigsetjmp and siglongjmp.


/* jumpfun - jump to the named context */

static void jumpfun(RCNTXT * cptr, int mask, SEXP val)
{
Rboolean savevis = R_Visible;

/* run onexit/cend code for all contexts down to but not including
   the jump target */
PROTECT(val);
R_run_onexits(cptr);
UNPROTECT(1);
R_Visible = savevis;

R_ReturnedValue = val;
R_GlobalContext = cptr; /* this used to be set to
   cptr->nextcontext for non-toplevel
   jumps (with the context set back at the
   SETJMP for restarts).  Changing this to
   always using cptr as the new global
   context should simplify some code and
   perhaps allow loops to be handled with
   fewer SETJMP's.  LT */
R_restore_globals(R_GlobalContext);

LONGJMP(cptr->cjmpbuf, mask);
}


Here's the SETJMP


SEXP applyClosure(SEXP call, SEXP op, SEXP arglist, SEXP rho, SEXP suppliedenv)
{
SEXP body, formals, actuals, savedrho;
volatile  SEXP newrho;
SEXP f, a, tmp;
RCNTXT cntxt;

/* formals = list of formal parameters */
/* actuals = values to be bound to formals */
/* arglist = the tagged list of arguments */

formals = FORMALS(op);
body = BODY(op);
savedrho = CLOENV(op);

[...]

/*  Set a longjmp target which will catch any explicit returns
from the function body.  */

if ((SETJMP(cntxt.cjmpbuf))) {
if (R_ReturnedValue == R_RestartToken) {
cntxt.callflag = CTXT_RETURN;  /* turn restart off */
R_ReturnedValue = R_NilValue;  /* remove restart token */
PROTECT(tmp = eval(body, newrho));
}
else
PROTECT(tmp = R_ReturnedValue);
}
else {
PROTECT(tmp = eval(body, newrho));
}

endcontext(&cntxt);

if (RDEBUG(op)) {
Rprintf("exiting from: ");
PrintValueRec(call, rho);
}
UNPROTECT(3);
return (tmp);
}


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] C stubs with many args.

2009-11-29 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Hi.

I've been recently reworking Maxence Guesdon's OCaml-R binding in order 
to provide a tighter integration with, and I'm currently trying to 
reverse-engineer the way closures are handled in R. So I've written up 
this small C stub code for a function with 6 parameters:


OK. Figured it out. Stupid me:


void Rf_begincontext (RCNTXT * cptr, int flags, SEXP syscall, SEXP env, SEXP 
sysp, SEXP promargs, SEXP callfun);
CAMLprim value r_reveng_begin_context_native (value flags, value syscall, value 
env, value sysp, value promargs, value callfun) {
  CAMLparam5(flags, syscall, env, sysp, promargs);
  CAMLxparam1(callfun);
  CAMLlocal1(result);
  result = caml_alloc(1, Abstract_tag);
  Rf_begincontext ( (context) Field(result, 0), Int_val(flags), 
Sexp_val(syscall), Sexp_val(env),
Sexp_val(sysp), Sexp_val(promargs), Sexp_val(callfun));
  CAMLreturn(result);
}
CAMLprim value r_reveng_begin_context_bytecode (value * argv, int argn) {
  return r_reveng_begin_context_native(argv[0], argv[1], argv[2], argv[3], 
argv[4], argv[5]);
}


All the best,

--
     Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] C stubs with many args.

2009-11-29 Thread Guillaume Yziquel

Hi.

I've been recently reworking Maxence Guesdon's OCaml-R binding in order 
to provide a tighter integration with, and I'm currently trying to 
reverse-engineer the way closures are handled in R. So I've written up 
this small C stub code for a function with 6 parameters:



void Rf_begincontext (RCNTXT * cptr, int flags, SEXP syscall, SEXP env, SEXP 
sysp, SEXP promargs, SEXP callfun);
CAMLprim value r_reveng_begin_context_native (value flags, value syscall, value 
env, value sysp, value promargs, value callfun) {
  CAMLparam5(flags, syscall, env, sysp, promargs);
  CAMLxparam1(callfun);
  CAMLlocal1(result);
  result = caml_alloc(1, Abstract_tag);
  Rf_begincontext ( (context) Field(result, 0), Int_val(flags), 
Sexp_val(syscall), Sexp_val(env),
Sexp_val(sysp), Sexp_val(promargs), Sexp_val(callfun));
  CAMLreturn(result);
}
CAMLprim value r_reveng_begin_context_bytecode (value * argv, int argn) {
  
} 


I've been trying to follow section 18.1.2 of:

http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html

Unfortunately, I'm a bit confused as to what should the CAMLparam and 
such be for the bytecode stub.


Could someone provide me with an example somewhere?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] solicitation for ocamlbuild examples to go in a new repository

2009-11-28 Thread Guillaume Yziquel

Erick Matsen a écrit :

Hello Ocaml-folk--

As the previous and many other posts on this list demonstrate, there
is a need for a collection of ocamlbuild examples which can be adapted
to various setting. I've started such a project (at Sylvain LeGall's
suggestion) at

http://forge.ocamlcore.org/projects/obuild-examples/

I hope that the community will take a bit of time to sumbit examples.


The point is, in my humble opinion, that we do need examples, but we'd 
better try to have a generic plugin that solves most of the use cases. 
And *precise* documentation of ocamlbuild to be able to write such a 
plugin, or other plugins.


For now, the pain/benefit ratio of writing ocamlbuild plugins is clearly 
not worth it. Due to lack of documentation.



I'd be very happy if others were interested in joining the project,
but it might be easiest just to email examples directly to me.

An ideal "package" from my perspective would have
- a short description of what it does, just a sentence or two.
- a commented myocamlbuild.ml file
- the corresponding _tags file


If you receive such examples, it would be useful to make them as generic 
as possible. There's no point, from a tutorial point of view, in having 
'complex' myocamlbuild plugins that you have to wrap your head around in 
order to reuse. I'm thinking about examples on the wiki pages.



I hope to get examples of all levels, from very basic to advanced.
However, I think that there is a distinct need for simple examples
which do one or two interesting things (a flood of 10 page
myocamlbuild files isn't going to help people get off the ground).


Yes. Exactly.


Thanks,

Erick


There's definitely a know how out there. I'm thinking of bluestorm who 
helped me out with the ".inferred.mli" target for the plugin on the wiki.


http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild

I gave feedback, and its been since then on the wiki page above.

Maybe I'm mistaken, but this plugin hasn't evolved much since then. I'm 
fairly disappointed that it has not been augmented to fit the needs of C 
stubs in a generic way.


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Re: Simple ocamlbuild example for C stubs?

2009-11-28 Thread Guillaume Yziquel

Sylvain Le Gall a écrit :

On 28-11-2009, Guillaume Yziquel  wrote:

Hello.

I'm trying to build a .cma with C stubs with ocamlbuild. Linking and 
includes are supposed to be set to non-standard directories.




You probably need to add some 'A"-ccopt"; A"your-option"' to the good
tag. 


Can you give more details/actual layout of your myocamlbuild.ml ?


OK. Yes, I could meddle with my myocamlbuild.ml file. My myocamlbuild.ml 
file is the same as the one on the wiki:


http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild

But I mean, if I'm supposed to write a myocamlbuild.ml for every project 
I make, I might as well use Makefiles, as below.


I was wondering if there was a myocamlbuild.ml that would solve the C 
stub problem and bottleneck. For instance, being able to _tag in the 
tags file for a given .c file the directories in which to look for 
headers (here /usr/share/R/include), and for .o files, all linking 
information (here, /usr/lib/R/lib/libR.so).


The ideal would be to have all that available only from _tags.

Because if you need to write a myocamlbuild.ml for each and every 
project, you might as well write Makefiles... That's the point of a 
generic plugin.


yziq...@seldon:~/git/ocaml-r$ cat Makefile 
RLIBDIR=/usr/lib/R/lib

RINCLUDES=-I . -I /usr/share/R/include
INCLUDES=   -I +ocamldoc -I `ocamlc -where`/caml $(RINCLUDES)

COMPFLAGS=$(INCLUDES)
LINKFLAGS=$(INCLUDES) -ccopt -L$(RLIBDIR) -cclib -lR
LINKFLAGS_BYTE=$(INCLUDES) -ccopt -L$(RLIBDIR)  -cclib -lR

all: build

#build: r.cma r.cmxa oCamlR.cma oCamlR.cmxa
build: r.cma r.cmxa

r.cma: dllr_stubs.so camlobjs
ocamlc -a -dllpath /usr/lib/R/lib -dllib dllr_stubs.so -dllib libR.so 
-o r.cma r.cmo

r.cmxa: dllr_stubs.so camlobjs
ocamlopt -a -ccopt -L/usr/lib/R/lib -cclib -lr_stubs -cclib -lR -o 
r.cmxa r.cmx

oCamlR.cma: camlobjs
ocamlc -a -o oCamlR.cma oCamlR.cmo

oCamlR.cmxa: camlobjs
ocamlopt -a -o oCamlR.cmxa oCamlR.cmx

camlobjs: standard.ml
#   ocamlbuild -classic-display r.cmo r.cmx oCamlR.cmo oCamlR.cmx
ocamlbuild -classic-display r.cmo r.cmx
cp _build/r.cmi .
cp _build/r.cmo .
cp _build/r.cmx .
cp _build/r.o .
#   cp _build/oCamlR.cmi .
#   cp _build/oCamlR.cmo .
#   cp _build/oCamlR.cmx .

standard.ml: r/standard.R
R --silent --vanilla --slave < r/standard.R > r/standard.ml

r_stubs.o: r_stubs.c
ocamlopt -ccopt -Wall $(COMPFLAGS) -ccopt -fPIC -c $<

libr_stubs.a: r_stubs.o
ar rcs libr_stubs.a r_stubs.o

dllr_stubs.so: libr_stubs.a r_stubs.o
ocamlmklib -o r_stubs r_stubs.o

clean:
rm -f r/tandard.ml
rm -f *.o *.so *.a *.cmi *.cmo *.cmx *.cma *.cmxa
ocamlbuild -clean

test: build
ocaml -init ocamlinit

install:
cp META *.a *.cm[ai] *.cmxa /usr/lib/ocaml/R/
cp dllr_stubs.so /usr/lib/ocaml/stublibs/


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Partially hiding modules in packages

2009-11-28 Thread Guillaume Yziquel

blue storm a écrit :


Regarding your original problem, I've had the same needs and came up
with a slightly different solution : in order to avoid the additional
indirection level related to -pack (Foobar.Foo), is used a flattened
representation by adding a "foobar.ml" file containing only :

  include Foo

(and possibly include of other modules in the package). Then the
foobarl.mli is :

  type foo_t

  val initial : foo_t
  val show : foo_t -> string

And values can be referred with Foobar.foo, instead of Foobar.Foo.foo.
Of course this is only useful if you don't want the user to see the
internal module hierarchy, wich may not be what you had in mind.


Where do you put the foobar.ml? I've been trying it all over, I do not 
see how you can flatten something that you pack.


Do you put foobar.ml at the same level of your directory foobar/, or in 
you directory foobar/ ?


Or am I understanding you wrong?

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Simple ocamlbuild example for C stubs?

2009-11-28 Thread Guillaume Yziquel

Hello.

I'm trying to build a .cma with C stubs with ocamlbuild. Linking and 
includes are supposed to be set to non-standard directories.


Is there a state-of-the-art, and *simple* example lying around? Is there 
an ocamlbuild plugin that is more generic than the one on the Wiki


http://brion.inria.fr/gallium/index.php/Ocamlbuild_example_with_C_stubs

which I unfortunately find quite obscure.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Polymorphic functors / modules and OCaml-R

2009-11-15 Thread Guillaume Yziquel

Hello.

I've been trying stuff like these:


# module type 'a A = sig
Error: Parse error: [a_UIDENT] expected after "type" (in [str_item])
# module type ['a] A = sig
Error: Parse error: [a_UIDENT] expected after "type" (in [str_item])
# module type A = sig module type B end
  ;;
Error: Failure: "abstract/nil module type not allowed here"
# 


Is there a way, somehow, of introducing such polymorphism in modules / 
functors?


That would help me a lot. I'm currently try to write bindings for R 
code, with OCaml-R, and I can come up with stuff like this:



module Description : R.LibraryDescription = struct
  let name = "xts"
  let symbols = ["xts"]
end

module Library : R.Library = OCamlR.Require (Description)

let [xts] = Library.root


What would be nice would be Description to be polymorphic in some sense 
or another, so that I could describe the various R symbols that are made 
available by the xts library.


The other, rather unrelated solution I see would be to replace stuff 
above by something like:



module Description : R.LibraryDescription = struct
  let name = "xts"
  let symbols = ["xts"; "print_xts"]
end
module Library : R.Library = OCamlR.Require (Description)

type t
external list_to_tuple : 'a list -> 'b = "list_to_tuple"
let ( (xts : unit -> t),
  (print_xts : t -> unit)
) = list_to_tuple Library.root


where list_to_tuple would be a function constructing the tuple (no fixed 
size) representing a given list. This is rather unsafe...


A polymorphic module, with argument a module type, would be something 
very useful to describe a R library...


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Including code from a .cm[ox] into another .cm[ox]

2009-11-12 Thread Guillaume Yziquel

Philippe Veber a écrit :

You're right this is a linking issue and now the question is at which level
you want to "link" your code. I do not see the point of including a cmo in
another like you describe : i believe there are simpler and mainstream
options. Maybe I miss some details about your problem ? Using findlib to
help the linker is one way to do it, but if you insist on loading a single
module then you have two other options :
- code inclusion -> m4, camlmix, camlp4 or any preprocessor (not that ugly,
but still)
- the -pack option for combining several cmo in a single one (but then all
your modules are included in a "toplevel" module)
sorry if i still didn't get your problem ;o).
ph.


You're getting my problem right. I'm working on the OCaml-R binding of 
Maxence Guesdon.


The thing is, I have a r.ml file, where all the binding work is done. 
However, in order to launch the shared library containing the code of 
the R interpreter, some environment variables must be set up first. 
Therefore I have a small R script, based on Dirk Eddelbuettel's littler 
software, that generates an .ml file, rstdenv.ml, containing the 
environment variables that need to be set up correctly.


Maybe it's trying to be a bit too pretty, but I do not like the name 
Rstdenv for a module. I'd rather have R.Standard.env...


So I'm looking for a way to include a module as a submodule, without 
having to link it to rstdenv.cmo, which I really do not want to be 
available from the r.cma archive.


That's why I was wondering if there is a clean, camlish way, to 
link-substitute code from one .cmo into another .cmo...


The -pack option is clearly overkill, camlp4 seems overkill too, m4 is 
ugly, do not know camlmix. There's also a package from Gerd Stolpmann, 
xstrp4 or something like that which could be useful. But as I want to 
minimise dependencies on extra stuff, I was wondering if there was an 
out-of-box obscure compiling option to do so.


All the best,

Guillaume Yziquel.


2009/11/12 Guillaume Yziquel 


Philippe Veber a écrit :

 Hi

maybe you can have a look at findlib and its #require statement. For
instance, pxp (xml related library) depends on many cma, but everything
loads automagically when invoking #require :


No, no, no... this is not the issue at all. My issue is not about loading
stuff with findlib, it's about including a .cmo into another .cmo. I'd like
to create a .cma with only a.ml, and not containing b.ml.

It's not a toplevel issue, but a 'linking' issue.

Thanks anyway.

Guillaume.




 2009/11/12 Guillaume Yziquel 

 Hello.

Imagine I have a file named a.ml containing

 module C = struct


 include B
end

 and a file named b.ml containing the code

 let f x = x + 1
When I compile everything to .cmo files, I cannot load a.cmo from the
toplevel without loading b.cmo beforehand.

Is there a way to make the 'include B' statement to include the code of
the
B module in the C submodule directly so that it is not required to load
the
b.cmo file before loading the a.cmo file?

That would be extremely useful to me...

All the best,

--
   Guillaume Yziquel
http://yziquel.homelinux.org/


___
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] Including code from a .cm[ox] into another .cm[ox]

2009-11-12 Thread Guillaume Yziquel

Hello.

Imagine I have a file named a.ml containing


module C = struct
  include B
end


and a file named b.ml containing the code


let f x = x + 1


When I compile everything to .cmo files, I cannot load a.cmo from the 
toplevel without loading b.cmo beforehand.


Is there a way to make the 'include B' statement to include the code of 
the B module in the C submodule directly so that it is not required to 
load the b.cmo file before loading the a.cmo file?


That would be extremely useful to me...

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Cannot safely evaluate the definition of the recursively-defined module

2009-09-25 Thread Guillaume Yziquel

Hello.

Sorry for reviving this short thread. I have the same error message, but 
I really do not understand what "safety" means in this context.


If I specify the signature of the recursive module, shouldn't the type 
checker work out right out of the box?


Sorry, but I'm a bit confused. You'll find the recursive submodule that 
I'm having problems with below Hugo's email.


All the best,

Guillaume Yziquel.

Hugo Ferreira a écrit :

Michael Furr wrote:


On Wed, 18 Mar 2009, Hugo Ferreira wrote:


I hope this is not a beginners questions.
I am trying to reuse code via functors,
however I am getting the following error:

Cannot safely evaluate the definition of the recursively-defined module
(refers to "AA.empty" when implemented as a constant value)

I circumvented the problem by not using a
constant value but a function instead. As I
understand it this may cause run-time errors.
My question is: is their any way to make the
following example work.


If you only need to store a constant value in the module, then you can 
get around the restriction by splitting the module into a 
(recursively-)safe module, and an extension that adds the constants.  
Here is a slightly modified version of your code showing the 
transformation:




Ok, I understand this.

Thanks,
Hugo F.




module type AA_Safe =
sig
  type q
  type t = string

  val compare: t -> t -> int
  val add: t -> q -> q
  (* omit empty here, since it is not "safe" *)
end

module rec A1 : AA_Safe with type q = ASet.t  =
struct
  type q = ASet.t
  type t = string
  let compare s1 s2 = Pervasives.compare s1 s2
  let add e s = ASet.add e s
end
and ASet : Set.S with type elt = A1.t = Set.Make(A1)

(* now create the full module *)
module type AA = sig
  include AA_Safe
  val empty: q
end

module A2 : AA = struct
  include A1
  let empty = ASet.empty
end

module type Wrap_A =
sig
  type t
  type q

  val init: q
  val add: t -> q -> q
end
module Make_A (An_A : AA) : Wrap_A
  =
struct
  type t = An_A.t
  type q = An_A.q

  (*let init = ASet.empty*)
  let init = An_A.empty
  let add t q = An_A.add t q
end

module Wrap_A1 = Make_A( A2 )


Cheers,
-Mike


Here's my recursive submodule:


module rec Registry : sig

  val new_status_signal : t -> status React.signal
  val registry : (t * status React.signal) list React.signal
  val status_of_agent : t -> status

end = struct 


  let new_status_signal agent = React.S.fold
begin function current_status -> function
  | AgentPresent (agent_of_signal, status_information) ->
  begin match agent = agent_of_signal with
  | false -> current_status
  | true -> status_information
  end
  | AsteriskStatus (Asterisk.Active activity) ->
  let agent_ip = match Registry.status_of_agent agent with
  | Present ip -> Some ip
  | Online (ip, _) -> Some ip
  | _ -> None in
  begin match agent_ip with None -> current_status
  | Some ip -> current_status (* To do... *)
  end
  | AsteriskStatus _ -> current_status
end Offline (React.E.select [
  agent_status_notification;
  (React.E.map begin function s -> AsteriskStatus s end
(Asterisk.server # status_change))
])

  let registry = React.S.fold
begin fun live_registry new_agent -> new_agent::live_registry end
begin Lwt_main.run (persistent_registry >>= Ocsipersist.get >>=
  begin function a_list -> Lwt.return (List.map
begin function (nom, prenom) ->
  let a = {nom = nom; prenom = prenom} in
  a, (Registry.new_status_signal a)
end a_list)
  end)
end
begin React.E.map
  begin function agent -> agent, (Registry.new_status_signal agent) end
  adding_to_registry
end

  let status_of_agent agent =
try React.S.value (List.assoc agent (React.S.value Registry.registry))
with Not_found -> raise (invalid_arg ("Agent.status_of_agent: "^agent.prenom^" 
"^agent.nom))

end



--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: React.E.switch issue.

2009-09-24 Thread Guillaume Yziquel

Daniel Bünzli a écrit :

My issue is that the 'reinitialise_with' function is called in a
function 'phi' which is used in the following way:

let message_event = React.E.map phi to_be_parsed_event.


Cannot really make sense out of your snippets of code.


What I want to do is the following:

The server sends events with chunks of string that I want to parse.

I accumulate the string chunks (with React.E.fold) until I can parse 
some server message out of it.


When some message is parsed, I discard this part of the event, and I 
install another "accumulating event" (accumulating with React.E.fold).


In order to discard and renew the "accumulating event", I send an event 
to the event of event. This is why I use the React.E.switch construct.


The output of React.E.switch is an event that can hold, for example the 
following sequence of values:


My fi
My first mes
My first message. My s

(Here is where the event of event is renewed:)

My s
My secon
My second mess

etc...


However this phi functions seems to invoke a primitive event sending function


Yes. phi is the function that parses the messages from the server. So it 
has to send an event to renew the "accumulating event".



and that's explicitely prohibited by the documentation. Primitive event
sending/signal setting functions cannot be invoked as side effects
inside update cycles (see doc of E.create/S.create).


OK. So this is not a bug, nor a feature.


Not sure what you are trying to achieve but I suspect fixed point
combinators (E.fix/S.fix) may help you to solve your problem.


I tried to look into this, but I did not see how they could help me with 
my specific issue.



Best,

Daniel


For now, I'm using a workaround, but I'll try to see how I can make this 
clean...


Many thanks for your answer.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: React.E.switch issue.

2009-09-24 Thread Guillaume Yziquel

Guillaume Yziquel a écrit :

Hello.


Hi again.

Here is a piece of code that I am having issue. I'm trying to use React 
to parse reactively a server output. I have the following event definition:


  let event_starting_at str = React.E.fold begin fun accu chunk -> 
accu^chunk end str received_event in   let 
to_be_parsed_event_of_event, set_to_be_parsed_event_of_event = 
React.E.create () in
  let to_be_parsed_event = React.E.switch (event_starting_at "") 
to_be_parsed_event_of_event in
  let reinitialise_with unparsed_text = 
set_to_be_parsed_event_of_event (event_starting_at unparsed_text) in


I've replaced the previous code by the following piece of code, and it 
now works...



  let event_starting_at ?drop:(drop = false) str = React.E.fold begin fun accu 
chunk -> accu^chunk end str
begin match drop with | false -> received_event | true -> React.E.drop_once received_event end in 
  let to_be_parsed_event_of_event, set_to_be_parsed_event_of_event = React.E.create () in

  let to_be_parsed_event = React.E.switch (event_starting_at "") 
to_be_parsed_event_of_event in
  let reinitialise_with unparsed_text = set_to_be_parsed_event_of_event
(event_starting_at ~drop: true unparsed_text) in


Now, is this a bug or a feature?

All the best,

Guillaume Yziquel.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] React.E.switch issue.

2009-09-24 Thread Guillaume Yziquel

Hello.

Here is a piece of code that I am having issue. I'm trying to use React 
to parse reactively a server output. I have the following event definition:


  let event_starting_at str = React.E.fold begin fun accu chunk -> accu^chunk end str received_event in 
  let to_be_parsed_event_of_event, set_to_be_parsed_event_of_event = React.E.create () in

  let to_be_parsed_event = React.E.switch (event_starting_at "") 
to_be_parsed_event_of_event in
  let reinitialise_with unparsed_text = set_to_be_parsed_event_of_event 
(event_starting_at unparsed_text) in


String chunks from the server are received by the 'received_event' 
event, on the first line.


My issue is that the 'reinitialise_with' function is called in a 
function 'phi' which is used in the following way:


let message_event = React.E.map phi to_be_parsed_event.

phi is the parsing function, so I'm not reproducing it directly here. 
However, you would have the behaviour described further below with the 
following code:


let phi string_chunk =
  let new_string_chunk = String.copy string_chunk in
  reinitialise_with new_string_chunk;
  new_string_chunk

This creates hiccups in the events.

For example, at different time intervals, with to_be_parsed_event, I get:

q
qqw
qqwwe
qqwweer
qqwweerrt

etc... where I'd like in fact to have

q
qw
qwe
qwer
qwert

Advice would be appreciated on how to correct this.

All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] polymorphic method.

2009-09-11 Thread Guillaume Yziquel

Jacques Garrigue a écrit :

From: Guillaume Yziquel 


To continue on the example of nil: the current definition of nil
(i.e. the one with type ) would be written as


class nil : object
  polymorphic method hd = raise Empty
  polymorphic method tl = raise Empty
end

and the definition


class nil : object
  method hd = raise Empty
  method tl = raise Empty
end

would not compile since the 'a and the 'b would not be bound in the
definition of class nil.

Just to be sure we are talking about the same thing.


This is indeed what you are proposing. But from my point of view the
distinction is not really relevant: one can easily build examples
where methods should be polymorphic, but not maximally.
A typical example is fold:

class nil = object
  polymorphic method fold f x = x
end


fold would here have type 'a 'b. 'b -> 'a -> 'a with the proposed use of 
the polymorphic keyword.



class nil : object
  method fold : 'a 'b. 'a -> 'b -> 'b
end


OK. Same type.


class ['a] cons (h:'a) (t : 'self) = object (self : 'self)
  polymorphic method fold f x = f h (t#fold f x)
end


fold would have type 'c. ('a -> 'c -> 'c) -> 'b -> 'c

And if you take into account the nil construct, then you would have 'b = 
'c. But that's not the case here.



class  ['a] cons : 'a -> 'b -> object ('b)
  method fold : 'c. ('a -> 'c -> 'c) -> 'c -> 'c
end


Yes, we broadly agree here.


As you can see, the right type is going to be inferred for cons (and a
polymorphic one!), but again the type for nil is wrong.
In order to obtain the right one, you must be fully explicit:
class ['a] nil = object
  polymorphic method fold (f : 'a -> 'b -> 'b) (x : 'b)  = x
end


I perfectly agree that one needs to be fully explicit to get the right 
types. Or what would perhaps be best, use a class type.


But, without wanting to offend you, this is rather theoretical. I do not 
say that it is not important, far from it. But you're showing the use of 
two different interacting classes and showing me that using the 
polymorphic keyword, I might not get what I want. From a practical point 
of view, I'm using (now) only one class with lots of methods, and lots 
of parameters. Which is a rather common situation. So we're not here in 
the exact same situation.


If I do not use the polymorphic keyword, I would still get the problem 
of having to type explicitely the fold method of the nil element. Using 
the polymorphic keyword, I still would. I do not see any improvement or 
any disadvantage from this point of view when it comes to the 
'polymorphic' keyword.


class ['a] nil = object
  polymorphic method fold (f : 'a -> 'b -> 'b) x = x : 'b
end

would be perfectly fine for me. At least better than

class ['a] nil = object
  method fold : 'b. (('a -> 'b -> 'b) -> 'b -> 'b) = fun f x -> x
end

The polymorphic keyword's only purpose would to avoid having to manually 
set types when developing methods incrementally, like adding arguments, 
erasing the only occurence of an argument in the method's code. Without 
a polymorphic keyword, these are a pain.


The former is neater when it comes to developing OO code. The latter is 
a pain because you have to mentally disconstruct the method type, match 
the right argument, et ceterae.


Of course, like any other thing, (seesaws, teddy bears, demineralised 
watter), wrong usage might lead to adverse consequences. The 
'polymorphic' keyword wouldn't be a typing miracle, just a mere 
convenience for OO development.



Isn't that inconsistent to allow 'a coming from exceptions to get
bound, while not doing so for some other 'a? (Sorry if I'm being
unclear and using approximative terminology).


This doesn't work because of raise, but because I used an immediate
object rather than a class. Immediate objects may have implicit
polymorphism at the object level (not at the method level), while
everything must be explicit in classes (because classes define types also).


I'll have to slowly swallow this one.


Humm... I still do not see why there would be ambiguity in choosing
'the most general' polymorphic type... Can't 'the most polymorphic
one' be properly defined?


The most polymorphic one is properly defined, as a function of the
current type system (which may always be improved). But the most
polymorphic one is not necessarily the one you want, as my example
with nil shows. And once you have a polymorphic type, there exists an
infinity of other valid polymorphic types for the same method
(obtained by instantiating repeatedly type variables with ['a option]
for instance).


Well if

Re: [Caml-list] polymorphic method.

2009-09-11 Thread Guillaume Yziquel

blue storm a écrit :


With a camlp4 extension, you could inspect the (syntaxically explicit)
parameters of you method, and (syntaxically) generate a polymorphic
type for each one : "polymorphic method foo bar baz = ..." would be
translated into "method foo : 'a 'b . 'a -> 'b -> 'c = fun (bar : 'a)
(baz : 'b) -> ...".
This is probably not what you want.


Indeed, it's not what I want.


but my general advice is not to try to much to do
type-level transformation by syntaxic transformations : they tend to
get flawed in ways you don't expect, and this is just not the right
tool for the job.


Too bad there's no "type checking extension" in Objective Caml. That 
would be huge fun.


Thanks.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] polymorphic method.

2009-09-10 Thread Guillaume Yziquel

Jacques Garrigue a écrit :

From: Guillaume Yziquel 


By the way, I do not exactly understand the "you might end up with
types more polymorphic than you expected" part.


This is actually the main problem.
At some point, I actually considered generating automatically
polymorphic method types where possible.
The idea would be simply to first give all the methods in a class
monomorphic types (to avoid the undecidability of polymorphic recursion), 
and then generalize all type variables that do not "escape": i.e. do

not appear in class parameters, value fields, or global references.
Technically this is perfectly doable.


Yes, I figured that out.


Theoretically, there are problems with principality, as there is no
most generic type for a polymorphic method (all types are incompatible
with each other).
It is easier to see that on a practical example.
Say that I defined lists:

class ['a] cons x l = object (_ : 'self)
  method hd : 'a = x
  method tl : 'self = l
end

class nil = object
  method hd = raise Empty
  method tl = raise Empty
end


Cute way of defining lists.


Now, both cons and nil would be typable (cons is already typable), and
the inferred types would be:
class ['a] cons : 'a -> 'b ->
  object ('b) method hd : 'a method tl : 'b end

class nil : object
  method hd : 'a
  method tl : 'b
end

At first glance, it seems that the type of nil being completely
polymorphic, we could pass it as second argument to cons.
However, it is not the case. cons has two monomorphic methods, while
nil has two polymorhic methods, and their types are incomparable.
If we look at object types,

type 'a cons = < hd : 'a; tl : 'b > as 'b
type nil = < hd : 'a.'a ; tl : 'b.'b >

Of course, you could argue that what is wrong is the definition of
nil. But basically there is no way to decide what is the right type
for nil as soon as we allow inferring polymorphic methods.


To continue on the example of nil: the current definition of nil (i.e. 
the one with type ) would be written as



class nil : object
  polymorphic method hd = raise Empty
  polymorphic method tl = raise Empty
end


and the definition


class nil : object
  method hd = raise Empty
  method tl = raise Empty
end


would not compile since the 'a and the 'b would not be bound in the 
definition of class nil.


Just to be sure we are talking about the same thing.


Interestingly, currently you can define nil as an immediate object
and have immediately the right type without any annotation:

exception Empty
let nil = object
  method hd = raise Empty
  method tl = raise Empty
end ;;
val nil : < hd : 'a; tl : 'b > = 


So you're saying that what I proposed up there, saying that it would not 
compile properly, indeed works out fine in the current setting?


Isn't that inconsistent to allow 'a coming from exceptions to get bound, 
while not doing so for some other 'a? (Sorry if I'm being unclear and 
using approximative terminology).



let l = new cons 3 nil ;;
val l : int cons = 

So, the current approach is to privilege the monomorphic case,
requiring type annotations for the polymorphic case. Your suggestion
of allowing to give a hint that you want a polymorphic type makes
sense, but it does not say which polymorphic type: there might be
several, with different levels of polymorphism, with no way to choose
between them. Probably it would be ok to choose the most polymorphic
one, but one can always find counter-examples.


Humm... I still do not see why there would be ambiguity in choosing 'the 
most general' polymorphic type... Can't 'the most polymorphic one' be 
properly defined?



So the meaning of your
"polymorphic" keyword would be: "give me the most polymorphic type for
this method, I hope I understand what it will be, but if I'm wrong and
it breaks my program I won't complain". This may be practically ok,


Yes. For me, it would be OK. Even more if 'the most polymorphic one' is 
properly defined. I wouldn't worry too much about the 'I hope I 
understand what it will be' in this case.



but this is a hard sell as a language feature. Particularly when you
think that future versions of the compiler may be able to infer more
polymorphic types, thanks to improvements in type inference, and
suddenly break your program.


I'd like to suggest something naïve: for each 'a type, try to bind it to 
the class definition (what you call monomorphic I think), and if you 
can't, then bind it to the method definition (what you call 
polymorphic). (This, of course, in the presence of the 'polymorphic' 
keyword).


This seems, at least naïvely, properly defined behaviour. And from a 
practical point of view, this is what I'd be looking for.


Of

Re: [Caml-list] polymorphic method.

2009-09-10 Thread Guillaume Yziquel

Jacques Garrigue a écrit :

There are already polymorphic methods in ocaml.
The syntax for your example would be:

class myobject = object
  method id : 'a. 'a -> 'a = fun x -> x
end


Yes, I know that there are already polymorphic methods in ocaml.


A "polymorphic" keyword might seem simpler, but it would be complex to
handle the case where a polymorphic method type contains also class
parameters:

class ['a] cell (x : 'a) = object
  method pair : 'b. 'b -> 'a * 'b = fun y -> (x,y)
end


Indeed. But you could also write:

class ['a] cell (x: 'a) = object
  polymorphic method pair y = (x, y)
end

The polymorphic keyword would only bind what can be bind. Since x is 
already of type 'a, it would escape the scope of the 'polymorphic' 
keyword. But y would not escape the scope of the polymorphic keyword.



More generally, you might end up with types more polymorphic than you
expected, and since differently instantiated polymorphic method types
are incompatible, this would be a problem.


Well, for now, when I write methods, my methods tend to be not 
polymorphic enough. One could keep the default behaviour without the 
keyword, and also use the keyword polymorphic to bind only what can be 
bound (i.e. not 'x' in your example).


The problem I am facing now is cumbersome: writing types for methods 
arguments everywhere... That's not what people would expect for type 
inference, unfortunately. The 'polymorphic' keyword would only be a hint 
as to how type inference would be done. This way I wouldn't have to keep 
the typing of the method arguments in sync with the code of the method 
(or at least, much less).


By the way, I do not exactly understand the "you might end up with types 
more polymorphic than you expected" part.



Jacques Garrigue


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: polymorphic method.

2009-09-10 Thread Guillaume Yziquel

Hello.

When developing with objects in OCaml, I'm quite often faced with 
polymorphic methods.


Such as:

class myobject = object
  method id x = x
end

Sometimes you have many methods that you're tinkling with, and the 
compiler keeps saying to you that 'a is inbound in this class declaration.


I'm therefore wondering if it would be a good idea to have a keyword 
'polymorphic', and one would write


class myobject = object
  polymorphic method id x = x
end

The polymorphic keyword would be a hint that the method is polymorphic 
and that there is no need to look at the class' type parameters.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] polymorphic method.

2009-09-10 Thread Guillaume Yziquel

Hello.

When developing with objects in OCaml, I'm quite often faced with 
polymorphic methods.


Such as:

class myobject = object
  method id x = x
end

Sometimes you have many methods that you're tinkling with, and the 
compiler keeps saying to you that 'a is inbound in this class declaration.


I'm therefore wondering if it would be a good idea to have a keyword 
'polymorphic', and one would write


class myobject = object
  polymorphic method id x = x
end

The polymorphic keyword would be a hint that the method is polymorphic 
and that there is no need to look at the class' type parameters.


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Compiling C++ in OCaml using Swig to native code

2009-06-21 Thread Guillaume Yziquel

Tautrimas Pajarskas a écrit :

Hello,


Hello.


I'm trying to access C++ code from OCaml using Swig. I successfully
compiled C++ code as a shared library through swig's C++ wrapper but
only in bytecode. Now, if I try the procedures listed in
http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_cplusplus
for ocamlopt, I get an error:


I'm sorry I can't help you, but you can help me: I'm also interested in 
binding C++ code to OCaml. Could I have a look at what you did so that I 
can have some guidance as to how to bind C++ code? I'd be perfectly 
happy with bytecode...



Tautrimas Pajarskas


All the best,

Guillaume Yziquel.

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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: Obj.magic and existential types.

2009-06-19 Thread Guillaume Yziquel

Daniel Bünzli a écrit :


Not directly responding to your question but you are looking for 
functional reactive programming (frp).


http://erratique.ch/software/react

I rewrote your example below with react (no magic used).

Best,

Daniel


Thanks a lot. Very good to know. That will save me time.

Just a side question: how thread-safe is React?

All the best,

Guillaume Yziquel.

___
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] Obj.magic and existential types.

2009-06-19 Thread Guillaume Yziquel

Hello.

Please don't scream: I've been using Obj.magic...

But the result is rather interesting. It can record a flow of 
computations, and recompute them only when upstream data has been modified:



# let (n', n) = Dependent.encapsulate 1;;
val n' : int Dependent.data = 
val n : int Dependent.t = 
# let (_, next) = Dependent.encapsulate (fun x -> x + 1);;
val next : (int -> int) Dependent.t = 
# let m = Dependent.apply next n;;
val m : int Dependent.t = 
# Dependent.access m;;
- : int = 2
# Dependent.set n' 3;;
- : unit = ()
# Dependent.access m;;
- : int = 4


The piece of code responsible for this behaviour is at the end of the 
message.


I learnt that I could perhaps overcome the use of Obj.magic by using 
existential types. I was advised to read the following post on this topic:


http://caml.inria.fr/pub/ml-archives/caml-list/2004/01/52732867110697f55650778d883ae5e9.en.html

However, I do not really understand how Daniel implemented existential 
types there, and I do not really see how it can be adapted to my code. 
Suggestions welcomed.


Here's the code, rather disorganised at the moment.

All the best,

Guillaume Yziquel.



type read;;
type write;;

type 'a computation = (Obj.t -> 'a) t * Obj.t t

and ('a, 'b) aux_t = Dependent of
  ( 'a option ref *
'a computation option *
Obj.t t list ref)

and 'a data = ('a, write) aux_t
and 'a t= ('a, read)  aux_t;;

let encapsulate (x : 'a) : ('a data) * ('a t) =
  let z = Dependent ((ref (Some x)), None, (ref [])) in (z, z);;

let add_dependency (alpha : 'a t) (beta : 'b t) =
  let Dependent (_, _, dep) = alpha in
  dep := ((Obj.magic beta) : Obj.t t)::!dep;;

let apply (f : ('b -> 'a) t) (x : 'b t) : 'a t =
  let computation : 'a computation =
((Obj.magic f) : (Obj.t -> 'a) t),
((Obj.magic x) : Obj.t t) in
  let f_x : 'a t = Dependent (
((ref None) : 'a option ref),
((Some computation) : 'a computation option),
((ref [])   : Obj.t t list ref)) in
  add_dependency f f_x;
  add_dependency x f_x;
  f_x;;

exception Undefined;;

module rec Aux :
sig

  val access : 'a t -> 'a
  val update : 'a t -> ('b -> 'a) t -> 'b t -> 'a
  val reset  : 'a t -> unit

end = struct

  let rec access y =
let Dependent (opt_ref_x, comp_opt, _) = y in
match !opt_ref_x with | Some x -> x | None ->
begin match comp_opt with
  | None -> raise Undefined
  | Some (fun_t, arg_t) -> Aux.update y fun_t arg_t
end

  and update y fun_t arg_t =
let Dependent (opt_ref_x, _, dependencies) = y in
List.iter Aux.reset !dependencies;
let result = (Aux.access fun_t) (Aux.access arg_t) in
opt_ref_x := Some result; result

  and reset z =
let Dependent (opt_ref_x, _, dependencies) = z in
match !opt_ref_x with
| None -> () | Some _ -> begin
opt_ref_x := None;
List.iter Aux.reset !dependencies
end;;

end;;

include Aux;;

exception Flawed_implementation;;

let set (x : 'a data) (v : 'a) : unit =
  let Dependent (opt_ref_x, comp_opt, dependencies) = x in
  match comp_opt with | Some _ -> raise Flawed_implementation | None ->
  begin List.iter Aux.reset !dependencies;
opt_ref_x := Some v
  end;;


--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] ocamlbuild and ocamlfind - infer_interface

2009-02-28 Thread Guillaume Yziquel

Hello.

A small comment on the ocamlbuild wiki, and more specifically on its 
plugin for ocamlfind:


http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild

This plugin fails to generate .inferred.mli files. The following lines 
(thanks to bluestorm on #ocaml irc channel) are needed in the 
After_rules of the plugin:


-1- flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];

-2- flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; 
A syntax];


-3- flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"])

Since I could not find a single occurrence of "infer_interface" on the 
Gallium wiki, and since I do not believe that using ocamlbuild and 
ocamlfind together to infer .mli files is "not a simple task", I 
sincerely believe that the documentation of ocamlbuild is insufficient, 
and insufficently structured. (This is to echo the debate between Daniel 
Bünzli and Romain Bardou, among others, two or three weeks ago 
concerning the lack of documentation).


Could these three lines be added to the myocamlbuild.ml plugin for 
ocamlfind on the Gallium wiki, and could tags such as "infer_interface" 
be documented thoroughly on the wiki? That would be helpful!


All the best,

--
 Guillaume Yziquel
http://yziquel.homelinux.org/

___
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] Compiling recursive modules into a .cma.

2008-10-20 Thread Guillaume Yziquel
Stéphane Glondu a écrit :
> 
> It seems that chain.cmo is linked before protection.cmo inside the .cma.
>  The order of modules inside of a .cma file is important. The behaviour
> is the same as if they were #loaded in the same order in a toplevel. Try
> writing explicitly all .ml files of $(SOURCE) in topological order.

Yes. Indeed. This is the problem. I was misled by the fact that
compiling things manually and in order didn't work at first, and I
believed something else was wrong, but I was mistaken.

It now works. Thanks.

Guillaume.

___
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] Compiling recursive modules into a .cma.

2008-10-20 Thread Guillaume Yziquel
Hello, list.

I've been recently trying to compile a module I made. I can load the
.cmo I generate out of it, but not the .cma I generate out of it.

> [EMAIL PROTECTED]:~/svn/ocaml-yziquel$ ocaml
> Objective Caml version 3.10.2
> 
> # #load "ocaml-yziquel.cma";;
> Reference to undefined global `Protection'
> # 

The issue is, I think, the fact that it is a recursive module. You'll
find the code at the end of this email.

I needed a recursive module because the following (simplified code) did
not manage to type things "correctly". For instance protected_value was
supposed to have type 'a protected -> 'a...

> type 'a protected =
> | Protected of 'a * ((Mutex.t * Condition.t) ref protected * Mutex.t)
> | Unprotected of 'a
> 
> let rec protect data = match data with
> | Unprotected _ -> ()
> | Protected (_, (locking_data, mutex)) ->
> Mutex.lock mutex;
> let (mut, cond) = !(protected_value locking_data) in
> Mutex.lock mut  
>   
>   and (protected_value: 'a protected -> 'a) =
> function protected_data -> match protected_data with
>   | Unprotected d -> d
>   | Protected (d, _) -> d
>   
>   and unprotect data = match data with
> | Unprotected _ -> ()
> | Protected (_, (locking_data, mutex)) ->
> let (mut, cond) = !(protected_value locking_data) in
> Mutex.unlock mut;
> unprotect locking_data;
> Mutex.unlock mutex;;
> 
> val protect : 'a protected -> unit = 
> val protected_value :
>   (Mutex.t * Condition.t) ref protected -> (Mutex.t * Condition.t) ref =
>   
> val unprotect : (Mutex.t * Condition.t) ref protected -> unit = 

A look at protection.cmo with ocamlobjinfo gave the following output:

> Unit name: Protection
>   Interfaces imported:
> 8ba3d1faa24d659525c9025f41fd0c57Pervasives
> 19e9e3e1586622e6bee0a641bcbccbd7Condition
> da1ce9168f0408ff26158af757456948List
> dc6994f75cfd14f73e718f81aa215803CamlinternalMod
> 855af44384a5465360efe6e8bff546abMutex
> 09ed2ebaeb54934aa3f583a41f71ca7bProtection
> 5cfae708052c692ea39d23ed930fd64dObj
>   Uses unsafe features: no

The modules CamlinternalMod and Obj are not pulled down to chain.cmo
(which depends on the Protection module). I do not know what these
modules stand for.

To sum up, I'm able to load the .cmo in the ocaml toplevel, but not the
.cma file generated out of the Protection and Chain modules...

Any ideas / suggestions / explanations are welcome...

(Please keep my adress in Cc: when replying).

All the best,

Guillaume Yziquel.


Here is the code of the protection.ml file:

> [EMAIL PROTECTED]:~/svn/ocaml-yziquel$ cat protection.ml
> module rec Protection :
> sig
> 
>   type 'a protected =
> | Protected of 'a * ((Mutex.t * Condition.t) ref protected * Mutex.t)
> | Unprotected of 'a
> 
>   val protect : 'a protected -> unit
>   val protected_value : ?protection:bool -> ?force:bool -> 'a protected -> 'a
>   val unprotect : ?strongly:bool -> ?force:bool -> 'a protected -> unit
>   val try_protect : ?strongly:bool -> 'a protected -> bool
>   val protected : ?protection:bool -> ?lockdata:(Mutex.t * Condition.t) list 
> -> 'a -> 'a protected
>   val mutually_protected : ?protection:bool -> ?lockdata:(Mutex.t * 
> Condition.t) list -> 'a list -> 'a protected list
>   val lock_of_protected : ?force:bool -> 'a protected -> (Mutex.t * 
> Condition.t) ref protected
> 
> end = struct
> 
>   type 'a protected = 
> | Protected of 'a * ((Mutex.t * Condition.t) ref protected * Mutex.t)
> | Unprotected of 'a;;
> 
>   let protect data =
> match data with
>   | Unprotected _ -> ()
>   | Protected (_, (locking_data, mutex)) ->
>   Mutex.lock mutex;
>   let aux_cond = ref None in
>   while not
>   ( let (mut, cond) = !(Protection.protected_value locking_data) in
> aux_cond := Some cond;
> let b = Mutex.try_lock mut in
> Protection.unprotect locking_data; b
>   ) do match !aux_cond with
>| None -> failwith "Protection.protected"
>| Some c -> Condition.wait c (Mutex.create ())
>   done;;
> 
>   let protected_value ?protection:(protection=true)
>   ?force:(force=false)
>   (protected_data: 'a protected) =
> if not force then protect protected_