-
Notifications
You must be signed in to change notification settings - Fork 190
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
WIP Bijective Read/Show instances for patterns #465
Conversation
I see that the While this is a not result of your pull-request, perhaps you'd be willing to add a fix for this? |
This has been done in |
I am taking a look at the other two types that have user-readable pattern synonyms, CmsgId and MsgFlag. MsgFlag is a bitmask so it is non-trivial to serialize and unserialize and the pattern translation would only occur in cases where only one flag was used. I am probably not going to implement any read or show instances unless there is a compelling reason to, and even then would need to know how exactly we wanted to read and show them. For CmsgId, I noticed that the pattern |
I also noticed that the second field of CmsgId is named |
I rebased onto the updated master and added instances for CmsgId. As long as everything I have implemented so far works (subject to style change on the actual |
Good catch! This is just a typo. I have fixed it in |
Good catch! Thanks! |
I added @vdukhovni Do you think that |
I see that this is presently only used via I don't see any obvious reason why users should not be allowed to use this control message directly, provided they know it only works for unix-domain sockets. So my instinct is that it should be exported. Users should be able to pattern match on it, and can in any case instantiate it numerically, so they may as well have access to the pattern, unless you know of a reason for them to not be able to? The documentation for the pattern in question can then explain that they are typically supposed to use it via case (lookupCmsg CmsgIdFd cmsgs >>= decodeCmsg) :: Maybe Fd of
Nothing -> return (-1)
Just (Fd fd) -> return fd Does the above make sense to you? |
@vdukhovni Thanks. I have exported it in |
@archaephyrryx Did I answer to all questions? If you wish, I will rebase this PR onto |
I think he also asked about |
First of all, The current behavior:
I'm OK with this if it is not pre-defined. But for pre-defined ones, I would like to have:
|
IIRC the data type in question is a |
Ah. I understand the question! Yes, it's hard. Displaying |
adds helper module Network.Socket.ReadShow for defining bijections between types, to be used for simultaneous read-show equivalence definitions implements read/show instances for SocketOption, SockType, and Family according to this paradigm additionally removes a bug in Network.Socket.Options where the OOBInline pattern name was unintentionally allcaps-ed in one of the CPP ifdef branches
implements bijective read/show instances for CmsgId adds missing ghc-dependent cpp guards around version-dependent pragmas and inlined haddock annotations adds commented-out pre-implementation of bijective read/show boilerplate for MsgFlag type
I rebased onto the updated master to include the various changes that were made since my last push. I think it would still be worthwhile to make the code I wrote more robust and less WIP, before it gets included in any releases at least. I haven't had a chance to rigorously test the behavior of the bijective instances I wrote, and in any case some parts could definitely be cleaned up a bit since some of what I did was proof-of-concept over polish. As far as the actual read and show methods are concerned, all of the nullary patterns should behave correctly since there is no real ambiguity as to how to represent them. For types that have a unary pattern on a CInt, the encoding currently appends the CInt representation to the name of the generic pattern/constructor without any intervening characters, so that it is considered a single token to make parsing more easy. For patterns that take two CInts in a tuple, the first CInt is directly appended, and the second is appended after the second with an intervening '_' character so that they can be parsed from a single token. One pathological case that @vdukhovni pointed out to me directly was that, in cases where a CInt happens to have a negative value, a '-' character would appear that would potentially cause the tokenization to break. I wanted to discuss stylistic choices in any case so I would probably wait for your feedback before merely patching that by conversion to an unsigned integral type. The choice to make all encodings single-token was largely to avoid having to deal with parentheses and precedence levels, which are mostly irrelevant as far as the nullary patterns were concerned. It also simplified the bijective definition a great deal. I am open to feedback on alternative approaches if the style isn't quite what you had in mind. |
I also wanted to point out that because CmsgIdFd is not defined for the Windows version of the code, exporting it in Network.Socket breaks the AppVeyor test suite completely. |
Promotes UnsupportedSocketType pattern to first element of pairlist to prevent patterns whose CPP macros are undefined from greedily displaying when calling show for -1 value Adds UnsupportedCmsgId pattern to Network.Socket.*.Cmsg and ensured proper short-circuiting Reimplements read/show used in Network.Socket.Posix.Cmsg in Network.Socket.Win32.Cmsg, omitting POSIX-exclusive CmsgIdFd pattern Removes POSIX-exclusive CmsgIdFd from Network.Socket export list Adds UnsupportedCmsgId pattern to Network.Socket export list
It seems that some of my commits have wiped the conversation history, so I will attempt to restate the major points I noted previously.
Otherwise, I am willing to continue working on polishing some of the rougher implementations, though more major changes might take more time. |
adds pattern UnsupportedSocketOption for short-circuit, as addendum to previous commit. Also adds export of said pattern to Network.Socket
The current policy avoids partial exporting. Things MUST be exported on all platforms. So, if |
This short-circuit approach looks fine to me. |
If you can keep backward compatibility, you can do what you want. |
You are doing more than I expected. ;-) Please move forward. |
No rush. I would like to merge your PR when you are satisfied. |
Network/Socket/Options.hsc
Outdated
|
||
socketOptionPairs :: [Pair SocketOption String] | ||
socketOptionPairs = | ||
[ (UnsupportedSocketOption, "Unsupported") |
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.
I prefer to "UnsupportedSocketOption" so that the string is the same as the pattern synonym.
Network/Socket/Options.hsc
Outdated
socketOptionBijection = Bijection{..} | ||
where | ||
cso = "CustomSockOpt" | ||
defFwd = \(CustomSockOpt (n,m)) -> cso++show n++"_"++show m |
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.
I would like have a space (' '
) before/after ++
.
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.
Leaving out spaces ensures that the read
conversion only needs to see a single token. While the style would be improved, it would be difficult to implement without requiring more invasive changes on the other side.
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.
Unless you meant space characters in the source rather than space characters in the function result.
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.
I meant cso ++ show n ++ "_" ++ show m
. But this is not mandatory. :-)
Unifies several common usage patterns of Network.Socket.ReadShow for types with bijective read/show definitions, consolidating reused boilerplate code to in-module functions
refactors definitions of _parse and _show in Network.Socket.ReadShow to be specific to Int-like types, with a single-quote character separating the two tuple elements introduces _readInt and _showInt for representation and parsing of negative numbers encoded with underscore ('_') instead of minus ('-') changes variable names in defRead and defShow to more appropriate descriptors explicitly reimplements bijections for Family and SocketType to use `_readInt` and `_showInt` instead of regular `read` and `show` methods of CInt; SocketOptions and CmsgId code unchanged as _parse and _show are internally reimplemented but their calls are unchanged
As far as this approach goes, I think that there isn't much more left to do. I am not planning on working more along these lines, though I may go with the suggestion of @vdukhovni to later implement a more feature-complete variant (on a separate branch) that doesn't ignore precedence and displays values in such a way that they would be valid in source code. As it stands, however, I am finished with this particular pull request. |
@kazu-yamamoto The basic issue that remains to decide is whether we want to have For example, instead of I think that this PR is not far from the more strictly correct approach, and unless you'd rather go with the current version as-is, I'll encourage @archaephyrryx to take the next step... |
I have merged this PR. @archaephyrryx Thank you for your great effort! If you took the next step, it would be appreciated. |
adds helper module Network.Socket.ReadShow for defining bijections
between types, to be used for simultaneous read-show equivalence
definitions
implements read/show instances for SocketOption, SockType, and Family
according to this paradigm
additionally removes a bug in Network.Socket.Options where
the OOBInline pattern name was unintentionally allcaps-ed in
one of the CPP ifdef branches