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

Allow nothing to be printed #32148

Merged
merged 2 commits into from
Aug 5, 2019
Merged

Conversation

oxinabox
Copy link
Contributor

@oxinabox oxinabox commented May 26, 2019

I don't have julia installed so I am just sketching this out.

What this should do:

  • allow nothing to be printed, and interpolated into strings
  • not allow nothing to be interpolated into commands.

This PR partially undoes #27352.
Turns out that not being able to print nothing is just really annoying.

@JeffBezanson
Copy link
Member

This is the kind of thing that causes somebody with the username nothing to get millions of emails 😛

@oxinabox oxinabox changed the title WIP: Allow nothing to be printed Allow nothing to be printed May 27, 2019
@oxinabox
Copy link
Contributor Author

The 1 CI failure was a network blip.
If someone wants to restart that one it should pass

@oxinabox
Copy link
Contributor Author

I guess this should be tagged with [Triage]

@JeffBezanson
Copy link
Member

Seriously though, I don't fully understand the argument for this. Why is it correct for a program that was trying to print something else to print the string nothing? If that's considered dangerous for commands, isn't it also dangerous for other strings (which might, for example, become part of commands later)?

@oxinabox
Copy link
Contributor Author

It just breaks so much code, so often.
One of the more annoying cases it breaks,
is when you are doing println debugging
and you do something like println("In central method, x=$(x)") and then that breaks.

But it breaks packages all the time when they forget to special case it.
E.g.
JuliaComputing/TableView.jl#19
felipenoris/Mongoc.jl#29

A particularly common place they forget to special case it is in error messages.
E.g.
throw(ArgumentError("Invalid Arguments for Fooing the Blarger ($x, $y$)")
Which then break with an error about printing nothing, rather than the intended error message.

Why is it correct for a program that was trying to print something else to print the string nothing?

If I understood our previous discussions in #30757
print has no real semantic meaning, (unlike show).
It is just a human readable representation of the thing being printed.
So "nothing" is perfectly human readable and that is what matters.

f that's considered dangerous for commands, isn't it also dangerous for other strings (which might, for example, become part of commands later)?

If you've put it into a string, e.g. via string interolation, then you know you are passing a string into a command, (and not the result of some other command).
So you won't run into the original issue described in #27352
I don't really think it is dangerous for commands.
Its just that that was the original motivation given in #27352
Where were other ways that could have been resolved.
But that one seems reasonable at the time.

To my mind that discussion and the expansion from
"Lets not let it be interpolated into commands"
into
"Lets not let it be printed/interpolated anywhere"
was something that seems reasonable.
Now we have tried it out.
Turns out it is pretty annoying.
So now we can and should change our minds.

@JeffBezanson
Copy link
Member

print has no real semantic meaning

Every generic function has to have a meaning, or else there is no way to tell which methods might make sense. But I'll put this aside and assume there is a better argument than just nihilism.

println("In central method, x=$(x)")

Here it's better to use @info "In central method" x which is shorter and produces nicely formatted output. Especially if you want to show many variables it's much more convenient.

throw(ArgumentError("Invalid Arguments for Fooing the Blarger ($x, $y$)")

Yes, this is a case that seems to come up a bunch. The problem is that string interpolation (and print) is a bad way to show a general value, and you really need repr/show. I don't know how to solve this. For ArgumentError it would make sense to add a field for the argument values so you don't need to write the boilerplate ($x, $y, ... every time. That isn't a totally general solution though of course.

@JeffBezanson JeffBezanson added the display and printing Aesthetics and correctness of printed representations of objects. label May 28, 2019
@oxinabox
Copy link
Contributor Author

Here it's better to use @info "In central method" x which is shorter and produces nicely formatted output. Especially if you want to show many variables it's much more convenient.

I agree, but it doesn't always generalize,
sometimes you want to provide more context and wrapping it up in a nice string is nicer.
Better example:
x > 3*10^8 && @warn "x ($x m/s) exceeded the speed limit"
There is certainly scope for debate as to if that is nicer than:
x > 3*10^8 && @warn "x exceeded the speed limit" x
I'ld still lean towards @info but I know others would go the other way.

It also comes up in the ArgumentError case where you want to write things midsentence.

ArgumentError("Inputs should be equal.  x (== $x) != y (== $y)")

One option is that they should get into the habit of writting

ArgumentError("Inputs should be equal.  x (== $(repr(x)) != y (== $(repr(y)))")

But sometimes you don't want repr because you've got a carefully written repr that does parse,
but it is way too long and not as nice as your string.

At the end of the day,
blocking interpolation of nothing is to prevent one kind of mistake,
but it introduces the ability to make another,
and I would argue that the one it introduces is more annoying.
Yes, if you didn't make mistakes, you wouldn't make either.
but I've now seen multiple very good julia programmers interpolate nothing so...

@iamed2
Copy link
Contributor

iamed2 commented May 28, 2019

I strongly believe that the existing error behaviour is much worse than printing something.

The default behaviour for a new type is to show. If I made an alternate type struct MyNothing end, it would print as MyNothing(). There's no reason to pull that rug out from under the user for Nothing; printing a Nothing has no more or less semantic meaning than printing a MyNothing. It would be different if the default behaviour for print was to error and any type had to opt in. In that case, the user would be expecting some types to fail and would control for that case. Right now Nothing is the only (AFAIK) type that fails on purpose.

As for printing the string "nothing", I believe either we should stick with the convention for singletons to print the name of the global singleton instance, if there is one (e.g., "missing"). Even the default "Nothing()" would be better than the current error state.

@JeffBezanson
Copy link
Member

JeffBezanson commented May 28, 2019

¯\_(ツ)_/¯ Ok.

base/show.jl Outdated Show resolved Hide resolved
fix missing bracket

fix up whitespace

Keep defining custom show for nothing

add printing of nothing

Let print of nothing fallback to show
@oxinabox
Copy link
Contributor Author

oxinabox commented Aug 3, 2019

Rebased. Assuming tests pass can this be merged?

ararslan pushed a commit that referenced this pull request Aug 20, 2020
ref #32148
string(nothing) is allowed because print(nothing) is allowed
simeonschaub pushed a commit to simeonschaub/julia that referenced this pull request Aug 29, 2020
ref JuliaLang#32148
string(nothing) is allowed because print(nothing) is allowed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants