caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: William Lovas <wlovas@stwing.upenn.edu>
To: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] static class member....
Date: Wed, 6 Aug 2003 14:30:53 -0400	[thread overview]
Message-ID: <20030806183052.GA23352@force.stwing.upenn.edu> (raw)
In-Reply-To: <20030806181148.GA30782@davidb.org>

On Wed, Aug 06, 2003 at 11:11:48AM -0700, David Brown wrote:
> On Wed, Aug 06, 2003 at 06:43:30PM +0100, Richard Jones wrote:
> > The question though is why does my example work? Is this a bug
> > in the compiler?
> [...]
> 
> Creating objects of classes is an unusual thing in ocaml, since it is
> like a function application of zero arguments.

Yes, i've just been playing around with it.  It's somewhat instructive to
limit yourself to the core language, and consider instantiation via `new'
to be something like applying a function whose first argument is ().

For a class with no arguments, e.g. something like,

    class foo =
        let counter = ref 0 in
        object
            method next () = incr counter; !counter
        end

the equivalent in the core language might be something like the following
interaction:

    # let new_counter =
        let counter = ref 0 in
        fun () -> fun () -> (incr counter; !counter);;
    val new_counter : unit -> unit -> int = <fun>
    # let count1 = new_counter ();;
    val count1 : unit -> int = <fun>
    # let count2 = new_counter ();;
    val count2 : unit -> int = <fun>
    # count1 ();;
    - : int = 1
    # count2 ();;
    - : int = 2
    # count1 ();;
    - : int = 3

where new_counter's first unit parameter is something like `new'.

But for classes that take arguments, as in

    class foo x =
        let counter = ref 0 in
        object
            method next () = incr counter; !counter
        end

the special initial unit parameter gets lifted up to the top, with the
other argument:

    # let new_counter () x =
        let counter = ref 0 in
        fun () -> (incr counter; !counter);;
    val new_counter : unit -> 'a -> unit -> int = <fun>
    # let count1 = new_counter () "(unused)";;
    val count1 : unit -> int = <fun>
    # let count2 = new_counter () "(unused)";;
    val count2 : unit -> int = <fun>
    # count1 ();;
    - : int = 1
    # count2 ();;
    - : int = 1
    # count1 ();;
    - : int = 2

(Note that the "class parameter" `x' is unused in both examples.)

When translated into this core language representation, it's syntactically
apparent why the counter is local to each "object" in one case and global
to all "objects" in the other -- in the first case, `counter's scope is the
closure that creates new "objects" (which are also closures), while in the
second, it is local to each "object" (each new closure gets its own copy).

Using this knowledge, it's possible to create a class with a parameter that
keeps the counter global to all instances:

    class foo =
        let counter = ref 0 in
        fun x ->
            object
                method next () = incr counter; !counter
            end

Maybe there's a better explanation, but viewed this way, the syntax for
class definitions -- or at least the syntactic sugar -- is somewhat
idiosyncratic.

cheers,
William

-------------------
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


  reply	other threads:[~2003-08-06 18:30 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-06 12:35 [Caml-list] Unix.kill on Win32 James Scott
2003-08-06 12:57 ` [Caml-list] static class member Vovka
2003-08-06 14:45   ` Richard Jones
2003-08-06 14:51     ` David Brown
2003-08-06 15:10       ` Richard Jones
2003-08-06 16:12         ` brogoff
2003-08-06 17:43           ` Richard Jones
2003-08-06 18:11             ` David Brown
2003-08-06 18:30               ` William Lovas [this message]
2003-08-06 18:14             ` Nicolas Cannasse
2003-08-07  0:12           ` Jacques Garrigue
2003-08-07  5:20           ` james woodyatt
2003-08-07 17:02             ` brogoff
2003-08-07 21:53             ` John Max Skaller
2003-08-06 16:24         ` David Brown
2003-08-07  0:21 ` [Caml-list] Unix.kill on Win32 Jacques Garrigue
2003-08-07  0:41   ` Jacques Garrigue
2003-08-08 14:38 [Caml-list] static class member Arturo Borquez

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=20030806183052.GA23352@force.stwing.upenn.edu \
    --to=wlovas@stwing.upenn.edu \
    --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).