Hello
Here is the latest Caml Weekly News, for the week of October 23 to 30, 2007.
Somewhat related to the discussion we had about the (bad) idea of embedding dependencies into projects. I'd like to share the following setup with ocamlbuild that allows me to work simultaneously on a 'base' project and two independent projects 'p1' and 'p2' that use 'base'. Basically my sources are distributed as follows : base/src p1/src p2/src What I used to do is to build a .cma out of the sources in base/src and point the others to that .cma. When I did a change in base, I had to build that .cma again, sometimes forgetting and seeking for bugs in code while it was just a .cma freshness issue. What I do now is that I completly forget about .cma's. I just create the following links in p1 and p2 ln -s ../base/src p1/base ln -s ../base/src p2/base And add the following to their _tags file : echo "<base>: include" >> p1/_tags echo "<base>: include" >> p2/_tags The rest is simply sorted out by ocamlbuild. Whenever I do a change in base/src I don't need to recompile anything there, if I rework in p1 or p2 things are automatically updated, I always use the latest version of base's code. Of course this means longer build time when you ocamlbuild -clean in p1 and p2 since they each build their own version of base. But on the scale at which I work it is currently not an issue. The only caveat (that may disappear in the future) is that base/src should be able to build without a plugin. Otherwise you will have to integrate base's myocamlbuild.ml instructions into p1 and p2's myocamlbuild.ml (btw. couldn't we find a less egoistic name for that file). But if you are only working with _tagged caml sources it should works perfectly, put your tags for base in base/src/_tags.
> Let's quote the manual (release 3.09): > exception Invalid_argument of string > Exception raised by library functions to signal that the given > arguments do not make sense. > exception Failure of string > Exception raised by library functions to signal that they are > undefined on the given arguments. > It seems to me that Invalid_argument is a sort of specialisation of > Failure. The convention that the standard library tries to follow is this. Invalid_argument is very much like a failed assertion: it indicates that something is wrong in the program itself, i.e. negative character positions in string functions. Most programs will not catch Invalid_argument, treating as a fatal error. Others will catch it, but only to enter a piece of generic "recover from unexpected error" code. Failure, on the other hand, signals errors that can happen in normal runs of the code. For instance, you're converting a user-provided string to a number, and the string does not represent a number. It is expected that the client code catches Failure and recovers gracefully, e.g. by asking for the number again, or producing a precise "syntax error" message. I recommend the use of Invalid_argument to report "should never happen" conditions at the boundary between library functions and user code. On the other hand, the "Failure" exception is a bit of a legacy from earlier designs (Caml Light and even the original LeLisp-based Caml), and often is not the best way to report "normal error" conditions: instead, you could consider defining your own exceptions as Alain suggested, or even have your functions return "option" types instead of raising exceptions.Yaron Minsky said, Joel Reymont asked, and Yaron Minsky replied:
> > Where I work, we have come to dearly love the practice of returning > > polymorphic variants with explicit variants for various "normal" > > error cases. > > Can you elaborate? Are your explicit variants still polymorphic? As in: map_of_alist : ('a * 'b) list -> [ `Repeated_key of 'a | `Succ of ('a,'b) Map.t ] The return value is both explicit and a polymorphic variant.
> I'm currently playing with camlp4 3.10. I've succeeded in making a > syntax extension to help me generate annotated trees, which is a good > start. > > Now, I understand that, by invoking ocpp, camlp4 may be used as a > pre-processor for non-OCaml language, which sounds interesting, for I > have need of pre-processing some parser generator input (at the moment, > menhir, but there are good chances I'll switch to Dypgen to get around > some limitations) to maintain consistency between the implementation and > the specifications. There are very good chances that I could do that > with cpp, as it's essentially trivial pre-processing, but I'd rather use > camlp4, if only to learn more about it. > > So, my question is: how do I write a pre-processor that doesn't depend > on the syntax of OCaml ? I'm hoping I can get away with one or two > quotations and one anti-quotation, but I have no clue how to register > these without adding dependencies to either OCaml's Original or Revised > syntax. Does anyone have any examples handy ? A way to start this is to just keep the lexer and provide a new grammar including quotations [2] and antiquotations. On the wiki [1] there is also a small but complete example of a grammar for the untyped lambda calculus with antiquotations [3], and also a tutorial of making a full parser with Camlp4 [4]. [1]: http://brion.inria.fr/gallium/index.php/Camlp4 [2]: http://brion.inria.fr/gallium/index.php/Quotation [3]: http://brion.inria.fr/gallium/index.php/Lambda_calculus_quotations [4]: http://brion.inria.fr/gallium/index.php/Full_parser_tutorialDavid Teller then asked and Nicolas Pouillard replied:
> I've read the Lambda example, but it looked to me like it was a syntax > extension for OCaml and no other language, unless I completely > misunderstand the meaning of, say, <:expr<...>> . You're right the lambda example is not adapted. > Now, do you suggest I should write a full lexer and parser with Camlp4 > just in order to write simple macros ? Hum, in fact that's because ocpp is no longer supported in Camlp4 3.10 (another (external) tool that can replace it is in preparation). However writing a small lexer that catch some quotation of yours is quite simple; but since you where talking about menhir and dypgen they certainly have lexing conventions quite close to OCaml, so the default lexer should suffice. It's mainly about writing a parser that search for some QUOTATION tokens and expand them, in fact it will be even simpler to directly use a stream parser. (* pseudo untested code *) let rec go = parse | [< '(QUOTATION q, _loc); strm >] -> expand q; go strm | [< '(token, _loc); strm >] -> Token.<some function> tok; go strm | [< >] -> ()
We are pleased to announce of Z3 version 1.1. Z3 is a new high-performance theorem prover for Satisfiability Modulo Theories (SMT) problems being developed at Microsoft Research. Z3 supports linear real and integer arithmetic, fixed-size bit-vectors, extensional arrays, uninterpreted functions, and quantifiers. Z3 has already been integrated in several projects and products at Microsoft. It can read problems in SMT-LIB, Simplify and a native low-level format. Z3 can also be invoked programmatically from either C/C++, OCaml or from .NET. More information about Z3, including download links are available from: http://research.microsoft.com/projects/z3
> > I'm just perusing the multitude of tree data structures out there and was > > wondering if anyone has a finger tree implementation written in OCaml? > > There's at least been a Coq implementation (proven correct if I'm not > mistaken). Thus extractible into OCaml in a probably idiomatic way. I don't > know if the library is self contained or just a small proof-of concept, > though. > > http://www.lri.fr/~sozeau/research/russell/fingertrees.fr.html Indeed, this is a certified implementation of Finger Trees, it's just not ready for release yet. I'm actually working on a version using modules which extracts to efficient OCaml code (e.g. ropes built on top of them permit to run the ICFP simulator in reasonnable time). So, the basic extracted code works well but I haven't finished building a certified implementation of the ropes which I want to release with it. In the meantime you can try this extracted version: http://www.lri.fr/~sozeau/res/fingertrees-0.1.tgz Some random notes: - No documentation / beautifying of the ocaml sources, look at the Coq literate code for that, available from the webpage: http://www.lri.fr/~sozeau/research/russell/fingertrees.en.html - Uses a bit of Obj.magic for polymorphic recursion - Some artifacts of extraction make it a bit slower than it could be (useless beta-redexes) - Should still be bug free even at 0.1 ! - Uses ocamlfind for installation - Released under the LGPL - It will get polished soon...
I'm pleased to announce a new release of `patterns', an OCaml extension providing general-purposes additions to pattern matching. This release includes a new feature, "lazy patterns". You can download patterns from http://code.google.com/p/ocaml-patterns/ Lazy patterns extend OCaml pattern syntax with the keyword "lazy", mirroring the use of lazy in expressions. With this extension patterns can be used to deconstruct lazy values; for example, you can define a function that behaves like Lazy.force as follows let force (lazy x) = x or, given a type of lazy lists in the "odd style": type 'a llist = Nil | Cons of 'a * lazy llist you can write a lazy map function: let rec map f = function | Nil -> Nil | Cons (h, lazy t) -> Cons (f h, lazy (map f t)) You can use "lazy" anywhere you can use a constructor: in nested patterns, or-patterns, patterns for "let", "function", "match", "try/with", etc. Lazy patterns can also be used with the other extension provided in the current release, pattern guards: you can write, for example, match v with | A (x, y) with lazy (z,w) = f x -> e Paradoxically, lazy patterns make pattern-matching more eager, since they force evaluation of delayed values. However, no more forcing than necessary (for some suitable definition thereof) will occur: the following will return "true", for example. match lazy 3, lazy (assert false) with | lazy 2, lazy x -> false | lazy 3, _ -> true Documentation for lazy patterns will be available soon. Comments are welcome, bug reports especially so. A caveat: due to the translation used, lazy patterns can sometimes give rise to spurious warnings. For example, for the following function function lazy (Some _) -> 1 | lazy None -> 0 OCaml gives the warning "Warning X: bad style, all clauses in this pattern-matching are guarded." It is of course possible to avoid these warnings by using "-w x" or by adding redundant match cases. For information on pattern guards see the previous announcements v0.1: http://groups.google.com/group/fa.caml/msg/b0ec5324180bfeba v0.2: http://groups.google.com/group/fa.caml/msg/016e76d7a51559c8 and the documentation on the website http://code.google.com/p/ocaml-patterns/wiki/PatternGuards
Editor note: the patches are available at the archive link above. One random little feature of GNAT that comes in handy for me is its habit of, when I misspell an identifier, giving me a possible correction in its compile error message. Spending some time with the 3.10.0 sources, I have created a "second draft" patch creating this functionality in my favored language. Example: ======== # /home/thelema/Projects/ocaml-custom/bin/ocamlc -o coml -I +lablgtk2 lablgtk.cma gtkInit.cmo coml.ml File "coml.ml", line 61, characters 16-25: Unbound value is_arcive, possible misspelling of is_archive Impacts: ======== Efficiency in the case of finding a mistake should be quite good, although this shouldn't matter too much since the compiler quits pretty early in compilation when it finds an unbound identifier. In the case of no unbound identifiers, the cost is an extra try/with block around the standard lookup. I haven't made any benchmarks, though. I expect this code to have little long term maintenance issues - the major source of code changes was adding a "* string list" to a number of exceptions to carry the list of possible correct spellings to the point they get output by the compiler. These exceptions are still usable as before with an empty list in this spot. It's possible the code has created opportunities for uncaught exceptions in the compiler as I only checked for instances of "Not_found" in a few files -- those which dealt with the Unbound_* exceptions. Someone who knows the internals better might find places the "Found_nearly" exception that carries possible corrections might escape into. Dedicated to: Yaron Minsky and the team at Jane StreetJulien Moutinho asked and Edgar Friendly answered:
> I'm sorry but could it be that you have posted an incomplete patch? I did. Here's a "third draft" which should include all the necessary bits to patch off 3.10.0. There's still plenty of rough edges to smooth out in the patch, but it should suffice for people to have something working.
Here is a quick trick to help you read this CWN if you are viewing it using vim (version 6 or greater).
:set foldmethod=expr
:set foldexpr=getline(v:lnum)=~'^=\\{78}$'?'<1':1
zM
If you know of a better way, please let me know.
If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.
If you also wish to receive it every week by mail, you may subscribe online.