Re: [Caml-list] zero-arity constructor

2010-11-27 Thread Martin Jambon
On 11/27/10 04:23, Julia Lawall wrote:
> In my case, I originally thought that the constructor should take an 
> argument, then changed my mind.  I would have hoped that OCaml would have 
> found the inconsistency.  That's what static typing is for.  Thus, I 
> find the change quite disappointing.

I also find the change uninspired.

> Perhaps it would have been nicer to have an option to allow the behavior 
> that is useful in the camlp4 case, rather than making it the default.

Could the warning be turned on by default in the next OCaml release, please?



Martin

___
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: help with regular expression

2010-12-06 Thread Martin Jambon
On 12/06/10 05:11, Sylvain Le Gall wrote:
> On 06-12-2010, David Allsopp  wrote:
>> zaid Khalid wrote:
>>>
>>
>>> Hint I am using (Str.regexp)
>>
>> There are other libraries (e.g. pcre-ocaml) which provide different (I
>> would say more powerful, rather than strictly better!)
>> implementations.
>>
>>
> 
> There is also syntax extension like mikmatch, that helps to write regexp
> in a very meaningful syntax:
> 
> match str with 
> | RE bol "a"* | "ab"* eol ->
>   true
> | _ ->
>   false

If I understand correctly the original problem, the solution is:

match str with
  | RE ("a"* | "aba"*) eos ->
  (* matches always the beginning of the string,
 eos enforces a match at the end of the string,
 and the vertical bar has the lowest priority
 and so parentheses are needed. *)
  true
  | _ ->
  false


> http://martin.jambon.free.fr/mikmatch-manual.html
> http://martin.jambon.free.fr/mikmatch.html
> 
> You can use pcre and str with mikmatch.

I would recommend the pcre variant mostly for one feature that is not
provided by str:  lazy quantifiers, i.e. "repeat as little as possible
before trying to match what comes next".


Martin

___
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] Atdgen/Biniou with support for cyclic values

2010-12-20 Thread Martin Jambon
Hi list,

Atdgen is a tool that produces OCaml serializers and deserializers from
type definitions in the ATD syntax.  Two serialization formats are
supported:  JSON and Biniou.  For more information on the project, see

  http://martin.jambon.free.fr/atd-biniou-intro.html

The main highlight of this release (1.1.0) is support for sharing, which
allows the serialization of cyclic values such as graphs.  Sharing is
currently supported for the Biniou format only and requires extra
wrapping using type ref for non-record types.

The other new features are listed here:

  http://oss.wink.com/atdgen/atdgen-1.1.0/Changes.txt


Example:

$ cat cycle.atd
type shared_node = node shared (* sharing point *)

type node = {
  label : string;
  self : shared_node;
}

$ cat test_cycle.ml
open Cycle

let () =
  let rec a = { label = "A"; self = a } in
  let s = string_of_shared_node a in
  Printf.printf "%i %S\n" (String.length s) s;
  let a' = shared_node_of_string s in
  assert (a != a');
  assert (a == a.self);
  assert (a' == a'.self);
  print_endline "Success"

$ atdgen cycle.atd
$ ocamlfind opt -o test_cycle \
graph.mli graph.ml test_cycle.ml \
-package atdgen -linkpkg
$ ./test_cycle
17 "\026\000\021\002\239\175\r\244\018\001A\204P\139\140\026\015"
Success


Dissection of the serialized value:

  \026 shared_tag
  \000 0 indicates that the value follows

  \021 record_tag
  \002 field count
\239\175\r\244 hash("label")
  \018 string_tag
  \001 string length
  Astring contents
\204P\139\140 hash("self")
  \026 shared_tag
  \015 find value 15 bytes backward

The Biniou format is fully described here:

  http://martin.jambon.free.fr/biniou-format.txt



Home of each project:

  http://martin.jambon.free.fr/biniou.html
  http://martin.jambon.free.fr/yojson.html
  http://oss.wink.com/atd/
  http://oss.wink.com/atdgen/


Non-interactive installation with Godi:

$ godi_console update
$ godi_console perform -build godi-atdgen


Each of these four projects are distributed under a BSD license.

Biniou (c) 2010 Martin Jambon
Yojson (c) 2010 Martin Jambon
Atd (c) 2010 MyLife
Atdgen (c) 2010 MyLife




Enjoy.



Martin

___
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] [OSR] Standard syntax extensions ?

2008-04-24 Thread Martin Jambon

On Thu, 24 Apr 2008, David Teller wrote:


* which syntax extensions do you use so often that you consider they
should be part of the language ?


None because it creates unneeded dependencies between unrelated 
libraries.
The problem is that software packages can only grow or be replaced 
because of compatibility issues.


What if a part of a package (such as one syntax extension among many) 
becomes unmaintainable?

The whole package dies.

I believe it's what happened to the Caml Development Kit (CDK).
I would love to hear some opinions from the CDK folks.


Martin

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

2008-04-25 Thread Martin Jambon

On Fri, 25 Apr 2008, Richard Jones wrote:


(1) How do I match on the pattern which is literally '_' in the
original code?

   match mypatt with
   | <:patt< _ >> -> ...

seems like it matches any pattern.


Strange.



(2) Is there a function hiding anywhere which tests whether a pattern
is exhaustive?


It's something that can't be done with camlp4.
If in some module M, some type t is defined by "type t = A | B | C"
then knowing that "M.A -> 1 | M.B -> 2" is incomplete requires access to 
more information than camlp4 has.




 Here's the problem I have: I want to generate code
like this:

   <:expr< match $someexpr$ with $mypatt$ -> $code$ | _ -> () >>

However this gives a compile-time warning if mypatt is already
exhaustive because the second case could never be matched.  If mypatt
is already exhaustive then I'd want to generate this code instead to
avoid the warning:

   <:expr< match $someexpr$ with $mypatt$ -> $code$ >>


One possible hack is to add "when true" guards everywhere and one final 
"| _ -> assert false" case.
This disables completeness checking and turns off warnings, at your own 
risk.


Note: "assert false" is not ideal, since you want to raise Match_failure 
with the proper location. <:expr< match () with [] >> should do it 
(assuming quotations in the revised syntax)




I hacked around it a little with this function:

 let pattern_is_exhaustive = function
 | <:patt< $lid:_$ >> -> true
 | _ -> false

but I guess you can see that this function is not a complete solution.

Rich.

--
Richard Jones
Red Hat

___
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



--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Cross-module data in camlp4

2008-04-27 Thread Martin Jambon

On Sun, 27 Apr 2008, Richard Jones wrote:


I'm trying to add named patterns to my bitmatch syntax extension.  The
idea would be you could write (exact syntax isn't nailed down yet):

 let p = BITMATCH { a : 4; b : 4 } ;;

 bitmatch bs with
 | { p } -> (a, b)

 let f a b = BITSTRING p

This is analogous to micmatch's Named regular expressions feature:

 http://martin.jambon.free.fr/micmatch-manual.html#htoc5
eg:
 RE phone = digit{3} '-' digit{4}

Reading the code to micmatch, these are implemented by saving the
camlp4 AST into a Hashtbl, so the example above would create a hash
entry ("phone" -> abstract syntax tree of (digit{3} '-' digit{4})).
At the point of use of the named RE, the AST is substituted.


Yes. It's a global table that ignores everything about module boundaries.



Of course micmatch's scheme only works if the named RE appears in the
same compilation unit as the substitution.  There is no way that I can
see to save these named expressions across compilation units.  In
other words this is not allowed:

 --- my_regexps_lib.ml -
 RE phone = digit{3} '-' digit{4}

 --- my_regexps_lib.mli -
 val phone : Micmatch.regexp

 --- another file -
 open My_regexps_lib
 (* ... and use 'phone' *)

I think this limits the usefulness of named expressions, but at the
same time I don't know how one would go about implementing
cross-module named expressions.  Is it even possible?  Presumably if
it could be done at all, we'd have to save the camlp4 AST
representation into the output file (*.cmo).  It would be easy enough
to marshal the AST into a string at the point of definition.  I don't
quite see how it can be accessed & unmarshalled at the point of use
however.

Any insights here gratefully accepted!


I had some ideas on the subject:

  
http://caml.inria.fr/pub/ml-archives/caml-list/2007/01/6f2e2f9db39543e92806742ddc10fa5f.en.html

Nothing clear comes out of this...


Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Help for Camlp4: Pcaml.input_file for 3.10?

2008-05-06 Thread Martin Jambon

On Tue, 6 May 2008, Loup Vaillant wrote:


2008/5/6 Nicolas Pouillard <[EMAIL PROTECTED]>:

Excerpts from Loup Vaillant's message of Tue May 06 11:57:41 +0200 2008:
>
> I would like to know if there is any equivalent
> of Pcaml.input_file in Ocaml 3.10's Camlp4.
> I tried to search the wiki, but with no luck so far.
> [...]

 If I clearly remember this ugly global variable has been removed.


OK, I got it, thank you for the fast response.

Now, I can have the name of the preprocessed file with _loc.


Not exactly: usually you'll get the location in the source file, because 
of #line directives. The file being processed may not be the source file.

For instance:
  source file: foo.mll
  file being processed by camlp4: foo.ml (locations refer to foo.mll)


But How can I include a file in another? More generally, do we have a
substitute for it?


I'd like to know too.

This is the syntax extension I wrote for the old camlp4, and as far as I 
remember it was working more or less:



(*pp camlp4o pa_extend.cmo q_MLast.cmo -loc loc *)

(* Created by Martin Jambon, 2004 *)
(* No copyright, no guarantee *)

let parse_stream s =
  let f = !Pcaml.parse_implem in
  let rec loop () =
match f s with
l, true -> List.map fst l @ loop ()
  | l, false -> List.map fst l in
  loop ()

let parse_file file =
  let ic = open_in file in
  let stream = Stream.of_channel ic in
  let current_file = !Pcaml.input_file in
  Pcaml.input_file := file; (* it doesn't work *)
  let l = parse_stream stream in
  close_in ic;
  Pcaml.input_file := current_file;
  l

EXTEND
  Pcaml.str_item: [
[ "USE"; file = STRING ->
let l = parse_file file in
<:str_item< declare $list:l$ end >> ]
  ];
END




Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Why OCaml rocks

2008-05-08 Thread Martin Jambon
You guys (Brian Hurt, Jon Harrop and whoever is concerned) should change 
the title of your posts, because it is obviously wrong.


A second "Ocaml **cks" in the top 10 Google results is totally 
superfluous. I think even an average PHP programmer would understand that.



Thanks!

Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Hashtbl.remove legal within Hashtbl.iter for the same hash table?

2008-05-11 Thread Martin Jambon

On Sun, 11 May 2008, Till Varoquaux wrote:


Indeed. The answer you got was, however, based on the actual
implementation not on the documentation. This means that, at some
point, this might evolve and not be valid anymore. If you want to be
on the safe side you should do a fold instead of an iter and collect
all of the items to remove and then remove them in a second pass. The
performance hit shouldn't be as bad as you could expect (ie: I
wouldn't bother unless performance really is critical).
I see it as very unlikely that ocaml's implementation of hashtbl would
evolve in such a way that it would break any code removing previously
visited items during a traversal. Your call.


If you (Florent) want to rely on the standard Hashtbl module, I would 
strongly advise against making assumptions such as "the implementation is 
unlikely to change". Think of the situation 5 years later, when the 
implementation actually changes, you've left the company 3 years before, 
and the maintainer has to figure why the program returns messed up 
results... 
I bet you wouldn't like to be this maintainer.


It's like drunk driving or forgetting the condom: just don't do it...



Martin



On 5/11/08, Florent Monnier <[EMAIL PROTECTED]> wrote:

Hatables are arrays of associative lists. When you are iterating over
them removing any element you have already visited should be ok.
Removing elements you haven't visited yet could cause you to encounter
them anyhow.


which means that it is dependent to the order in which the content is
itered,
while the manual says :
"The order in which the bindings are passed to f is unspecified."

___
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




--
http://till-varoquaux.blogspot.com/

___
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



--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Compose function for multiple parameters ?

2008-05-31 Thread Martin Jambon

On Sat, 31 May 2008, Fabrice Marchant wrote:


It would be cooler to write the later on the basis of :
(( <<- ) (( <<- ) f)) g


Sorry, I just discover that this is cleaner :
(( <<- ) <<- ( <<- ))

and extendable to any number of parameters.

(( <<- ) <<- ( <<- ) <<- ( <<- ))
to compose with a 3 parameters function.


Personally, I call this obfuscated, not clean.


Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] Compose function for multiple parameters ?

2008-05-31 Thread Martin Jambon

On Sat, 31 May 2008, Fabrice Marchant wrote:


On Sat, 31 May 2008 13:24:55 +0200 (CEST)
Martin Jambon <[EMAIL PROTECTED]> wrote:


On Sat, 31 May 2008, Fabrice Marchant wrote:


It would be cooler to write the later on the basis of :
(( <<- ) (( <<- ) f)) g


Sorry, I just discover that this is cleaner :
(( <<- ) <<- ( <<- ))

and extendable to any number of parameters.

(( <<- ) <<- ( <<- ) <<- ( <<- ))
to compose with a 3 parameters function.


Personally, I call this obfuscated, not clean.


Martin


 OK, it's far to be perfect - funny at best. But what would be the right way ?

Defining the 2 ops :
let ( <<- ) f g x = f (g x)
let ( <<-- ) f g x y = f (g x y)

is it better ?


Sorry Fabrice, I'm realizing that my answer was a bit rude...

My point is: why do you insist on having such operators? In my experience 
only the simple composition operator can be useful occasionally, locally.
Stuff that is not used frequently or which is used far from its point of 
definition should receive identifiers that mean something. So what I would 
do is use no operator at all unless you use it more than 5 times in the 
same module (more or less).


In other words, it's fun to play with such things, but in production code 
it's not useful except in some very special situations.



Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] picking / marshaling to strings in ocaml-revision-stable way

2008-05-31 Thread Martin Jambon

On Sat, 31 May 2008, Luca de Alfaro wrote:


Is there a standard way to represent variant types in Json?
As in:
type edit = Ins of int * int | Del of int * int | Mov of int * int * int

Using a list of two elements the first the name of the variant, the second
the encoding of the variant itself?
Is this the standard way?


For this type definition using json-static:

type json t = A | B of int | C of int * int | D of (int * int)

here's the mapping:

A -> "A"
B 1 -> [ "B", 1 ]
C (1, 2) -> [ "C", 1, 2 ]
D (1, 2) -> [ "D", [ 1, 2 ] ]

See http://martin.jambon.free.fr/json-static-readme.txt for more.

It is totally not standard, because the world of mainstream programming 
languages ignores the notion of variants.


Note that the option type uses null for None and x for Some x, which is 
very handy for loading foreign data, but has the problem of representing 
both None and Some None as null.


Overall json-static or the conventions used by json-static are not usable 
for arbitrary OCaml data supported by Marshal. The purpose is to be able 
to exchange data with other applications that use JSON as well. There are 
lots of them and the big advantage of JSON is its great simplicity.


And finally you don't get nude pictures when you look for "json" in 
Google...

;-)


Martin



On Sat, May 31, 2008 at 10:00 AM, Robert Fischer <[EMAIL PROTECTED]>
wrote:


How far is the reach from the Jane St S-exp library from producing JSON?
 I've not actually looked
at it, but that'd be super nifty in the interoperation world.

~~ Robert.

Luca de Alfaro wrote:

Thanks for this insight... I imagined the lack of robustness of

Marshaling,

but without all the details you mentioned!... actually, I DO desperately
need speed, as I am processing TB's of Wikipedia data, but precisely

because

the datasets are so large, I cannot afford having to recompute / convert
them often, and so I want a robust format. Furthermore, I think the
bottleneck for me is anyway the speed of mysql and the disk, not really

the

small amount of time that natively compiled Ocaml would take for the
conversion (I have anyway to do more complex computation that converting

a

few lists and datatypes to ascii, unfortunately).  Moreover, a plaintext
format greatly helps debugging; it also helps that I can read the same

data

with other programming languages.

Speaking of debugging, and said in passing, I cannot say enough how much

I

LOVE the ability of ocamldebug of executing code backwards.  It is such a
revelation.  You simply go to the error, then back off a bit to see how

you

got there.  But, this is a topic for another thread.

Many thanks,

Luca


On Sat, May 31, 2008 at 2:38 AM, Berke Durak <[EMAIL PROTECTED]>

wrote:



I second Luca's suggestion to use Sexplib.  At the very least, use a
plaintext format.
Don't use Marshal for long-term storage of values.  Avoid it if you
can.  Been there, done that.
Why?

(1) Not type-safe.  Translation: your program *wil segfault* and you
won't know why.
(2) Not human-readable nor editable.
(3) Not future-proof.  What happens if you change your type
definition?  Your program
will segfault.  So you'll have to migrate your data.  But how?  You'll
have to find
the exact revision used to generate the binary data.  Good luck with
that.  Did you put
a revision number in your data?  Are you sure it was up-to-date?  Then
you'll have to hand-write a converter that uses type declarations from
the old and the new modules.
I hope your dependencies are not too complex.  Not fun *at all*.

However, there are some situations where Marshal is appropriate :

(1) Your data is not acyclic, contains closures, or needs sharing to
be compact enough.  Sexplib doesn't handle these.
(2) The data won't live long anyway.  As in: you're doing IPC between
known versions of Ocaml programs.
(3) You desperately need speed.  As in: you're processing 200GB of
Wikipedia data.
Then I can understand.
--
Berke Durak






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





--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] picking / marshaling to strings in ocaml-revision-stable way

2008-06-01 Thread Martin Jambon

On Sat, 31 May 2008, Berke Durak wrote:


On Sat, May 31, 2008 at 7:00 PM, Robert Fischer
<[EMAIL PROTECTED]> wrote:

How far is the reach from the Jane St S-exp library from producing JSON?  I've 
not actually looked at it, but that'd be super nifty in the interoperation 
world.


If you just want JSON syntax, you can use Sexplib to convert an
arbitrary type to a
Sexp.t

 type t = Atom of string | List of t list

and then output in Json format:

let rec output_json oc = function
| Atom u -> fprintf oc "%S" u
| List xl -> fprintf oc "[%a]" (fun oc xl -> List.iter (fun x ->
fprintf "%a," output_json x) xl) xl

You can then do the same thing for parsing.


You won't obtain anything useful if you treat Atoms as JSON strings and 
Lists as JSON arrays because JSON has also null, numbers, booleans and 
objects.


This is the JSON standard: http://www.json.org/

And that is the concrete type used to represent JSON trees in the 
json-wheel library (which json-static uses):


type json_type =
Object of (string * json_type) list
  | Array of json_type list
  | String of string
  | Int of int
  | Float of float
  | Bool of bool
  | Null


Cheers,

Martin

--
http://wink.com/profile/mjambon
http://mjambon.com

___
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] ANN: patterns v0.4

2008-06-20 Thread Martin Jambon

On Fri, 20 Jun 2008, Richard Jones wrote:


On Tue, Jun 17, 2008 at 10:58:35PM +0100, Jeremy Yallop wrote:

Nathaniel Gray wrote:

On Tue, Jun 17, 2008 at 4:20 AM, Jeremy Yallop <[EMAIL PROTECTED]>
wrote:

I'm pleased to announce a new release of `patterns', an OCaml
framework for writing extensions to pattern matching using Camlp4.


Ooh, very interesting!  Have you looked at "active patterns" in F#?
They look really useful and I've been wanting to code them up in
camlp4 for a while now but haven't had the time.  It sounds like your
framework could make that much easier.


Yes, one of the reason for writing the framework was to be able to
implement F#-like active patterns.  I think it should be reasonably
straightforward to do -- in fact, I'd expect design considerations to
take up more time than actual implementation work (although I say that
from the perspective of being already familiar with the "patterns"
framework, of course).  If I remember rightly, there's a note at the end
of the ICFP07 active patterns paper about using polymorphic variants to
add active patterns in OCaml, which seems like it might be a good
starting point.


Can someone summarise active patterns for us?  The MSDN site
containing the paper is down at the moment.


You might also be interested in the "views" feature of Martin Jambon's
"Micmatch", which is along the same lines as active patterns:

 http://martin.jambon.free.fr/micmatch-manual.html#htoc10


Is anyone working on upgrading micmatch to 3.10?


I am, but I don't spend as much time on my personal projects than I used 
to, so it goes slowly.


The dev page is at http://forge.ocamlcore.org/projects/micmatch/
There's a subversion repository. Although the code is currently unusable
you can see if there's some progress:

http://forge.ocamlcore.org/plugins/scmsvn/viewcvs.php/trunk/micmatch-redux/?root=micmatch


Martin

--
http://wink.com/profile/mjambon
http://mjambon.com/

___
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] ocamlhackers.ning.com is open

2008-06-26 Thread Martin Jambon

I couldn't resist creating an OCaml social network at Ning:

  http://ocamlhackers.ning.com/

It's free and easy. Allows you to have your OCaml blog and exclusively 
OCaml friends. If you like this, join now :-)




Martin

--
http://wink.com/profile/mjambon
http://mjambon.com/

___
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] New library: Easy-format 0.9.0

2008-07-09 Thread Martin Jambon

Hi list,

I would like to announce a small library (a module in fact) that is meant 
to make it easy to produce pretty-printed text:


  http://martin.jambon.free.fr/easy-format.html

The data to be printed goes through a tree that carries all the 
information required for pretty-printing. After that, a single call to 
Easy_format.Pretty.to_stdout (for instance) outputs the indented result.


There's a reasonably complete example at

  http://martin.jambon.free.fr/easy_format_example.html


Comments and suggestions for improvement are welcome.
Enjoy.


Martin

--
http://wink.com/profile/mjambon
http://mjambon.com/

___
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


Easy-format 1.0.0 (Re: [Caml-list] New library: Easy-format 0.9.0)

2008-07-13 Thread Martin Jambon

I've just released a richer version of Easy-format.
The main URL is still http://martin.jambon.free.fr/easy-format.html

It now offers the following additional features:

- Support for separators that stick to the next list item (e.g. "|")
- More wrapping options
- Added Custom kind of nodes for using Format directly or existing
  pretty-printers
- Support for markup and escaping, allowing to produce colorized output
  (HTML, terminal, ...) without interfering with the computation of
  line breaks and spacing.

Easy-format now takes advantage of most features of the Format module, 
with the notable exception of tabulation boxes. I'd be curious so see any 
interesting use of tabulation boxes.



This release has slight incompatibilities with version 0.9.0 which was 
released earlier this week, simply because more options were added:


- Deprecated use of Easy_format.Param. Instead, inherit from
  Easy_format.list,
  Easy_format.label or Easy_format.atom.
- Atom nodes have now one additional argument for parameters.
- All record types have been extended with more fields.
  Using the "with" mechanism for inheritance is the best way of limiting
  future incompatibilities.


Martin

--
http://mjambon.com/
http://wink.com/profile/mjambon
http://ocamlhackers.ning.com/profile/MartinJambon

___
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] Mutually recursive types in different modules

2008-07-14 Thread Martin Jambon

On Mon, 14 Jul 2008, Andre Nathan wrote:


Hello

Say I have the following type definition:

 type a = { x: int; foo: b } and  b = { y: int; bar: a }

Is it possible to define types a and b in their own files (thus in
modules A and B) and still allow them to be mutually recursive?


No.
The usual way to proceed is to use one file for the type definitions and 
as many files as you want for the implementation.


If after that you want to make the types abstract for external use, you 
can use the -pack option of ocamlc or ocamlopt. It lets you define a 
super module with its own .mli file.



Martin

--
http://wink.com/profile/mjambon
http://mjambon.com/

___
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] Another question about modules

2008-07-15 Thread Martin Jambon

On Tue, 15 Jul 2008, Andre Nathan wrote:


Hi

I've run this:

ocamlc -c a.mli
ocamlc -c b.mli
ocamlopt -c a.ml

The third command gives the error. I thought that the circular
dependency problem was related only to mutually-dependent types on
separate modules, but I guess I was wrong.

Searching the archives, it seems that the solution is to eliminate the
references to B in A by passing a function argument to A.f, as in

 type t = { id: int }
 let f bfun x = print_int x.id; bfun x

and then in b.ml something like

 let f x = print_endline (string_of_int 42)
 let _ = let a = { A.id = 1 } in A.f f a

That appears to solve the issue, although in my actual code it means
adding an extra parameter to many functions, since the call to what was
B.f here is somewhat deep in the call stack, so maybe there is a better
solution.


If you have no other choice, you can do something like that:

--- a.ml ---

let b_fun_ref = ref (fun _ -> assert false)
let b_fun x = !b_fun_ref x

let a_fun x =
  ...
  b_fun
  ...

--- b.ml ---

let b_fun x =
 ...
 A.a_fun
 ...

let () =
  A.b_fun_ref := b_fun



For complex projects, the object system happens to be an excellent way of 
avoiding interdependency problems:


* You define class types early. Not a requirement, but highly recommended.
* You develop independent modules that would work with objects of these
  class types, without worrying about inter-dependencies.
* You just pass objects around, since they carry all the functions needed.
* You can have different implementations of the same class type.
* You can use inheritance.

In my opinion, using OCaml objects makes sense only in large 
projects. It's not theoretically or algorithmically exciting, but makes 
things manageable without magic skills.


I would say that objects are not well-suited to represent nodes 
of low-level data structures, because of performance but 
also because you may want to use pattern matching, circularity and other 
things that tuples, records and variants do better.



I hope you'll find this useful
:-)


Martin



Thanks,
Andre

On Tue, 2008-07-15 at 20:18 -0400, Ashish Agarwal wrote:

Firstly, you have a circular dependency. How are you compiling? That
should be the first error you get.


On Tue, Jul 15, 2008 at 6:51 PM, Andre Nathan <[EMAIL PROTECTED]>
wrote:
I think this is similar to this simpler problem:

a.ml:

 type t = { id: int }
 let f x = print_int x.id; B.f x

a.mli:

 type t
 val f : t -> unit


b.ml:

 let f x = print_int 42

b.mli:

 val f : A.t -> unit


Which results in "This expression has type t but is here used
with type
A.t" in a.ml, even though t and A.t are the same type. Is
there a
general solution for this kind of situation?

Thanks,

Andre

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



--
http://wink.com/profile/mjambon
http://mjambon.com/

___
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] Released Mikmatch 1.0.0 and Micmatch 1.0.0

2008-07-26 Thread Martin Jambon

Hi list,

I am pleased to announce the availability of Micmatch for the new Camlp4.
The new package is called "Mikmatch", with a K. "Micmatch" with a C refers 
to the original implementation which now uses Camlp5.


http://martin.jambon.free.fr/micmatch.html

or  GODI if you want to jump directly to the installation.


Micmatch is a Camlp4 syntax extension that allows to use regexps in 
match-with constructs. Compilation of the underlying PCRE or Str regexp is 
done transparently, just once. The syntax of the regexps is reminiscent of 
ocamllex. For those who are not familiar with ocamllex, this syntax is 
very OCaml-friendly and in particular avoids backslash headaches.



This is a double announcement:

micmatch-1.0.0 (stable except for possibly some packaging issues):
  Legacy implementation, slightly modified to work with
  Camlp5 (thanks to John Gregorski for the patch).

mikmatch-1.0.0 (beta quality):
  Partial reimplementation that supports Camlp4 3.10 aka the
  "new Camlp4". Currently there is no toplevel support.
  For details on the changes, see
  http://martin.jambon.free.fr/mikmatch-changes.txt


Have fun, program safely, and please report problems to

  [EMAIL PROTECTED]
  (archive at http://groups.google.com/group/micmatch )


Thanks to the OCamlForge team for providing free and worry-free hosting.


Martin

--
http://mjambon.com/
Join http://ocamlhackers.ning.com/

___
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] Released Mikmatch 1.0.0 and Micmatch 1.0.0

2008-07-28 Thread Martin Jambon

On Mon, 28 Jul 2008, SerP wrote:


Martin Jambon wrote:

 Hi list,

 I am pleased to announce the availability of Micmatch for the new Camlp4.
 The new package is called "Mikmatch", with a K. "Micmatch" with a C refers
 to the original implementation which now uses Camlp5.

Are you planning to return the support of revised syntax?


Maybe, maybe not. I will depend on my mood.


Martin

--
http://mjambon.com/
Join http://ocamlhackers.ning.com/

___
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] Why is this coercion necessary?

2008-08-14 Thread Martin Jambon

On Wed, 13 Aug 2008, Jacques Carette wrote:

Here is a much simplified version from a (much) larger problem I have 
recently encountered:


type 'a a = [`A of 'a b]
and 'a b  = [`B of 'a a]
and 'a c  = [`C ]

type 'a d = [ 'a a | 'a b | 'a c]
type e = e d

# this code gives an error (details below)
let f1 (x:e) : e = match x with
  |  `A n -> n
  |  `B n -> n
  |  `C   -> `C

# this works
let f2 (x:e) : e = match x with
  |  `A n -> (n :> e)
  |  `B n -> (n :> e)
  |  `C   -> `C

f1 gives an error  on the "| `B n -> n" line, pointing to the second 'n' with
This expression has type e a but is used with type e b
These two variant types have no intersection

Indeed, they have no intersection, but they have a union!  That is what it 
seems the coercion in f2 'forces' the type-checker to realize, and all works 
fine.  But of course, such coercions end up polluting my code all over the 
place (since the actual example is made of 9 types with 20 tags in total, and 
the 'recursive knot' requires 2 parameters to close properly).


So, is this a bug?  Is there a way to avoid these coercions?



The following works, but I doubt it would make your code shorter:


type 'a a = [`A of 'a b]
and 'a b  = [`B of 'a a]
and 'a c  = [`C ]

type 'a d = [ 'a a | 'a b | 'a c]
type e = e d

type f = [`A of e | `B of e | `C ]

let f3 (x:e) : e = match (x :> f) with
   | `A n -> n
   | `B n -> n
   | `C   -> `C


Martin

--
http://mjambon.com/

___
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] Specifying recursive modules?

2008-08-20 Thread Martin Jambon

On Wed, 20 Aug 2008, Jérémie Lumbroso wrote:


Hello,

I'd always thought of separating specification and definition as
simply not possible in OCaml, but OCaml's reference manual (3.10,
which is, as far as I can tell, the most recent version of the
documentation) seems to contradict my assumption:

http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html#htoc100

It says that recursive specifications can be written as:

 
 module rec  :  { and ... }
 

What does this mean? When I attempt to use this feature in the
toplevel, it results in an error:

 
 # module rec Tmp : sig
 type t = Stop | Next of Tmp.t
   end**;;**
 Syntax error
 


This is a signature item, i.e. goes directly in a .mli file or
in the definition of a module signature:

module type X =
sig

  module rec A :
  sig
type t = A of B.t
  end
  and B :
  sig
type t = B of A.t
  end

end


Martin



On the off-chance that OCaml might explicitly need an "and", I also
tried adding a second dummy module to the definition, but no dice ...
When I try to use this feature in a .mli/.ml file coupling, I get the
same (syntax) error. Have I misunderstood the usage? Or has this been
removed since its introduction (and the documentation not updated
accordingly)? Or is this a bug?

Jérémie

___
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



--
http://mjambon.com/___
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] How to join ocaml-tutorial.org?

2008-08-31 Thread Martin Jambon

Hi list,

Is it possible to create new user accounts to edit the OCaml tutorial at
http://ocaml-tutorial.org/ ?

http://ocaml-tutorial.org/_login says "This site is only available for use 
to registered members. If you believe that you should be a member of this 
site, please contact the administrator with your email address and reason 
for joining."


But it doesn't says who the administrator is. Richard, do you still have 
the admin rights? If not, what's the cheapest solution to circumvent the 
problem?



Thanks,


Martin

--
http://mjambon.com/

___
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 join ocaml-tutorial.org?

2008-09-01 Thread Martin Jambon

On Sun, 31 Aug 2008, Richard Jones wrote:


On Sun, Aug 31, 2008 at 03:40:42PM +0200, Martin Jambon wrote:

Is it possible to create new user accounts to edit the OCaml tutorial at
http://ocaml-tutorial.org/ ?

http://ocaml-tutorial.org/_login says "This site is only available for use
to registered members. If you believe that you should be a member of this
site, please contact the administrator with your email address and reason
for joining."

But it doesn't says who the administrator is. Richard, do you still have
the admin rights? If not, what's the cheapest solution to circumvent the
problem?


Yes it is possible, and yes I still do have admin rights (I should
hope, since I run the domain & servers :-)  Because of a huge amount of
spam I was forced to disable free account creation a few months ago.


Now I'm seeing this on the bottom of the first page: "This website is a 
wiki. This means you can edit any page to correct mistakes or improve the 
tutorial. Because of spammers signing up endless fake accounts, I have 
disabled new account creation. Please email rich on-the-annexia.org 
server for a new account."


I think it would be great if you could make this info visible on
http://ocaml-tutorial.org/_login



I've sent an email invite to your current email address.  Anyone else
who has problems, please send me an email and include 'ocaml'
prominently in the subject line.


Thanks. It was primarily for someone (Gregoire Seux, cc'ed) who made a 
French translation of 2 pages and was asking me to put this into the 
wiki.




Also I hope this is of interest: I've picked up mod_caml & cocanwiki
development again for Fedora & RHEL, so I should have F10 packages for
them shortly, plus an active upstream.


Cool. I very much appreciate the non-bloated design.


Martin

--
http://mjambon.com/

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] Ocaml type with constraints?

2008-09-21 Thread Martin Jambon

On Mon, 22 Sep 2008, Andrej Bauer wrote:


Angela Zhu wrote:

Hi,

I want to define an OCaml type with constraints.
For example:

type item = Item of int * float;;

If here this float type is for price of some item, and I want to make sure
it is positive. In other words, if x = (xi, xf) of type item,
I want to enforce, xf must >= 0.

Is there a way to define OCaml type like this?


No, because Ocaml type checker always check all the types at compile
time. It is an undecidable problem whether a given expression of type
float evaluates to a non-negative number.


By the way, even float does not guarantee to have a number: 0./.0. 
compiles and runs happily.



Martin

--
http://mjambon.com/

___
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] Dum: dumper module with cycle detection

2008-09-22 Thread Martin Jambon

Hi list,

Wink.com is releasing a module called Dum for dumping data.
It derives from Dumper by Richard W Jones (now Std.dump in Extlib) and
from Size by Jean-Christophe Filliatre.

   http://oss.wink.com/dum/

The main improvement over the original Dumper is that shared values 
and therefore cycles are detected and labelled:


# let rec loopy = 1 :: 2 :: loopy in Dum.p loopy;;
- : string = "#0: (1 (2 #0))"

Dum was originally developed to print the maximum out of uncaught 
exceptions, since the standard Printexc.to_string does not go arbitrarily 
deep and this was occasionally a source of frustration.


Now data such as closure fields and object fields are dumped like regular 
data without causing particular problems or worries.


The output is pretty-printed and its size limit is configurable.


Enjoy!


Martin, for Wink.

--
http://wink.com/

___
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] mutually dependent class and type

2008-09-25 Thread Martin Jambon

On Fri, 26 Sep 2008, Sébastien Hinderer wrote:


Dear list,

Is there a (clean) way to define simultaneously a class and a type that
are mutually recursive ?


I don't think so, but you don't have to.


Something like this :
class element (c : content) =
object
 ...
end and type content =
 | Data of string
 | Elements of element list;;

This is of course not a valid OCaml definition, but is there a way to
express it ?


With each class comes a type of the same name. Such type can also be 
defined independently from the notion of class. It is syntactically like 
a record with angle brackets:


type element =
< content : content >

and content =
Data of string
  | Elements of element list;;

class element_class (c : content) =
object
  method content = c
end


# new element_class (Elements [ new element_class (Data "abc") ]);;
- : element_class = 


Martin


Many thanks in advance for your help,
Sébastien.

___
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



--
http://mjambon.com/___
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] Syntax highlighting and Ocaml/PHP integration

2008-10-01 Thread Martin Jambon

On Wed, 1 Oct 2008, Dario Teixeira wrote:


P.S.  Another (possibly far-fetched) solution is to take advantage of the
 syntax highlighting capabilities of Vim or Emacs.  Something along
 the lines of embedding or remotely invoking one of these editors,
 with the sole purpose of asking them to highlight a text file.
 Is this even possible?


I've used vim a little bit for my static webpages, here's the result:

http://martin.jambon.free.fr/hello.c.html
http://martin.jambon.free.fr/quine.sh.html
http://martin.jambon.free.fr/micmatch/Makefile.html


The script is:


#!/bin/sh -e

# Usage : any2html  [ ...]
# Requires : vim

[ $# -lt 1 ] && echo "Usage : $0   ..." && exit 1

while [ -n "$1" ]
do
file=`basename "$1"`
cp -f "$1" /tmp
vim -f +"syn on" +"so \\\$VIMRUNTIME/syntax/2html.vim" +"wq" +"q" 
/tmp/"$file"
cp -f /tmp/"$file".html "$1".html
shift
done
###


Martin
--
http://mjambon.com/

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] What does Jane Street use/want for an IDE? What about you?

2008-10-20 Thread Martin Jambon
Kuba Ober wrote:
> I have questions to the kind folks at Jane Street,
> and others who use OCaml for commercial/non-research
> development: what do you guys use for your development
> environment? What would be the minimal set of functionality
> that would make you happy for an IDE? What are killer features
> you dream of?

I'm working for wink.com (people search engine) and speaking on my own
behalf.

I use 16 (4x4) virtual Fvwm desktops with free mouse movement between
them and a small map of the desktops in the lower-right corner (+
xosview). The majority of the population finds this disturbing, I'm not
really sure why. I hate clicking or typing to switch from a window to
another so I just move my arm in order to place the mouse cursor over
the right window in the right virtual desktop as shown on the map.
That's the feature I was dreaming of until I discovered its existence,
quite a long time ago.

There are no icons or toolbar. A left-click anywhere on the background
displays a menu with the applications I commonly use, and that's enough.

Here are graphical applications I use:
* standard 80x25 xterm for filesystem navigation, commands and remote
logins.
* 80xN emacs
* wider xterm for reading log files with less, grep, etc.
* ocamlbrowser
* web browser
* IM client
* email client

Build tools:
* omake for large OCaml projects (which represents now more than 95% of
my time)
* whatever-works for small or public projects

Compilation:
* from within emacs with tuareg-mode (C-c C-c) or from an (O)Makefile
(C-x C-e)
* middle-click on the error message or warning brings me directly to the
error location (killer feature)
* compiling now always with -dtypes; C-c C-t shows the type under the
cursor (killer feature; requires caml-mode installed if I remember
correctly)

Editor:
* emacs + tuareg-mode for OCaml
* still emacs for any other text format

Testing:
* ocaml toplevel within emacs (C-x C-e to evaluate a phrase in tuareg-mode)
* or ocaml toplevel + xterm + ledit
* programs are run from an xterm
* I'm close to totally ignorant about ocamldebug. Maybe a graphical
interface would help (is there any?).


All of this is the best combination for me because I chose it myself
from the largest choice available. I must say I don't understand the
meaning or the need for the I in IDE. What I use is accessible using a
single monitor, a keyboard and a mouse + a desk + paper and pen.
Technically it is integrated on my desk, I have full control over it, it
is safe, it does what I want and never does what I don't want.

Now I hope someone will react and tell me the benefits of "Integrated"
but so far it looks to me that the close interaction between the build
system, the file system and the text editor is taken care of nicely by
emacs+tuareg-mode.


> I'm trying to come up with a longer time plan for Camelia --
> this so far relegated, to the dismay of my wife and daughter
> -- to prolonging my morning showers, so I may as well ask
> around. None of those plans/feedback would have immediate
> effect, but I wouldn't mind it simmering for a bit.
> 
> The reason I got into camelia is not only OCaml, but it
> seems like a small and manageable enough IDE to base
> other tools that I'm working on for various embedded
> architectures. In the long run, for Windows platform
> I will statically link it and literally have it be
> a single executable, so that it can be trivially
> shared, it would also make it easier to consume
> by people on locked-down computers where software
> installations are disallowed. Of course OCaml is another
> deal here, but you have to start with something :)

I would already be unhappy and underproductive with KDE, so don't even
mention Windows and its single virtual desktop. (How do people manage
20+ windows without using several virtual desktops? I can't because I
need to switch between them all the time)

The great thing about an all-in-one-app solution is that it makes it
possible to get started quickly, which is great for teaching a
programming language to inexperienced students.

For a daily use it seems to me like a source of frustration and waste of
productivity.


Martin

-- 
http://mjambon.com/

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] What does Jane Street use/want for an IDE? What about you?

2008-10-25 Thread Martin Jambon
DooMeeR wrote:
> Another possibility is:
> 
> let x = List.map begin fun z ->
>  very_blabla
> end my_list in
> 
> It's quite compact, doesn't run into the margin, is consistent with
> tuareg, but might be less readable.

Now I generally tend to use this:

let x =
  List.map (
fun z ->
  very_blabla
  ...
  ) my_list
in
...

I find that the most significant barrier is of psychological nature.
This formatting of parentheses is unnatural in natural languages and in
mathematics.

Other than that, it's no different from curly braces as used in the
C-like syntaxes.

The additional 2 or 3 lines are generally negligible and introduce some
vertical spacing which improves readability.


Martin

-- 
http://mjambon.com/

___
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


Indentation (was Re: [Caml-list] What does Jane Street use/want for an IDE? What about you?)

2008-10-25 Thread Martin Jambon
Daniel Bünzli wrote:
> 
> Le 25 oct. 08 à 14:43, Martin Jambon a écrit :
> 
>> Now I generally tend to use this:
>>
>> let x =
>>  List.map (
>>fun z ->
>>  very_blabla
>>  ...
>>  ) my_list
>> in
> 
> I think the best solution is to name your anonymous function, as the
> guidelines suggest [1].

It says: "Justification: Much clearer, in particular if the name given
to the function is meaningful."

I think that's true for typical functional code which follows some clear
logic or model.

In many cases it's not possible to give a meaningful name to such a
function and defining it out of the current block can make things
needlessly hard to follow.

I can think of 4 cases:

1. anonymous function that fits on one line
2. anonymous function that doesn't fit on one line (my original example)
3. named function defined locally using let-in
4. named function defined globally using let

I don't use (3) very much since:
* it still causes the outermost function definition to be very long and
hard to follow like (2),
* and it's okay to define a function globally (4) because there is no
serious risk of global namespace pollution, thanks to the module system.

I think (3) is most useful for defining named functions that depend on a
lot of locally-defined values. This creates a closure, which is often
acceptable performance-wise, instead of having to make each parameter of
the function explicit.

In performance-critical code or maybe imperative code in general, it
feels good to control when closures are created. In such cases, avoiding
local functions helps.


Martin

-- 
http://mjambon.com/

___
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: Indentation (was Re: [Caml-list] What does Jane Street use/want for an IDE? What about you?)

2008-10-26 Thread Martin Jambon
Daniel Bünzli wrote:
> 
> Le 26 oct. 08 à 01:08, Martin Jambon a écrit :
> 
>> In performance-critical code or maybe imperative code in general, it
>> feels good to control when closures are created. In such cases, avoiding
>> local functions helps.
> 
> Just to be clear, naming your anonymous function locally (which is what
> is recommended) or not naming it doesn't make any performance difference
> AFAIK.

What I mean is that:


let f x y = x + y

let g x l =
  List.map (f x) l


is clearer than:


let g x l =
  let f y = x + y in
  List.map f l


in the sense that it is obvious that a closure is created in the first
case, while it is less visible in the second case.



Martin

-- 
http://mjambon.com/

___
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] understanding weak

2008-10-30 Thread Martin Jambon
Warren Harris wrote:
> I'd like to understand better how ocaml's weak pointers operate. First,
> although it doesn't seem to be specified in the documentation, I assume
> that weak pointers will *not* be reclaimed (e.g. from a weak hash table)
> if the program retains some other reference to the object. I.e. the weak
> pointer must be the last remaining pointer to the object for reclamation
> to occur.

Yes, otherwise the program would crash.

> My second question relates specifically to my application. I would like
> to have a primary cache of objects, and a secondary index into
> sub-objects referenced from the primary cache. I.e. CacheA references
> objects of type A; objects of type A reference objects of type B; CacheB
> references objects of type B. I would like to guarantee that weak
> references in CacheB are not flushed unless the corresponding reference
> from CacheA is first flushed. I assume will be the case if a non-weak
> reference from A to B is maintained. Can anyone verify?

Weak pointers are useful for data that should be shared by several
independent "users" and discarded when the number of users drops to zero.

I wouldn't call your CacheB a cache if it is a weak array or a weak hash
table. It is a table of shared objects. These objects of type B are
shared by objects of type A and possibly other users of CacheB.



Martin

-- 
http://mjambon.com/

___
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] understanding weak

2008-10-31 Thread Martin Jambon
Daniel Bünzli wrote:
> 
> Le 31 oct. 08 à 03:14, Martin Jambon a écrit :
> 
>> Warren Harris wrote:
>>> I'd like to understand better how ocaml's weak pointers operate. First,
>>> although it doesn't seem to be specified in the documentation, I assume
>>> that weak pointers will *not* be reclaimed (e.g. from a weak hash table)
>>> if the program retains some other reference to the object. I.e. the weak
>>> pointer must be the last remaining pointer to the object for reclamation
>>> to occur.
>>
>> Yes, otherwise the program would crash.
> 
> No since Weak.get returns an option type. As written the documentation
> sounds like the binding could disappear from the array even though the
> program still has references to the value. This could be done, wouldn't
> be usefull, but wouldn't crash the program.

let x = (1, 2);;
let wa = Weak.create 10;;
Weak.set wa 0 (Some x);;
...
print_int (fst x);;

(fst x) would certainly cause funny effects if x were GC'ed at an
arbitrary time after it has been added to the weak array.

An object can be reclaimed by the GC only if there is no reference to
it. This remains true. Adding an object to a weak array just doesn't
count as a reference.



Martin

-- 
http://mjambon.com/

___
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] understanding weak

2008-10-31 Thread Martin Jambon
Daniel Bünzli wrote:
> 
> Le 31 oct. 08 à 15:57, Martin Jambon a écrit :
> 
>> (fst x) would certainly cause funny effects if x were GC'ed at an
>> arbitrary time after it has been added to the weak array.
> 
> You are confusing reclaiming the weak pointer (the Some x) and
> reclaiming what the weak pointer refers to (the x). It's the former the
> OP was talking about.

I don't see what makes you define (Some x) as a weak pointer.


Martin
-- 
http://mjambon.com/

___
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] understanding weak

2008-10-31 Thread Martin Jambon
Aleksey Nogin wrote:
> On 31.10.2008 07:57, Martin Jambon wrote:
> 
>> let x = (1, 2);;
>> let wa = Weak.create 10;;
>> Weak.set wa 0 (Some x);;
>> ...
>> print_int (fst x);;
>>
>> (fst x) would certainly cause funny effects if x were GC'ed at an
>> arbitrary time after it has been added to the weak array.
>>
>> An object can be reclaimed by the GC only if there is no reference to
>> it. This remains true. Adding an object to a weak array just doesn't
>> count as a reference.
>>
> Martin,
> 
> You are answering the wrong question - you are answering "could x be
> GCed too early?" - the answer is obviously "no". However, the initial
> question was "could (Some x) be removed from wa too early by GC - before
> x is orphaned?" The answer is "we'd hope not", but the documentation is
> somewhat ambiguous.

OK. I think now I understand the question :-)
And we all agree that the documentation could be clearer.

What I'm wondering is why there is one Weak.set function that takes an
option as argument rather than a pair Weak.set/Weak.clear.

What is certain is that some (re)boxing is done by Weak.get:

# let a = Weak.get wa 0;;
val a : (int * int) option = Some (1, 2)
# let b = Weak.get wa 0;;
val b : (int * int) option = Some (1, 2)
# a == b;;
- : bool = false

Of course it doesn't tell whether the original (Some x) is stored as-is
but copied by Weak.get or if x is stored unwrapped.

I think I'll just take a look at the implementation. That can only be a
good thing.


Martin
-- 
http://mjambon.com/

___
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] understanding weak

2008-10-31 Thread Martin Jambon
Aleksey Nogin wrote:
> On 31.10.2008 07:57, Martin Jambon wrote:
> 
>> let x = (1, 2);;
>> let wa = Weak.create 10;;
>> Weak.set wa 0 (Some x);;
>> ...
>> print_int (fst x);;
>>
>> (fst x) would certainly cause funny effects if x were GC'ed at an
>> arbitrary time after it has been added to the weak array.
>>
>> An object can be reclaimed by the GC only if there is no reference to
>> it. This remains true. Adding an object to a weak array just doesn't
>> count as a reference.
>>
> Martin,
> 
> You are answering the wrong question - you are answering "could x be
> GCed too early?" - the answer is obviously "no". However, the initial
> question was "could (Some x) be removed from wa too early by GC - before
> x is orphaned?" The answer is "we'd hope not", but the documentation is
> somewhat ambiguous.

So I checked the implementation and it turns out that x is unboxed from
(Some x) before being added to the weak array.

x is really the value that matters and of course not keeping any
reference to (Some x) has no importance.

The weak pointer is x (or a null value), stored as a cell of the weak array.


Martin
-- 
http://mjambon.com/

___
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] Hiding a public module/type?

2008-11-03 Thread Martin Jambon
David Teller wrote:
>  Dear list,
> 
>  In order to simplify the error messages for users of my library, I'd
> like to hide some type aliasing.
> 
> I have the following:
> 
> (*** module [Inner], defined in inner.mli ***)
> type t
> 
> 
> (*** module [Outer], defined in outer.mli ***)
> type t = Inner.t
> val f : t -> t
> 
> 
> Now, module [Inner] is only useful to define the library and shouldn't
> be visible from the outside. Unfortunately, for the moment, whenever a
> client makes a type error involving [f], the error message looks like
> 
> # f 5;;
> ^
> This expression has type int but is used with type
>  Outer.t = Inner.t
> 
> Is there a simple way of turning this error message into
> 
> This expression has type int but is used with type
>  Outer.t
> ?

One solution consists in using submodules for achieving an intermediate
level of privacy ("friend" modules):

$ cat inner.mli
type t = int

$ cat outer.mli
type t = Inner.t
val f : t -> t

$ cat packed.mli
module Outer :
sig
  type t
  val f : t -> t
end


Create valid inner.ml and outer.ml files but no packed.ml.

Compile:

$ ocamlc -c inner.mli
$ ocamlc -c outer.mli
$ ocamlc -c inner.ml
$ ocamlc -c outer.ml

Pack:

$ ocamlc -c packed.mli
$ ocamlc -pack -o packed.cmo inner.cmo outer.cmo


Then you only have to install the packed.cm* files. It gives you:

# Packed.Outer.f 5;;
This expression has type int but is here used with type Packed.Outer.t



Martin
-- 
http://mjambon.com/

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] Ocaml 3.01 and camlp4 syntax?

2008-11-12 Thread Martin Jambon
Erik de Castro Lopo wrote:
> Hi all,
> 
> Mostly out of curiosity, I'm having a look at the efuns Emacs
> clone written in Ocaml:
> 
> http://pauillac.inria.fr/cdrom/prog/unix/efuns/eng.htm
> 
> and trying to compile it with a recent Ocaml compiler like 3.10.2.
> 
>>From the files, it seems that the last version of Ocaml this code
> compiled with was 3.01 (around the year 2000?). I've managed to find
> fixes for a bunch of problems.
> 
> One of those problems was that one of the files (common/options.ml)
> had code like this:
> 
> open Genlex
>   
> let lexer = make_lexer [ "=" ; "{" ; "}"; "["; "]"; ";" ; "("; ")"; ","; 
> "."]
>   
> let rec parse_gwmlrc = parser
> [< id = parse_id; 'Kwd "="; v = parse_option ; 
>   eof = parse_gwmlrc >] -> (id, v) :: eof
> | [< >] -> []
> 
> which the current compiler complained about "[<". A bit of googling
> suggested that this was in fact camlp4 source code. Sure enough,
> renaming that file to pa_options.ml and running it throught camlp4
> resulted in a file that the standard compiler digested quite happily.
> 
> I've now come to another file gwml/afterstep.mll that seems to be
> ocamllex source code but again has these camlp4 like extensions.
> Unfortunately camlp4 doesn't like this file, probably because it
> has ocamllex syntax instead of ocaml syntax.
> 
> So, I have two questions :
> 
>  1) Did early versions of ocaml (say up to and including 3.01) handle
> constructs like those above that were later removed and and added
> to camlp4 instead?

Exactly.

The 3.10 manual says:


7.2  Streams and stream parsers

The syntax for streams and stream parsers is no longer part of the
Objective Caml language, but available through a Camlp4 syntax
extension. See the Camlp4 reference manual for more information. Support
for basic operations on streams is still available through the
Stream[Stream] module of the standard library. Objective Caml programs
that use the stream parser syntax should be compiled with the -pp
camlp4o option to ocamlc and ocamlopt. For interactive use, run ocaml
and issue the #load "camlp4o.cma";; command.



>  2) Any suggestions on how to handle the camlp4 syntax stuff in an
> ocamllex source file? Obviously, this code could be extracted
> and placed in its own file but I'm open to other suggestions.

I don't know. Have you tried ocamllex followed by camlp4?


Martin
-- 
http://mjambon.com/

___
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] Computing with big numbers?

2008-12-01 Thread Martin Jambon
Alan Schmitt wrote:
> Hello,
> 
> In preparation for a talk I'm going to give, I wanted to estimate how
> good 128 bits MD5 hashes were: how many hashes must be taken before the
> probability for a collision become non negligible? (I'm assuming
> equi-probability of every hash.)
> 
> The brute force approach is simply to enumerate the non-collision
> probability for k different hashes, and compute until it becomes lower
> than 1. This probability is (writing N for 2 ^ 128):
> N * (N-1) * (N - 2) * ... * (N - k)
> ---
> N^k
> 
> I tried computing this using the bignum library that comes with OCaml,
> and it slows down to a crawl very fast (for k ~ 1000).
> 
> So I tried to be more subtle and approximate the result (using
> Stirling's approximation of factorials), but OCaml's floats are not
> precise enough to yield anything significant. (I'm trying to compute the
> log of the approximation of N! / (N^k * (N-k)!), which is N (ln N) - N -
> (k (ln N) + (N - k)(ln (N - k)) - (N - k)).)
> 
> Is there a library with better floating point precision than the OCaml one?

If I understand your problem correctly, this is the so-called birthday
problem with 2^128 days in a year. The Wikipedia article gives useful
approximations:

http://en.wikipedia.org/wiki/Birthday_problem


Martin

-- 
http://mjambon.com/

___
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] Computing with big numbers?

2008-12-04 Thread Martin Jambon
Florian Hars wrote:
> Alan Schmitt schrieb:
>> But I don't think this applies here, as the hashes I'm
>> looking at are the one used by Unison to identify file contents.
> 
> Then it is *especially* relevant, as it is quite trivial to generate
> several files with  different content and the same MD5 hash, all you
> need is a Playstation 3:
> http://www.win.tue.nl/hashclash/Nostradamus/

It's like being able to manufacture a lock and the key that goes with
it: big deal!

:-)


Martin

-- 
http://mjambon.com/

___
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] Parsing simple type expressions

2009-01-06 Thread Martin Jambon
David Allsopp wrote:
> ocamlyacc - you can get most of it for free out of parsing/parser.mly in the 
> OCaml sources... the section on type expressions starts at line 1144 for 
> OCaml 3.11.0.

Our json-wheel library is a complete example:

http://martin.jambon.free.fr/json-wheel.html


Martin

>> -Original Message-
>> From: caml-list-boun...@yquem.inria.fr [mailto:caml-list-
>> boun...@yquem.inria.fr] On Behalf Of Paolo Donadeo
>> Sent: 06 January 2009 14:04
>> To: OCaml mailing list
>> Subject: [Caml-list] Parsing simple type expressions
>>
>> For a serializer I'm writing I need to parse simple OCaml type
>> expressions composed by OCaml basic types, tuples, options and lists.
>> Given a string like "(int * string option) list" and this type:
>>
>> type types =
>>   | Int
>>   | String
>>   | Float
>>   | Char
>>   | Bool
>>   | Option of types
>>   | List of types
>>   | Tuple of types list
>>
>> the function I need should return something like List (Tuple ([Int;
>> Option(String)]))
>>
>> Before starting with low level sscanf functions I looked at the Genlex
>> module, but it wasn't so inspiring. Then I tried with Camlp4 but the
>> documentation doesn't really shine :-)
>>
>> So is there a simple way to write this function using some standard
>> module?
>>
>> TIA,
>>
>>
>> --
>> Paolo
>> ~
>> ~
>> :wq

-- 
http://mjambon.com/

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] What is a future of ocaml?

2009-01-14 Thread Martin Jambon
Dawid Toton wrote:
> (say, following is a collection of dreams :))
> 
> Is there any hope for a grand 'OCaml 4' release that would iron out the
> last ugly spots left in the language with some breaking changes?
   ^^
Hahaha.

(the rest of my reaction is censored)



Martin

-- 
http://mjambon.com/

___
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] Making a polymorphic type non-polymorphic to comply with original signature

2009-01-20 Thread Martin Jambon
Hugo Ferreira wrote:
> Hello,
> 
> I have the following definition:
> 
> module rec H :
>   sig
>   type 'a node =
>   | Node of 'a node J.t
>   | Leaf of 'a
> 
>  type 'a t = 'a node
>  val equal : 'a t -> 'a t -> bool
> val hash : 'a t -> int
>   end =
> struct
> type 'a node =
> | Node of 'a node J.t
> | Leaf of 'a
> 
> type 'a t = 'a node
> let equa = (==)
> let hash = Hashtbl.hash
> end
> 
> and J : Hashtbl.S with type 'a key = 'a H.node = Hashtbl.Make( H )
> ;;
> 
> The data type 'a node is polymorphic. It is also a key used by the
> hash-table. Note that H now does not comply with Hashtbl.HashedType
> (because Hashtbl.HashedType is not polymorphic). By adding the
> constraint "with type" also does not help.
> 
> Is it possible to make H comply with Hashtbl.HashedType i.e: make
> J.Key = 'a H.node ?


I just posted an implementation of polymorphic hash tables with physical
comparison, using the Obj module:

  http://martin.jambon.free.fr/phys.html

It is the following code:

(* phys.mli *)

type ('a, 'b) t

val add : ('a, 'b) t -> 'a -> 'b -> unit
val clear : ('a, 'b) t -> unit
val copy : ('a, 'b) t -> ('a, 'b) t
val create : int -> ('a, 'b) t
val find : ('a, 'b) t -> 'a -> 'b
val find_all : ('a, 'b) t -> 'a -> 'b list
val fold : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c
val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit
val length : ('a, 'b) t -> int
val mem : ('a, 'b) t -> 'a -> bool
val remove : ('a, 'b) t -> 'a -> unit
val replace : ('a, 'b) t -> 'a -> 'b -> unit



(* phys.ml *)

(*
  This implementation uses the Obj module which allows to transgress
  the type system. It is not regular OCaml.
*)

module Magic_key =
struct
  type t = Obj.t
  let equal = ( == )
  let hash = Hashtbl.hash
end

module Magic_table = Hashtbl.Make (Magic_key)


type ('a, 'b) t = 'b Magic_table.t

let add tbl k v = Magic_table.add tbl (Obj.repr k) v
let clear tbl = Magic_table.clear tbl
let copy tbl = Magic_table.copy tbl
let create n = Magic_table.create n
let find tbl k = Magic_table.find tbl (Obj.repr k)
let find_all tbl k = Magic_table.find_all tbl (Obj.repr k)
let fold f tbl accu = Magic_table.fold (Obj.magic f) (Obj.magic tbl) accu
let iter f tbl = Magic_table.iter (Obj.magic f) (Obj.magic tbl)
let length tbl = Magic_table.length tbl
let mem tbl k = Magic_table.mem tbl (Obj.repr k)
let remove tbl k = Magic_table.remove tbl (Obj.repr k)
let replace tbl k v = Magic_table.replace tbl (Obj.repr k) v


(*)



Martin

-- 
http://mjambon.com/

___
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] Warning wished

2009-01-28 Thread Martin Jambon
Julien SIGNOLES wrote:
> Hello,
> 
> Is it a bug or a well-known feature that the above program does not emit
> a warning (because "f x" should have type unit in the body of "g") ?
> 
> =
> let f x = x
> let g x = f x; 1
> (* let _ = g 2 *)
> 

The compiler could have a command-line switch that enforces the unit type in
sequences, i.e. it would add type annotations for you:

let f x = x
let g x = (f x : unit); 1

There's a camlp4/camlp5 syntax extension that does this (but I don't use it).


Martin

-- 
http://mjambon.com/

___
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] Hiding private types

2009-02-10 Thread Martin Jambon
David Rajchenbach-Teller wrote:
>  Dear list,
> 
>  I'm looking for a way to remove one or two annoyances of Batteries,
> which are related to private magic leaking into the type system and into
> the documentation.
> 
> 
> 
> We define a module [IO] with, among other things, a type [output]. In
> fact, in order to avoid circular dependencies, [output] is actually
> defined in a private module [InnerIO], which lets other modules such as
> [ExtString] use [output] and still be used by [IO]. For instance,
> [ExtString] defines a function [print : InnerIO.output -> string ->
> unit].
> 
> At a later stage, we pack [IO], [InnerIO], [ExtString] and others into a
> module [Extlib] and we later define a module [Batteries] containing
> 
> module IO  = Extlib.IO
> module String = ExtString.String
> 
> etc.
> 
> 
> Now, all of this works. Unfortunately, the types visible by the user,
> either from the toplevel, from error messages or from -dannot, reveal
> too much from the inner workings of Batteries.
> 
> For instance,  [InnerIO], as implied by the name, is private. The
> existence of this module should not be visible by the user.
> Unfortunately, on the toplevel, we have
> 
> # String.print;;
> - : Extlib.InnerIO.output -> string -> unit = 
> 
> Two abstractions have leaked out:
> * the existence of [InnerIO]
> * the existence of [Extlib]
> 
> I would rather have
> 
> # String.print;;
> - : IO.output -> string -> unit = 
> 
> or, at worst
> 
> # String.print;;
> - : Batteries.IO.output -> string -> unit = 
> 
> 
> Does anyone have an idea of how we could/should do this?


It looks like you can applying a signature to Batteries.IO does the trick:

(* IO's signature *)
module type A_sig =
sig
  type t
  val add : t -> t -> t
  val create : unit -> t
end

(* Extlib.IO *)
module A : A_sig =
struct
  type t = int
  let add = ( + )
  let create () = 1
end

(* Batteries.IO, version 1 *)
module B = A

(* Batteries.IO, version 2 *)
module C : A_sig = A


This is the problem that you're having, i.e. A.t appears in the error message:

# B.create () = 1;;
Characters 14-15:
  B.create () = 1;;
^
This expression has type int but is here used with type B.t = A.t


This looks better:

# C.create () = A.create ();;
Characters 14-25:
  C.create () = A.create ();;
^^^
This expression has type A.t but is here used with type C.t



I just hope it works for your problem.



Martin

-- 
http://mjambon.com/

___
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] speeding up matrix multiplication (newbie question)

2009-02-20 Thread Martin Jambon
Erick Matsen wrote:
> Wow, once again I am amazed by the vitality of this list. Thank you
> for your suggestions.
> 
> Here is the context: we are interested in calculating the likelihood
> of taxonomic placement of short "metagenomics" sequence fragments from
> unknown organisms in the ocean. We start by assuming a model of
> sequence evolution, which is a reversible Markov chain. The taxonomy
> is represented as a tree, and the sequence information is a collection
> of likelihoods of sequence identities. As we move up the tree, these
> sequences "evolve" by getting multiplied by the exponentiated
> instantaneous Markov matrix.
> 
> The matrices are of the size of the sequence model: 4x4 when looking
> at nucleotides, and 20x20 when looking at proteins.
> 
> The bottleneck is (I mis-spoke before) that we are multiplying many
> length-4 or length-20 vectors by a collection of matrices which
> represent the time evolution of those sequences as follows.
> 
> Outer loop:
>   modify the amount of time each markov process runs
>   exponentiate the rate matrices to get transition matrices
> 
>   Recur over the tree, starting at the leaves:
> at a node, multiply all of the daughter likelihood vectors together
> return the multiplication of that product by the trasition matrix
> (bottleneck!)
> 
> The trees are on the order of 50 leaves, and there are about 500
> likelihood vectors done at once.
> 
> All of this gets run on a big cluster of Xeons. It's not worth
> parallelizing because we are running many instances of this process
> already, which fills up the cluster nodes.
> 
> So far I have been doing the simplest thing possible, which is just to
> multiply the matrices out like \sum_j a_ij v_j. Um, this is a bit
> embarassing.
> 
> let mul_vec m v =
> if Array.length v <> n_cols m then
>   failwith "mul_vec: matrix size and vector size don't match!";
> let result = Array.create (n_rows m) N.zero in
> for i=0 to (n_rows m)-1 do
>   for j=0 to (n_cols m)-1 do
>   result.(i) <- N.add result.(i) (N.mul (get m i j) v.(j))
>   done;
> done;
> result
> 
> I have implemented it in a functorial way for flexibility. N is the
> number class. How much improvement might I hope for if I make a
> dedicated float vector multiplication function? I'm sorry, I know
> nothing about "boxing." Where can I read about that?

Depending on the savings, you can afford to spend more or less time optimizing
this. Here are some simple things to consider:

In the OCaml land, try first getting rid of the functor (or use a
defunctorizer; ocamldefun?).

Limit memory accesses, by doing something like:

for i = 0 to m - 1 do
  let a_i = m.(i) in
  for j = 0 to n - 1 do
let a_ij = a_i.(j) in (* instead of a.(i).(j) *)
...
  done
done

Also you can use Array.unsafe_get where it really matters.


You can also use bigarrays and implement the loop in C. It could be fun. I'm
not sure how much it saves.


Martin

___
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] Using camlp4 syntax extensions in the top-level

2009-02-25 Thread Martin Jambon
David Allsopp wrote:
> I'm trying to use json-static in the toplevel (OCaml 3.11.0 / MinGW /
> findlib 1.2.4) but I'm getting an error message:
> 
> # #camlp4o;;
> C:\Dev\OCaml\lib\dynlink.cma: loaded
> C:\Dev\OCaml\lib\camlp4: added to search path
> C:\Dev\OCaml\lib\camlp4\camlp4o.cma: loaded
> Camlp4 Parsing version 3.11.0
> 
> # #require "json-static";;
> c:\Dev\OCaml\lib\site-lib\pcre: added to search path
> c:\Dev\OCaml\lib\site-lib\pcre\pcre.cma: loaded
> c:\Dev\OCaml\lib\site-lib\netsys: added to search path
> c:\Dev\OCaml\lib\site-lib\netsys\netsys.cma: loaded
> c:\Dev\OCaml\lib\site-lib\netstring: added to search path
> c:\Dev\OCaml\lib\site-lib\netstring\netstring.cma: loaded
> c:\Dev\OCaml\lib\site-lib\netstring\netstring_top.cmo: loaded
> c:\Dev\OCaml\lib\site-lib\netstring\netaccel.cma: loaded
> c:\Dev\OCaml\lib\site-lib\netstring\netaccel_link.cmo: loaded
> c:\Dev\OCaml\lib\site-lib\json-wheel: added to search path
> c:\Dev\OCaml\lib\site-lib\json-wheel\jsonwheel.cma: loaded
> c:\Dev\OCaml\lib\site-lib\json-static: added to search path
> c:\Dev\OCaml\lib\site-lib\json-static\pa_json_static.cmo: loaded
> # type json point = < x: number; y: number >
>   and coords = point array;;
> Assertion failed, file "camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml", line
> 795, char 11
> 
> I can build the example using ocamlc with no problems - I just don't seem to
> be able to do it interactively in the toplevel. Should I be able to?

In theory yes. It was working fine with the old camlp4 and ocaml 3.09.3.

The piece of code from which the failed assertion comes from is the following
(camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml version 3.11.0, line 795, char 11):


  and mktype_decl x acc =
match x with
[ <:ctyp< $x$ and $y$ >> ->
 mktype_decl x (mktype_decl y acc)
| Ast.TyDcl _ c tl td cl ->
let cl =
  List.map
(fun (t1, t2) ->
  let loc = Loc.merge (loc_of_ctyp t1) (loc_of_ctyp t2) in
  (ctyp t1, ctyp t2, mkloc loc))
cl
in
[(c, type_decl (List.fold_right type_parameters tl []) cl td) :: acc]
| _ -> assert False ]



I had no idea of this problem. Even a very simple example fails:


# type json t = int;;
Assertion failed, file "camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml", line 795,
char 11


The pretty-printed code produced by camlp4o is the following:


$ cat toto.ml
type json t = int

$ camlp4o -printer o -I /home/martin/godi3110/lib/ocaml/pkg-lib/json-static
-parser pa_json_static.cmo toto.ml

type t = int

let __json_static_error obj msg =
  let m = 400 in
  let s = Json_io.string_of_json obj in
  let obj_string =
if (String.length s) > m then (String.sub s 0 (m - 4)) ^ " ..." else s
  in Json_type.json_error (msg ^ (":
" ^ obj_string))

let rec (t_of_json : Json_type.t -> t) = fun x -> Json_type.Browse.int x

let rec (json_of_t : t -> Json_type.t) = fun x -> Json_type.Build.int x




There may be a workaround. It needs more investigation. Thanks for reporting
the problem.



Martin

-- 
http://mjambon.com/

___
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] stl?

2009-03-03 Thread Martin Jambon
Brian Hurt wrote:
> 
> 
> On Tue, 3 Mar 2009, Jon Harrop wrote:
> 
>> Functors give
>> you the same capability in OCaml but they are rarely used precisely
>> because
>> the functionality is not very useful.
> 
> I think I disagree with this.  I think functors aren't used very much in
> Ocaml because:
> 1) They're a big, scary name, and
> 2) They're slightly less efficient.

Functors are not used very much because they are not needed very often. OCaml
is a free market.

All sorts of reusable algorithms on arbitrary data can be nicely implemented
using functors, without more difficulty than the specialized versions of the
same algorithm. But do you often implement cool algorithms that work on
arbitrary types? Not me. Certainly less than 5% of the time. Most of the time
we have to deal with the brutality of the real world, which is all bytes and
strings.


Martin

-- 
http://mjambon.com/

___
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 records with weak hashtbl

2009-03-04 Thread Martin Jambon
Vsevolod Fedorov wrote:
> Hello!
> 
> I want to define two records referencing each other. First record (A)
> has direct reference to second (B) and second (B) has weak hash table to
> list records A, which have reference to it. For example (pseudo code):
> 
> type a
> {
>   id : int ;
>   mutable field1 : string;
>   mutable b : B;
> }
> type b
> {
> id : int;
> mutable field2 : string;
> a_list : Weak-Hashtbl(a);  (* they referenced me *)
> }
> 
> Is it possible at all?
> Is it possible with A and B declarations in separate files?
> 
> Any hints and references are welcomed.

Assuming your weak hash table module is created by a functor parametrized by
type "a", the problem is solved with recursive modules. They are documented as
a language extension in the reference manual:

  http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html#toc75


Here is some code that compiles and runs without raising the
Undefined_recursive_module exception:


module rec W : Weak.S =
  Weak.Make (
struct
  type t = X.a
  let equal = ( = )
  let hash = Hashtbl.hash
end
  )

and X :
sig
  type a = {
id : int ;
mutable field1 : string;
mutable b : b;
  }
  and b = {
id : int;
mutable field2 : string;
a_list : W.t;  (* they referenced me *)
  }
end =
struct
  type a = {
id : int ;
mutable field1 : string;
mutable b : b;
  }
  and b = {
id : int;
mutable field2 : string;
a_list : W.t;  (* they referenced me *)
  }
end



Martin

-- 
http://mjambon.com/

___
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] ocamllex question

2009-03-10 Thread Martin Jambon
Robert Muller wrote:
> I am attempting to use ocamllex together with ocamlyacc to parse a
> subset of python. Python uses indentation to denote
> statement blocks so a lexer is sometimes required to return a sequence
> of tokens without advancing the input pointer. In
> particular, a lexer for python should return a sequence of so-called
> DEDENT tokens when indented fragments
> end. E.g.,
> 
> def f(x):
> statement1;
> statement2;
> statement3;
> statement4;
> A
> 
> the lexer should return two consecutive DEDENT tokens between the '\n'
> at the end of statement4 and the token for A.

What I would do is:

1. pass an argument to each "rule" function, containing the stack of
indentation information (current block and parent blocks, with first line
number and indentation).

2. let each rule produce as many tokens as necessary and return lists of tokens

3. create a token stream for ocamlyacc/menhir that would call the
ocamllex-generated functions as needed; these would put the tokens into a
queue. Refill when the queue is empty.

4. Figure how make good error reports :-)



Martin


> Looking at the documentation and examples, it isn't clear how to
> convince the generated lexer to not advance the input pointer
> so that two consecutive DEDENT tokens can be returned before the token
> for A is returned.
> 
> Any ocamllex perts out there?
> 
> Thanks,
> Bob Muller
> 
> ___
> 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
> 


-- 
http://mjambon.com/

___
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: how do you write this rule?

2009-03-11 Thread Martin Jambon
Joel Reymont wrote:
> I would like my expression rule to parse "1 + 2 points" as "Plus (1,
> Points 2)".
> 
> I currently have the following, with Points right-associative and at the
> bottom, but it doesn't work. Is this something that Camlp4 can handle?
> 
> Thanks, Joel
> 
> expr:
>   [ ...
>   | LEFTA
> [ e1 = expr; "Or"; e2 = expr -> Or (e1, e2)
> | e1 = expr; "And"; e2 = expr -> And (e1, e2)
> | e1 = expr; "Mod"; e2 = expr -> Mod (e1, e2)
> | e1 = expr; "*"; e2 = expr -> Mul (e1, e2)
> | e1 = expr; "/"; e2 = expr -> Div (e1, e2)
> | "Not"; e = expr -> Not e
> ]
>   | RIGHTA
> [ e = expr; [ "Points"; "Point" ]; i = OPT instr -> Points (e, i) ]
>   ];

I'm sure you mean:

[ "Points" | "Point" ]



Martin

-- 
http://mjambon.com/

___
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] Commuting labeled arguments

2009-03-14 Thread Martin Jambon
Philippe Veber wrote:
> Hi all,
> 
> is this behaviour of the type checker expected ?
> 
> Objective Caml version 3.11.0
> 
> # let f g x y = g ~x ~y;;
> val f : (x:'a -> y:'b -> 'c) -> 'a -> 'b -> 'c = 
> # let g ~y ~x = x + y;;
> val g : y:int -> x:int -> int = 
> # f g;;
> Error: This expression has type y:int -> x:int -> int
>but is here used with type x:'a -> y:'b -> 'c
> 
> If so, I'm tempted to fill a report to mantis anyway, to get this said
> in the manual (i've not seen anything for this case, but i might have
> missed something).

Imagine that any function has a unique runtime representation that only
accepts one particular order for its arguments.

Labeled arguments can only commute during function application when a
particular order is expected. Reordering is done solely by the compiler based
on the presence labels. If no particular order is expected (g ~x ~y in your
definition of f), then the type checker assumes something reasonable but must
make a choice. This is why the first argument of f is inferred to have type
(x:'a -> y:'b -> 'c) although a type annotation could change this.


I find this interesting:

# let f g x y =
  g ~x ~y + g ~y ~x
;;
Characters 26-27:
g ~x ~y + g ~y ~x
  ^
This function is applied to arguments in an order different from other calls.
This is only allowed when the real type is known.

# let f (g : x:_ -> y:_ -> _) x y =
  g ~x ~y + g ~y ~x
;;
val f : (x:'a -> y:'b -> int) -> 'a -> 'b -> int = 



Martin

-- 
http://mjambon.com/

___
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] native compilation: no implementation provided for dynlink?

2009-03-17 Thread Martin Jambon
Joel Reymont wrote:
> How do I fix this?

Upgrade ocamlfind/findlib for 3.11.


> Thanks, Joel
> 
> ---
> 
> + ocamlfind ocamlopt -package 'extlib, dynlink, camlp4.lib' -linkpkg -g
> src/easy_ast.cmx src/easy_lexer.cmx src/token.cmx src/static1.cmx
> src/easy_parser.cmx src/easy_symtab.cmx src/easy_typer.cmx
> src/ninja_ast.cmx src/ninja_morpher.cmx src/pretty.cmx
> src/ninja_printer.cmx src/topdog.cmx -o src/topdog.native
> File "_none_", line 1, characters 0-1:
> Error: No implementations provided for the following modules:
>  Dynlink referenced from
> /usr/local/lib/ocaml/camlp4/camlp4lib.cmxa(Camlp4)


Martin

___
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] native compilation: no implementation provided for dynlink?

2009-03-17 Thread Martin Jambon
Joel Reymont wrote:
> ocaml -version
> The Objective Caml toplevel, version 3.12.0+dev2 (2009-01-25)
> 
> Do you mean to recompile them with 3.11?

I think the problem is in a META file, which lacks a dependency.
Dynlink must be loaded by the camlp4 lib since 3.11.
I think Gerd fixed it in the latest release of ocamlfind.
I'll let you check all of that.


Martin

> I compiled with 3.12.
> 
> On Mar 17, 2009, at 6:36 PM, Martin Jambon wrote:
> 
>> Joel Reymont wrote:
>>> How do I fix this?
>>
>> Upgrade ocamlfind/findlib for 3.11.
> 
> ---
> http://tinyco.de
> Mac, C++, OCaml
> 
> 
> 
> 


-- 
http://mjambon.com/

___
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] First release of focalize, a development environment for high integrity programs.

2009-03-24 Thread Martin Jambon
David MENTRE wrote:
> For those interested in such details, FoCaLize seems to be under a
> BSD-like license (I have not made a detailed review of the code). I
> would be interested to know if knowledged people (e.g. Debian
> developers ;-) consider this code Free Software or not.

Let me take the bait and bury it.
Such discussion would be 100% off-topic.


Thanks.

Martin

-- 
http://mjambon.com/

___
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] integer regular expressions

2009-03-30 Thread Martin Jambon
florent.ouc...@imag.fr wrote:
> Hello,
> 
> I'm looking for a way to match integer numbers (immediate values), whose
> types may be either int, int32, int64 or big_int. A conversion to string
> in order to use string (perl compatible) regular expressions is likely
> not the solution I'm looking for because it will not allow integer
> specific matches.
> 
> For instance (not normative), the regular expression syntax and
> semantics would allow complex matches such as "0%30" === "this integer
> matches if and only if its modulo to 30 is equal to 0". As in string
> regular expressions, operator | will implement a logical or...
> 
> I googled a little but all the results are always related to string
> regular expressions :( any pointers? any existing Caml code?

You want something called "views" or "active patterns".
You can do that in OCaml with mikmatch, which includes such syntax extension.

See http://martin.jambon.free.fr/mikmatch-manual.html#htoc10

Here is your example:

let view Mod30 = fun x -> x mod 30 = 0
(*
   but not:
 let view Mod m = fun x -> x mod m = 0

   but it could be implemented without difficulty (if really needed).
*)


let test x =
  match x with
 %Mod30 -> ...
   | ... ->


Of course the whole point is to use %Mod30 within arbitrary patterns,
otherwise it wouldn't be useful.

I you want to match regular expressions over anything else than bytes, there's
nothing out-of-the-box. You can define views on lists that would consume any
number of elements, but it is pretty limited.



Martin

-- 
http://mjambon.com/

___
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] when OO is wrong

2009-03-30 Thread Martin Jambon
Alexy Khrabrov wrote:
> What is it about FP which makes modeling simpler than OO, conceptually
> and technically?  How can folks summarize their "enlightenment"
> experiences in this regard?

OO is not dirty. Wait until you feel it's the right time and do it safely ;-)


Objects and classes tend to be more appropriate than modules and records in
the following cases:

- self-centric data that can be considered as a "resource", typically for IO
operations.
- frequent need to define and use interfaces before implementations.
- keeping familiar names for functions/methods without requiring
disambiguation prefixes ("input", "output", "print", "flush", "read", "send",
etc.)



Martin

-- 
http://mjambon.com/

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

2009-03-31 Thread Martin Jambon
Kuba Ober wrote:
> There must be some reason why the manual and other materials on the
> official site are of such poor quality. I've thought a bit about it, and
> the only reason I see is that the authors do not have a feel for what it
> takes to learn/understand/use that language. They obviously know it all
> through, but that's still far removed from being able to explain it to
> someone else. I don't know, of course, how it is that one understands
> something "well" yet is not able to explain it to somebody else. To me,
> that's very fragile knowledge. I always thought that deep understanding
> implies an ability to extract what's important, and to lead the other
> person from some "basics" (whatever they may be) to the conclusion.

I can see one reason: like many other French OCaml programmers, I learned
OCaml at school (it was in 1998). French teachers don't rely heavily on a
book. There is however one book that covers the essentials, "Le Langage Caml"
by Weis and Leroy, which despite using the Caml Light dialect is the most
enlightening programming book I've ever got to read. For the rest, there is
the reference manual of OCaml and plenty of source code all around the web.

I think that's why there is not much more incentive to write a complete
"replace-the-teacher" text book on OCaml written by the core OCaml developers,
who are mostly a French team. Besides, it's a lot of work and doesn't make 
money.

Of course there are now a few great books and tutorials on OCaml in English,
none of them having an official status.


Martin

-- 
http://mjambon.com/

___
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] Bug? Constraints get ignored in methods

2009-03-31 Thread Martin Jambon
Goswin von Brederlow wrote:
> Hi,
> 
> I want to keep a linked list of structures that have a common subset
> of functionality. I thought this would be a good use of ocaml objects.

It is not a good use of objects. You'll notice this pretty soon as you'll run
into a variety of problems:

- polymorphism
- initialization
- verbosity
- performance

All of these issues are inexistent if you use records instead of objects for
the list structure (or just a classic list).

You can still use objects as elements of the list, but the elements would have
to share the base type, as you know.


(continued below)

> A base class with the common subset of functionality and methods to
> link them. And then derived classes for the specific types. Most
> simplified it looks like this:
> 
> # class type base_type = object val mutable next : base_type option method 
> set_next : base_type option -> unit end;;
> class type base_type =
>   object
> val mutable next : base_type option
> method set_next : base_type option -> unit
>   end
> 
> # class base : base_type = object val mutable next = None method set_next n = 
> next <- n end;;
> class base : base_type
> 
> # class foo = object inherit base method foo = () end;;
> class foo :
>   object
> val mutable next : base_type option
> method foo : unit
> method set_next : base_type option -> unit
>   end
> 
> # let a = new base in
> let b = new foo in
>   a#set_next (Some (b :> base_type));;
> - : unit = ()
> 
> # let a = new base in
> let b = new foo in
>   a#set_next (Some b);;
>^
> Error: This expression has type foo but is here used with type base_type
>The second object type has no method foo
> 
> This last error isn't nice. I don't want to have to cast the objects
> all the time. So I thought there must be a better way using
> polymorphic methods with a constraint. But here is where everything
> breaks down. First lets look at just the set_next method:
> 
> # class type virtual vbase_type = object method virtual set_next : 'a. 'a 
> option -> unit constraint 'a = #vbase_type end;;
> class type virtual vbase_type =
>   object method virtual set_next : 'a option -> unit end
> 
> # class virtual vbase : vbase_type = object method virtual set_next : 'a. 'a 
> option -> unit constraint 'a = #vbase_type end;;
> class virtual vbase : vbase_type
> 
> # class base = object inherit vbase method set_next _ = () end;;
> class base : object method set_next : 'a option -> unit end
> 
> # let b = new base;;
> val b : base = 
> 
> # b#set_next (Some 1);;
> - : unit = ()
> 
> Huh? That should not work. 1 is not a superset of #vbase_type. The
> constraint gets completly ignored by ocaml. Adding back the next gives
> further problems:
> 
> # class type virtual vbase_type = object val mutable next : #vbase_type 
> option method virtual set_next : 'a. 'a option -> unit constraint 'a = 
> #vbase_type end;;
> class type virtual vbase_type =
>   object
> val mutable next : #vbase_type option
> method virtual set_next : 'a option -> unit
>   end
> 
> # class virtual vbase : vbase_type = object val mutable next = None method 
> virtual set_next : 'a. 'a option -> unit constraint 'a = #vbase_type end;;
> class virtual vbase : vbase_type
> 
> # class base = object inherit vbase
> method set_next n = next <- (n :> vbase_type option) end;;
> 
> Error: This method has type #vbase_type option -> unit
>which is less general than 'a. 'a option -> unit
> 
> Again I  blame ocaml for dropping the constraint. Given the constraint
> the type would be correct.
> 
> 
> 
> So how do I have to specify the set_next method that any superset of
> #base_type will be accepted as argument? Or is that a bug in ocaml and
> my syntax is perfectly fine?


I have no idea. It looks way too complicated.
Use a classic list:


class base = ...
class derived = ... (* inherits base *)

type obj = Base of base | Derived of derived

let obj_list = [ Base (new base); Derived (new derived); ... ]

let iter_base f l =
  List.iter (function Base x -> f x | Derived x -> f (x :> base)) l

let iter_derived f l =
  List.iter (function Derived x -> f x | Base _ -> ()) l

...




Martin

-- 
http://mjambon.com/

___
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] Bug? Constraints get ignored in methods

2009-03-31 Thread Martin Jambon
Martin Jambon wrote:
> Use a classic list:
> 
> 
> class base = ...
> class derived = ... (* inherits base *)
> 
> type obj = Base of base | Derived of derived
> 
> let obj_list = [ Base (new base); Derived (new derived); ... ]
> 
> let iter_base f l =
>   List.iter (function Base x -> f x | Derived x -> f (x :> base)) l
> 
> let iter_derived f l =
>   List.iter (function Derived x -> f x | Base _ -> ()) l
> 
> ...

Or simply one list per type, each list containing all the elements compatible
with the type.

I would stay away from any solution that requires special methods in order to
solve the polymorphism/heterogeneity problem. Keep the modifications 
non-invasive.


Cheers,


Martin

-- 
http://mjambon.com/

___
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] Bug? Constraints get ignored in methods

2009-04-01 Thread Martin Jambon
Goswin von Brederlow wrote:
> Hi,
> 
> small add on to my last mail.
> 
> Think of it as having a set of work queues: clean, dirty, reading,
> writing, write_prepare. The objects need to be able to quickly jump
> from one queue to the back of another when the objects internal state
> changes. And is not only the objects at the head of the queue that
> change states. Can be pretty random what object changes.
> 
> If I put the prev/next links into the objects themself they can easily
> detach themself from a queue and insert themself into another.
> 
> If I put the objects into other generic queue structures then I have to
> find the position in the old queue to remove an object and that would
> be slow.
> 
> 
> If you can think of a solution that would allow
> 
> type 'a data = { next : 'b data option; data : 'a }
> 
> without having to know possibly types of 'b then I could use functors.
> 
> This would have to work:
> 
> let s = { next = None; data = "string" }
> let i = { next = Some s; data = 23 }



Would the following work for you:



type 'a linked = {
  data : 'a;
  mutable next : < > linked option
}
(* constraint 'a = < .. > *)

let create data next = {
  data = data;
  next = (next :> < > linked option)
}

let set_next x y =
  x.next <- (y :> < > linked option)


class s =
object
  method s = "abc"
end

class i =
object
  method i = 123
end


let s = create (new s) None
let i = create (new i) (Some s)



val create : 'a -> < .. > linked option -> 'a linked = 
val set_next : 'a linked -> < .. > linked option -> unit = 
class s : object method s : string end
class i : object method i : int end
val s : s linked = {data = ; next = None}
val i : i linked = {data = ; next = Some {data = ; next = None}}



-- 
http://mjambon.com/

___
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] Bug? Constraints get ignored in methods

2009-04-01 Thread Martin Jambon
Goswin von Brederlow wrote:
> Martin Jambon  writes:
> 
>> Would the following work for you:
> 
> No. Not just like this.
> 
>> type 'a linked = {
>>   data : 'a;
>>   mutable next : < > linked option
>> }
>> (* constraint 'a = < .. > *)
>>
>> let create data next = {
>>   data = data;
>>   next = (next :> < > linked option)
>> }
>>
>> let set_next x y =
>>   x.next <- (y :> < > linked option)
>>
>>
>> class s =
>> object
>>   method s = "abc"
>> end
>>
>> class i =
>> object
>>   method i = 123
>> end
> 
> class s and i have no access to the linked type.

Yes, that's exactly what I'm trying to achieve.
They are contained in cells of the list.
You need to handle cells if you want to change the linkage.

> You could not remove
> a class s or i from the linked structure in O(1) from within class s
> or i. So linked would have to handle any function that might require
> altering the linked structure and pass parts of it to its data. But
> data is an unknown type so no method of it can be called.

< > is your base class. Replace it by whatever you like.


Martin

-- 
http://mjambon.com/

___
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] OCaml job at MyLife

2009-04-01 Thread Martin Jambon
MyLife, a people search engine, is seeking an engineer to join a back-end
software development team in Mountain View, California.  The primary
requirements for this position are:

- proficiency in the OCaml programming language -- as most of the team's
software is written in OCaml

- proficiency in written English -- as much of our team communications (design
brainstorms, bug reports, etc.) are written

- proficiency with Linux and shell scripting, build tools, and source control
tools


The ideal candidate will have a good nose for hunting bugs, diagnosing
performance problems, and reading colleagues' code.

MyLife offers an informal work environment, and an opportunity to work on
challenging engineering problems and information-retrieval algorithms over
vast data, with high-impact on end-user experience. Our team was formed at
Wink (acquired by MyLife this past summer) and includes contributors that are
active in the OCaml community.  If you're interested in applying for this
position, please contact the hiring manager at ocaml-...@mylife.com.



Martin Jambon

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

2009-04-03 Thread Martin Jambon
Daniel Bünzli wrote:
> 
> Le 3 avr. 09 à 16:46, Jon Harrop a écrit :
> 
>> Just because my OCaml programs were mutating strings and translating
>> that into
>> F# is non-trivial if the string is shared or big. In essence, I've always
>> used OCaml's strings as a more efficient byte array. In fact, the best
>> translation to F# is often to use byte arrays as a replacement for
>> strings.
> 
> So immutable strings are not a "PITA" you are just using them for
> something they should not be taken for (mutable byte arrays).

I love this recurrent discussion!

Here is my firm point of view which hasn't changed over the years and hundreds
of millions documents processed:

- I see absolutely no practical advantage of having an immutable "character
string" type.

- There is nothing to change in OCaml's string type because it is an "array of
bytes", with type char representing single bytes.




Martin

-- 
http://mjambon.com/

___
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] pattern matching and records vs tuples

2009-04-15 Thread Martin Jambon
blue storm wrote:
> On Wed, Apr 15, 2009 at 2:44 AM, Yaron Minsky  wrote:
>> Another thought I've had for making record matches lighter is to do the same
>> kind of trick that's done with labeled arguments, i.e., have
>>
>>let { foo; bar } = x
>>
>> bind the variable foo to the x.foo, and bind bar to x.bar.
> 
> That part is achieved by the pa_records [1] syntax extension.
> To my knowledge, it has not been port to post-3.10 camlp4 yet, but if
> you're interested, I could probably do it.
> 
> [1] http://oandrieu.nerim.net/ocaml/#pa_records

It's in the works for the next release of OCaml, according to Xavier Leroy's
talk at the OCaml meeting in Grenoble (Feb 2009).

(Note to organizers: slides and video would be cool!)



Martin

-- 
http://mjambon.com/

___
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] pattern matching and records vs tuples

2009-04-15 Thread Martin Jambon
Yaron Minsky wrote:
> 
> 
> On Wed, Apr 15, 2009 at 5:30 AM, Martin Jambon
> mailto:martin.jam...@ens-lyon.org>> wrote:
> 
> blue storm wrote:
> > On Wed, Apr 15, 2009 at 2:44 AM, Yaron Minsky  <mailto:ymin...@gmail.com>> wrote:
> > That part is achieved by the pa_records [1] syntax extension.
> > To my knowledge, it has not been port to post-3.10 camlp4 yet, but if
> > you're interested, I could probably do it.
> >
> > [1] http://oandrieu.nerim.net/ocaml/#pa_records
> 
> It's in the works for the next release of OCaml, according to Xavier
> Leroy's
> talk at the OCaml meeting in Grenoble (Feb 2009).
> 
> 
> What's in the works?  The lighter record syntax (let { foo; bar } = x)
> or the exhaustiveness check on record matches?  I vaguely remember
> hearing something about the former, but not the latter.

The syntax { foo; bar }.


-- 
http://mjambon.com/

___
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] Extending modules and signatures

2009-04-18 Thread Martin Jambon
Ashish Agarwal wrote:
> This is a commonly requested feature.

Ah.

> One issue is that a file a.ml
>  creates a module A. However, a file a.mli does not create
> a module type A. I'm not sure why this is the case. Does anyone know if
> there is a specific reason?

The module type exists, it's just that it doesn't have a name.

  let x = (123, "abc")

does not define "type x = int * string" either.



Martin

-- 
http://mjambon.com/

___
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] Extending modules and signatures

2009-04-19 Thread Martin Jambon
Ashish Agarwal wrote:
>> The module type exists, it's just that it doesn't have a name.
> 
> Right, thanks for the clarification.
> 
> 
>> let x = (123, "abc")
>> does not define "type x = int * string" either.
> 
> True, but I think the expectations are different for module types. A
> file a.ml  creates a module named A, and it seems natural
> to expect a.mli to create a module type A. I find it inconsistent that
> it does not.
> 
> Further, if you wanted to name the above type, it is easy, just write
> "type x = int * string". The corresponding solution to naming module
> types is burdensome. You have to define it within another module,
> introducing an unnecessary layer into your module hierarchy. Also that
> doesn't help you when using somebody else's library.
> 
> Having the compiler introduce module type names automatically from mli
> files would be very helpful, and I don't see any disadvantages.

OK, but I think the real issue is inheritance.  In order to truly extend an
existing module, one needs to access the private items of the inherited module
implementation.  In order to avoid messing up with the original module's
global variables, the inherited "module" should be more like a functor that
would create a fresh instance of the module each time it is instantiated, just
like classes generate objects.


I could imagine something like this:

module class A :
sig
  val get_x : unit -> int
end =
struct
  let x = ref 123
  let get_x () = !x
end

module class B =
struct
  inherit A
  let incr_x () = incr x
end

module B1 = new module B
module B2 = new module B
;;

B1.incr_x ();;
- : unit = ()
B1.get_x ();;
- : int = 124
B2.get_x ();;
- : int = 123


Module class implementations and signatures could be conveniently created as
whole files using new file extensions, say .mc and .mci.  These would be like
.ml files except that they would support module class inheritance and would be
evaluated only when they are instantiated with "new module".




Martin

-- 
http://mjambon.com/

___
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] Extending modules and signatures

2009-04-20 Thread Martin Jambon
Goswin von Brederlow wrote:
> Which would also need
> 
> module A1 = new module A
> module A2 = new module A
> A1.incr_x ()
> A1.get_x;;
> - : int = 124
> A2.get_x ();;
> - : int = 123
> 
> So you see A does not have global variables but only instance
> variables. What you describe are ocaml objects. Not modules.

The tiny  difference is that objects may not contain type definitions.
Functors do, but they don't support inheritance because all the private
members are hidden behind the module interface.



Martin

-- 
http://mjambon.com/

___
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] let x = ... in object ...

2009-05-26 Thread Martin Jambon
Guillaume Hennequin wrote:
> Dear list,
> 
> I was just wondering whether in
> 
> class a =
>   let x = Array.make 1 0. in
> object
>   val y = Array.copy x
>   ...
> end

# class a = let () = print_endline "hello" in object end;;
hello
class a : object  end


Maybe you mean the following:

class a () =
  let x = Array.make 1 0. in
object
  val y = Array.copy x
  ...
end


> x will be garbage collected or not.
> (this is just an example, I know creating x and copying is just doesn't
> make sense, but I wanted to point out that in my case, x doesn't need to
> be kept, but just used during object creation. I would like it to be
> garbage collected).
> I roughly recall a previous post where I think the reply was
> "intermediate values such as x are "kept" as members of the class", but
> I'm not sure.
> 
> 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


-- 
http://mjambon.com/

___
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] let x = ... in object ...

2009-05-26 Thread Martin Jambon
Guillaume Hennequin wrote:
> 
> 
> 
> # class a = let () = print_endline "hello" in object end;;
> hello
> class a : object  end
> 
> 
> Maybe you mean the following:
> 
> 
> ?

I was just pointing out that "class a = let x = ... in object ... end"
creates x once and for all when the class is defined, and x will therefore not
be GC'ed because of the language definition, not because of its implementation.


Martin
-- 
http://mjambon.com/

___
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] Strange, occasional build failure with ocamlmklib / ranlib

2009-06-02 Thread Martin Jambon
Richard Jones wrote:
> I just want to post this here in case it rings a bell with anyone:
> 
> ocamlfind ocamlc -c guestfs.mli
> ocamlfind ocamlc -c guestfs.ml
> ocamlfind ocamlopt -c guestfs.ml
> ocamlmklib -o mlguestfs guestfs_c.o guestfs_c_actions.o guestfs.cmo
> -L../src/.libs -lguestfs
> ocamlmklib -o mlguestfs guestfs_c.o guestfs_c_actions.o guestfs.cmx
> -L../src/.libs -lguestfs
> ranlib: './libmlguestfs.a': No such file
> 
> There's no other error visible.
> 
> The error is intermittent, and fairly rare.  Usually if we just run
> the build again it succeeds.

Similar problem here (ocaml 3.09.2, amd64, Linux).  Because the error is
intermittent, I never took the pain to look at it further.  All I remember is
the pattern of the error message:

   ranlib: './your_ocaml_library_here.a': No such file

and the fact that it is infrequent and seems to occur randomly.


Martin


> We've seen the same bug happening on 3.09.3 and on 3.11.1+rc0.
> 
> There are more detailed build logs here:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=502309
> 
> Anyone got any ideas at all?
> 
> Rich.
> 


-- 
http://mjambon.com/

___
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] Which types for representing HTML documents ?

2009-06-08 Thread Martin Jambon
Sébastien Hinderer wrote:
> Dear all,
> 
> According to you, how could an HTML document best be represented in
> OCaml ?

Ocamlnet's Nethtml works fine for parsing:

type document =
Element of
  (string * (string * string) list *
   Nethtml.document list)
  | Data of string


If your goal is to interpret arbitrary web pages, you have to allow all kinds
of standard or non-standard elements and attributes anywhere in the document.

If you are creating HTML documents, beware that you can't embed Flash objects
using standard HTML.  I'm not even speaking of javascript happily manipulating
the DOM tree with little restrictions.


Personally I use text templates and validate web pages once they are in my
browser (using the shortcut to validator.w3.org that opera provides).  For
javascript-generated nodes, I just check that it works in various browsers
(the firefox "View source chart" extension is useful for debugging the DOM 
tree).


I do not suffer at all from the absence of static type-checking of the HTML
tree.  I imagine that the reasons for this are:

* HTML is the final product and is trivial to debug (no need to printf
everything since everything is already printed...)

* There are no complicated conditionals that would leave certain parts of the
code untested for a long time.

* Mainstream web browsers are very tolerant.  Small accidental deviations from
the strict W3C standards usually have no visible effect.



> In particular: would you rather use classes or records, polymorphic
> variants or normal constructors ?
> 
> There are attributes which can occur in several elements, such as id,
> class... How shold these be represented ?
> Should the types reflect the differences between inline elements and
> other types of elements ?


I know this is going to annoy a lot of people on that list, but this feels
very academic to me :-)



Martin

-- 
http://mjambon.com/

___
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] ocamllex and python-style indentation

2009-06-11 Thread Martin Jambon
Andrej Bauer wrote:
> My parsing powers are not sufficient to easily come up with
> lexer/parser for a simple language that uses python-style indentation
> and newline rules. Does anyone have such a thing lying around, written
> in ocamllex/yacc or menhir? I would appreciate a peek to see how
> you've dealt with it.
> 
> For example, suppose we want just a very simple fragment of Python
> involving True, False, conditional statements, variables, and
> assignments, such as:
> 
> if True:
> x = 3
> y = (2 +
>   4 + 5)
> else:
> x = 5
> if False:
> x = 8
> z = 2
> 
> How would I go about writing a lexer/parser for such a thing in ocaml?

I would use a first pass that converts the input lines into this imaginary
structure:


{
if True:
;
{
x = 3
;
y = (2 +
;
  {
  4 + 5)
  }
}
;
else:
;
{
x = 5
;
if False:
;
{
x = 8
;
z = 2
}
}
}


You could create a generic tool that parses a file into this:

type t = Line of loc * string | Block of loc * t list


but as suggested by Yoann, the next step should probably be to flatten this
into a stream by introducing artificial tokens:

type gen_token =
   Open of loc  (* fake "{" *)
 | Close of loc (* fake "}" *)
 | Separator of loc (* fake ";" *)
 | Line of loc * string


then parse each Line into a list of tokens and flatten the result into one
single token stream:

type token =
   OPEN_BLOCK of loc  (* fake "{" *)
 | CLOSE_BLOCK of loc (* fake "}" *)
 | SEPARATOR of loc   (* fake ";" *)
 | ... (* your language-specific tokens here *)


The token stream could then be processed by ocamlyacc/menhir.


That's the approach I would follow if I had to solve this problem again.



Martin

-- 
http://mjambon.com/

___
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] ocamllex and python-style indentation

2009-06-12 Thread Martin Jambon
Andrej Bauer wrote:
> Thanks to Andreas, I'll have a look at the "old" code.
> 
> I think I understand the general idea of inserting "virtual" tokens,
> but the details confuse me still. So starting with
> 
>> if True:
>> x = 3
>> y = (2 +
>>   4 + 5)
>> else:
>> x = 5
>> if False:
>> x = 8
>> z = 2
> 
> Martin suggests the following:
> 
>> {
>> if True:
>> ;
>>{
>>x = 3
>>;
>>y = (2 +
>>;
>>  {
>>  4 + 5)
>>  }
>>}
>> ;
>> else:
>> ;
>>{
>>x = 5
>>;
>>if False:
>>;
>>{
>>x = 8
>>;
>>z = 2
>>}
>>}
>> }
> 
> I have two questions. Notice that the { ... } and ( ... ) need not be
> correctly nested (in the top half), so how are we going to deal with
> this? The second question is, why are there the separators after and
> just before "else:". I would expect separators inside {  }, but
> not around "else".

Original example:

if True:
x = 3
y = (2 +
  4 + 5)
else:
x = 5
if False:
x = 8
z = 2


For pure indentation concerns, it is equivalent to:

x
  x
  x
x
x
  x
  x
x
x


Which is parsed into:

[
  Line;
  Block
[
  Line;
  Line;
  Block
   [
 Line
   ]
];
  Line;
  Block
[
   Line;
   Line
];
  Block
[
  Line;
  Line
]
]


I wrote the following code, which does the job.  You might want to use
ocamllex instead in order to better manage newline characters (CRLF...), line
number directives and allow input from something else than a file or in_channel.


Note that the following must be rejected:

x
x
  x (indentation here could be only 0, 4 or more)


But this is accepted:

x
x
x
  x


You could also enforce that the indentation of a block must be the current
indentation + k, for example k=2 for the whole input.



(*** indent_parser.ml **)

type indent_line = Lexing.position * (int * string)

type indent_tree =
[ `Line of (Lexing.position * string)
| `Block of (Lexing.position * indent_tree list) ]


let split s =
  let len = String.length s in
  let result = ref None in
  try
for i = 0 to len - 1 do
  if s.[i] <> ' ' then (
result := Some (i, String.sub s i (len - i));
raise Exit
  )
done;
 None
  with Exit -> !result

let parse_lines fname ic : indent_line list =
  let lines = ref [] in
  let lnum = ref 0 in
  try
while true do
  let bol = pos_in ic in
  let s = input_line ic in
  incr lnum;
  match split s with
  None -> ()
| Some ((n, _) as x) ->
let pos = {
  Lexing.pos_fname = fname;
  pos_lnum = !lnum;
  pos_bol = bol;
  pos_cnum = bol + n;
} in
lines := (pos, x) :: !lines
done;
assert false
  with End_of_file -> List.rev !lines

let parse_lines_from_file fname =
  let ic = open_in fname in
  try
let x = parse_lines fname ic in
close_in ic;
x
  with e ->
close_in_noerr ic;
raise e

let error pos msg =
  let cpos = pos.Lexing.pos_cnum - pos.Lexing.pos_bol in
  let msg =
Printf.sprintf "File %S, line %i, characters %i-%i:\n%s"
  pos.Lexing.pos_fname pos.Lexing.pos_lnum 0 cpos msg
  in
  failwith msg

let rec block_body cur_indent sub_indent cur_block l :
indent_tree list * indent_line list =
  match l with
  [] -> (List.rev cur_block, [])
| (pos, (n, s)) :: tl ->
if n = cur_indent then
  block_body cur_indent sub_indent (`Line (pos, s) :: cur_block) tl
else if n > cur_indent then (
  (match sub_indent with
   None -> ()
 | Some n' ->
 if n <> n' then
   error pos "Inconsistent indentation"
  );
  let sub_block, remaining =
block_body n None [ `Line (pos, s) ] tl in

  block_body
cur_indent (Some n) (`Block (pos, sub_block) :: cur_block)
remaining
)
else
  (List.rev cur_block, l)


let parse_indentation fname =
  let l = parse_lines_from_file fname in
  let result, remaining = block_body 0 None [] l in
  assert (remaining = []);
  result


let test () =
  let fname = Filename.temp_file "test" ".ind" in
  let oc = open_out fname in
  output_string oc "
if True:
x = 3
y = (2 +
  4 + 5)
else:
x = 5
if False:
x = 8
z = 2
";
  close_out oc;

  try
let result = parse_indentation fname in
Sys.remove fname;
result
  with Failure msg as e ->
Printf.eprintf "%s\n%!" msg;
Sys.remove fname;
raise e


(*)






> Presumably the intermediate stage that I would preprocess the token
> stream would have to know about indentation levels. I have not tried
> this, but ocaml lexer will correctly match things like
> 
> | '\n' [' ' '\t']* 

Re: [Caml-list] ocamllex and python-style indentation

2009-06-12 Thread Martin Jambon
Andrej Bauer wrote:
> Thanks to Andreas, I'll have a look at the "old" code.
> 
> I think I understand the general idea of inserting "virtual" tokens,
> but the details confuse me still. So starting with
> 
>> if True:
>> x = 3
>> y = (2 +
>>   4 + 5)
>> else:
>> x = 5
>> if False:
>> x = 8
>> z = 2
> 
> Martin suggests the following:
> 
>> {
>> if True:
>> ;
>>{
>>x = 3
>>;
>>y = (2 +
>>;
>>  {
>>  4 + 5)
>>  }
>>}
>> ;
>> else:
>> ;
>>{
>>x = 5
>>;
>>if False:
>>;
>>{
>>x = 8
>>;
>>z = 2
>>}
>>}
>> }
> 
> I have two questions. Notice that the { ... } and ( ... ) need not be
> correctly nested (in the top half), so how are we going to deal with
> this?

It depends on the characteristics of your language.
It is generally easier to use several successive passes rather than trying to
do everything in one pass.


Martin

-- 
http://mjambon.com/

___
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] default arguments in classes

2009-06-16 Thread Martin Jambon
Jacques Le Normand wrote:
> Hello list,
> I'm trying to define a method with a default argument, but I keep
> getting an error. Here's the code:
> 
> class foo  =
>   object (self)
> method bar ?(baz="moo") () =
> (new foo)#bar ~baz ()
>   end
> 
> and the error:
> 
> The expression "new foo" has type foo but is used with type
>   < bar : baz:string -> unit -> 'a; .. >
> Types for method bar are incompatible
> 
> how do I fix this?


Adding type annotations often helps:

class foo =
object (self)
  method bar ?(baz="moo") () : unit =
((new foo) # bar : ?baz:_ -> _) ~baz ()
end



Martin

-- 
http://mjambon.com/

___
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: ocamllex and python-style indentation

2009-07-01 Thread Martin Jambon
Sylvain Le Gall wrote:
> Hello,
> 
> On 01-07-2009, Andreas Rossberg  wrote:
>> Mike Lin wrote:
>>> OK, now I'm curious :) how does your lexer match balanced parentheses,
>>> or in this case comments?
>>>   
>> Easily, with a bit of side effects (I think that's roughly how all ML 
>> compilers do it):
>>
>> 
>> let error l s = (* ... *)
>> let commentDepth = ref 0
>> let start = ref 0
>> let loc length = let pos = !start in (pos, pos+length)
>>
>> rule lex =
>> parse eof{ EOF }
>> (* | ... *)
>> | "{-"{ start := pos lexbuf;
>>   lexNestComment lexbuf }
>>
>> and lexNestComment =
>> parse eof{ error (loc 2) "unterminated comment" }
>> | "(*"{ incr commentDepth;
>>   lexNestComment lexbuf }
>> | "*)"{ decr commentDepth;
>>   if !commentDepth > 0
>>   then lexNestComment lexbuf
>>   else lex lexbuf }
>> | _{ lexNestComment lexbuf }
>> 
>>
>> If you also want to treat strings in comments specially (like OCaml), 
>> then you need to do a bit more work, but it's basically the same idea.
>>
> 
> May I recommend you to write this in a more simple way:
> 
> -
> rule lex =
>   parse eof{ () }
>   | "(*"   { start := pos lexbuf; lexNestComment lexbuf; lex lexbuf }
> 
> and lexNestComment =
>   parse eof{ error (loc 2) "unterminated comment" }
> | "(*" { lexNestComment lexbuf }
> | "*)" { () }
> | _{ lexNestComment lexbuf }
> -
> 
> I think it works the same way, except that it uses less global
> variables.


You can even get rid of global variables completely:


rule lex x = parse
  eof{ () }
| "(*"   { x.start <- pos lexbuf; lexNestComment x lexbuf; lex x lexbuf }

and lexNestComment x = parse
  eof  { error (loc x 2) "unterminated comment" }
| "(*" { lexNestComment x lexbuf }
| "*)" { () }
| _{ lexNestComment x lexbuf }





Martin

-- 
http://mjambon.com/

___
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: ocaml sefault in bytecode: unanswered questions

2009-08-10 Thread Martin Jambon
Elnatan Reisner wrote:
> On Sun, 2009-08-09 at 21:09 +0200, Alain Frisch wrote:
>> On 8/9/2009 8:56 PM, Elnatan Reisner wrote:
>>> My other issue is that the description of (==) for mutable structures
>>> doesn't specify that it is symmetric; reading the documentation
>>> literally only implies that e1 is a substructure of e2. Even just adding
>>> 'and vice versa' might clean this up:
>>> |e1 == e2| is true if and only if physical modification of |e1| also
>>> affects |e2 and vice versa|
>> It depends on what 'physical modification' and 'affect' mean. Clearly, 
>> the documentation means toplevel modifications of the values (i.e. 
>> modifying fields for record values, or elements for arrays or strings). 
>> If one includes deep modifications, then your extended criterion does 
>> not work either (think about two mutually recursive records).
> 
> You're right; thanks for pointing this out. But what does this mean for
> physical equality? What does it really mean? Does [e1 == e2] mean e1 and
> e2 are the same entity in memory---i.e., they are equal as C pointers?
> 
>> Note that (=) sometimes terminates for cylic values.
>>
>> # type t = A of t | B of t;;
>> type t = A of t | B of t
>> # (let rec x = A x in x) = (let rec x = B x in x);;
>> - : bool = false
> 
> Again, thanks for pointing this out. But can (=) ever evaluate to true
> on cyclic structures?

Yes:

let rec x = `A x;;
let o = object val x = x end;;
o = o;;

-> true


Martin

-- 
http://mjambon.com/

___
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] lazy vs fun

2009-08-24 Thread Martin Jambon
Stéphane Glondu wrote:
> Warren Harris a écrit :
>> Is there any advantage to using lazy evaluation in ocaml rather than
>> just using thunks to defer evaluation? [...]
> 
> Two things I can think of right now: they are evaluated only once (even
> if you call Lazy.force several times), and you can do pattern matching
> with them.


Note that the memoization feature can be implemented like this:

let lz f =
  let result = ref `None in
  fun () ->
match !result with
`None ->
  (try
 let y = f () in
 result := `Result y;
 y
   with e ->
 result := `Exn e;
 raise e
  )
  | `Result y -> y
  | `Exn e -> raise e


# #load"unix.cma";;
# let first_date = lz Unix.gettimeofday;;
val first_date : unit -> float = 
# first_date ();;
- : float = 1251151837.4585979
# first_date ();;
- : float = 1251151837.4585979


However this is slightly less efficient than how "lazy" is implemented, and of
course you don't have the nice syntax nor the (recent) pattern matching feature.



Martin

-- 
http://mjambon.com/

___
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] lazy vs fun

2009-08-24 Thread Martin Jambon
Martin Jambon wrote:
> Stéphane Glondu wrote:
>> Warren Harris a écrit :
>>> Is there any advantage to using lazy evaluation in ocaml rather than
>>> just using thunks to defer evaluation? [...]
>> Two things I can think of right now: they are evaluated only once (even
>> if you call Lazy.force several times), and you can do pattern matching
>> with them.
> 
> 
> Note that the memoization feature can be implemented like this:
> 
> let lz f =
>   let result = ref `None in
>   fun () ->
> match !result with
> `None ->
>   (try
>let y = f () in
>  result := `Result y;
>y
>with e ->
>result := `Exn e;
>raise e
> )
>   | `Result y -> y
>   | `Exn e -> raise e


Oops.
The following makes it possible for f to be garbage-collected:


let lz f =
  let result = ref (`None f) in
  fun () ->
match !result with
`None f ->
  (try
 let y = f () in
 result := `Result y;
 y
   with e ->
 result := `Exn e;
 raise e
  )
  | `Result y -> y
  | `Exn e -> raise e



Martin

-- 
http://mjambon.com/

___
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] A (Silly?) Question About Universal Type Quantification

2009-09-10 Thread Martin Jambon
Will M Farr wrote:
> Hello,
> 
> I recently encountered a situation where I had (effectively) the
> following polymorphic type:
> 
> type 'a record = { id : int; data : 'a }

You could do this:

type record = { id : int; data : 'a . 'a }

The only minor problem is that you can't create values of such type :-)


> and the following compare function
> 
> let compare {id = id1} {id = id2} = Pervasives.compare id1 id2
> 
> and wanted to put such records into a set.  However, I could not figure
> out how to make the polymorphic 'a in the type definition "disappear" in
> the module argument to the Set.Make functor.  For example, the obvious
> 
> Set.Make(struct
>   type t = 'a record
>   let compare = compare
> end)
> 
> fails because the 'a in the type definition for t is unbound.  Is there
> no way to do this?  I'm thinking of some sort of "forall" designation,
> which universally quantifies the type parameter, like
> 
> Set.Make(struct
>   type t = forall 'a : 'a record
>   let compare = compare
> end)
> 
> (I'm sure that there is better terminology for this---please pardon my
> ignorance about types and type theory.)
> 
> I ended up solving my problem by placing the record type into a functor,
> whose argument specified the concrete type for data, but I'm curious if
> other solutions exist.

Looks like the right approach.

You could also used a defunctorized version of Set, at the cost of losing the
static guarantee that you won't mix sets using inconsistent comparison 
functions.


Martin

-- 
http://mjambon.com/

___
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] Cache algorithms: implementation or library available?

2009-09-22 Thread Martin Jambon
Hugo Ferreira wrote:
> Hello,
> 
> I would like to know if anyone has or knows of an Ocaml
> library or open-source code implementation of some cache
> algorithms (example: least recently used).
> 
> Basically I need to cache a function that maps a list
> of ordered integers into a value (float, integer). I
> would like something that allows setting a maximum size
> of the map and automatically discards the data.

There are so many possible access patterns and trade-offs:

- speed requirements?
- memory requirements?
- constant size or just bounded?
- is the probability of accessing an element a function of time?

I see two frequent use cases:

a.  some elements are accessed more frequently than others regardless of time
b.  recently-accessed elements have a higher probability of being accessed

Alain Frisch provides an implementation of roughly a hash table in which
buckets hold only one element, which looks great at least for case (a):

  http://alain.frisch.fr/soft.html#memo



Martin

-- 
http://mjambon.com/

___
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] Generation of Java code from OCaml

2009-09-24 Thread Martin Jambon
blue storm wrote:
> In case it helps, below is a basic patch against json-static (SVN
> trunk, 3.10 version). On your example it produces the following code :
[...]

Yes, patching the original code of json-static would work but it's not ideal.

Maybe Deriving is a better choice (http://code.google.com/p/deriving/).  I
just say "maybe" because I've never used it.

Or you can write your own camlp4 extension from scratch and find out how to
use one of the predefined filters that would let you output only
record-derived data.


Note that if you're already using json-static but need to duplicate type
definitions, you can do as follows:

type foo = { bar : int }
type json foo = predefined { bar : int }



Martin

-- 
http://mjambon.com/

___
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] Generation of Java code from OCaml

2009-09-24 Thread Martin Jambon
blue storm wrote:
> On Thu, Sep 24, 2009 at 1:18 PM, Martin Jambon
>  wrote:
>> Yes, patching the original code of json-static would work but it's not ideal.
> 
>>From the example given, it seems that the original poster already uses
> json-static. In that case, I think that reusing the code logic is a
> good idea (coherent behaviour, etc.). I suppose that you dislike the
> "patching" solution as it is not easily reusable (one cannot use the
> upstream json-static anymore).

Of course, the internals of json-static are much more likely to change than
its user interface.  This may however not be such a big problem here in 
practice.

The problem is more that it's not compatible with other possible extensions of
json-static provided by 3rd parties.

> What about factorising json-static to allow adding arbitrary code
> generators (represented as functions from (string * type_def) list to
> a camlp4 Ast) at camlp4-time ? You would have a design similar to
> type-conv, wich allows adding new generators without modifying
> type-conv itself.

Oh yes, there's type-conv too.  I don't know the pros and cons of using either
type-conv or deriving.  If anyone knows, a brief comparison would be helpful.


Martin

-- 
http://mjambon.com/

___
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] Unboxed float tuples

2009-11-08 Thread Martin Jambon
Daniel Bünzli wrote:
> Tuples and records are represented the same way. However when it comes
> to records with only floats fields we get a special unboxed
> representation.
> 
> Why don't we get that for tuples of floats only ?

Because polymorphic functions like fst would break (or would require extra
runtime checking).

Note that ('a * 'b) is pretty much the same as:
type ('a, 'b) tuple = { a : 'a; b : 'b }


# Obj.tag (Obj.repr { a = 1.0; b = 1.0 });;
- : int = 0
# Obj.tag (Obj.repr (1.0, 1.0));;
- : int = 0


whereas:

# Obj.tag (Obj.repr { Complex.re = 1.0; im = 1.0 });;
- : int = 254



Martin

-- 
http://mjambon.com/

___
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: The lexer hack

2009-11-11 Thread Martin Jambon
Dario Teixeira wrote:
> Hi,
> 
>> Interesting. Have you confirmed that this works? I am slightly
>> worried by the fact that an LR parser reads one token ahead,
>> i.e. one token past BEGIN_VERB might already have been read
>> before the enter_verb semantic action is executed. If that is
>> so, then this token would be read while the lexer is still in
>> the wrong mode.
> 
> Yes, I was just thinking about that as well... :-)
> I think I can pile another hack on top of the dummy action:
> dummy tokens to take care of the readahead issue.  Though
> this has the potential to get comically silly pretty quickly!
> 
> I'll report later...

If the lexer to use can be determined by only one token (BEGIN_VERB), I think
you can change the state in the lexer like this:

rule token state = parse
 ""   { match !state with
 `Normal -> normal_token state lexbuf
   | `Verbatim -> verbatim_token state lexbuf
  }

and normal_token state = parse
  ...
| "\\begin{verbatim}"   { state := `Verbatim; BEGIN_VERB }

