caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] kprintf with user formatters
@ 2004-06-30 16:32 Damien
  2004-07-14 21:10 ` Pierre Weis
  0 siblings, 1 reply; 56+ messages in thread
From: Damien @ 2004-06-30 16:32 UTC (permalink / raw)
  To: Ocaml

Hi,

I am writing a multi-threaded program, so that I need some
synchronization when pretty-printing things :

<<
#directory "+threads";;
#load "unix.cma";;
#load "threads.cma";;
module Debug = struct
  let m = Mutex.create()
  let printf x = 
  Format.kprintf 
    (fun s -> Mutex.lock m; print_endline s; Mutex.unlock m) 
   x
end;;
(*
module Debug :  sig 
  val m: Mutex.t
  val printf : ('a, unit, string, unit) format4 -> 'a 
end
*)
>>

but now, I can't _nicely_ use my previously defined printers :

suppose I have got a type with its toplevel pretty-printer :
<<
type t
val format_t: Format.formatter -> t -> unit
val x: t
>>

I would like to write :
<<
Debug.printf "val t = %a" format_t x
>>

but I cannot since the user printer is expected to be "unit->t->string"
(while it is "formatter->t->unit" for the standard Format.printf "%a")

currently I use :
<<
let (!!) f = (fun () x -> 
  f Format.str_formatter x;
  Format.flush_str_formatter());;
(* val (!!): (Format.formatter -> 'a -> 'b) -> unit -> 'a -> string *)

Debug.printf "val t = %a" !!format_t x
>>

this seems to be working, but I wonder if :
 - there is a better solution
 - this use of the global value "Format.str_formatter" is really
	thread-safe (I would say no...)
 - I missed something
 - printf could not understand a conversion character 'A' that would
	always need a _general_ user-formatter (of type formatter->t->unit)

thanks,
damien

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-06-30 16:32 [Caml-list] kprintf with user formatters Damien
@ 2004-07-14 21:10 ` Pierre Weis
  2004-07-15  0:17   ` Markus Mottl
  0 siblings, 1 reply; 56+ messages in thread
From: Pierre Weis @ 2004-07-14 21:10 UTC (permalink / raw)
  To: Damien; +Cc: caml-list

Hi,

> I am writing a multi-threaded program, so that I need some
> synchronization when pretty-printing things :
[...]
> module Debug = struct
>   let m = Mutex.create()
>   let printf x = 
>   Format.kprintf 
>     (fun s -> Mutex.lock m; print_endline s; Mutex.unlock m) 
>    x
> end;;
> (*
> module Debug :  sig 
>   val m: Mutex.t
>   val printf : ('a, unit, string, unit) format4 -> 'a 
> end
> *)
> 
> but now, I can't _nicely_ use my previously defined printers :
> type t
> val format_t: Format.formatter -> t -> unit
> val x: t
> 
> I would like to write :
> <<
> Debug.printf "val t = %a" format_t x
> >>
> 
> but I cannot since the user printer is expected to be "unit->t->string"
> (while it is "formatter->t->unit" for the standard Format.printf "%a")

Your problem is thus that the function Debug.printf is not the right
one (since it has not the right type :)

Hence, you should use another definition for Debug.printf

 let printf fmt =
   Format.kfprintf (fun ppf -> ()) Format.err_formatter fmt

This way, you get:

printf "%a";;
- : (Format.formatter -> '_a -> unit) -> '_a -> unit = <fun>

as expected.

However, your problem is simpler than that: you just have to define a
custom formatter devoted to your debugging purposes. For instance:

module Debug = struct
   let m = Mutex.create ()
   let out s idx len =
     Mutex.lock m;
     prerr_string (String.sub s idx len); flush stderr;
     Mutex.unlock m
   let flush () = flush stderr
   let dppf = Format.make_formatter out flush
   let printf fmt = Format.fprintf dppf fmt
 end;;

Now you can substitute Debug.printf to any well-typed occurrence of
Format.printf, since we have:

#  Debug.printf;;
- : ('a, Format.formatter, unit) format -> 'a = <fun>
# Format.printf;;
- : ('a, Format.formatter, unit) format -> 'a = <fun>

> currently I use :
>
> let (!!) f = (fun () x -> 
>   f Format.str_formatter x;
>   Format.flush_str_formatter());;
> (* val (!!): (Format.formatter -> 'a -> 'b) -> unit -> 'a -> string *)
> 
> Debug.printf "val t = %a" !!format_t x
>
> this seems to be working, but I wonder if :
>  - there is a better solution

See above: a custom formatter is probably simpler and more elegant.

>  - this use of the global value "Format.str_formatter" is really
> 	thread-safe (I would say no...)

I'm afraid I could not answer for sure to this one: let's say that
using Format.str_formatter is as thread safe as using a Buffer.t value
and the Buffer.add_* functions.

Also, can we consider in the first place that using any printf variant
could be thread safe ? If the answer is no, you would need to stick to
pp_* versions of the basic primitives and this would be a major
modification of your code.

>  - I missed something

May be you missed the fact that Format was designed from the beginning
to support formatting in parallel to user's defined pretty-printing
engines.

>  - printf could not understand a conversion character 'A' that would
> 	always need a _general_ user-formatter (of type formatter->t->unit)

Once more, I cannot answer to this question: I need some time to
figure out what it mean in term of typing (and semantics of printf)...

Tell me if the suggested solution solves your problem.

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-14 21:10 ` Pierre Weis
@ 2004-07-15  0:17   ` Markus Mottl
  2004-07-15  7:30     ` David MENTRE
                       ` (3 more replies)
  0 siblings, 4 replies; 56+ messages in thread
From: Markus Mottl @ 2004-07-15  0:17 UTC (permalink / raw)
  To: Pierre Weis; +Cc: caml-list

On Wed, 14 Jul 2004, Pierre Weis wrote:
> Your problem is thus that the function Debug.printf is not the right
> one (since it has not the right type :)

Btw., since we are at it: I'd like to use my own printers depending on
a conditional, e.g.:

  let log level fmt =
    if may_log level then
      kfprintf ...
    else
      ???

If the given log level "level" does not allow logging the message
specified by "fmt", I just want to ignore the parameters provided together
with "fmt" - but how?  Is there some (safe) trick, or do I have to write
my own Printf/Format-modules?  I don't want to waste computation time
by unnecessarily converting format arguments to strings, which may be
very costly, e.g. when this would mean converting IPs to hostnames, etc.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  0:17   ` Markus Mottl
@ 2004-07-15  7:30     ` David MENTRE
  2004-07-15  7:59       ` Jean-Christophe Filliatre
  2004-07-15  7:39     ` Damien
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 56+ messages in thread
From: David MENTRE @ 2004-07-15  7:30 UTC (permalink / raw)
  To: caml-list

Hello,

Markus Mottl <markus@oefai.at> writes:

> Btw., since we are at it: I'd like to use my own printers depending on
> a conditional, e.g.:
>
>   let log level fmt =
>     if may_log level then
>       kfprintf ...
>     else
>       ???
>
> If the given log level "level" does not allow logging the message
> specified by "fmt", I just want to ignore the parameters provided together
> with "fmt" - but how?

# let cur_level = ref 0;;
val cur_level : int ref = {contents = 0}
# let log level fmt =
  let print_at_level str = if !cur_level >= level then print_string str in
  Format.kprintf print_at_level fmt;;
val log : int -> ('a, unit, string, unit) format4 -> 'a = <fun>

# log 3 "%d %s" 3 "toto";;
- : unit = ()

# cur_level := 4;;
- : unit = ()
# log 3 "%d %s" 3 "toto";;
3 toto- : unit = ()

The trick is to call kprintf as last expression. Thank you to Damien
Doligez: http://caml.inria.fr/archives/200405/msg00355.html

I hope it helps,
Yours,
d.
-- 
 David Mentré <dmentre@linux-france.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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  0:17   ` Markus Mottl
  2004-07-15  7:30     ` David MENTRE
@ 2004-07-15  7:39     ` Damien
  2004-07-15 12:19       ` Markus Mottl
  2004-07-16  6:02       ` Pierre Weis
  2004-07-15 22:20     ` Pierre Weis
  2004-07-16 16:17     ` james woodyatt
  3 siblings, 2 replies; 56+ messages in thread
From: Damien @ 2004-07-15  7:39 UTC (permalink / raw)
  To: caml-list

On Thu, 15 Jul 2004 02:17:58 +0200 Markus Mottl wrote:
> Btw., since we are at it: I'd like to use my own printers depending on
> a conditional, e.g.:
> 
>   let log level fmt =
>     if may_log level then
>       kfprintf ...
>     else
>       ???
> 
> If the given log level "level" does not allow logging the message
> specified by "fmt", I just want to ignore the parameters provided
> together with "fmt" - but how?  Is there some (safe) trick, or do I
> have to write my own Printf/Format-modules?  I don't want to waste
> computation time by unnecessarily converting format arguments to
> strings, which may be very costly, e.g. when this would mean
> converting IPs to hostnames, etc.

I had the same problem a month ago,
I ended with the following ugly function:

let log b fmt = 
  if b then Printf.printf fmt
  else 
    let rec f x = Obj.magic f in 
      f fmt
