List Info

Thread: "ocaml_beginners"::[] Questions about classes




"ocaml_beginners"::[] Questions about classes
country flaguser name
United States
2007-02-21 19:56:50

Two questions about classes and objects in Ocaml:

- The manual says that "Several constructors can be defined ... to
build objects of the same class but with different initialization
patterns". What is the syntax for this? The examples that I've seen
only ever show one set of arguments to a class.

- Is there any way to treat a method as a first-class value? In other
words, is there some way to refer to a method other than after it has
been bound to a particular object? For example, if I have a class Foo
which has a method bar, and I have a list of Foo objects, what would I
pass as the first parameter to map() to get the return value of bar
for each object in the list? I know I could pass in an anonymous
function which just turns around and calls bar on its input, but that
seems awkward and inefficient.

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United Kingdom
2007-02-21 20:21:53

On Thursday 22 February 2007 01:56, Geoffrey Romer wrote:
> Two questions about classes and objects in Ocaml:
>
> - The manual says that "Several constructors can be defined ... to
> build objects of the same class but with different initialization
> patterns". What is the syntax for this? The examples that I've seen
>; only ever show one set of arguments to a class.

How about this: define a class type:

# class type z = object method x : float method y : float end;;
class type z = object method x : float method y : float end

and two functions that create objects of that type:

# let complex_of_rect x y : z = object method x=x method y=y end;;
val complex_of_rect : float -> float -> z = <fun>;
# let complex_of_polar r t : z =
object method x = r *. sin t method y = r *. cos t end;;
val complex_of_polar : float -> float -> z = <fun>;

> - Is there any way to treat a method as a first-class value?

I don't think so.

&gt; In other
> words, is there some way to refer to a method other than after it has
> been bound to a particular object? For example, if I have a class Foo
> which has a method bar, and I have a list of Foo objects, what would I
> pass as the first parameter to map() to get the return value of bar
> for each object in the list? I know I could pass in an anonymous
> function which just turns around and calls bar on its input, but that
>; seems awkward and inefficient.

Like this:

# let bars list = List.map (fun o -> o#bar) list;;
val bars : < bar : 'a; .. > list -> 'a list = <fun>;

That isn't outrageously verbose and, if you're interested in efficiency, then
you shouldn't be using objects as they're very slow in OCaml.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
Germany
2007-02-22 03:12:15

Geoffrey Romer wrote:
&gt;
> Two questions about classes and objects in Ocaml:
&gt;
> - The manual says that "Several constructors can be defined ... to
> build objects of the same class but with different initialization
> patterns&quot;. What is the syntax for this? The examples that I've seen
>; only ever show one set of arguments to a class.
&gt;

like that:
class complex r i = object
method x = (r : float)
method y = (i : float)
end;;

class complex_of_polar r t = complex (r *. sin t) (r *. cos t) ;;

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United States
2007-02-22 08:21:41

A apologize but what is the meaning of "method x = (r : float)&quot;?

How do you read that? More precisely, what's "= (r : float)&quot;?

Thanks, Joel

On Feb 22, 2007, at 9:12 AM, micha wrote:

> like that:
&gt; class complex r i = object
&gt; method x = (r : float)
&gt; method y = (i : float)
&gt; end;;

--
http://wagerlabs.com/

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
France
2007-02-22 08:31:51

HELLO,
LE JEU 22 FéV 2007 14:21:41 CET,
JOEL REYMONT < JOELR1%40GMAIL.COM">JOELR1GMAIL.COM> A éCRIT :

>; THANKS, JOEL
>;
> ON FEB 22, 2007, AT 9:12 AM, MICHA WROTE:
&GT;
> > LIKE THAT:
&GT; > CLASS COMPLEX R I = OBJECT
&GT; > METHOD X = (R : FLOAT)
&GT; > METHOD Y = (I : FLOAT)
&GT; > END;;
&GT; A APOLOGIZE BUT WHAT IS THE MEANING OF "METHOD X = (R : FLOAT)&QUOT;?
>
> HOW DO YOU READ THAT? MORE PRECISELY, WHAT'S "= (R : FLOAT)&QUOT;?
>

THE EXPRESSION '(X: FLOAT)' IS A WAY TO CONSTRAIN THE TYPE OF X
(OTHERWISE, OCAML WOULD COMPLAIN THAT THERE ARE SOME FREE TYPE
VARIABLES IN THIS CLASS). IT WOULD BE EQUIVALENT TO PUT THE CONSTRAINT
AT THE PARAMETER'S LEVEL:
CLASS COMPLEX (R: FLOAT) (I: FLOAT) = OBJECT
METHOD X = R
METHOD Y = I
END

NOW, 'METHOD X = (R: FLOAT)' IS SIMPLY THE DEFINITION OF THE METHOD X
OF THE CLASS COMPLEX.

--
E TUTTO PER OGGI, A LA PROSSIMA VOLTA.
VIRGILE

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
Germany
2007-02-22 08:46:48

Joel Reymont wrote:
&gt;
> A apologize but what is the meaning of "method x = (r : float)&quot;?
>
> How do you read that? More precisely, what's "= (r : float)&quot;?
>

Just to define x and y to be float. I tried the example in the toplevel
and it complains about the unknown type of x and y.
If you use it in a project, mostly this isn't neccessary.

cheers
Michael

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United Kingdom
2007-02-22 09:26:10

On Thursday 22 February 2007 14:21, Joel Reymont wrote:
&gt; A apologize but what is the meaning of "method x = (r : float)&quot;?

Define a method called "x&quot; that returns the value of "r&quot; with a type
annotation saying that "r&quot; is of type float.

It is equivalent to:

class complex (r:float) (i:float) =
method x = r end
...

You can put type annotations just about anywhere in OCaml. Even inside
patterns.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United Kingdom
2007-02-23 15:51:34

On Wed, Feb 21, 2007 at 05:56:50PM -0800, Geoffrey Romer wrote:

To answer this in several stages ...

&gt; - Is there any way to treat a method as a first-class value?

OK, so once it's been bound, it's just a function, as you already
know. The only wrinkle is that if you want to use such methods in
this way, make sure they take at least one argument. If they have no
arguments normally, make sure they take a unit arg:

let o = object
method test () = print_endline "hello"
end ;;

let f = o#test;;
>> val f : unit -> unit = <fun>;

f ();;
>;> hello

> In other words, is there some way to refer to a method other than
>; after it has been bound to a particular object? For example, if I
> have a class Foo which has a method bar, and I have a list of Foo
> objects, what would I pass as the first parameter to map() to get
> the return value of bar for each object in the list? I know I could
&gt; pass in an anonymous function which just turns around and calls bar
> on its input, but that seems awkward and inefficient.

I had to translate this a bit before I understood what you were
talking about

# class foo = object method test () = print_endline "test" end;;
class foo : object method test : unit -> unit end
# let o1 = new foo;;
val o1 : foo = <obj>;
# let o2 = new foo;;
val o2 : foo = <obj>;
# List.iter (fun o -> o#test ()) [o1; o2];;
test
test
- : unit = ()

That's using the anonymous function, which in my opinion is just fine.

There is no "#test" syntax to allow you to do this without the
anonymous function, but you could write your own iterator:

# let rec iter = function [] -> () | o :: os -> o#test (); iter os;;
val iter : < test : unit -> 'a; .. > list -> unit = <fun>;
# iter [o1; o2];;
test
test
- : unit = ()

