-
Notifications
You must be signed in to change notification settings - Fork 1.1k
A crazy idea: provide a reasonable toString for case classes #1341
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
Comments
misclicked and submitted too early. Still improving the proposal. |
Why |
|
Counter-idea: make case classes
|
Why not XML? |
Added sections Introduction, Current Status and Real Motivation. |
.toString
generate JSON
@densh I like your idea. I've updated the issue title&start. class A[T]{}
(new A[String]).toString |
@densh - with Dmitry's proposal I guess you could just call the |
Updates: added sections Drawbacks and Alternatives. |
I'd rather we invest our energy in coming up with a mechanism for abstracting over the structure of case classes so that we can express the boilerplate the compiler generates for case classes in the library. Pardon my poor quasi-quote hygiene, but wouldn't it be cool if you could implement
|
100% agree with @adriaanm. |
@adriaanm, I agree it would be nice to have a better mechanism for implementing such proposals. Actually, the your proposed version of Or am I misunderstanding what snipped you proposed does? |
I suppose what Adriaan wants is the possibility to do this at compile time. |
... which could be achieved my making productPrefix and productElements |
Added an opening to the issue, covering why this (crazy) idea was submitted. |
Mentioning #1347 here to make sure they are "linked" from github's perspective. |
Uh oh!
There was an error while loading. Please reload this page.
When having discussions with people in the community, I saw a misconception that as soon as compiler developers have some idea, it quickly gets implemented and shipped in the next release. At the same time, the misconception suggest that ideas from outsiders never get support and are never implemented.
The source of this misconception is that decisions that originate from compiler developers that do are not supported by majority in compiler team(s) are never publicly presented.
This creates a biased distribution for ideas that are presented to public: most of them are already fleshed out, discussed in private and preliminary decision is frequently made. They have been privately discussed for month if not years in order to cover all the corner-cases of both abstract idea and practical implementation.
This issue exists to show discussion that normally happens in private, to demonstrate that quite a few of ideas that we have are not implemented, as
not good enough
. This is an example of such a idea, that may simplify everyday life of a particular developer (me) but I believe it's not good enough (yet?) to be implemented.The proposal
This proposal proposes a best-effort to make toString on case classes be JSON.
Another good option is proposed by @densh in comment below.
I don't have preference over either of two currently, as his version has also some convincing advantages, such as repl compatibility. Additionally, AFAIK this is what Python does.
Introduction:
I've been thinking about it for a year or so already, sometimes leaning towards "it's very easy to implement, and it makes common usage easier, so why not do it", while sometimes leaning towards "I like JSON as much as I like XML".
Recently, we've had a lot of discussions with @felixmulder on how should dottydoc compiler part and web-part communicate. And it seemed that what he intended to implement is comparable in amount of code to implementing inside the compiler.
I'd like to finally have this discussion, mostly to gather opinions of people and see if we should do it.
If we don't do it in Dotty, I guess it's better to never do it. So why not have discussion now?
Motivation
When discussing including serializer in standard library, in most cases this is seen as a bad idea, as there are multiple formats available and we do not want to bear the burden of supporting all of them. In particular there have always been an argument not to include JSON\XML\Protobuf serializer in standard library\compiler as we'll need to maintain it.
Current status
Compiler generates a toString on case classes that calls into
That is implemented as
Idea
TLDR: replace parenthesis with brackets and include field names. Add a best effort
fromString(s): Option[CaseClass]
method.Thinking about it, we already have a toString defined on all classes. So we already have a conversion from every case-class to a String. I propose to make this string try to be JSON.
And make companion object have a
fromString
method that does best-effort in trying to create the class from aJSON
string.Design guidelines
Several details of how I would prefer it to work:
toString
generated for case-classes emits a pretty-printed version of JSON, that can be compacted by a library function that strips whitespaces;fromString(s: String): Option[CaseClass]
is generated on companions of case classes;fromString
does not use reflection, but instead relies on existence offromString
for all the fields;fromString
on fields that are not case classes can be user-defiend in a companion of a field class or added through implicit conversion;fromString
is provided for some parts of stdlib such as primitives, commonly used classes such asjava.util.Date
, standard collections. For java-defined classes it is added through implicit conversion;fromString
for it automatically based on the hierarchy;fromString
andtoString
do not try to provide best performance and fit all requirements. They aren't to replace JSON serializer but to provide an easy to use and convenient default that makes sense(unlike current toString that is impossible to read on nested case classes)Proposed implementation
(c: CaseClass).toString()
_class$
with a fully specified class name of what is being serialized;\n\t${field-name}: ${fieldValue}
to every field, concatenates it with field from step 1 and wraps all this in{}
.fromString(s: String): Option[CaseClass]
fromString
s, taking into account structure of JSON. It would need to import the scope of companion class of field type. See example below for illustrationfromStrings
calls for fields returned None, returns NoneDemonstration:
Arrays & stuff that has crazy toString
First of all, the provided version of toString does not guarantee that it returns a valid JSON.
And even if it does return a valid one, it provides no guarantee that you can deserialize from it.
Take example of
I'm fine with this state, as this proposal does not aim to replace serialization frameworks and it does not make current situation with useless toString worse, while it would help in many common cases.
But If we decide that we would like to always generate valid JSON, we can instead of calling a
toString
in this code:call a
toJsonString
method, that has a low-priority implicit decorator implementation that callstoString
and provides correct escaping. Case classes would have a nativetoJsonString
that forwards totoString
Drawbacks
Alternatives
ScalaRuntime.toString(Product):String
: to include some pretty printing;Real motivation
show
, but if I need to read the internal raw structure of raw tree I still use Lisp-formatter in my emacs.The text was updated successfully, but these errors were encountered: