Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: A Few Questions
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: oleg@p...
Subject: Re: A Few Questions

Jonathan T Bryant wrote:
> module type AModule = sig type t end
> module type BModule =
>    functor (A : AModule) ->
>       sig
>        type t
>        type s = A.t
>    end
> module S : sig type t end
> module Make = functor (B : BModule) -> S with type t = B.t 

and indeed the last line is problematic: S is a module (aka structure)
rather than a module type (aka signature). The `with type' applies
only to signatures. You have omitted S's body. In full, one would
write
  module S : sig type t end = struct type t = unit end
What is the meaning of `S with type t = B.t' then? The type `t' in S
signature is already associated with unit; we can't replace it with
another type B.t. Imagine if we could write
	module Foo : sig type t val v : t end =
		struct type t = unit let v = () end
	let module Bar = Foo with type t = int
what is the value of Bar.v then?

Incidentally, OCaml does support higher-order functors (that is,
functors can be both arguments and results of other functors). Also,
module signatures (`module type') may be components of structures.

> why isn't this allowed:
> val make : ('a -> 'b) -> ('a -> 'c) -> 
>    sig type t val x : 'a -> 'b val y : 'a -> 'c end
> let make a b = struct
>     type t = int
>     let x = a
>     let y = b
> end
> module X = make (fun x -> x) (fun y -> y)

Hmm, the following

module Make(X: sig val a : 'a -> 'a val b : 'a -> 'a end) :
  sig type t val x : 'a -> 'a val y : 'a -> 'a end =
  struct
    type t = int
    let x = X.a
    let y = X.b
  end;;
module X = Make(struct let a = fun x -> x let b = fun y -> y end);;

seems quite isomorphic to the desideratum, and is accepted by Ocaml. I
assumed that the signature
   val make : ('a -> 'b) -> ('a -> 'c)
has a typo: there are few interesting functions that have the type of 
'a -> 'b (e.g., let rec loop x = loop x and failwith and
Obj.magic). Certainly fun x -> x is not one of them. So, 
	make (fun x -> x) (fun y -> y)
in your code must raise the type error at least for that reason.

> 4) I've found that in sending functions across sockets,
> I can only send them between copies of the exact same binary image.
> Is it possible to marshal functions to different binaries of the same
> code, i.e., different platforms?  Again, does native vs. bytecode make
> a difference?

Different platforms may have different word sizes, different
alignment. Different version of the bytecode programs may be compiled
by ocamlc that has different sets of primitive operations and
pervasives. Your program may contain
	let foo () = Unix.fork ()
now, we serialize the closure 'foo', ship it over to a network pipe
to a windows machine, deserialize and attempt to execute. What the
result would be?

It is far easier for the programmer to defunctionalize the part of his
code that is intended to be mobile.


> 5) Number-parameterized vectors
Matthias Blume has done exactly that, for SML. His technique is
applicable to OCaml. Although the functions like concatenation of
vectors is not expressible as this requires the type system to do
decimal arithmetics. It is possible in Haskell btw, with the
typechecker indeed doing decimal arithmetics.

    Matthias Blume: 
    No-Longer-Foreign: Teaching an ML compiler to speak C ``natively.'' 
    In BABEL'01: First workshop on multi-language infrastructure and
interoperability, September 2001, Firenze, Italy.
    http://people.cs.uchicago.edu/~blume/pub.html

However, we can achieve essentially the same with the simpler means

  http://pobox.com/~oleg/ftp/ML/eliminating-array-bound-check-literally.ml

Actually, we can achieve something more powerful: elimination of array
bound check even if the array is allocated dynamically and its size is
not known till the run-time: see especially the comment by Alain
Frisch at the end of the above file.