(* val f: bool -> ('a, out_channel, unit) format -> 'a *)

(I think this is safe since f just eats its arguments, 
 and gets typed with "-rectypes" : ('b->'a) as 'a)

maybe a function "zprintf" could be added to Printf and Format to do
this job ?

regards,
damien

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  7:30     ` David MENTRE
@ 2004-07-15  7:59       ` Jean-Christophe Filliatre
  2004-07-15 23:35         ` henri dubois-ferriere
  0 siblings, 1 reply; 56+ messages in thread
From: Jean-Christophe Filliatre @ 2004-07-15  7:59 UTC (permalink / raw)
  To: David MENTRE; +Cc: caml-list


David MENTRE writes:
 >
 > > If the given log level "level" does not allow logging the message
 > > specified by "fmt", I just want to ignore the parameters provided together
 > > with "fmt" - but how?
 > 
 > # let cur_level = ref 0;;
 > val cur_level : int ref = {contents = 0}
 > # let log level fmt =
 >   let print_at_level str = if !cur_level >= level then print_string str in
 >   Format.kprintf print_at_level fmt;;
 > val log : int -> ('a, unit, string, unit) format4 -> 'a = <fun>

This solution still has the drawback of evaluating the whole message
(which can be costly). 

Damien Pous's post has the expected behavior (printf arguments are
simply discarded without any evaluation) but requires Obj.magic...

-- 
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  7:39     ` Damien
@ 2004-07-15 12:19       ` Markus Mottl
  2004-07-15 12:42         ` Basile Starynkevitch [local]
  2004-07-16  6:02       ` Pierre Weis
  1 sibling, 1 reply; 56+ messages in thread
From: Markus Mottl @ 2004-07-15 12:19 UTC (permalink / raw)
  To: Damien; +Cc: caml-bugs, OCaml

On Thu, 15 Jul 2004, Damien wrote:
> I had the same problem a month ago,
> I ended with the following ugly function:
> 
> let log b fmt = 
>   if b then Printf.printf fmt
>   else 
>     let rec f x = Obj.magic f in 
>       f fmt
> (* val f: bool -> ('a, out_channel, unit) format -> 'a *)
> 
> (I think this is safe since f just eats its arguments, 
>  and gets typed with "-rectypes" : ('b->'a) as 'a)
> 
> maybe a function "zprintf" could be added to Printf and Format to do
> this job ?

Thanks for the hint, this works for me!  I also think that there should be
some kind of "zprintf"-function in the standard library.  Forcing people
to use "-rectypes" or "Obj.magic" is evil.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 12:19       ` Markus Mottl
@ 2004-07-15 12:42         ` Basile Starynkevitch [local]
  2004-07-15 13:45           ` Markus Mottl
  0 siblings, 1 reply; 56+ messages in thread
From: Basile Starynkevitch [local] @ 2004-07-15 12:42 UTC (permalink / raw)
  To: caml-list

On Thu, Jul 15, 2004 at 02:19:47PM +0200, Markus Mottl wrote:
> On Thu, 15 Jul 2004, Damien wrote:
> > I had the same problem a month ago,
> > I ended with the following ugly function:
> > 
> > let log b fmt = 
> >   if b then Printf.printf fmt
> >   else 
> >     let rec f x = Obj.magic f in 
> >       f fmt
> > (* val f: bool -> ('a, out_channel, unit) format -> 'a *)
> > 
> > (I think this is safe since f just eats its arguments, 
> >  and gets typed with "-rectypes" : ('b->'a) as 'a)
> > 
> > maybe a function "zprintf" could be added to Printf and Format to do
> > this job ?

I don't understand what this zprintf function should be, but the above
log proposal behave strangely (and perhaps unsafely) : 

# log false "a=%d s=%S\n%!" 1 "xyz";;
- : unit = <unknown constructor>


For what it's worth, long time ago, I ended writing a camlp4 extension
for a similar logging (or tracing purpose) see file README.trace and
pa_trace.ml of
http://cvs.sourceforge.net/viewcvs.py/poesia/PoesiaSoft/PoesiaMonIcap/

Regards.

-- 
Basile STARYNKEVITCH -- basile dot starynkevitch at inria dot fr
Project cristal.inria.fr - phone +33 1 3963 5197 - mobile 6 8501 2359
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 12:42         ` Basile Starynkevitch [local]
@ 2004-07-15 13:45           ` Markus Mottl
  2004-07-15 14:22             ` Basile Starynkevitch [local]
  2004-07-16  6:17             ` [Caml-list] kprintf with user formatters Pierre Weis
  0 siblings, 2 replies; 56+ messages in thread
From: Markus Mottl @ 2004-07-15 13:45 UTC (permalink / raw)
  To: Basile Starynkevitch [local]; +Cc: caml-list

On Thu, 15 Jul 2004, Basile Starynkevitch [local] wrote:
> I don't understand what this zprintf function should be,

It should parse the format string, and ignore format arguments following
it.

> but the above
> log proposal behave strangely (and perhaps unsafely) : 
> 
> # log false "a=%d s=%S\n%!" 1 "xyz";;
> - : unit = <unknown constructor>

The reason for this is that it returns a function and not a unit value.
Unless you parse the format string, there is no way you can know when
to stop eating arguments to return a value.

I don't think that this hack will be too dangerous.  You might get an
exception 'Invalid_argument "equal: functional value"' if you want to
compare those fancy unit-values, which is about the worst thing you
can achieve.  But who would want to compare unit-values anyway?

> For what it's worth, long time ago, I ended writing a camlp4 extension
> for a similar logging (or tracing purpose) see file README.trace and
> pa_trace.ml of
> http://cvs.sourceforge.net/viewcvs.py/poesia/PoesiaSoft/PoesiaMonIcap/

The preprocessor is not good enough for me.  I would like to change
log levels at runtime, because the application is a server which should
run permanently.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 13:45           ` Markus Mottl
@ 2004-07-15 14:22             ` Basile Starynkevitch [local]
  2004-07-15 14:57               ` Markus Mottl
  2004-07-16  6:47               ` Pierre Weis
  2004-07-16  6:17             ` [Caml-list] kprintf with user formatters Pierre Weis
  1 sibling, 2 replies; 56+ messages in thread
From: Basile Starynkevitch [local] @ 2004-07-15 14:22 UTC (permalink / raw)
  To: caml-list

On Thu, Jul 15, 2004 at 03:45:30PM +0200, Markus Mottl wrote:
> On Thu, 15 Jul 2004, Basile Starynkevitch [local] wrote:
> > I don't understand what this zprintf function should be,
> 
> It should parse the format string, and ignore format arguments following
> it.

let zprintf fmt = Printf.kprintf (fun _ -> ()) fmt
should be ok.

But I think that the format string should not even be parsed. I've got
no solution (except the one below) to this!

> 
> I don't think that this hack will be too dangerous.  You might get an
> exception 'Invalid_argument "equal: functional value"' if you want to
> compare those fancy unit-values, which is about the worst thing you
> can achieve.  But who would want to compare unit-values anyway?
> 
> > For what it's worth, long time ago, I ended writing a camlp4 extension
> > for a similar logging (or tracing purpose) see file README.trace and
> > pa_trace.ml of
> > http://cvs.sourceforge.net/viewcvs.py/poesia/PoesiaSoft/PoesiaMonIcap/
> 
> The preprocessor is not good enough for me.  I would like to change
> log levels at runtime, because the application is a server which should
> run permanently.

The above hack was written with the same requirements, and provide the
possibility to change log levels (or log flags actually).

Actually, I more and more hate printf, both in C and in Ocaml. I
really believe it is a nightmare.

A possible suggestion might be to 
  add a StopPrintf exception to Printf
and
  add a tryprintf function to Printf, which takes a prologue function
as an argument. If the prologue raises an exception, no formatting
occur;  otherwise, tryprintf works like kprintf

-- 
Basile STARYNKEVITCH -- basile dot starynkevitch at inria dot fr
Project cristal.inria.fr - phone +33 1 3963 5197 - mobile 6 8501 2359
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 14:22             ` Basile Starynkevitch [local]
@ 2004-07-15 14:57               ` Markus Mottl
  2004-07-16  6:47               ` Pierre Weis
  1 sibling, 0 replies; 56+ messages in thread
From: Markus Mottl @ 2004-07-15 14:57 UTC (permalink / raw)
  To: Basile Starynkevitch [local]; +Cc: caml-list

On Thu, 15 Jul 2004, Basile Starynkevitch [local] wrote:
> let zprintf fmt = Printf.kprintf (fun _ -> ()) fmt
> should be ok.

This would force string conversion of arguments, which is what I want
to avoid, because some of those computations (user-defined ones) would
just be too costly.

> But I think that the format string should not even be parsed. I've got
> no solution (except the one below) to this!

It has to be if you want to avoid those computations and return a
meaningful value.  But the recursive argument-eating function is ok for
me, too.

> The above hack was written with the same requirements, and provide the
> possibility to change log levels (or log flags actually).

Ok, I see.  This is certainly a way to do it, though it requires
the preprocessor.  It would still be nice to have an efficient, clean
solution without resorting to additional tools.  Thanks, anyway!

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  0:17   ` Markus Mottl
  2004-07-15  7:30     ` David MENTRE
  2004-07-15  7:39     ` Damien
@ 2004-07-15 22:20     ` Pierre Weis
  2004-07-15 23:01       ` Markus Mottl
  2004-07-16 16:17     ` james woodyatt
  3 siblings, 1 reply; 56+ messages in thread
From: Pierre Weis @ 2004-07-15 22:20 UTC (permalink / raw)
  To: Markus Mottl; +Cc: pierre.weis, caml-list

> On Wed, 14 Jul 2004, Pierre Weis wrote:
> > Your problem is thus that the function Debug.printf is not the right
> > one (since it has not the right type :)
> 
> Btw., since we are at it: I'd like to use my own printers depending on
> a conditional, e.g.:
> 
>   let log level fmt =
>     if may_log level then
>       kfprintf ...
>     else
>       ???
> 
> If the given log level "level" does not allow logging the message
> specified by "fmt", I just want to ignore the parameters provided together
> with "fmt" - but how?  Is there some (safe) trick, or do I have to write
> my own Printf/Format-modules?  I don't want to waste computation time
> by unnecessarily converting format arguments to strings, which may be
> very costly, e.g. when this would mean converting IPs to hostnames, etc.

I don't know of any way to safely prevent the arguments of printf from
being converted to string when interpreting the format.

If you tolerate this effect, the problem is still a mere question of
user's defined pretty-printer.

Since you have a if then else, the ``???'' expression should have
exactly the same type as the ``then kfprintf ...'' expression. Hence
the simplest way to do so is to have another kfprintf invocation with
the same format. Evidently you want to redirect the output of this
invocation to /dev/null (I mean you do not want to see its output).

The best way to do so is not to redefine a specialized version of
printf, it is simply to define a specialized pretty printer that would
behave as you want and then to specialize fprintf with it:

let null_formatter =
  let null_out s idx len = () in
  let null_flush = ignore in
  Format.make_formatter null_out null_flush;;

let may_log level = level > 1;;

let log level fmt =
  if may_log level
  then fprintf err_formatter fmt
  else fprintf null_formatter fmt;;

Hope this helps,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 22:20     ` Pierre Weis
@ 2004-07-15 23:01       ` Markus Mottl
  0 siblings, 0 replies; 56+ messages in thread
From: Markus Mottl @ 2004-07-15 23:01 UTC (permalink / raw)
  To: Pierre Weis; +Cc: caml-list

On Fri, 16 Jul 2004, Pierre Weis wrote:
> I don't know of any way to safely prevent the arguments of printf from
> being converted to string when interpreting the format.

This would probably require some changes in the implementation of
Printf/Format.

> Since you have a if then else, the ``???'' expression should have
> exactly the same type as the ``then kfprintf ...'' expression. Hence
> the simplest way to do so is to have another kfprintf invocation with
> the same format. Evidently you want to redirect the output of this
> invocation to /dev/null (I mean you do not want to see its output).

Not only this: I want to prevent any computations associated with
generating output strings.

> The best way to do so is not to redefine a specialized version of
> printf, it is simply to define a specialized pretty printer that would
> behave as you want and then to specialize fprintf with it:
> 
> let null_formatter =
>   let null_out s idx len = () in
>   let null_flush = ignore in
>   Format.make_formatter null_out null_flush;;

This would surely ignore any output, but "null_out" would still be called
with superfluously generated strings.

Anyway, the argument-eating function that makes use of "Obj.magic"
works for me so my problem is solved.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  7:59       ` Jean-Christophe Filliatre
@ 2004-07-15 23:35         ` henri dubois-ferriere
  0 siblings, 0 replies; 56+ messages in thread
From: henri dubois-ferriere @ 2004-07-15 23:35 UTC (permalink / raw)
  To: Jean-Christophe Filliatre; +Cc: David MENTRE, caml-list

any idea how this would compare (performance-wise) to building a closure 
(fun () ->  printf  ...) , and then evaluating the closure only when
the debug level is ok?

henri 


On Thu, 15 Jul 2004 09:59:45 +0200, Jean-Christophe Filliatre
<jean-christophe.filliatre@lri.fr> wrote:
> 
> David MENTRE writes:
>  >
>  > > If the given log level "level" does not allow logging the message
>  > > specified by "fmt", I just want to ignore the parameters provided together
>  > > with "fmt" - but how?
>  >
>  > # let cur_level = ref 0;;
>  > val cur_level : int ref = {contents = 0}
>  > # let log level fmt =
>  >   let print_at_level str = if !cur_level >= level then print_string str in
>  >   Format.kprintf print_at_level fmt;;
>  > val log : int -> ('a, unit, string, unit) format4 -> 'a = <fun>
> 
> This solution still has the drawback of evaluating the whole message
> (which can be costly).
> 
> Damien Pous's post has the expected behavior (printf arguments are
> simply discarded without any evaluation) but requires Obj.magic...
> 
> --
> 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
>

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  7:39     ` Damien
  2004-07-15 12:19       ` Markus Mottl
@ 2004-07-16  6:02       ` Pierre Weis
  2004-07-16  8:42         ` Damien
  2004-07-16 16:52         ` Markus Mottl
  1 sibling, 2 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-16  6:02 UTC (permalink / raw)
  To: Damien; +Cc: caml-list

[...]
> I had the same problem a month ago,
> I ended with the following ugly function:
> 
> let log b fmt = 
>   if b then Printf.printf fmt
>   else 
>     let rec f x = Obj.magic f in 
>       f fmt
> (* val f: bool -> ('a, out_channel, unit) format -> 'a *)
> 
> (I think this is safe since f just eats its arguments, 
>  and gets typed with "-rectypes" : ('b->'a) as 'a)

No, this is not safe: you break the type system and create buggy
values like that.

# let log b fmt = 
    if b then Printf.printf fmt else 
    let rec f x = Obj.magic f in f fmt;;
val log : bool -> ('a, out_channel, unit) format -> 'a = <fun>
# log false "";;
- : unit = <unknown constructor>
# let x = log false "";;
val x : unit = <unknown constructor>
# Marshal.to_string;;
- : 'a -> Marshal.extern_flags list -> string = <fun>
# Marshal.to_string x [];;
Exception: Invalid_argument "output_value: abstract value (outside
heap)".

There is clearly something wrong!

> maybe a function "zprintf" could be added to Printf and Format to do
> this job ?

It is overkill to introduce a new printf function just for that case.

I suggest we try a bit harder to find an acceptable solution without
introducing zprintf :)

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 13:45           ` Markus Mottl
  2004-07-15 14:22             ` Basile Starynkevitch [local]
@ 2004-07-16  6:17             ` Pierre Weis
  2004-07-16 17:14               ` Markus Mottl
  1 sibling, 1 reply; 56+ messages in thread
From: Pierre Weis @ 2004-07-16  6:17 UTC (permalink / raw)
  To: Markus Mottl; +Cc: basile.starynkevitch, caml-list

> On Thu, 15 Jul 2004, Basile Starynkevitch [local] wrote:
> > I don't understand what this zprintf function should be,
> 
> It should parse the format string, and ignore format arguments following
> it.
> 
> > but the above
> > log proposal behave strangely (and perhaps unsafely) : 
> > 
> > # log false "a=%d s=%S\n%!" 1 "xyz";;
> > - : unit = <unknown constructor>
> 
> The reason for this is that it returns a function and not a unit value.
> Unless you parse the format string, there is no way you can know when
> to stop eating arguments to return a value.

That's the debugger view of the problem :)

The Caml compiler's view is simpler: you broke the type system, you
get wrong results!

> I don't think that this hack will be too dangerous.  You might get an
> exception 'Invalid_argument "equal: functional value"' if you want to
> compare those fancy unit-values, which is about the worst thing you
> can achieve.  But who would want to compare unit-values anyway?

I have no time to try and find a way to get a bus error with that one
but I would not be glad to use software based on such a ugly hack that
is not proved harmless in any case.

> > For what it's worth, long time ago, I ended writing a camlp4 extension
> > for a similar logging (or tracing purpose) see file README.trace and
> > pa_trace.ml of
> > http://cvs.sourceforge.net/viewcvs.py/poesia/PoesiaSoft/PoesiaMonIcap/
> 
> The preprocessor is not good enough for me.  I would like to change
> log levels at runtime, because the application is a server which should
> run permanently.

``the application is a server which should run permanently'' ? Wao!
May I suggest no to use Obj.magic too often for this kind of
application ? Especially when you ``don't think that this hack will
be too dangerous'': this hack could kill your server not too permanently!

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15 14:22             ` Basile Starynkevitch [local]
  2004-07-15 14:57               ` Markus Mottl
@ 2004-07-16  6:47               ` Pierre Weis
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
                                   ` (2 more replies)
  1 sibling, 3 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-16  6:47 UTC (permalink / raw)
  To: Basile Starynkevitch [local]; +Cc: caml-list

> On Thu, Jul 15, 2004 at 03:45:30PM +0200, Markus Mottl wrote:
> > On Thu, 15 Jul 2004, Basile Starynkevitch [local] wrote:
> > > I don't understand what this zprintf function should be,
> > 
> > It should parse the format string, and ignore format arguments following
> > it.
> 
> let zprintf fmt = Printf.kprintf (fun _ -> ()) fmt
> should be ok.
> 
> But I think that the format string should not even be parsed. I've got
> no solution (except the one below) to this!

Well, you just need to think functionnally!

If I understand properly:

- you want to skip the runtime time penalty of formatting the
arguments to string before discarding the result,
- you even want not to parse the format string,
- ideally you also want NOT TO EVALUATE the reminding arguments of
your printf call ?

Hmm, this sounds extremely lazy to me; so this suggests thunk
programming; hey, we have that in the language, so let's go!

let log level thunk =
 if may_log level then thunk ();;

...

 log 2 (fun () ->
   eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))

That's the way we use to log in the OcamlP3l compiler: we've got no
runtime penalty if there is no necessity to log. Moreover, this
solution is general enough to accomodate threads, side effects, or
whatever.

To me the (fun () -> ) additional verbosity is not so bad: it clearly
emphasizes that nothing at all is evaluated when logging is unnecessary.

To go beyond that, we would need some help from the language that
would offer some provision for debugging from a special debug keyword,
semantically reminiscent to lazy and assert (as a kind of combined
semantics of both constructs). A compiler flag would then
automatically remove the debugging code (as is done for assert with
the -noassert flag) and the compiler will automatically insert the
(fun () -> ) as it already does in the case of lazy ...

[...]
> Actually, I more and more hate printf, both in C and in Ocaml. I
> really believe it is a nightmare.

Could you elaborate a bit ? We worked hard to provide a clean fully
typed interface to printf and, well ... we like using it :)

We may have missed the point that makes your printf experience ``a
nightmare'', and having information on that could be helpful to
improve the implementation. 

> A possible suggestion might be to 
>   add a StopPrintf exception to Printf
> and
>   add a tryprintf function to Printf, which takes a prologue function
> as an argument. If the prologue raises an exception, no formatting
> occur;  otherwise, tryprintf works like kprintf

I don't think the problem is in printf. The problem is in the way you
call printf (no printf variant could prevent evaluating the format
string and evaluating the arguments of its call: this is mandatory due
to the semantics of the language).

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:47               ` Pierre Weis
@ 2004-07-16  7:13                 ` Jean-Christophe Filliatre
  2004-07-16  7:23                   ` henri dubois-ferriere
                                     ` (2 more replies)
  2004-07-16  7:21                 ` henri dubois-ferriere
  2004-07-16 17:44                 ` Markus Mottl
  2 siblings, 3 replies; 56+ messages in thread
From: Jean-Christophe Filliatre @ 2004-07-16  7:13 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Basile Starynkevitch [local], caml-list


Pierre Weis writes:
 > 
 > If I understand properly:
 > 
 > - you want to skip the runtime time penalty of formatting the
 > arguments to string before discarding the result,
 > - you even want not to parse the format string,
 > - ideally you also want NOT TO EVALUATE the reminding arguments of
 > your printf call ?
 > 
 > Hmm, this sounds extremely lazy to me; so this suggests thunk
 > programming; hey, we have that in the language, so let's go!
 > 
 > let log level thunk =
 >  if may_log level then thunk ();;
 > 
 > ...
 > 
 >  log 2 (fun () ->
 >    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))

I  also  use  the same  kind  of  trick  in  practice, with  a  little
refinement  to avoid  building the  closure. I  introduce higher-order
functions such as

   val if_debug : ('a -> unit) -> 'a -> unit

which behaves  like application  when the debug  flag is on  (and does
nothing otherwise). Then you can simply write

   ...
   if_debug eprintf "this is a message";
   ...

I even introduce variants for functions with more than one argument to
be able to write stuff like

   ...
   if_debug3 eprintf "syntax tree is %a@." print_tree t;
   ...

without addition of parentheses. I still find this very convenient and
not obtrusive as far as style is concerned.

Hope this helps,
-- 
Jean-Christophe Filliâtre (http://www.lri.fr/~filliatr)

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:47               ` Pierre Weis
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
@ 2004-07-16  7:21                 ` henri dubois-ferriere
  2004-07-16 17:44                 ` Markus Mottl
  2 siblings, 0 replies; 56+ messages in thread
From: henri dubois-ferriere @ 2004-07-16  7:21 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Basile Starynkevitch [local], caml-list

> To go beyond that, we would need some help from the language that
> would offer some provision for debugging from a special debug keyword,
> semantically reminiscent to lazy and assert (as a kind of combined
> semantics of both constructs). A compiler flag would then
> automatically remove the debugging code (as is done for assert with
> the -noassert flag) and the compiler will automatically insert the
> (fun () -> ) as it already does in the case of lazy ...

count one person at least who would be very interested in such a feature!!
exactly for this purpose of log messages with varying debug levels.

henri


> 
> [...]
> > Actually, I more and more hate printf, both in C and in Ocaml. I
> > really believe it is a nightmare.
> 
> Could you elaborate a bit ? We worked hard to provide a clean fully
> typed interface to printf and, well ... we like using it :)
> 
> We may have missed the point that makes your printf experience ``a
> nightmare'', and having information on that could be helpful to
> improve the implementation.
> 
> > A possible suggestion might be to
> >   add a StopPrintf exception to Printf
> > and
> >   add a tryprintf function to Printf, which takes a prologue function
> > as an argument. If the prologue raises an exception, no formatting
> > occur;  otherwise, tryprintf works like kprintf
> 
> I don't think the problem is in printf. The problem is in the way you
> call printf (no printf variant could prevent evaluating the format
> string and evaluating the arguments of its call: this is mandatory due
> to the semantics of the language).
> 
> 
> 
> Best regards,
> 
> Pierre Weis
> 
> INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/
> 
> -------------------
> 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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
@ 2004-07-16  7:23                   ` henri dubois-ferriere
  2004-07-16  7:44                     ` Jean-Christophe Filliatre
  2004-07-16 17:56                   ` Markus Mottl
  2004-07-19  9:17                   ` Pierre Weis
  2 siblings, 1 reply; 56+ messages in thread
From: henri dubois-ferriere @ 2004-07-16  7:23 UTC (permalink / raw)
  To: Jean-Christophe Filliatre
  Cc: Pierre Weis, Basile Starynkevitch [local], caml-list

this sounds interesting! could you point us to any available code
showing more of this in practice?

thanks
henri

On Fri, 16 Jul 2004 09:13:20 +0200, Jean-Christophe Filliatre
<jean-christophe.filliatre@lri.fr> wrote:
> 
> Pierre Weis writes:
>  >
>  > If I understand properly:
>  >
>  > - you want to skip the runtime time penalty of formatting the
>  > arguments to string before discarding the result,
>  > - you even want not to parse the format string,
>  > - ideally you also want NOT TO EVALUATE the reminding arguments of
>  > your printf call ?
>  >
>  > Hmm, this sounds extremely lazy to me; so this suggests thunk
>  > programming; hey, we have that in the language, so let's go!
>  >
>  > let log level thunk =
>  >  if may_log level then thunk ();;
>  >
>  > ...
>  >
>  >  log 2 (fun () ->
>  >    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))
> 
> I  also  use  the same  kind  of  trick  in  practice, with  a  little
> refinement  to avoid  building the  closure. I  introduce higher-order
> functions such as
> 
>    val if_debug : ('a -> unit) -> 'a -> unit
> 
> which behaves  like application  when the debug  flag is on  (and does
> nothing otherwise). Then you can simply write
> 
>    ...
>    if_debug eprintf "this is a message";
>    ...
> 
> I even introduce variants for functions with more than one argument to
> be able to write stuff like
> 
>    ...
>    if_debug3 eprintf "syntax tree is %a@." print_tree t;
>    ...
> 
> without addition of parentheses. I still find this very convenient and
> not obtrusive as far as style is concerned.
> 
> Hope this helps,
> --
> Jean-Christophe Filliâtre (http://www.lri.fr/~filliatr)
> 
> 
> 
> -------------------
> 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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  7:23                   ` henri dubois-ferriere
@ 2004-07-16  7:44                     ` Jean-Christophe Filliatre
  0 siblings, 0 replies; 56+ messages in thread
From: Jean-Christophe Filliatre @ 2004-07-16  7:44 UTC (permalink / raw)
  To: henri dubois-ferriere
  Cc: Pierre Weis, Basile Starynkevitch [local], caml-list


henri dubois-ferriere writes:
 > this sounds interesting! could you point us to any available code
 > showing more of this in practice?

Sure: http://why.lri.fr/ (this is a software verification tool)

You'll find many instances of the trick I was describing in src/main.ml

-- 
Jean-Christophe Filliâtre



henri dubois-ferriere writes:
 > On Fri, 16 Jul 2004 09:13:20 +0200, Jean-Christophe Filliatre
 > <jean-christophe.filliatre@lri.fr> wrote:
 > > 
 > > Pierre Weis writes:
 > >  >
 > >  > If I understand properly:
 > >  >
 > >  > - you want to skip the runtime time penalty of formatting the
 > >  > arguments to string before discarding the result,
 > >  > - you even want not to parse the format string,
 > >  > - ideally you also want NOT TO EVALUATE the reminding arguments of
 > >  > your printf call ?
 > >  >
 > >  > Hmm, this sounds extremely lazy to me; so this suggests thunk
 > >  > programming; hey, we have that in the language, so let's go!
 > >  >
 > >  > let log level thunk =
 > >  >  if may_log level then thunk ();;
 > >  >
 > >  > ...
 > >  >
 > >  >  log 2 (fun () ->
 > >  >    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))
 > > 
 > > I  also  use  the same  kind  of  trick  in  practice, with  a  little
 > > refinement  to avoid  building the  closure. I  introduce higher-order
 > > functions such as
 > > 
 > >    val if_debug : ('a -> unit) -> 'a -> unit
 > > 
 > > which behaves  like application  when the debug  flag is on  (and does
 > > nothing otherwise). Then you can simply write
 > > 
 > >    ...
 > >    if_debug eprintf "this is a message";
 > >    ...
 > > 
 > > I even introduce variants for functions with more than one argument to
 > > be able to write stuff like
 > > 
 > >    ...
 > >    if_debug3 eprintf "syntax tree is %a@." print_tree t;
 > >    ...
 > > 
 > > without addition of parentheses. I still find this very convenient and
 > > not obtrusive as far as style is concerned.
 > > 
 > > Hope this helps,
 > > --
 > > Jean-Christophe Filliâtre (http://www.lri.fr/~filliatr)
 > > 
 > > 
 > > 
 > > -------------------
 > > 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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:02       ` Pierre Weis
@ 2004-07-16  8:42         ` Damien
  2004-07-19  9:00           ` Pierre Weis
  2004-07-16 16:52         ` Markus Mottl
  1 sibling, 1 reply; 56+ messages in thread
From: Damien @ 2004-07-16  8:42 UTC (permalink / raw)
  To: caml-list

your CPS solution is fine (except its syntax), 
but I would like to defend my solution...

On Fri, 16 Jul 2004 08:02:27 +0200 (MET DST) Pierre Weis wrote:
> # let log b fmt = 
>     if b then Printf.printf fmt else 
>     let rec f x = Obj.magic f in f fmt;;
> val log : bool -> ('a, out_channel, unit) format -> 'a = <fun>
> # let x = log false "";;
> val x : unit = <unknown constructor>
> # Marshal.to_string x [];;
> Exception: Invalid_argument "output_value: abstract value (outside
> heap)".
> 
> There is clearly something wrong!
then, what about the following :-)
# Marshal.to_string (fun () -> ()) [];;
Exception: Invalid_argument "output_value: abstract value".

> It is overkill to introduce a new printf function just for that case.
maybe...
but it is not to hard to implement (after a quick look at printf.ml)
without the "invalid unit value" problem:

<<
let count fmt = 
  (* this function could be implemented more safely using Printf
     internals*)  
  let s = string_of_format fmt in
  let rec aux a i = 
    match String.unsafe_get s i with
      | '%'  ->
	  (match String.unsafe_get s (i+1) with
	     | '%'  -> aux a (i+2)
	     | '!'  -> aux a (i+2)
	     | 'a'  -> aux (a+2) (i+2)
	     | _    -> aux (a+1) (i+2))
      | '\000'   -> a
      | _    -> aux a (i+1)
  in aux 0 0

let rec eat = function
  | 0 -> Obj.magic ()
  | i -> Obj.magic (fun x -> eat (i-1))

let zprintf (fmt: ('a, _, _, _) format4): 'a = eat (count fmt)

let log b = if b then Printf.printf else zprintf
>>

if (like me), you don't like Obj.magic, please have look at printf.ml...

regards,
damien

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-15  0:17   ` Markus Mottl
                       ` (2 preceding siblings ...)
  2004-07-15 22:20     ` Pierre Weis
@ 2004-07-16 16:17     ` james woodyatt
  3 siblings, 0 replies; 56+ messages in thread
From: james woodyatt @ 2004-07-16 16:17 UTC (permalink / raw)
  To: The Caml Trade

On 14 Jul 2004, at 17:17, Markus Mottl wrote:
> On Wed, 14 Jul 2004, Pierre Weis wrote:
>> Your problem is thus that the function Debug.printf is not the right
>> one (since it has not the right type :)
>
> Btw., since we are at it: I'd like to use my own printers depending on
> a conditional, e.g.:
>
>   let log level fmt =
>     if may_log level then
>       kfprintf ...
>     else
>       ???
>
> If the given log level "level" does not allow logging the message
> specified by "fmt", I just want to ignore the parameters provided 
> together
> with "fmt" - but how?  Is there some (safe) trick, or do I have to 
> write
> my own Printf/Format-modules?  I don't want to waste computation time
> by unnecessarily converting format arguments to strings, which may be
> very costly, e.g. when this would mean converting IPs to hostnames, 
> etc.

The next release of my [Cf] library (due probably sometime this 
weekend) contains the foundation of a flexible diagnostic event 
journaling system, which is inspired by Log4j and various other similar 
systems.

Using just the interface I'm almost ready to release now, the code 
would look like this:

	module J = Cf_journal

	if J.stdout#enabled `Info then
	  J.stdout#info "this is an informational message (x=%d) x

Note: because I plan to build this out to look a lot like Log4j, the 
format and its associated arguments are used to construct an event 
object and the event is sent to visit a list of archivers, each of 
which makes its own decision about how to write the events into their 
respective repositories.  The [#enabled] method can be used to 
short-cut the call to [kprintf] embedded in the journal agent's logging 
methods.  The example above is an example of using the built-in 
[stdout] basic agent, but that's a trivial example.

For debugging messages, I simply made the [#debug] method return [true] 
so that it will be easily used inside [assert] expressions, like so:

	assert (J.stdout#debug "this is a debug message (x=%d)" x)

I know this isn't what you want, but I don't see how there is a good 
way to get what you want.  I generally like the idea of using the 
-noassert compile time option to decide whether to include the code for 
generating console debugging logs.


-- 
j h woodyatt <jhw@wetware.com>
markets are only free to the people who own them.

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:02       ` Pierre Weis
  2004-07-16  8:42         ` Damien
@ 2004-07-16 16:52         ` Markus Mottl
  2004-07-19  9:28           ` Pierre Weis
  1 sibling, 1 reply; 56+ messages in thread
From: Markus Mottl @ 2004-07-16 16:52 UTC (permalink / raw)
  To: Pierre Weis; +Cc: caml-list

On Fri, 16 Jul 2004, Pierre Weis wrote:
> No, this is not safe: you break the type system and create buggy
> values like that.

True, but unit values are not very useful so if the user ignores them
(as usual), there won't be any problems.

> # let log b fmt = 
>     if b then Printf.printf fmt else 
>     let rec f x = Obj.magic f in f fmt;;
> val log : bool -> ('a, out_channel, unit) format -> 'a = <fun>
> # log false "";;
> - : unit = <unknown constructor>
> # let x = log false "";;
> val x : unit = <unknown constructor>
> # Marshal.to_string;;
> - : 'a -> Marshal.extern_flags list -> string = <fun>
> # Marshal.to_string x [];;
> Exception: Invalid_argument "output_value: abstract value (outside
> heap)".
> 
> There is clearly something wrong!

Oh, come on, don't prohibit my use of Obj.magic by demonstrating strange
interactions with the equally unsafe Marshal-module ;-)

Btw., what has happened to generics?  They were said to solve problems
associated with type safety and I/O.  Any intentions to put them into
the experimental CVS-tree of OCaml?

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:17             ` [Caml-list] kprintf with user formatters Pierre Weis
@ 2004-07-16 17:14               ` Markus Mottl
  2004-07-19 10:00                 ` Pierre Weis
  0 siblings, 1 reply; 56+ messages in thread
From: Markus Mottl @ 2004-07-16 17:14 UTC (permalink / raw)
  To: Pierre Weis; +Cc: caml-list

On Fri, 16 Jul 2004, Pierre Weis wrote:
> ``the application is a server which should run permanently'' ? Wao!
> May I suggest no to use Obj.magic too often for this kind of
> application ? Especially when you ``don't think that this hack will
> be too dangerous'': this hack could kill your server not too permanently!

Well, I suppose you don't want to imply that I should refrain from using
modules Printf and Format?  They are full of Obj.magic!  I have definitely
given it some thought whether there could be some kind of unsound use
of return values, but I didn't find anything, because unit-values are
always ignored.

Any other solution I have seen so far is much more complicated: it either
requires the use of a preprocessor, thunking or the use of lazy values
(I had already used them before - very unwieldy) or forces unnecessary
computations even if some action at the current log level shouldn't
be logged.

The only sufficiently efficient, elegant and safe solution would be to
introduce some kind of flag into the fprintf_out function in Printf so
that it doesn't call string conversion functions.  Or provide a dummy
function that just parses the format string and removes arguments.
This way a zprintf-function could be put into the interface.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  6:47               ` Pierre Weis
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
  2004-07-16  7:21                 ` henri dubois-ferriere
@ 2004-07-16 17:44                 ` Markus Mottl
  2004-07-19 10:10                   ` Pierre Weis
  2 siblings, 1 reply; 56+ messages in thread
From: Markus Mottl @ 2004-07-16 17:44 UTC (permalink / raw)
  To: Pierre Weis; +Cc: caml-list

On Fri, 16 Jul 2004, Pierre Weis wrote:
> Hmm, this sounds extremely lazy to me; so this suggests thunk
> programming; hey, we have that in the language, so let's go!
> 
> let log level thunk =
>  if may_log level then thunk ();;
> 
> ...
> 
>  log 2 (fun () ->
>    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))

I have used thunks (and lazy values) before, but they are usually
syntactically ugly.

Instead of:

  log (fun () -> sprintf "%d" n)

I'd rather want to write

  log "%d" n

without having the log function compute a string from an integer if this
is not necessary.  Would this really be so difficult to support?

> That's the way we use to log in the OcamlP3l compiler: we've got no
> runtime penalty if there is no necessity to log.

Well, you have to create a thunk, but this cost is acceptable to me.
I just don't want to clutter my code with thunks + additional sprintf
statements.

> Moreover, this solution is general enough to accomodate threads,
> side effects, or whatever.

You always need mutexes if you want to prevent that your output gets
messed up by multiple threads.

> To me the (fun () -> ) additional verbosity is not so bad: it clearly
> emphasizes that nothing at all is evaluated when logging is unnecessary.

It's rather the other way round: people using format strings may get
the wrong idea that arguments are not converted if there is no output.

> To go beyond that, we would need some help from the language that
> would offer some provision for debugging from a special debug keyword,
> semantically reminiscent to lazy and assert (as a kind of combined
> semantics of both constructs). A compiler flag would then
> automatically remove the debugging code (as is done for assert with
> the -noassert flag) and the compiler will automatically insert the
> (fun () -> ) as it already does in the case of lazy ...

I don't think it is necessary or even useful to introduce new keywords.

A customized, beautiful solution would be possible with camlp4, thunks
solve the problem semantically, but look ugly, and some support for a
kind of zprintf would be ideal :-)

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
  2004-07-16  7:23                   ` henri dubois-ferriere
@ 2004-07-16 17:56                   ` Markus Mottl
  2004-07-19  9:17                   ` Pierre Weis
  2 siblings, 0 replies; 56+ messages in thread
From: Markus Mottl @ 2004-07-16 17:56 UTC (permalink / raw)
  To: OCaml

On Fri, 16 Jul 2004, Jean-Christophe Filliatre wrote:
> I  also  use  the same  kind  of  trick  in  practice, with  a  little
> refinement  to avoid  building the  closure. I  introduce higher-order
> functions such as
> 
>    val if_debug : ('a -> unit) -> 'a -> unit

This actually looks quite nice to me!  Though one needs to add several
functions for varying numbers of arguments, this makes hardly any
difference syntactically, and it is still sufficiently easy to maintain.

On Fri, 16 Jul 2004, Damien wrote:
> > It is overkill to introduce a new printf function just for that case.
> maybe...
> but it is not to hard to implement (after a quick look at printf.ml)
> without the "invalid unit value" problem:

Yes, a change like this in the Printf/Format-implementation was what I
was thinking about.  Just count the number of arguments in the format
and discard them.  This is sufficiently efficient (no allocations)
and convenient.

Regards,
Markus

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  8:42         ` Damien
@ 2004-07-19  9:00           ` Pierre Weis
  0 siblings, 0 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-19  9:00 UTC (permalink / raw)
  To: Damien; +Cc: caml-list

[...]
> > # Marshal.to_string x [];;
> > Exception: Invalid_argument "output_value: abstract value (outside
> > heap)".
> > 
> > There is clearly something wrong!
> then, what about the following :-)
> # Marshal.to_string (fun () -> ()) [];;
> Exception: Invalid_argument "output_value: abstract value".

As you may have guessed this is a completely different problem:
marshalling functions is hard and had always be. It is no surprise we
fail in this case.

On the other hand, the value () is a basic one and had always been
handled properly everywhere in the compiler and runtime: introducing a
strange (if not buggy) behaviour for () is not desirable to say the
least.

> but it is not to hard to implement (after a quick look at printf.ml)
> without the "invalid unit value" problem:

The implementors will never accept to introduce an ``invalid unit
value'' into the standard library. Thanks God, we never did so, and
I'm pretty sure that if we had, the language and the compiler would
not have the quality they have now.

However, your solution does not solve the problem of the useless
evaluation of the arguments of the call to printf. For that, you need
the help of the compiler and a lazy construct and/or a flag of the
compiler to pay nothing when you should not have to pay.

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16  7:13                 ` Jean-Christophe Filliatre
  2004-07-16  7:23                   ` henri dubois-ferriere
  2004-07-16 17:56                   ` Markus Mottl
@ 2004-07-19  9:17                   ` Pierre Weis
  2004-07-19  9:32                     ` Jean-Christophe Filliatre
  2 siblings, 1 reply; 56+ messages in thread
From: Pierre Weis @ 2004-07-19  9:17 UTC (permalink / raw)
  To: Jean-Christophe.Filliatre; +Cc: pierre.weis, basile.starynkevitch, caml-list

[...]
> I  also  use  the same  kind  of  trick  in  practice, with  a  little
> refinement  to avoid  building the  closure. I  introduce higher-order
> functions such as
> 
>    val if_debug : ('a -> unit) -> 'a -> unit
> 
> which behaves  like application  when the debug  flag is on  (and does
> nothing otherwise). Then you can simply write
[...]

This does not solve the problem of evaluating the argument(s) of the logging
application. Consider the example I gave:

>  log 2 (fun () ->
>    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))

Your solution would lead to

 if_debug2 eprintf "Argument 1 is hard to compute %d\n" (ackermann x x)

which wastes is too much computing power when the debug turn out to be
off.

This is not purely rethorical: I already encountered this problem in
practice (the runtime with logging output turned to off was still so
slow that it was impossible to compute the result in a comfortable
time delay; I was obliged to turn the logging facility to the (fun ()
-> ...) style to continue the development).

The solution is the same as for the previous request (``not converting
the arguments to strings before discarding the result''): use a
devoted construct that would change the semantics for this common but
arguably very specific case.

Regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16 16:52         ` Markus Mottl
@ 2004-07-19  9:28           ` Pierre Weis
  0 siblings, 0 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-19  9:28 UTC (permalink / raw)
  To: Markus Mottl; +Cc: pierre.weis, caml-list

[...]

> > # log false "";;
> > - : unit = <unknown constructor>
[...]
> > There is clearly something wrong!
> 
> Oh, come on, don't prohibit my use of Obj.magic by demonstrating strange
> interactions with the equally unsafe Marshal-module ;-)

I cannot and would not like to prohibit your uses of Obj.magic. Go on
if you dare. I just pointed out that this particular use of Obj.magic
created a value that is considered by the Caml system as an ``<unknown
constructor>'': a value that breaks the compiler invariant so deeply
that it cannot print it. This is a bad property that could eventually
bit your program and crash it.

> Btw., what has happened to generics?  They were said to solve problems
> associated with type safety and I/O.  Any intentions to put them into
> the experimental CVS-tree of OCaml?

That's still something to do...

Regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-19  9:17                   ` Pierre Weis
@ 2004-07-19  9:32                     ` Jean-Christophe Filliatre
  0 siblings, 0 replies; 56+ messages in thread
From: Jean-Christophe Filliatre @ 2004-07-19  9:32 UTC (permalink / raw)
  To: Pierre Weis; +Cc: basile.starynkevitch, caml-list


Pierre Weis writes:
 > 
 > This does not solve the problem of evaluating the argument(s) of the logging
 > application. Consider the example I gave:
 > 
 > >  log 2 (fun () ->
 > >    eprintf "Argument 1 is hard to compute %d\n" (ackermann x x))
 > 
 > Your solution would lead to
 > 
 >  if_debug2 eprintf "Argument 1 is hard to compute %d\n" (ackermann x x)
 > 
 > which wastes is too much computing power when the debug turn out to be
 > off.

This is indeed  right, in the general case. However the  way I use it,
all  the computation  is  always  within a  function  being the  first
argument of a printf %a, and  thus not evaluated (as in the print_tree
example I gave).

-- 
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16 17:14               ` Markus Mottl
@ 2004-07-19 10:00                 ` Pierre Weis
  0 siblings, 0 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-19 10:00 UTC (permalink / raw)
  To: Markus Mottl; +Cc: pierre.weis, caml-list

[...]
> Well, I suppose you don't want to imply that I should refrain from using
> modules Printf and Format?  They are full of Obj.magic!

I certainly not want to imply that you should refrain from using
Printf, Format, Scanf, and also the ocaml interactive system,
given that they all use Obj.magic.

However, all those uses of Obj.magic have a strong theoretical
justification. In the best case they have been proved to be perfectly sound.

In any case, we certainly never have a proof that some of those
Obj.magic uses can lead to a wrong value (as a closure supposed to
have type unit would be).

> I have definitely given it some thought whether there could be some
> kind of unsound use of return values, but I didn't find anything,
> because unit-values are always ignored.

Thank you for given some thought about unsound use of Obj.magic on the
compiler. If you ever discover one (out of Marshall), please let us
know, we will be glad to modify it :)

However, I'm glad that you ``didn't find anything''. I should say that
this is not, as you guessed, ``because unit-values are always
ignored'': the reason is more likely to be that we always have strong
evidence that those Obj.magic occurrences are harmless and extremely
hard to eliminate.

> Any other solution I have seen so far is much more complicated: it either
> requires the use of a preprocessor, thunking or the use of lazy values
> (I had already used them before - very unwieldy) or forces unnecessary
> computations even if some action at the current log level shouldn't
> be logged.
> 
> The only sufficiently efficient, elegant and safe solution would be to
> introduce some kind of flag into the fprintf_out function in Printf so
> that it doesn't call string conversion functions.  Or provide a dummy
> function that just parses the format string and removes arguments.
> This way a zprintf-function could be put into the interface.

Once more you do not solve the problem of arguments useless
evaluation. I'm convinced that the more elegant way is to introduce
some support for logging into the system.

Regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-16 17:44                 ` Markus Mottl
@ 2004-07-19 10:10                   ` Pierre Weis
  2004-07-19 10:43                     ` Jon Harrop
  0 siblings, 1 reply; 56+ messages in thread
From: Pierre Weis @ 2004-07-19 10:10 UTC (permalink / raw)
  To: Markus Mottl; +Cc: pierre.weis, caml-list

[...]
> > Moreover, this solution is general enough to accomodate threads,
> > side effects, or whatever.
> 
> You always need mutexes if you want to prevent that your output gets
> messed up by multiple threads.

Using thunks, the mutex handling can be done into the log function
around the tunk call.

> > To me the (fun () -> ) additional verbosity is not so bad: it clearly
> > emphasizes that nothing at all is evaluated when logging is unnecessary.
> 
> It's rather the other way round: people using format strings may get
> the wrong idea that arguments are not converted if there is no output.

They also can have the wrong idea that arguments are not evaluated
(since there is no need to convert them to string) which is wrong.

[...]
> I don't think it is necessary or even useful to introduce new keywords.

You are right in general, but in this case we have to deal with a
notion that should change the evaluation regime of some
expressions. This cannot be implemented without the help of the
compiler.

> A customized, beautiful solution would be possible with camlp4, thunks
> solve the problem semantically, but look ugly,

That why I propose to use something similar to assert and lazy: to get
a simple way to express this semantics.

> and some support for a kind of zprintf would be ideal :-)

I'm afraid this would not solve the lazyness problem.

Regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-19 10:10                   ` Pierre Weis
@ 2004-07-19 10:43                     ` Jon Harrop
  2004-07-21 15:52                       ` Pierre Weis
  0 siblings, 1 reply; 56+ messages in thread
From: Jon Harrop @ 2004-07-19 10:43 UTC (permalink / raw)
  To: caml-list

On Monday 19 July 2004 11:10, Pierre Weis wrote:
> They also can have the wrong idea that arguments are not evaluated
> (since there is no need to convert them to string) which is wrong.

Forgive me if this is irrelevant (I've failed to understand all of your 
discussion) but can this be tied in with a general way to define functions 
with specified argument evaluation, e.g. to define your own, short-circuit-
evaluated && operator:

# (print_endline "1"; false) && (print_endline "2"; true);;
1
- : bool = false
# let (&&) a b = a && b;;
val ( && ) : bool -> bool -> bool = <fun>
# (print_endline "1"; false) && (print_endline "2"; true);;
2
1
- : bool = false

Not that I need such a thing...

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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-19 10:43                     ` Jon Harrop
@ 2004-07-21 15:52                       ` Pierre Weis
  2004-07-21 17:43                         ` lazyness in ocaml (was : [Caml-list] kprintf with user formatters) Daniel Bünzli
                                           ` (2 more replies)
  0 siblings, 3 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-21 15:52 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

> On Monday 19 July 2004 11:10, Pierre Weis wrote:
> > They also can have the wrong idea that arguments are not evaluated
> > (since there is no need to convert them to string) which is wrong.
> 
> Forgive me if this is irrelevant (I've failed to understand all of your 
> discussion) but can this be tied in with a general way to define functions 
> with specified argument evaluation, e.g. to define your own, short-circuit-
> evaluated && operator:
> 
> # (print_endline "1"; false) && (print_endline "2"; true);;
> 1
> - : bool = false
> # let (&&) a b = a && b;;
> val ( && ) : bool -> bool -> bool = <fun>
> # (print_endline "1"; false) && (print_endline "2"; true);;
> 2
> 1
> - : bool = false
> 
> Not that I need such a thing...
> 
> Cheers,
> Jon.

Yes this remark is completely relevant: the built-in && and ||
operators and the if then else construct (considered as a 3 places
operator) are the only lazy constructs of the language. Well we now
have another extra lazy construction that allows lazy evaluation, as
in:

let x = lazy (print_string "toto");;
val x : unit lazy_t = <lazy>

Lazy.force x;;
toto- : unit = ()

So we could imagine a lazy version of printf that only accepts 'a
lazy_t arguments and would have to force their evaluation to print
them. This way, a global flag may ask lazyprintf to skip
everything. The drawback is that you would have to write (lazy expr)
for each argument ``expr'' to be printed. Quite a bit intrusive, I think.

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-21 15:52                       ` Pierre Weis
@ 2004-07-21 17:43                         ` Daniel Bünzli
  2004-07-22 16:28                           ` Pierre Weis
  2004-07-21 20:41                         ` [Caml-list] kprintf with user formatters Jon Harrop
  2004-07-22  8:05                         ` [Caml-list] wait instruction lehalle@miriad
  2 siblings, 1 reply; 56+ messages in thread
From: Daniel Bünzli @ 2004-07-21 17:43 UTC (permalink / raw)
  To: caml-list


Le 21 juil. 04, à 17:52, Pierre Weis a écrit :

> The drawback is that you would have to write (lazy expr)
> for each argument ``expr'' to be printed. Quite a bit intrusive, I 
> think.
I agree. I once tried to port some haskell combinators [1] to ocaml. 
However I had to stop since using them meant cluttering your code with 
(lazy e) and lead to unreadable code.

A more lightweight notation would be needed in order to do real lazy 
programming in ocaml. At that time I wondered if specifiying the 
lazyness when one defines the function and not when one uses it would 
be a problem (I mean a technical problem, not an ideological one).
For example if one defines

let f (lazy x) = ...

then the application f (x + y) would implicitely mean f (lazy (x + y)). 
Alternatively something less intrusive than the keyword 'lazy' would be 
good.

Daniel

[1] <http://doi.acm.org/10.1145/944705.944727>

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-21 15:52                       ` Pierre Weis
  2004-07-21 17:43                         ` lazyness in ocaml (was : [Caml-list] kprintf with user formatters) Daniel Bünzli
@ 2004-07-21 20:41                         ` Jon Harrop
  2004-07-22 15:39                           ` Pierre Weis
  2004-07-22  8:05                         ` [Caml-list] wait instruction lehalle@miriad
  2 siblings, 1 reply; 56+ messages in thread
From: Jon Harrop @ 2004-07-21 20:41 UTC (permalink / raw)
  To: caml-list

On Wednesday 21 July 2004 16:52, Pierre Weis wrote:
> Yes this remark is completely relevant:

I knew it. ;-)

> the built-in && and || 
> operators and the if then else construct (considered as a 3 places
> operator) are the only lazy constructs of the language.

Is "match pred with true -> expr1 | false -> expr2" not equivalent to "if pred 
then expr1 else expr2"? If so, isn't pattern matching a fourth lazy 
construct?

Just after I wrote that last post I realised that this approach could actually 
be useful in numerical contexts. As a trivial example, integer multiply could 
lazily evaluate its second argument (only when it is pure, if conventional 
semantics are to be preserved), not needing it if the first argument is zero. 
This may be useful in more complicated settings, i.e. when dealing with data 
structures rather than primitive types and when predicates over the data 
structure can be evaluated much more quickly than the corresponding 
expression.

Such functionality can, of course, be implemented in vanilla OCaml. But I'd 
like to see a language which allowed mathematics to be expressed in a 
notation as close to conventional written form as possible (although I prefer 
type distinctions, like "+" vs "+.") whilst retaining efficiency (I'd also 
like to see deforesting, e.g. in vector expressions without having to resort 
to maps, folds etc.).

Perhaps an OCaml -> OCaml optimising compiler would be a good project for 
someone? That way implementation details and their benefits can be examined 
without having to touch the OCaml compilers. I think it could be quite fun to 
play with such a thing...

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] 56+ messages in thread

* [Caml-list] wait instruction
  2004-07-21 15:52                       ` Pierre Weis
  2004-07-21 17:43                         ` lazyness in ocaml (was : [Caml-list] kprintf with user formatters) Daniel Bünzli
  2004-07-21 20:41                         ` [Caml-list] kprintf with user formatters Jon Harrop
@ 2004-07-22  8:05                         ` lehalle@miriad
  2004-07-22  8:40                           ` Olivier Andrieu
  2004-07-22 10:33                           ` Vitaly Lugovsky
  2 siblings, 2 replies; 56+ messages in thread
From: lehalle@miriad @ 2004-07-22  8:05 UTC (permalink / raw)
  To: caml-list

Hi,

I want a function that allow my code to wait for m milliseconds before  
continuing, and I need a cross-platform function (win and linux) to perfom  
that. any idea ?

thanks,
charles

-- 
Charles-Albert Lehalle --- MIRIAD Technologies
Responsable Développements Algorithmiques et Applications
mailto:charles.lehalle@miriadtech.com
keyserver: http://pgp.mit.edu/
tel : 0156431816 - fax: 0156431828
8 av Hoche - 75008 PARIS - FRANCE

-------------------
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] 56+ messages in thread

* Re: [Caml-list] wait instruction
  2004-07-22  8:05                         ` [Caml-list] wait instruction lehalle@miriad
@ 2004-07-22  8:40                           ` Olivier Andrieu
  2004-07-22 10:35                             ` lehalle@miriad
  2004-07-22 10:33                           ` Vitaly Lugovsky
  1 sibling, 1 reply; 56+ messages in thread
From: Olivier Andrieu @ 2004-07-22  8:40 UTC (permalink / raw)
  To: charles.lehalle; +Cc: caml-list

 "lehalle@miriad" [Thu, 22 Jul 2004]:
 > Hi,
 > 
 > I want a function that allow my code to wait for m milliseconds
 > before continuing, and I need a cross-platform function (win and
 > linux) to perfom that. any idea ?

select ?

let msleep ms = 
  let _ = Unix.select [] [] [] (float ms /. 1000.) in ()

-- 
   Olivier

-------------------
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] 56+ messages in thread

* Re: [Caml-list] wait instruction
  2004-07-22  8:05                         ` [Caml-list] wait instruction lehalle@miriad
  2004-07-22  8:40                           ` Olivier Andrieu
@ 2004-07-22 10:33                           ` Vitaly Lugovsky
  1 sibling, 0 replies; 56+ messages in thread
From: Vitaly Lugovsky @ 2004-07-22 10:33 UTC (permalink / raw)
  To: lehalle@miriad; +Cc: caml-list

On Thu, 22 Jul 2004, lehalle@miriad wrote:

> Hi,
>
> I want a function that allow my code to wait for m
> milliseconds before
> continuing, and I need a cross-platform function (win and
> linux) to perfom
> that. any idea ?

 I am using OcamlSDL bindings for this, even in the scientific
computations applications.



-------------------
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] 56+ messages in thread

* Re: [Caml-list] wait instruction
  2004-07-22  8:40                           ` Olivier Andrieu
@ 2004-07-22 10:35                             ` lehalle@miriad
  0 siblings, 0 replies; 56+ messages in thread
From: lehalle@miriad @ 2004-07-22 10:35 UTC (permalink / raw)
  To: caml-list; +Cc: Olivier Andrieu

On Thu, 22 Jul 2004 10:40:51 +0200 (CEST), Olivier Andrieu  
<andrieu@ijm.jussieu.fr> wrote:
> select ?
> let msleep ms =
>   let _ = Unix.select [] [] [] (float ms /. 1000.) in ()

thank you, it is indeed what I wanted.

I will use it for my (now traditionnal) open source "summer game", that I  
program in ocaml for 2 years,
the last year release was dominocaml (a domino game engine with an  
interface with any language to implement "AI players")
and this year will be an hybrid tetris-winmine game called BoCaL, you can  
find its actual release here:
http://sourceforge.net/project/showfiles.php?group_id=72934&package_id=123433&release_id=254953

more seriously I will try to upgrade ocamaweb (a "widely" used literate  
programming tool in ocaml) next week including new features accordingly to  
the new MATLAB release and allowing it to work with ANY programming  
language. if someone here already use it and wants to give me advices :  
monday is the dead line.

charles

-------------------
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-21 20:41                         ` [Caml-list] kprintf with user formatters Jon Harrop
@ 2004-07-22 15:39                           ` Pierre Weis
  2004-07-22 22:16                             ` [Caml-list] lazy evaluation: [Was: kprintf with user formatters] skaller
  2004-07-22 22:42                             ` [Caml-list] kprintf with user formatters skaller
  0 siblings, 2 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-22 15:39 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

[...]
> Is "match pred with true -> expr1 | false -> expr2" not
> equivalent to "if pred then expr1 else expr2"? If so, isn't pattern
> matching a fourth lazy construct?

Yes indeed, if you consider ``match'' as an operator, which is a bit
hairy, since match would be a (2n+1)-ary operator (for any given
positive integer n), taking as input 1 expression (the one to be
matched) and n (pattern, expression) pairs to match the
expression. Given that there is no notion of evaluation semantics
associated to a pattern (in the sense of the evaluation of expression)
this would be strange. However, the very match expression you
mentioned has indeed something of a lazyness behavior, since it is
indeed equivalent of an ``if ... then ... else ...'' construct, as
I know you know :)

> Just after I wrote that last post I realised that this approach
> could actually be useful in numerical contexts. As a trivial
> example, integer multiply could lazily evaluate its second argument
> (only when it is pure, if conventional semantics are to be
> preserved), not needing it if the first argument is zero.

I don't think the gain would overcome the cost of having to create
thunks in practice. On the other hand, taht would lead to evaluate the
operation 0 * expr to 0, even if the computation of expr would lead to
divergence (never terminates or fails). It's mathematically kind of
weird, I think. For instance, you would have a hard time to persuade a
matematician that

0 * ln (0)

is well-defined and evaluates to 0, ``because ln (0) has not to be
considered at all given the left operand''.

Hence, as far as I know, arithmetics operators are always considered
strict in lazy languages.

> This may be useful in more complicated settings, i.e. when dealing
> with data structures rather than primitive types and when predicates
> over the data structure can be evaluated much more quickly than the
> corresponding expression.

I'm a bit lost here. Could you explain a bit ?

> Such functionality can, of course, be implemented in vanilla
> OCaml. But I'd like to see a language which allowed mathematics to
> be expressed in a notation as close to conventional written form as
> possible (although I prefer type distinctions, like "+" vs "+.")
> whilst retaining efficiency (I'd also like to see deforesting,
> e.g. in vector expressions without having to resort to maps, folds
> etc.).

Yes, we all want such a language. Caml is the best approximation I
know, wrt a perfect match between efficiency and notational facility.

> Perhaps an OCaml -> OCaml optimising compiler would be a good
> project for someone? That way implementation details and their
> benefits can be examined without having to touch the OCaml
> compilers. I think it could be quite fun to play with such a
> thing...
>
> Cheers,
> Jon.

Yes, many people have dreamed upon (or even have planned to do) such a
tool in the past. These days, the availability of the camlp4 tools
would help a lot to perform such a goal...

Best regards,

Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis

-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-21 17:43                         ` lazyness in ocaml (was : [Caml-list] kprintf with user formatters) Daniel Bünzli
@ 2004-07-22 16:28                           ` Pierre Weis
  2004-07-22 17:03                             ` William Lovas
  2004-07-22 23:00                             ` skaller
  0 siblings, 2 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-22 16:28 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: caml-list

> I agree. I once tried to port some haskell combinators [1] to ocaml. 
> However I had to stop since using them meant cluttering your code with 
> (lazy e) and lead to unreadable code.

Yes using lazy all over the place is too much!

That's why we had once in Caml some implicit way to denote lazy
expressions, such as when applying a constructor or building a
record. Lazy record fields or lazy constructors had to be declared
when defining the type they belongs to; then their usage was
implicitely lazy. For example, lazy integer lists were defined as:

type llist = {lazy head : int; lazy tail : llist};;

Now, {head = expr_head; tail = expr_tail} was automatically compiled
as {head = lazy (expr_head); tail = lazy (expr_tail)} (with trivial
optimisations if the lazy expressions are simple enough ({head = 1;
...} would build any lazy thunk)). Also an addition to the pattern
matching algorithm allowed automatic forcing of lazy parts of data
structures. This technic leads to simple and readable lazy programs.

> A more lightweight notation would be needed in order to do real lazy 
> programming in ocaml. At that time I wondered if specifiying the 
> lazyness when one defines the function and not when one uses it would 
> be a problem (I mean a technical problem, not an ideological one).
> For example if one defines
> 
> let f (lazy x) = ...
> 
> then the application f (x + y) would implicitely mean f (lazy (x + y)). 

That's a good idea, if only it were compatible with higher-order
functionality (and modularity), which I don't know for sure.

In my mind, this idea would be a type-based transformation of the
source code. The typing rule for lazy function application would be:

|~ -: (f : 'a lazy -> 'b) (e : 'a)
----------------------------------  (lazy app)
           |~ -: (f e : 'b)

and the transformation rule on the type annotated abstract syntax
trees would be:

(f : 'a lazy -> b) (e : 'a) => (f : 'a lazy -> b) (lazy e : 'a lazy)

Interestingly enough, the typing rule implies that you not only can
omit the lazy keyword at application time: it would be mandatory to
omit it! Weel, not so bad, after all ...

This has to be precisely ruled out and the necessary proofs have to be
made, but I think it could work (including for higher-order
functional, map, fold, and so on). I mean, I don't see any trivial
counter-example that would ruin this scheme. Wao! If this rule
turned out to be usable, it would be a major improvement for lazy
evaluation in our favorite language.

> Alternatively something less intrusive than the keyword 'lazy' would be 
> good.
>
> Daniel
> 
> [1] <http://doi.acm.org/10.1145/944705.944727>

Right, but which one ?

Best regards,

Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis

-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-22 16:28                           ` Pierre Weis
@ 2004-07-22 17:03                             ` William Lovas
  2004-07-22 23:00                             ` skaller
  1 sibling, 0 replies; 56+ messages in thread
From: William Lovas @ 2004-07-22 17:03 UTC (permalink / raw)
  To: caml-list

On Thu, Jul 22, 2004 at 06:28:51PM +0200, Pierre Weis wrote:
> > A more lightweight notation would be needed in order to do real lazy 
> > programming in ocaml. At that time I wondered if specifiying the 
> > lazyness when one defines the function and not when one uses it would 
> > be a problem (I mean a technical problem, not an ideological one).
> > For example if one defines
> > 
> > let f (lazy x) = ...
> > 
> > then the application f (x + y) would implicitely mean f (lazy (x + y)). 
> 
> [...]
>
> This has to be precisely ruled out and the necessary proofs have to be
> made, but I think it could work (including for higher-order
> functional, map, fold, and so on). I mean, I don't see any trivial
> counter-example that would ruin this scheme. Wao! If this rule
> turned out to be usable, it would be a major improvement for lazy
> evaluation in our favorite language.

This is reminiscent of the notation in Wadler's paper, "How to add laziness
to a strict language, without even being odd"[1].  He even gives the
semantics as a translation into the delay/force ("odd") style already
supported in O'Caml, similar to this proposal.  Perhaps it could even be
implemented in camlp4, without any need for type-based transformations.

William

[1] http://homepages.inf.ed.ac.uk/wadler/papers/lazyinstrict/lazyinstrict.txt

-------------------
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] 56+ messages in thread

* [Caml-list] lazy evaluation: [Was: kprintf with user formatters]
  2004-07-22 15:39                           ` Pierre Weis
@ 2004-07-22 22:16                             ` skaller
  2004-07-22 22:42                             ` [Caml-list] kprintf with user formatters skaller
  1 sibling, 0 replies; 56+ messages in thread
From: skaller @ 2004-07-22 22:16 UTC (permalink / raw)
  To: caml-list

On Fri, 2004-07-23 at 01:39, Pierre Weis wrote:
> However, the very match expression you
> mentioned has indeed something of a lazyness behavior, since it is
> indeed equivalent of an ``if ... then ... else ...'' construct, as
> I know you know :)

I'm intrigued! 

Felix has a side-effect free functional subsystem,
and I expected this to buy considerable optimisation
opportunities unavailable in Ocaml: in particular,
any functional code which is normally evaluated eagerly
can always be evaluated lazily (which the optimiser effects
by converting it to procedural goto-spagetti).

However, erroneous or non-terminating lazy code can't
be prematurely evaluated in either language
I'd kind of assumed this could be done in Felix,
but it is clear now this isn't the case.

This seems to indicate in hybrid languages like Ocaml 
and Felix well specified parts of the language must
be deemed eager or lazy: both languages support expicitly
procedural constructions, however even the functional
code in both languages seems to need the evaluation time
specified (to more extent than I'd believed previously..)

Curiously this seems to indicate that in the long run
Haskell compilers should be able to generate more efficient
code if only the optimisers are smart enough to prove
it is both correct and efficient to evaluate something
prematurely.

One of my friends is actually doing a thesis on this.
His technique is basically to make everything eager
by default, and then upgrade it to lazy if necessary
(rather than the other way around).

-- 
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] 56+ messages in thread

* Re: [Caml-list] kprintf with user formatters
  2004-07-22 15:39                           ` Pierre Weis
  2004-07-22 22:16                             ` [Caml-list] lazy evaluation: [Was: kprintf with user formatters] skaller
@ 2004-07-22 22:42                             ` skaller
  1 sibling, 0 replies; 56+ messages in thread
From: skaller @ 2004-07-22 22:42 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Jon Harrop, caml-list

On Fri, 2004-07-23 at 01:39, Pierre Weis wrote:

> For instance, you would have a hard time to persuade a
> matematician that
> 
> 0 * ln (0)
> 
> is well-defined and evaluates to 0, ``because ln (0) has not to be
> considered at all given the left operand''.

Actually, this IS the case in many languages such as C.
0 is not in the domain of ln. Therefore, the result is undefined
when you apply ln to 0 because you're applying a function to a value
outside its domain. In language standards it is sometimes
said that the result is undefined in such cases, which means
that the compiler can generate code to do anything it wants
in such cases.

In particular it can return 0 and remain conforming
and therefore it can apply the shortcut evaluation.

This is NOT the case if the language standard specifies
an exception must be thrown, or NaN or +Inf returned,
which is generally a very bad idea precisely because it 
makes the semantics determinate and thus defeats the
optimisation which could otherwise be obtained by
using the usual mathematical law 0 * x = 0.

C is very careful to leave lots of things undefined.

This issue actually arose directly on the C++ Standards
Committee, except the function was division not ln.
The question was whether a compiler was allowed and/or
required to issue a diagnostic error message given:

main() { return 1/0; }

Note that it is possible to prove IN THIS CASE
that the program will always fail by dividing by zero.

However, it isn't always so obvious -- so you simply cannot
require a diagnostic. Indeed, one can argue -- and
someone DID argue -- that even if the program always
fails when executed .. who knows if it is executed?

The code must be generated, C compiler can issue a warning
but it is NOT allowed to reject the program. It must
actually generated code which can be executed .. even though
that code can do anything (Aas far as I can remember that
was the interpretation..)

-- 
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-22 16:28                           ` Pierre Weis
  2004-07-22 17:03                             ` William Lovas
@ 2004-07-22 23:00                             ` skaller
  2004-07-23  3:32                               ` William Lovas
  2004-07-28  7:26                               ` Pierre Weis
  1 sibling, 2 replies; 56+ messages in thread
From: skaller @ 2004-07-22 23:00 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Daniel Bünzli, caml-list

On Fri, 2004-07-23 at 02:28, Pierre Weis wrote:

> In my mind, this idea would be a type-based transformation of the
> source code. The typing rule for lazy function application would be:
> 
> |~ -: (f : 'a lazy -> 'b) (e : 'a)
> ----------------------------------  (lazy app)
>            |~ -: (f e : 'b)
> 
> and the transformation rule on the type annotated abstract syntax
> trees would be:
> 
> (f : 'a lazy -> b) (e : 'a) => (f : 'a lazy -> b) (lazy e : 'a lazy)
> 
> Interestingly enough, the typing rule implies that you not only can
> omit the lazy keyword at application time: it would be mandatory to
> omit it! Weel, not so bad, after all ...
> 
> This has to be precisely ruled out and the necessary proofs have to be
> made, but I think it could work (including for higher-order
> functional, map, fold, and so on). I mean, I don't see any trivial
> counter-example that would ruin this scheme. Wao! If this rule
> turned out to be usable, it would be a major improvement for lazy
> evaluation in our favorite language.

But this looks very dangerous!

Its kind of like reference parameters in C++, which make
it impossible to tell if  f(expr) can modifiy expr or not
[without finding which 'f' it is and examining it]

In the lazy case it would destroy an important identity:

f x <==> let x' = x in f x'

With your rule, the LHS might not evaluate x, whereas the RHS
would. Of course we already have that:

f x y <=/=> let x' = x in y' = y in f x' y'

since the RHS guarrantees x is evaluated before y,
whilst it happens by chance in the current Ocaml implementation
the reverse is true for the LHS.

So even if your rule is sound, it might not be a good idea
because it breaks 'the substitution principle'.

How about sugar:

\(expr) <==> lazy expr

Since arguments to be lazily evaluated are never variables,
they're often going to be surrounded in brackets already, 
and so this is only a single character .. 
a lazy way to spell lazy  .. and a very easy implementation :)

-- 
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-22 23:00                             ` skaller
@ 2004-07-23  3:32                               ` William Lovas
  2004-07-28  7:26                               ` Pierre Weis
  1 sibling, 0 replies; 56+ messages in thread
From: William Lovas @ 2004-07-23  3:32 UTC (permalink / raw)
  To: caml-list

On Fri, Jul 23, 2004 at 09:00:49AM +1000, skaller wrote:
> How about sugar:
> 
> \(expr) <==> lazy expr
> 
> Since arguments to be lazily evaluated are never variables,
> they're often going to be surrounded in brackets already, 
> and so this is only a single character .. 
> a lazy way to spell lazy  .. and a very easy implementation :)

... and this is a lot like Okasaki's $ proposal, also mentioned in Wadler's
paper on lazy notation in strict languages[1].  There really is nothing new
under the sun :)

William

[1] http://homepages.inf.ed.ac.uk/wadler/papers/lazyinstrict/lazyinstrict.txt

-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-22 23:00                             ` skaller
  2004-07-23  3:32                               ` William Lovas
@ 2004-07-28  7:26                               ` Pierre Weis
  2004-07-28  8:06                                 ` skaller
  2004-07-28 10:17                                 ` Jason Smith
  1 sibling, 2 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-28  7:26 UTC (permalink / raw)
  To: skaller; +Cc: pierre.weis, daniel.buenzli, caml-list

[...]
> But this looks very dangerous!

Yes: lazyness in the presence of side-effects is tricky. But don't
worry, that's not the introduction of this new rule that is dangerous,
it is the concept of lazy evaluation and more importantly the mixing
of lazy evaluation and strict evaluation that is difficult in the
presence of side effects.

> Its kind of like reference parameters in C++, which make
> it impossible to tell if  f(expr) can modifiy expr or not
> [without finding which 'f' it is and examining it]

I cannot understand that one. We have that in Caml already and we had
it from the very begining of Caml (1984). For instance, if I write

f (expr)

could you tell me ``if  f(expr) can modifiy expr or not [without
finding which 'f' it is and examining it]'' ?

To the best of my knowledge, the answer is no.

To the best of my knowledge, nobody never complained about that feature.

> > In the lazy case it would destroy an important identity:
> 
> f x <==> let x' = x in f x'
> 
> With your rule, the LHS might not evaluate x, whereas the RHS
> would.

Yes, that's exactly what we want: if (f e) is a lazy application you
don't know if e is evaluated or not. This is just what lazyness is
about !

Also, I didn't know that such an ``important identity'' stands for
Caml expressions. Except in the trivial case where ``x'' just denotes
a variable in the statment. In this case, the statment still holds with
the new rule :)

> Of course we already have that:
> 
> f x y <=/=> let x' = x in y' = y in f x' y'
> 
> since the RHS guarrantees x is evaluated before y,
> whilst it happens by chance in the current Ocaml implementation
> the reverse is true for the LHS.

So what? Is the ``important identity'' wrong after all, being wrong in
this case ? Or do you suggest to suppress currying in order to restore
the ``important identity'' ?

> So even if your rule is sound, it might not be a good idea
> because it breaks 'the substitution principle'.

There is nothing such as your ``substitution principle'' in Caml,
except if we restrict the language to truly trivial expressions (as
soon as expressions may incoporate basic operators such as the integer
addition your ``principle'' does not stand anymore).

> How about sugar:
> 
> \(expr) <==> lazy expr
> 
> Since arguments to be lazily evaluated are never variables,

Wait a minute: do you mean I cannot write f e, if e is just a variable?

If the answer is yes, your suggestion breaks something important (we
still want to apply a function to any expression of the suitable
type); if the answer is no then you would need to write f \x as you
now have to write f (lazy x) with the current compiler. Or you would
have to implement something really strange to handle f e differently
if the expression e is a variable or not.

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  7:26                               ` Pierre Weis
@ 2004-07-28  8:06                                 ` skaller
  2004-07-28  8:29                                   ` Daniel Bünzli
  2004-07-28  9:13                                   ` Pierre Weis
  2004-07-28 10:17                                 ` Jason Smith
  1 sibling, 2 replies; 56+ messages in thread
From: skaller @ 2004-07-28  8:06 UTC (permalink / raw)
  To: Pierre Weis; +Cc: daniel.buenzli, caml-list

On Wed, 2004-07-28 at 17:26, Pierre Weis wrote:

> There is nothing such as your ``substitution principle'' in Caml,
> except if we restrict the language to truly trivial expressions (as
> soon as expressions may incoporate basic operators such as the integer
> addition your ``principle'' does not stand anymore).

I thought:

let x = expr in f x

and

f expr

are identical in all circumstances in Ocaml
for all terms 'expr', I must have missed
something .. do you have a counter example?

-- 
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  8:06                                 ` skaller
@ 2004-07-28  8:29                                   ` Daniel Bünzli
  2004-07-28  9:13                                   ` Pierre Weis
  1 sibling, 0 replies; 56+ messages in thread
From: Daniel Bünzli @ 2004-07-28  8:29 UTC (permalink / raw)
  To: skaller; +Cc: Pierre Weis, caml-list

Le 28 juil. 04, à 10:06, skaller a écrit :
> do you have a counter example?

let f c =
   let a = input_byte c in
   let b = input_byte c in
   (a,b)

let f' c = (input_byte c, input_byte c)


f and f' do not produce the same pair on my platform.

Daniel

-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  8:06                                 ` skaller
  2004-07-28  8:29                                   ` Daniel Bünzli
@ 2004-07-28  9:13                                   ` Pierre Weis
  2004-07-28  9:36                                     ` skaller
  2004-07-28  9:38                                     ` skaller
  1 sibling, 2 replies; 56+ messages in thread
From: Pierre Weis @ 2004-07-28  9:13 UTC (permalink / raw)
  To: skaller; +Cc: pierre.weis, daniel.buenzli, caml-list

> On Wed, 2004-07-28 at 17:26, Pierre Weis wrote:
> 
> > There is nothing such as your ``substitution principle'' in Caml,
> > except if we restrict the language to truly trivial expressions (as
> > soon as expressions may incoporate basic operators such as the integer
> > addition your ``principle'' does not stand anymore).
> 
> I thought:
> 
> let x = expr in f x
> 
> and
> 
> f expr
> 
> are identical in all circumstances in Ocaml
> for all terms 'expr', I must have missed
> something .. do you have a counter example?

We have to precisely state the statement here:

- if you mean that ``f'' is just an ident (more precisely, a
lowercase ident in the Caml parser parlance) bound to a unary
function, then the two expressions are equivalent.

- if f can have more than one argument, then the two expressions are
obviously not equivalent since the first one fixes the order of
evaluation when the second does not. This is true in particular if f
is ( + ):

 let x = expr in expr2 + x

 and

 expr2 + x

may not evaluate the same (depending on the compiler: a lot of
flamewar already occurred on this list about that feature).

- if f can be more than a lowercase ident and in particular if f can
introduce a lazy construction, then the two expressions are not
equivalent (as desired), since the first one explicitely evaluates
expr when the second may not. Consider f being ``lazy'' and expr being
``failwith "evaluated"'':

 # let x = failwith "evaluated" in
   lazy x;;
 Exception: Failure "evaluated".
 # lazy (failwith "evaluated");;
 - : 'a lazy_t = <lazy>

Here, you check again that lazy evaluation just breaks the eagerness
of the language (and hence breaks your ``identity'' a bit more):
lazyness changes the default evaluation regime, just as desired. It's
no surprise, something has changed after the introduction of lazyness!

What I propose is a smoother interaction with the rest of the language
with the (re)-introduction of lazy constructors, lazy labels and a new
typing (and compilation) rule to facilitate the use of lazy functions.

Best regards,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  9:13                                   ` Pierre Weis
@ 2004-07-28  9:36                                     ` skaller
  2004-07-28  9:38                                     ` skaller
  1 sibling, 0 replies; 56+ messages in thread
From: skaller @ 2004-07-28  9:36 UTC (permalink / raw)
  To: Pierre Weis; +Cc: daniel.buenzli, caml-list

On Wed, 2004-07-28 at 19:13, Pierre Weis wrote:
> > On Wed, 2004-07-28 at 17:26, Pierre Weis wrote:
> > 
> > > There is nothing such as your ``substitution principle'' in Caml,
> > > except if we restrict the language to truly trivial expressions (as
> > > soon as expressions may incoporate basic operators such as the integer
> > > addition your ``principle'' does not stand anymore).
> > 
> > I thought:
> > 
> > let x = expr in f x
> > 
> > and
> > 
> > f expr
> > 
> > are identical in all circumstances in Ocaml
> > for all terms 'expr', I must have missed
> > something .. do you have a counter example?
> 
> We have to precisely state the statement here:
> 
> - if you mean that ``f'' is just an ident (more precisely, a
> lowercase ident in the Caml parser parlance) bound to a unary
> function, then the two expressions are equivalent.

f is a function constant, but i didn't specify unary..

> - if f can have more than one argument, then the two expressions are
> obviously not equivalent since the first one fixes the order of
> evaluation when the second does not.

OK, thanks. You are right. Given

let x = f e in x y

and

(f e) y

might evaluate e and y in different orders.
Sorry -- you did already point this out too, i just didn't see it :)

-- 
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  9:13                                   ` Pierre Weis
  2004-07-28  9:36                                     ` skaller
@ 2004-07-28  9:38                                     ` skaller
  1 sibling, 0 replies; 56+ messages in thread
From: skaller @ 2004-07-28  9:38 UTC (permalink / raw)
  To: Pierre Weis; +Cc: daniel.buenzli, caml-list

On Wed, 2004-07-28 at 19:13, Pierre Weis wrote:

> What I propose is a smoother interaction with the rest of the language
> with the (re)-introduction of lazy constructors, lazy labels and a new
> typing (and compilation) rule to facilitate the use of lazy functions.

OK: I said this looked dangerous, but the resulting discussion
convinces me that it could be worth it, since the guarrantees
I thought might be broken didn't really exist in the first place.

-- 
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28  7:26                               ` Pierre Weis
  2004-07-28  8:06                                 ` skaller
@ 2004-07-28 10:17                                 ` Jason Smith
  2004-07-28 12:31                                   ` skaller
  1 sibling, 1 reply; 56+ messages in thread
From: Jason Smith @ 2004-07-28 10:17 UTC (permalink / raw)
  To: caml-list

Hello, first off I come from a Haskell background, and especially ghc so I
might be a little off key here, but I thought I'd add my thoughts come what
may. Also I'm a newbie so go easy if I'm off base :) (which is more then
likely!)


> I cannot understand that one. We have that in Caml already and we had
> it from the very begining of Caml (1984). For instance, if I write
>
> f (expr)
>
> could you tell me ``if  f(expr) can modifiy expr or not [without
> finding which 'f' it is and examining it]'' ?
>
> To the best of my knowledge, the answer is no.

Well thats kinda what strictness analysis does. If f is going to use the
expression then we evaluate it before entering the function so we don't have
to pass around THUNKS. But yes we have to know what the 'f' is were playing
with.

> To the best of my knowledge, nobody never complained about that feature.

Its an optimization that is performed regularly in the ghc compiler, and
yeah no one complains about its abscence! :)

> > > In the lazy case it would destroy an important identity:
> >
> > f x <==> let x' = x in f x'
> >
> > With your rule, the LHS might not evaluate x, whereas the RHS
> > would.

I'm not exactly sure why u defined the substitution principle like this, the
syntax should be a non-issue.  The way I learned it (from Mitchells
excellent book) was the following. The substitution lemma intuitively says
that susbtituting a term N for a variable x in M is the same effect on the
meaning of M as changing the environment so that the value of x is the value
of N.

The meaning is what matters, not its syntactic form. If we use just plain
alegbra here, where S is the set of sorts, G the environment assigning types
to terms, we can define it as given M 'elem' Terms(S, G, x:s'), and N 'elem'
Terms(S, G), so that [N/x]M 'elem' Terms(S, G). Then for any environment E,
we can say that the denotational meaning (given by the meaning function  <
>) for each is the same, i.e.

<[N/x]M>E == <M>E{x -> a}

where a = <N>E is the meaning of N at E.

In the above, the meanings of an evaluated expression and an unevaluated
expression are as far as I'm aware identical.

In the prescence of side-effects this complicates the operational semantics
(and invalidates equivalences in the denotational semantics), because
side-effects change the storage semantics of the environment and can
invalidate the meaning function. For example when we substitute N for x in
M, evaluating N may change the meaning of a variable other then x free in M.

There are a number of papers by Sullivan and Wand discussing various
transformations like lambda lifting in a denotational model based on a
operational based term model where interaction is the basic observable, and
they don't consider the store as the final part of the congruence proof.
Anywayz, the problem with the above is that this equivelence already does
not hold in Ocaml'.

In Haskell the above identity phrased as it is, would hold, because we don't
have side effects. Threading of the world through the IO Monad forces the
same evaluation order for both expressions.

> Also, I didn't know that such an ``important identity'' stands for
> Caml expressions. Except in the trivial case where ``x'' just denotes
> a variable in the statment. In this case, the statment still holds with
> the new rule :)

>From what I can see yes it is broken because of side-effects, we cannot
guarentee that the two phrases are equivalent in the standard denotational
semantics.

> > Of course we already have that:
> >
> > f x y <=/=> let x' = x in y' = y in f x' y'
> >
> > since the RHS guarrantees x is evaluated before y,
> > whilst it happens by chance in the current Ocaml implementation
> > the reverse is true for the LHS.
>
> So what? Is the ``important identity'' wrong after all, being wrong in
> this case ? Or do you suggest to suppress currying in order to restore
> the ``important identity'

I'm a bit behind the discussion but I think the original poster was just
pointing out that we can impose AOR reduction explicitly by using the let
constructs.

Cheers,
Jason.

-------------------
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] 56+ messages in thread

* Re: lazyness in ocaml (was : [Caml-list] kprintf with user formatters)
  2004-07-28 10:17                                 ` Jason Smith
@ 2004-07-28 12:31                                   ` skaller
  0 siblings, 0 replies; 56+ messages in thread
From: skaller @ 2004-07-28 12:31 UTC (permalink / raw)
  To: Jason Smith; +Cc: caml-list

On Wed, 2004-07-28 at 20:17, Jason Smith wrote:

> > > f x <==> let x' = x in f x'

> I'm not exactly sure why u defined the substitution principle like this, the
> syntax should be a non-issue.  

I'm talking about programming in a specific language Ocaml, 
defined in terms of its syntax -- so there is no choice but to
talk about it in those terms. Ocaml is Ocaml not
lambda calculus :)


-- 
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] 56+ messages in thread

end of thread, other threads:[~2004-07-28 12:31 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-30 16:32 [Caml-list] kprintf with user formatters Damien
2004-07-14 21:10 ` Pierre Weis
2004-07-15  0:17   ` Markus Mottl
2004-07-15  7:30     ` David MENTRE
2004-07-15  7:59       ` Jean-Christophe Filliatre
2004-07-15 23:35         ` henri dubois-ferriere
2004-07-15  7:39     ` Damien
2004-07-15 12:19       ` Markus Mottl
2004-07-15 12:42         ` Basile Starynkevitch [local]
2004-07-15 13:45           ` Markus Mottl
2004-07-15 14:22             ` Basile Starynkevitch [local]
2004-07-15 14:57               ` Markus Mottl
2004-07-16  6:47               ` Pierre Weis
2004-07-16  7:13                 ` Jean-Christophe Filliatre
2004-07-16  7:23                   ` henri dubois-ferriere
2004-07-16  7:44                     ` Jean-Christophe Filliatre
2004-07-16 17:56                   ` Markus Mottl
2004-07-19  9:17                   ` Pierre Weis
2004-07-19  9:32                     ` Jean-Christophe Filliatre
2004-07-16  7:21                 ` henri dubois-ferriere
2004-07-16 17:44                 ` Markus Mottl
2004-07-19 10:10                   ` Pierre Weis
2004-07-19 10:43                     ` Jon Harrop
2004-07-21 15:52                       ` Pierre Weis
2004-07-21 17:43                         ` lazyness in ocaml (was : [Caml-list] kprintf with user formatters) Daniel Bünzli
2004-07-22 16:28                           ` Pierre Weis
2004-07-22 17:03                             ` William Lovas
2004-07-22 23:00                             ` skaller
2004-07-23  3:32                               ` William Lovas
2004-07-28  7:26                               ` Pierre Weis
2004-07-28  8:06                                 ` skaller
2004-07-28  8:29                                   ` Daniel Bünzli
2004-07-28  9:13                                   ` Pierre Weis
2004-07-28  9:36                                     ` skaller
2004-07-28  9:38                                     ` skaller
2004-07-28 10:17                                 ` Jason Smith
2004-07-28 12:31                                   ` skaller
2004-07-21 20:41                         ` [Caml-list] kprintf with user formatters Jon Harrop
2004-07-22 15:39                           ` Pierre Weis
2004-07-22 22:16                             ` [Caml-list] lazy evaluation: [Was: kprintf with user formatters] skaller
2004-07-22 22:42                             ` [Caml-list] kprintf with user formatters skaller
2004-07-22  8:05                         ` [Caml-list] wait instruction lehalle@miriad
2004-07-22  8:40                           ` Olivier Andrieu
2004-07-22 10:35                             ` lehalle@miriad
2004-07-22 10:33                           ` Vitaly Lugovsky
2004-07-16  6:17             ` [Caml-list] kprintf with user formatters Pierre Weis
2004-07-16 17:14               ` Markus Mottl
2004-07-19 10:00                 ` Pierre Weis
2004-07-16  6:02       ` Pierre Weis
2004-07-16  8:42         ` Damien
2004-07-19  9:00           ` Pierre Weis
2004-07-16 16:52         ` Markus Mottl
2004-07-19  9:28           ` Pierre Weis
2004-07-15 22:20     ` Pierre Weis
2004-07-15 23:01       ` Markus Mottl
2004-07-16 16:17     ` james woodyatt

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