* Streams
@ 2006-08-10 10:51 Error404
2006-08-10 11:40 ` [Caml-list] Streams Jonathan Roewen
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Error404 @ 2006-08-10 10:51 UTC (permalink / raw)
To: caml-list
Hi,
I'm looking for some streams related tutorial or any other info.
By stream i mean something like this (I don't know exact definition):
open Lazy;;
type 'a stream = Nil | Cons of 'a Lazy.t * 'a stream Lazy.t;;
(* For example stream of 'integers from x' would look like this: *)
let rec intsfrom x =
Cons(lazy x,lazy (intsfrom (x+1)));;
If you know any www/book or anything on this kind of streams please mail me (error92@tlen.pl).
Many thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Streams
2006-08-10 10:51 Streams Error404
@ 2006-08-10 11:40 ` Jonathan Roewen
2006-08-10 19:02 ` Chris King
2006-08-10 18:32 ` Martin Jambon
2006-08-11 0:00 ` Jon Harrop
2 siblings, 1 reply; 12+ messages in thread
From: Jonathan Roewen @ 2006-08-10 11:40 UTC (permalink / raw)
To: Error404; +Cc: caml-list
The Stream module provides exactly this functionality.
With camlp4o, you can use the old parser syntax too.
#load "camlp4o.cma";
let rec enum_from n = [< 'n; enum_from (n + 1) >];;
let first_10 = Stream.npeek 10 (enum_from 1);;
Streams are also lazily evaluated. More complex examples can be had
too, and there is the parser keyword to deconstruct streams as well.
You should be able to find more info in the camlp4 manual at the caml
site.
Jonathan
On 8/10/06, Error404 <error92@tlen.pl> wrote:
> Hi,
>
> I'm looking for some streams related tutorial or any other info.
> By stream i mean something like this (I don't know exact definition):
>
> open Lazy;;
> type 'a stream = Nil | Cons of 'a Lazy.t * 'a stream Lazy.t;;
>
> (* For example stream of 'integers from x' would look like this: *)
>
> let rec intsfrom x =
> Cons(lazy x,lazy (intsfrom (x+1)));;
>
> If you know any www/book or anything on this kind of streams please mail me (error92@tlen.pl).
> Many thanks.
>
> _______________________________________________
> 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
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Streams
2006-08-10 10:51 Streams Error404
2006-08-10 11:40 ` [Caml-list] Streams Jonathan Roewen
@ 2006-08-10 18:32 ` Martin Jambon
2006-08-11 0:00 ` Jon Harrop
2 siblings, 0 replies; 12+ messages in thread
From: Martin Jambon @ 2006-08-10 18:32 UTC (permalink / raw)
To: Error404; +Cc: caml-list
[-- Attachment #1: Type: TEXT/PLAIN, Size: 975 bytes --]
On Thu, 10 Aug 2006, Error404 wrote:
> Hi,
>
> I'm looking for some streams related tutorial or any other info.
> By stream i mean something like this (I don't know exact definition):
>
> open Lazy;;
> type 'a stream = Nil | Cons of 'a Lazy.t * 'a stream Lazy.t;;
>
> (* For example stream of 'integers from x' would look like this: *)
>
> let rec intsfrom x =
> Cons(lazy x,lazy (intsfrom (x+1)));;
>
> If you know any www/book or anything on this kind of streams please mail me (error92@tlen.pl).
> Many thanks.
I call this a lazy list. Anyway, I use the following definition:
type 'a l = Empty | Cons of 'a * 'a t
and 'a t = 'a l lazy_t (* only one lazy object per cell *)
See attachment for the full implementation.
You can manipulate such lists like real lists, only the syntax is less
comfortable. They are different from streams in the sense of the standard
Stream module, which are mutable.
Martin
--
Martin Jambon, PhD
http://martin.jambon.free.fr
[-- Attachment #2: Type: TEXT/PLAIN, Size: 2295 bytes --]
(* lazy lists *)
type 'a l = Empty | Cons of 'a * 'a t
and 'a t = 'a l lazy_t
let empty = lazy Empty
let is_empty l = Lazy.force l = Empty
let rec force l =
match Lazy.force l with
Empty -> ()
| Cons (hd, tl) -> force tl
let hd l =
match Lazy.force l with
Empty -> invalid_arg "Lizt.hd"
| Cons (x, _) -> x
let tl l =
match Lazy.force l with
Empty -> invalid_arg "Lizt.tl"
| Cons (_, x) -> x
let peek1 l =
match Lazy.force l with
Empty -> None
| Cons (x, _) -> Some x
let peek2 l =
match Lazy.force l with
Empty -> None
| Cons (x1, l) ->
match Lazy.force l with
Empty -> None
| Cons (x2, l) -> Some (x1, x2)
let peek3 l =
match Lazy.force l with
Empty -> None
| Cons (x1, l) ->
match Lazy.force l with
Empty -> None
| Cons (x2, l) ->
match Lazy.force l with
Empty -> None
| Cons (x3, l) -> Some (x1, x2, x3)
let rec of_list l =
lazy (match l with
[] -> Empty
| hd :: tl -> (Cons (hd, of_list tl)))
let rec to_list l =
match Lazy.force l with
Empty -> []
| Cons (hd, tl) -> hd :: to_list tl
let from f =
let rec make f i =
lazy (match f i with
None -> Empty
| Some x -> Cons (x, make f (i+1))) in
make f 0
let rec append l1 l2 =
lazy (match Lazy.force l1 with
Cons (hd, tl) -> Cons (hd, (append tl l2))
| Empty -> Lazy.force l2)
let rec iter f l =
match Lazy.force l with
Empty -> ()
| Cons (hd, tl) -> f hd; iter f tl
let rec map f l =
lazy (match Lazy.force l with
Empty -> Empty
| Cons (hd, tl) -> Cons (f hd, map f tl))
let filter f l =
let rec loop f l =
match Lazy.force l with
Empty -> lazy Empty
| Cons (hd, tl) ->
if f hd then lazy (Cons (hd, loop f tl))
else loop f tl in
lazy (Lazy.force (loop f l))
let optmap f l =
let rec loop f l =
match Lazy.force l with
Empty -> lazy Empty
| Cons (hd, tl) ->
match f hd with
Some y -> lazy (Cons (y, loop f tl))
| None -> loop f tl in
lazy (Lazy.force (loop f l))
let rec fold_left f accu l =
match Lazy.force l with
Empty -> accu
| Cons (hd, tl) -> fold_left f (f accu hd) tl
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Streams
2006-08-10 10:51 Streams Error404
2006-08-10 11:40 ` [Caml-list] Streams Jonathan Roewen
2006-08-10 18:32 ` Martin Jambon
@ 2006-08-11 0:00 ` Jon Harrop
2 siblings, 0 replies; 12+ messages in thread
From: Jon Harrop @ 2006-08-11 0:00 UTC (permalink / raw)
To: caml-list
On Thursday 10 August 2006 11:51, Error404 wrote:
> I'm looking for some streams related tutorial or any other info.
> By stream i mean something like this (I don't know exact definition):
>
> open Lazy;;
> type 'a stream = Nil | Cons of 'a Lazy.t * 'a stream Lazy.t;;
>
> (* For example stream of 'integers from x' would look like this: *)
>
> let rec intsfrom x =
> Cons(lazy x,lazy (intsfrom (x+1)));;
>
> If you know any www/book or anything on this kind of streams please mail me
> (error92@tlen.pl). Many thanks.
I just posted a link to some stuff on streams in the context of parsing but
you can write intsfrom as:
# #load "camlp4o.cma";;
Camlp4 Parsing version 3.09.2
# let rec intsfrom n = [< 'n; intsfrom(n+1) >];;
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Re: generic programming
@ 2002-07-05 23:05 Dave Berry
2002-08-02 14:49 ` [Caml-list] Streams Diego Olivier Fernandez Pons
0 siblings, 1 reply; 12+ messages in thread
From: Dave Berry @ 2002-07-05 23:05 UTC (permalink / raw)
To: Francois.Pottier, caml-list
At 10:33 05/07/2002, Francois Pottier wrote:
>My memories of STL are vague, but if an iterator is what I think it
>is, then implementing one in O'Caml is pretty straightforward. An
>iterator is a function that returns a function which maintains a
>piece of internal state.
But can you compile it down to a single increment instruction on a pointer
(for an iterator over an array)?
Also, can you compare two iterators for equality?
Dave.
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Caml-list] Streams
2002-07-05 23:05 [Caml-list] Re: generic programming Dave Berry
@ 2002-08-02 14:49 ` Diego Olivier Fernandez Pons
2002-08-02 15:29 ` Alain Frisch
0 siblings, 1 reply; 12+ messages in thread
From: Diego Olivier Fernandez Pons @ 2002-08-02 14:49 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: TEXT/PLAIN, Size: 3297 bytes --]
Bonjour,
Dans le cadre de la librairie de structures de données EDiSon
(Efficient Data Structures, Okasaki 2000) que je suis en train de
porter et d'adapter (pour l'instant 500k, prérelease prévue en
septembre), j'ai réalisé plusieurs types de listes à évaluation
retardée.
La première remarque est que j'ai eu beaucoup de mal à trouver de la
documentation à ce sujet :
- une implémentation très simple dans ML for the working programmer
(Paulson 1991, 1996)
- une implémentation par Pierre Weiss pour le problème des 8 dames sur
l'échiquer dans la librairie d'exemples d'Objective Caml
- l'implémentation de Daniel de Rauglaudre, cette dernière ayant
l'inconvénient de s'appuyer sur des fonctions non documentées de Caml,
mais il faut reconnaître que le code est parfaitement lisible et que
l'on devine à peu près ce qui se passe. C'est de surcroît la seule
implémentation à prendre en compte les fonctions génératrices et la
concaténation
- un article de Wadler (1997) sur l'implémentation de l'évaluation
retardée dans les langages stricts, qui a la particularité d'enfoncer
des portes ouvertes (ne considérant que les deux implémentations
traditionnelles) et de parler d'une implémentation particulièrement
efficace en SML/NJ qui serait en cours de développement, or la version
CVS de SML/NJ (110.41) ne comporte rien de tout cela, sinon le
traditionnel module Lazy
Enfin le rapport de recherche de Didier Remy et Daniel de
Rauglaudre (1992) n'est disponible que sous forme papier.
Voici donc mes questions :
- serait-il possible de documenter un peu le module obj ? Peut-être
est-ce une mauvaise idée, dans la mesure où cela pourrait permettre à
des utilisateurs non avertis d'écrire du code dangereux
j'ai écrit une version de listes à évaluation retardée qui simule le
fonctionnement des streams de Caml (fichier joint streamVI.ml)
type
'a stream = { mutable data : 'a streamCell } and
'a streamCell =
| Nil
| Cons of 'a * 'a stream
| Append of 'a stream * 'a stream
| Delayed of (unit -> 'a stream)
| Generator of int * (int -> int) * (int -> 'a)
L'inconvénient est que l'on perd le polymorphisme de la liste vide.
N'y a t-il aucun moyen de s'en sortir en utilisant du Caml
conventionnel ?
ensuite je voudrais abstraire le type int du constreur Generator afin
que l'utilisateur puisse indicer sa fonction génératrice par le type
de son choix :
| Generator of 'k * (k' -> 'k) * ('k -> 'a)
seulement si je déclare un type ('k, 'a) streamCell alors on ne peut
plus utiliser des listes d'indexes de type différent alors qu'elles
sont "logiquement" compatibles puisque le type 'k ne sert qu'a
construire les nouvelles valeurs de type 'a
comment limiter "l'étendue" du type 'k au seul constructeur
[Generator] ?
- la forme spéciale lazy ressemble très fortement à la fonction lazy_
ci-dessous mis à part qu'elle n'évalue pas ses arguments
(* OCaml 3.04 *)
let lazy_ = function x -> ref (Lazy.Delayed (function () -> x))
Quels seraient les inconvénients (théoriques ? pratiques ?) d'une
forme spéciale [uneval_] qui serait équivalente à function () ->,
autrement dit
uneval : 'a -> (unit -> 'a)
uneval_ x <=> function () -> x
Diego Olivier
[-- Attachment #2: streams --]
[-- Type: APPLICATION/octet-stream, Size: 8911 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Streams
2002-08-02 14:49 ` [Caml-list] Streams Diego Olivier Fernandez Pons
@ 2002-08-02 15:29 ` Alain Frisch
2002-08-03 14:19 ` Diego Olivier Fernandez Pons
0 siblings, 1 reply; 12+ messages in thread
From: Alain Frisch @ 2002-08-02 15:29 UTC (permalink / raw)
To: Diego Olivier Fernandez Pons; +Cc: caml-list
Hello Diego,
On Fri, 2 Aug 2002, Diego Olivier Fernandez Pons wrote:
> - serait-il possible de documenter un peu le module obj ? Peut-être
> est-ce une mauvaise idée, dans la mesure où cela pourrait permettre à
> des utilisateurs non avertis d'écrire du code dangereux
Using Obj safely requires to know a little bit about the runtime
representation of objects; and once you have this knowledge (after
reading the section on interfacing with C in the manual, or the OCaml
runtime source files), the module interface should be self-explanatory.
> L'inconvénient est que l'on perd le polymorphisme de la liste vide.
> N'y a t-il aucun moyen de s'en sortir en utilisant du Caml
> conventionnel ?
You have to explain to the typechecker that the Nil stream will
never be patched:
type
'a stream =
| Nil
| Patchable of 'a stream_patchable
and 'a stream_patchable = { mutable data : 'a streamCell }
and
'a streamCell =
| Cons of 'a * 'a stream
| Append of 'a stream * 'a stream
| Delayed of (unit -> 'a stream)
| Generator of int * (int -> int) * (int -> 'a)
Of course, this is less efficient (one would like to write
as in other ML dialects,
type
'a stream =
| Nil
| Patchable of { mutable data : 'a streamCell }
[see http://pauillac.inria.fr/~lefessan/src/ for such a patch
to OCaml 2.02]
...
Any plan to introduce this syntax in OCaml ?
)
> ensuite je voudrais abstraire le type int du constreur Generator afin
> que l'utilisateur puisse indicer sa fonction génératrice par le type
> de son choix :
>
> | Generator of 'k * (k' -> 'k) * ('k -> 'a)
>
> seulement si je déclare un type ('k, 'a) streamCell alors on ne peut
> plus utiliser des listes d'indexes de type différent alors qu'elles
> sont "logiquement" compatibles puisque le type 'k ne sert qu'a
> construire les nouvelles valeurs de type 'a
>
> comment limiter "l'étendue" du type 'k au seul constructeur
> [Generator] ?
Couln't you just abstract the generator outside the stream ?
let gen ini f =
let state = ref ini in
(fun () -> state := f !state),
(fun () -> !state);;
Do you really need to keep the current state visible ?
> - la forme spéciale lazy ressemble très fortement à la fonction lazy_
> ci-dessous mis à part qu'elle n'évalue pas ses arguments
>
> (* OCaml 3.04 *)
> let lazy_ = function x -> ref (Lazy.Delayed (function () -> x))
>
> Quels seraient les inconvénients (théoriques ? pratiques ?) d'une
> forme spéciale [uneval_] qui serait équivalente à function () ->,
> autrement dit
>
> uneval : 'a -> (unit -> 'a)
> uneval_ x <=> function () -> x
What do you mean by "forme spéciale" ? If you just want syntactic
sugar, you can implement it yourself with Camlp4.
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Streams
2002-08-02 15:29 ` Alain Frisch
@ 2002-08-03 14:19 ` Diego Olivier Fernandez Pons
0 siblings, 0 replies; 12+ messages in thread
From: Diego Olivier Fernandez Pons @ 2002-08-03 14:19 UTC (permalink / raw)
To: Alain Frisch; +Cc: caml-list
Alain,
> type
> 'a stream =
> | Nil
> | Patchable of 'a stream_patchable
> and 'a stream_patchable = { mutable data : 'a streamCell }
> and
> 'a streamCell =
> | Cons of 'a * 'a stream
> | Append of 'a stream * 'a stream
> | Delayed of (unit -> 'a stream)
> | Generator of int * (int -> int) * (int -> 'a)
Mes listes à évaluation retardées contrairement à celles de Rauglaudre
supportent (quasi) totalement les fonctions génératrices, en
particulier leur concaténation.
Quand Generator ou Delayed vont envoyer une exception [Empty] ou une
liste vide [Nil] respectivement, il faut que je mémorise la valeur, ce
qui empêche la construction que vous proposez à moins d'utiliser
Append (Nil, Nil) ou un nouveau constructeur NilBis dans StreamCell.
voici ma fonction force
let rec force = function stream ->
(match stream.data with
| Delayed f -> let x = f () in stream.data <- x.data
| Generator (index, succ, gen) ->
(try
let next_index = succ index in
stream.data <- Cons (gen next_index,
makeStream (Generator (next_index, succ, gen)))
with Empty -> stream.data <- Nil)
etc.
) ;
stream
En fait nous voudrions mimer le mieux possible le comportement des
listes de base, avec une unique représentation de la liste vide :
# []
- : 'a list = []
# let (_ :: tail) = [1] in tail
- : int list = []
# { data = Nil }
- : '_a stream = { data = Nil }
> Couln't you just abstract the generator outside the stream ?
>
> let gen ini f =
> let state = ref ini in
> (fun () -> state := f !state),
> (fun () -> !state);;
>
> Do you really need to keep the current state visible ?
Cette représentation des générateurs a été choisie afin de pouvoir
implémenter (relativement) efficacement les fonctions take et drop.
J'ai gardé l'indexe courant visible car c'était fait ainsi dans
l'implémentation de Rauglaudre, en effet dans les streams de Caml
l'indexe compte simultanément le nombre d'états consommés :
la fonction drop k applique simplement succ^k sur l'indexe,
la fonction take k remplace succ par la version suivante
let count = ref k in
let succ' = function index ->
if !count = 0 then raise Empty
else decr count ; succ index
L'idée est essentiellement que décaler d'un indice est plus rapide que
générer une valeur avec evenutellement une fonction triviale si ce
n'est pas le cas 'a * 'a -> 'a * 'a -> 'a
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <F241eHu7RVLCMUWktUq0000fbc1@hotmail.com>]
* Re: [Caml-list] Cannot find Stream Parser Documentation
[not found] <F241eHu7RVLCMUWktUq0000fbc1@hotmail.com>
@ 2002-04-09 18:09 ` Wolfram Kahl
2002-04-10 11:03 ` [Caml-list] Streams Daniel de Rauglaudre
0 siblings, 1 reply; 12+ messages in thread
From: Wolfram Kahl @ 2002-04-09 18:09 UTC (permalink / raw)
To: caml-list; +Cc: rtarpine
To my questions about streams and camlp4, I received two answers so far:
The first one from Ryan Tarpine <rtarpine@hotmail.com> unintentionally didn't
make it to the list:
>
> >From: Wolfram Kahl <kahl@cas.mcmaster.ca>
> >To: caml-list@inria.fr
> >Subject: [Caml-list] Cannot find Stream Parser Documentation
> >Date: Fri, 5 Apr 2002 13:58:18 -0500
> >
> >...
> >
> >The documentation for stream parsers that had been in the
> >``Language extensions'' chapter of the OCaml manual
> >seems to have disappeared, too.
> >I looked for it in the camlp4 directory,
> >but that directory doesn't even contain a README.
> >
> >In the OCaml distribution, camlp4 seems to come with no documentation
> >besides the manpage!
> >(And on the camlp4 web pages, I couldn't find anything related
> > to the implementation of streams.)
>
> I found the most information on stream parsers to be in camlp4's tutorial
> section, not the reference manual like I expected. See
> <http://caml.inria.fr/camlp4/tutorial/tutorial002.html> for the best info I
> stumbled across. It seems that '??' is the correct syntax, and your code
> works if you take out the 'when' clause, so maybe this is a bug?
>
> >A related issue: Among about 50 modules, only one uses stream parsers.
> >But
> >
> > ocamldep -pp camlp4o *.mli *.ml > .depend
> >
> >takes much longer than without camlp4.
> >How can I tell ocamldep to use camlp4 only for this file?
> >
> >...
>
> I recommend using Mr. Mottl's OCamlMakefile to manage your project. See
> <http://www.ai.univie.ac.at/~markus/home/ocaml_sources.html#OCamlMakefile>
> for info. With OCamlMakefile you just place the comment (*pp camlp4o *) at
> the top of any files that need to be preprocessed, and it takes care of the
> dirty work!
>
> HTH,
>
> Ryan Tarpine, rtarpine@hotmail.com
> "To err is human, to compute divine. Trust your computer but not its
> programmer."
> - Morris Kingston
>
In the second, Jean-Christophe Filliatre <Jean-Christophe.Filliatre@lri.fr>
provides a practical pattern for use in hand-made makefiles:
>
> Regarding dependencies, there are several solutions. As far as I'm
> concerned, I chose to name my camlp4 files .ml4 and to produce the .ml
> file before computing the dependencies, like this:
>
> ======================================================================
> foo.ml: foo.ml4
> camlp4o pr_o.cmo -impl $< > $@
>
> depend: foo.ml
> ocamldep *.ml *.mli > .depend
> ======================================================================
>
> Of course, I do not produce the .ml file for compiling; I use ocamlc
> -pp:
>
> ======================================================================
> foo.cmo: foo.ml4
> ocamlc -c -pp "camlp4o -impl" -impl $<
>
> ======================================================================
This solves my ocamldep problem.
However, my real problem is not solved yet:
The stream language as currently supported by camlp4
apparently does not contain the full stream language of OCaml 3.02
(and many, many previous versions),
and I cannot find any document that explains the differences.
(In addition, all the OCaml sites at INRIA seem to be down since at least
yesterday ...)
So I did a few experiments with camlp4 stream translation:
My original code (this worked for years!):
Input 1:
-------------------------------
let pc0 c = parser n
[< ' x
when x == c
?? (string_of_int n ^ ": pc '" ^ String.make 1 c ^ "'")
>] -> ();;
-------------------------------
Message:
-------------------------------
File "streamTest.ml4", line 4, characters 8-10:
Parse error: '>]' expected after [stream_patt] (in [parser_case])
-------------------------------
The error points to `??'.
Since Ryan Tarpine points out that the ``when'' might be the problem,
but I need the condition, I try to factorise:
Input 2:
-------------------------------
let pc0 c = parser n
[< ' x
when (x == c)
>] -> ();;
let pc c = parser n
[< _ = pc0 c
?? (string_of_int n ^ ": pc '" ^ String.make 1 c ^ "'")
>] -> ();;
-------------------------------
Message:
-------------------------------
File "streamTest.ml4", line 7, characters 8-10:
Parse error: '>]' expected after [stream_patt] (in [parser_case])
-------------------------------
The error points to `??', again.
This is particularly interesting given that the following works
(only difference: two invocations of pc0 before `??'):
Input 3:
-------------------------------
let pc0 c = parser n
[< ' x
when (x == c)
>] -> ();;
let pc c = parser n
[< _ = pc0 c; _ = pc0 c
?? (string_of_int n ^ ": pc '" ^ String.make 1 c ^ "'")
>] -> ();;
-------------------------------
Output:
-------------------------------
let pc0 c (strm__ : _ Stream.t) =
let n = Stream.count strm__ in
match Stream.peek strm__ with
Some x when x == c -> Stream.junk strm__; ()
| _ -> raise Stream.Failure
;;
let pc c (strm__ : _ Stream.t) =
let n = Stream.count strm__ in
let _ = pc0 c strm__ in
let _ =
try pc0 c strm__ with
Stream.Failure ->
raise
(Stream.Error (string_of_int n ^ ": pc '" ^ String.make 1 c ^ "'"))
in
()
;;
-------------------------------
Against my expectations,
only the last invocation of pc0 is inside the try ... catch.
(Parentheses around the two invocations of pc0 are not accepted.)
I'm puzzled... Should I rather recode all my 247 Stream parsers manually?
Wolfram
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Caml Development Kit
@ 2001-03-27 2:12 Patrick M Doane
2001-03-27 3:15 ` Brian Rogoff
0 siblings, 1 reply; 12+ messages in thread
From: Patrick M Doane @ 2001-03-27 2:12 UTC (permalink / raw)
To: Fabrice Le Fessant; +Cc: caml-list
This is excellent news! I'm looking forward to helping with this effort.
I have quite a bit of code lying around on my machine for working with
e-mail protocols (such as POP, SMTP, NNTP, IMAP, etc) and associated data.
I recently created a Sourceforge project to try to organize an effort to
making high-quality Ocaml modules for these types of modules. For those
interested, it is located at:
http://sourceforge.net/projects/ocamlnet/
I have placed a project goals document but not much source code yet for a
reason that this CDK project might be able to resolve:
As much as I love Caml as a language, I have to admit that I've been less
than pleased with the standard infrastructure for string manipulation.
First a summary of approaches that I'm aware of:
1) Manipulate the string manually with functions like String.index and
maintain position variables. I find this to be pretty error-prone and
hard to read.
2) Use the stream parsers. I hesitate to use them because of their
status as "experimental" and that be removed at any time. I also have
heard claims that their performance is not too good compared with other
techniques. Does anyone know if this true?
3) Use ocamllex. This would be the most natural approach to me but
their utility is hampered by not being able to pass additional parameters
to the rules. I understand that there is patch available that adds this
functionality, but it's part of the standard distribution.
4) Use a regular expression matching library. The builtin Str is
not thread-safe which is problematic. PCRE and xstr provide good
alternatives. Too many choices here though.
5) Write another custom module for string manipulation!
Since I wasn't happy with the builtin functions and didn't want to rely on
a third party distribution, I opted for option 5 while writing a good bit
of the code. But then I think, does the world really need another string
manipulation library?
If we can converge on a small set of good workable solutions, then it'll
make it much easier to produce a large set of modules for protocols and
parsing.
Any thoughts?
Patrick
On Mon, 26 Mar 2001, Fabrice Le Fessant wrote:
>
> A few weeks ago, we started a project called "Caml Development Kit" or
> CDK, which would gather in one big tarball or RPM several tools and
> libraries, useful for Ocaml programming.
>
> For example, the CDK will include Ocaml, Camlp4, ledit, and many
> user-contributed libraries. A new CDK will be released at each Ocaml
> release (and probably more often from CVS sources), removing the need
> to update, compile and install many different packages everytime to
> have a coherent development envirronment.
>
> If you are interested in contributing to this project, you can either
> send me your code, or an URL where we can download your contribution.
>
> We are particularly interested in general modules, providing useful
> data structures, network(urlget,http_server,etc)/ crypto(des)/
> multimedia(images) functions, or bindings to C libraries.
>
> The package includes a simple tool to generate HTML from .mli files.
> Thus, contributions must provide .mli files for all interesting
> modules, and these .mli files must be correctly documented.
>
> Have a look at the just created web site:
>
> http://pauillac.inria.fr/cdk
>
> - Fabrice
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr
>
-------------------
To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] Caml Development Kit
2001-03-27 2:12 [Caml-list] Caml Development Kit Patrick M Doane
@ 2001-03-27 3:15 ` Brian Rogoff
2001-03-27 6:48 ` [Caml-list] Streams Daniel de Rauglaudre
0 siblings, 1 reply; 12+ messages in thread
From: Brian Rogoff @ 2001-03-27 3:15 UTC (permalink / raw)
To: Patrick M Doane; +Cc: Fabrice Le Fessant, caml-list
On Mon, 26 Mar 2001, Patrick M Doane wrote:
> As much as I love Caml as a language, I have to admit that I've been less
> than pleased with the standard infrastructure for string manipulation.
> First a summary of approaches that I'm aware of:
>
> 1) Manipulate the string manually with functions like String.index and
> maintain position variables. I find this to be pretty error-prone and
> hard to read.
>
> 2) Use the stream parsers. I hesitate to use them because of their
> status as "experimental" and that be removed at any time. I also have
> heard claims that their performance is not too good compared with other
> techniques. Does anyone know if this true?
This is like shooting squirrels with a sniper rifle. It's quite a bit more
power than you need for most string processing tasks. I certainly wouldn't
worry about the "experimental" label since it's been there for quite a
long time.
Why not steal the substring library from the SML Basis? It's a variant on
your 1) and has the added advantage that we can lift much of the
documentation from the SML community.
It might even be worthwhile to just steal as much of the Basis library as
possible from Mosml and SML/NJ. Stealing code is this way is good, and it
allows SML programmers to migrate more easily (and ultimately would allow
Caml programmers easy migration too) which is a good thing.
As far as regexp libraries go, I like Pcre, but I haven't tried xstr.
-- Brian
-------------------
To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Caml-list] Streams
2001-03-27 3:15 ` Brian Rogoff
@ 2001-03-27 6:48 ` Daniel de Rauglaudre
[not found] ` <3AC04E85.EE51D597@univ-savoie.fr>
0 siblings, 1 reply; 12+ messages in thread
From: Daniel de Rauglaudre @ 2001-03-27 6:48 UTC (permalink / raw)
To: caml-list
Hello,
On Mon, Mar 26, 2001 at 07:15:54PM -0800, Brian Rogoff wrote:
> > 2) Use the stream parsers. I hesitate to use them because of their
> > status as "experimental" and that be removed at any time. I also have
> > heard claims that their performance is not too good compared with other
> > techniques. Does anyone know if this true?
>
> This is like shooting squirrels with a sniper rifle. It's quite a bit more
> power than you need for most string processing tasks. I certainly wouldn't
> worry about the "experimental" label since it's been there for quite a
> long time.
Streams date from 1992. They have been implemented in Caml Light.
I added them in OCaml but actually it was an error: streams and
streams parsers are just syntactic sugar, it is work for Camlp4, but
Camlp4 did not exist at this time. We plan to remove them from OCaml
but after having moved Camlp4 in OCaml contribution directory.
--
Daniel de RAUGLAUDRE
daniel.de_rauglaudre@inria.fr
http://cristal.inria.fr/~ddr/
-------------------
To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-08-11 0:01 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-10 10:51 Streams Error404
2006-08-10 11:40 ` [Caml-list] Streams Jonathan Roewen
2006-08-10 19:02 ` Chris King
2006-08-10 18:32 ` Martin Jambon
2006-08-11 0:00 ` Jon Harrop
-- strict thread matches above, loose matches on Subject: below --
2002-07-05 23:05 [Caml-list] Re: generic programming Dave Berry
2002-08-02 14:49 ` [Caml-list] Streams Diego Olivier Fernandez Pons
2002-08-02 15:29 ` Alain Frisch
2002-08-03 14:19 ` Diego Olivier Fernandez Pons
[not found] <F241eHu7RVLCMUWktUq0000fbc1@hotmail.com>
2002-04-09 18:09 ` [Caml-list] Cannot find Stream Parser Documentation Wolfram Kahl
2002-04-10 11:03 ` [Caml-list] Streams Daniel de Rauglaudre
2002-04-11 14:35 ` Wolfram Kahl
2001-03-27 2:12 [Caml-list] Caml Development Kit Patrick M Doane
2001-03-27 3:15 ` Brian Rogoff
2001-03-27 6:48 ` [Caml-list] Streams Daniel de Rauglaudre
[not found] ` <3AC04E85.EE51D597@univ-savoie.fr>
2001-03-27 8:37 ` Daniel de Rauglaudre
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox