Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] OCaml 3.12.0+beta1

30 views
Skip to first unread message

Damien Doligez

unread,
Jun 16, 2010, 9:07:44 AM6/16/10
to caml users
Dear OCaml users,

We have the pleasure of celebrating Bloomsday by announcing the release of
OCaml version 3.12.0+beta1.

This is a beta release, available as source only and intended for power
users to test new features and report bugs (if any). This release brings
a lot of new features, see the list included below.

It is available here: < http://caml.inria.fr/pub/distrib/ocaml-3.12/ >,
along with the updated reference manual.

Happy hacking,

-- Damien Doligez for the OCaml team.


--------------------------------------------------------------------------

(Changes that can break existing programs are marked with a "*" )

Language features:
- Shorthand notation for records: in expressions and patterns,
{ lbl } stands for { lbl = lbl } and { M.lbl } for { M.lbl = lbl }
- Record patterns of the form { lbl = pat; _ } to mark that not all
labels are listed, purposefully. (See new warning below.)
- Explicit naming of a generic type; in an expression
"fun ... (type t) ... -> e", the type t is considered abstract in its
scope (the arguments that follow it and the body of the function),
and then replaced by a fresh type variable. In particular, the type
t can be used in contexts where a type variable is not allowed
(e.g. for defining an exception in a local module).
- Explicit polymorphic types and polymorphic recursion. In let
definitions, one can write an explicit polymorphic type just
immediately the function name; the polymorphism will be enforced,
and recursive calls may use the polymorphism.
The syntax is the same as for polymorphic methods:
"let [rec] <ident> : 'a1 ... 'an. <typexp> = ..."
- First-class packages modules.
New kind of type expression, for packaged modules: (module PT).
New kind of expression, to pack a module as a first-class value:
(module MODEXPR : PT).
New kind of module expression, to unpack a first-class value as a module:
(val EXPR : PT).
PT is a package type of the form "S" or
"S with type t1 = ... and ... and type tn = ..." (S refers to a module type).
- Local opening of modules in a subexpression.
Syntax: "let open M in e", or "M.(e)"
- In class definitions, method and instance variable override can now
be made explicit, by writing "method!", "val!" or "inherit!" in place of
"method", "val" and "inherit". It is an error to override an
undefined member (or to use overriding inheritance when nothing get
overridden). Additionally, these constructs disactivate respectively
warnings 7 (method override, code 'M') and 13 (instance variable
override, code 'V'). Note that, by default, warning 7 is inactive
and warning 13 is active.
- "Destructive" substitution in signatures.
By writing "<signature> with type t := <typeconstr>" and
"<signature> with module M := <module-path>" one replaces "t" and "M"
inside the signature, removing their respective fields. Among other
uses, this allows to merge two signatures containing identically
named fields.
* While fixing PR#4824, also corrected a gaping hole in the type checker,
which allowed instantiating separately object parameters and instance
variables in an interface. This hole was here since the beginning of
ocaml, and as a result many programs using object inheritance in a non
trivial way will need to be corrected. You can look at lablgtk2 for an
example.

Compilers and toplevel:
- Warnings are now numbered and can be switched on and off individually.
The old system with letters referring to sets of warnings is still
supported.
- New warnings:
+ 9 (code 'R') to signal record patterns without "; _" where
some labels of the record type are not listed in the pattern.
+ 28 when giving a wildcard argument to a constant constructor in
a pattern-matching.
+ 29 when an end-of-line appears unescaped in a string constant.
+ 30 when the same constructor or record field is defined twice in
mutually-recursive type definitions.
* The semantics of warning 7 (code 'M', method override) have changed
(it now detects all overrides, not just repeated definitions inside
the same class body), and it is now inactive by default.
- Better error report in case of unbound qualified identifier: if the module
is unbound this error is reported in the first place.
- Added option '-strict-sequence' to force left hand part of sequence to have
type unit.
- Added option '-no-app-funct' to turn applicative functors off.
This option can help working around mysterious type incompatibilities
caused by the incomplete comparison of applicative paths F(X).t.

Native-code compiler:
- AMD64: shorter and slightly more efficient code generated for
float comparisons.

Standard library:
- Format: new function ikfprintf analoguous to ifprintf with a continuation
argument.
* PR#4210, #4245: stricter range checking in string->integer conversion
functions (int_of_string, Int32.of_string, Int64.of_string,
Nativeint.of_string). The decimal string corresponding to
max_int + 1 is no longer accepted.
- Scanf: to prevent confusion when mixing Scanf scanning functions and direct
low level input, value Scanf.stdin has been added.
* Random: changed the algorithm to produce better randomness. Now passes the
DieHard tests.
- Map: implement functions from Set that make sense for Map.

Other libraries:
* Str: letters that constitute a word now include digits 0-9 and
underscore _. This changes the interpretation of '\b' (word boundary)
in regexps, but is more consistent with other regexp libraries. (PR#4874).

Ocamlbuild:
- Add support for native dynlink.

New tool:
- ocamlobjinfo: displays various information, esp. dependencies, for
compiled OCaml files (.cmi, .cmo, .cma, .cmx, .cmxa, .cmxs, and bytecode
executables). Extends and makes more official the old objinfo tool
that was installed by some OCaml packages.

All tools:
- PR#4857: add a -vnum option to display the version number and nothing else

Bug Fixes:
- PR#4012: Map.map and Map.mapi do not conform to specification
- PR#4478: better error messages for type definition mismatches
- PR#4683: labltk script uses fixed path on windows
- PR#4742: finalisation function raising an exception blocks other finalisations
- PR#4775: compiler crash on crazy types (temporary fix)
- PR#4824: narrowing the type of class parameters with a module specification
- PR#4862: relaxed value restriction and records
- PR#4884: optional arguments do not work when Some is redefined
- PR#4964: parenthesized names for infix functions in annot files
- PR#4970: better error message for instance variables
- PR#4975: spelling mistakes
- PR#4988: contravariance lost with ocamlc -i
- PR#5004: problem in Buffer.add_channel with very large lengths.
- PR#5008: on AMD64/MSVC port, rare float corruption during GC.
- PR#5018: wrong exception raised by Dynlink.loadfile.
- PR#5057: fatal typing error with local module + functor + polymorphic variant
- Wrong type for Obj.add_offset.
- Small problem with the representation of Int32, Int64, and Nativeint constants.

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

Yoann Padioleau

unread,
Jun 16, 2010, 2:31:11 PM6/16/10
to Damien Doligez, caml users

On Jun 16, 2010, at 6:07 AM, Damien Doligez wrote:

>
> Dear OCaml users,

[...]

> - Record patterns of the form { lbl = pat; _ } to mark that not all
> labels are listed, purposefully. (See new warning below.)

This is cool. Thank you! Does it have to be '_' only ? Can we write also { lbl = pat; _XXX } ?
It's just that _XXX is easier to grep.

Martin Jambon

unread,
Jun 16, 2010, 2:41:06 PM6/16/10
to Yoann Padioleau, Damien Doligez, caml users
Yoann Padioleau wrote:
> On Jun 16, 2010, at 6:07 AM, Damien Doligez wrote:
>
>> Dear OCaml users,
>
> [...]
>
>> - Record patterns of the form { lbl = pat; _ } to mark that not all
>> labels are listed, purposefully. (See new warning below.)
>
> This is cool. Thank you! Does it have to be '_' only ? Can we write also { lbl = pat; _XXX } ?
> It's just that _XXX is easier to grep.

I'm guessing that it would be interpreted as { lbl = pat; _XXX = _XXX }.


Martin

--
http://mjambon.com/

Török Edwin

unread,
Jun 16, 2010, 4:52:22 PM6/16/10
to caml...@yquem.inria.fr
On 06/16/2010 04:07 PM, Damien Doligez wrote:
> Dear OCaml users,
>
> We have the pleasure of celebrating Bloomsday by announcing the release of
> OCaml version 3.12.0+beta1.
>
> This is a beta release, available as source only and intended for power
> users to test new features and report bugs (if any).

I have run the included OCaml testsuite, but I must have done something
wrong since I got some compile failures (unbound modules, and some
missing symbols when linking thread-related tests).

make report output:
Summary:
278 test(s) passed
8 test(s) failed
24 compilation error(s)
0 compilation warning(s)

My system is a Debian Linux x86_64.
What I've done is:
./configure -prefix ~/compilers/o312
make world.opt
make install

Then put $HOME/compilers/o312/bin first in PATH.
Then I've simply run a 'make all' in testsuite/
(under ulimit -v 1024000 -d 1024000 -t 3600).
Note that I also have ocaml 3.11.2 installed.

The failures are below, is this something I'm doing wrong, or should I
open a bugreport?
... testing 't01.ml'Fatal error: cannot load shared library dllcamlstr
Reason: dllcamlstr.so: cannot open shared object file: No such file or
directory
... testing 'Exemples.ml.reference':Files Exemples.ml.reference and
Exemples.ml.result differ
=> failed
... testing 'Tests.ml.reference':Files Tests.ml.reference and
Tests.ml.result differ
=> failed
... testing 'poly.ml.principal.reference':Files
poly.ml.principal.reference and poly.ml.principal.result differ
=> failed
... testing 'poly.ml.reference':Files poly.ml.reference and
poly.ml.result differ
=> failed
... testing 'private.ml.reference':Files private.ml.reference and
private.ml.result differ
=> failed

The link failures in the testsuite look like this:
/home/edwin/compilers/o312/lib/ocaml/threads/threads.a(thread.o): In
function `camlThread__fun_1101':
(.text+0x4b): undefined reference to `caml_thread_uncaught_exception'
/home/edwin/compilers/o312/lib/ocaml/threads/threads.a(thread.o): In
function `camlThread__fun_1086':
(.text+0x8a): undefined reference to `caml_wait_signal'

The unbound module:
... testing 'tbuffer.ml': ocamlcFile "tbuffer.ml", line 3, characters 0-12:
Error: Unbound module Testing

Best regards,
--Edwin

xclerc

unread,
Jun 17, 2010, 9:35:31 AM6/17/10
to caml...@yquem.inria.fr

This looks like a bug in the test suite.
Can you send me (off list) a copy of the "*.result" files that appear
in the trace you get when running the tests?


Thanks for reporting,

Xavier Clerc

xclerc

unread,
Jun 18, 2010, 10:56:17 AM6/18/10
to caml...@yquem.inria.fr


These issues are now fixed in the SVN repository.


Thanks again for reporting,

Stéphane Glondu

unread,
Jun 19, 2010, 1:52:29 AM6/19/10
to caml users, Debian Ocaml Maint ML
Le 16/06/2010 06:07, Damien Doligez a écrit :
> We have the pleasure of celebrating Bloomsday by announcing the release of
> OCaml version 3.12.0+beta1.
>
> This is a beta release, available as source only and intended for power
> users to test new features and report bugs (if any). [...]

I've successfully recompiled almost all Debian packages with this new
version. There are still a few packages that don't compile [3], either
because they are broken or have broken dependencies.

A list of bugs related to this new version is available at [1]. The
titles of the bugreports should give an overview of practical sources of
incompatibilities (these are not Debian-specific). Some of them are
already fixed (either in upstream repository, or with a home-made patch).

I've made a (unofficial) repository binary packages for the amd64
architecture, available at [2]. All sources and build logs are available
as well. It might progressively get populated by binary packages for
armel and mipsel. The binary packages should work with current Debian
unstable, and people using testing or unstable can easily test them.
However, please note that OCaml 3.12.0 will most likely not be updated
(and supported) in the official repositories before the next release of
Debian (Squeeze).

[1]
http://bugs.debian.org/cgi-bin/pkgreport.cgi?users=debian-oc...@lists.debian.org;tag=ocaml312-ftbfs
[2] http://ocaml.debian.net/debian/ocaml3120beta1/
[3] http://ocaml.debian.net/debian/ocaml3120beta1/missing.txt

> [...] This release brings
> a lot of new features, see the list included below. [...]

Here are some other worthwhile features:

- Native-code compiler for ARM EABI -> armel becomes a native
architecture in Debian. Native Dynlink doesn't work, but otherwise
all packages were compiling natively during my earlier experiments
with the SVN version.

- Some support for Findlib in ocamlbuild.

I don't know their official status, though...


Enjoy,

--
Stéphane

Florent Ouchet

unread,
Jun 24, 2010, 5:38:11 AM6/24/10
to Damien Doligez, caml users
Hello,

No problem so far with 3.12.0b1 but...

Damien Doligez a écrit :


> - Record patterns of the form { lbl = pat; _ } to mark that not all
> labels are listed, purposefully. (See new warning below.)
>

This modification heavily breaks backward compatibility with OCaml 3.11.
You should provide some preprocessing scripts to strip these extra "_".

Best Regards,

--
Florent Ouchet
PhD Student
CIS/VDS Team - TIMA Laboratory

Martin Jambon

unread,
Jun 24, 2010, 1:45:29 PM6/24/10
to florent...@imag.fr, Damien Doligez, caml users
Florent Ouchet wrote:
> Hello,
>
> No problem so far with 3.12.0b1 but...
>
> Damien Doligez a écrit :
>> - Record patterns of the form { lbl = pat; _ } to mark that not all
>> labels are listed, purposefully. (See new warning below.)
>>
> This modification heavily breaks backward compatibility with OCaml 3.11.
> You should provide some preprocessing scripts to strip these extra "_".

I disagree. The syntax is a new and optional feature. Authors who want their
new code to compile with an earlier version of OCaml should simply avoid using
the new feature, as always.

Finally we'll be able to use pattern matching on records for real and it's
really cool. That means we can use records where we used to prefer tuples,
typically on things like tree nodes. It will make it easier to add fields
when the code evolves, compared to tuples.

Tuple version:

let loc, _, _, name, _ = x in ...

Record version:

let { loc; name; _ } = x in ...

Old record version:

let { loc = loc; name = name } = x in ...

Martin

--
http://mjambon.com/

Florent...@imag.fr

unread,
Jun 24, 2010, 2:59:22 PM6/24/10
to Martin Jambon, Damien Doligez, caml users
Martin Jambon <martin...@ens-lyon.org> a écrit :

> I disagree. The syntax is a new and optional feature. Authors who
> want their
> new code to compile with an earlier version of OCaml should simply
> avoid using
> the new feature, as always.

The 3.12 version number is just minor increment. It should keep
backward compatibility with the 3.x branch as much as possible.

> Finally we'll be able to use pattern matching on records for real and it's
> really cool. That means we can use records where we used to prefer tuples,
> typically on things like tree nodes. It will make it easier to add fields
> when the code evolves, compared to tuples.

Yes, this feature is cool. We agree on this point. However not all
systems will be updated to 3.12 as soon as the final version is out.
Most users rely on their linux distribution ocaml (Debian stable is
still stuck at 3.10 for instance).

For syntax sugar extensions, such as { loc; name; _ }, your "don't use
it" conclusion can be understood. But for code stabilization syntax
extensions, such as { ... ; _ }, it's an other story. Users stuck with
more stable versions of the compiler should be able to use more stable
versions of software compiled with it.

- Florent

Dmitry Bely

unread,
Jun 24, 2010, 3:29:41 PM6/24/10
to Caml List
On Thu, Jun 24, 2010 at 10:59 PM, <Florent...@imag.fr> wrote:
> Martin Jambon <martin...@ens-lyon.org> a écrit :
>>
>> I disagree.  The syntax is a new and optional feature.  Authors who want
>> their
>> new code to compile with an earlier version of OCaml should simply avoid
>> using
>> the new feature, as always.
>
> The 3.12 version number is just minor increment. It should keep backward
> compatibility with the 3.x branch as much as possible.

I'm sorry but where do you see a violation of backward compatibility?
Can you provide an example that compiles OK with Ocaml 3.11 and
generates an error with Ocaml 3.12?

- Dmitry Bely

Mathias Kende

unread,
Jun 24, 2010, 3:32:11 PM6/24/10
to Florent...@imag.fr, Damien Doligez, caml users
Le jeudi 24 juin 2010 à 20:59 +0200, Florent...@imag.fr a écrit :
> Martin Jambon <martin...@ens-lyon.org> a écrit :
> > I disagree. The syntax is a new and optional feature. Authors who
> > want their
> > new code to compile with an earlier version of OCaml should simply
> > avoid using
> > the new feature, as always.
>
> The 3.12 version number is just minor increment. It should keep
> backward compatibility with the 3.x branch as much as possible.

Backward compatibility is the ability for the 3.12 compiler to compile
source code written for the 3.11 or earlier version. And this is
(mostly) achieved.

What you're asking for is "forward compatibility". An no one really
wants that, because it would prevent any new feature in the compiler
exept on those rare major version.

Mathias

Till Varoquaux

unread,
Jun 24, 2010, 3:39:50 PM6/24/10
to Florent...@imag.fr, Damien Doligez, caml users
On Thu, Jun 24, 2010 at 2:59 PM, <Florent...@imag.fr> wrote:
> Martin Jambon <martin...@ens-lyon.org> a écrit :
>>
>> I disagree.  The syntax is a new and optional feature.  Authors who want
>> their
>> new code to compile with an earlier version of OCaml should simply avoid
>> using
>> the new feature, as always.
>
> The 3.12 version number is just minor increment. It should keep backward
> compatibility with the 3.x branch as much as possible.
>
>> Finally we'll be able to use pattern matching on records for real and it's
>> really cool.  That means we can use records where we used to prefer
>> tuples,
>> typically on things like tree nodes.  It will make it easier to add fields
>> when the code evolves, compared to tuples.
>
> Yes, this feature is cool. We agree on this point. However not all systems
> will be updated to 3.12 as soon as the final version is out. Most users rely
> on their linux distribution ocaml (Debian stable is still stuck at 3.10 for
> instance).
>
> For syntax sugar extensions, such as { loc; name; _ }, your "don't use it"
> conclusion can be understood. But for code stabilization syntax extensions,
> such as { ... ; _ }, it's an other story. Users stuck with more stable
> versions of the compiler should be able to use more stable versions of
> software compiled with it.
>
> - Florent

>From wikipedia:

"In the context of telecommunications and computing a device or
technology is said to be backwards or downwards compatible if it can
work with input generated by an older device"

Do you have an example of old code not being able to compile anymore
because of that change? If so you should probably fill in a bug
report.

As for forward compatibility (ie programs coded with 3.12 in mind
might not compile with 3.10) this is a price I am happy to pay in
order to have a language that's constantly improving. I think that
this is feeling that is shared by many.

And, last but nor least, older does not necessarily mean more stable.
You seem to use those interchangeably in your mail. Windows 3.11 is
old...

Till

Florent Ouchet

unread,
Jun 24, 2010, 4:50:02 PM6/24/10
to Till Varoquaux, Damien Doligez, caml users
Till Varoquaux <ti...@pps.jussieu.fr> a écrit :

> As for forward compatibility (ie programs coded with 3.12 in mind
> might not compile with 3.10) this is a price I am happy to pay in
> order to have a language that's constantly improving. I think that
> this is feeling that is shared by many.

ok all, it has to be considered as forward compatibility, speaking at
ocaml point-of-view, this POV is likely the one most of you have.
However, at source POV (where OCaml is seen as a tool), this can be
seen as backward compatibility: the source code we write could be
backward compatible with older versions of OCaml. Anyway, I will stop
here the terminology fight and use your POV...

> And, last but nor least, older does not necessarily mean more stable.

..and I won't feed the troll too.

> You seem to use those interchangeably in your mail. Windows 3.11 is
> old...

This specific ( { ; _} ) forward compatibility with ocaml <3.12 is
possible for a little cost. It's just about removing the extra
underscore characters. Anyway if the preprocessing script does not
come out of the ocaml 3.12 box, I will have to do it. Other developers
may have to so as well.
Mainly because this coverage check is a must-do and because I do not
want to force a general update to OCaml 3.12 when that can be avoided.
The coverage check has to be done only once, at "developer's" side,
using 3.12. Once the changes are done, stripped code can easily be
compiled using older versions of OCaml, at "user's" side.

- Florent

Hezekiah M. Carty

unread,
Jun 24, 2010, 4:57:40 PM6/24/10
to Florent Ouchet, caml users
On Thu, Jun 24, 2010 at 4:49 PM, Florent Ouchet <florent...@imag.fr> wrote:
>
> This specific ( { ; _} ) forward compatibility with ocaml <3.12 is possible
> for a little cost. It's just about removing the extra underscore characters.
> Anyway if the preprocessing script does not come out of the ocaml 3.12 box,
> I will have to do it. Other developers may have to so as well.
> Mainly because this coverage check is a must-do and because I do not want to
> force a general update to OCaml 3.12 when that can be avoided. The coverage
> check has to be done only once, at "developer's" side, using 3.12. Once the
> changes are done, stripped code can easily be compiled using older versions
> of OCaml, at "user's" side.
>

The trailing _ in a record match is not required. It is allowed in
3.12, and in combination with an optional warning flag it can be used
to check for incomplete record matches. Why is any preprocessing
needed? If an application is written to require OCaml 3.12.x or
later, why would you expect it to compile with an earlier version?

How is this a bigger "backward compatibility" break than first-class
modules or the "let open Module in" syntax?

Hez

Florent Ouchet

unread,
Jun 24, 2010, 6:06:24 PM6/24/10
to Hezekiah M. Carty, caml users
"Hezekiah M. Carty" <hca...@atmos.umd.edu> a écrit :

> The trailing _ in a record match is not required. It is allowed in
> 3.12, and in combination with an optional warning flag it can be used
> to check for incomplete record matches. Why is any preprocessing
> needed? If an application is written to require OCaml 3.12.x or
> later, why would you expect it to compile with an earlier version?

Software development is not your perfect and ideal world. Would you
buy a brand new car because your current two-month-old car does not
have seat belt reminders? New warnings are almost the only
improvements I'm interested in 3.12.

Sometimes you have to support old compiler versions (this choice is
not yours) and you need a complete confidence in all the thousands
record pattern matchings of your application, some of them (maybe 30%)
are intentionally left incomplete in order to keep the code as simple
as possible.

Without preprocessing scripts, I will not be able to insert extra "_"
for masking intentionally-left-incomplete pattern matchings. The
compilation log will be polluted by hundred warnings (false-positive).
Finally, the catch of the few remaining should-not-be-incomplete
pattern matchings (true-positive) will be very hard.

Anyway, I'm running out of arguments and the problem is still there...
I would have wasted less time in having the scripts setup than in
arguing here.

--
Florent Ouchet
PhD Student, CIS/VDS Groups
TIMA Laboratory, Grenoble, France

bluestorm

unread,
Jun 25, 2010, 1:55:09 AM6/25/10
to Florent Ouchet, caml users
Wouldn't a simple sed "s/; _ }/}/g" suffice in practice ?

bluestorm

unread,
Jun 25, 2010, 3:30:09 AM6/25/10
to Damien Doligez, caml users
There is a small typo in the 3.12 reference manual. In section 7.14 :
« The code above should how to use first-class modules to simulate
existentials. » (should how)

bluestorm

unread,
Jun 25, 2010, 4:18:14 AM6/25/10
to Florent Ouchet, caml users
Here is a small Camlp4 filter removing exhaustive patterns. It obviously
depends on 3.12.

open Camlp4.PreCast;;

let filter =
function
| <:patt@_loc< { $p$ } >> ->
let rec clean = function
| <:patt< _ ; $p$ >> | <:patt< $p$; _ >> -> clean p
| <:patt@_loc< $p1$; $p2$ >> -> <:patt< $clean p1$; $clean p2$ >>
| p -> p in
<:patt< { $clean p$ } >>
| t -> t
;;

AstFilters.register_str_item_filter (Ast.map_patt filter)#str_item;;


(*
#step I used to compile and test the code from a freshly compiiled (but
not installed) ocaml-3.12 beta :
#I build using fastworld.sh (see INSTALL) then `cd _build`
../byterun/ocamlrun -I otherlibs/unix/ camlp4/camlp4orf.byte /tmp/
exhaustive_record_stripper.ml -o /tmp/stripper.ml
../byterun/ocamlrun ./ocamlc -I stdlib -I camlp4 /tmp/stripper.ml -c
../byterun/ocamlrun -I otherlibs/unix/ camlp4/camlp4o.byte
/tmp/stripper.cmo -str 'fun {a; b; _} -> c'
#output : fun { a = a; b = b } -> c
*)


Notes :
- that the OCaml printer expand sugared { a; b } patters into { a = a; b = b
} is necessary for printing backward-compatible code; I'm not sure it's a
good idea to rely on this.
- as with every camlp4 filters, the code is parsed then pretty-printed; do
not expect indentation to stay as is. Comment placement is also going to do
weird things (know and nearly-unfixable camlp4 defect) : ocamldoc may not
work properly on the output code.

David Allsopp

unread,
Jun 25, 2010, 4:48:51 AM6/25/10
to bluestorm, Florent Ouchet, caml users
bluestorm wrote:
> Here is a small Camlp4 filter removing exhaustive patterns. It obviously depends on 3.12.
>
<snip>

>
>
> Notes :
> - that the OCaml printer expand sugared { a; b } patters into { a = a; b = b } is necessary
> for printing backward-compatible code; I'm not sure it's a good idea to rely on this.

If *your* code has to be *backwards*-compatible with the OCaml 3.11.x compiler then you shouldn't be using that shorthand at all - the point with the {; _} syntax is that it's necessary to suppress a warning in OCaml 3.12 which isn't present in 3.11 (in other words, that syntax has to be used in 3.12 as I'm sure we all agree that any well-written piece of code should never emit compiler warnings). Any features in 3.12 shouldn't be being used at all *if* 3.11 compatibility is your goal.

> - as with every camlp4 filters, the code is parsed then pretty-printed; do not expect indentation
> to stay as is. Comment placement is also going to do weird things (know and nearly-unfixable camlp4 defect)

Seems fine.

> : ocamldoc may not work properly on the output code.

Sounds like a showstopper for most packages as that would break doc/docs Makefile targets (shame, because a camlp4 script seems the obvious way to do it). Presumably any package that's going to be written for 3.12 but aim to compile on 3.11.x is going to have to .311.ml files (or some such scheme) generated for the sources tarball and then have those selected by a configure script when it detects OCaml 3.11.x or earlier (similar scheme to supporting 3.09- camlp4 and 3.10+ camlp4). If camlp4 sadly can't do it reliably, how about combining the sed suggestion you made:

sed -e "s/; *_ *}/}/g"

with a test compilation in OCaml 3.11 to pick up any instances where line-breaking has been a problem (in other words, change your coding conventions and use the compiler to check that they've been adhered to)? It's not a particularly hard sed[*] script to read a few lines at a time and change the regexp to "s/;[ \t\n]*_[ \t\n]*}/}/g" to handle different line breaking conventions as well (and you could insert an additional regexp to handle non-nested comments in that gap as well). That would have the benefit of not messing up ocamldoc comments.

As an aside, while it seems fair enough that a pre-processor such as camlp4 may mess up *comments* it seems to me a bug that it messes up ocamldoc *instructions* (which are reasonably viewable as a functional part of your code). But is that a well-rehearsed argument about a really unfixable problem?


David


[*] or substitute your favourite text processor here!

bluestorm

unread,
Jun 25, 2010, 5:35:55 AM6/25/10
to David Allsopp, caml users
On Fri, Jun 25, 2010 at 10:48 AM, David Allsopp <dra-...@metastack.com>wrote:

>
> If *your* code has to be *backwards*-compatible with the OCaml 3.11.x

> compiler then you shouldn't be using that shorthand at all. [..] Any


> features in 3.12 shouldn't be being used at all *if* 3.11 compatibility is
> your goal.


The problem is that camlp4 doesn't distinguish at present between "a; " and
"a = a;" as label patterns : the former is desugared into the latter while
parsing. With the current implementation, both will be pretty-printed as "a
= a;". It may happen however than the implementation change and both be
printed as "a;". In that case, my implementation would break. That's what I
meant.

In the best of all worlds (user-wise), Camlp4 would track that information
and always output "a;" when there was "a;", and "a = a;" otherwise. I'm not
sure it's worth complicating the Camlp4 AST again for such a feature.

It is possible to work-around this issue by using a slightly more subtle
pattern : my filter could for example translate "a = a" in "a = (_ as a)",
wich is equivalent and surely wouldn't be resugared.

> I'm sure we all agree that any well-written piece of code should never emit
> compiler warnings


I don't agree. Warnings are there for things that could be errors, but are
not necessarily one. In some case you'll want to break the rules. You may
use build options to disable the specific warning in the specific file, but
that's not necessarily a good idea. I'm happy with some warning remaining if
they're justified.

This discussion is reminiscent of on the warn-error problem we were recently
warned (!) about by Damien (do not use warn-error for released code !) :
http://caml.inria.fr/pub/ml-archives/caml-list/2009/11/91883440c8a0481a4233758946e5c3bf.fr.html

> As an aside, while it seems fair enough that a pre-processor such as camlp4
> may mess up *comments* it seems to me a bug that it messes up ocamldoc
> *instructions* (which are reasonably viewable as a functional part of your
> code). But is that a well-rehearsed argument about a really unfixable
> problem?
>

In that case, it isn't really a problem. There could be an issue if an user
want to build documentation for a 3.12 code translated into a 3.11 code by a
camlp4 filter. Why not simply use ocamldoc-3.12 to generate the
documentation instead ?


For the generate case, well, it is a problem. OCaml doc instructions are
comments (if we're both talking about the (** .. *) thing), and comments and
whitespace are not handled well by syntaxic AST for language where they
don't matters.
Ocamldoc use a comment position hack to associate comments to the caml AST,
and while it's probably a necessary hack, I'm not sure it's fair to blame
camlp4 for breaking it.


If you really want language-integrated documentation, the Right Thing To Do
is to keep places for documentation/annotations directly in the language
syntax (and AST). This is what Python has done with the "docstring" wich has
a dedicated place in declarations.
There is no such thing in Ocaml syntax, so we have to use workarounds that
work reasonably well, but not always.

0 new messages