caml-list - the Caml user's mailing list
 help / Atom feed
* [Caml-list] Returning printf from a function
@ 2018-08-23  9:16 Richard W.M. Jones
  2018-08-23  9:29 ` Florian Angeletti
  0 siblings, 1 reply; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23  9:16 UTC (permalink / raw)
  To: caml-list

This is a problem we hit from time to time and I don't think I've ever
really understood why it happens.  This made up example shows the
essence:

----------------------------------------------------------------------
let get_printer out =
  if out then Printf.printf else Printf.fprintf stderr

let () =
  let printer = get_printer true in
  printer "hello\n";
  printer "goodbye %s\n" "everyone"      (* line 7 *)
----------------------------------------------------------------------

$ ocamlopt test2.ml
File "test2.ml", line 7, characters 2-9:
Error: This function has type (unit, out_channel, unit) format -> unit
       It is applied to too many arguments; maybe you forgot a `;'.

Type inference in line 6 seems to overspecify the inferred type of
printer, so that we get the error on line 7.

Why?  And how to fix it?

Rich.

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Returning printf from a function
  2018-08-23  9:16 [Caml-list] Returning printf from a function Richard W.M. Jones
@ 2018-08-23  9:29 ` Florian Angeletti
  2018-08-23  9:48   ` Richard W.M. Jones
  0 siblings, 1 reply; 5+ messages in thread
From: Florian Angeletti @ 2018-08-23  9:29 UTC (permalink / raw)
  To: caml-list

This is the value restriction at work, you can avoid the issue by replacing

let printer = get_printer true in ...


where the type of printer is "Format.formatter -> ('_weak1, 
Format.formatter, unit) format -> '_weak1",  with

let printer x = get_printer true x in ...


− octachron.

On 23/08/2018 11:15, Richard W.M. Jones wrote:
> This is a problem we hit from time to time and I don't think I've ever
> really understood why it happens.  This made up example shows the
> essence:
>
> ----------------------------------------------------------------------
> let get_printer out =
>    if out then Printf.printf else Printf.fprintf stderr
>
> let () =
>    let printer = get_printer true in
>    printer "hello\n";
>    printer "goodbye %s\n" "everyone"      (* line 7 *)
> ----------------------------------------------------------------------
>
> $ ocamlopt test2.ml
> File "test2.ml", line 7, characters 2-9:
> Error: This function has type (unit, out_channel, unit) format -> unit
>         It is applied to too many arguments; maybe you forgot a `;'.
>
> Type inference in line 6 seems to overspecify the inferred type of
> printer, so that we get the error on line 7.
>
> Why?  And how to fix it?
>
> Rich.
>


-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Returning printf from a function
  2018-08-23  9:29 ` Florian Angeletti
@ 2018-08-23  9:48   ` Richard W.M. Jones
  2018-08-23 10:08     ` Florian Angeletti
  0 siblings, 1 reply; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23  9:48 UTC (permalink / raw)
  To: Florian Angeletti; +Cc: caml-list


Let's complicate this a bit further.  The nearly exact code we are
having problems with is (note that give_fn can return None in the real
code):

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

let debug fs =
  ksprintf print_endline fs

let give_fn () =
  Some debug

let () =
  let param = "x" in
  debug "single";
  debug "param: %s" param;
  (match give_fn () with
  | None -> ()
  | Some fn ->
    fn "fn";
    fn "fn param: %s" param
  );
  ()
----------------------------------------------------------------------

In this case there's no apparent way to add the extra parameter, I
don't think ...

Rich.

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Returning printf from a function
  2018-08-23  9:48   ` Richard W.M. Jones
@ 2018-08-23 10:08     ` Florian Angeletti
  2018-08-23 10:23       ` Richard W.M. Jones
  0 siblings, 1 reply; 5+ messages in thread
From: Florian Angeletti @ 2018-08-23 10:08 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 609 bytes --]

A solution that works in this specific example and does not require to 
rewire the logic is
to return the printing function inside a record with the right universal 
quantification:

...

type debug = {fn: 'a. ('a, unit, string, unit) format4 -> 'a }[@@unboxed];;

let udebug = {fn=debug}

let give_fn () = Some udebug

...

   | Some {fn} ->
     fn "fn";
     fn "fn param: %s" param



-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

[-- Attachment #2: Type: text/html, Size: 1163 bytes --]

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

* Re: [Caml-list] Returning printf from a function
  2018-08-23 10:08     ` Florian Angeletti
@ 2018-08-23 10:23       ` Richard W.M. Jones
  0 siblings, 0 replies; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23 10:23 UTC (permalink / raw)
  To: Florian Angeletti; +Cc: caml-list

On Thu, Aug 23, 2018 at 12:08:10PM +0200, Florian Angeletti wrote:
> A solution that works in this specific example and does not require to
> rewire the logic is
> to return the printing function inside a record with the right universal
> quantification:
> 
> ...
> 
> type debug = {fn: 'a. ('a, unit, string, unit) format4 -> 'a }[@@unboxed];;
> 
> let udebug = {fn=debug}
> 
> let give_fn () = Some udebug
> 
> ...
> 
>   | Some {fn} ->
>     fn "fn";
>     fn "fn param: %s" param

Thanks, that does indeed work.

Rich.

-- 
Richard Jones

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-23  9:16 [Caml-list] Returning printf from a function Richard W.M. Jones
2018-08-23  9:29 ` Florian Angeletti
2018-08-23  9:48   ` Richard W.M. Jones
2018-08-23 10:08     ` Florian Angeletti
2018-08-23 10:23       ` Richard W.M. Jones

caml-list - the Caml user's mailing list

Archives are clonable: git clone --mirror https://inbox.ocaml.org/caml-list

AGPL code for this site: git clone https://public-inbox.org/ public-inbox