- Nov 4, 2004On Thu, 4 Nov 2004, andrew cooke wrote:

> That seems easy to do with a reference, but how does it shed light on the

Yes. OCaml is not a pure functional language. It is possible to make a

> relative optimisations for examples 1 and 2? Are you saying that the

> optimisations used depend on whether there are mutable values (which I'm

> sure is true)?

> Or that OCaml only does optimisations that are safe in the

> presence of mutable values (which seems pretty limiting for a functional

> language)?

program compute things in a specified order without difficulties.

And the compiler generally doesn't know which functions perform side

effects.

You can write:

for i = 1 to 100_000_000 do

ignore (1 + 1)

done

This will perform 100 million times the same addition.

These examples have a different semantics:

>> let example1 a b x =

example1 a b just creates an object that is a function that will accept

>> let a' = f1 a in

>> let b' = f2 b in

>> f3 a' b' x

one argument (x) and compute everything after the equal

sign (=)

example1 a b x computes everything after the equal sign

>> let example2 a b =

example2 a b computes everything after the equal sign:

>> let a' = f1 a in

>> let b' = f2 b in

>> fun x -> f3 a' b' x

- f1 a

- f2 b

- builds the function which is returned as a result

example2 a b x is strictly equivalent to

(example2 a b) x which computes the following:

- f1 a

- f2 b

- applies (fun x -> f3 a' b') to x which may not

involve the creation of a specific object

representing the temporary function because it is

applied immediately (that's a possible optimisation)

Note that example1 can be rewritten as:

let example1' a b =

fun x ->

let a' = f1 a in

let b' = f2 b in

f3 a' b' x

example1' a b like before, computes everything after the equal sign,

which only consists in building a function that may even

not exist as a physical object (e.g. if it is applied

immediately).

The following is the example of the counter. It is essential to be sure

when a new counter is created and when not:

[droopy] ~ % ledit ocaml

Objective Caml version 3.08.1

# let make_counter init =

let counter = ref init in

((fun () -> !counter), (fun () -> incr counter));;

val make_counter : int -> (unit -> int) * (unit -> unit) = <fun>

# let (get1, step1) = make_counter 1;;

val get1 : unit -> int = <fun>

val step1 : unit -> unit = <fun>

# let (get2, step2) = make_counter 1;;

val get2 : unit -> int = <fun>

val step2 : unit -> unit = <fun>

# get1 ();;

- : int = 1

# get2 ();;

- : int = 1

# step1 ();;

- : unit = ()

# get1 ();;

- : int = 2

# get2 ();;

- : int = 1

In practice, this kind of things can be useful if a datastructure has to

be initialized, e.g.:

let is_in l =

let tbl = Hashtbl.create (List.length l) in

List.iter (fun aa -> Hashtbl.add tbl aa ()) l;

Hashtbl.mem tbl

let is_in_abc = is_in ['a'; 'b'; 'c']

let is_in_123 = is_in [1; 2; 3; 12; 23; 31; 123; 231; 312]

Martin - << Previous post in topic Next post in topic >>