caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Brian Hurt <bhurt@spnz.org>
To: Andrej.Bauer@andrej.com
Cc: caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] How important are circular lists/recursive objects?
Date: Wed, 4 Apr 2007 19:28:41 -0400 (EDT)	[thread overview]
Message-ID: <Pine.LNX.4.64.0704041848540.5725@localhost> (raw)
In-Reply-To: <4611FBAB.1020508@fmf.uni-lj.si>



On Tue, 3 Apr 2007, Andrej Bauer wrote:

> Brian Hurt wrote:
>> Does anyone  actually use this construct, and if so, for what?
>
> When I teach my students "theory" of programming languages, we write 
> interpreters for mini languages. The recursive data structures are used to 
> create closures of recursive functions, environments that contain mutually 
> recursive values, closures of objects, etc. Life would be very hard without 
> this feature.

No.  I'm just thinking about circular lists.

It's somewhat off-topic, but here's where I'm comming from.  Imagine a 
language with variant types and Wadler-style views

For those who don't know what Wadler style views, the long intro is:
http://citeseer.ist.psu.edu/wadler86views.html

The short intro is that it's a way to tie new data structures into pattern 
matching.  You could define a new data type, and a new operator on that 
datatype, for example (in pseudo-Ocaml):
 	type 'a t = Cons of 'a * 'a t | Nil;;

 	let cons h t = Cons(h, t);;

 	let decons arg matches doesnt_match =
 		match arg with
 			| Cons(h, t) -> matches h t
 			| Nil -> doesnt_match ()
 	;;

You could then tie the cons and decons functions in with the argument, 
maybe like:

 	define ( ::. ) = cons, decons ;;

so that when the compiler saw the code:

 	match lst with
 		| h ::. t -> expr1
 		| _ -> expr2

it would compile it as:
 	decons lst (fun h t -> expr1) (fun () -> expr2)

Allowing users of your new data structure to pattern match on the data 
structure using the normal operators for that data structure.

As you might guess from the above example, at this point you don't need to 
define lists as a built-in data structure.  You have all the capabilities 
you need to implement lists as a library.  With one, minor, exception- how 
does the compiler handler expressions like:
 	let rec a = 1 ::. 2 ::. a in ...

As that code compiles like:
 	let rec a = cons 1 (cons 2 a) in ...

Ocaml handles this construct because it knows about lists.  But it doesn't 
know about this t data structure.  It could be defined in another module, 
and be an abstract type.  It could have an arbitrarily complicated 
definition.  There is no garuentee in this case that cons doesn't look at 
the argument.  In fact, it'd be perfectly reasonble for t to be an 
implementation of Okasaki's random access lists:
http://citeseer.ist.psu.edu/okasaki95purely.html
at which point the implementation of cons *would* inspect the tail 
argument.

So, the question is: if a (at this point in time entirely hypothetical) 
programming language decided to go this route, and decided to simply 
outlaw self-referential data structures such as circular lists, would this 
be a problem?  Not that recursive and mutually recursive functions would 
still allowed, those are downright necessary.  I'm only thinking 
self-referential data structures.  But the compiler needs to know the 
structure of a closure, for obvious reasons, so the compiler knowing how 
to cheat and "fill in" the closure with the right values after those 
values have been generated isn't a problem.  I've become quite fond of the 
continuation passing style of code recently.

And this probably holds for a lazy thunk as well, especially considering a 
lazy thunk contains a closure (at least initially).

I will note that in Ocaml you can do:
# let rec x = lazy (Lazy.force x);;
val x : 'a Lazy.t = <lazy>
# Lazy.force x;;
Exception: Lazy.Undefined.
#

Simply because it compiles doesn't mean it makes sense, necessarily.

But hopefully this will clarify what I'm asking.

Brian


  parent reply	other threads:[~2007-04-04 23:28 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-02 23:55 Brian Hurt
2007-04-03  6:24 ` Gleb Alexeyev
2007-04-03  6:58 ` [Caml-list] " Ville-Pertti Keinonen
2007-04-03  7:00 ` Andrej Bauer
2007-04-03 12:09   ` Jon Harrop
2007-04-03 13:31     ` Bruno De Fraine
2007-04-04 23:28   ` Brian Hurt [this message]
2007-04-05  0:51     ` Jon Harrop
2007-04-03 12:49 ` Philippe Wang
2007-04-04  3:52 ` Stefan Monnier
2007-04-04  5:28   ` [Caml-list] " skaller
2007-10-04 17:48     ` Fabrice Marchant
2007-10-04 20:39       ` skaller
2007-10-04 21:36         ` rossberg
2007-10-04 22:25           ` skaller
2007-10-05 10:42             ` Dominique Martinet
2007-10-08  9:57             ` Andreas Rossberg
2007-04-04  8:45   ` Don Syme

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=Pine.LNX.4.64.0704041848540.5725@localhost \
    --to=bhurt@spnz.org \
    --cc=Andrej.Bauer@andrej.com \
    --cc=caml-list@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).