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

[Caml-list] Ocaml compiler features

14 views
Skip to first unread message

Edgar Friendly

unread,
Jan 13, 2007, 12:41:43 AM1/13/07
to caml...@yquem.inria.fr
There's a few things I'd like to fix about ocaml, and I should probably
air these and get feedback/help before jumping in and getting lost in
the compiler code.

First, I'd like to fix grouping within the if/then/else construct. This
is parsed fine:

if y=1 then
let z = 2 in
print_int y;
print_int z;
else
print_string "not one"

But the following isn't accepted:

if y=1 then
print_int y;
print_int 2;
else
print_string "not one"

I understand that the let statement groups the following compound
expression into one statement for the then-clause, so it's a precedence
problem. Would it really be enough to raise the precedence of ; higher
than that of if/then? Is there any reason this hasn't been done already?

Second, I have some ideas of things to do with Atomic Variants (sounds
like they could be a monster in a sci-fi movie). First thing is to
somehow allow the use of a type composed of all Atomic (non-polymorphic)
Variants as an integer type. One thing I want to do is index arrays
with them. Yes, I could use records, but then I couldn't iterate across
the structure.

Thanks for listening, and tune in next time for more crazy ideas.
E.

_______________________________________________
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

Tom

unread,
Jan 13, 2007, 1:00:25 AM1/13/07
to Edgar Friendly
>
>
> Second, I have some ideas of things to do with Atomic Variants (sounds
> like they could be a monster in a sci-fi movie). First thing is to
> somehow allow the use of a type composed of all Atomic (non-polymorphic)
> Variants as an integer type. One thing I want to do is index arrays
> with them.
>

Hm... instead of having

type food = Carrot | Apple | Pizza | Coke | Sushi

let in_supply = Array.create 5 0

in_supply.(Coke) <- 20

you could do it like this instead

let carrot, apple, pizza, coke, sushi = 0, 1, 2, 3, 4

let in_supple = Array.create 5 0

in_supply.(coke) <- 20

What do you think?

- Tom

David Baelde

unread,
Jan 13, 2007, 2:45:13 AM1/13/07
to Edgar Friendly
On 1/13/07, Edgar Friendly <thele...@gmail.com> wrote:
> I understand that the let statement groups the following compound
> expression into one statement for the then-clause, so it's a precedence
> problem. Would it really be enough to raise the precedence of ; higher
> than that of if/then? Is there any reason this hasn't been done already?

It may be useful to note that some people might want to write code like:

foo ;
x <- if y then a else b ;
bar ;

In that example bar is really meant to be outside the if-then-else.

OCaml has no such thing as statements, but only expressions. But let
me use these words: you want a statement-level if-then-else with lower
precedence than ";", it cannot be the same as this expression-level
if-then-else with higher precedence than ";". If you're bored with
begin/end a good solution might be to define a new construct using
camlp4 instead of hacking the compiler. It's the good advice in
general for syntax problems.

my_if condition my_then
foo ;
x <- if y then a else b ;
bar ;
my_else
etc

Of course one wants better keywords than this. Finally, I'd made the
closing of that new if mandatory, it seems clearer.

Hope that helps.
--
David

ketty

unread,
Jan 13, 2007, 4:35:35 AM1/13/07
to david....@ens-lyon.org
Hi,

On 1/13/07, Edgar Friendly <thele...@gmail.com> wrote:
> Would it really be enough to raise the precedence of ; higher
> than that of if/then? Is there any reason this hasn't been done already?

and

On 1/13/07, David Baelde <david....@gmail.com> wrote:
> It may be useful to note that some people might want to write code like:
>
> foo ;
> x <- if y then a else b ;
> bar ;
>
> In that example bar is really meant to be outside the if-then-else.


I think the biggest consern is that the else clause is optional. So
you can write code like this:

