caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Re: [Caml-list] Function forward declaration?
  2004-04-07 14:15             ` Richard Jones
@ 2002-01-03 15:21               ` Issac Trotts
  2004-04-07 15:51               ` skaller
                                 ` (2 subsequent siblings)
  3 siblings, 0 replies; 35+ messages in thread
From: Issac Trotts @ 2002-01-03 15:21 UTC (permalink / raw)
  To: caml-list

On Wed, Apr 07, 2004 at 03:15:19PM +0100, Richard Jones wrote:
> On Wed, Apr 07, 2004 at 11:52:17PM +1000, skaller wrote:
> > IMHO it isn't forward calling that is broken, 
> > but global variables.
> 
> A somewhat controversial viewpoint ...  While minimising the use of
> global variables might be a theoretical desirable goal, they are very
> useful when you're actually writing real programs under the schedule
> pressure for real users..
> 
> > > and this can be checked by the compiler.
> > 
> > How? *** 
> > 
> > What do you suggest if the compiler
> > is not sure if a variable is initialised or not?
> > Java bans, Felix allows, Ocaml forces the programmer
> > to hack.
> 
> The trouble seems to be that I have a perfectly practical and
> reasonable desire to see prototypes added to the language, because,
> believe it or now, it helps to solve some problems in the Real World.
> Now if there's some deep reason why it's actually impossible I would
> understand, but plenty of other languages (eg. C) seem to have
> prototypes and they get along just fine.

How about this:

# let f g x = g x  (* Pass the function g as an argument. *)
let g x = x*x      (* or whatever. *)
let f = f g        (* Define a fresh f in terms of g and the old f. *)
;;
val g : int -> int = <fun>
val f : int -> int = <fun>
# f 3;;
- : int = 9

> (Same, by the way, goes for a 'return' statement which OCaml is crying
> out for).

If you're looking for clarity, you can use the comment (* return *).  If
it's for flow control, you can raise an exception.

Issac Trotts

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [Caml-list] Function forward declaration?
@ 2004-04-06 12:14 Timo.Tapiola
  2004-04-06 12:20 ` Andrew Birkett
                   ` (4 more replies)
  0 siblings, 5 replies; 35+ messages in thread
From: Timo.Tapiola @ 2004-04-06 12:14 UTC (permalink / raw)
  To: caml-list

Hi,

could someone tell me if there is some way to forward declare functions in
OCaml?

Code example, some parts of code removed:

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

let evaluate_funcall funsig =
	let func = Funspace.get_funref funsig in
		match !func with
				Funct(s, block) -> interpret_block block;
ValNone
;;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

let rec evaluate_expr expr =
	match expr with
			ExpInt(int) 				->
ValInt(int)
		|	ExpFloat(float) 				->
ValFloat(float)
		|	ExpString(str) 				->
ValString(str)
		|	ExpBool(bool) 				->
ValBool(bool)
		|	ExpVar(var) 				-> let
varval = Varspace.get_varvalue var in
	
if varval = ValNone then
	
raise (Interpret_error("Error: variable not declared.\n"))
	
else
	
varval
		|	ExpBinary(ex1, bin, ex2)			->
let value1 = evaluate_expr ex1 in
	
let value2 = evaluate_expr ex2 in
	
evaluate_binary value1 bin value2
		|	ExpUnary(un, ex) 			-> let
value1 = evaluate_expr ex in
	
evaluate_unary un value1
		|	ExpCast(vartype, ex)			-> let value
=  evaluate_expr ex in
	
evaluate_cast vartype value
		|	ExpFunCall(funsig) 			->
evaluate_funcall funsig

;;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

let interpret_phrase phrase =
	match phrase with
			PhrExpression(exp) 	-> evaluate_expr exp; ()
		|	PhrStatement(stmt)	-> interpret_stmt stmt
		|	PhrCommand(cmd) 	-> interpret_cmd cmd;
;;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

let rec interpret_phrases phrases =
	match phrases with
			[] 	-> ()
		|	p::r 	-> interpret_phrase p; interpret_phrases r
;;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

let interpret_block block =
	match block with
			Block([])	 -> ()
		|	Block(phrases)	 -> interpret_phrases phrases
;;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
--------------

Call path starting from function interpret_block:

interpret_block
	interpret_phrases
		interpret_phrase
			interpret_expr
				evaluate_funcall
					interpret_block


How should I deal with this situation if there is no way to forward declare
functions?	

Thanks in advance,
	
	Timo

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
@ 2004-04-06 12:20 ` Andrew Birkett
  2004-04-06 12:37 ` Remi Vanicat
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 35+ messages in thread
From: Andrew Birkett @ 2004-04-06 12:20 UTC (permalink / raw)
  To: caml-list

Timo.Tapiola@tietoenator.com wrote:
> How should I deal with this situation if there is no way to forward declare
> functions?	

You can define mutually recursive functions like this:

let rec foo x = bar x
and bar x = foo x

Andrew

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
  2004-04-06 12:20 ` Andrew Birkett
@ 2004-04-06 12:37 ` Remi Vanicat
  2004-04-06 13:00   ` Issac Trotts
  2004-04-06 12:53 ` Correnson Loïc
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 35+ messages in thread
From: Remi Vanicat @ 2004-04-06 12:37 UTC (permalink / raw)
  To: caml-list

Timo.Tapiola@tietoenator.com writes:

> Hi,
>
> could someone tell me if there is some way to forward declare functions in
> OCaml?

no, but you can :

use the "let rec ... and .. and ... " construct :

let rec simpl1 x y = simpl2 y x
and simpl2 x y = simpl1 y x

or use local function :

let rec simpl1 x y =
  let simpl2 x y = simpl1 y x in
  simpl2 y x

You can even use both technique at the same time.

The third technique is less clean, and is rarely needed : it use
references :

let simpl1_ref = ref (fun x -> assert false)

let simpl2 x y = !simpl1_ref y x
let simpl1 x y = simpl2 x y
let _ = simpl1_ref := simpl1

both two first method cover most of the case, the third one is needed
only in very long code, or in recurrence between compilation unit.

[...]

-- 
Rémi Vanicat

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
  2004-04-06 12:20 ` Andrew Birkett
  2004-04-06 12:37 ` Remi Vanicat
@ 2004-04-06 12:53 ` Correnson Loïc
  2004-04-06 15:14   ` skaller
  2004-04-06 17:39   ` brogoff
  2004-04-06 12:58 ` Jean-Christophe Filliatre
  2004-04-06 17:26 ` Christopher Dutchyn
  4 siblings, 2 replies; 35+ messages in thread
From: Correnson Loïc @ 2004-04-06 12:53 UTC (permalink / raw)
  To: Timo.Tapiola; +Cc: Ocaml

Hi,
Of course you may use mutually recursive functions, but it is not always
easy when you must use forward declarations between different modules. It
would be especially the case when writing complex interpreters (as yours ?).
You may use two tips & trickes to resolve such forward definitions :

a) You can use an extra parameter to handle recursive calls:
    let evaluate_expr eval_fun_rec expr = [...] (** use eval_fun_rec instead
of evaluate_funcall **)
    let evaluate_stmt eval_fun_rec stmt = [...] (** use (evaluate_expr
eval_fun_rec) **)
    let rec evaluate_funcall = [...] evaluate_expr evaluate_funcall
expression [...]

   better: you may pack several callback-functions into a record.
Additionnaly, this technique allow to
    insert *easily* tracing in/out or debuging functions etc.

b) You can also define *real* forward function by using references (already
suggested)
    However, you may loose polymorphism, if any, due to (_a ->_b) ref types.

LC.

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
                   ` (2 preceding siblings ...)
  2004-04-06 12:53 ` Correnson Loïc
@ 2004-04-06 12:58 ` Jean-Christophe Filliatre
  2004-04-06 17:26 ` Christopher Dutchyn
  4 siblings, 0 replies; 35+ messages in thread
From: Jean-Christophe Filliatre @ 2004-04-06 12:58 UTC (permalink / raw)
  To: Timo.Tapiola; +Cc: caml-list


Timo.Tapiola@tietoenator.com writes:
 > 
 > could someone tell me if there is some way to forward declare functions in
 > OCaml?
 > 
 > [...]
 > 
 > How should I deal with this situation if there is no way to forward declare
 > functions?	

Use mutually recursive functions, with syntax

	let rec f x = ...
   
	and g x = ...

	and h x = ...

-- 
Jean-Christophe

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:37 ` Remi Vanicat
@ 2004-04-06 13:00   ` Issac Trotts
  0 siblings, 0 replies; 35+ messages in thread
From: Issac Trotts @ 2004-04-06 13:00 UTC (permalink / raw)
  To: caml-list

On Tue, Apr 06, 2004 at 02:37:11PM +0200, Remi Vanicat wrote:
> Timo.Tapiola@tietoenator.com writes:
> 
> > Hi,
> >
> > could someone tell me if there is some way to forward declare functions in
> > OCaml?
> 
> no, but you can :
> 
> use the "let rec ... and .. and ... " construct :
> 
> let rec simpl1 x y = simpl2 y x
> and simpl2 x y = simpl1 y x
> 
> or use local function :
> 
> let rec simpl1 x y =
>   let simpl2 x y = simpl1 y x in
>   simpl2 y x
> 
> You can even use both technique at the same time.
> 
> The third technique is less clean, and is rarely needed : it use
> references :
> 
> let simpl1_ref = ref (fun x -> assert false)
> 
> let simpl2 x y = !simpl1_ref y x
> let simpl1 x y = simpl2 x y
> let _ = simpl1_ref := simpl1
> 
> both two first method cover most of the case, the third one is needed
> only in very long code, or in recurrence between compilation unit.

This cleaner alternative should cover some of those cases:

    let simpl2 f x y = f y x
    let rec simpl1 x y = simpl2 simpl1 x y

-- 
Issac Trotts
http://mallorn.ucdavis.edu/~ijtrotts
(w) 530-757-8789

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:53 ` Correnson Loïc
@ 2004-04-06 15:14   ` skaller
  2004-04-06 17:39   ` brogoff
  1 sibling, 0 replies; 35+ messages in thread
From: skaller @ 2004-04-06 15:14 UTC (permalink / raw)
  To: Correnson Loïc; +Cc: Timo.Tapiola, Ocaml

On Tue, 2004-04-06 at 22:53, Correnson Loïc wrote:

>    better: you may pack several callback-functions into a record.

You can also use classes. Classes cost a small overhead,
but checking is much heavier: when you fill the slots of
an abstract class type with functions, you do so by
coercing an object to a class type, which checks the
functions have the correct names, as well as the right types.
In addition, the functions are declared together, so the collection
of functions is again more likely to be the right collection
than merely filling slots in a record or tuple...

... quite apart from the functions being able to share state in
a well organised way.

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
                   ` (3 preceding siblings ...)
  2004-04-06 12:58 ` Jean-Christophe Filliatre
@ 2004-04-06 17:26 ` Christopher Dutchyn
  4 siblings, 0 replies; 35+ messages in thread
From: Christopher Dutchyn @ 2004-04-06 17:26 UTC (permalink / raw)
  To: Timo.Tapiola; +Cc: caml-list


I've seen something like this in the ocaml source (cf. typing/typecore.ml):

	let my_fun_ = ref ((fun x -> assert false) : (int -> int));;
	let my_fun = fun x -> !my_fun_ x     (* can't be just !my_fun_ *);;

	(* elsewhere*)
	my_fun_ := (fun x -> x + 1) ;;

	(* elsewhere again *)
	(my_fun 2);;

This breaks the lexical connection that letrec requires, by explicitly
allocating and mutating the reference cell.  In this way, the declaration
and definition can be separated.

Of course, the typechecker can't ensure that you're using my_fun_ only
after it is replaced with it's real value.

Chris D.

On Tue, 6
Apr
2004 Timo.Tapiola@tietoenator.com wrote:

> Hi,
>
> could someone tell me if there is some way to forward declare functions in
> OCaml?
>
> Code example, some parts of code removed:
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> let evaluate_funcall funsig =
> 	let func = Funspace.get_funref funsig in
> 		match !func with
> 				Funct(s, block) -> interpret_block block;
> ValNone
> ;;
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> let rec evaluate_expr expr =
> 	match expr with
> 			ExpInt(int) 				->
> ValInt(int)
> 		|	ExpFloat(float) 				->
> ValFloat(float)
> 		|	ExpString(str) 				->
> ValString(str)
> 		|	ExpBool(bool) 				->
> ValBool(bool)
> 		|	ExpVar(var) 				-> let
> varval = Varspace.get_varvalue var in
>
> if varval = ValNone then
>
> raise (Interpret_error("Error: variable not declared.\n"))
>
> else
>
> varval
> 		|	ExpBinary(ex1, bin, ex2)			->
> let value1 = evaluate_expr ex1 in
>
> let value2 = evaluate_expr ex2 in
>
> evaluate_binary value1 bin value2
> 		|	ExpUnary(un, ex) 			-> let
> value1 = evaluate_expr ex in
>
> evaluate_unary un value1
> 		|	ExpCast(vartype, ex)			-> let value
> =  evaluate_expr ex in
>
> evaluate_cast vartype value
> 		|	ExpFunCall(funsig) 			->
> evaluate_funcall funsig
>
> ;;
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> let interpret_phrase phrase =
> 	match phrase with
> 			PhrExpression(exp) 	-> evaluate_expr exp; ()
> 		|	PhrStatement(stmt)	-> interpret_stmt stmt
> 		|	PhrCommand(cmd) 	-> interpret_cmd cmd;
> ;;
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> let rec interpret_phrases phrases =
> 	match phrases with
> 			[] 	-> ()
> 		|	p::r 	-> interpret_phrase p; interpret_phrases r
> ;;
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> let interpret_block block =
> 	match block with
> 			Block([])	 -> ()
> 		|	Block(phrases)	 -> interpret_phrases phrases
> ;;
>
> ----------------------------------------------------------------------------
> ----------------------------------------------------------------------------
> --------------
>
> Call path starting from function interpret_block:
>
> interpret_block
> 	interpret_phrases
> 		interpret_phrase
> 			interpret_expr
> 				evaluate_funcall
> 					interpret_block
>
>
> How should I deal with this situation if there is no way to forward declare
> functions?
>
> Thanks in advance,
>
> 	Timo
>
> -------------------
> 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
>

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 12:53 ` Correnson Loïc
  2004-04-06 15:14   ` skaller
@ 2004-04-06 17:39   ` brogoff
  2004-04-06 17:53     ` Richard Jones
  1 sibling, 1 reply; 35+ messages in thread
From: brogoff @ 2004-04-06 17:39 UTC (permalink / raw)
  To: Correnson Loïc; +Cc: Timo.Tapiola, Ocaml

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=X-UNKNOWN, Size: 1325 bytes --]

On Tue, 6 Apr 2004, [iso-8859-1] Correnson Loïc wrote:
> b) You can also define *real* forward function by using references (already
> suggested)
>     However, you may loose polymorphism, if any, due to (_a ->_b) ref types.

You may sidestep this issue by rolling your own refs using the explicit
polymorphism on record fields, sketched below:

type fwd_ref = { mutable f : 'a 'b . 'a -> 'b }

module Module1 = struct
  let forward_g = { f = (fun x -> failwith "forward_g") }

  let f = forward_g.f
end

module Module2 = struct
  let g = Module1.f

  let _ = Module1.forward_g.f <- g
end

and of course you can make it as pretty (yeah, I know, dressing up a pig)
as refs if you wish.

There was a discussion of this a looooong time ago, in the context of supporting
polymorphic recursion in the language, and I believe it was mentioned that some
experimental Caml compiler had a forward declaration capability. It seems like a
good idea, and I wonder why it hasn't made it into the language, as this is a
FAQ and a language blemish.

-- Brian

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 17:39   ` brogoff
@ 2004-04-06 17:53     ` Richard Jones
  2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Jones @ 2004-04-06 17:53 UTC (permalink / raw)
  Cc: Ocaml

On Tue, Apr 06, 2004 at 10:39:26AM -0700, brogoff@speakeasy.net wrote:
> There was a discussion of this a looooong time ago, in the context
> of supporting polymorphic recursion in the language, and I believe
> it was mentioned that some experimental Caml compiler had a forward
> declaration capability. It seems like a good idea, and I wonder why
> it hasn't made it into the language, as this is a FAQ and a language
> blemish.

I was wondering this too.  Is there some reason why we couldn't
add a way to do forward declarations, eg:

val g : unit -> int		(* prototype; val is already reserved word *)

let f () = (* ... *) g ()

(* some intervening code which makes it difficult to use let rec ... and *)

let g () = (* ... *) 42		(* compiler checks that g matches proto *)

?  Seems it would preserve type safety.

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
MOD_CAML lets you run type-safe Objective CAML programs inside the Apache
webserver. http://www.merjis.com/developers/mod_caml/

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 17:53     ` Richard Jones
@ 2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
  2004-04-06 22:37         ` Jon Harrop
                           ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Marcin 'Qrczak' Kowalczyk @ 2004-04-06 19:28 UTC (permalink / raw)
  To: caml-list

W liście z wto, 06-04-2004, godz. 18:53 +0100, Richard Jones napisał:

> val g : unit -> int		(* prototype; val is already reserved word *)
> 
> let f () = (* ... *) g ()
> 
> (* some intervening code which makes it difficult to use let rec ... and *)
> 
> let g () = (* ... *) 42		(* compiler checks that g matches proto *)

What would this code do?

   val g : unit -> int
   let f () = g ()
   let x = f ()
   let y = x + 1
   let g () = y

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/


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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
@ 2004-04-06 22:37         ` Jon Harrop
  2004-04-07  2:18         ` skaller
  2004-04-07  6:01         ` Nicolas Cannasse
  2 siblings, 0 replies; 35+ messages in thread
From: Jon Harrop @ 2004-04-06 22:37 UTC (permalink / raw)
  To: caml-list

On Tuesday 06 April 2004 8:28 pm, Marcin 'Qrczak' Kowalczyk wrote:
> ...
> What would this code do?
>
>    val g : unit -> int
>    let f () = g ()
>    let x = f ()
>    let y = x + 1
>    let g () = y

If you could get it to compile, would that not just give the same as:

let rec l1=1::l1 and l2=1::l2 in l1=l2;;

=;-)

