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
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
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
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...
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.
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
E.
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
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
_______________________________________________
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
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
>> 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.
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
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
_______________________________________________
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
_______________________________________________
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
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
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
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.
> > 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
> 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
_______________________________________________
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
_______________________________________________
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
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
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
> 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
> 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
> 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
--
Martin Jambon
http://martin.jambon.free.fr
_______________________________________________
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
_______________________________________________
> 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>
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
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
> 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
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
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
_______________________________________________
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
_______________________________________________
> 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.
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.
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.
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 :)
> 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
_______________________________________________
> 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
_______________________________________________
> 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
_______________________________________________
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.