if condition then do_something (); (* no trailing else clause *)
do_something_else (); (* this is outside the if expression ')
...etc...

Edgar Friendly

unread,
Jan 14, 2007, 12:38:47 PM1/14/07
to caml...@yquem.inria.fr
David Baelde wrote:
> > On 1/13/07, Edgar Friendly <thele...@gmail.com> wrote:
>> >> I understand that the let statement groups the following compound
>> >> expression into one statement for the then-clause, so it's a
precedence
>> >> problem. Would it really be enough to raise the precedence of ;
higher
>> >> than that of if/then? Is there any reason this hasn't been done
already?
> >
> > It may be useful to note that some people might want to write code like:
> >
> > foo ;
> > x <- if y then a else b ;
> > bar ;
> >
> > In that example bar is really meant to be outside the if-then-else.
> >

I think this is the uncommon case, and deserves the parentheses:
x <- (if y then a else b) ;

> > OCaml has no such thing as statements, but only expressions. But let
> > me use these words: you want a statement-level if-then-else with lower
> > precedence than ";", it cannot be the same as this expression-level
> > if-then-else with higher precedence than ";".

I think I'm arguing that the precedence of if/then/else is too high, and
maybe should be lowered. Of course this isn't a reasonable thing to
ask, because it'll likely break existing code. Anyone with a way to
have my cake and eat it too?

> > If you're bored with
> > begin/end a good solution might be to define a new construct using
> > camlp4 instead of hacking the compiler. It's the good advice in
> > general for syntax problems.

Writing things in camlp4 could help me, but won't improve the world of
ocaml. I want to compare the situation to TeX / LaTeX -- since you can
customize it so much, people fix what they don't like on their local
copy, but these improvements never make it upstream to improve the
situation for the world.

I will agree that I am too eager to "fix" the compiler, and appreciate
the community's help in tempering my inexperience. But I'd like to help
ocaml become a better language, and this seems like a reasonable small
step to start on.

E.

ketty

unread,
Jan 14, 2007, 1:03:29 PM1/14/07
to Edgar Friendly
On 1/14/07, Edgar Friendly <thele...@gmail.com> wrote:
> That gives me what I've asked for at the moment, but I really want
> arrays indexed by atomic variant types in a type-safe way. i.e. so I
> could do:

>
> type food = Carrot | Apple | Pizza | Coke | Sushi
> let in_supply = Super_array.create food 0
> in_supply.(Coke) <- 20
> for f in food'range do
> printf "%s - %d" f'name in_supply.(f)
> done
>

What you really want is a mapping from a variant type to elements of
data. We already have the Map and Hashtbl modules for that. Although
it would be nice with some syntactic sugar for dealing with them.
There seems to be an old syntax extension for hashtables here:
http://www.bononia.it/~zack/stuff/hashtbl_ext.ml

Edgar Friendly

unread,
Jan 14, 2007, 1:26:09 PM1/14/07
to ketty
ketty wrote:
> On 1/14/07, Edgar Friendly <thele...@gmail.com> wrote:
>> That gives me what I've asked for at the moment, but I really want
>> arrays indexed by atomic variant types in a type-safe way. i.e. so I
>> could do:
>>
>> type food = Carrot | Apple | Pizza | Coke | Sushi
>> let in_supply = Super_array.create food 0
>> in_supply.(Coke) <- 20
>> for f in food'range do
>> printf "%s - %d" f'name in_supply.(f)
>> done
>>
>
> What you really want is a mapping from a variant type to elements of
> data. We already have the Map and Hashtbl modules for that. Although
> it would be nice with some syntactic sugar for dealing with them.
> There seems to be an old syntax extension for hashtables here:
> http://www.bononia.it/~zack/stuff/hashtbl_ext.ml
>
Yes to the first sentence, I think no on the second. Map and Hashtbl
are very good, but I think I really want an array. For an ('a, 'b) Map,
this is for situations where the set of 'a is fixed at design time, I
don't see the overhead of Maps and Hashtbls being appropriate. Atomic
variants already have unique ids from 0 to n-1, so they seem quite
appropriate for this kind of task.

E.

Jon Harrop

unread,
Jan 14, 2007, 1:28:49 PM1/14/07
to caml...@yquem.inria.fr
On Sunday 14 January 2007 17:33, Edgar Friendly wrote:
> I think this is the uncommon case, and deserves the parentheses:
> x <- (if y then a else b) ;

Not in a functional language, like OCaml, where you're composing expressions
into programs. If you want to make a fair comparison you should at least
start by quantifying how common each is, and whether or not your proposed
change has knock on effects (e.g. cyclic precedences).

> I think I'm arguing that the precedence of if/then/else is too high, and
> maybe should be lowered. Of course this isn't a reasonable thing to
> ask, because it'll likely break existing code. Anyone with a way to
> have my cake and eat it too?

Use camlp4 to create some more revised syntaxes.

> > > If you're bored with
> > > begin/end a good solution might be to define a new construct using
> > > camlp4 instead of hacking the compiler. It's the good advice in
> > > general for syntax problems.
>
> Writing things in camlp4 could help me, but won't improve the world of
> ocaml.

It will if you do something more productive with camlp4, like try...finally
or ...

> I want to compare the situation to TeX / LaTeX -- since you can
> customize it so much, people fix what they don't like on their local
> copy, but these improvements never make it upstream to improve the
> situation for the world.
>
> I will agree that I am too eager to "fix" the compiler, and appreciate
> the community's help in tempering my inexperience. But I'd like to help
> ocaml become a better language, and this seems like a reasonable small
> step to start on.

I wouldn't call changing the precedence of "if" a small step...

On a related note, current precedences dictate that this:

string1^string2 :: list

is parsed as:

string1^(string2 :: list)

which is useless.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

Jon Harrop

unread,
Jan 14, 2007, 1:36:23 PM1/14/07
to caml...@yquem.inria.fr
On Sunday 14 January 2007 18:21, Edgar Friendly wrote:
> Yes to the first sentence, I think no on the second. Map and Hashtbl
> are very good, but I think I really want an array. For an ('a, 'b) Map,
> this is for situations where the set of 'a is fixed at design time, I
> don't see the overhead of Maps and Hashtbls being appropriate. Atomic
> variants already have unique ids from 0 to n-1, so they seem quite
> appropriate for this kind of task.

You should at least measure the overhead of using a hash table before trying
to address the overhead...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

Vincent Hanquez

unread,
Jan 14, 2007, 1:46:06 PM1/14/07
to Jon Harrop
On Sun, Jan 14, 2007 at 06:23:32PM +0000, Jon Harrop wrote:
> > > > If you're bored with
> > > > begin/end a good solution might be to define a new construct using
> > > > camlp4 instead of hacking the compiler. It's the good advice in
> > > > general for syntax problems.
> >
> > Writing things in camlp4 could help me, but won't improve the world of
> > ocaml.
>
> It will if you do something more productive with camlp4, like try...finally
> or ...

and create lots of different syntax which make the code unsharable at
the end (each one using different syntaxes).

I think camlp4 is the not the proper way to extends the language, and is
definitevely *NOT* going to improve the world of OCaml.

--
Vincent Hanquez

Vincent Hanquez

unread,
Jan 14, 2007, 1:55:24 PM1/14/07
to Edgar Friendly
On Sun, Jan 14, 2007 at 11:33:26AM -0600, Edgar Friendly wrote:
> I will agree that I am too eager to "fix" the compiler, and appreciate
> the community's help in tempering my inexperience. But I'd like to help
> ocaml become a better language, and this seems like a reasonable small
> step to start on.

Although I disagree with this first step, I think OCaml need a hand in
becoming more mainstream. unfortunately, it seems that INRIA is not really
interested in making this happened, maybe tweaking syntax and extending the
libraries [1].

At the moment, every one seems to have their own standard libraries to extends
the deficiency/problems/lacks of the common one, and also a bunch a
syntax extensions, that are also incompatible/redundant with each other
for most of them.

[1] I would certainly prefer to be dead wrong here, but at the moment
I'm conforted in this idea.

Cheers,
--
Vincent Hanquez

Edgar Friendly

unread,
Jan 14, 2007, 2:05:24 PM1/14/07
to Jon Harrop
Jon Harrop wrote:
> If you want to make a fair comparison you should at least
> start by quantifying how common each is, and whether or not your proposed
> change has knock on effects (e.g. cyclic precedences).
>
is it possible to have cyclic precedences? Don't the precedences have
to be linearly ordered?

>> I think I'm arguing that the precedence of if/then/else is too high, and
>> maybe should be lowered. Of course this isn't a reasonable thing to
>> ask, because it'll likely break existing code. Anyone with a way to
>> have my cake and eat it too?
>
> Use camlp4 to create some more revised syntaxes.
>

I was thinking more along the lines of some parsing trick that would
look for the 'else' without the user having to use a 'let' binding as
the then-expression.

hmm, maybe it'd suffice to change
| if /expr/ then /expr/ [ else /expr/ ]
to
| if /expr-high-priority-semi/ then /expr-high-priority-semi/ [ else
/expr-high-priority-semi/ ]

>> I want to compare the situation to TeX / LaTeX -- since you can
>> customize it so much, people fix what they don't like on their local
>> copy, but these improvements never make it upstream to improve the
>> situation for the world.
>>

Does this make sense? It's like every user having their own forked
system. Without someone collecting, filtering, editing, integrating
improvements, improvements stay scattered and of little use to the
community.

E.

Tom

unread,
Jan 14, 2007, 4:51:48 PM1/14/07
to Edgar Friendly
>
>
>
> I think this is the uncommon case, and deserves the parentheses:
> x <- (if y then a else b) ;


It's not the uncommon case... It's what's the ?: operator for C++ and Java.
I guess it's very common indeed.

I think I'm arguing that the precedence of if/then/else is too high, and
> maybe should be lowered. Of course this isn't a reasonable thing to
> ask, because it'll likely break existing code. Anyone with a way to
> have my cake and eat it too?
>
>

Look at nemerle [1], I believe they have the if/then/else construct with the
else clause mandatory, and for cases where in OCaml it is ommited, they
would use the when keyword. This solves your problem:

if y=1 then
print_int y;
print_int 2;
else
print_string "not one"

is same as

if y=1 then
( print_int y;
print_int 2; )
else
print_string "not one"

but

when y=1 then
print_int y;
print_int 2;

would be (in OCaml)

(if y=1 then print_int y); print_int 2

Jon Harrop

unread,
Jan 14, 2007, 6:24:27 PM1/14/07
to caml...@yquem.inria.fr
On Sunday 14 January 2007 18:41, you wrote:
> On Sun, Jan 14, 2007 at 06:23:32PM +0000, Jon Harrop wrote:
> > It will if you do something more productive with camlp4, like
> > try...finally or ...
>
> and create lots of different syntax which make the code unsharable at
> the end (each one using different syntaxes).

Does it make code unsharable or can you apply multiple camlp4 macros to one
piece of code?

> I think camlp4 is the not the proper way to extends the language, and is
> definitevely *NOT* going to improve the world of OCaml.

Camlp4 may be the best we have. I can't wait to see the next generation...

Playing with Haskell and F# has opened my eyes a bit. F#'s operator
overloading and active patterns will make my code much nicer. Being lazier
can simplify things until you have to optimise, in which case it suddenly
becomes really complicated and error prone.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

Jon Harrop

unread,
Jan 14, 2007, 6:24:35 PM1/14/07
to caml...@yquem.inria.fr
On Sunday 14 January 2007 18:51, Vincent Hanquez wrote:
> At the moment, every one seems to have their own standard libraries to
> extends the deficiency/problems/lacks of the common one, and also a bunch a
> syntax extensions, that are also incompatible/redundant with each other for
> most of them.

I've been considering commercialising the replacement OCaml stdlib that I
developed. Are you still using it? Would anyone else be interested?

Lots can be done to improve upon the reliability and performance of OCaml's
stdlib...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

Gabriel Kerneis

unread,
Jan 14, 2007, 6:42:00 PM1/14/07
to caml...@yquem.inria.fr
Le Sun, 14 Jan 2007 20:49:57 +0000, Jon Harrop <j...@ffconsultancy.com>
a écrit :

> Playing with Haskell and F# has opened my eyes a bit. F#'s operator
> overloading and active patterns will make my code much nicer. Being
> lazier can simplify things until you have to optimise, in which case
> it suddenly becomes really complicated and error prone.

What do you mean exactly in this last sentence ? I agree OCaml should
evolve but what kind of "laziness" are you referring to ?

Sincerely,
--
Gabriel Kerneis

signature.asc

Vincent Hanquez

unread,
Jan 14, 2007, 7:09:50 PM1/14/07
to Jon Harrop
On Sun, Jan 14, 2007 at 08:49:57PM +0000, Jon Harrop wrote:
> Does it make code unsharable or can you apply multiple camlp4 macros to one
> piece of code?

What I meant, is when you need to read code that used camlp4 you need to
learn almost a new language. It obviously depends of the changes, but
it's not pure OCaml.

I can trivially find a lots of different incompatible syntax doing a 5s
search, that's the problem.

The common syntax "extensions" should come with OCaml so that everyone
that use OCaml use the same language. I'm not saying camlp4 has no use,
but it should be limited to very specific use.

--
Vincent Hanquez

Vincent Hanquez

unread,
Jan 14, 2007, 7:23:31 PM1/14/07
to Jon Harrop
On Sun, Jan 14, 2007 at 08:49:56PM +0000, Jon Harrop wrote:
> I've been considering commercialising the replacement OCaml stdlib that I
> developed.

That won't help to make OCaml a mainstream language.
The ones which are going to buy this, if there's anyone, will have a
different code than the one that are not going to buy it. it just
balkenized a bit more the situation.

It's not really complex to have a replacement stdlib anyway, everybody
can do it, and a lots of people have already put some freely-available
on the internet.

> Are you still using it?

It has been heavily stripped.

--
Vincent Hanquez

Jon Harrop

unread,
Jan 14, 2007, 8:01:49 PM1/14/07
to caml...@yquem.inria.fr

Lazy (as opposed to eager) computation. OCaml is very eager. Using laziness
more can speed things up in some simple cases, e.g. nested maps and folds.

skaller

unread,
Jan 15, 2007, 1:00:22 AM1/15/07
to Jon Harrop
On Sun, 2007-01-14 at 20:49 +0000, Jon Harrop wrote:

> > I think camlp4 is the not the proper way to extends the language, and is
> > definitevely *NOT* going to improve the world of OCaml.
>
> Camlp4 may be the best we have. I can't wait to see the next generation...
>
> Playing with Haskell and F# has opened my eyes a bit. F#'s operator
> overloading and active patterns will make my code much nicer.

Felix has 'user defined syntax' which includes infix operators,
outfix operators (brackets), and arbitrary statements. Arbitrary
extensions to expressions aren't supported yet.

However the system isn't really as good as Camlp4: if user
grammar productions are overloaded, then because the system
uses recursive descent parsing error handling is weak
(an unoverloaded production is handled as a special case,
so left factoring is recommended). Caml p4 allows almost arbitrary
intervention in the grammar, and the action rules are arbitrary
Ocaml -- felix only allows syntax macros (which are Turing complete
but macros just don't cut it compared to explicit code generation
for complex cases).

Of course, Felix has function overloading (which subsumes
operator overloading).

I'm curious what active patterns are. Is that using RTTI to
decode expressions at run time? Like a strong form of
C++ 'dynamic cast'? (or, an extension of variant decoding,
which after all is also using a variant tag for run time
decoding).

BTW: the *major* problem with all code generators is error handling.
It's very easy to add 'sugar' to a language in the form of rewrite
rules .. it is much harder to handle errors, because they might
occur either in the desugaring OR in subsequent processing
(eg type checking). Since the subsequent processing uses the
desugared form of the code, it is hard to refer properly
to the location of the error.

Mind you .. HM type inference has this problem too.


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

skaller

unread,
Jan 15, 2007, 1:02:45 AM1/15/07
to Vincent Hanquez
On Mon, 2007-01-15 at 01:05 +0100, Vincent Hanquez wrote:

> The common syntax "extensions" should come with OCaml so that everyone
> that use OCaml use the same language. I'm not saying camlp4 has no use,
> but it should be limited to very specific use.

Conditional compilation is one of those uses I think.
There is little need for it in Ocaml, compared to C, but it
is still occasionally useful.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Jan 15, 2007, 1:15:39 AM1/15/07
to Jon Harrop
On Mon, 2007-01-15 at 00:55 +0000, Jon Harrop wrote:
> On Sunday 14 January 2007 23:38, Gabriel Kerneis wrote:
> > Le Sun, 14 Jan 2007 20:49:57 +0000, Jon Harrop <j...@ffconsultancy.com>
> > a écrit :
> > > Playing with Haskell and F# has opened my eyes a bit. F#'s operator
> > > overloading and active patterns will make my code much nicer. Being
> > > lazier can simplify things until you have to optimise, in which case
> > > it suddenly becomes really complicated and error prone.
> >
> > What do you mean exactly in this last sentence ? I agree OCaml should
> > evolve but what kind of "laziness" are you referring to ?
>
> Lazy (as opposed to eager) computation. OCaml is very eager. Using laziness
> more can speed things up in some simple cases, e.g. nested maps and folds.

This is not clear. Laziness can be very fast if well optimised,
but optimisation is hard in general. The trivial case of nested maps
and folds can be optimised by hand in Ocaml.

It also isn't really true Ocaml is 'eager' in 'general'.
Almost all constructions in all languages are in fact lazy:
indeed procedural/imperative programming is ultimately lazy.
A simple example: Ocaml match is lazy:

match x with | true -> t | false -> f

evaluates t or f lazily .. in general this is obviously
necessary since any pattern variables (not exhibited in
this case) are not known until the match is done.

At best you can say function application in Ocaml is eager,
and even that isn't true: wherever you use a reference,
you're passing a pointer, and that's lazy evaluation,
until you 'eagerify' it by dereferencing the pointer.

Similarly when you pass a mutable data structure as an argument,
evaluation is actually lazy .. operations on it are done
*inside* the function body.

So actually, in an imperative language like Ocaml, there is no
real need for lazy evaluation of function arguments .. there
is already plenty of control over evaluation time. The main
downside is that the programmer needs to exert this control
manually .. and that is also the main upside, compared to
say Haskell, where you really don't know how good a job
the optimiser is doing precisely because of the lazy semantics.


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Nicolas Pouillard

unread,
Jan 15, 2007, 4:42:15 AM1/15/07
to Vincent Hanquez
On 1/14/07, Vincent Hanquez <t...@snarc.org> wrote:
> On Sun, Jan 14, 2007 at 06:23:32PM +0000, Jon Harrop wrote:
> > > > > If you're bored with
> > > > > begin/end a good solution might be to define a new construct using
> > > > > camlp4 instead of hacking the compiler. It's the good advice in
> > > > > general for syntax problems.
> > >
> > > Writing things in camlp4 could help me, but won't improve the world of
> > > ocaml.
> >
> > It will if you do something more productive with camlp4, like try...finally
> > or ...
>
> and create lots of different syntax which make the code unsharable at
> the end (each one using different syntaxes).
>
> I think camlp4 is the not the proper way to extends the language, and is
> definitevely *NOT* going to improve the world of OCaml.
>

Although remind you that a property of camlp4 syntaxes is that you can
trivially convert an input source in plain (indented) OCaml code. This
is done using the Pr_o module, an OCaml pretty printer.

Thus, you can share it.

$ camlp4 some_strange_syntax.cmo pr_o.cmo foo.ml -o foo_ocaml.ml

--
Nicolas Pouillard

Richard Jones

unread,
Jan 15, 2007, 5:39:52 AM1/15/07
to Edgar Friendly
On Fri, Jan 12, 2007 at 11:37:21PM -0600, Edgar Friendly wrote:
> if y=1 then
> let z = 2 in
> print_int y;
> print_int z;
> else
> print_string "not one"

Hmmm .. changing the precedence of operators to avoid two parentheses ...
I don't think that's good.

if y=1 then (


let z = 2 in
print_int y;
print_int z;

) else
print_string "not one"

I will however add my own pet wish: a 'return' statement! It doesn't
have to break type safety -- you should only be allowed to 'return' a
type compatible with the ordinary return type of the function. The
alternative (using exceptions to jump out of code) is ugly, slow and
unsafe.

Rich.

--
Richard Jones
Red Hat UK Limited

Vincent Hanquez

unread,
Jan 15, 2007, 11:35:14 AM1/15/07
to Richard Jones
On Mon, Jan 15, 2007 at 10:36:02AM +0000, Richard Jones wrote:
> Hmmm .. changing the precedence of operators to avoid two parentheses ...
> I don't think that's good.
>
> if y=1 then (
> let z = 2 in
> print_int y;
> print_int z;
> ) else
> print_string "not one"
>
> I will however add my own pet wish: a 'return' statement! It doesn't
> have to break type safety -- you should only be allowed to 'return' a
> type compatible with the ordinary return type of the function. The
> alternative (using exceptions to jump out of code) is ugly, slow and
> unsafe.

I agree, I cannot think of a bad way to use it, and it would be more
useful than having one more nested if then else or an exception mechanism.

(the only problem I'm seeing if that people will use this return
statement at the end of function)

Xavier, if somebody does a patch to do that or some other useful feature,
would that be considered for entering CAML's CVS ?
(i.e. what are the rules for accepting a patch ?)

Cheers,
--
Vincent Hanquez

Martin Jambon

unread,
Jan 15, 2007, 1:33:02 PM1/15/07
to Nicolas Pouillard
On Mon, 15 Jan 2007, Nicolas Pouillard wrote:

> On 1/14/07, Vincent Hanquez <t...@snarc.org> wrote:
> > and create lots of different syntax which make the code unsharable at
> > the end (each one using different syntaxes).
> >
> > I think camlp4 is the not the proper way to extends the language, and is
> > definitevely *NOT* going to improve the world of OCaml.
> >
>
> Although remind you that a property of camlp4 syntaxes is that you can
> trivially convert an input source in plain (indented) OCaml code. This
> is done using the Pr_o module, an OCaml pretty printer.
>
> Thus, you can share it.
>
> $ camlp4 some_strange_syntax.cmo pr_o.cmo foo.ml -o foo_ocaml.ml

Getting standard OCaml code doesn't guarantee that you can do something
with it: in the case of syntax extensions, the result will be most likely
unreadable. But the real problem is that there is no way of reverting
back to the original source code. So if you write your programs in the
revised syntax, all patches must be written in the revised syntax.

Martin

--
Martin Jambon
http://martin.jambon.free.fr

ls-ocaml-de...@m-e-leypold.de

unread,
Jan 15, 2007, 2:03:03 PM1/15/07
to caml...@yquem.inria.fr

Martin Jambon <martin...@ens-lyon.org> writes:

> On Mon, 15 Jan 2007, Nicolas Pouillard wrote:
>
>> On 1/14/07, Vincent Hanquez <t...@snarc.org> wrote:
>> > and create lots of different syntax which make the code unsharable at
>> > the end (each one using different syntaxes).
>> >
>> > I think camlp4 is the not the proper way to extends the language, and is
>> > definitevely *NOT* going to improve the world of OCaml.
>> >
>>
>> Although remind you that a property of camlp4 syntaxes is that you can
>> trivially convert an input source in plain (indented) OCaml code. This
>> is done using the Pr_o module, an OCaml pretty printer.
>>
>> Thus, you can share it.
>>
>> $ camlp4 some_strange_syntax.cmo pr_o.cmo foo.ml -o foo_ocaml.ml
>
> Getting standard OCaml code doesn't guarantee that you can do something
> with it: in the case of syntax extensions, the result will be most likely
> unreadable. But the real problem is that there is no way of reverting
> back to the original source code. So if you write your programs in the
> revised syntax, all patches must be written in the revised syntax.

Yes.

And the worst thing is, that your "original" source will only be
usable as long as the syntax extension is being maintained by
someone. You might even have to take over maintenance yourself at the
end. That might be a big cost for a bit of syntactic sugar in the long
run.

Regards -- Markus

Martin Jambon

unread,
Jan 15, 2007, 3:28:25 PM1/15/07
to Vincent Hanquez
On Mon, 15 Jan 2007, Vincent Hanquez wrote:

> On Sun, Jan 14, 2007 at 08:49:57PM +0000, Jon Harrop wrote:
> > Does it make code unsharable or can you apply multiple camlp4 macros to one
> > piece of code?
>
> What I meant, is when you need to read code that used camlp4 you need to
> learn almost a new language. It obviously depends of the changes, but
> it's not pure OCaml.
>
> I can trivially find a lots of different incompatible syntax doing a 5s
> search, that's the problem.
>
> The common syntax "extensions" should come with OCaml so that everyone
> that use OCaml use the same language. I'm not saying camlp4 has no use,
> but it should be limited to very specific use.

OCaml is well-enough designed so that there is no "common" syntax
extension. The problem is that people use it for a variety of things, and
each domain may benefit from particular enhancements of the syntax.
Either you incorporate all those extensions into the standard syntax,
which is totally insane, or you consider them just as libraries. Loading
a library is no big deal, whether it provides more functions or more
syntax.

IMHO the problem is more that writing camlp4 syntax extensions is very
different from writing everyday OCaml code. In other words,
it is inaccessible to beginners, and most other people think it's too
complicated anyway. It requires too much expertise and only few people are
able to maintain such code.

Here is a list of things that I suggest if one ever wants to have a
standard and widely use way of extending the syntax in OCaml:

* implement a 2-stage (2, not n) compilation so that syntax extensions can
be defined in standard OCaml modules.

* each "macro" has a name and is provided as a module item.

* there should a standard syntax for macro expansions, so that external
readers know that a special syntax is being used. E.g.
<:Mymodule.mymacro< blabla >>
where blabla is parsed using the standard OCaml lexer, and the custom
"mymacro" parser provided by module "Mymodule" (as opposed to current
quotations where the content is parsed with any lexer).

* defining a syntax extension should be done with some code which looks as
much as possible like standard Ocaml.


Here is an example. There are three new keywords "macro", "quote" and
"pragma", plus some special syntax for writing the parser.
"macro" is used to introduce the definition of a syntax extension.
"quote" is used to represent the OCaml syntax tree and is available only
in macro definitions. It would be a standard replacement for
<:expr< ... >>, <:patt< ... >>, etc. Its type (expr, patt, str_item, ...)
should be figured out automatically.
"pragma" would introduce normal OCaml code which must be compiled during
the first stage of the compilation (not shown in the example).

macro cond stream =
let subst e1 e2 e3 = (* could be defined externally using "pragma" *)
match e1 with
quote true -> e2
| quote false -> e3
| _ -> quote (if $e1 then $e2 else $e3) in

parse stream with (* equivalent of an EXTEND statement with a single,
new entry *)
[ [ e1 = Ocaml.expr; e2 = Ocaml.expr; e3 = Ocaml.expr -> subst e1 e2 e3
| e1 = Ocaml.expr; e2 = Ocaml.expr -> subst e1 e2 (quote ()) ] ]


(* same program, continuing *)

let test_cond x y z =
<:cond< (x + y = z) (z + 1) 0 >>

(* is equivalent to:

let test_cond x y z =
if (x + y = z) then (z + 1) else 0

*)


OK, there are many issues to solve, and it may not look as simple as
advertised, but I am sure it can be done.


Martin

_______________________________________________

Jon Harrop

unread,
Jan 15, 2007, 4:37:00 PM1/15/07
to caml...@yquem.inria.fr
On Monday 15 January 2007 20:23, Martin Jambon wrote:
> OCaml is well-enough designed so that there is no "common" syntax
> extension.

The camlp4-based syntax extension for lazy stream parsing could be considered
a "common" extension because it is bundled with OCaml and is used by lots of
people.

I used it in several of the tutorial papers on our site simply because it is
the most succinct approach to parsing:

http://www.ffconsultancy.com/free/ocaml/parsing.html
http://www.ffconsultancy.com/free/ocaml/interpreter.html

It may be superceded by active patterns but I'd still like to see this syntax
incorporated into OCaml itself.

> The problem is that people use it for a variety of things, and
> each domain may benefit from particular enhancements of the syntax.

try ... finally is another syntax extension that I think would be welcomed by
all.

> Either you incorporate all those extensions into the standard syntax,
> which is totally insane, or you consider them just as libraries.

I think there are several camlp4 syntax extensions that are sufficiently
useful that we would all benefit from them being incorporated into the
language.

> IMHO the problem is more that writing camlp4 syntax extensions is very
> different from writing everyday OCaml code. In other words,
> it is inaccessible to beginners,

I highly recommend this web page by some guy called Martin Jambon: ;-)

http://martin.jambon.free.fr/extend-ocaml-syntax.html

Your page is really the only resource on the web that aims to elucidate
camlp4. It is very good, but I still failed to write the syntax extension
that I wanted (symbolic expressions as patterns).

> OK, there are many issues to solve, and it may not look as simple as
> advertised, but I am sure it can be done.

All good ideas.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

Daniel Bünzli

unread,
Jan 15, 2007, 5:16:42 PM1/15/07
to caml...@yquem.inria.fr

Le 15 janv. 07 à 22:30, Jon Harrop a écrit :

> try ... finally is another syntax extension that I think would be
> welcomed by
> all.

A less invasive alternative would be to add something like this to
pervasives (taken from Leroy and Rémy's unix course [1]) :

let apply f x ~finally y =
let res = try f x with exn -> finally y; raise exn in
finally y;
res

The only quirk is that when you need to introduce a local or
anonymous function for the blocks, but I don't really care about that.

However I'm tired of copying this function over and over in my io
intensive sources.

Best,

Daniel

[1] <http://pauillac.inria.fr/~remy/poly/system/camlunix/index.html>

Vincent Hanquez

unread,
Jan 15, 2007, 5:22:09 PM1/15/07
to Martin Jambon
On Mon, Jan 15, 2007 at 12:23:32PM -0800, Martin Jambon wrote:
> OCaml is well-enough designed so that there is no "common" syntax
> extension.

There ARE common syntax extensions.
how many people miss a try-except-finally construct ?
how many people miss a return statement to break the flow of a function.
etc ..

I'm not talking about weird extensions that ease the life of grammar
writter or lambda calculus , etc .. but really the basic one.

I still think camlp4 is a good idea for limited use like this.

> The problem is that people use it for a variety of things, and
> each domain may benefit from particular enhancements of the syntax.
> Either you incorporate all those extensions into the standard syntax,
> which is totally insane, or you consider them just as libraries. Loading
> a library is no big deal, whether it provides more functions or more
> syntax.

I'm especially not talking about all extensions, but obviously the ones
that everybody can use, whatever they works on.

> IMHO the problem is more that writing camlp4 syntax extensions is very
> different from writing everyday OCaml code. In other words,
> it is inaccessible to beginners, and most other people think it's too
> complicated anyway. It requires too much expertise and only few people are
> able to maintain such code.

What about the beginners then ?
All what you suggest below doesn't really help making it more accessible
I think.

> Here is a list of things that I suggest if one ever wants to have a
> standard and widely use way of extending the syntax in OCaml:

> [snip]

I like this special "macro" keyword and this should also be part of the
language. So does some specific construction like try-finally.

--
Vincent Hanquez

Vincent Hanquez

unread,
Jan 15, 2007, 5:33:11 PM1/15/07
to Daniel Bünzli
On Mon, Jan 15, 2007 at 11:13:58PM +0100, Daniel Bünzli wrote:
> A less invasive alternative would be to add something like this to
> pervasives (taken from Leroy and Rémy's unix course [1]) :
>
> let apply f x ~finally y =
> let res = try f x with exn -> finally y; raise exn in
> finally y;
> res
>
> The only quirk is that when you need to introduce a local or
> anonymous function for the blocks, but I don't really care about that.
>
> However I'm tired of copying this function over and over in my io
> intensive sources.

This is exactly my point.

I have this kind of trivial function spread over and over again.
and lots of people have this function as well, maybe a bit different,
slightly imcompatible with each other.

Coding with OCaml would be some much easier if all those trivia would
come directly with the STANDARD distribution. and it would be much more
consistant across 2 differents developers as well.

Cheers,
--
Vincent Hanquez

Quôc Peyrot

unread,
Jan 15, 2007, 5:46:45 PM1/15/07
to caml...@yquem.inria.fr

On Jan 15, 2007, at 2:27 PM, Vincent Hanquez wrote:

> On Mon, Jan 15, 2007 at 11:13:58PM +0100, Daniel Bünzli wrote:
>> A less invasive alternative would be to add something like this to
>> pervasives (taken from Leroy and Rémy's unix course [1]) :
>>
>> let apply f x ~finally y =
>> let res = try f x with exn -> finally y; raise exn in
>> finally y;
>> res
>>
>> The only quirk is that when you need to introduce a local or
>> anonymous function for the blocks, but I don't really care about
>> that.
>>
>> However I'm tired of copying this function over and over in my io
>> intensive sources.
>
> This is exactly my point.
>
> I have this kind of trivial function spread over and over again.
> and lots of people have this function as well, maybe a bit different,
> slightly imcompatible with each other.
>
> Coding with OCaml would be some much easier if all those trivia would
> come directly with the STANDARD distribution. and it would be much
> more
> consistant across 2 differents developers as well.

I don't know for the other trivial functions, but this apply function
looks like
Std.finally from extlib.

I hardly miss any trivial functions when using extlib, mileage might
vary.

--
Best Regards,
Quôc

Vincent Hanquez

unread,
Jan 15, 2007, 6:13:37 PM1/15/07
to Quôc Peyrot
On Mon, Jan 15, 2007 at 02:40:13PM -0800, Quôc Peyrot wrote:
> I don't know for the other trivial functions, but this apply function
> looks like
> Std.finally from extlib.
>
> I hardly miss any trivial functions when using extlib, mileage might
> vary.

extlib is not the only standard extension library that exists.
I can easily count 3 of them widely available on internet.

and, agreed that's a good start (if that's would be directly available
in pervasives), it's not as good has having a:

try
...
finally
...

directly in the language.

Cheers,
--
Vincent Hanquez

skaller

unread,
Jan 15, 2007, 8:24:51 PM1/15/07
to Vincent Hanquez
On Mon, 2007-01-15 at 23:17 +0100, Vincent Hanquez wrote:
> On Mon, Jan 15, 2007 at 12:23:32PM -0800, Martin Jambon wrote:
> > OCaml is well-enough designed so that there is no "common" syntax
> > extension.
>
> There ARE common syntax extensions.
> how many people miss a try-except-finally construct ?
> how many people miss a return statement to break the flow of a function.
> etc ..

I don't miss any of those things .. the point being they're
not so 'common' as you might think.

I'm a Python programmer too, and I never use 'finally' ..
I've never found any use for it.

Felix has return statement .. but then Felix has *statements*:
executable Ocaml is all expressions, so a return statement would
seem out of place.

> I'm not talking about weird extensions that ease the life of grammar
> writter or lambda calculus , etc .. but really the basic one.

One man's nice extensions are weird to another. Many parts of
Ocaml are weird (IMHO :) but at least its a shared weirdness.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Jon Harrop

unread,
Jan 15, 2007, 9:16:41 PM1/15/07
to caml...@yquem.inria.fr
On Tuesday 16 January 2007 01:18, skaller wrote:
> On Mon, 2007-01-15 at 23:17 +0100, Vincent Hanquez wrote:
> > On Mon, Jan 15, 2007 at 12:23:32PM -0800, Martin Jambon wrote:
> > > OCaml is well-enough designed so that there is no "common" syntax
> > > extension.
> >
> > There ARE common syntax extensions.
> > how many people miss a try-except-finally construct ?
> > how many people miss a return statement to break the flow of a function.
> > etc ..
>
> I don't miss any of those things .. the point being they're
> not so 'common' as you might think.

try ... finally is useful when closing file handles.

However, simply trying to read a file as a list of strings is a sticking point
for many newbies because the obvious functional implementations aren't
robust:

let rec read ch = try input_line ch :: read ch with End_of_file -> []

Elegant but not tail recursive. Conventional transformation into tail
recursive form using an accumulator:

let rec read ?(t=[]) ch =
try read ~t:(input_line ch::t) ch with End_of_file -> t

Still not tail recursive because tail calls inside a try block are not
optimised, so it still segfaults when the file has >100,000 lines on a 64-bit
machine.

Solution is to box and unbox, moving the tail-recursive call outside the try
block:

let rec read ?(t=[]) ch =
match try Some(input_line ch) with End_of_file -> None with
| Some h -> read ~t:(h::t)
| None -> t

Inelegant.

We really want a File.fold function to fold over the lines of the file, and a
cons function:

File.fold cons ch []

I have a much bigger wish list for functions than I do for syntax. I'd like
the stdlib functions to be tail recursive, more comprehensive and faster...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

Edgar Friendly

unread,
Jan 16, 2007, 12:22:55 AM1/16/07
to Jon Harrop
Jon Harrop wrote:
> We really want a File.fold function to fold over the lines of the file, and a
> cons function:
>
> File.fold cons ch []
>
While we're at it, why not parameterize the splitting mechanism: one
fold for token-based folding (each \n or other separator), and a second
fold for record-based folding (every n bytes).

> I have a much bigger wish list for functions than I do for syntax. I'd like
> the stdlib functions to be tail recursive, more comprehensive and faster...
>

Should we start another thread to put improved/needed stdlib functions?
I imagine some discussion (and postings of code) related to this matter
could be productive.

E.

ketty

unread,
Jan 16, 2007, 12:37:33 AM1/16/07
to Edgar Friendly
On 1/16/07, Edgar Friendly <thele...@gmail.com> wrote:
> No, I want to make the following code legal:
>
> if y = 1 then

> print_int y;
> print_int z;
> else
> print_string "not one"
>

correct me if i am wrong,

you want this to work like it currently does:
if cond then bla;
bla_outside_if;

and this to work like you describe it:
if cond then bla;
bla_inside_if;
else
inside_else;
what_about_this; (* ? *)

appart from the what_about_this expression, consider this:
if cond then
bla;
bla; if cond2 then bla;
bla;
bla;
else ... (* which if do this belong to? *)

allthough it is straitforward to say that else always belongs to the
"if" it is closest to, it does add a whole new elemnt of confusion.

Christophe TROESTLER

unread,
Jan 16, 2007, 12:59:18 AM1/16/07
to caml...@yquem.inria.fr
On Mon, 15 Jan 2007, Edgar Friendly <thele...@gmail.com> wrote:

>
> Richard Jones wrote:
> > On Fri, Jan 12, 2007 at 11:37:21PM -0600, Edgar Friendly wrote:
> >> if y=1 then
> >> let z = 2 in
> >> print_int y;
> >> print_int z;
> >> else
> >> print_string "not one"
> >
> > Hmmm .. changing the precedence of operators to avoid two parentheses ...
> > I don't think that's good.
>
> No, I want to make the following code legal:
>
> if y = 1 then
> print_int y;
> print_int z;
> else
> print_string "not one"
>
> It's just an unnecessary stumbling block for programmers coming from
> other languages.

Just pretend parentheses are compulsory :). (What would happen in C
if we left the braces out anyway! Go and change C instead, this will
affect far more people!)

BTW, learning a language by saying you want to change it (before you
even did any interesting programming in it) is not IMHO the most
beneficial attitude. It is really kind of you to want to help us to
"improve the world of ocaml" but shouldn't you learn the language
inside out and write two or three projects in it first ?

My 2^(-10)€ (with or without parentheses),
C.

ketty

unread,
Jan 16, 2007, 1:14:03 AM1/16/07
to Edgar Friendly
On 1/16/07, Edgar Friendly <thele...@gmail.com> wrote:
> I don't know if this is reasonable, but what about having an
> if/then[/else] as now (no semis inside), but also having an
> if/then[/else]/end that allows semi-delimited expressions inside? This
> would be light-weight (and non-intrusive), but still allow imperative
> programmers their nice compound expressions inside if control paths.
>

I would suggest using some other name than 'end' (maybe 'endif'?)
since end is allready used to terminate a lot of other structures, if
'end' might or might not follow an if it would mess those other
structures up big time :)

skaller

unread,
Jan 16, 2007, 1:37:23 AM1/16/07
to Jon Harrop
On Tue, 2007-01-16 at 02:11 +0000, Jon Harrop wrote:

> try ... finally is useful when closing file handles.

[]

> Solution is to box and unbox, moving the tail-recursive call outside the try
> block:
>
> let rec read ?(t=[]) ch =
> match try Some(input_line ch) with End_of_file -> None with
> | Some h -> read ~t:(h::t)
> | None -> t
>
> Inelegant.

But what I do all the time to eliminate exceptions, which in general
I dislike. In my context

let entry = try Some (Hasthtbl.find tbl key) with Not_found -> None in
match entry with
| Some v ->
| None ->

No issue of recursion here. Of course, it is easy to just define
the first line as a function, encapsulating the inelegance at
the expense of readers needing to know what an undocumented
function does.

But is it the job of a language to provide syntax for everything?

Usually languages provide syntax which spans the primitives
and a bit more covering really common idioms .. and leaves
the rest to the library.

A too rich syntax is harder to learn IMHO, for example
Ocaml classes are hard to learn. I've been writing Ocaml
for a while and still have no idea what the difference
between a method interface in a class type and a virtual
method is.


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Jan 16, 2007, 1:41:03 AM1/16/07
to Edgar Friendly
On Mon, 2007-01-15 at 23:18 -0600, Edgar Friendly wrote:
> Jon Harrop wrote:

> Should we start another thread to put improved/needed stdlib functions?
> I imagine some discussion (and postings of code) related to this matter
> could be productive.

It would be more productive, IMHO, to join with a developer
team such as that of extlib and contribute to an existing
library, wouldn't it?

Alternatively, you can put a feature request in the
official Ocaml bugtracker.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Jan 16, 2007, 1:55:37 AM1/16/07
to Edgar Friendly
On Mon, 2007-01-15 at 23:21 -0600, Edgar Friendly wrote:
> Richard Jones wrote:

> No, I want to make the following code legal:
>
> if y = 1 then

> print_int y;
> print_int z;
> else
> print_string "not one"
>
>

> It's just an unnecessary stumbling block for programmers coming from
> other languages.

So is your syntax:

if cond1 then e1
elif cond2 then e2
..
else el
endif

is THE correct, unambiguous, formulation, and what Felix uses <g>.
For procedural code:

if cond do ..
elif ..
..
else ..
done


These forms were decided by Wirth after the Pascal ambiguities,
and his next attempt, Modula, uses them.

Felix also uses

match .. with .. endmatch

but strangely has an open

let .. in ...

whereas Standard ML uses

let .. in .. end

Ocaml uses a closed form here:

for .. do .. done


Felix, like C++, also has ; as a statement terminator
not a separator. Research was done on this (no I can't
cite it). Terminators are known to be better :)

Closed forms are precedence free, allow an unambiguous
grammar, and support easy cut and paste: all in all,
these syntaxen obey an important rule: the substitution
principle.

However, they lead to excess terminators, and so most languages
close some forms and leave others open. IMHO Ocaml leaves
too many open, but this is just a minor taste issue: what
really interested me is the semantics.

BTW: Python solves the excess terminator problem by using indentation,
which is generally quite nice, IMHO, though it makes code containing
long quoted strings very ugly.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Florian Hars

unread,
Jan 16, 2007, 3:06:28 AM1/16/07
to Richard Jones
Richard Jones wrote:
> The alternative (using exceptions to jump out of code) is ugly, slow and
> unsafe.

Of course, the correct® ugly alternative is to manually CPS-transform your code.
If functions don't return, you don't need no steenkin' return statements :-).

Yours, Florian.

Hendrik Tews

unread,
Jan 16, 2007, 3:51:05 AM1/16/07
to caml...@yquem.inria.fr
t...@snarc.org (Vincent Hanquez) writes:

Xavier, if somebody does a patch to do that or some other useful feature,
would that be considered for entering CAML's CVS ?
(i.e. what are the rules for accepting a patch ?)

Last time this question came up the answer was submit the patch
as feature wish to the bug tracking system and pray. See

http://caml.inria.fr/pub/ml-archives/caml-list/2001/10/4bad397017270c62b70852840f37ad61.en.html

But perhaps the position of the Ocaml team has changed?

Bye,

Hendrik

Vincent Hanquez

unread,
Jan 16, 2007, 4:05:00 AM1/16/07
to skaller
On Tue, Jan 16, 2007 at 12:18:11PM +1100, skaller wrote:
> I don't miss any of those things .. the point being they're
> not so 'common' as you might think.

It's totally common to to do some action despite that an exception has
been raised or not to cleanup stuff (like file descriptor is the obvious
example).

At the moment in OCaml you need to multiple layer or try/with to be able
to express this. it would be much nicer to allow this construction as a
proper idiom, not ad-hoc.

> I'm a Python programmer too, and I never use 'finally' ..
> I've never found any use for it.

You probably don't write/read much python code then.

( I found 2 use of finally in felix's python code )

> Felix has return statement .. but then Felix has *statements*:
> executable Ocaml is all expressions, so a return statement would
> seem out of place.

OCaml is a functional language, however it also contains imperative feature.

It doesn't seems so inappropriate to have a return statement, as long
it's not abused.

--
Vincent Hanquez

Vincent Hanquez

unread,
Jan 16, 2007, 4:13:26 AM1/16/07
to Hendrik Tews
On Tue, Jan 16, 2007 at 09:45:26AM +0100, Hendrik Tews wrote:
> t...@snarc.org (Vincent Hanquez) writes:
>
> Xavier, if somebody does a patch to do that or some other useful feature,
> would that be considered for entering CAML's CVS ?
> (i.e. what are the rules for accepting a patch ?)
>
> Last time this question came up the answer was submit the patch
> as feature wish to the bug tracking system and pray. See
>
> http://caml.inria.fr/pub/ml-archives/caml-list/2001/10/4bad397017270c62b70852840f37ad61.en.html
>
> But perhaps the position of the Ocaml team has changed?

Well, seeing that the very useful native exception backtrace patch has been
sitting idle (acknowledged) for more than a year, I think that's not
working it out too well :\

Seeing the number of people monitoring the issue, I think lots of people
are waiting it.

I'm not saying the patch is perfect, but at least if somebody in the
ocaml team would say something about it, we could improve it.

http://caml.inria.fr/mantis/view.php?id=3885

--
Vincent Hanquez

Brian Hurt

unread,
Jan 16, 2007, 9:01:27 AM1/16/07
to Jon Harrop
Jon Harrop wrote:

>However, simply trying to read a file as a list of strings is a sticking point
>for many newbies because the obvious functional implementations aren't
>robust:
>
>
>

Exceptions are evil.

Brian

skaller

unread,
Jan 16, 2007, 9:19:18 AM1/16/07
to Vincent Hanquez
On Tue, 2007-01-16 at 10:00 +0100, Vincent Hanquez wrote:
> On Tue, Jan 16, 2007 at 12:18:11PM +1100, skaller wrote:
> > I don't miss any of those things .. the point being they're
> > not so 'common' as you might think.
>
> It's totally common to to do some action despite that an exception has
> been raised or not to cleanup stuff (like file descriptor is the obvious
> example).

No it isn't. First, I don't use exceptions like that: I usually
wrap them. Second, this technique isn't that useful in a language
with garbage collection: this is not C++. A thirdly, in my own
language Felix there ARE no exceptions .. so it can hardly
be 'common'.

The Felix compiler (an Ocaml program) throws exceptions
in three circumstances:

(a) Errors: no cleanup is required.

(b) Library functions: either it is a program error
or I map the exception to a variant: no cleanup is
required.

(c) Exiting a deep recursion: in no case is any
cleanup required.

So actually in a 60Kloc program, no cleanup is done
anywhere for any reason. It just isn't necessary.

> > I'm a Python programmer too, and I never use 'finally' ..
> > I've never found any use for it.
>
> You probably don't write/read much python code then.

Actually I'm a Python ex-guru, I have two major pieces
of software written in it, and I've even *implemented*
a Python interpreter .. in Ocaml :)

> ( I found 2 use of finally in felix's python code )

Probably written by Erick not me :)

> > Felix has return statement .. but then Felix has *statements*:
> > executable Ocaml is all expressions, so a return statement would
> > seem out of place.
>
> OCaml is a functional language, however it also contains imperative feature.
>
> It doesn't seems so inappropriate to have a return statement, as long
> it's not abused.

If I recall, the revised syntax also has a return statement.

I'm simply trying to show that the only way to really substantiate
a claim something is common is to do a real survey of code.

I have not analysed all the Ocaml code out there but it is
my guess most Ocaml programmers would have no real use for
a return expression.

Many may agree exception handling is not so good, but many
would probably favour another proposal for restructuring
exceptions, rather than adding a finally clause.

I forget the URL of the proposal, which is a kind of
let/try construction, perhaps someone can fill that in?

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Vincent Hanquez

unread,
Jan 16, 2007, 10:05:58 AM1/16/07
to skaller
On Wed, Jan 17, 2007 at 01:14:32AM +1100, skaller wrote:
> No it isn't. First, I don't use exceptions like that: I usually
> wrap them. Second, this technique isn't that useful in a language
> with garbage collection: this is not C++. A thirdly, in my own
> language Felix there ARE no exceptions .. so it can hardly
> be 'common'.
>
> The Felix compiler (an Ocaml program) throws exceptions
> in three circumstances:
>
> (a) Errors: no cleanup is required.
>
> (b) Library functions: either it is a program error
> or I map the exception to a variant: no cleanup is
> required.
>
> (c) Exiting a deep recursion: in no case is any
> cleanup required.
>
> So actually in a 60Kloc program, no cleanup is done
> anywhere for any reason. It just isn't necessary.

Does you felix program have threads ? or lots of file descriptor ? or
has to stay up for a long period of time ? or use side effect quite
extensively ?

Absolutely not, it's a compiler that doesn't need much of these stuff.
And even then, you can most of the time just rely on exit(3) to cleanup
since it's a short live service.

What about a server now ? add threads in the mix where all mutex need to
be properly unlocked, add also function with weird side effects that
don't have any representation variable at the OCaml level (thus cannot be
garbage collected), etc...

So please don't generalise your situation which is quite specific
(compiler) to the whole world of OCaml and open your mind to the fact
that people has different need/expectation.

(and that Felix doesn't have exceptions, I couldn't care less. OCaml
does and there are no going away, so live with it.)

> Actually I'm a Python ex-guru, I have two major pieces
> of software written in it, and I've even *implemented*
> a Python interpreter .. in Ocaml :)

Good for you. (interpreter still fall in the compiler category btw)

Cheers,
--
Vincent Hanquez

skaller

unread,
Jan 16, 2007, 12:52:59 PM1/16/07
to Vincent Hanquez
On Tue, 2007-01-16 at 16:00 +0100, Vincent Hanquez wrote:

> Does you felix program have threads ? or lots of file descriptor ? or
> has to stay up for a long period of time ? or use side effect quite
> extensively ?
>
> Absolutely not, it's a compiler that doesn't need much of these stuff.
> And even then, you can most of the time just rely on exit(3) to cleanup
> since it's a short live service.

Correct.

> What about a server now ? add threads in the mix where all mutex need to
> be properly unlocked, add also function with weird side effects that
> don't have any representation variable at the OCaml level (thus cannot be
> garbage collected), etc...

What about it? C manages to handle all that .. and has no exceptions.

> So please don't generalise your situation which is quite specific
> (compiler) to the whole world of OCaml and open your mind to the fact
> that people has different need/expectation.

Try not to make assumptions about what people know.
I've been programming for three decades. My mind isn't
closed .. you just don't seem to get that what YOU think
is common practice may actually not be.

> (and that Felix doesn't have exceptions, I couldn't care less. OCaml
> does and there are no going away, so live with it.)

You missed the point. Neither C nor Felix have exceptions, and Ocaml
can be programmed the same way. There's no need for finally
if you program in an 'exception free' style.

It may be convenient but your claim was that the need was 'common'.
I doubt this.

I DO agree exceptions, as structured now, are not so good.
They're clumsy, hard to use, and dangerous (if not downright evil).

But adding 'finally' may not be the best solution,
the try/let construction looks better to me.

> > Actually I'm a Python ex-guru, I have two major pieces
> > of software written in it, and I've even *implemented*
> > a Python interpreter .. in Ocaml :)
>
> Good for you. (interpreter still fall in the compiler category btw)

The interpreter actually needed finalisation, since it used
Ocaml GC instead of Python reference counting. In fact Ocaml
finalisers were more or less added to Ocaml *because* my
project provided a solid use case.

In fact I have used Ocaml in a telco environment .. using
the nice Event module, with many threads, services,
and clients interacting in (soft) real time. That was some
time ago so I can't say if I would have used 'finally'
in that context or not. But typically I do that kind of
thing the C way, which is generally the Ocaml way too:
you propagate return codes from functions using variants
up call chains.


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Edgar Friendly

unread,
Jan 16, 2007, 1:05:31 PM1/16/07
to skaller
skaller wrote:
> So is your syntax:
>
> if cond1 then e1
> elif cond2 then e2
> ..
> else el
> endif
>
that would do what I want. Now is it possible to keep the open syntax
as well, for the ?: uses of if/then/else?

E.

Edgar Friendly

unread,
Jan 16, 2007, 2:29:38 PM1/16/07
to skaller
skaller wrote:
> What about it? C manages to handle all that .. and has no exceptions.
>
I think the point here is that because OCaml has exceptions (that other
people use, maybe not you), it should also have finally blocks to allow
them to easily do what you do without exceptions.

> But adding 'finally' may not be the best solution,
> the try/let construction looks better to me.
>

I can't find an example of this. Something about doing variable binding
as part of the try statement, and then finalizing how?

> But typically I do that kind of
> thing the C way, which is generally the Ocaml way too:
> you propagate return codes from functions using variants
> up call chains.
>

The OCaml standard library seems to be programmed using exceptions over
variants. I'll have to say I don't like or use exceptions much, but I'm
forced to by the standard libraries.


E.

Jon Harrop

unread,
Jan 16, 2007, 2:49:48 PM1/16/07
to caml...@yquem.inria.fr
On Tuesday 16 January 2007 17:47, skaller wrote:
> In fact I have used Ocaml in a telco environment .. using
> the nice Event module, with many threads, services,
> and clients interacting in (soft) real time. That was some
> time ago so I can't say if I would have used 'finally'
> in that context or not. But typically I do that kind of
> thing the C way, which is generally the Ocaml way too:
> you propagate return codes from functions using variants
> up call chains.

Choosing boxing and unboxing over exceptions is fine if you have that choice
and are willing to endure the performance degredation and added verbosity.
However, you only have that choice if your code is self-contained. If you're
writing a library where users can raise exceptions, you must be careful to
undo state changes. In OpenGL, for example:

let transform m k x =
GlMat.push();
GlMat.mult m;
try
k x;
GlMat.pop()
with e ->
GlMat.pop();
raise e

could be rewritten:

let transform m k x =
GlMat.push();
GlMat.mult m;
try k x finally
GlMat.pop()

Handling user-raised exceptions in this way is likely if you're using
higher-order functions.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

skaller

unread,
Jan 16, 2007, 9:27:34 PM1/16/07
to Edgar Friendly
On Tue, 2007-01-16 at 12:01 -0600, Edgar Friendly wrote:
> skaller wrote:
> > So is your syntax:
> >
> > if cond1 then e1
> > elif cond2 then e2
> > ..
> > else el
> > endif
> >
> that would do what I want. Now is it possible to keep the open syntax
> as well, for the ?: uses of if/then/else?

Not directly. You could use IF .. THEN .. ENDIF and have both.
Or perhaps you could add

if .. do .. done

to Ocaml -- "if .. then .. " and "if .. do .. " are both
supported in Felix which uses Ocamlyacc to parse it,
I think indicating LALR1 can distinguish these two cases?
However camlp4 is recursive descent isn't it?

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Jan 16, 2007, 10:32:37 PM1/16/07
to Edgar Friendly
On Tue, 2007-01-16 at 13:24 -0600, Edgar Friendly wrote:
> skaller wrote:
> > What about it? C manages to handle all that .. and has no exceptions.
> >
> I think the point here is that because OCaml has exceptions (that other
> people use, maybe not you), it should also have finally blocks to allow
> them to easily do what you do without exceptions.

That is a reasonable argument to examine: but I'm not sure
finally is actually all that useful. If you're thinking of:

try maybe_throw X; do something
finally -> cleanup done

then it can be coded in Ocaml like:

begin try maybe_throw X; do something; cleanup
with x -> cleanup; throw x end

Now you can argue the repetition of 'cleanup' is a bad,
and I would agree, BUT in Ocaml this is no big deal:

begin let cleanup = .. in try ... end

In Java and other brain dead languages without lexical scoping
you cannot do this.

So Java really NEEDS finally, whereas in Ocaml the utility
is less. I note C++ can use RAII:

class file {
FILE * f; file(string x) : f(open(x)) {}
~file() { close(f); }
};
..
{
file f(name); maybe throw ..
}

and here needs no finally, but in general in C++ you have
the same problem as Java: no lexical scoping.

> > But adding 'finally' may not be the best solution,
> > the try/let construction looks better to me.
> >
> I can't find an example of this. Something about doing variable binding
> as part of the try statement, and then finalizing how?

I have lost the URL, sorry. But the problem is localisation:
the only sane way to use exceptions is like:

let result = try Some (open f) with Error -> None in
match result with None -> ... Some ....

If you try to do it like:

try
before
open f
middle
close f
after
with _ -> close f

then you have all sorts of problems if a different exception
is thrown in the before or after parts. Using type information
to distinguish the kind of exception is clearly a hack:
what if you're opening two files?

So roughly, this structure is not amenable to composition.
Adding 'finally' doesn't solve that problem, and that
problem is far worse than the lack of finally.
[Sorry this is a really bad explanation ..]

> > But typically I do that kind of
> > thing the C way, which is generally the Ocaml way too:
> > you propagate return codes from functions using variants
> > up call chains.
> >
> The OCaml standard library seems to be programmed using exceptions over
> variants. I'll have to say I don't like or use exceptions much, but I'm
> forced to by the standard libraries.

Yes, but you can do what many people do: map the exceptions into
variants like:

let hfind x y =
try Some(Hashtbl.find x y)
with Not_found -> None

religiously, eliminating the exceptions. And you can convert
to exceptions from variants like:

let efind x y =
match hfind x y with
| Some r -> r
| None -> raise Not_found

So really the library gives one of two cases, and allows you
to code the other easily. You aren't forced to use "long throw"
handlers, i.e. handlers which are a long way from the point
of the throwing code lexically.

The wrapper above eliminates any need for a finally clause
since ordinary conditionals and matches can be used instead --
in the case you're converting to variants.

It still leaves open the case of "long throw" exceptions
where you want to use exceptions: that may well benefit
from a finally clause but you see now the number of use
cases is reduced because the wrapper technique will be
appropriate in some cases.

IN FACT the problem is not entirely an issue with exceptions!
Examining the 'exception free' case using fopen below
we have the SAME problem:

let fopen f lock = try Some (open f) with Error -> None in
let lck = mutex () in lock mutex;
let f = fopen name lck in
match f with
| Some file -> ... close, release lck
| None -> release lck

WOOPS! Again we had to repeat the cleanup code.
Releasing the mutex AFTER the whole code works, but
if we want separate control flows for the two cases
we have to test the variant again:

begin match f with .. end; release lck;
match f with .. (* fork again *)

So actually, you could use a 'finally' here too: the problem
doesn't appear to be special to exception handling, but rather
a case where you have a control fork and want some code done in
the middle of both branches of the fork.

Roughly .. block structure (nesting) can't handle interleaved
execution very cleanly: you can minimise the impact with
lexically scoped subroutine call, but you still need to call
it twice.

Whereas with 'finally' clause you don't, the problem is
that you're restricted to the balanced (block) structure so the
code location of the 'finally' clause is right for both
branches. In complex cases .. the finally clause isn't
useful because it imposes too much nested structure
that turns out to be wrong anyhow: you have a state machine
which just can't be represented with a pushdown stack,
not even one that supports a second control path via
stack unwinding.

Please note again I'm not arguing against adding finally
(though I might do so!) I'm arguing the need for it isn't
as common as you might think in Ocaml, and part of the need
is only a symptom of a wider problem.

Some other languages provide continuations instead
of exceptions, and it is much easier to manage control
flow in such a language, since in effect 'goto' targets
are first class (can be stored in variables). I guess
it is also easier to *lose* control too :)


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

skaller

unread,
Jan 16, 2007, 10:50:44 PM1/16/07
to Jon Harrop
On Tue, 2007-01-16 at 19:42 +0000, Jon Harrop wrote:
> On Tuesday 16 January 2007 17:47, skaller wrote:

> Choosing boxing and unboxing over exceptions is fine if you have that choice
> and are willing to endure the performance degredation and added verbosity.
> However, you only have that choice if your code is self-contained. If you're
> writing a library where users can raise exceptions, you must be careful to
> undo state changes. In OpenGL, for example:
>
> let transform m k x =
> GlMat.push();
> GlMat.mult m;
> try
> k x;
> GlMat.pop()
> with e ->
> GlMat.pop();
> raise e
>
> could be rewritten:
>
> let transform m k x =
> GlMat.push();
> GlMat.mult m;
> try k x finally
> GlMat.pop()
>
> Handling user-raised exceptions in this way is likely if you're using
> higher-order functions.


Of course any specific example has a work around:

let finally u f = try u () with e -> f (); raise e in

let u () = GlMat.push(); GlMat.mult m in
let f () = GlMat.pop() in
finally u f

This would, however, be a mess if the push/pop things were
nested (which is likely I guess). Felix provides the syntax

{ code here }

meaning Ocaml's

(fun () -> code here)

which is very convenient for this idiom:

finally { push GlMat; mult GlMat m; } { pop GlMat; };

More generally you can write:

let f = new thing in
let finally () = close f in
try ... finally()
with e -> finally(); raise e

which all gets very messy when you have to repeat the
exercise in the 'try' block for some other exception AND
in the 'new thing' code as well .. and it's a nightmare
if your 'finally()' code can ALSO raise an exception.. ;(


--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Vincent Hanquez

unread,
Jan 17, 2007, 6:47:23 AM1/17/07
to skaller
On Wed, Jan 17, 2007 at 02:28:47PM +1100, skaller wrote:
> That is a reasonable argument to examine: but I'm not sure
> finally is actually all that useful. If you're thinking of:
>
> try maybe_throw X; do something
> finally -> cleanup done
>
> then it can be coded in Ocaml like:
>
> begin try maybe_throw X; do something; cleanup
> with x -> cleanup; throw x end

It would be more convincing if you hadn't made the trivial mistake to
put the first cleanup function in the try.
if for a really weird reason cleanup raises an exception, cleanup is done twice.

the correct OCaml code is:

let r = try maybe_throw X; do something; with exn -> cleanup; raise exn in
cleanup;
r

the point is not it's hard to do, it's annoything to duplicate here and
there, and doing the inline code lose the higher level view we can have
with a syntaxic sugar like try-finally.

> try
> before
> open f
> middle
> close f
> after
> with _ -> close f
>
> then you have all sorts of problems if a different exception
> is thrown in the before or after parts. Using type information
> to distinguish the kind of exception is clearly a hack:
> what if you're opening two files?

The thing is you don't do this with a flat block. If you need to unwind
a complex state you do:

before
try
let fd = open fd
try
middle
finally
close fd
finally
after

> Yes, but you can do what many people do: map the exceptions into
> variants like:
>
> let hfind x y =
> try Some(Hashtbl.find x y)
> with Not_found -> None

I'm not arguing against this method. You do it the way you want,
but when you use exception, having a finally is very handy for a lots of
case. Nothing more, nothing less.

> let fopen f lock = try Some (open f) with Error -> None in
> let lck = mutex () in lock mutex;
> let f = fopen name lck in
> match f with
> | Some file -> ... close, release lck
> | None -> release lck
>
> WOOPS! Again we had to repeat the cleanup code.
> Releasing the mutex AFTER the whole code works, but
> if we want separate control flows for the two cases
> we have to test the variant again:
>
> begin match f with .. end; release lck;
> match f with .. (* fork again *)
>
> So actually, you could use a 'finally' here too:

seems that you *finally* understand it ;)

--
Vincent Hanquez

Vincent Hanquez

unread,
Jan 17, 2007, 6:56:28 AM1/17/07
to skaller
On Wed, Jan 17, 2007 at 02:46:13PM +1100, skaller wrote:
> > let transform m k x =
> > GlMat.push();
> > GlMat.mult m;
> > try k x finally
> > GlMat.pop()
> >
> > Handling user-raised exceptions in this way is likely if you're using
> > higher-order functions.
>
>
> Of course any specific example has a work around:
>
> let finally u f = try u () with e -> f (); raise e in
>
> let u () = GlMat.push(); GlMat.mult m in
> let f () = GlMat.pop() in
> finally u f

Again, it would more convincing if the code you wrote was correct.
Here the f function doesn't get call if u didn't raise an exception.
We want the f function to be called in ALL case.

> This would, however, be a mess if the push/pop things were
> nested (which is likely I guess). Felix provides the syntax

This is not about Felix.

> which is very convenient for this idiom:
>
> finally { push GlMat; mult GlMat m; } { pop GlMat; };

And I would wrote it in OCaml with the abstraction function I have:

finally (fun () -> push GlMat; mult GlMat m) (fun () -> pop GlMat);

See, you can also show what you want to show without talking about
language X on language Y's ML, and thus been more on topic.

Cheers,
--
Vincent Hanquez

Olivier Andrieu

unread,
Jan 17, 2007, 7:58:45 AM1/17/07
to Vincent Hanquez
On 1/17/07, Vincent Hanquez <t...@snarc.org> wrote:
> On Wed, Jan 17, 2007 at 02:28:47PM +1100, skaller wrote:
> > That is a reasonable argument to examine: but I'm not sure
> > finally is actually all that useful. If you're thinking of:
> >
> > try maybe_throw X; do something
> > finally -> cleanup done
> >
> > then it can be coded in Ocaml like:
> >
> > begin try maybe_throw X; do something; cleanup
> > with x -> cleanup; throw x end
>
> It would be more convincing if you hadn't made the trivial mistake to
> put the first cleanup function in the try.
> if for a really weird reason cleanup raises an exception, cleanup is done twice.
>
> the correct OCaml code is:
>
> let r = try maybe_throw X; do something; with exn -> cleanup; raise exn in
> cleanup;
> r

that's not clear-cut ; it depends on the cleanup function. For
instance, concerning I/O channels in the standard library, you have
close_out and close_out_noerr. They do not have the same behavior, and
you should rather use the _no_err one in the with exn part.

> the point is not it's hard to do, it's annoything to duplicate here and
> there, and doing the inline code lose the higher level view we can have
> with a syntaxic sugar like try-finally.

Just use a higher-order function: it won't duplicate code, it's
high-level and it doesn't require any syntactic sugar.

let with_file_out fname f =
let oc = open_out fname in
try let r = f oc in close_out oc ; r
with exn -> close_out_noerr oc ; raise exn

let with_mat m f =
GlMat.push () ;
let r =
try GlMat.mult m ; f ()
with exn -> GlMat.pop () ; raise exn in
GlMat.pop () ;
r

Vincent Hanquez

unread,
Jan 17, 2007, 8:23:39 AM1/17/07
to Olivier Andrieu
On Wed, Jan 17, 2007 at 01:53:47PM +0100, Olivier Andrieu wrote:
> that's not clear-cut ; it depends on the cleanup function. For
> instance, concerning I/O channels in the standard library, you have
> close_out and close_out_noerr. They do not have the same behavior, and
> you should rather use the _no_err one in the with exn part.

You're right it's not clear-cut, but I'm talking about generic code.

Some function doesn't have the opportunity to not raise something
(without bracing them in try fct () with _ -> ()) and sometimes you also
want to propagate the cleanup's fct exception .. because something went
very wrong.

> >the point is not it's hard to do, it's annoything to duplicate here and
> >there, and doing the inline code lose the higher level view we can have
> >with a syntaxic sugar like try-finally.
>
> Just use a higher-order function: it won't duplicate code, it's
> high-level and it doesn't require any syntactic sugar.

Please read what I wrote before replying. The higher order function is
what I do now, because there's no other way for the code I use. It's *not*
hard to do and I already have lots of code that just look like your
example functions.

That said, it's just would be *easier* to express the "concept" with
appropriate keyword, not *emulated* through try-with.

> let with_file_out fname f =
> let oc = open_out fname in
> try let r = f oc in close_out oc ; r
> with exn -> close_out_noerr oc ; raise exn

This one doesn't have equivalent with finally, but that's fine
it cannot cover everything.
But *most* of the time the cleanup function is similar in both case.

> let with_mat m f =
> GlMat.push () ;
> let r =
> try GlMat.mult m ; f ()
> with exn -> GlMat.pop () ; raise exn in
> GlMat.pop () ;
> r

This become:

let with_mat m f =
GlMat.push ();

try GlMat.mult m ; f (); finally GlMat.pop ()

I can see in a jiffie what the second function does.
It's not as clear with the first one, I need to read a bit more to see
what it does (and GlMat.pop has been duplicated)

Cheers,
--
Vincent Hanquez

skaller

unread,
Jan 17, 2007, 9:17:25 AM1/17/07
to Vincent Hanquez
On Wed, 2007-01-17 at 12:41 +0100, Vincent Hanquez wrote:
> On Wed, Jan 17, 2007 at 02:28:47PM +1100, skaller wrote:
> > That is a reasonable argument to examine: but I'm not sure
> > finally is actually all that useful. If you're thinking of:
> >
> > try maybe_throw X; do something
> > finally -> cleanup done
> >
> > then it can be coded in Ocaml like:
> >
> > begin try maybe_throw X; do something; cleanup
> > with x -> cleanup; throw x end
>
> It would be more convincing if you hadn't made the trivial mistake to
> put the first cleanup function in the try.
> if for a really weird reason cleanup raises an exception, cleanup is done twice.
>
> the correct OCaml code is:
>
> let r = try maybe_throw X; do something; with exn -> cleanup; raise exn in
> cleanup;
> r

My code lacks generality, in that it assumed the expression
returned the unit. I see no difference whether the cleanup
is in the try or not: did I miss something?

[Well yes .. if the cleanup can raise an exception .. :]

> the point is not it's hard to do, it's annoything to duplicate here and
> there, and doing the inline code lose the higher level view we can have
> with a syntaxic sugar like try-finally.

I don't dispute these claims. However the same is true for many
features. We don't want to implement them all, so how do we choose?

The C++ committee basically chose features which either:

(a) were extremely common
(b) were so complex many people would get it wrong
(c) couldn't be done any other way

In addition, the C++ committee had limited time and couldn't
do everything. So a choice of a few features had to be made.

Some were accepted simply because they met the criteria and
were easy to implement, and others, although harder, provided
great benefit.

Given all these factors .. would you REALLY chose 'finally' as
a feature?

If I gave you just three features you could add .. would you
REALLY waste one of your wishes on 'finally'?

> seems that you *finally* understand it ;)

Lol! I have no trouble understanding it. See above.
My issue is with whether it is really that useful and common
it really should be part of an already over rich language.

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Jon Harrop

unread,
Jan 20, 2007, 2:29:14 PM1/20/07
to caml...@yquem.inria.fr
On Monday 15 January 2007 00:19, you wrote:
> On Sun, Jan 14, 2007 at 08:49:56PM +0000, Jon Harrop wrote:
> > I've been considering commercialising the replacement OCaml stdlib that I
> > developed.
>
> That won't help to make OCaml a mainstream language.
> The ones which are going to buy this, if there's anyone, will have a
> different code than the one that are not going to buy it.

The most important changes are compatible with OCaml's stdlib. I've just made
it faster and more robust.

> it just balkenized a bit more the situation.

I see no alternative.

> It's not really complex to have a replacement stdlib anyway, everybody
> can do it, and a lots of people have already put some freely-available
> on the internet.

Depends what features you want.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

_______________________________________________

skaller

unread,
Jan 20, 2007, 4:42:27 PM1/20/07
to Jon Harrop
On Sat, 2007-01-20 at 19:19 +0000, Jon Harrop wrote:

> > It's not really complex to have a replacement stdlib anyway, everybody
> > can do it, and a lots of people have already put some freely-available
> > on the internet.
>
> Depends what features you want.

And on the licence ;(

--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

_______________________________________________

Xavier Leroy

unread,
Jan 21, 2007, 12:09:51 PM1/21/07
to caml...@yquem.inria.fr
Among the 150 messages that accumulated while I was at the POPL
conference, I notice that the topic of native-code exception
backtraces is making its come-back:

> Well, seeing that the very useful native exception backtrace patch has
been
> sitting idle (acknowledged) for more than a year, I think that's not
> working it out too well :\

Like elephants, I'm slow, but never forget :-) You'll be pleased to
learn that I've been working recently on exception backtraces for
ocamlopt. The code (nearly finished) currently sits in the
"opt_backtrace" branch of the repository and should be part of
release 3.10.

It implements an exception backtrace mechanism similar to that already
available in bytecode, but different from Markus Mottl's call backtrace.
The two kinds of backtraces are incomparable in general, but while
Markus's solution is quite low overhead already, mine has even lower
overhead, especially in terms of code size.

Native-code backtraces will be available initially for the following
back-ends: i386, amd64 and powerpc, both for Unix-like OS and for
Windows. Ports to other back-ends will be considered if there is
sufficient demand.

- Xavier Leroy

Pierre Etchemaïté

unread,
Jan 21, 2007, 1:56:37 PM1/21/07
to caml...@yquem.inria.fr
Hi,

Le Sun, 21 Jan 2007 18:07:04 +0100, Xavier Leroy <Xavier...@inria.fr> a écrit :

> You'll be pleased to
> learn that I've been working recently on exception backtraces for
> ocamlopt. The code (nearly finished) currently sits in the
> "opt_backtrace" branch of the repository and should be part of
> release 3.10.

Now, that's an excellent news!

Will backtraces still be only available to uncaught exceptions ?
Sometimes it'd be useful to have backtraces in other cases, to
understand what's going on.

Not to get backtraces for all exceptions! Since exceptions have many
uses in OCaml, that would be uselessly painful :)

But maybe something like Printexc.to_string_with_backtrace (or
Printexec.to_string ~backtrace:true ?), so that debugging code could
decide to report, or log, backtraces of chosen exceptions...

Best regards,
Pierre.

0 new messages