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

Add a print function that prints to stderr #1777

Open
1 task done
dann-merlin opened this issue Mar 28, 2024 · 5 comments
Open
1 task done

Add a print function that prints to stderr #1777

dann-merlin opened this issue Mar 28, 2024 · 5 comments

Comments

@dann-merlin
Copy link
Contributor

dann-merlin commented Mar 28, 2024

What new feature should Elvish have?

This is probably a question of taste, but I think builtin print-to-stderr functions would be useful.

I know that I can just pipe the output of print or echo to stderr and that I can just write such a function myself.
However, I think for scripting in particular this would be a great addition, as printing errors is something that is very commonly done and having a shortcut like this would make it a bit less tedious.

It would probably be sensible to add error versions for the three main printing functions.

Here are some proposals how these functions can be called. I personally like the err-suffix most.

original e-prefix err-prefix e-suffix err-suffix
print eprint errprint printe printerr
printf eprintf errprintf printfe printferr
echo eecho errecho echoe echoerr

These functions should maybe also automatically style the output in red (or maybe only in the case of echo, idk).

I would also be open to implement this my self, if there's interest in this. While I don't really have experience with go, I don't think this should be too hard.

Output of "elvish -version"

0.20.1+archlinux4

Code of Conduct

@xiaq
Copy link
Member

xiaq commented Mar 28, 2024

(Elvish doesn't have fprint, I think you misspelt printf? Also errecho and eecho seems transposed - that's not important though.)

I'm not sure about this. I agree with you that printing to stderr is common enough in shell scripts and it may warrant a bit of special treatment. But I feel that there's a bigger problem about providing feedback to the user and logging in general, and providing a parallel stderr version for echo, print and printf is only scratching at the surface. I don't have a clear definition to that problem or a clear solution in mind, so I'll need to think more about this.

Re naming, I'd go with the -err suffix with a dash, so print-err, printf-err and echo-err.

@dann-merlin
Copy link
Contributor Author

Ah, yes. I fixed the misspelling and switch-up.

Maybe elvish could have a log module, similar to python's logging module?
In that case it might look like this:

log:error some error
log:warn some warning
log:info some info
log:debug some debug info

by default these functions would have a default output file(descriptor), but they could also be configured to behave differently.
Also they might have some default style which could be changed as well.

About the other issues with these functions: Have you put them into words somewhere yet?

@xiaq
Copy link
Member

xiaq commented Apr 1, 2024

A log module with a runtime-configurable destination and style is definitely a reasonable building block, and it does make the need for separate stderr-writing commands obsolete.

The API is orthogonal to the echo/print/printf dimension though. Which one does log:error behave like?

There are some more high-level questions I'd like to have answered:

  • When should I just let something fail and print a stack trace vs catch and log an error?
  • Who controls the current logging level? The library author, the application author or the application user?

I think traditional logging libraries are fairly unopinionated in that they don't really answer these questions and just give you APIs to do whatever you prefer. Elvish should probably have an unopinionated logging library as a foundation but since shells are more in the business of "applications" I feel there needs to be either a more opinionated high-level library or at least a pattern.

(Another question is when multiple libraries use the logging library, how would the logging library know the source of each log message. This is a more technical question though, so no need to delve on it too much for now.)

@dann-merlin
Copy link
Contributor Author

dann-merlin commented Apr 2, 2024

These are some tough questions...

Sometimes an application might just want to print an error/warning to stderr without failing, if e.g. some parsed file does not look like it should, but the application can handle that and just keep going. In this case log:error would be appropriate.

I think the application user should probably be able to control the log level of an application (including its libraries).
However an application may want to disable all logging output for a library, because it e.g. would generate very noisy logs otherwise.
This on the other hand might be exactly what the user wants.

I think the best compromise might be that there's a variable LOGLEVEL which states the general preference of the user and some other way to somehow overwrite the loglevel an application set for an imported library.

I'm not sure what would be the most sensible way of doing this tough.
Here are some ideas:

  1. specific loglevel variables for libraries:
    If the user wants to see debug output for a fictional ffmpeg module a script might import, they could set
    LOGLEVEL_<module-name>=debug
    so
    LOGLEVEL_ffmpeg=debug
    or maybe something like: LOGLEVEL_OVERWRITE=ffmpeg:debug
  2. general forcing of user specified loglevel
    This approach would not have such a fine-grained control, but would be a little simpler.
    Instead of LOGLEVEL, the user might alternatively (LOGLEVEL would the be ignored) specify FORCED_LOGLEVEL=debug
    which would force the loglevel for all modules to be the one specified by the user.

I think I would prefer the first approach, but the second one might also be preferable due to its simplicity.

I'm not sure if there really is a need for a more opinionated high-level library.
I could maybe think of a echo-err or only err(or) which would really just be a call to log:error including some formatting like a timestamp and the location (i.e. line of code + srcfile).
Would that be kind of what you mean by "opinionated high-level library"?

Oh, also: when talking about these variables I had environment variables in mind, but they could (and in the case of elvish probably should) of course also be variables in a module in which case the naming would obviously be a bit different.
Edit: I'm not sure how a user calling an elvish script from another shell would set these variables without environment variables though.

@krader1961
Copy link
Contributor

Note that there are a large number of commands that produce output on the byte stream; e.g., to-lines. We probably do not want special cases of all those commands and it is unclear why commands like print and echo should have stderr variants while to-lines does not. There is also the potential for unexpected mistakes; e.g., echo-err hello | from-lines would not pipe the "hello" text to the from-lines command. As established earlier in this issue what would be more useful is an Elvish logging module that would take care of things like (optionally) time-stamping a message and provide context for where the message was emitted. Possibly also providing different behavior depending on whether the output destination was a tty or not.

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

No branches or pull requests

3 participants