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

Precedence-compliant Read/Show instances using Bijective pairs for patterns #466

Merged
merged 2 commits into from
Jul 17, 2020

Conversation

archaephyrryx
Copy link
Contributor

Adapts bijective read/show boilerplate in Network.Socket.ReadShow to be precedence-sensitive while maintaining full generality of base implementation.

Re-implements bijective read/show instances for SocketOption, SocketType, Family, and CmsgId.

Copy link

@vdukhovni vdukhovni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good overall.
I'm requesting a couple of changes, and would like to see this squashed to a single commit.
Also perhaps some tests added to test round-trip correctness read (show x) == x and a few select cases of explicit show x == "expected result".

Network/Socket/ReadShow.hs Outdated Show resolved Hide resolved
Network/Socket/ReadShow.hs Outdated Show resolved Hide resolved
Network/Socket/ReadShow.hs Outdated Show resolved Hide resolved
Network/Socket/ReadShow.hs Outdated Show resolved Hide resolved
Copy link

@vdukhovni vdukhovni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks! Basically done.

I'm asking @kazu-yamamoto to also review, and it'd be good if someone would suggest better names for _show and _parse which show and read a pair of integers, presumably wrapped by some constructor or pattern synonym. The names don't make that clear. Otherwise, this is good.

@kazu-yamamoto: The reason for the name prefix (constructor or pattern for the generic case) being optional, is that if we decide to assign patterns for, e.g., protocol numbers, then the generic case is just a literal number, because protocol numbers would have a Num instance even if they become newtype ProtocolNumber = ProtocolNumber CInt. We might then display some common protocols via their pattern names, such as TCP for 6 and UDP as 17, but most protocols would continue to display as just a number.

@kazu-yamamoto
Copy link
Collaborator

This looks excellent to me.

it'd be good if someone would suggest better names for _show and _parse

show' and parse'?

@archaephyrryx Could you add tests as @vdukhovni suggested?

@kazu-yamamoto kazu-yamamoto self-requested a review July 15, 2020 01:52
@vdukhovni
Copy link

it'd be good if someone would suggest better names for _show and _parse

show' and parse'?

To me, these don't quite say "show/parse 2 consecutive numeric literals". So perhaps showIntX2 and parseIntX2? Though a sufficiently concise name that's clear is a bit tricky.

@archaephyrryx
Copy link
Contributor Author

it'd be good if someone would suggest better names for _show and _parse

show' and parse'?

To me, these don't quite say "show/parse 2 consecutive numeric literals". So perhaps showIntX2 and parseIntX2? Though a sufficiently concise name that's clear is a bit tricky.

One difficulty is that the two functions convert between tuples of Integer-like values and strings containing a space-separated sequence of possibly-parenthesized integers. The tuple is necessary for _parse to be able to return two values so it is not natural to curry the input for _show, but any reference to 'tuple' in the name would be misleading as the string output of _show and the expected input for _parse are not represented as tuples.

@archaephyrryx
Copy link
Contributor Author

I also plan on squashing several of the commits before this PR gets merged, once all outstanding concerns have been settled. Unless I am mistaken, rewriting the history of this branch would wipe the conversation history of this PR, so I am planning to hold off until things are resolved. In any case, instead of merging right away, let me know that you intend to merge so that I can reorganize the commits more naturally.

@vdukhovni
Copy link

To me, these don't quite say "show/parse 2 consecutive numeric literals". So perhaps showIntX2 and parseIntX2? Though a sufficiently concise name that's clear is a bit tricky.

One difficulty is that the two functions convert between tuples of Integer-like values and strings containing a space-separated sequence of possibly-parenthesized integers. The tuple is necessary for _parse to be able to return two values so it is not natural to curry the input for _show, but any reference to 'tuple' in the name would be misleading as the string output of _show and the expected input for _parse are not represented as tuples.

Yes, getting the name to precisely capture the input/output types is difficult, and largely impractical. I still think that showIntX2 and parseIntX2 is about the best we can do, it captures the leaf data type and multiplicity, and leaves the "shape" (tuple) deliberately vague, because we're converting between a tuple (i, j) and a curried constructor application "Cstr istr jstr".

