-
Notifications
You must be signed in to change notification settings - Fork 372
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
proper reprs for Hy models #1360
Conversation
a61e090
to
30dd07a
Compare
This breaks |
Nice! I don't think |
Although I like the idea, is there a reason why the HyCons repr is totally different in style from the others (e.g. |
@kirbyfan64, this is so nested conses are still readable as dotted lists, for example => (cons 1 (cons 2 3))
from hy.core.language import cons
cons(1, cons(2, 3))
<HyCons (HyInteger(1) HyInteger(2) . HyInteger(3))>
=> '(1 2 . 3)
from hy import HyCons, HyInteger
HyCons(HyInteger(1), HyCons(HyInteger(2), HyInteger(3)))
<HyCons (HyInteger(1) HyInteger(2) . HyInteger(3))> Python >>> object()
<object object at 0x000002513237A770> Note also, that And furthermore, That said, I don't have very strong feelings about keeping this version of the HyCons repr. I'd consider a better version, but other things might have to change too. How would you want it to work? |
Touche. |
@kirbyfan64, Thinking about <HyCons (HyInteger(1) HyInteger(2) . HyInteger(3))> --should probably be spread over multiple lines like the other compound models. Maybe like this. <HyCons (
HyInteger(1)
HyInteger(2)
. HyInteger(3))> If we want it to round trip, then HyCons(HyInteger(1), HyCons(HyInteger(2), HyCons(HyInteger(3), HyInteger(4)))) --is the most obvious. But we'd want that spread over multiple lines too, to be consistent with the reprs from the other models. HyCons(HyInteger(1),
HyCons(HyInteger(2),
HyCons(HyInteger(3),
HyCons(HyInteger(4),
HyInteger(5))) But I'm not sure that I like the indent for a single list. So we could just not indent conses. HyCons(HyInteger(1),
HyCons(HyInteger(2),
HyCons(HyInteger(3),
HyCons(HyInteger(4),
HyInteger(5))))) But how should any of that look with a tree structure made from conses? Something like--
Hy currently renders it like--
--and Common Lisp too. Notice how we lost dots, because it's a valid list prefix when the cdr is also a cons cell. This PR currently renders it like-- <HyCons (<HyCons (HyInteger(1) . HyInteger(2))> <HyCons (HyInteger(3) . HyInteger(4))> HyInteger(5) . HyInteger(6))> --which is too long to really read. If we spread it over lines it's better. But is it good enough? <HyCons (
<HyCons (
HyInteger(1)
. HyInteger(2))>
<HyCons (
HyInteger(3)
. HyInteger(4))>
HyInteger(5)
. HyInteger(6))> The round-trip version over lines without indents-- HyCons(HyCons(HyInteger(1),
HyInteger(2)),
HyCons(HyCons(HyInteger(3),
HyInteger(4)),
HyCons(HyInteger(5),
HyInteger(6)))) --is hard to read. With indents-- HyCons(HyCons(HyInteger(1),
HyInteger(2)),
HyCons(HyCons(HyInteger(3),
HyInteger(4)),
HyCons(HyInteger(5),
HyInteger(6)))) This seems less bad. It would be clearer if the cars had their own line though. HyCons(
HyCons(
HyInteger(1),
HyInteger(2)),
HyCons(
HyCons(
HyInteger(3),
HyInteger(4)),
HyCons(
HyInteger(5),
HyInteger(6)))) It's much easier to see the structure this way. But look what that does to long lists. HyCons(
HyInteger(1),
HyCons(
HyInteger(2),
HyCons(
HyInteger(3),
HyCons(
HyInteger(4),
HyInteger(5))) Maybe this is okay. And it round trips (given <HyCons (
HyInteger(1)
HyInteger(2)
HyInteger(3)
HyInteger(4)
. HyInteger(5))> Which do you prefer? Or do you have a better idea? |
IMO the last is the best (which is basically the current version but with indents, right?). |
I redid the |
Looks great to me! |
3c82857
to
4568a34
Compare
I colorized the reprs of the compound models to make deeply nested structures more readable. Try it out. Python reprs are not usually colorized like this. They're not usually indented either. I feel like I'm breaking convention a bit here. Most Python reprs are not colored, are not indented, and have no newlines. But it's much closer to normal Python than the Hy-like reprs we had before, to the point that you could manually copy/paste into a Python repl and usually expect it to work. If this is too much trouble, we could have a module flag in Hy models to turn off coloring just for the models (if we turn it off in I also noticed that the HyCons(
1,
HyCons(
2,
HyCons(
3,
4)))
list*(
1,
2,
3,
4) The problem is, that won't round trip either, because One option is to give the HyCons.list(
1,
2,
3,
4) |
Pretty cool. It might make sense to separate the pretty-printing code from the |
I don't see how. Python's native
A mechanism to disable or enable the coloring and pretty printing would make sense. This is a great use case for a dynamic var. hylang/hyrule#51. Until that's implemented, a module-level flag would have to do. But the way the reprs are built, separating them altogether (without adding a lot of duplication) seems harder. It's much easier to add the pretty printing when the string is built than it is after, which would be error-prone. Starting with a pretty string and stripping the color works pretty well, but there might be edge cases where it strips too much. Stripping indents and newlines seems even more error-prone. We could give Hy models a |
Okay, then, are we ready for tests? |
The I'll need to mention the |
9e6cfce
to
e6ef61f
Compare
Okay, there are docs and tests. Do these tests look sufficient? It should probably have a NEWS entry too, but I'll save that for last after the rest has approval, since it's likely to conflict with other PRs. |
82a20f7
to
435ec2f
Compare
|
HyList([ | ||
HyFloat(1.0)]), | ||
HyDict([ | ||
HyFloat(1.0) # odd |
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.
What do these comments with the text "odd" mean?
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.
It means there's an odd number of elements in your HyDict
. This is allowed, since a HyDict
is really a list, but it's a mistake if your macro expands to this, because a dict
is built from pairs. So I wanted to make it very visible for debugging purposes.
Note also that # odd
only shows up when PRETTY is on.
You might legitimately have an odd number in an intermediate stage of the macroexpansion though. So I don't want to add error checking to the HyDict
methods to prevent that state.
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.
Oh, interesting. That makes sense.
435ec2f
to
49edd62
Compare
49edd62
to
af8d209
Compare
I made two edits: I added the name |
After playing around for a bit, there's only one thing I find odd:
Why is there a trailing comma only on |
The short answer is, "it was easier to implement that way". Would you prefer that I add a trailing comma to everything, or remove it from |
I mean, I'd prefer the latter, provided it's not too difficult. |
Yeah, it seems best not to have trailing commas in |
Okay, that wasn't too hard. How's that? |
Closes #914.
This will make development of macros sooo much easier, since we can tell exactly what we're looking at in the repl with macroexpand or any other manipulations of Hy models.
The reprs for HyList and derivatives will use two-space indents, so even deeply nested structures are readable in the repl.
This also makes the reprs valid Python code to reconstruct the hytree in most cases, as is preferred in Python. This will improve Python interop somewhat, since if a Hy model leaks through, the error message will make sense as a Hy model, instead of looking like Hy code that could be confused for some kind of Python display.