caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: bluestorm <bluestorm.dylc@gmail.com>
To: caml-list caml-list <caml-list@yquem.inria.fr>
Subject: [Caml-list] Purity and lazyness
Date: Fri, 7 Jan 2011 21:52:13 +0100	[thread overview]
Message-ID: <AANLkTi=GOgfkJ-cZO6oi1ZgdqyfDoRzwLyMLkYsXKoNS@mail.gmail.com> (raw)
In-Reply-To: <AANLkTikxCSQ+0XkOmSVDb3EWq_2oQ0pac3bDgc7f7jq+@mail.gmail.com>

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

On Fri, Jan 7, 2011 at 8:17 PM, Florian Weimer <fw@deneb.enyo.de> wrote:

> Essential laziness occurs when you construct values which would not
> otherwise be possible to construct in a pure language.  For instance,
> if you have got some sort of compiler, at one point, you might want to
> perform name resolution.  At that point, you want to translate names
> (references) to the program entities they denote (referents).  In
> general, these references do not form a tree (for instance, a function
> body can refer to another function by name, which refers to the
> original function).  With laziness, you can compute a map from names
> to entities, and the entities use this maps to resolve the names they
> use as references.  Name lookup is only performed once per name.
> Without laziness, you have to perform name lookup each time you follow
> a reference because the self-referential nature of the data structure
> cannot be reflected in the program.
>

I'm not convinced by your example. You need lazyness because you want to
build a cyclic data structure. But is this such a good idea ? In my
experience, implicit cyclicity often raises more problems than it solves,
and it is much safer to use an explicit indirection layer.

In your example, the resolved identifiers could contain not the declaration
code itself, but a unique key that is associated to those declaration sites.
This can be done easily, with only one traversal. Then in a second pass you
can record the mapping of keys to resolved declaration sites, and therefore
tie the knot.

Below is a simple code example:

  type unique_loc = int
  type name = string

  (* a simple language with identifiers and mutually recursive definitions
*)
  type 'a term =
    | Name of 'a
    | Lets of ((name * unique_loc) * 'a term) list * 'a term

  (* unique_loc are supposed to be unique, names are not due to
     shadowing. In a source program, a identifier points to a name,
     which is ambiguous. To resolve it means to turn all such names into
     the unique identifiers corresponding to the binding declaration
  *)
  type input_term = name term
  type resolved_term = unique_loc term

  let resolve : input_term -> resolved_term =
    let rec resolve (env : (name * unique_loc) list) = function
      | Name n -> Name (List.assoc n env)
      | Lets (decls, body) ->
        let env' = List.map fst decls @ env in
        let resolve_decl (binder, code) =
          binder, resolve env' code in
        Lets (List.map resolve_decl decls, resolve env' body)
    in resolve []

  (* we can easily build a table that, to each unique location,
     associates the declaration code; during further analysis, this may
     allow some handling of identifiers based on the expression they
     denote. *)
  let rec resolution_table : resolved_term -> (unique_loc * resolved_term)
list =
    function
      | Name _ -> []
      | Lets (decls, body) ->
        let decl_table ((_, loc), code) =
          (loc, code) :: resolution_table code in
        resolution_table body @ List.concat (List.map decl_table decls)

  (* if you want to test *)
  let input : input_term =
    Lets ([
      ("x", 1), Name "y";
      ("y", 2), Name "x";
      ("z", 3),
        Lets ([
          ("a", 4), Name "x";
          ("b", 5), Name "y";
        ], Name "z");
    ],
      Lets (
        [("x", 6), Name "x"],
        Name "z"))

[-- Attachment #2: Type: text/html, Size: 4747 bytes --]

  parent reply	other threads:[~2011-01-07 20:52 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-07 15:35 Dario Teixeira
2011-01-07 16:07 ` Damien Doligez
2011-01-07 16:38   ` David Rajchenbach-Teller
2011-01-07 18:16     ` Holger Weiß
2011-01-07 20:22     ` Eray Ozkural
2011-01-07 20:29       ` orbitz
2011-01-07 20:30         ` Joel Reymont
2011-01-07 20:33         ` Eray Ozkural
2011-01-08  9:44     ` Jesper Louis Andersen
2011-01-07 17:21 ` Alain Frisch
2011-01-07 17:46   ` Christophe Raffalli
2011-01-07 18:11 ` Holger Weiß
2011-01-07 18:52   ` Brian Hurt
2011-01-07 19:32     ` Petter Urkedal
2011-01-07 20:25     ` Eray Ozkural
2011-01-09 16:11     ` Jon Harrop
2011-01-10  6:27       ` Eray Ozkural
2011-01-07 19:17 ` Florian Weimer
     [not found]   ` <AANLkTikxCSQ+0XkOmSVDb3EWq_2oQ0pac3bDgc7f7jq+@mail.gmail.com>
2011-01-07 20:52     ` bluestorm [this message]
2011-01-09 16:15       ` Jon Harrop
2011-01-08  0:26   ` Elias Gabriel Amaral da Silva
2011-01-08  9:28     ` Christophe Raffalli
2011-01-08 22:47     ` Florian Weimer
2011-01-09 10:00       ` Petter Urkedal

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='AANLkTi=GOgfkJ-cZO6oi1ZgdqyfDoRzwLyMLkYsXKoNS@mail.gmail.com' \
    --to=bluestorm.dylc@gmail.com \
    --cc=caml-list@yquem.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).