Cheers,
Jon.

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
  2004-04-06 22:37         ` Jon Harrop
@ 2004-04-07  2:18         ` skaller
  2004-04-07  6:01         ` Nicolas Cannasse
  2 siblings, 0 replies; 35+ messages in thread
From: skaller @ 2004-04-07  2:18 UTC (permalink / raw)
  To: Marcin 'Qrczak' Kowalczyk; +Cc: caml-list

On Wed, 2004-04-07 at 05:28, Marcin 'Qrczak' Kowalczyk wrote:

> What would this code do?
> 
>    val g : unit -> int
>    let f () = g ()
>    let x = f ()
>    let y = x + 1
>    let g () = y

Executing the equivalent Felix program:
-----------------------
include "std";

fun f () = { return g (); }
val x = f ();
val y:int = x + 1;
fun g () = { return y; }

print x; print " "; print y; endl;
----------------------
[skaller@pelican] ~/links/flx>flx aa
0 1
-----------------------
By luck, y starts at 0 :)


-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
  2004-04-06 22:37         ` Jon Harrop
  2004-04-07  2:18         ` skaller
@ 2004-04-07  6:01         ` Nicolas Cannasse
  2004-04-07  7:31           ` Marcin 'Qrczak' Kowalczyk
  2004-04-07 13:52           ` skaller
  2 siblings, 2 replies; 35+ messages in thread
From: Nicolas Cannasse @ 2004-04-07  6:01 UTC (permalink / raw)
  To: Marcin 'Qrczak' Kowalczyk, caml-list

> val g : unit -> int (* prototype; val is already reserved word *)
>
> let f () = (* ... *) g ()
>
> (* some intervening code which makes it difficult to use let rec ... and
*)
>
> let g () = (* ... *) 42 (* compiler checks that g matches proto *)
>
> What would this code do?
>
>   val g : unit -> int
>   let f () = g ()
>   let x = f ()
>   let y = x + 1
>   let g () = y

What about "compilation error : recursive calls in forward declaration" ?
And what would this code do ?

let f () = while true do () done

That's not because people can write stupid things using any language that
you can forbid them to use some ways of programming. IMHO, function forward
declaration is such a thing : very useful in most of the cases, still
theoricaly broken (as your example show), and this can be checked by the
compiler.

Nicolas Cannasse

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07  6:01         ` Nicolas Cannasse
@ 2004-04-07  7:31           ` Marcin 'Qrczak' Kowalczyk
  2004-04-07 16:40             ` brogoff
  2004-04-07 13:52           ` skaller
  1 sibling, 1 reply; 35+ messages in thread
From: Marcin 'Qrczak' Kowalczyk @ 2004-04-07  7:31 UTC (permalink / raw)
  To: caml-list

W liście z śro, 07-04-2004, godz. 08:01 +0200, Nicolas Cannasse napisał:

> >   val g : unit -> int
> >   let f () = g ()
> >   let x = f ()
> >   let y = x + 1
> >   let g () = y
> 
> What about "compilation error : recursive calls in forward declaration" ?

At which point? What are the correctness criteria in general?

For forward declarations to be useful, they would need to give something
more than let rec. But I don't see a safe subset which is larger than
let rec and doesn't need runtime checking.

(In my language something like the above is legal, even without a
forward declaration. Using g from f does a runtime check that the
definition of g has been already executed. The check is avoided in cases
it's easy to be proven unnecessary, e.g. with mutual recursion between
successive function definitions.)

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/


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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07  6:01         ` Nicolas Cannasse
  2004-04-07  7:31           ` Marcin 'Qrczak' Kowalczyk
@ 2004-04-07 13:52           ` skaller
  2004-04-07 14:15             ` Richard Jones
  2004-04-07 14:24             ` Ville-Pertti Keinonen
  1 sibling, 2 replies; 35+ messages in thread
From: skaller @ 2004-04-07 13:52 UTC (permalink / raw)
  To: Nicolas Cannasse; +Cc: Marcin 'Qrczak' Kowalczyk, caml-list

On Wed, 2004-04-07 at 16:01, Nicolas Cannasse wrote:
> > What would this code do?

> What about "compilation error : recursive calls in forward declaration" ?

That's the whole point of having
forward declarations though  .. :)

> And what would this code do ?
> 
> let f () = while true do () done

It blocks a thread. Not even marginally stupid,
a very common and correct construction at the heart
of every operating system, it even has a name "wait loop".

> IMHO, function forward
> declaration is such a thing : very useful in most of the cases, still
> theoricaly broken (as your example show), 

IMHO it isn't forward calling that is broken, 
but global variables.

> and this can be checked by the compiler.

How? *** 

What do you suggest if the compiler
is not sure if a variable is initialised or not?
Java bans, Felix allows, Ocaml forces the programmer
to hack.

*** This isn't a dumb question. Sophisticated algorithms
can chase down uninitialised values. The question is,
is it sensible in a language to have an error condition
be so elusive that a human can't determine whether
the error will be issued or not?

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 13:52           ` skaller
@ 2004-04-07 14:15             ` Richard Jones
  2002-01-03 15:21               ` Issac Trotts
                                 ` (3 more replies)
  2004-04-07 14:24             ` Ville-Pertti Keinonen
  1 sibling, 4 replies; 35+ messages in thread
From: Richard Jones @ 2004-04-07 14:15 UTC (permalink / raw)
  Cc: caml-list

On Wed, Apr 07, 2004 at 11:52:17PM +1000, skaller wrote:
> IMHO it isn't forward calling that is broken, 
> but global variables.

A somewhat controversial viewpoint ...  While minimising the use of
global variables might be a theoretical desirable goal, they are very
useful when you're actually writing real programs under the schedule
pressure for real users..

> > and this can be checked by the compiler.
> 
> How? *** 
> 
> What do you suggest if the compiler
> is not sure if a variable is initialised or not?
> Java bans, Felix allows, Ocaml forces the programmer
> to hack.

The trouble seems to be that I have a perfectly practical and
reasonable desire to see prototypes added to the language, because,
believe it or now, it helps to solve some problems in the Real World.
Now if there's some deep reason why it's actually impossible I would
understand, but plenty of other languages (eg. C) seem to have
prototypes and they get along just fine.

(Same, by the way, goes for a 'return' statement which OCaml is crying
out for).

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
http://www.winwinsales.co.uk/ - CRM improvement consultancy

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 13:52           ` skaller
  2004-04-07 14:15             ` Richard Jones
@ 2004-04-07 14:24             ` Ville-Pertti Keinonen
  2004-04-07 15:12               ` skaller
  1 sibling, 1 reply; 35+ messages in thread
From: Ville-Pertti Keinonen @ 2004-04-07 14:24 UTC (permalink / raw)
  To: skaller; +Cc: Nicolas Cannasse, Marcin 'Qrczak' Kowalczyk, caml-list


On Apr 7, 2004, at 4:52 PM, skaller wrote:

> On Wed, 2004-04-07 at 16:01, Nicolas Cannasse wrote:
>> And what would this code do ?
>>
>> let f () = while true do () done
>
> It blocks a thread. Not even marginally stupid,
> a very common and correct construction at the heart
> of every operating system, it even has a name "wait loop".

Minor nit - you probably mean "idle thread"...and it really isn't 
currently common in the above form, since most modern CPUs are halted 
when idle (although in some cases - SMP, where the wakeup might come 
from another CPU rather than an interrupt - it might be preferable to 
poll something for better wakeup latency).

> *** This isn't a dumb question. Sophisticated algorithms
> can chase down uninitialised values. The question is,

I'd expect (but haven't attempted to prove) detecting uninitialized 
values to be equivalent to the halting problem, so there would 
inevitably be cases that would need to be rejected, detected at 
run-time or result in unsound programs.

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 14:24             ` Ville-Pertti Keinonen
@ 2004-04-07 15:12               ` skaller
  0 siblings, 0 replies; 35+ messages in thread
From: skaller @ 2004-04-07 15:12 UTC (permalink / raw)
  To: Ville-Pertti Keinonen
  Cc: skaller, Nicolas Cannasse, Marcin 'Qrczak' Kowalczyk, caml-list

On Thu, 2004-04-08 at 00:24, Ville-Pertti Keinonen wrote:
> On Apr 7, 2004, at 4:52 PM, skaller wrote:

> Minor nit - you probably mean "idle thread"...and it really isn't 
> currently common in the above form, since most modern CPUs 

That may be true, but 99% of all real time code is executed
on archaic processors because of the price tag (we're talking
instrumentation and device control and $1 parts here .. )

> I'd expect (but haven't attempted to prove) detecting uninitialized 
> values to be equivalent to the halting problem, so there would 
> inevitably be cases that would need to be rejected, detected at 
> run-time or result in unsound programs.

I suspect you are right for a totally unconstrained
language, whatever that means.

However clearly, this isn't the case for
a constrained language: uninitialised values are impossible
in Ocaml as it stands and any fault is detected immediately
by the parser :D

I don't know the exact algorithm, but Java allows a variable
to be declared without an initialiser, provided it 
is 'manifestly assigned before use'. That condition is
reputedly easy to check by both machine and human.

Of course, Charity guarrantees termination, so with
the constraints it imposes the halting problem itself
is easily solved (it isn't Turing complete).

Perhaps then, your observation needs to be inverted
to a question: what is a reasonable balance between
expressiveness and error trapping?

The Ocaml solution is least expressive, and its STILL
fails to catch all errors because sometimes programs
have to 'cheat' the system by using the wrong type
for a variable, or a wrong value to initialise it,
or even Obj.magic (eg: variable length array cannot
be defined in Ocaml without cheating).

Still, I personally find most code can be organised
so the number of initialisation tricks is quite small
and not too offensive: there is just one I'm aware
of in Felix. 

That particular case isn't a result of the Ocaml language
per se, but its compilation model.

There is a record containing the build number, 
which changes every compilation,
the record is compiled last to avoid full recompile every time,
and so can't be accessed by the rest of the system. 
So an 'uninitialised variable' is used which is compiled first, 
and the last initialisation the program does is to store 
the build number constant into the variable.

That build number is used when Marshalling data,
to allow a check the same version of the binary
creates and reads the data: I don't do any marshalling
during "initialisation" .. :D

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 14:15             ` Richard Jones
  2002-01-03 15:21               ` Issac Trotts
@ 2004-04-07 15:51               ` skaller
  2004-04-07 16:41                 ` Richard Jones
  2004-04-07 16:52               ` Shawn Wagner
  2004-04-07 17:26               ` Basile Starynkevitch
  3 siblings, 1 reply; 35+ messages in thread
From: skaller @ 2004-04-07 15:51 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list

On Thu, 2004-04-08 at 00:15, Richard Jones wrote:
> On Wed, Apr 07, 2004 at 11:52:17PM +1000, skaller wrote:
> > IMHO it isn't forward calling that is broken, 
> > but global variables.
> 
> A somewhat controversial viewpoint ...  While minimising the use of
> global variables might be a theoretical desirable goal, they are very
> useful when you're actually writing real programs under the schedule
> pressure for real users..

This may be the case with a poorly designed program,
or a programmer not practiced in the techniques of
avoiding them. Since people must work with others,
one is bound to run into this problem.

However, if you write your code to be reentrant from
scratch, and do so regularly, you soon learn the
idioms required, and soon enough the benefits
of explicitly passing values around will reward you,
and everyone who works with your code.

At least, that is my experience. I allow myself
to use global variables only for debugging.
And I get a bit annoyed when system software
isn't reentrant -- for example AFAIK Ocamlyacc parsing
engine uses global data, which is very annoying
because I actually have a need for recursive parsing
and I cannot do it: I'm forced to build temporary
data structures to defer the recursion.

> The trouble seems to be that I have a perfectly practical and
> reasonable desire to see prototypes added to the language, because,
> believe it or now, it helps to solve some problems in the Real World.

I'm familiar with the Real World  :D

> Now if there's some deep reason why it's actually impossible I would
> understand, but plenty of other languages (eg. C) seem to have
> prototypes and they get along just fine.

But they don't. There is a tradeoff between static assurance
and expressivity. Ocaml errs on the side of providing stronger
guarrantees at the expense of some loss of expressivity.

I believe that a large class of 'real world' problems
where you would use prototypes can be solved in a slightly
different way, by allowing some limited form of intermodule
recursion.

The Ocaml team is working on that Right Now. The CVS version
of Ocaml supports some intermodule recursion, but only
within a single compilation unit. If that proves successful
I believe the team will start work on extending the facility
to recursion across compilation unit boundaries.

If all goes as one hopes, this should increase the expressivity
of the language: the cost will be that some error checks are
defered to initialisation time. That is a reasonable compromise
since with simple enough initialisation one would expect
a single test to find all errors immediately.

> (Same, by the way, goes for a 'return' statement which OCaml is crying
> out for).

I don't think it makes any sense in Ocaml.

I'd like to explain why, by first explaining that
Felix *does* have an explicit return statement.

In Felix, there is a syntactic distinction between
statements and expressions. There is a semantic
difference too: statements may have side effects,
expressions may not. Within a function, you can
use statements provided the side effects don't
propogate outside the function's closure.

Syntactically, because a function is made up
of imperative statements, there must be an
explicit return statement.

In Ocaml, expressions can have side effects.
So there is no need for a syntactic category
other than expressions for executable code.
So a return statement would be impossible
syntactically, it would have to be a return *expression*.

It is easy to define: here it is:

	let return x = x

and you can use it wherever you want.

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07  7:31           ` Marcin 'Qrczak' Kowalczyk
@ 2004-04-07 16:40             ` brogoff
  0 siblings, 0 replies; 35+ messages in thread
From: brogoff @ 2004-04-07 16:40 UTC (permalink / raw)
  To: caml-list

On Wed, 7 Apr 2004, Marcin 'Qrczak' Kowalczyk wrote:
> W liście z śro, 07-04-2004, godz. 08:01 +0200, Nicolas Cannasse napisał:
>
> > >   val g : unit -> int
> > >   let f () = g ()
> > >   let x = f ()
> > >   let y = x + 1
> > >   let g () = y
> >
> > What about "compilation error : recursive calls in forward declaration" ?
>
> At which point? What are the correctness criteria in general?
>
> For forward declarations to be useful, they would need to give something
> more than let rec.

Cross module recursion would be enough for me. As a way to provide explicit
typing so that OCaml has good support for polymorphic recursion, would be just
dandy too.

As I'm sure you know, your example fails if translation into let rec form on
account of OCaml's restrictions on allowable recursive values.

BTW, the old mail I mentioned is here

	http://caml.inria.fr/caml-list/1059.html

and the context is polymorphic recursion.

-- Brian

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 15:51               ` skaller
@ 2004-04-07 16:41                 ` Richard Jones
  2004-04-07 17:31                   ` Remi Vanicat
                                     ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Richard Jones @ 2004-04-07 16:41 UTC (permalink / raw)
  Cc: caml-list

On Thu, Apr 08, 2004 at 01:51:21AM +1000, skaller wrote:
> > (Same, by the way, goes for a 'return' statement which OCaml is crying
> > out for).
> 
> I don't think it makes any sense in Ocaml.
[...]

This is the sort of thing which I'd like to write.  Note not only the
return statement, but also the regular expression support:

let run dbh q userid =
  if check_permissions userid = Failed then (
    StdPages.error q "Sorry, but you don't have permission to see this";
    return
  );

  let query = q#param "query" in

  if query =~ /^\s*$/ then (
    StdPages.error q "Please enter a query";
    return
  );

  let resource =
    try find_resource dbh query
    with
      Not_found ->
	StdPages.error q "That resource doesn't exist in the database";
        return
    in

  (* Do lots and lots of real processing here. *)


  StdPages.ok q "OK, your query was executed"

-----

That's pseudocode of course, and I'm not saying that it isn't possible
to do this in OCaml already using exceptions, but doing so is very
clumsy compared to having a return statement (and indeed regular
expression support).

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
'There is a joke about American engineers and French engineers. The
American team brings a prototype to the French team. The French team's
response is: "Well, it works fine in practice; but how will it hold up
in theory?"'

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 14:15             ` Richard Jones
  2002-01-03 15:21               ` Issac Trotts
  2004-04-07 15:51               ` skaller
@ 2004-04-07 16:52               ` Shawn Wagner
  2004-04-07 17:26               ` Basile Starynkevitch
  3 siblings, 0 replies; 35+ messages in thread
From: Shawn Wagner @ 2004-04-07 16:52 UTC (permalink / raw)
  To: caml-list

On Wed, Apr 07, 2004 at 03:15:19PM +0100, Richard Jones wrote:
> 
> (Same, by the way, goes for a 'return' statement which OCaml is crying
> out for).

I'd rather see continuations. That gives you return and a whole lot more.

-- 
Shawn Wagner
shawnw@speakeasy.org

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 14:15             ` Richard Jones
                                 ` (2 preceding siblings ...)
  2004-04-07 16:52               ` Shawn Wagner
@ 2004-04-07 17:26               ` Basile Starynkevitch
  2004-04-07 17:46                 ` Marcin 'Qrczak' Kowalczyk
  2004-04-07 18:44                 ` Christopher Dutchyn
  3 siblings, 2 replies; 35+ messages in thread
From: Basile Starynkevitch @ 2004-04-07 17:26 UTC (permalink / raw)
  To: Richard Jones, caml-list

On Wed, Apr 07, 2004 at 03:15:19PM +0100, Richard Jones wrote:
> 
> The trouble seems to be that I have a perfectly practical and
> reasonable desire to see prototypes added to the language, because,
> believe it or now, it helps to solve some problems in the Real World.
> Now if there's some deep reason why it's actually impossible I would
> understand, but plenty of other languages (eg. C) seem to have
> prototypes and they get along just fine.

What I understand you call prototypes are signature items (or I
misunderstood your point). You can have use signatures and modules,
either by compiling both foo.mli & foo.ml (with the prototypes in
foo.mli & the implementations in foo.ml) or by having, inside your
compilation unit, a signature (or module type) and an structure (or
module).


[....]

> (Same, by the way, goes for a 'return' statement which OCaml is crying
> out for).

For your information, the revised syntax (provided by camlp4) does
have (IIRC) a return keyword (but I don't remember more, and I never
used it).


Regarding this thread, a useful trick (somehow a hack, but used in the
compiler itself) is to declare a reference to a function initialised
to a function throwing an exception:

   (** in foo.mli *)

   val rf: (int -> string) ref

   (** in foo.ml *)

   let rf = ref ((fun x -> failwith "rf not yet implemented") 
                : (int -> string))

   (* in a bar.ml *)

   Foo.rf := (fun x -> Printf.sprintf "the real rf %d" x);;

this trick is needed e.g. when two modules are mutually recursive, eg
if a function of foo calls a function of bar which calls the first
function of foo. (In the compiler, you can find such an instance -
Env;check_modtyping_inclusion is a reference to
Includemod.check_modtype_inclusion - in directory caml/typing/ )

Regards.
-- 
Basile STARYNKEVITCH -- basile dot starynkevitch at inria dot fr
Project cristal.inria.fr - INRIA Rocquencourt
http://cristal.inria.fr/~starynke --- all opinions are only mine 

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 16:41                 ` Richard Jones
@ 2004-04-07 17:31                   ` Remi Vanicat
  2004-04-07 17:36                     ` Richard Jones
  2004-04-07 19:27                     ` skaller
  2004-04-07 18:04                   ` Benjamin Geer
  2004-04-07 19:21                   ` skaller
  2 siblings, 2 replies; 35+ messages in thread
From: Remi Vanicat @ 2004-04-07 17:31 UTC (permalink / raw)
  To: caml-list

Richard Jones <rich@annexia.org> writes:

> On Thu, Apr 08, 2004 at 01:51:21AM +1000, skaller wrote:
>> > (Same, by the way, goes for a 'return' statement which OCaml is crying
>> > out for).
>> 
>> I don't think it makes any sense in Ocaml.
> [...]
>
> This is the sort of thing which I'd like to write.  Note not only the
> return statement, but also the regular expression support:
Let do it without return nor exception :


let run dbh q userid =
  if check_permissions userid = Failed then (
    StdPages.error q "Sorry, but you don't have permission to see this"
  ) else
  let query = q#param "query" in

  if query =~ /^\s*$/ then (
    StdPages.error q "Please enter a query"
  ) else

  let resource =
    try find_resource dbh query
    with
      Not_found ->
	StdPages.error q "That resource doesn't exist in the database"
    in

  (* Do lots and lots of real processing here. *)


  StdPages.ok q "OK, your query was executed"

I don't see what is your problem here...

-- 
Rémi Vanicat

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:31                   ` Remi Vanicat
@ 2004-04-07 17:36                     ` Richard Jones
  2004-04-07 17:54                       ` Marcin 'Qrczak' Kowalczyk
  2004-04-07 19:27                     ` skaller
  1 sibling, 1 reply; 35+ messages in thread
From: Richard Jones @ 2004-04-07 17:36 UTC (permalink / raw)
  Cc: caml-list

On Wed, Apr 07, 2004 at 07:31:02PM +0200, Remi Vanicat wrote:
> I don't see what is your problem here...

[I think you missed out some ( ... ) around expressions]

Well the very specific problem is that tuareg-mode doesn't indent like
this.  The indenting probably should reflect the actual structure of
the code.

I have another much more complex example actually which I could post,
but I'm a bit short of time now.  If you want have a look see the
j-london.com/dist/ files login.ml and postform.ml.  These could really
be helped out with the odd 'return' and 'goto'.  Ah, but that would be
considered harmful ...

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
MOD_CAML lets you run type-safe Objective CAML programs inside the Apache
webserver. http://www.merjis.com/developers/mod_caml/

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:26               ` Basile Starynkevitch
@ 2004-04-07 17:46                 ` Marcin 'Qrczak' Kowalczyk
  2004-04-07 18:03                   ` Kenneth Knowles
  2004-04-07 18:44                 ` Christopher Dutchyn
  1 sibling, 1 reply; 35+ messages in thread
From: Marcin 'Qrczak' Kowalczyk @ 2004-04-07 17:46 UTC (permalink / raw)
  To: caml-list

W liście z śro, 07-04-2004, godz. 19:26 +0200, Basile Starynkevitch
napisał:

> Regarding this thread, a useful trick (somehow a hack, but used in the
> compiler itself) is to declare a reference to a function initialised
> to a function throwing an exception:

It's a pity that using such a reference requires explicit "!"·

IMHO it would be nice if OCaml had mutable bindings, using the syntax
analogous to mutable record fields.

   let mutable r = 0 in
   ... r <- r + 1 ...

would be equivalent to

   let r = ref 0 in
   ... r := !r + 1 ...

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/


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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:36                     ` Richard Jones
@ 2004-04-07 17:54                       ` Marcin 'Qrczak' Kowalczyk
  0 siblings, 0 replies; 35+ messages in thread
From: Marcin 'Qrczak' Kowalczyk @ 2004-04-07 17:54 UTC (permalink / raw)
  To: caml-list

W liście z śro, 07-04-2004, godz. 18:36 +0100, Richard Jones napisał:

> Well the very specific problem is that tuareg-mode doesn't indent like
> this.  The indenting probably should reflect the actual structure of
> the code.

I believe "let ... in" and "if ... then ... else" should not necessarily
increase the indentation level, even though syntactically they open a
new level of nesting. It's not Lisp, we don't have an additional ")" to
close at the end :-)