Note that because of duck typing ("structural subtyping&quot;) iter is
actually defined over a list of any objects which have #test methods,
not merely instances of class foo. (Actually, the same is true of the
anon function above).

Now (and regular readers may wish to look away at this point) it is
also possible to call arbitrary methods on an object at runtime. This
is of course Really Evil, and uses the undocumented CamlinternalOO and
Obj modules which you should never use unless you know what you're
doing.

----------------------------------------------------------
open Printf

class foo =
object
method test1 = printf "method #test1 calledn%!&quot;
method test2 () = printf "method #test2 calledn%!&quot;
method test3 a b = printf "method #test3 called, %d + %d = %dn%!";
a b (a+b)
end

let o = new foo

open CamlinternalOO

let obj_of_object : < .. > -> obj = Obj.magic
let fn_of_closure : closure -> 'a = Obj.magic

let () =
let f = get_public_method (obj_of_object o) (public_method_label "test1") in
(fn_of_closure f : foo -> unit) o;
let f = get_public_method (obj_of_object o) (public_method_label "test2") in
(fn_of_closure f : foo -> unit -> unit) o ();
let f = get_public_method (obj_of_object o) (public_method_label "test3") in
(fn_of_closure f : foo -> int -> int -> unit) o 4 5
----------------------------------------------------------

$ ocamlopt test.ml
$ ./a.out out
method #test1 called
method #test2 called
method #test3 called, 4 + 5 = 9

(There are other problems with this too - for instance I think in very
rare circumstances it may call the wrong method.
http://caml.inria.fr/mantis/view.php?id=3761 )

Rich.

--
Richard Jones
Red Hat UK Limited

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United States
2007-02-23 22:39:19

But won't this produce objects of two different classes- complex and
complex_of_polar?

On 2/22/07, micha < micha-1%40fantasymail.de">micha-1fantasymail.de> wrote:
&gt;
> Geoffrey Romer wrote:
&gt; >
>; > Two questions about classes and objects in Ocaml:
&gt; >
>; > - The manual says that "Several constructors can be defined ... to
> > build objects of the same class but with different initialization
> > patterns&quot;. What is the syntax for this? The examples that I've seen
>; > only ever show one set of arguments to a class.
&gt; >
>;
> like that:
&gt; class complex r i = object
&gt; method x = (r : float)
&gt; method y = (i : float)
&gt; end;;
&gt;
> class complex_of_polar r t = complex (r *. sin t) (r *. cos t) ;;
>
>
>

[Non-text portions of this message have been removed]

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] Questions about classes
country flaguser name
United Kingdom
2007-02-24 02:41:04

On Fri, Feb 23, 2007 at 08:39:19PM -0800, Geoffrey Romer wrote:
&gt; On 2/22/07, micha < micha-1%40fantasymail.de">micha-1fantasymail.de> wrote:
&gt; > class complex r i = object
&gt; > method x = (r : float)
&gt; > method y = (i : float)
&gt; > end;;
&gt; >
>; > class complex_of_polar r t = complex (r *. sin t) (r *. cos t) ;;
>
> But won't this produce objects of two different classes- complex and
> complex_of_polar?

See http://caml.inria.fr/pub/docs/manual-ocaml/manual005.html section
3.1 (and read it closely! -- blink and you'll miss it).

The second statement defining complex_of_polar is a shorthand for:

class complex_of_polar r t =
let r' = r *. sin t in
let i' = r *. cos t in
object
method x = r'
method y = i'
end

Now it doesn't yet look like complex and complex_of_polar have any
relationship to each other. However because of the duck typing going
on, any object which has methods "x&quot; and "y&quot; which return float can be
considered either a complex or a complex_of_polar. There's no real
difference between the two classes because they have the same methods
with the same types. So you can constrain a complex_of_polar into a
complex:

# let o = new complex_of_polar 1. 1.;;
val o : complex_of_polar = <obj>;
# (o : complex);;
- : complex = <obj>;

In fact you can constrain _any_ object which looks similar, eg an
immediate object (immediate objects don't have classes at all):

# let o2 = object method x = 1. method y = 1. end;;
val o2 : < x : float; y : float > = <obj>;
# (o2 : complex);;
- : complex = <obj>;
# (o2 : complex_of_polar);;
- : complex_of_polar = <obj>;

Rich.

--
Richard Jones
Red Hat UK Limited

__._,_.___
.

__,_._,___
[1-10] [11-20] [21-25]

about | contact  Other archives ( Real Estate discussion Medical topics )