Re: [Caml-list] OCamlJit 2.0
Hi, What would be really nice is to make a JIT for a language that really need one, like PHP! There are lots of companies out there (Yahoo, Facebook, wikimedia) that spend hundreds of millions of dollars on machines that run PHP bytecode interpreters implemented by people who are not Xavier Leroy. Actually, Facebook has a compiler that transforms PHP source code into C++ [1], and they claim a 50% reduction in CPU usage. It's an interesting approach, though I suspect that even as we speak a new circle of hell is being warmed up especially for those who are enabling PHP's continued existence thanks to gimmicks such as this one... Cheers, Dario Teixeira [1] https://github.com/facebook/hiphop-php/wiki/ ___ 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] Merging object signatures
Hi, Can't you make foo_t and bar_t class types and foobar_t inherits them both? Thanks for the reply. Yes, in the toy example I posted that would indeed be an alternative. Still, I'm wondering about the most general case; suppose I had a function that took an object satisfying both foo_t and bar_t: val do_something: foo_t; bar_t; .. - bool This is what I'm wondering if it's possible to express. Best regards, Dario Teixeira ___ 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] Merging object signatures
Hi, class type foobar_t = object inherit foo_t inherit bar_t end val do_something : #foobar_t - bool I agree that this is rather verbose. I thought a few times of adding the syntax you propose, but was always stopped by the fact you can already do it in a verbose way. Actually, I was unaware that the '#' syntax could also be used for objects, though in retrospect it does make sense given how its used with polymorphic variants. And verboseness notwithstanding, the code above does solve my problem nicely -- thanks! Best regards, Dario Teixeira ___ 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] Merging object signatures
Hi, Similarly to polymorphic variants, is there a way for object signatures to be merged by type name? Consider the example at the end; I'm wondering if it is possible for the declaration of 'foobar' to be something along the lines of 'val foobar: int - int - foo_t; bar_t ' instead of needing to explicitly list all the methods in foo_t and bar_t. Thanks in advance for your help! Best regards, Dario Teixeira module Test: sig type foo_t = a: int type bar_t = b: int val foobar: int - int - a:int; b: int (* val foobar: int - int - foo_t; bar_t *) end = struct type foo_t = a: int type bar_t = b: int class foo a = object method a: int = a end class bar b = object method b: int = b end let foobar a b = object inherit foo a inherit bar b end end ___ 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: type inference problem with Printf.sprintf ?
Hi, core's (http://ocaml.janestreet.com/?q=node/13) Date.t and TZ.t also contain lots of functions that help dealing with dates. One feature that Core supports and that is sorely missed in Calendar is native handling of the timezone database present in Unix systems. Sure, Calendar does have some rudimentary knowledge of timezones, but I've come across situations where it's not enough, forcing me to write C stubs to directly access the Libc timezone handling functions (which are not pretty). Cheers, Dario Teixeira ___ 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: Generalized Algebraic Datatypes
Hi, If I misunderstood you, then I still misunderstand you: the App constructor you quoted took only 1 argument (a pair), so you can't partially apply it, and that's from the type declaration. IOW the type declaration you quoted is *not* curried. Now I get what you mean, and there's definitely been a misunderstanding. First, I wasn't referring to constructor App in particular, nor confusing a tuple argument with a curried form. I may be abusing the term, but I used partial application in the most general sense, ie, including an application with zero arguments (in other words, a first-class value). Suppose I had the following type declaration: val f: int - int - int - int I could do a partial application with 2 arguments: let f2 = f 1 2 A partial application with 1 argument: let f1 = f 1 And generalising, a partial application with 0 arguments, which is simply referring to f itself: let f0 = 0 Now, going back to the GADTs example, a declaration such as the one below hints that the constructors may be used as first-class values (a zero-arg partial application), when in fact they cannot. That is why I find this syntax to be inconsistent with the rest of the language. type _ t = | IntLit : int - int t | BoolLit : bool - bool t Best regards, Dario Teixeira ___ 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: Generalized Algebraic Datatypes
Hi, While this does make sense in Haskell, in Ocaml it feels a bit out of place, because you cannot, for example, partially apply a type constructor. The types above don't allow partial applications either. They use the OCaml/SML style of constructors were partial application is not possible because the various arguments are not provided in a curried way. That was precisely my point (I think you may have misunderstood what I said). In Ocaml, whenever you see a curried type declaration you can safely assume that the constructors may be partially applied. The GADT syntax under discussion breaks this assumption; hence my reticence. Cheers, Dario Teixeira ___ 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: Generalized Algebraic Datatypes
Hi, If the risk of confusion with constructors-as-functions is deemed problematic, a syntax like App of ('a - 'b) t * 'a t : 'b t seems OK too. Actually this would have the advantage of allowing the scope of existential variables to be explicit. I.e. one could write App of 'a. ('a - 'b) t * 'a t : 'b t I find this new syntax preferable too. As I just mentioned in my reply to Stefan Monnier, my main criticism to the currently implemented GADT syntax is that type constructors are declared in a curried way, despite the fact that they cannot actually be partially applied. This breaks an assumption that is otherwise consistent throughout the language, and I think we can all agree that adding caveats and exceptions to a language specification is something that should be avoided as much as possible (and is often the symptom of a bad specification). Best regards, Dario Teixeira ___ 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] Generalized Algebraic Datatypes
Hi, Don't take the syntax from my 2008 CUG talk too seriously, it was just a mock-up for the purpose of the talk. Besides, it's too early for a syntax war :-) Indeed. There's just something about syntax that tickles the more primitive parts of the programmer's brain... :-) This said, Coq could be another source of syntactic inspiration: it has several equivalent syntaxes for inductive type declarations (a superset of GADTs), one Haskell-like, others more Caml-like. I think we can all agree that ultimately the chosen syntax should be one that is unambiguous and coherent. Nevertheless, all other factors being equal, it would be preferable to have a Camlish syntax that feels right at home within the broader language. My initial reticence to Jacques proposal syntax was based solely on it having provoked a context-switch in my brain: the declarations only made intuitive sense when I tried reading them as if they were Haskell. In contrast, the CUG 2008 syntax made immediate sense, even if it may require serious massaging before it can be deemed suitable. But anyway, this syntax talk is all small potatoes. The important thing is that Ocaml is getting yet another killer feature... Cheers, Dario Teixeira ___ 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] Generalized Algebraic Datatypes
Hi, I am pleased to announce an experimental branch of the O'Caml compiler: O'Caml extended with Generalized Algebraic Datatypes. You can find more information on this webpage: More in depth feedback will come after proper digestion; for now let me just say these are great news! And I'm sure there are other Ocaml users out there who will be glad to finally get rid of some of the Obj.magic blemishes in their code... Best regards, Dario Teixeira ___ 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] Asynchronous IO programming in OCaml
Hi, Is there a tutorial on using something like LWT for asynchronous programming in OCaml? I'm looking for an example like an echo server that handles clients concurrently without blocking threads, so it can handle thousands of clients without significant performance degradation. Lwt comes with a manual, which should be enough to get you started. If you are looking for real-world examples, then the source of the Ocsigen server is the most obvious place to look. (Lwt was my first exposure to the monadic style of programming; this caused some head-scratching in the beginning, but after a while it became second nature. I reckon this experience might be common to other Lwt users). Hope that helps, Dario Teixeira ___ 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] Asynchronous IO programming in OCaml
Hi, Can you recommend papers on monadic programming? Or how did you mastered it? Mastered it might be too strong a word... :-) Anyway, my recommendation is to simply start using it and let practice do its thing. (In my case practice came from developing Ocsigen/Eliom apps). As for books or tutorials, I would suggest taking a look at material for learning Haskell. Recently, some well-publicised Haskell books targeted at beginners have come out [1,2]. No introduction to Haskell is really complete without also discussing monads. (Reading Haskell is fairly straightforward for those familiar with Ocaml, btw). Cheers, Dario Teixeira [1] http://book.realworldhaskell.org/ [2] http://learnyouahaskell.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] oasis v0.2.0: Architecture for building OCaml libraries and applications
Hi, OASIS generates a full configure, build and install system for your application. It starts with a simple `_oasis` file at the toplevel of your project and creates everything required. Do you have plans to make GODI packages for Oasis and its dependencies? (I don't mean using Oasis to automate the generation of GODI packages; I mean GODI packages for Oasis itself). It's a little step that makes trying out new software all the more convenient... Cheers, Dario Teixeira ___ 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] my own exceptions from ocamlyacc?
Hi, Hmhh, a while ago I tried around with menhir, but did not really used it. I have that in mind for cases, when ocamlyacc would become too annoying, but at least at the moment I'm fine with ocamlyacc. I thought menhir is necessary for more complex grammars; don't know if it helps me here. I find that Menhir's advantages over Ocamlyacc go beyond accepting a superset of grammars. For instance, Menhir allows the use EBNF notation, which makes the grammar productions much simpler and easier to read. Moreover, Menhir facilities for debugging and 'explaining' the grammar make it a much friendlier tool for beginners and experts alike. Cheers, Dario Teixeira ___ 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] web server interface for Ocaml ( like rack, wsgi, ...)?
Hi, My dream is *really* Eliom over Ocamlnet. Could you expand on the reasoning a little? I mean, what is for you the advantage of running Eliom over Ocamlnet as opposed to over the Ocsigen server? Cheers, Dario Teixeira ___ 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: ANN: ocamljs 0.3
Hi, What are the differences between: - OBrowser (http://www.pps.jussieu.fr/~canou/obrowser/tutorial/) - Js_of_OCaml (http://ocsigen.org/js_of_ocaml/overview) - OcamlJS These three projects have one goal in common -- running Ocaml code inside a browser -- but approach it differently: - O'Browser implements in Javascript an interpreter of Ocaml bytecode (the code produced by ocamlc). - js_of_ocaml compiles Ocaml bytecode into Javascript. - ocamljs is a new backend for the Ocaml compiler that translates Ocaml's intermediate representation (the lambda representation) into Javascript. Hope that clarifies things a bit, Dario Teixeira ___ 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] Emulating width subtyping with 1st-class modules
Hi, I have a problem where some form of width subtyping for records would be useful. At the present I'm taking advantage of the structural subtyping nature of Ocaml's object system to emulate the width subtyping. This works and is reasonably compact, but I'm still open to other approaches. It has occurred to me that 3.12's modules-as-first-class-values provide yet another solution: module type BRIEF = sig val a: int val b: string end module type FULL = sig include BRIEF val c: float end let print_brief m = let module M = (val m: BRIEF) in Printf.printf A: %d, B: %s\n M.a M.b let print_full m = let module M = (val m: FULL) in Printf.printf A: %d, B: %s, C: %f\n M.a M.b M.c module Full = struct let a = 1 let b = full let c = 0.5 end module Brief = struct let a = 0 let b = short end let () = print_brief (module Brief : BRIEF); print_brief (module Full : BRIEF); print_full (module Full : FULL) While this approach seems awfully verbose, I reckon it could be made much more palatable via some Camlp4 sugaring. Nevertheless, I have a question: just how heavy would this approach be when compared to the object one? And how would it fare in comparison to regular records? Thanks for your attention! Best regards, Dario Teixeira ___ 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] Emulating width subtyping with 1st-class modules
Hi, It depends on what you call heavy. For the syntactic aspects, as you say, Camlp4 can be helpful. One could also imagine future extensions in the compiler itself, e.g.: I meant heavy performance-wise, which you've also clarified -- thanks! Incidentally, has the Ocaml team ever entertained adding native support for a record type with width subtyping? From my type-theory-non-expert point of view, what strikes me about width subtyping is how closely related it seems to the structural subtyping found in the object system and in polymorphic variants. It would therefore fit very nicely along those features. Perhaps it could even leverage the same row variable mechanism. While 1st-class-modules add yet another user-space solution to the width subtyping problem (the other prominent approaches being the object system and Jacques Garrigue's Polymap [1]), these user-space solutions always imply some -- albeit small -- price to pay performance-wise. Cheers, Dario Teixeira [1] http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html ___ 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: scalable web apps
Hi, I am creating an application with ocsigen that requires to serve a lot of .tar.gz as static contents. Do you think the no Unix supports non-blocking mode will cause problem in this case? I presume that application is related to the Oasis-DB initiative, right? I wouldn't worry too much in that case. First, because the Ocaml community is not that big (yet) as to cause such heavy traffic. Second, because the set of tar.gz files is not that great (a few hundred, max?) and those files will tend to be small. If your server has enough memory, there's a good chance many of the file blocks requested will eventually be buffered in memory by the kernel, thus minimising expensive disc I/O. Cheers, Dario Teixeira ___ 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] scalable web apps
Hi, How does Ocsigen handle database operations? I thought it was using PG'OCaml, but maybe I'm wrong. Ocsigen itself does not use PG'OCaml. The two are frequently associated because the latest versions of PG'OCaml are Lwt-friendly and therefore a good choice for Ocsigen apps. (Note that internally, Ocsigen uses either Dbm or Sqlite to store session data). Cheers, Dario Teixeira ___ 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] scalable web apps
Hi, BTW it is planed to add some kind of asynchronous file I/O support in Lwt by using mmap and mincore. Excellent! When that arrives I suspect a naked Ocsigen server will also be able to handle a large load of static-file requests, thus eliminating the need for Nginx Co. Cheers, Dario Teixeira ___ 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: scalable web apps
Hi, Why would you use ocsigen to serve static files? Simplicity. A single server takes care of dynamic and static content, making it easy to develop and administer. For corefarm.com we put all the files in amazon s3 and we just generate on the fly the url to retrieve them (adding the timestamp, signing the get parameters etc). Yes, S3 is awesome, but I reckon it would be overkill for what Sylvain has in mind. Moreover, it does represent an extra -- albeit small -- cost. Cheers, Dario Teixeira ___ 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] scalable web apps
Hi, How do you build scalable web apps with OCaml? Do you use Apache with mod_caml? Naked Ocsigen? Do you put Ocsigen behind Nginx? Your question is quite open-ended. There are several scalability crisis that an web app is expected to confront as it grows from handling at most a handfull of requests per second to dealing with tens or even hundreds of thousands of requests per second. Are we talking about surviving a mere Slashdot effect (not as scary nowadays as it once was), or about competing with Facebook? Naked Ocsigen -- particularly naked native-code Ocsigen -- should serve you a long way in the initial stage of the growth path. In fact, I suspect you'll run into scalability problems with the database backend much sooner than you'll find them on the Ocsigen side. (For caching DB requests, I reckon that Ocsigen's Ocsigen_cache module should be sufficient for this early stage, single Ocsigen server situations). The only circumstance where I would be cautious on relying solely on a naked Ocsigen is if you are also required to serve plenty of static content (images, etc). Even though Ocsigen includes an extension for serving static pages, for hysterical reasons no Unix supports non-blocking mode for regular files, which of course causes problems for Lwt-apps (see the Lwt manual for more information on this). Therefore, in this context you may get better results by having another server (like Nginx) dedicated to static content. As Sylvain mentioned, in my talk I discussed that Ocaml's single-coredness is in no way an obstacle to scaling an web app beyond a single Ocsigen server. However, at this stage of growth you'll also have to consider using a distributed caching mechanism, such as Memcached or Wink's Cache [1] (the later developed in Ocaml by Gerd Stolpmann et al). Best regards, Dario Teixeira [1] http://oss.wink.com/cache/ ___ 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] scalable web apps
Hi, I would ask that question again, but miss out the with OCaml part, because really the choice of language doesn't matter very much. Indeed. Note, however, that more than once have people raised the issue of Ocaml's non-concurrent GC on Ocsigen's mailing-list. The doubt is always whether this makes any Ocaml-based framework unsuitable for scalable web applications. I think it's important to assuage those fears once and for all: in no meaningful way does Ocaml's single-coredness constitute an impediment towards scalability in the web domain. Or if you prefer think of it this way: People are using really unsuitable languages (PHP) and really slow languages (Ruby, PHP, Python, Perl) on some massive websites out there. Yeap. Personally, I find Ocsigen's greatest advantage to be the safety and expressiveness that it brings to backend programming (and soon also to the frontend). The fact that it's also fast is just icing on the cake... Cheers, Dario Teixeira ___ 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] scalable web apps
Hi, How does Ocsigen handle database operations? I assume they need to be asynchronous because of lightweight threads (Lwt). Ocsigen itself is agnostic on DB matters. However, your assumption concerning the Lwt-friendliness of the DB layer is correct. There's basically two solutions to this problem: 1) Use whatever DB bindings you prefer, but wrap them under Lwt_preemptive; 2) Use Lwt-aware DB bindings. For the latter the usual recommendation is PG'OCaml [1], which in its current incarnation can be used in a monadic fashion (with Lwt, for example). If you want to interact with the DB at an even higher level there's also Macaque [2], which is part of the Ocsigen project (note that Macaque relies on PG'OCaml for the low-level work). When using PG'OCaml with Lwt, pretty soon you'll come across the problem of connection pooling. This is the moment you'll want to look into Lwt_pool, which makes this task a breeze. Finally, if you're looking for a concrete example of all this stuff put together I suggest taking a look at the Lambdium's database.ml module [3] (you can find it under 'backend/src/data/'). Hope that's enough to get you going... Cheers, Dario Teixeira [1] http://pgocaml.berlios.de/ [2] http://ocsigen.org/macaque/ [3] https://forge.ocamlcore.org/projects/lambdium/ ___ 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: Cryptokit and HMAC-SHA256
Hi, Well in fact, HMAC-SHA256 and HMAC-RIPEMD160 has been implemented in the source code, but never released. So no patching involved. Indeed... In fact, I had looked into the project's WebSVN before, but since the last trunk commit was dated from 3 years ago, I assumed th current release was up-to-date and didn't investigate further. Anyway, a new release is definitely welcome! Cheers, Dario ___ 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] Cryptokit and HMAC-SHA256
Hi, I need a keyed hash function (HMAC) based on SHA256. I looked at Cryptokit's support for HMAC, and though it has built-in support for HMAC-MD5 and HMAC-SHA1, it seems HMAC-SHA256 is not directly supported, despite Cryptokit implementing the SHA256 algorithm. While RFC 2104 seems straightforward enough and there's always the option of adapting Cryptokit's HMAC-SHA1 code, I wonder if someone else out there either a) has already done this, or b) knows of an alternative library implementing HMAC-SHA256. Best regards, Dario Teixeira ___ 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: Cryptokit and HMAC-SHA256
Hi, If you decide to code the solution and provide the patch, I will be happy to apply it to cryptokit (if the main author of cryptokit accepts it, of course). I'm attaching the patches adding support for HMAC-SHA256 and HMAC-RIPEMD160 (I don't need the latter, but for the sake of completeness it seemed silly not to support it as well). Note that these are *very* straightforward patches -- kudos to Xavier for making Cryptokit so easy to extend. The caveat is that I'm not a cryptographer. I did, however, verify that these new HMACs pass all the test cases listed in RFC4231 (for HMAC-SHA256) and RFC2286 (for HMAC-RIPEMD160). Thanks for your attention! Cheers, Dario Teixeira --- cryptokit.mli.old 2010-07-21 22:10:37.0 +0100 +++ cryptokit.mli 2010-07-21 22:13:09.0 +0100 @@ -483,6 +483,16 @@ applied to SHA-1. The returned hash values are 160 bits (20 bytes) long. The [key] argument is the MAC key; it can have any length, but a minimal length of 20 bytes is recommended. *) + val hmac_sha256: string - hash +(** [hmac_sha256 key] returns a MAC based on the HMAC construction (RFC2104) +applied to SHA-256. The returned hash values are 256 bits (32 bytes) +long. The [key] argument is the MAC key; it can have any length, +but a minimal length of 32 bytes is recommended. *) + val hmac_ripemd160: string - hash +(** [hmac_ripemd160 key] returns a MAC based on the HMAC construction (RFC2104) +applied to RIPEMD-160. The returned hash values are 160 bits (20 bytes) +long. The [key] argument is the MAC key; it can have any length, +but a minimal length of 20 bytes is recommended. *) val hmac_md5: string - hash (** [hmac_md5 key] returns a MAC based on the HMAC construction (RFC2104) applied to MD5. The returned hash values are 128 bits (16 bytes) --- cryptokit.ml.old 2010-07-21 19:33:24.0 +0100 +++ cryptokit.ml 2010-07-21 22:03:48.0 +0100 @@ -947,9 +947,13 @@ module MAC = struct module HMAC_SHA1 = HMAC(struct class h = Hash.sha1 let blocksize = 64 end) +module HMAC_SHA256 = HMAC(struct class h = Hash.sha256 let blocksize = 64 end) +module HMAC_RIPEMD160 = HMAC(struct class h = Hash.ripemd160 let blocksize = 64 end) module HMAC_MD5 = HMAC(struct class h = Hash.md5 let blocksize = 64 end) let hmac_sha1 key = new HMAC_SHA1.hmac key +let hmac_sha256 key = new HMAC_SHA256.hmac key +let hmac_ripemd160 key = new HMAC_RIPEMD160.hmac key let hmac_md5 key = new HMAC_MD5.hmac key let aes ?iv ?pad key = ___ 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] Converting variants with only constant constructors to integers
Hi, The compiler does not convert the above code to 'hashtable lookup'. Is there a point where the compiler does do a table lookup for matches rather than jumps or have I clearly just dreamt that? :o) I think Luc's objection was to the use of the word hash in hashtable. Using the word hashtable for an indexed lookup table is technically correct if you consider the trivial hash function (the identity function); this may be what David meant. Nevertheless, in most people's minds an hashtable conjures images of a non-trivial mapping, which I'm quite sure is not what the compiler generates... Cheers, Dario Teixeira ___ 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 concerning modules as first-class values
Hi, I disagree with your terminology. Below is the one I use: -- | | 0-arity | n-arity (n0) | -- | Value | constant | function | | | | | | Module | structure | functor | -- This terminology is indeed better. But note that since modules are now first-class values, the word value itself becomes ambiguous. I'm not trying to be picky; I think that having clear, unambiguous terminology is essential to properly convey a message, particularly to beginners. If I well understood what Alain Frisch and Xavier Leroy explained, modules (including both structures and functors) become first class value: structures may be converted to records and functors to functions; and conversely. But I let more informed person confirm this. I am not sure about the implementation details, but at least syntax-wise I did not get the impression that structures would be converted to records. What do you mean, exactly? Cheers, Dario Teixeira ___ 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] Static exception analysis or alternative to using exceptions
Hi, Personally I've found that you should only throw those exceptions which can be caught in a single place in the program. By this I mean that an exception such as Not_found shouldn't be thrown, and instead it would be better to use an option type (for stdlib functions which throw Not_found, you have to be _very_ careful that the exception cannot escape). Yes, I agree. As an illustration, dictionary lookup functions such as Map.find should return an option type, but use exceptions for truly exceptional circumstances that no sane programmer should have to watch for at every single invocation (say, raise Dictionary_eaten_by_bears). Cheers, Dario Teixeira ___ 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] Static exception analysis or alternative to using exceptions
Hi, What experience does people have to using alternatives to exceptions, such as option types or exception monads? Does use of third part libraries that still throws exceptions make such approaches hard to use? Performance wise it seems to be comparable to catching exceptions or matching for options, so I guess the difference be might a question of programming style? Partly yes, though I would say that in Ocaml it is tempting to use exceptions beyond what is reasonable, because they are so cheap and convenient. As you noted, this can lead to trouble at runtime, which is why some libraries discourage the exceptional style, preferring option types and forcing users to invoke functions suffixed by _exc if they really want to use the exception-based version. Personally, I think the litmus test hinges on whether the supposedly exceptional situation is truly worthy of the name. If it's a common occurrence, perhaps one should reconsider the use of an exception. Without meaning to start an holy war, let me just add that even on the Stdlib there are functions (such as Map.S.find) that raise an exception but which should perhaps return an option type. Btw, you didn't mention it explicitly in your message, but I trust you are familiar with Catch me if you can? [1] Best regards, Dario Teixeira [1] http://dutherenverseauborddelatable.wordpress.com/downloads/exception-monads-for-ocaml/ ___ 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] Generating random generators
Hi, However, random numbers are tricky, and I'm suspicious of just adding a new operation ad hoc when I don't understand how the underlying PRNG works. Hence, I'd appreciate if anyone could offer some insight on whether the above approach has any hidden pitfalls (i.e. some sort of regularity that might appear when the values from two generated streams are combined in a particular fashion), or if there is a faster way of generating new generators robustly. Random.State.make invokes Digest.string for every int of the seed, so it seems like overkill. Have you considered using Cryptokit's Random module? It offers many generators, one of which meets your determinism criteria. Cheers, Dario Teixeira ___ 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] Subtyping structurally-equivalent records, or something like it?
Hi, type kinematic = { lin: Vec.t; ang: Vec.t } Which I've been using to represent a medley of physical attributes (force, momentum, velocity, etc.). I second Stéphane's suggestion of using phantom types; moreover, I recommend you read an article that discusses them to some detail and covers their use for precisely this sort of problem: http://camltastic.blogspot.com/2008/05/phantom-types.html Cheers, Dario Teixeira ___ 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] Unicode solutions
Hi, It seems like ulex + dypgen works for the front-end part. Back-end? [It's not clear to me that ulex + menhir works] I can confirm that at least with a recent Menhir, you can use whichever lexer you want, even Ulex. In fact, I have used the Ulex+Menhir combination in a couple of my own projects, and their source-code is available if you want to check out how it's done: https://forge.ocamlcore.org/scm/viewvc.php/trunk/ccss/src/ccss.ml?root=ccss https://forge.ocamlcore.org/scm/viewvc.php/trunk/lambdoc/src/lib/lambdoc_read_lambtex/main.ml?root=lambdoc Hope that helps, Dario Teixeira ___ 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] Forced linking and Ocamlbuild
Hi, I'm using Ocamlbuild with the findlib plugin listed on the Wiki. In this setting, how does one force a given module to always be linked into the final executable, even if it's not referenced anywhere? (I realise there's always the option of adding a dummy reference, but I'm looking for a cleaner solution). Note that the package is of course listed under true in the top-level _tags file, but it's being pruned out from the actual invocation of ocamlfind. Normally this is a sensible approach, but in this case I want to force linking. Also, I've searched into the (long) list of built-in tags, but couldn't find anything resembling this purpose. While I can of course explicitly change the myocamlbuild plugin so that invocations of the compiler always append the module I want to link, I wonder if there's not already a cleaner, more general solution that I may have missed. Thanks in advance! Best regards, Dario Teixeira ___ 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] Structural subtyping problem
Hi, I'm using the structural subtyping aspects of Ocaml's object system to emulate width subtyping. I've come across a problem which does not type-check, though intuitively it seems correct. I reckon that the compiler may need some help in the form of type annotations and/or coercions, though their exact shape elludes me. A simple nonsensical example that illustrates the problem is listed below; the type-checking error occurs in function step1, where the optional parameter story is used as an object of type title:string; .. . In function step3, this parameter story is actually instantiated with objects of type title:string and title:string; count:int . Anyway, am I correct in assuming this should be feasible? And if so, what coercions are required to make this compile? Thanks in advance! Best regards, Dario Teixeira = let rec step1 ?story () = match story with | Some s - step2 s#title | None - step2 title1 and step2 title = let story = object method title = title method count = 0 end in step3 ~story and step3 ~story = match story#count with | 0 - step1 ~story () | 1 - let story = object method title = title2 end in step1 ~story () | _ - true = ___ 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] Structural subtyping problem
Hi, I'm using the structural subtyping aspects of Ocaml's object system to emulate width subtyping. I've come across a problem which does not type-check, though intuitively it seems correct. I reckon that the compiler may need some help in the form of type annotations and/or coercions, though their exact shape elludes me. Thank you all for your assistance. In the real-world code, the solution based on coercion is the most straightforward to implement. And it looks obvious now... Cheers, Dario Teixeira ___ 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 modules
Hi, AFAIK local modules is a syntax extension not a compiler extension - I expect (not looked at it) that the syntax extension simply alpha renames all the local module declarations to make them unique and puts them globally... a very useful extension but no expressive power added. But if that were true, wouldn't the functor instantiation happen at initialisation time, thus preventing the delayed instantiation that is key for this solution to work? I believe that the module system due for OCaml 3.12.0 will allow this kind of runtime application of functors as modules are first class values. Again, I'm under the impression that functor application can already (with 3.11 at least) occur at runtime when local modules are used. (Or are you talking about different things?). For example: # module Foo (S: sig end) = struct let () = print_endline foo! end;; module Foo : functor (S : sig end) - sig end # let hello () = let module F = Foo (struct end) in ();; val hello : unit - unit = fun # hello ();; foo! - : unit = () Hope that's helpful - the inability to do what you're wanting to do is one of the reasons that I've never delved deeply into the module system - powerful as it may be, it didn't seem to be able to help performing a simple task (similar to yours) that I wanted it to do (I have also in the past wanted to exactly what you're doing - i.e. a module of loaded configuration values). Yep, Alain confirmed that modules as first-class values are indeed coming for 3.12. Ocaml's module system just got more interesting... Cheers, Dario Teixeira ___ 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] CCSS 1.0
Hi, In the meantime I've released version 1.1, which includes the requested unit conversion feature. It works as I described in a previous email, but is not activated by default. If you really need this feature, simply provide option '--convert' (short version '-c') upon command line invocation. For more information: http://ccss.forge.ocamlcore.org/ Hope you find it useful! Best regards, Dario Teixeira ___ 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] CCSS 1.0
Hi, Unit aware is good but the classes should be broader. I find it disappointing that it won't allow you to add mm to cm correctly, since it's supposed to be unit aware. It's unit-aware in the sense that it knows that numeric values may have this thing called units attached, and they impose some constraints on arithmetic, but it knows nothing about the semantics and relation between units. I understand why you may see this as a bug, but for me it's a feature. Personal experience tells me that mixing units -- even if they belong to the same system, as cm and mm -- is asking for trouble (never mind mixing units from metric and imperial -- ask NASA). While CCSS has no intention of being a CSS-lint, it does enforce a couple of good-practices constraints. Forbidding unit mixing is one of them; another is ensuring each property declaration is terminated by a semicolon, even if it's the last one: again, experience tells me that omitting it is asking for trouble. From a user perspective, it makes it much easier to copy paste snippets from here and there without having to bother to normalize every length to a single unit. That will be a good point if CCSS ever becomes popular and you wish to copy'n'paste CSS fragments augmented with its syntax. But presently that's a moot point, since the CSS fragments you find in the wild are not augmented with variable declarations and/or arithmetic. But anyway, if you really think unit conversion is a must-have feature, I can add it to the next release (it's actually simple to implement). However, personally I remain sceptical about its real-world usefulness. Best regards, Dario Teixeira ___ 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: Being aware of memory overuse
Hi, I always wanted to have kernel spport for this. Some way for aplication to tell the kernel about freeable memory and for the kernel to request some memory to be freeed instead of swapping it out. If I recall correctly, there was an Lwn.net article reporting a lkml (the Linux kernel mailing list) discussion on that subject. One of the proposals was for the kernel to send processes a signal (SIGFREE?) requesting they free up memory (by running a major GC, for example) whenever memory was running low. In theory this could in some cases avoid the invocation of the draconian OOM killer. Question: just how effective such a feature would be in the Ocaml case? Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] GPL with linking exception?
Hi, I've been looking around on the net to see if I could find a GPL3 + linking exception copyright notice lying around. I only found LGPL + linking exception. Does anyone know what to write for GPL3 + linking exception? Is it even possible, or is only LGPL + linking exception possible? IANALNDIPOOTV (I am neither a lawyer nor do I play one on TV), but I'm under the impression that the linking exception only makes sense to appease the requirements of LGPL. The LGPL requires that the main binary may be used with an updated version of the LGPL library, which in most cases implies some form of dynamic linking. However, this conflicts with the most common way of building Ocaml programs, where all Ocaml libraries are statically linked into the main executable. Hence the need for a linking exception, which relaxes the LGPL requirement. If, on the other hand, the library is GPL, then all source code is available (library + main), which renders this point moot. Best regards, Dario Teixeira ___ 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] Batteries Included 1.0.0
Hi, The Batteries Included project has come under new management since David Teller moved on. The project has gone through a process of reorganization and is finally ready for a release. We've rethought a lot of the structure decisions of the old codebase to make it easier to use and develop. A big thanks to you and the entire Batteries team is definitely in order! I do have a couple of questions/suggestions: - What is the relation between the development of ExtLib and AAA Batteries? A first glance at the AAA Batteries API suggests it to be a superset of ExtLib's. If both development teams are on board, I would suggest an explicit deprecation of ExtLib in favour of AAA Batteries. - Is AAA Batteries definitely the new Batteries? - Please provide also a GODI package. Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] GPL with linking exception?
Hi, My question about GPL is mostly the following: Can you distribute GPL bytecode files? Do you have any issues when 'linking' the runtime with the GPL bytecode? Or are there other issues preventing from releasing GPL OCaml code? If you want a waterproof lawyerly response you should consider contacting an organisation like the Software Freedom Law Center [1]. Nevertheless, IMHO I see no obstacle in using the GPL with Ocaml code, and there are in fact plenty of Ocaml projects using this license. Could you elaborate on why you feel that the GPL could in theory prevent the release of Ocaml code? Cheers, Dario Teixeira [1] http://www.softwarefreedom.org/ ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] general question, was Re: OCaml is broken
Hi, i dont want to go into a which-programming-language-is-best-for-what discussion (as this will never end), but at this point i wanted to know if ocaml is still alive, i.e. if you can still easily download and install it on a variety of OS, and if it will be supported in the future. The fact that the compiler's source code is (a) available, and (b) straightforward enough for mere mortals to understand should give you some assurances that Ocaml can never die by fiat. Moreover, there's a vibrant community around it, both in industry and in the open-source world. (Ocaml support in Debian and Fedora is top-notch, for example). Last but not least, Ocaml plays a central role in multiple INRIA projects, which means its creators have all the reason to continue maintaining it and improving it for the foreseeable future (and there's some interesting goodies in the upcoming 3.12 release, for example). Though I am grateful and acknowledge Jon Harrop's help in the beginner's list, you should take his prognostications with a grain of salt. Every now and again he proclaims that Ocaml is doomed! We're all gonna die!. It has almost become a comedy catchphrase of sorts in this list... So yes, do choose Ocaml for your project. You won't regret it. Best regards, Dario Teixeira ___ 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: multicore wish
Hi, I am beginning using Ocsigen, for a growing web project: Is multicore support useless for scaling on Ocsigen? Categorically, yes. In fact, I would say that the model used by Ocsigen is close to being optimal performance-wise as far as web applications are concerned. The Ocsigen server and Eliom applications use Lwt for concurrency, ensuring that the CPU is always busy and will not idle waiting for I/O. Moreover, the green threads offered by Lwt are much lighter than system threads, and avoid the context switching penalty incurred by the latter. And what about those multiple cores? Simple, if you have n cores, then simply fire up n instances of the Ocsigen server, and put a dispatching server like HAProxy or Ocsigen itself as frontend (there are some simple tricks to ensure that the same client is always directed to same server). This solution takes advantage of the fact that serving web requests from multiple clients is embarrasingly parallel from the web application standpoint. (Sure, you'll have contention on the database side, but most DBMSs handle that reasonably well). (And yes, I am aware that Lwt's performance could be improved further by using syscalls like epoll/kqeueue/etc instead of select. That is however an implementation issue, not an architectural flaw). Best regards, Dario Teixeira ___ 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 is broken
Hi, It's too bad that INRIA is not interested in fixing this bug. No matter what people say I consider this a bug. Two cores is standard by now, I'm used to 8, next year 32 and so on. OCaml will only become more and more irrelevant. I hate to see that happening. This is a perennial topic in this list. Without meaning to dwell too long on old arguments, I simply ask you to consider the following: - Do you really think a concurrent GC with shared memory will scale neatly to those 32 cores? - Will memory access remain homogeneous for all cores as soon as we get into the dozens of cores? - Have you considered that many Ocaml users prefer a GC that offers maximum single core performance, because their application is parallelised via multiple processes communicating via message passing? In this context, your bug is actually a feature. Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] The lexer hack
Hi, if the lexer cannot decide it on the tokens seen, a packrat parser (like Aurochs) may be a better choice, since in a PEG there is no seperate lexer, it's all one grammar, so you don't have this problem. But does Aurochs also handle UTF8 streams? In the meantime I've implemented the parser using Ulex/Menhir with the dummy action trick I mentioned before. It allowed me to simplify the tokenizer tremendously, though it's still present: https://forge.ocamlcore.org/plugins/scmsvn/viewcvs.php/trunk/lambdoc/src/lib/lambdoc_read_lambtex/?root=lambdoc Cheers, Dario Teixeira ___ 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
Hi, 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: Unfortunately the language features some verbatim-like environments where choosing the right scanner entails knowing more about the context than what is available to the lexer. As an example, in the command \link{url}{text}, the url should be interpreted verbatim, whereas the text portion uses the general scanner. The parser is fully aware of the context, of course, which is why the dummy action solution worked fine. (And yes, I thought of having different delimiters for different scanning contexts, but in many ways it would make the language more cumbersome for the user). Cheers, Dario Teixeira ___ 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 yyless, putting back chars in lexbuf
Hi, Is there a way in ocamllex to put back certain characters in the buffer. In flex you can do that It is also possible with Ulex, using Ulexing.rollback. Even if you don't need the UTF8 features, I suggest you take a look at Ulex anyway; the approach used (it's a syntax extension) provides greater flexibility. Moreover, it also handles latin1 streams fine. Cheers, Dario Teixeira ___ 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] The lexer hack
Hi, I'm creating a parser for a LaTeX-ish language that features verbatim blocks. To handle them I want to switch lexers on-the-fly, depending on the parsing context. Therefore, I need the state from the (Menhir generated) parser to influence the lexing process (I believe this is called the lexer hack in compiler lore). Presently I am doing this by placing a module between the lexer and the parser, listening in on the flow of tokens, and using a crude state machine to figure out the parsing context. This solution is however error-prone and a bit wasteful, since I'm reimplementing by hand stuff that should be the sole competence of the parser generator. Anyway, since I'm sure this problem pops up often, does someone have any alternative suggestions? I would preferably keep Menhir, but I'll switch if some other generator offers a better approach(*). Thanks + best regards, Dario Teixeira (*) I've looked into Dypgen, and its partial actions may offer a way out. Does someone have any experience with those and with real-world usage of Dypgen in general? (In other words, is it stable enough for production use?) ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
RE: [Caml-list] The lexer hack
Hi, Out of interest, how LaTeX-ish do you mean? I would hazard a guess that it's impossible to parse an unrestricted TeX file using an LR grammar (or at least no more clear than a hand-coded automaton) because you have to execute the macro expander in order to parse the file *completely* correctly. However, if you only mean LaTeX-ish in syntax (i.e. the files aren't actually TeX files) then you don't have to worry about TeX's elegant (by which I mean terrifying) \catcode mechanism and macro language! I developed the language's syntax in tandem with the parser/lexer so I made sure it was LR-friendly and Ulex-friendly (the verbatim environments are the only parsing-unfriendly features). The language looks and feels like LaTeX, but without the hairy stuff... Incidentally, the dummy token/action trick seems to be working fine with Menhir. Since the parser will look ahead one token, I just have a tokenizer sitting between the lexer and the parser, and inserting a DUMMY token into the stream after any token that precedes a dummy action: inline: | (...) | BEGIN_VERBATIM enter_verb DUMMY RAW exit_verb END_VERBATIM {...} | (...) enter_verb: /*empty*/ {Global.context := Global.Verbatim} exit_verb: /*empty*/ {Global.context := Global.General} It's not the prettiest thing in the world (and I suspect I might still find some problem with it), but as far as lexer hacks go it's not bad and a lot better than building a state machine. Cheers, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
[Caml-list] Ocamlbuild directory inclusion problem
Hi, I've come across another issue with Ocamlbuild, and I'm not sure if this one is a bug or a feature. Consider the project tree below; note that everything under lib/ is supposed to produce a foo.cma library, while cmd/ is a command line application that uses foo.cma (and which can be safely ignored for now). |-- _tags |-- lib/ | |-- _tags | |-- foo.mllib | |-- foo_core.mlpack | |-- foo_core/ | | |-- (...) | | | |-- foo_ext.mlpack | |-- foo_ext/ | |-- (...) | |-- cmd/ |-- (...) The file lib/_tags just contains foo_core or foo_ext: include. If I issue ocamlbuild foo.cma inside the lib/ directory, then foo.cma gets built as expected. However, if I move to the parent directory and issue ocamlbuild lib/foo.cma, I get an error: ocamlc -pack lib/foo_ext/beta.cmo lib/foo_ext/alpha.cmo -o lib/foo_ext.cmo File _none_, line 1, characters 0-1: Error: The implementation (obtained by packing) does not match the interface lib/foo_ext.mli: Modules do not match: sig val num : int end is not included in Foo_core.Zero.S Unbound module type Foo_core.Zero.S Command exited with code 2. The problem is of course that -I lib should be added to the invocation of ocamlc. For this purpose I've created a myocamlbuild.ml in the root directory, with the following contents: let () = dispatch begin function | After_rules - Pathname.define_context lib/foo_ext [lib]; | _ - () end However, this doesn't work as expected. Perhaps I've misunderstood the purpose of Pathname.define_context? In any case, I would expect a simple example like this one to work even without the need for a myocamlbuild.ml plugin. So, what is missing here? Thanks in advance! Best regards, Dario Teixeira ___ 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] xpath or alternatives
Hi, Ocamlduce has been mentioned before in this thread, but I didn't catch the reason why it has been discarded as a solution. Is it because you don't want to carry the extra (large) dependency, or is there some other reason? And on the subject of simple XML parsers for Ocaml, there's also the aptly named Simplexmlparser from the Ocsigen project [1]. It's about as spartan as one can conceive, yet sufficient for a large subset of XML extraction tasks. Cheers, Dario Teixeira [1] http://ocsigen.org/docu/1.2.0/Simplexmlparser.html ___ 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] OC4MC : OCaml for Multicore architectures
Hi, Cheers for the work you guys put into this project! And I'd like to join the crowd that has questions, if I may: a) If I understand correctly, part of prerequisites for implementing the new GC was cleaning up the excessive use of imperative constructs in the compiler's tree. Will the new tree be also more amenable to the implementation of new language constructs such as GADTs? b) Could you quantify the performance penalty (if any) of using the new GC in a single-thread context? And should this penalty be significant, are there provisions for a compile-time choice of which GC to use? c) Is there an understanding between you and the folks at INRIA concerning the eventual merging of this code into the mainline tree? Thanks a lot for your time! Best regards, Dario Teixeira ___ 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] OC4MC : OCaml for Multicore architectures
Hi, Very few programs that are not written with multicore in mind would not be penalized. I mean our GC is much much dumber than INRIA OCaml's one. Our goal was to show it was possible to have good performance with multicores for OCaml. Maybe someday we'll find some time to optimize the GC, but it's likely not very soon. Thanks for the clarification. While not detracting from your work (which I think is very interesting and valuable), for me single-thread performance is still paramount. I am working in a domain (doing backend web application programming using the Ocsigen framework) where multi-threaded parallelism is a bit silly, since you can get much better performance and design simplicity by running multiple independent servers (one for each core). Each server runs multiple concurrent Lwt-threads (a cooperative form of green threads) to make sure the CPU is always busy and not waiting on I/O. This solution has the advantage of requiring no process context-switching within each server, while still maximising CPU utilisation. And I suspect there are many other fields where a similar approach could be used advantageously instead of thread-based parallelism. I guess that if INRIA decides to implement parallel threads capability, they will have to make the runtime library ready (clean up some global variables, tidy the code like remove compatibility.h and such stuff) before thinking about the GC. This could take some time, because it's not good to break everything at once. Then, if they have finished this step, I would be confident that they could integrate an awesome GC. But that's only my personal opinion... Again, it's a question of whether the cost justifies the benefits. Personally, I'm in the camp that would rather see improvements to the type system (like native GADTS!)... Anyway, keep us appraised of your work. It's very welcome. Best regards, Dario Teixeira ___ 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?
Hi, 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). The Ocsigen folks have also developed a caching module for Ocsimore. It may be interesting to you if your app uses Lwt.. The module is called 'Cache': http://ocsigen.org/ocsimore/sources/ Cheers, Dario Teixeira ___ 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] Ocamlbuild for project with C portion
Hi, The key is to create a file with the extension .clib that contains the list of .o files that should be compiled from your C stubs. Ocamlbuild will then build these into a libary (foo.clib will result in foo.a). You then add rules in myocamlbuild.ml that define tags for depending on and linking with that library, and add these to your _tags file. Thanks for your reply. In the end I managed to solve the problem, though not using clib (which seems tangential to this problem). All that was required was the following myocamlbuild.ml: open Ocamlbuild_plugin open Command let _ = dispatch begin function | After_rules - flag [ocaml; byte; link] (S[A-custom]); dep [ocaml; link] [foobar.o] | _ - () end Though it still strikes me as odd that Ocamlbuild's manual won't cover such basic examples... Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
[Caml-list] Ocamlbuild for project with C portion
Hi, The Ocamlbuild manual begins by stating that the tool has builtin support for projects with C stubs, but unfortunately is subsequently mute on the subject. So, I have a foobar.ml module that declares an external function stuff which is defined in foobar_lowlevel.c. What is the Ocamlbuild tagging wizardry that allows this programme to compile? Thanks in advance for your time! Best regards, Dario Teixeira P.S. Does someone who groks it have plans to write a more complete manual for Ocamlbuild? It's a tool whose great potential goes unfulfilled due to deficient documentation. ___ 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 don't you use batteries?
Hi, It seems like batteries' adoption isn't quite as thorough as expected. We in the batteries devel team would love to know why you don't use batteries. Here's some of our guesses: Batteries is a great project, and you guys shouldn't feel discouraged if it doesn't take over the world overnight. There's unfamiliarity and inertia to overcome, and that takes time. Personally, I've installed Batteries and played with it, but I'm not using it (yet) on my projects. Going back to your list, here's why: 2) It's not 1.0 yet, I'll try it then That's indeed a factor. 3) It makes my executables too big This used to be a bigger problem. Previous versions of Batteries would pack everything into a module, disabling the linker's ability to link only effectively used code. Thankfully newer versions are going towards a flatter hierarchy. 4) It's too hard to install (dependencies, godi failures) Never ran into this problem. 5) It's difficult to compile against Not an issue. 6) It doesn't work on my platform Not an issue. 7) It uses camlp4 Not an issue for me. There's this thing called a build system that should handle all that transparently, so I couldn't care less if it required carrier pigeons to compile my programs. But yes, I admit it may be an issue for more constrained platforms. 8) Other (please explain) a) Lack of exposure to the advantages of Batteries. It borrows lots of cool ideas from Haskell, but that may not be immediately apparent. You guys should take advantage of the Ocaml Planet to run a publicity campaign: you can make a number of tutorial posts showing the old way versus the Batteries way. There's more to Batteries than just a collection of APIs, and that message may not be getting through. b) I'm already using Extlib extensively, and that reduces the advantage for Batteries. (Same way the Minitel slowed down Internet adoption in France in the mid-nineties?) Best regards, Dario Teixeira ___ 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] Storing UTF-8 in plain strings
Hi, I'm using Ulex + Menhir to parse UTF-8 encoded source code, and I'm relying on plain strings for processing and storing data. I *think* I can get away with using only the String module to handle this variable-length encoding as long as I am careful with the way I treat these strings. Here are the assumptions I am making: Thank you all for your comments. Ulex has caught all the intentionally malformed code points I've inserted in the stream, so I'm fairly confident it's up to the task. But if I find a problem I'll keep Netconversion's and Extlib's validation functions in mind... Best regards, Dario Teixeira ___ 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] Storing UTF-8 in plain strings
Hi, Thank you all for your comments. Ulex has caught all the intentionally malformed code points I've inserted in the stream, so I'm fairly confident it's up to the task. But if I find a problem I'll keep Netconversion's and Extlib's validation functions in mind... By the way, I just noticed that the 'validate' function in Extlib's UTF8 module accepts 5-byte and 6-byte sequences. Though these were part of UTF-8's original specification, they have been deprecated by RFC 3629. Perhaps adding a 'Deprecated_code' exception for these cases is in order? (Or just raise the existing 'Malformed_code' exception). Note that Ulex correctly raises an exception if any of these deprecated sequences are found. Cheers, Dario Teixeira ___ 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] Storing UTF-8 in plain strings
Hi, I'm using Ulex + Menhir to parse UTF-8 encoded source code, and I'm relying on plain strings for processing and storing data. I *think* I can get away with using only the String module to handle this variable-length encoding as long as I am careful with the way I treat these strings. Here are the assumptions I am making: - If the source is invalid UTF-8 in any way, Ulex will raise Utf8.MalFormed. I can therefore assume in subsequent steps that the source is compliant. - It is forbidden to use String.get, String.sub, String.length, or other functions where awareness of variable-length encoding is required. - String concatenation is allowed. - Using Extlib's String.nsplit is okay if the separator is a newline (0x0a), because in a multi-byte sequence all bytes have a value 127. There is therefore no chance of splitting a multi-byte sequence down the middle. So, can someone find any problems with this reasoning? (Thanks in advance!) Best regards, Dario Teixeira P.S. And yes, I am aware that there are excellent libraries for handling UTF-8 (like the Rope module in Batteries). ___ 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] GADTs in OCaml
Hi, We present a simple, pure, magic-free implementation of a form of GADTs in OCaml that is sufficient for the common applications of GADTs such as data structures with embedded invariants, typed printf/scanf, tagless interpreters. (...) Very interesting -- clever, yet so simple! But note that as far as the link-nodes-shall-not-be-ancestors-of-their-kind problem is concerned, there is one problem with the presented implementation. Consider the following declarations: let t1 = text ola let t2 = href http let t3 = bold [t1; t2] let t4 = mref http [t1] This causes an error upon t4. The reason is that because of t3, t1 was unified as node_link node_t, whereas t4 requires it to be node_nolink node_t. I think the solution is to revert to using polymorphic variants for the phantom type, and take advantage of their open-ended nature. (Though I'm guessing some extra massaging will be required -- it's Sunday and I don't have much time to look into this). Anyway, perhaps the Batteries folks will consider including both versions of the Eq module? It will certainly prove useful for many people. (Am I correct in assuming you are releasing the code into the public domain or at least some open-source friendly license?) Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
[Caml-list] Linking order with Ocamlbuild
Hi, I am using the custom myocamlbuild.ml for ocamlfind support that is listed in the Ocamlbuild wiki [1]. I would like to separate the list of packages used for compilation and for linking; and in the latter case I would like to provide an explicit linking order. This is what I'm currently listing in _tags: **/main.native: pkg_a, pkg_b, pkg_c **/*.ml: pkg_b, pkg_c Which is neither particularly pretty nor actually working. Namely, during the linking stage, ocamlbuild is invoking -package b -package a. This is in the wrong order, and different from the one I specified. Is there any straightforward way to fix it? Thanks for your thoughts! Cheers, Dario [1] http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild ___ 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] Virtual packages in findlib
Hi, (This is somewhat related to my previous question; having an order-preserving Ocamlbuild would be moot if findlib supported some sort of virtual packages). Suppose that for successful linking you need a package B to appear after package A1. However, A1 is only one particular instantiation of A-ness. You could replace A1 with A2 or A3, and the program would also link and run. Is there a way of expressing this sort of dependency with findlib? Something like requires = A1 | A2 | A3. Or even better, allowing packages A1, A2, and A3 to provide a virtual package A, and make B depend on that. (The Debian folks will recognise this pattern). Best regards, Dario Teixeira ___ 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] file mapped bigarray and Unix.unlink
Hi, The strategy I adopted is to spawn a recursive thread that periodically try to erase the file until success. That seems the wrong solution to me. The unlink syscall should work immediately or you have another reason why it only works after a certain time. I second David's discomfort. Have you considered issuing a sync after the unlink? For efficiency reasons the OS may not actually be deleting the file immediately after the unlink; the sync should force it to do it. Cheers, Dario Teixeira ___ 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] Width subtyping
Hi, If you're willing to give up some of the syntactic niceties of records (and the ability to pattern-match) you can get what you want using an abstract type. Thanks -- that is also an interesting solution. I'm guessing it will be faster, though it might consume more memory in cases where only one field is actually used. I'll have to try it side-by-side with the object based solution to see how they compare in the real world with my actual problem... Here, we've chosen to use a default value for fields that we don't fill in. We could just as well have used options here. The performance of the above will be roughly the same as the performance of a simple record. Obviously, all of the different subtypes have the full record stored at a physical level. Which might turn out to be not that big a deal. After all, the object based solution also adds some default overhead per object created, right? Cheers, Dario Teixeira ___ 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] Width subtyping
Hi, Heavier in terms of efficiency, or syntax? My concern is the former. The extra two fields per record and the heavier runtime calls make them so systemically slower that (to me, at least) it just feels wrong to use objects just to achieve a little syntactic clarity and a small reduction in the amount of code written. Polymorphic variants (which use only slightly more memory than regular variant values) otherwise perform at the same speed as their normal counterparts. I also meant heavier in terms of efficiency. And like David said, it does feel wrong to carry the performance penalty of the object system solely because I need the structural subtyping features. Ideally, what I should be using is record subtyping: something along the lines of the Polymap extension (which I advise everyone to take a look at), but with compile-time checking. However, my guess is that proper record subtyping cannot be tacked onto the language by means of Camlp4, and it probably needs to be a builtin feature (though I would gladly be proven wrong). Which leads to the obvious question: is there any theoretical reason why record subtyping is not available in Ocaml? Or is the answer simply just use the object system; it's not as heavy as you think it is?... Cheers, Dario Teixeira ___ 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] Width subtyping
Hi, There must be something that escapes me This seems to be an example where ocaml objects really shine because of the structural typing (i.e. an object is defined by the its structure): You are right. I was probably too fixated on the OOP way of doing this, translating record fields into object fields and the functions acting on records into object methods. Your solution, where record fields become object methods and external functions act on objects that match a certain structure, does solve the inconveniences I mentioned before. But objects are still a somewhat heavier solution, right? In the meantime I also investigated Polymap, and it is close to being the ideal solution. It has one huge drawback, though: type inconsistencies cannot be detected at compile-time, producing instead runtime exceptions. The example below illustrates this; note that function printx should accept both m1 and m2, but not m3. However, the mistake in 'foobar' is not reported until runtime: (In fairness, there's probably no easy technical fix for this.) let printx m = Printf.printf X is %d and Y is %s\n m.`x m.`y let m1 = `{x=1; y=foo} let m2 = `{x=2; y=bar; z=true} let m3 = `{y=ola; z=false} let foobar = printx m1; printx m2; printx m3 Cheers, Dario ___ 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] Width subtyping
Hi, Though it is probably been-there-done-that material for the veterans in this list, for the sake of the not-so-veterans I have to ask: how do you guys typically model width subtyping in Ocaml? Consider for example three record types that share some of their fields: type t1 = {a: int; b: int; c: int;} type t2 = {a: int; b: int; c: int; d: int;} type t3 = {b: int; c: int; d: int;} In some circumstances, the object system can be put to good use for this kind of problem. Not always though, so I'm curious about other approaches people use. One approach I've considered is to create a superset record where each field is an optional type, and then creating constructors/getters for each valid subset. Unfortunately this solution feels a bit kludgy, even if it reduces code duplication. For safety reasons I'm therefore currently just declaring each record type independently (concerns about duplication be damned). In other words, polymorphic variants provide a very elegant solution for subtyping with sum types. Is there some brilliant idea that could do the same for product types? Best regards, Dario Teixeira ___ 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] Width subtyping
Hi, This way you're always dealing with the same product type, but the sum type tells you which fields are actually valid. Of course, it relies on there being an obvious sentinel value for unused fields (otherwise you just end up with 'a option everywhere) and I still don't think it's that neat as you can still match against fields which aren't valid but at least the type system prevents you from being handed an illegal value. The benefit is that you don't need special get functions (just a match on type t to extract the t' value from each constructor). I can't get my head around how private polymorphic variants work to see if they can refine this further... This is indeed a reasonable solution for many classes of problems. However, the need for a sentinel value for unused fields makes it somewhat heavyweight for those record variants where just one field is valid. Moreover, this solution requires outside functions that should only operate on T1 (for example) to voluntarily check by pattern matching that the t they are getting is indeed a T1 (and presumably raise failure otherwise). The object-based solution can at least automatically take care of this (though it has other problems). Cheers, Dario ___ 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] Width subtyping
Hi, The dual of sums is products. Open (labelled) sums are polymorphic variants. Their duals are open (labelled) products are rows (which O'Caml already supports, through its objects). Yes, as I mentioned, for some classes of this particular problem the object system can be put to good use -- when there is a clear tree for inheritance, for example. Unfortunately that is always not the case; there are problems where you would end up with a tangled web of multiple inheritances just for the sake of avoiding duplicating methods. Cheers, Dario ___ 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] Width subtyping
Hi, I've very tired at the moment, but I think that Garrigue's polymap syntax extension does what you want: http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html If not, just ignore me! I should have suspected this discussion would eventually lead to something out of Jacques Garrigue's magic hat! :-) But on a first glance, yes, it does look like it might be of interest. I'll explore it further, thanks! Cheers, Dario ___ 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] Ocamlfind query
Hi, I would like to get the name of the cma associated a findlib package. I expect this to be available via the query command, but running ocamlfind query -l pkg_name always lists the archive as empty. Is there some other option? Best regards, Dario Teixeira ___ 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] Trouble with Ocamldoc + Ocamlbuild
Hi, I'm having some trouble getting Ocamlbuild to produce API documentation via Ocamldoc in a project that uses packed modules. The project has two main directories, modA and modB, each contanining a couple of modules, as follows: modA |- Foo |- Bar modB |- Glu |- Bah I placed the modA.mlpack and modB.mlpack files at the top-level, listing the modules in the respective directories. The main target itself is to build the library mylib.cma, containing the packed modules modA.cmo and modB.cmo. Therefore, also at the top level directory is the file mylib.mllib, whose contents are modA and modB in separate lines. Now, building the library with ocamlbuild mylib.cma works fine. But how can I tell Ocamlbuild to build the API doc with Ocamldoc? I reckon I have to create a mylib.odocl file at the top-level, but what should its contents be? I have tried modA and modB, but it doesn't work. Neither does a fully qualified specification, such as modA.Foo, etc. Any thoughts? Thanks in advance! Best regards, Dario Teixeira P.S. The caml-list seems to be cloning posts today. Sorry if you get this message multiple times. ___ 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] Trouble with Ocamldoc + Ocamlbuild
Hi, You should take a look at Batteries' myocamlbuild.ml, we're solving this issue and it's messy (it involves generating the .mli for each .mlpack). Thanks! But what does your myocamlbuild.ml expect that it be placed in the various files (namely *.odocl) in order to generate the API doc for a project like the one I described? Cheers, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] The new OCaml book (Objective Caml Programming Language by Tim Rentsch)
Hi, Oh dear. Then I am very sorry to tell you that Tim Rentsch's book is virtually identical to your own, having been tweaked just enough to evade copyright. Should this be confirmed (namely by Jason Hickey himself), the comments section at Amazon and other online stores may prove useful in pointing people to Jason's book instead (once it comes out)... Cheers, Dario Teixeira ___ 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] Unusual type declaration and Sexplib
Hi, You program below is exactly equivalent to the following, without as. Or is your real code something different? You're right, the formulation without 'as' is simpler, and Sexplib handles it just fine. The real code adds a phantom type variable to t, and the advantage of using 'as' was making the phantomness obvious: type +'a t = private [ 'b node_t ] as 'b versus type +'a t = private [ 'a t node_t ] But in this case, 'as' does raise more trouble than it's worth... Anyway, issue solved -- thanks! Best regards, Dario Teixeira ___ 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] Unusual type declaration and Sexplib
Hi, I'm having some trouble serialising via Sexplib a data structure defined recursively. Consider module M defined below; note how type foobar_t includes a with sexp declaration, telling the Sexplib syntax extension to create (de)serialisers automatically. However, type t cannot rely on that automatism, because type declarations with the as operator are not fully supported. Therefore, I need to create the (de)serialisers for this type manually. module M: sig type 'a foobar_t = [ `Foo of int | `Bar of 'a list ] with sexp type t = private [ 'a foobar_t ] as 'a val foo: int - t val bar: t list - t end = struct type 'a foobar_t = [ `Foo of int | `Bar of 'a list ] with sexp type t = 'a foobar_t as 'a let foo x = `Foo x let bar x = `Bar x end So basically the problem is creating the functions with the following signatures: val sexp_of_t: t - Sexplib.Sexp.t val t_of_sexp: Sexplib.Sexp.t - t Using as base the automatically created functions whose signatures are as follows: val sexp_of_foobar_t: ('a - Sexplib.Sexp.t) - 'a foobar_t - Sexplib.Sexp.t val foobar_t_of_sexp: (Sexplib.Sexp.t - 'a) - Sexplib.Sexp.t - 'a foobar_t But in practice, I'm having trouble seeing how these later functions can be used. The problem lies in their recursive definition: how would I break it? (And yes, I realise that the definition of type t is unusual, but it's extremely convenient for avoiding a lot of explicit annotations and coercions [1]). Thanks for your help! Best regards, Dario Teixeira [1] http://groups.google.com/group/fa.caml/browse_thread/thread/7552095ab859fb5f/9c4a6fd19812fbcc ___ 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] Union of type variables
Hi, Obviously I would like to get rid of this kludge. The signature and implementation for union should be something like the (syntactically incorrect) code below. But is it at all possible to declare an union of type variables? (which presupposes they are polymorphic variants) val union: 'x t - 'y t - [ 'x | 'y ] t let union x y = Union (x, y) In the meantime I realised what the problem was. I neglected to take into account the open nature of polymorphic variants, meaning that as long as the phantom type variable is open, then the following code is enough to do what I want: val union: 'a t - 'a t - 'a t let union x y = Union (x, y) Cheers, Dario Teixeira ___ 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: [ANN] OCaml Meeting 2009 -- dinner, schedule for talks
Hi, No, I mean Monday. I need to call the restaurant before midday on Tuesday, so I need to have the list on Monday (or Tuesday before midday, but Monday is better). The dinner, I am speaking of, is on Tuesday. Yeah, English grammar is ambiguous that way... I would phrase the statement as We need to know on Monday how many people are coming to the dinner (on Tuesday) to book the restaurant. An alternative is start learning Lojban: http://en.wikipedia.org/wiki/Lojban Cheers, Dario ___ 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] Private types in 3.11, again
Hi, And once more, thanks for your very informative reply. I spent the last few days exploring these issues (there's quite some info on the Haskell wiki) and weighting in the pros/cons of each solution. I've decided for an approach similar to that taken by the Ocsigen guys. That is, acknowledge that a proper modeling of this problem requires GADTs, and that since Ocaml does not have them (yet), this is one of those cases where the use of Obj.magic is justified. Yes, I know Obj.magic is evil and all that, but it does allow me to model the problem in a way that is not too contrived and that is easily ported to a GADT solution once it does become available in Ocaml. In the end it's about choosing the lesser of two evils, and so I've made my peace with having to use Obj.magic. In your first example, you want to simultaneously deconstruct a value, a reconstruct a new value with the same polymorphic type. For this, you need the expressive power of GADTs, i.e. the ability to instanciate type variables differently inside different branches of a pattern-matching. Since they are not available in ocaml, (...) Thanks for the explanation. So there is indeed an expression deficit that GADTs fix. Also, note that this little link-node example is not the only instance in my current project where GADTs would be useful. (I'm guessing that eventually reaching the limits of the type system is part of the journey for an Ocaml programmer!...) Best regards, Dario Teixeira ___ 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] Private types in 3.11, again
Hi, Thank you very much for your help, Jacques! It's always enlightening to see an Ocaml ninja in action, though I'm still digesting the finer points of your message. Anyway, I have implemented all three solutions you suggested: a) Using a private row and PV b) Using a private abbreviation and PV c) Using the mapper + object system with regular variants Solution a) is by far the most convenient, though I'm still having some trouble with it (more below). Which brings me to a crucial point where I'm still fuzzy. My initial model for the link-nodes-shall-not-be-ancestors-of-their-kin problem did indeed rely on what I now realise are GADTs. I ran into a limitation of the type system and so I recast the model using phantom types because I hoped they could provide a workaround. So my question is whether it is at all possible to emulate GADTs using only PV + phantom types, or if on the contrary one needs to use the object system in these cases, as exemplified by solution c). In other words, is solution a) futile, or did you use the object system in solution c) simply because you were also using regular variants? As for the problem with solution a), it shows up when I implement outside of module Node any non-trivial function operating on 'a Node.t. Function capitalise_node, for example: module Node: sig type 'a node_t = [ `Text of string | `Bold of 'a list | `Href of string | `Mref of string * 'a list ] type +'a t = private [ 'b node_t ] as 'b val text: string - [ `Nonlink ] t val bold: 'a t list - 'a t val href: string - [ `Link ] t val mref: string - [ `Nonlink ] t list - [ `Link ] t end = struct type 'a node_t = [ `Text of string | `Bold of 'a list | `Href of string | `Mref of string * 'a list ] type +'a t = 'b node_t as 'b let text txt = `Text txt let bold seq = `Bold seq let href lnk = `Href lnk let mref lnk seq = `Mref (lnk, seq) end module Foobar: sig val capitalise_node: 'a Node.t - 'a Node.t end = struct let capitalise_node node = let rec capitalise_node_aux forbid_link node = match (forbid_link, node) with | (_, `Text txt)- Node.text (String.capitalize txt) | (x, `Bold seq)- Node.bold (List.map (capitalise_node_aux x) seq) | (false, `Href lnk)- Node.href lnk | (false, `Mref (lnk, seq)) - Node.mref lnk (List.map (capitalise_node_aux true) seq) | _ - failwith this shouldn't happen in capitalise_node_aux false node end The code above produces the compiler error below (though remember that this same function works fine inside the Node module): Error: This expression has type ([ `Link | `Nonlink ] as 'a) Node.t list but is here used with type ([ `Nonlink ] as 'b) Node.t list Type 'a Node.t = [ `Bold of 'a Node.t list | `Href of string | `Mref of string * 'a Node.t list | `Text of string ] is not compatible with type 'b Node.t = [ `Bold of 'b Node.t list | `Href of string | `Mref of string * 'b Node.t list | `Text of string ] The first variant type does not allow tag(s) `Link Thanks again for all your time! Best regards, Dario Teixeira ___ 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] GADTs in Ocaml (was: Private types in 3.11, again)
Hi, I didn't followed the thread closely, but did you have a look at Ocsigen's way to implement params_type? Thanks for the suggestion. Actually, there's an Ocsigen connection with what I'm doing. The Node module we've been discussing is a simplification; the real problem is for a data type that can be converted into the XHTML.M data used in Ocsigen. (As was discussed some time ago in the Ocsigen mailing list, the XHTML.M module does not strictly enforce the nested link nodes rule of the W3C. Nevertheless I have been looking for a solution that does enforce this rule). Anyway, I took a brief look at the code you mentioned, and re-read the relevant section in the Rapport Ocsigen you wrote a while ago (when I first read that report I had no idea what GADTs were!). It does seem that we're all just cooking up workarounds to the lack of GADTs in Ocaml. Now, I recall Xavier Leroy mentioning this topic at the user meeting last year. It seems the theory is ready, but the compiler needs some work done before it can accommodate this new feature. Are there news on that front? Best regards, Dario Teixeira ___ 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] Private types in 3.11, again
Hi again, I ditched the regular variants in favour of polymorphic variants, hoping the coercion trick described by Jacques Garrigue would help [1]. I've also simplified the formulation as much as possible. Anyway, I'm still stuck with the same problem: while function 'sprint' works alright inside the Node module, its clone 'sprint2' fails to compile when placed outside. Is this a case where no amount of explicit annotations and coercions will work or am I missing something obvious? Thanks in advance! Regards, Dario Teixeira [1] http://groups.google.com/group/fa.caml/msg/855011402f1ca1b5 module Node: sig type elem_t = [ `Text of string | `Bold of elem_t list ] type +'a t = private elem_t val text: string - [ `Basic ] t val bold: 'a t list - [ `Complex ] t val sprint: 'a t - string end = struct type elem_t = [ `Text of string | `Bold of elem_t list ] type +'a t = elem_t let text str = `Text str let bold seq = `Bold seq let rec sprint = function | `Text str - Printf.sprintf (Text %s) str | `Bold seq - Printf.sprintf (Bold %s) (List.fold_left (^) (List.map sprint seq)) end module Foobar: sig val sprint2: 'a Node.t - string end = struct let rec sprint2 node = match (node : _ Node.t : [ ]) with | `Text str - Printf.sprintf (Text %s) str | `Bold seq - Printf.sprintf (Bold %s) (List.fold_left (^) (List.map sprint2 (seq : _ Node.t list : [] list))) end ___ 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] Private types in 3.11, again
Hi, Hmmm, a variant of your code may be exhibiting a bug in ocaml 3.11.0. Thanks for the reply. I'm kind of hoping it is indeed a bug, because those are fixable and it would mean what I intend to do is feasible... Best regards, Dario Teixeira ___ 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] Private types in 3.11, again
Hi, So my question is how can I make the Foobar code behave as if it were defined inside Node. Based on a previous thread [1], I'm guessing there is a solution, but I've been unable to hit on its exact formulation. There have been no replies yet to my question, but I'm still stuck with this little problem. The offending code is below; though it doesn't compile, I reckon that all it needs is a suitable type annotation. I'm guessing this because the function capitalise_node function will compile fine if placed inside the Node module. Any ideas on how to solve this? Thanks in advance! Best regards, Dario Teixeira module Node: sig type node_t = private | Text of string | Bold of node_t list | Href of string | Mref of string * node_t list type +'a t = private node_t val text: string - [ `Nonlink ] t val bold: 'a t list - 'a t val href: string - [ `Link ] t val mref: string - [ `Nonlink ] t list - [ `Link ] t end = struct type node_t = | Text of string | Bold of node_t list | Href of string | Mref of string * node_t list type +'a t = node_t let text txt = Text txt let bold seq = Bold seq let href lnk = Href lnk let mref lnk seq = Mref (lnk, seq) end module Foobar: sig open Node val capitalise_node: 'a t - 'a t end = struct open Node let capitalise_node node = let rec capitalise_node_aux forbid_link node = match (forbid_link, node) with | (_, Text txt) - text (String.capitalize txt) | (x, Bold seq) - bold (List.map (capitalise_node_aux x) seq) | (false, Href lnk) - href lnk | (false, Mref (lnk, seq)) - mref lnk (List.map (capitalise_node_aux true) seq) | _ - failwith oops in capitalise_node_aux false node end ___ 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] Private types in 3.11, again
Hi, (Note: this problem is similar to one I've posted before; there are however differences. Also, my apologies for the problem requiring a long introduction before actually being presented). Consider a sequence of nodes such as those present in an inline context in XHTML. Some of these nodes are leaf nodes (Text and Href), while others are built from a list of existing nodes (Bold and Mref). Moreover, some nodes create hyperlinks (Href and Mref). A straightforward Ocaml representation could be as follows: type node_t = | Text of string | Bold of node_t list (* recursive! *) | Href of string | Mref of string * node_t list (* recursive! *) There is furthermore an important restriction: a link node may not be the ancestor of another link node, no matter how deep the ancestry level (in similarity with the W3C rules for XHTML). While this restriction could be enforced by runtime checking, I very much prefer to represent nodes in such a way that the type system itself would ensure the impossibility of creating illegal values. Below is the best solution I could come up with so far (note that this code requires 3.11). It uses a phantom type to taint link nodes, making them unsuitable to be descendants of other link nodes. Also, note the use of 'private' to allow pattern-matching by external code without breaking the phantom type restrictions. module Node: sig type node_t = private | Text of string | Bold of node_t list | Href of string | Mref of string * node_t list type +'a t = private node_t val text: string - [ `Nonlink ] t val bold: 'a t list - 'a t val href: string - [ `Link ] t val mref: string - [ `Nonlink ] t list - [ `Link ] t end = struct type node_t = | Text of string | Bold of node_t list | Href of string | Mref of string * node_t list type +'a t = node_t let text txt = Text txt let bold seq = Bold seq let href lnk = Href lnk let mref lnk seq = Mref (lnk, seq) end So far so good. Now consider a function that takes a node and returns another node, in all identical except that all occurrences of Text (either in the parent or in all descendants if the node is defined recursively) are replaced by the capitalised version. Moreover, I want to place this function in a different module, called Foobar: module Foobar: sig open M val capitalise_node: 'a t - 'a t end = struct open M let capitalise_node node = let rec capitalise_node_aux forbid_link node = match (forbid_link, node) with | (_, Text txt) - text (String.capitalize txt) | (x, Bold seq) - bold (List.map (capitalise_node_aux x) seq) | (false, Href lnk) - href lnk | (false, Mref (lnk, seq)) - mref lnk (List.map (capitalise_node_aux true) seq) | _ - failwith oops in capitalise_node_aux false node end Unfortunately, the code above fails to compile, producing this error: Error: This expression has type [ `Link | `Nonlink ] M.t list but is here used with type [ `Nonlink ] M.t list The second variant type does not allow tag(s) `Link For the Foobar module to work, I have to remove the 'private' declaration in module Node, which of course breaks the phantom type. Note that the function above will also compile fine if it is defined inside Node instead of Foobar (but which is useless to me). So my question is how can I make the Foobar code behave as if it were defined inside Node. Based on a previous thread [1], I'm guessing there is a solution, but I've been unable to hit on its exact formulation. Thanks in advance for any light you may shed on this issue. It is much appreciated! Kind regards, Dario Teixeira [1] http://groups.google.com/group/fa.caml/browse_thread/thread/d9c5e30b973db187# ___ 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?
Hi, I understand that there's no manpower to push the core compiler forward faster. But it would be a solace to know that there are at least some optimistic plans with a broader horizon. Speaking of which, there's something that's been on my mind for quite some time: what's the holdup preventing INRIA from having more manpower dedicated to Ocaml? The language already has a sizable community, a fair industrial usage, and a visible presence among the academia. I'm sure that given the language advantages that we all know, if it had more widespread usage there would be a positive multiplier effect on the French economy and beyond (think of productivity losses resulting from crappy language choices). Should we write a letter to monsieur le président telling him that a well-supported Ocaml language would do a lot more pour la gloire de la France than supermodel wives? 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? Backwards compatibility is overrated in an open-source environment. However, to avoid alienating users with large code bases in legacy code, the best solution would be to keep 3.x being updated for bugfixes for the foreseeable future (would that require all that much manpower?), while simultaneously developing a version 4.0 not hindered by backwards compatibility. Cheers, Dario Teixeira ___ 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] More cores
Hi, Is it time to start rethinking concurrency in OCaml? (...) That's a recurrent topic in this list. I'll summarise the arguments and save us all some time: i) Someone raises the issue that it's time for Ocaml to go multicore. ii) A few voices go yeah! and state that with a concurrent GC, Ocaml can take over the world. Their argument is as follows: 1) Ocaml gets a concurrent GC; 2) ... 3) Profit! iii) A voice of reason notes that the devil is in step 2) above. If your programming paradigm for concurrency is Threads+Mutexes, then you are exposing yourself to a world of pain in race conditions. At this point someone usually links to Xavier's standard speech on concurrency (which is a few years old, but as poignant now as it was then). iv) The voices from step ii) retort that they're über-programmers and that they can make perfectly scalable and race condition-free programmes with Threads+Mutexes if only they had a concurrent GC. v) The voice of reason remarks that one of the main reasons we all chose Ocaml is because the language ensures safe, resilient programmes. In a way it's the humble recognition that we are human, and that we make mistakes. Choosing the Threads+Mutexes path would be hubris and an abandonment of fundamental reasons why we chose Ocaml in the first place. While I tend to agree with viewpoints iii) and v), I do think a healthy discussion on the subject of multicore is in order. Though I suggest we focus the discussion on concurrency models that will allow us to take advantage of those multicores in a safe, sane manner: a) Could Jocaml be the future of Ocaml? b) How do we handle the global mutability issue? Best regards, Dario Teixeira ___ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
Re: [Caml-list] The Axis of Eval (was: More cores)
Hi again, I can imagine a spawn statement in a concurrent Caml that expects that the function passed as parameter be pure. And of course a function would only be pure if it did not modify global state and only invoked pure functions itself. Incidentally, it is of course possible for a function to invoke impure functions while still being pure itself (ie, it ensures the impurity does not leak out). One question to those more familiar with current language research: any recommended resources out there about this topic? Cheers, Dario Teixeira ___ 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?
Hi, 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.) I reckon that by saying how good 128 bits MD5 hashes were you are aware of the recent attacks that make MD5's effective security less than 128-bit. The Wikipedia has a good summary: http://en.wikipedia.org/wiki/MD5 Cheers, Dario Teixeira ___ 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] Issues with Sexplib (#1)
Hi, I have found a couple of issues with Sexplib/Type-conv. I am not sure they are bugs or features, but to me they come across as unexpected, regardless. In this message I'll report the first one; the second follows momentarily. Consider the Foobar module defined below. It uses a phantom type to annotate values of type Foobar.t, defined recursively. The idea is that constructors A and C are deemed basic while B and D are complex. Functions make_basic and make_complex are used to freeze the structure. Because the complex phantom value propagates across a structure, one cannot apply make_basic to a structure that uses any of the complex constructors. On the other hand, make_complex can be applied to any structure. module Foobar: sig type foobar_t = | A | B | C of foobar_t | D of foobar_t with sexp type basic_t = [ `Basic ] with sexp type complex_t = [ `Complex ] with sexp type 'a t with sexp val make_a: unit - [ `Basic ] t val make_b: unit - [ `Complex ] t val make_c: 'a t - 'a t val make_d: 'a t - [ `Complex ] t val make_basic: [ `Basic ] t - [ `Basic ] t val make_complex: [ `Basic | `Complex ] t - [ `Complex ] t end = struct type foobar_t = | A | B | C of foobar_t | D of foobar_t with sexp type basic_t = [ `Basic ] with sexp type complex_t = [`Complex ] with sexp type 'a t = foobar_t with sexp let make_a () = A let make_b () = B let make_c foobar = C foobar let make_d foobar = D foobar let make_basic x = x let make_complex x = x end So far so good; now consider the code below, which serialises and then unserialises a value of type Foobar.t. Note how a complex structure can be unserialised as basic without any consequences. Therefore, the (de)serialisation process can be used to circumvent the restrictions imposed by the phantom type. open Foobar let foobar = make_complex (make_c (make_b ())) let doc = let sexp = sexp_of_t sexp_of_complex_t foobar in let str = Sexplib.Sexp.to_string_hum sexp in print_endline str; let sexp2 = Sexplib.Sexp.of_string str in let doc = t_of_sexp basic_t_of_sexp sexp2 in doc The resulting types are: val foobar : Document.Foobar.complex_t Document.Foobar.t(* Complex *) val doc : Document.Foobar.basic_t Document.Foobar.t (* Basic *) I understand that phantom types have only a compile-time significance, with no runtime expression at all (hence their name). Therefore, it's not altogether surprising that the S-expression builder would simply ignore them. Still, is there a way to make them explicit in the serialised data, such that the unserialiser would cause a runtime error in the above example? Note that the serialiser is already passed sexp_of_complex_t though it doesn't seem to put it into any actual use. Thanks for your time! Best regards, Dario Teixeira ___ 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] Issues with Sexplib (#2)
Hi again, The second issue is a bit more straightforward, though I reckon it may actually be in Type-conv (used by Sexplib). Consider the following code: (* TYPE_CONV_PATH Order *) module Order = struct type ordinal_t = [ `Ordinal of int ] (* with sexp *) type hierarchical_t = [ `Hierarchical of int list ] (* with sexp *) type appendix_t = [ `Appendix of int list ] (* with sexp *) type 'a scheme_t = 'a constraint 'a = [ ordinal_t | hierarchical_t | appendix_t ] (* with sexp *) type 'a auto_t = [ `Auto of 'a scheme_t ] (* with sexp *) type 'a user_t = [ `User of 'a scheme_t ] (* with sexp *) type none_t = [ `None ] (* with sexp *) type ('a, 'b) given_t = 'b constraint 'b = [ 'a auto_t | 'a user_t | none_t ] (* with sexp *) type body_sectional_order_t = (hierarchical_t as 'a, ['a auto_t | 'a user_t | none_t ]) given_t (* with sexp *) type appendix_sectional_order_t = (appendix_t as 'a, ['a auto_t | 'a user_t | none_t ]) given_t (* with sexp *) type preset_sectional_order_t = (hierarchical_t, none_t) given_t (* with sexp *) type wrapper_order_t = (ordinal_t as 'a, ['a auto_t | 'a user_t]) given_t (* with sexp *) type ghost_order_t = (ordinal_t as 'a, 'a auto_t) given_t (* with sexp *) end It compiles fine. Now uncomment the (* with sexp *) parts, such that it makes use of the Sexplib syntax extension. The compilation fails on the definition of body_sectional_order_t, with an error type_is_recursive: unknown type construct. Is this a known limitation in Type-conv/Sexplib? One last note to the authors of Sexplib: for each reporting of an issue with Sexplib there are tons of unreported happy cases. It is such a great tool that I find myself using it everywhere, hence the inevitability of every now and then running into problems... Thanks again for your attention. Cheers, Dario Teixeira ___ 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] Issues with Sexplib (#1)
Hi, This is not really a bug; I'd qualify this as an undesirable feature: sexplib erases type information; for instance the representation of None* will always be the same and therefore will be desexpable to any other option type. You may also note that some other type have compatible representations. In practice it would be really hard for a camlp4 extension to keep track of types. In you case you could use custom converters and save the phantom type in the sexp. Yes, I figured as much (see the last paragraph of my original message). I was just wondering if there was already a canned solution to this sort of problem (or one in the works), before I wrote a custom converter. Cheers, Dario Teixeira ___ 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 dynlink on 3.11: a request for packagers
Hi, To make it easy to do this for a module or a library would it be possible to add a new default %.cmxs target in ocamlbuild before 3.11 is released (or is it already too late) ? Good point. It shouldn't be too late, since the changes are minimal and 3.11 is only at RC1 status... Cheers, Dario ___ 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] Native dynlink on 3.11: a request for packagers
Hi, As you are probably aware, the upcoming 3.11 release includes Alain Frisch's native dynlink patches. AFAIK, you cannot directly dynlink a cmxa or cmx file like you would do in bytecode with cma or cmo files. Beforehand, a native code binary must be made into a plugin via ocamlopt's -shared option. The suggested convention [1] is to give these plugins a cmxs extension: ocamlopt -shared -linkall -o foobar.cmxs foobar.cmxa These native code plugins are a prerequisite if one intends to run Ocsigen in native mode. Therefore, the life of Ocsigen users would be greatly simplified if library writers and packagers (GODI, Debian, Fedora, etc) would add this little extra step of generating cmxs for each cmxa. This request only makes sense for 3.11, of course. Complementary, META files should also include extra directives for plugins. For example: archive(byte) = foobar.cma archive(native) = foobar.cmxa archive(plugin,byte) = foobar.cma archive(plugin,native) = foobar.cmxs This request can of course become an OSR. My question is if the herein contained instructions will still be valid verbatim for 3.11 final. Will they? Also, please check the Ocsigen Wiki for more info on this subject [2]. Best regards, Dario Teixeira [1] http://alain.frisch.fr/natdynlink.html [2] http://www.ocsigen.org/trac/wiki/NativeCodeVersion ___ 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 dynlink on 3.11: a request for packagers
Hi, Does ocamlfind support any of this? Since I'm now also cross-compiling OCaml, I've certainly come to appreciate findlib more than ever. Indeed it does. The current version of Ocsigen already makes use of this feature. However, because very few (none, actually, other than Ocsigen's) packages currently ship with cmxs files, an Ocsigen user who wants to play with native code is forced to manually generate them. (What impelled me to write the request was precisely having just gone through the process of producing the cmxs for a bunch of Ocamlnet and PXP libraries...) Cheers, Dario ___ 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