Unfortunately perfect indentation is not automatically deducible from
the list of tokens. The natural OCaml style of finding the right
condition among many:

   if ... then
      ...
   else if ... then
      ...
   else if ... then
      ...
   else
      ...

or with a newline in each "else if" pair, looks better when all branches
are indented the same amount.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/


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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:46                 ` Marcin 'Qrczak' Kowalczyk
@ 2004-04-07 18:03                   ` Kenneth Knowles
  0 siblings, 0 replies; 35+ messages in thread
From: Kenneth Knowles @ 2004-04-07 18:03 UTC (permalink / raw)
  To: caml-list

On Wed, Apr 07, 2004 at 07:46:20PM +0200, Marcin 'Qrczak' Kowalczyk wrote:
> IMHO it would be nice if OCaml had mutable bindings, using the syntax
> analogous to mutable record fields.

That's funny because I kind of feel that mutable fields are a bit of a language
hiccup for performance (I assume it is to save one pointer dereference from
using a reference).  Explicit references are a major strength of O'Caml,
emphasizing non-imperative style.

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 16:41                 ` Richard Jones
  2004-04-07 17:31                   ` Remi Vanicat
@ 2004-04-07 18:04                   ` Benjamin Geer
  2004-04-07 19:21                   ` skaller
  2 siblings, 0 replies; 35+ messages in thread
From: Benjamin Geer @ 2004-04-07 18:04 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list

Richard Jones wrote:
> This is the sort of thing which I'd like to write.

It looks as if using exceptions would simplify your example.  If your 
check_permissions and find_resource functions threw exceptions 
containing error messages (e.g. Failure), you could write:

let run dbh q userid =
   try
     check_permissions userid;
     let query = q#param "query" in
       if is_empty query then
         failwith "Please enter a query"
       else
         let resource =
           try
             find_resource dbh query
           with Not_found ->
             failwith "That resource doesn't exist in the database"
         in
           (* do some work *);
           StdPages.ok q "OK, your query was executed"
   with Failure msg ->
     StdPages.error q msg ;;

Besides being more concise, I think this is an improvement because it 
separates the identification of an error with the way the error is 
reported.  This means that if someday you want to change the way you 
handle errors, you have less code to change; in the version above, there 
is only one line of code that knows about StdPages.error.

