Closed ghost closed 6 years ago
What are the reasons behind it? I find a quite fundamental part of the language - just look at OCaml for a language that does not have this feature and triggers never ending requests for it!
Doing this would make life harder for every beginner out there and cause a bad first impression. Please, do not remove it!
@nc-x Instead of removing, you can help improve it.
Also against the removal of this. I outlined my reasons on IRC: https://irclogs.nim-lang.org/12-06-2018.html#14:07:47
Doing this would make life harder for every beginner out there
Well I am certainly a beginner and having a default $ for objects did make my life harder
What are the reasons behind it?
The reason is that when you have a single file in which you have an object and you use $ in that file, everything works ok. But now if you try to use $ in another file, all the values are printed as ...
because they are not exported. And then you waste hours trying to find out why are you getting ...
and in the end you either unneccessarily export all fields or you have your own little $
.
After wasting time on this exact same case, IMO i would prefer not to have a default $ for objects and have the compiler give an error when trying to print an object so that without wasting time I can create my own $.
and cause a bad first impression.
No it won't.
Rust has a clear difference between Display
and Debug
and it is pretty much liked by everyone in the community.
In Nim, we also get the same kind of distinction with $
vs repr.
The proposal is to remove default $
for objects but improve repr for more use cases.
I've hit the bug twice now that my own $
failed to be imported and the compiler used system.$
instead which is wrong. This is just too error prone and should be done explicitly via implementToString(MyType)
where implementToString
is a simple template in system
.
This is just too error prone and should be done explicitly via implementToString(MyType) where implementToString is a simple template in system.
IMO that is the wrong solution, since the point of the default $
is to make debugging easier. Adding implementToString
to every type you want to debug is horrible.
It would be better to change repr
into something that is actually useful (most importantly, it needs to handle collection types somehow), and maybe introduce a separate echo
that uses repr
instead of $
.
I think it would be easier to warn novices in the manual about the reason why ...
can appear when printing an object.
At the very, very, very least, there should be some macro that implements what we have today, so that people who want to keep this behaviour just need to from sugar import printObjects
The introduction of new proc like dbg
that can print a more complete and accurate data might be the right solution. It can also support output in some machine-readable format such as JSON that certain debuggers might be able to display in even better way (as expandable tree of items, with embedded HTML or graphical fragments, etc).
the point of the default $ is to make debugging easier.
$ is meant for converting to a string, not for debugging. repr is meant for debugging and should be improved if it does not fulfill its requirements.
I think it would be easier to warn novices in the manual about the reason why ... can appear when printing an object.
Yeah, it would be a 1 line change. But how many people do you think are going to remember it? Also, how many people do you think read the manual line to line?
from sugar import printObjects
Why is this any better than echo obj.repr
(if repr is improved) or implementToString(obj)
? Just because you have to type .repr
or implementToString
for every object does not provide enough reasoning for this import IMO.
$ is meant for converting to a string, not for debugging. repr is meant for debugging and should be improved if it does not fulfill its requirements.
What I mean is that the only use case for system.$
for objects is debugging (at least I can't image any other use case). If it's removed, that use case must be covered some other way. An improved repr
covers the use case, but implementToString
does not. I agree that it's useful to have separate procs for debug and stringify, so I agree that system.$
for objects should be removed.
It would be better to change repr into something that is actually useful (most importantly, it needs to handle collection types somehow), and maybe introduce a separate echo that uses repr instead of $.
Yes, good, I like this proposal better than my own.
No matter whether one points users to repr
, people will just try echo myObj
. This should work and produce something reasonable.
The current behaviour works, is convenient, can be easily overriden by implementing $
for some particular object, and apparently has the only downside that fields that are not exported appear as ...
. I really fail to see a problem.
If ...
is so mysterious, just change it to <private>
so that the reason for not seeing a value would be clear
how many people do you think read the manual line to line?
not many, but people who have some issue printing objects would find this note.
With the proposal to force users to use repr
- how many users would find about it?
not many, but people who have some issue printing objects would find this note.
Unfortunately, no one has enough time or interest in searching for a needle in a haystack. This is reason for the "We want better compiler error messages" movement in this decade which Elm, Rust, etc. are trying to follow as well as pioneer.
With the proposal to force users to use repr - how many users would find about it?
If the user tries to echo myObj
and the compiler shows message
$ is not defined for myObj
implement $ for myObj, or use myObj.repr
I would say anyone and everyone would be able to find it with ease.
When I just want to write some code to try nim like this:
type
Foo = object
x: int
f: float
s: string
echo F()
echo F(x: 1, f: 1.0, s: "hello")
Now I have to write '$' proc, feel rather bad.
@slangmgh
Yeah, but if you try to write echo F(x: 1, f: 1.0, s: "hello")
in another nim file, all you are gonna get is a few ...
. To workaround it, you need to implement $
yourself or you would need to export all the fields to the objects, which means that you are just making the fields public which may lead to accidental value change.
And this behaviour, though easy, is certainly not intuitive or great.
This is the exact scenario being discussed here, and the alternative proposed is that, you could use echo F(x: 1, f: 1.0, s: "hello").repr
to print the value if you don't want to implement $
yourself, or you go and implement $
yourself.
If we remove the default '$' for object, we need implement '$' not only when I access the object in another file, but also in the same file. An more clearer error message is enough.
Having a $
for objects that works is very intuitive, it composes incredibly well with a $
for other types. I would argue that it should be extended to ref
objects too.
repr
should be improved, but it's use case is to look at the low-level details of objects. This is why when you repr
an object with a Table
field you will get a lot of "hidden" information about the Table
object. This IS useful, and adding special cases for things like Table
in repr
is bad.
If ... is so mysterious, just change it to
so that the reason for not seeing a value would be clear
That should be done in any case, yes.
Looks like $
for ref objects was rejected here: https://github.com/nim-lang/Nim/issues/7890#issuecomment-392680367 :'(
IMO the decision has been made: $
for objects should remain and we should add $
for even more generic things (ref types for example).
See https://github.com/nim-lang/Nim/issues/8149 for further discussion
I'd like to comment on this as I am having frustrations with this myself and I was late to the initial conversation. It sounds like people were against moving it to debug()
and I can't follow the final statement about repr()
.
What if we didn't disable it but didn't force it on users? We could put it under a pragma. {.supplyDefault$.}
Having any user defined object supplied a $
operator is both a neat debugging tool but also an annoyance, especially if it sometimes overrides user supplies $
s (unless that was fixed). That said, this also conflicts with Nim's design of having a strong static typing system and isn't intuitive. It's broken my code a few times now...
Can we AT LEAST have a command line/nimscript option to disable these? It's extremely annoying to have to declare `proc `$`(x: myType) {.error.}
and if the default does override the user defined one in certain cases, it isn't even guaranteed to work.
It causes more headaches than implementing
$
for our objects ourselves.