-
Notifications
You must be signed in to change notification settings - Fork 177
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
Lwt_fmt #548
Lwt_fmt #548
Conversation
src/unix/Lwt_fmt.mli
Outdated
|
||
val printf : ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a | ||
(** Returns a promise that prints on the standard output. | ||
Similar to [Format.printf]. *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{!Format.printf}
src/unix/Lwt_fmt.mli
Outdated
|
||
val eprintf : ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a | ||
(** Returns a promise that prints on the standard error. | ||
Similar to [Format.eprintf]. *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{!Format.eprintf}
src/unix/Lwt_fmt.mli
Outdated
|
||
(** This module bridges the gap between [Format] and [Lwt]. | ||
Although it is not required, it is recommended to use this module with the | ||
[Fmt] library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These toplevel module names could be {!links}
.
src/unix/Lwt_fmt.mli
Outdated
val fprintf : formatter -> ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a | ||
|
||
val kfprintf : | ||
(Format.formatter -> unit Lwt.t -> 'a) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to have (formatter -> 'a)
rather than (Format.formatter -> unit Lwt.t -> 'a)
for the continuation argument: with write_pending
exposed, it is still possible to write fprintf
from the formatter -> 'a
version and it avoids exposing the underlying Format.formatter
of the formatter
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, that is right, but I'm pretty sure people will forget to call write_pending
if you don't do it for them, which will lead to very weird bugs.
I'm trying to think if exposing the Format.formatter
is a bad thing or not. It's not really unsafe, but I'm not sure if it's useful or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In term of coherency of the API, I think that in any case it would be better to expose a formatter
rather than Format.formatter
otherwise kfprintf
provides a strange entry point to features only available for Format.formatter
(e.g. modifying margin, tags).
I agree that people will probably forget the call to write_pending
, even if this could be mitigated by adding Do not forget to call {!write_pending}
to the documentation and the limited amount of people using kprintf without reading the documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe we can keep the unit Lwt.t
and just expose a formatter
.
Do you think I need to expose a function to retrieve the Format.formatter
too ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I think that formatter -> unit Lwt.t -> 'a
is a good compromise.
Do you think I need to expose a function to retrieve the Format.formatter too ?
I think that It would be nice to avoid it. I believe that letting make_formatter
handle the configuration of the formatter is fine since safely modifying the underlying formatter is as hard as safely creating a second formatter with the same output channel. Nevertheless, in this case, it might be interesting to add the part of the Format
API not exposed to kfprintf
, i.e. the tabulation boxes and pp_print_if_newline
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that point sort of moot, given the existence of %t
and %a
? Lwt_fmt.fprintf fmt "%t" (fun fmt -> ....)
will always work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True,%t
and %a
should be enough for tabulation boxes and friends.
For what reason would I want the formatting functions to return promises? If I were just reading the documentation for this module, it would not be readily apparent to me that these functions would be blocking. |
@hakuch The underlying channel on which the printing is done can be blocking. That is why the |
Thanks, @Drup. That makes sense! |
This seems pretty nice. My only real concern is where it should go. I don't mind ultimately adding a new module to Lwt, but what are people's opinions on that, as opposed to:
|
src/unix/Lwt_fmt.mli
Outdated
val stderr : formatter (** Formatter printing on {!Lwt_io.stdout}. *) | ||
|
||
val make_formatter : | ||
commit:(unit -> unit Lwt.t) -> fmt:Format.formatter -> formatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a ()
argument at the end, so future versions can add optional arguments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
This looks cool. I think it should go in the core lwt library, provided it's only accessed through module aliases (and thus is of minimal overhead for people who don't use it). |
I like it as a top-level module slightly more than in |
It currently depends on |
I strongly think this should be in Lwt itself, and I'm not going to bother creating a package for that alone. I think leftpad-ifying the OCaml ecosystem by creating lot's of 100-lines packages that would be perfectly at home in other packages is a complete waste of time and is very user hostile. As for Currently, the functions of |
Very well. Perhaps this is already proposed, but I suggest we merge this as is, putting it into |
@aantron That seems like a good direction for me. Let me fix what I discussed with @Octachron above and we will be good to go! :) |
I just added a new commit that make the API a bit more regular, as discussed with @Octachron . If CI is happy, this is ready to be merged as far as I'm concerned. |
Ok, thank you! |
Something that's unrelated but still important: Is there a plan for Lwt to move away from having multiple top level modules per library? It would be really nice if Lwt switched to using The reason why I'm raising this here is that this PR adds yet another toplevel module which is a bit unfortunate. |
@rgrinberg lwt has multiple distinct libraries. If you were to wrap everything, |
To me this is a good thing. Yes, this can look a little less aesthetically pleasing, but it streamlines understanding new code for people as you no longer have to think about which library introduces a particular module. |
I want to reorganize the module structure of Lwt eventually, but I have no concrete plan to do it at the moment. I think putting modules now in |
This is a prelude to solving #310. This adds a new module
Lwt_fmt
which exposes some lwt-powered printf function in the style of Format. The functions return promises and are compatible with all the Format/Fmt combinators. The implementation is not complicated, but uses some fairly subtle Format tricks. I added some tests to ensure that the behavior of flushing and composition was correct.For now, the module is in
lwt_unix
. I believe this should not be the case, but I expect @aantron to have better ideas on how and what to split where.cc @Octachron @c-cube (@dbuenzli) as fellow Format fetishists.