(It would perhaps be even better to wrap the calls to StdPages.ok and 
StdPages.error in more generic report_success and report_error 
functions, so that if someday you changed your mind about having a 
single standard error page, or if you decided to implement a completely 
different sort of GUI, e.g. using GTK+, you wouldn't have to change the 
'run' function at all.)

Ben

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:26               ` Basile Starynkevitch
  2004-04-07 17:46                 ` Marcin 'Qrczak' Kowalczyk
@ 2004-04-07 18:44                 ` Christopher Dutchyn
  1 sibling, 0 replies; 35+ messages in thread
From: Christopher Dutchyn @ 2004-04-07 18:44 UTC (permalink / raw)
  To: Basile Starynkevitch; +Cc: Richard Jones, caml-list


On Wed, 7 Apr 2004, Basile Starynkevitch wrote:

> For your information, the revised syntax (provided by camlp4) does
> have (IIRC) a return keyword (but I don't remember more, and I never
> used it).

The return keyword in the revised syntax does not do what Richard wants.
In particular, the revised syntax supports (as deprecated syntax)

	do 1; 2; return 3

as an expression.  Note that return is used solely to mark the terminal
expression in the sequence, not to obtain an early exit.  Specifically,
it allows one to omit the braces from the identical expression:

	do { 1; 2; 3 }

In particular, this doesn't work

	let i = ref 10 in
	while (i.val = 0) do {
		if i.val = 7 then
                   return i.val  (* or blank or anything *)
                else i.val := i.val - 1
        }

Interestingly, the deprecated syntax is not included in the reference and
tutorial manuals for camlp4.

Chris Dutchyn
cdutchyn@cs.ubc.ca

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 16:41                 ` Richard Jones
  2004-04-07 17:31                   ` Remi Vanicat
  2004-04-07 18:04                   ` Benjamin Geer
@ 2004-04-07 19:21                   ` skaller
  2 siblings, 0 replies; 35+ messages in thread
From: skaller @ 2004-04-07 19:21 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list

On Thu, 2004-04-08 at 02:41, Richard Jones wrote:

>   if query =~ /^\s*$/ then (

> (and indeed regular
> expression support).

Regexp support is a different story.

You might look at 'ulex' which provides
in-language  support (including UTF-8
support) strong enough to translate a large
and complex lexer (namely, the Felix lexer).

Since it uses regular definitions and multi branched
matching, it is much more scalable than the weak Perl
technology -- which only handles regexps, cant
do parallel matches, can't handle I18n properly,
and of course is totally unreadable as well as being slow.

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 17:31                   ` Remi Vanicat
  2004-04-07 17:36                     ` Richard Jones
@ 2004-04-07 19:27                     ` skaller
  2004-04-07 20:24                       ` Christopher Dutchyn
  1 sibling, 1 reply; 35+ messages in thread
From: skaller @ 2004-04-07 19:27 UTC (permalink / raw)
  To: Remi Vanicat; +Cc: caml-list

On Thu, 2004-04-08 at 03:31, Remi Vanicat wrote:
> Richard Jones <rich@annexia.org> writes:

> Let do it without return nor exception :
> 
> 
> let run dbh q userid =
>   if check_permissions userid = Failed then (
>     StdPages.error q "Sorry, but you don't have permission to see this"
>   ) else
>   let query = q#param "query" in
> 
>   if query =~ /^\s*$/ then (
>     StdPages.error q "Please enter a query"
>   ) else

> I don't see what is your problem here...

The code you have written works but it is fragile.
A more complex error check might look like this:

	if A then
		if B then error
	;

which disrupts the simple if/then/else chain.

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



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


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Caml-list] Function forward declaration?
  2004-04-07 19:27                     ` skaller
@ 2004-04-07 20:24                       ` Christopher Dutchyn
  0 siblings, 0 replies; 35+ messages in thread
From: Christopher Dutchyn @ 2004-04-07 20:24 UTC (permalink / raw)
  To: skaller; +Cc: Remi Vanicat, caml-list


On Wed, 8 Apr 2004, skaller wrote:

> A more complex error check might look like this:
>
> 	if A then
> 		if B then error
> 	;

Color me naive, but isn't that just

	if A and B then
		error
	else
		...

assuming there's something else to do than check A and B.  Eliding else in
a failwith/throw seems common.


Chris Dutchyn
cdutchyn@cs.ubc.ca

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


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2004-04-07 20:24 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-06 12:14 [Caml-list] Function forward declaration? Timo.Tapiola
2004-04-06 12:20 ` Andrew Birkett
2004-04-06 12:37 ` Remi Vanicat
2004-04-06 13:00   ` Issac Trotts
2004-04-06 12:53 ` Correnson Loïc
2004-04-06 15:14   ` skaller
2004-04-06 17:39   ` brogoff
2004-04-06 17:53     ` Richard Jones
2004-04-06 19:28       ` Marcin 'Qrczak' Kowalczyk
2004-04-06 22:37         ` Jon Harrop
2004-04-07  2:18         ` skaller
2004-04-07  6:01         ` Nicolas Cannasse
2004-04-07  7:31           ` Marcin 'Qrczak' Kowalczyk
2004-04-07 16:40             ` brogoff
2004-04-07 13:52           ` skaller
2004-04-07 14:15             ` Richard Jones
2002-01-03 15:21               ` Issac Trotts
2004-04-07 15:51               ` skaller
2004-04-07 16:41                 ` Richard Jones
2004-04-07 17:31                   ` Remi Vanicat
2004-04-07 17:36                     ` Richard Jones
2004-04-07 17:54                       ` Marcin 'Qrczak' Kowalczyk
2004-04-07 19:27                     ` skaller
2004-04-07 20:24                       ` Christopher Dutchyn
2004-04-07 18:04                   ` Benjamin Geer
2004-04-07 19:21                   ` skaller
2004-04-07 16:52               ` Shawn Wagner
2004-04-07 17:26               ` Basile Starynkevitch
2004-04-07 17:46                 ` Marcin 'Qrczak' Kowalczyk
2004-04-07 18:03                   ` Kenneth Knowles
2004-04-07 18:44                 ` Christopher Dutchyn
2004-04-07 14:24             ` Ville-Pertti Keinonen
2004-04-07 15:12               ` skaller
2004-04-06 12:58 ` Jean-Christophe Filliatre
2004-04-06 17:26 ` Christopher Dutchyn

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