Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of October 23 to 30, 2007.

  1. Working on dependent projects with ocamlbuild
  2. Preferred use of Invalid_argument and Failure
  3. Camlp4 as a universal pre-processor ?
  4. Z3 version 1.1
  5. Finger trees
  6. lazy patterns (patterns v 0.3)
  7. Patch to 3.10.0 compiler enabling simple spell-checking

Working on dependent projects with ocamlbuild

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/1e39219f2117bd17/3b6a5ea1f0c70fe0#3b6a5ea1f0c70fe0

Daniel Bünzli explained:
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.
			

Preferred use of Invalid_argument and Failure

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/afe65861a6c384f1/3162e6c9f0aef307#3162e6c9f0aef307

Michaël Le Barbier asked and Xavier Leroy answered:
> 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.
			

Camlp4 as a universal pre-processor ?

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/522333c5bc79d1a9/400ecef341ba4ab5#400ecef341ba4ab5

David Teller asked and Nicolas Pouillard answered:
>  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_tutorial
			
David 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 
  | [< >] -> ()
			

Z3 version 1.1

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/940f31dd01d454b2/ea7b2cb91cddcd85#ea7b2cb91cddcd85

Leonardo de Moura and Nikolaj Bjorner announced:
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
			

Finger trees

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/aeff1d0f48e5b36f/8b64513d1f4830c9#8b64513d1f4830c9

Jon Harrop asked, Arnaud Spiwack said, and Matthieu Sozeau replied:
> > 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...
			

lazy patterns (patterns v 0.3)

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/acfcb60f77824d38/f02a4ba3b0b9e80c#f02a4ba3b0b9e80c

Jeremy Yallop announced:
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
			

Patch to 3.10.0 compiler enabling simple spell-checking

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/97d67528b2c832fa/9d528ae994d45191#9d528ae994d45191

Edgar Friendly announced:
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 Street
			
Julien 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.
			

Using folding to read the cwn in vim 6+

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}$'?'&lt;1':1
zM

If you know of a better way, please let me know.


Old cwn

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.


Alan Schmitt