caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Max Kirillov <max630@mail.ru>
To: caml-list@pauillac.inria.fr
Subject: Re: [Caml-list] Re: Haskell-like syntax
Date: Sat, 15 Mar 2003 01:30:57 +0600	[thread overview]
Message-ID: <20030315013056.C5826@max.home> (raw)
In-Reply-To: <20030314003336.D748@max.home>; from max630@mail.ru on Fri, Mar 14, 2003 at 12:33:36AM +0600

[-- Attachment #1: Type: text/plain, Size: 3096 bytes --]

On Fri, Mar 14, 2003 at 12:33:36AM +0600, Max Kirillov wrote:
> Talking about the single thigs: at the beginning of my way into ocaml, I
> did some camlp4 hacks. For example, that was "where" keyword support
> (much more powerful than in revised syntax) and some support for "from
> top to bottom" style of sources. If you interested, I could post them.

I'm sending the changes. Note that, though they are quite stable, I
picked them from an environment, so something may broke.

A little comment what is it.

file test_where.ml -- obvious. Very little, more to demonstrate, than to
cover all possible (and really seen) dangers.

file lazyX.ml -- misc functions to handle lazy values (see later)
note that it is already uses the extension

file where.ml -- the main thing

There are several things:

1) 'where' notation:

<expr> ::=  <expr> where { [rec] <let-binding> }
	|   <expr> where [begin] [rec] <let-binding> end

the two version are the same (some like {..}, some begin..end).
there are some unresolved quastions with prioriries, so, in practice, I
often had to use brackets. However, I think that the level I choose is
quite reasonable.

2) reorder srt_items

there are keyword 'WHERE' (uppercase) in place of structure item. At the
point, the structure (or the whole file if at toplevel) is cut, then
pieces swapped and concated again. this allows writing:

------- file.ml
main ();;
WHERE
let main () =
    do_this ();
    do_that ();;
WHERE
let do_this () =
    <.......>
and do_that () =
    <........>
------

3) lazy values predeclaration

<str-item> ::=	[let] [lazy] [rec] <let-binding>

this allows define lazy value, which is seen to the whole structure, and
not only to the following items. Every value that is binded is lazy
value, that, when forced, computes the definition. It uses the LazyX
module: nondef () produces the value, set dest src replaces the
unforced lazy value dest by the unforced lazy expression src, if any of
then is already forced (it is at module initialization time, so it's
easy to catch), the exception is raised.

I used it in plays with "functional GUI", where needed to declare many
inter-depended values and, for various reasons, didn't want to use "let
rec <...> and <...>" chain.

There is one trouble. When you define a type, and then a lazy value of
the type, the compiler complains "the type xxx would escape its scope".
this berore it comes to need to infer the type for the initial
declaration "let x = LazyX.nondef ()", where it is not yet defined.
To solve the problem, I added "HEADER" keyword. It explicitly says that
the forward declataions must be placed here instead of beginning of the
file. You place it after the type declaration. Of course the lazy values
definitions must itself follow the type declarations.

The lazy stuff is intended to work only in toplevel, it is not for
"struct..end".

I used the (1) very much, and would say it quite workable. The (2) is
also quite stable, but, now, I would say the realization needs to be
changed. The (3) are more a toy than real thing. There could be problems
with that.

-- 
Max

[-- Attachment #2: test_where.ml --]
[-- Type: text/plain, Size: 355 bytes --]


let main () =
    Lazy.force a;
    Lazy.force b;
    Lazy.force c;
    Lazy.force d

WHERE

lazy c = Int 123
lazy b = String "4567"

HEADER

lazy a = Int 123
lazy d = match Lazy.force b with Int n -> n | String s -> s2i s
    where {s2i = int_of_string}

WHERE

lazy c = Int 123
lazy b = String "4567"

WHERE

type value = Int of int | String of string

[-- Attachment #3: where.ml --]
[-- Type: text/plain, Size: 2609 bytes --]

open Pcaml;;

type exprT = MLast.expr Grammar.Entry.e
and  pattT = MLast.patt Grammar.Entry.e;;

let let_gen = Grammar.Entry.create gram "let_general";;
let expr_where = Grammar.Entry.create gram "expr_where";;
let str_item_semi = Grammar.Entry.create gram "str_item_semi";;
let implem_pre = Grammar.Entry.create gram "implem_pre";;
let let_lazy_binding = Grammar.Entry.create gram "let_lazy_binding";;

let rec insert ?(word="WHERE") elems lst =
    match lst with [] -> elems
	| (<:str_item< $str:name$ >>,_ as w)::tl when name=word -> elems@(w::tl)
	| hd::tl -> hd::insert ~word elems tl

let is_header = function <:str_item< value $lid:_$ = LazyX . nondef () >>, _ -> true | _ -> false

EXTEND
    implem:
	[[ (l,stopped) = implem_pre -> 
	    let lst1,lst2 = List.partition is_header l in
	    (List.rev (insert ~word:"HEADER" lst1 lst2),stopped) ]];
    implem_pre:
	[[ "WHERE"; (sil,stopped) = SELF ->
			    ((<:str_item< $str:"WHERE"$ >>,loc)::sil, stopped)
	| "HEADER"; (sil,stopped) = SELF ->
			    (insert [(<:str_item< $str:"HEADER"$ >>,loc)] sil, stopped)
	| si = str_item_semi; OPT ";;"; (sil, stopped) = SELF ->
			    (insert si sil, stopped)
	| "#"; n = LIDENT; dp = OPT expr; ";;" ->
	      ([(<:str_item< # $n$ $opt:dp$ >>, loc)], true)
	| EOI -> ([], false) ]];
    str_item_semi:
	[[ si = str_item; OPT ";;" ->
	    match si with 
		<:str_item< LazyX.set $lid:dest$ $e$ >> as si ->
		    [(<:str_item< value $lid:dest$ = LazyX . nondef () >>,loc);(si, loc)];
		| _ -> [(si, loc)] ]];
    str_item: LEVEL "top"
	[[ "let"; "lazy"; lb = let_lazy_binding -> lb
	| "lazy"; lb = let_lazy_binding -> lb]];
    let_lazy_binding:
	[[ lb = let_binding ->
	    let tr (p,e) = match p with
		<:patt< $lid:name$ >> ->
		    <:str_item< LazyX.set $lid:name$ ( lazy $e$ ) >>
		| _ -> raise Stream.Failure in
	    tr lb ]];
    expr: BEFORE "top"
	[[ e = SELF; (ifRec,l) = expr_where -> 
	    <:expr< let $rec:ifRec!=None$ $list:l$ in $e$ >> ]];
    expr_where:
	[["where"; _ = OPT "begin"; (ifRec,l) = let_gen; "end" ->
	    (ifRec,l)
	| "where"; "{"; (ifRec,l) = let_gen; "}" -> (ifRec,l) ]];
    let_gen: [[r = OPT "rec"; l = LIST1 let_binding SEP "and" -> (r,l)]];
    module_expr:
	[[ "struct"; st = LIST0 [ "WHERE" -> `Where
			    | s = str_item; OPT ";;" -> `Item s ]; "end" ->
		    let rec f ((il::ils) as ilS:'a list list) =
			    function [] -> ilS
				    | (`Item i::l) -> f ((i::il)::ils) l
				    | (`Where::l) -> f ([]::ilS) l in
		    let s = <:str_item< $lid:"b"$ = $lid:"a"$ >> in
		    <:module_expr< struct $list:(List.concat (List.map List.rev (f [[]] st)))$ end >>
	]];
END;;

[-- Attachment #4: lazyX.ml --]
[-- Type: text/plain, Size: 319 bytes --]

exception Already_forced
let nondef () = lazy ( raise Lazy.Undefined )
let set (dest:'a Lazy.t) (src:'a Lazy.t) =
    (if	Obj.tag dobj <> Obj.lazy_tag ||
	    Obj.tag sobj <> Obj.lazy_tag
	then raise Already_forced
	else Obj.set_field dobj 0 (Obj.field sobj 0))
    where {dobj = Obj.repr dest and sobj = Obj.repr src}

  reply	other threads:[~2003-03-14 19:32 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-06 23:27 [Caml-list] OCaml popularity Graham Guttocks
2003-03-10 20:43 ` Paul Steckler
2003-03-10 23:48 ` Gerd Stolpmann
2003-03-11  0:18   ` Brian Hurt
2003-03-17 23:49   ` Graham Guttocks
2003-03-11  1:43 ` Nicolas Cannasse
2003-03-11 10:23   ` Pierre Weis
2003-03-11 14:27     ` Guillaume Marceau
2003-03-11 16:16       ` David Brown
2003-03-11 16:47       ` [Caml-list] about -rectypes Christophe Raffalli
2003-03-12  2:32       ` [Caml-list] OCaml popularity Nicolas Cannasse
2003-03-12  3:55         ` Cross-platform GUI (was Re: [Caml-list] OCaml popularity) mgushee
2003-03-12 10:51         ` [Caml-list] OCaml popularity Alex Romadinoff
2003-03-12 18:24         ` Max Kirillov
2003-03-11 19:02     ` Graham Guttocks
2003-03-12 17:12       ` Richard W.M. Jones
2003-03-12 18:08         ` Alwyn Goodloe
2003-03-12 22:34           ` Michael Schuerig
2003-03-12 23:13             ` Martin Weber
2003-03-12 23:35               ` Michael Schuerig
2003-03-13  8:02                 ` Alessandro Baretta
2003-03-13 10:23                   ` Michael Schuerig
2003-03-12 23:35             ` Brian Hurt
2003-03-12 23:18         ` Daniel Bünzli
2003-03-12 23:47           ` Brian Hurt
2003-03-13  2:15         ` William Lovas
2003-03-13  3:44           ` Graham Guttocks
2003-03-13  9:31           ` Richard W.M. Jones
     [not found]           ` <20030313095232.GC347@first.in-berlin.de>
2003-03-13 20:50             ` William Lovas
2003-03-13 21:17               ` Oliver Bandel
2003-03-13 22:01                 ` Brian Hurt
2003-03-13 22:17                 ` Oliver Bandel
2003-03-14  6:33                 ` Michal Moskal
2003-03-14 11:50                   ` Markus Mottl
2003-03-14 15:38                     ` Oliver Bandel
2003-03-14 10:13               ` MikhailFedotov
2003-03-14 10:30                 ` Johann Spies
2003-03-13  8:09       ` Pierre Weis
2003-03-15  1:43     ` Tushar Samant
2003-03-15  8:19       ` Andreas Eder
2003-03-11 16:26   ` Fred Yankowski
2003-03-11 19:47     ` [Caml-list] OCaml popularity (long!) mgushee
2003-03-12 11:23       ` Diego Olivier Fernandez Pons
2003-03-30  5:59         ` Belated thanks (was Re: [Caml-list] OCaml popularity) Matt Gushee
2003-03-31 15:27           ` [Caml-list] Re: Belated thanks cashin
2003-04-01  8:22           ` Belated thanks (was Re: [Caml-list] OCaml popularity) Johann Spies
2003-03-12 20:41       ` [Caml-list] OCaml popularity (long!) Max Kirillov
2003-03-13  2:36         ` Haskell-like syntax (was: [Caml-list] OCaml popularity (long!)) Oleg
2003-03-13 18:33           ` [Caml-list] Re: Haskell-like syntax Max Kirillov
2003-03-14 19:30             ` Max Kirillov [this message]
2003-03-14 19:47               ` Max Kirillov
2003-03-14 20:01               ` Seth Kurtzberg
2003-03-14 20:34                 ` brogoff
2003-03-14 21:17                   ` Sebastien Carlier
2003-03-14 21:51                     ` brogoff
2003-03-15  2:27                 ` Max Kirillov
2003-03-15 10:58                   ` Markus Mottl
2003-03-15 15:52                     ` [Caml-list] globally valid symbols (was: Haskell-like syntax) Max Kirillov
2003-03-15 20:16                     ` [Caml-list] Re: Haskell-like syntax David Brown
2003-03-16  5:28                     ` Module recursion (Was Re: [Caml-list] Re: Haskell-like syntax) brogoff
2003-03-16 11:10                       ` Markus Mottl
2003-03-16 18:02                         ` brogoff
2003-03-16 18:34                           ` Markus Mottl
     [not found]                     ` <Pine.LNX.4.44.0303152112560.27230-100000@grace.speakeasy.n et>
2003-03-16  5:38                       ` Chris Hecker
2003-03-16 18:34                         ` brogoff
2003-03-17  2:20                           ` Jacques Garrigue
     [not found]                         ` <Pine.LNX.4.44.0303161020480.11736-100000@grace.speakeasy.n et>
2003-03-17  5:08                           ` Chris Hecker
2003-03-17 17:06                             ` brogoff
2003-03-17 19:01                               ` Ville-Pertti Keinonen
     [not found]                             ` <Pine.LNX.4.44.0303170836240.29039-100000@grace.speakeasy.n et>
2003-03-17 19:33                               ` Chris Hecker
2003-03-17 20:28                                 ` brogoff
     [not found]                                 ` <Pine.LNX.4.44.0303171145500.29039-100000@grace.speakeasy.n et>
2003-03-17 21:09                                   ` Chris Hecker
2003-03-19  2:34                                 ` [Caml-list] ocamlopt speed (was Re: Module recursion) Chris Hecker
2003-03-19 10:03                                   ` Michal Moskal
2003-03-19 10:38                                     ` Gerd Stolpmann
2003-03-19 20:36                                   ` Chris Hecker
2003-03-17  1:46                     ` [Caml-list] Re: Haskell-like syntax Nicolas Cannasse
2003-03-14 22:50               ` Oleg
2003-03-20 15:01                 ` Andreas Rossberg
2003-03-12 20:46       ` [Caml-list] Monads was OCaml popularity Christophe Raffalli
2003-03-13  0:03       ` [Caml-list] monads for dummies james woodyatt
2003-03-13  4:32         ` Christopher Quinn
2003-03-13 11:53         ` Christian Lindig
2003-03-12 18:59 ` [Caml-list] OCaml popularity Martin Weber
2003-03-12 20:24   ` Xavier Leroy
2003-03-13  8:57     ` [Caml-list] how to interface with integer Bigarrays using camlidl francois bereux
2003-03-13  9:36       ` Xavier Leroy
2003-03-13  0:42   ` [Caml-list] OCaml popularity Graham Guttocks

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030315013056.C5826@max.home \
    --to=max630@mail.ru \
    --cc=caml-list@pauillac.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).