Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mismatch between Pervasives.format_of_string's type signature and its documented behavior #5591

Closed
vicuna opened this issue Apr 15, 2012 · 3 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented Apr 15, 2012

Original bug ID: 5591
Reporter: rbonichon
Assigned to: @gasche
Status: closed (set by @xavierleroy on 2015-12-11T18:04:31Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 3.12.1
Category: standard library

Bug description

The type signature of this function is documented as

format_of_string : ('a, 'b, 'c, 'd, 'e, 'f) format6 ->
('a, 'b, 'c, 'd, 'e, 'f) format6

though its behavior is documented -- as we expect -- as
"format_of_string s returns a format string read from the string literal s."

Further note

There are three functions (seemingly) related to the conversion of string/format in pervasives.ml:

  • format_of_string (exported but with the mismatched documentation/signature above)
  • format_to_string (exported)
  • string_to_format (not exported)

string_to_format is used in the module (not format_of_string) for conversion and seems to be redundant with format_of_string.

Additional information

The fix might be as simple as replacing:

external format_of_string :
('a, 'b, 'c,'d, 'e, 'f) format6 ->
('a, 'b, 'c, 'd, 'e, 'f) format6 = "%identity"

by

external format_of_string :
string ->
('a, 'b, 'c, 'd, 'e, 'f) format6 = "%identity"

Or exporting the function "string_to_format" from pervasives.ml in its stand.

@vicuna
Copy link
Author

vicuna commented Apr 15, 2012

Comment author: @gasche

The whole printf/scanf magic is based on on the fact that the typer can analyse string literal as format string and extract rich format typing information out of them. Of course this can only work with constant strings (hence the restriction to string literals): format_of_string (read_line ()) would of course not be typeable.

This explains the type of format_of_string: it only has the effect of a type annotation to force the type-checker to use its "format hack" on the string literal, even if it wasn't clear from the context that it will indeed be used as a format. And it's much more convenient than explicitly coercing to (blah, blah, blah...) format6.

Consider the two toplevel sessions:

let s = "%s";;

val s : string = "%s"

Printf.printf s;;

Error: This expression has type string but an expression was expected of type
('a, out_channel, unit) format =
('a, out_channel, unit, unit, unit, unit) format6

let s = format_of_string "%s";;

val s : (string -> '_a, '_b, '_c, '_d, '_d, '_a) format6 =

Printf.printf s;;

  • : string -> unit =

(string_to_format : string -> ... format) is a type-unsafe coercion that is only used inside the standard library in provably safe places (namely the implementation of "%,"). Exposing it to the users would give them yet another way to shoot them in the foot (including segfaults) for dubious benefit -- if you want to do subtle type-level format handling, you should use an equally-expressive type-safe printing combinator library anyway.

To conclude, I am under the impression that your bug report is not a bug (even an documentation bug), but the result of a mismatch between your expectations and how formats are handled by the compiler. As the misunderstanding could equally likely be on my side, I mark this bug as "feedback": can you confirm that your suggested fix is not correct for the reasons above?

@vicuna
Copy link
Author

vicuna commented Apr 15, 2012

Comment author: rbonichon

You're right, your impression is correct and I alsostand corrected. This is not a bug. Do close it!

@vicuna
Copy link
Author

vicuna commented Apr 16, 2012

Comment author: @glondu

For the record, there is Scanf.format_from_string that converts a string to a format6 in a type-safe way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants