caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gerd Stolpmann <Gerd.Stolpmann@darmstadt.netsurf.de>
To: caml-list@inria.fr
Subject: Re: speed versus C
Date: Sun, 10 Oct 1999 18:27:12 +0200	[thread overview]
Message-ID: <99101018244300.30629@ice> (raw)
In-Reply-To: <199910080026.BAA03378@toy.william.bogus>

On Fri, 08 Oct 1999, William Chesters wrote:

>OK, how about this real life example from the Linux kernel:
>
>	error = file->f_op->read(inode,file,buf,count);
>
>Here, `file' is a faked object, with `vtbl' = `f_op' and `this' passed
>in the second argument.  And what is a closure if not an object with
>one method :-) ?  I think this is quite a natural idiom to use, even
>in assembler---especially once one has seen how it can be given a nice
>meaning within a higher level framework like C++ or indeed Caml.

This is exactly what I mean because your example is not as general as a closure
in Caml. As far as I understand, the "f_op" component of "file" contains
pointers to the functions implementing the file operations of the various
filesystems. When the file is opened, these pointers are initialized with the
addresses of the functions of the file system where the file resides. Let me
show the difference to Caml by porting the definitions:

type file_operations =
  { llseek : file -> loff_t -> int -> loff_t;
    read   : file -> buffer -> loff_t -> size_t;
    (* and many others *)
  }
and file =
  { (* among other components: *)
    f_op : file_operations;
  }

When the f_op component is initialized functions are assigned to the "llseek",
"read" and the other components, e.g.

f_op.read <- (fun f b offset -> ... code ...)

Caml is more general because the code defining the function has access to EVERY
variable of the current scope, not only the parameters and global variables.
For example, you could use this to pass additional runtime configurations to
the functions:

let config = ... some value ... in
f_op.read <- (fun f b offset -> ... code accessing 'config' ...)

The value of 'config' is computed at the time the function is assigned, and it
is stored in a private array of implicitly passed parameters such that it is
still available when the function is actually called.

This is a language feature which can always be replaced by simpler
techniques. In this case you can simply extend the "file" struct by an
additional "config" component. 

If you wanted to have a fully general substitute of closures in C (or
assembler), you could do it as follows: For every function store a function
pointer and an array of implicit parameters, e.g.

struct file_operations {
        loff_t (*llseek) (struct file *, loff_t, int);
	void  **llseek_implicit_params;
        ssize_t (*read) (struct file *, char *, size_t, loff_t *);
	void  **read_implicit_params;
	...
}

When the function is assigned, you can now pass implicit parameters by
storing them into the array; in the function definition you can access the
parameters. The point is that every function definition can have its own array
of implicit parameters with its own meaning; to the outer world this is fully
abstract.

There are many reasons not to paraphrase closures as described, most important
you lose all type safety. For almost all situations in which closures would be
adequate it is also possible to make the implicit parameters explicit, and I
think most programmers do so.

In object-oriented languages there is another way of paraphrasing closures.
Define an abstract class with just one method (e.g. "read"); every
implementation of this method is done in subclasses. You can then pass implicit
parameters when the object is created and store them into instance variables.

>(Though I'd argue that's because it sticks to
>abstractions that "ornament" the low-level computational model without
>"obscuring" it :-) .)

I think this is exactly the point where we have different opinions.

Gerd
--
----------------------------------------------------------------------------
Gerd Stolpmann      Telefon: +49 6151 997705 (privat)
Viktoriastr. 100             
64293 Darmstadt     EMail:   Gerd.Stolpmann@darmstadt.netsurf.de (privat)
Germany                     
----------------------------------------------------------------------------




  reply	other threads:[~1999-10-10 20:24 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-10-03 21:35 Jan Brosius
1999-10-04 21:59 ` skaller
1999-10-05 23:22   ` chet
1999-10-06 10:22     ` skaller
1999-10-05 20:20 ` Gerd Stolpmann
1999-10-06 15:21   ` William Chesters
1999-10-06 22:49     ` Gerd Stolpmann
1999-10-07 10:26       ` Michel Quercia
1999-10-07 10:46       ` William Chesters
1999-10-07 15:48         ` Pierre Weis
1999-10-07 19:21         ` Gerd Stolpmann
1999-10-08  0:26           ` William Chesters
1999-10-10 16:27             ` Gerd Stolpmann [this message]
1999-10-10 20:48               ` William Chesters
1999-10-10 23:54                 ` Alain Frisch
1999-10-11 17:58                   ` William Chesters
1999-10-12 14:36                     ` Ocaml Machine (was Re: speed versus C) Alain Frisch
1999-10-12 15:32                       ` David Monniaux
1999-10-12 15:42                         ` Alain Frisch
1999-10-11 19:32                   ` speed versus C John Prevost
1999-10-11 20:50                 ` Gerd Stolpmann
1999-10-12 20:07                   ` skaller
1999-10-08  9:56           ` Pierre Weis
1999-10-07 15:25     ` Markus Mottl
1999-10-07  6:56   ` skaller
1999-10-07 12:37     ` Xavier Urbain
1999-10-07 22:18     ` Gerd Stolpmann
1999-10-08 19:15       ` skaller
1999-10-08 13:40   ` Anton Moscal
1999-10-06  7:58 ` Reply to: " Jens Olsson
1999-10-07 13:00 STARYNKEVITCH Basile
1999-10-08  6:57 Pascal Brisset
     [not found] <Pine.LNX.4.03.9910081713230.31666-100001@post.tepkom.ru>
1999-10-10  4:51 ` skaller
1999-10-11  9:08   ` Anton Moscal
1999-10-12 13:21 Damien Doligez
1999-10-12 20:42 ` skaller

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=99101018244300.30629@ice \
    --to=gerd.stolpmann@darmstadt.netsurf.de \
    --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).