and verbatim_token state = parse
  ...  { RAW (...) }
| "\\end{verbatim}"{ state := `Normal; END_VERB }



An even simpler option, if possible in your case, is to use a single token for
the whole verbatim section:

rule token = parse
  ...
| "\\begin{verbatim}"   { finish_verbatim lexbuf }

and finish_verbatim = shortest
  _* as s "\\end{verbatim}"   { RAW s }




Martin

-- 
http://mjambon.com/

___
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] New: cppo, C preprocessor for OCaml

2009-11-17 Thread Martin Jambon
Dear list,

It is my pleasure to announce the first release of cppo, an OCaml-friendly
equivalent of the C preprocessor (cpp).

Cppo provides the classic #include, #define and conditionals (#ifdef, ...)
which are occasionally useful.  Cppo can be used on OCaml files and variants
of OCaml that use the same lexer, such as ocamllex.

The implementation of cppo was tested with ocaml 3.09 to 3.11 and is based on
ocamllex/ocamlyacc (works also with menhir which I used during the development).


The documentation and the source tarballs are at:

  http://martin.jambon.free.fr/cppo.html

The package is also available from GODI (apps-cppo).


Enjoy.


Martin

-- 
http://mjambon.com/

___
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] New: cppo, C preprocessor for OCaml

2009-11-18 Thread Martin Jambon
Goswin von Brederlow wrote:
> Martin Jambon  writes:
> 
>> Dear list,
>>
>> It is my pleasure to announce the first release of cppo, an OCaml-friendly
>> equivalent of the C preprocessor (cpp).
>>
>> Cppo provides the classic #include, #define and conditionals (#ifdef, ...)
>> which are occasionally useful.  Cppo can be used on OCaml files and variants
>> of OCaml that use the same lexer, such as ocamllex.
>>
>> The implementation of cppo was tested with ocaml 3.09 to 3.11 and is based on
>> ocamllex/ocamlyacc (works also with menhir which I used during the 
>> development).
>>
>>
>> The documentation and the source tarballs are at:
>>
>>   http://martin.jambon.free.fr/cppo.html
>>
>> The package is also available from GODI (apps-cppo).
>>
>>
>> Enjoy.
>>
>>
>> Martin
> 
> Without looking at it, is is camlp4 based and can I combine that with
> other camlp4 modules or do I need to seperately preprocess the
> source?

No, cppo is a standalone executable and is independent from camlp4 or camlp5.

Note that the camlp4 world has optcomp:

  http://forge.ocamlcore.org/projects/optcomp/



Martin

-- 
http://mjambon.com/

___
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: [***SPAM*** Score/Req: 10.1/8.0] Re: [Caml-list] Re: OCaml is broken

2009-12-20 Thread Martin Jambon
Erik Rigtorp wrote:

> It's too bad that INRIA is not interested in fixing this bug.

Ask Santa Claus, you'll get it by Friday.  Free shipping.


;-)

Martin

___
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] OCaml jobs at MyLife

2010-01-05 Thread Martin Jambon
Dear fellow OCaml programmers,

Our company, MyLife, is continuing to seek OCaml programmers to expand our
team in the Silicon Valley.

We develop back-end people search technologies and the vast majority of our
code is written in Objective Caml and runs on Linux.  We love that as it
provides us with an opportunity to tackle on big challenges with great
productivity.  We are now looking for talented and passionate people to share
the fun in Mountain View, California.


The primary requirements for the job are:

- proficiency in a functional programming language and eventually OCaml

- familiarity with Linux and shell scripting

- proficiency in written English, as much of our team communications are
written (brainstorms, bug reports, etc.)

- ability to understand end-user requirements and translate them into robust
software that gets the job done

The ideal candidate will have a good nose for hunting bugs, diagnosing
performance problems, and hacking his/her way through colleagues' code.


Please contact us at ocaml-...@mylife.com if you are interested or might be
interested in the future.



Martin

___
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] Buffer.add_channel hangs

2010-03-17 Thread Martin Jambon
Stas Miasnikou wrote:
> Hi,
> 
> OCaml 3.11.1, OpenBSD 4.6, i386.
> 
> I am trying to read whole file by doing:
> 
> let read_file_bin name =
>   let ic = open_in_bin name in
>   let b = Buffer.create 1024 in
>   (try Buffer.add_channel b ic max_int with _ -> ()); (* <-- HERE *)
>   close_in ic;
>   Array.init (Buffer.length b) (fun i -> int_of_char (Buffer.nth b i))
> 
> but it hangs on the line marked. Am I doing something wrong?

The problem is max_int and the fact that Buffer.add_channel and Buffer.resize
 do not check for this possibility:

let add_channel b ic len =
  if b.position + len > b.length then resize b len;
  really_input ic b.buffer b.position len;
  b.position <- b.position + len

Something like the following would be better:

let add_channel b ic len =
  if len < 0 || len > Sys.max_string_length then
invalid_arg "Buffer.add_channel";
  ...

Since you uncovered this problem, please kindly submit a proper bug report at
  http://caml.inria.fr/mantis

(and figure what to do if the file is larger than 16MB on 32-bit systems)


Of course, you can see from the implementation of the Buffer module that a
string of your maximum length is created no matter what, which you surely want
to avoid especially on 64-bit systems where Sys.max_string_length is very large.



Martin

-- 
http://mjambon.com/

___
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] Building multiple configurations?

2010-03-22 Thread Martin Jambon
Grant Olson wrote:
> I'm doing something weird here and I'm thinking there has to be a better
> way.
> 
> I've got a configuration file that's a .ml file.  And I do want it to be
> an .ml file that gets included at compile time, not some .txt config
> file that gets read in at runtime.  I'm building two different versions
> of my app, with two different configurations.
> 
> Basically, I want to do the same thing as a C #ifdef:
> 
> #ifdef VERSION2
>... include version one
> #else
>... include version two
> #endif

I implemented a "C preprocessor" for OCaml called cppo that lets you do that.
 It may not be the best choice here but I think it's worth some advertising:

  http://martin.jambon.free.fr/cppo.html


Martin

-- 
http://mjambon.com/

___
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 infix let

2010-04-07 Thread Martin Jambon
Jérémie Dimino wrote:
> Hi,
> 
> Le mercredi 07 avril 2010 à 15:05 -0400, Jacques Le Normand a écrit :
>> Dear List,
>> I'm writing a camlp4 syntax extension and I'd like to write 
>>
>> <:expr< let ( >>= ) = Bar.( >>= ) in 5 >>
>> but camlp4 complains:
>>
>>   While expanding quotation "expr" in a position of "expr":
>> Parse error: ")" or [ipatt] expected after "(" (in [ipatt])
>>
>> yet it seems to be valid revised syntax. Does anyone have any ideas?

The revised syntax of the old camlp4 or camlp5 requires a backslash in front
of the operator instead of parentheses:

$ cat foo.ml
let \>>= = Bar.\>>= in 5 ;

$ camlp5r pr_o.cmo foo.ml
let _ = let (>>=) = Bar.(>>=) in 5


I don't know how to make it work with the new camlp4:

$ camlp4r -printer o foo.ml
File "foo.ml", line 1, characters 4-8:
Parse error: "module" or [opt_rec] expected after "let" (in [expr])


> It is because the ">>" of the ">>=" operator is detected as the end of
> the camlp4 quotation. You can try something like that:
> 
>let operator = ">>=" in <:expr< let ($lid:operator$) = 
> Bar.($lid:operator$) in 5 >>

I would add it is simpler to just avoid << and >> in any ocaml source code
unless camlp5/camlp4 is not involved.


Martin

-- 
http://mjambon.com/

___
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] Format: Fortran (&c.) style continuation lines?

2010-04-08 Thread Martin Jambon
Thorsten Ohl (TP2) wrote:
> Hi,
> 
> for ages, I've been using the following (somewhat hackish) approach to
> pretty printing source code that requires special lexical markers to
> allow statements that continue over more than one line.  (e.g. in
> Fortran
> 
>   foo = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 &
>  + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 &
>  + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 &
>  + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 &
>  + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 &
>  + 1 + 1 + 1 + 1 + 1 + 1 + 1
> 
> and in /bin/sh we have the same with "\\" instead of "&"):
> 
>   open Format;;
> 
>   let continuing = ref true;;
> 
>   let wrap_newline () =
> let out, flush, newline, space = get_all_formatter_output_functions
> () in
> let newline' () =
>   if !continuing then
> out " &" 0 2;
>   newline () in
> set_all_formatter_output_functions out flush newline' space;;
> 
>   let nl () =
> continuing := false;
> print_newline ();
> continuing := true;;
> 
>   let _ =
> wrap_newline ();;
> 
>   (* Nonsensical example: *)
>   for statement = 1 to 3 do
> printf "  @[<2>foo = 1";
> for i = 1 to 100 do
>   printf "@, + 1"
> done;
> nl ()
>   done;;
> 
> The requirement to end each statement with "nl ()" is tedious in real
> world applications and the use of the global variable "continuing"
> violates my sense of aesthetics...
> 
> Is there a more idiomatic approach that I'm missing?

Given the imperative nature of the Format module interface, your solution
seems right to me.  Maybe you'll output up to 2 bytes beyond the margin but I
guess that's ok.

You may also consider using easy-format, which offers a functional interface
on top of Format.  The programmer's job is to create a tree containing strings
and parameters while the actual printing is done by a single function call.
That said, easy-format does not support custom newline strings although I
could add the feature.  Link:  http://martin.jambon.free.fr/easy-format.html


Martin

-- 
http://mjambon.com/

___
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] Inspect and dump values on the OCaml heap

2010-04-14 Thread Martin Jambon
Kaspar Rohrer wrote:
> On Apr 15, 2010, at 12:45 AM, Richard Jones wrote:
>> Graphviz output is interesting, but I would add that such a thing
>> exists as the 'Std.dump' function in extlib.
> 
> The last time I've checked, Std.dump had several shortcomings. It did not 
> handle cycles in the object graph that well (that's probably an 
> understatement, it did not print much information about some value types 
> (e.g. custom, closure).
> I tried to remedy that in my library. I also do not try to interpret the 
> values (e.g. lists are printed as either 0 or (BL0#2 hd tl) ). The library 
> simply dumps the object graph, with references or links where appropriate or 
> needed.
> 
> I will go into more detail if anybody is interested, but right now I just 
> want to get the code out there.
> 
> In the meantime, there are two sample pictures of graphviz dumps on my 
> personal blog: http://lambdamuesli.blogspot.com/ (I apologize for the 
> shameless plug)

By the way, there is also Dum, which takes care of cycles. No graphviz/dot
output though:

  http://oss.wink.com/dum/


Martin

-- 
http://mjambon.com/

___
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] Inspect and dump values on the OCaml heap

2010-04-14 Thread Martin Jambon
Kaustuv Chaudhuri wrote:
> On Wed, Apr 14, 2010 at 5:02 PM, Kaspar Rohrer  
> wrote:
>> [...]
> 
> Implementing dumpers seems like a teething procedure for
> OCaml hackers. Here's my own attempt from a couple of years ago.
> It handles cycles, renders SVGs (via Graphviz), and can accept
> data structure "descriptions" to produce better names for the
> internal nodes. It is almost 100% OCaml.
> 
>   http://www.lix.polytechnique.fr/~kaustuv/misc/ocaml_show.html
> 
> I am convinced that such things have *no* usefulness. If you
> are trying to debug your data structure, state its global
> invariants, prove (at whatever level of formality you are most
> comfortable with) that all API functions preserve the invariants,
> and use the module system to hide functions that do not
> preserve them. You will be done faster than trying to make
> sense of graphs and your code will be better.

The only reason why I wrote Dum was to print exceptions deeper than
Printexc.to_string:

# exception Foo of [`Bar of string];;
exception Foo of [ `Bar of string ]

# Printexc.to_string (Foo (`Bar "abc"));;
- : string = "Foo(_)"

# Dum.to_string (Foo (`Bar "abc"));;
- : string = "((\"Foo\") (3303859 \"abc\"))"


Martin

-- 
http://mjambon.com/

___
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 (<)

2010-04-21 Thread Martin Jambon
Jacques Le Normand wrote:
> Hello caml-list,
> Why doesn't (<) check for physical equality before traversing the
> structures?

If I remember correctly it used to be the case in older versions of OCaml, but
it changed because of the standard behavior expected from NaN float values.
The comparison of a NaN value with any other float should always return false,
and therefore the structural comparison of any data structure containing a NaN
with itself should also return false:

# let x = Some [ nan ];;
val x : float list option = Some [nan]

# x = x;;
- : bool = false

# x == x;;
- : bool = true


The solution to your problem is to use Pervasives.compare instead of the
comparison operators:

# compare x x;;
- : int = 0



Martin

-- 
http://mjambon.com/

___
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


  1   2   >