@archaephyrryx
Copy link
Contributor Author

To me, these don't quite say "show/parse 2 consecutive numeric literals". So perhaps showIntX2 and parseIntX2? Though a sufficiently concise name that's clear is a bit tricky.

One difficulty is that the two functions convert between tuples of Integer-like values and strings containing a space-separated sequence of possibly-parenthesized integers. The tuple is necessary for _parse to be able to return two values so it is not natural to curry the input for _show, but any reference to 'tuple' in the name would be misleading as the string output of _show and the expected input for _parse are not represented as tuples.

Yes, getting the name to precisely capture the input/output types is difficult, and largely impractical. I still think that showIntX2 and parseIntX2 is about the best we can do, it captures the leaf data type and multiplicity, and leaves the "shape" (tuple) deliberately vague, because we're converting between a tuple (i, j) and a curried constructor application "Cstr istr jstr".

Would showIntInt and parseIntInt be any better or does the 'X2' paradigm make more sense? IntInt is deliberately ambiguous between concatenation and tuple type signature, so it seems at least natural, even if not actually better than the X2 variation.

@vdukhovni
Copy link

Yes, getting the name to precisely capture the input/output types is difficult, and largely impractical. I still think that showIntX2 and parseIntX2 is about the best we can do, it captures the leaf data type and multiplicity, and leaves the "shape" (tuple) deliberately vague, because we're converting between a tuple (i, j) and a curried constructor application "Cstr istr jstr".

Would showIntInt and parseIntInt be any better or does the 'X2' paradigm make more sense? IntInt is deliberately ambiguous between concatenation and tuple type signature, so it seems at least natural, even if not actually better than the X2 variation.

I have no preference, either is fine.

@kazu-yamamoto
Copy link
Collaborator

I also plan on squashing several of the commits before this PR gets merged, once all outstanding concerns have been settled. Unless I am mistaken, rewriting the history of this branch would wipe the conversation history of this PR, so I am planning to hold off until things are resolved. In any case, instead of merging right away, let me know that you intend to merge so that I can reorganize the commits more naturally.

Please feel free to edit your commits (maybe by git rebase -i master) and do git push -f. I don't care even if some conversations are lost.

Defines a CmsgIdFd pattern (unsupported) in Network.Socket.Win32.Cmsg
and exports CmsgIdFd in Network.Socket
refactors and reimplements Network.Socket.ReadShow to allow
for precedence-sensitive Read/Show instances built on an underlying
bijective framework. Behavior conforms to derived read/show instances
by default but short-circuits to fixed strings when input matches
element of a list of paired elements defining a partial bijection.

adds several flexible helper-functions to Network.Socket.ReadShow
to allow for minimal-boilerplate implementations of bijective
read/show for arbitrary types in future.

Adds more descriptive documentation for non-obvious properties
of Network.Socket.ReadShow types and functions

reimplements instance declarations of read/show for types already
using bijective read/show definitions

Adds cases to Network.SocketSpec test suite to ensure that ReadShow-based Show instances produce expected output for each pattern-bijection type

Adds quickcheck-dependent (updated cabal file) tests to ensure
roundtrip equality for `read.show` for all types using ReadShow-based
instances over arbitrary values, specifically biased towards pattern
synonym values
@archaephyrryx
Copy link
Contributor Author

I did the rebase and the commits organized a bit better. I am probably finished with working on this PR for now, unless there are any specific adjustments you think would be appropriate. Feel free to merge whenever.

Copy link
Collaborator

@kazu-yamamoto kazu-yamamoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kazu-yamamoto kazu-yamamoto merged commit 16a2327 into haskell:master Jul 17, 2020
@kazu-yamamoto
Copy link
Collaborator

Merged. Thank you for your excellent work!

If you have further plans, please let me know.

@archaephyrryx archaephyrryx deleted the precedence branch July 18, 2020 18:49
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

Successfully merging this pull request may close these issues.

3 participants