-
-
Notifications
You must be signed in to change notification settings - Fork 48
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
Create "safe" functions that return Maybe a
instead of throwing an exception
#51
Comments
I'll look into this. Grepping for
around all of them or is there a way to narrow the results down by "notoriety"? |
Awesome @SirBoonami, Thanks! So, you have a good question. Can the calls into the C library produce exceptions? If so, then I like your approach. If not, it might be better to just get rid of the calls to We should also bring @geekosaur into this discussion. I wonder if we should even bother preserving the API. We could bump the version number to 2.0 and actually change the function signatures so we don't need unsafe/safe versions. Thoughts? |
A more useful check is to look for all occurrences of |
Good call. Including definitions and imports, there are currently 36 occurences of One more thing: All of these |
I was actually thinking about that, either via Except or by logging to
stderr (which you'll find in a few other places, some of which are annoying
to other users of the X11 package); we might want to go with an `Except
String`-based setup instead.
…On Tue, Apr 11, 2017 at 2:12 PM, Felix Hirn ***@***.***> wrote:
Good call. Including definitions and imports, there are currently 36
occurences of throwIf*. Changing these is a good start, we can take a
look at foreign exceptions after that.
One more thing: All of these throwIf* calls supply error strings (like "xGetCommand
returned status " ++ show status). Replacing these with a simple return
Nothing discards this potentially helpful debug information. Wouldn't Either
String a be a better choice?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#51 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB8SoGvoJWJj2w5aKaFZjM9PKMm9SlgUks5ru8KrgaJpZM4M5Poh>
.
--
brandon s allbery kf8nh sine nomine associates
[email protected] [email protected]
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
|
Not a fan of unconditional stderr logging either, even when tied to a compilation flag. Wouldn't want to drown the user in a flood of exception messages if he's looking for a specific one. Also, some exceptions naturally occur during normal production use, logging everything would needlessly inflate log files like Also, what is this |
Ah, thank you. I was thinking about |
`EitherT` is deprecated; `ExceptT` is the replacement. Also, nobody said
you had to use its `Monad` interface; how many people use `Either a`'s
`Monad`?
…On Tue, Apr 11, 2017 at 2:42 PM, Felix Hirn ***@***.***> wrote:
Ah, thank you. I was thinking about EitherT from either
<https://hackage.haskell.org/package/either> myself (which is virtually
the same thing). But I don't know if refactoring large parts of the lib to
use a different monad, sprinkling liftIOs and runExceptTs all over the
place is really worth the effort...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#51 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB8SoI-kPZMGDP2fzKgH5gsvgk_CljV5ks5ru8mKgaJpZM4M5Poh>
.
--
brandon s allbery kf8nh sine nomine associates
[email protected] [email protected]
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
|
So you mean our functions should look something like |
Probably. `Either` would also work for that usage, but both the old
`Either` and the `Error` instances were deprecated in order to make
`Either` a simple product type that doesn't favor either alternative and
`Except` the one that specifically considers its right type the normal one.
…On Tue, Apr 11, 2017 at 3:11 PM, Felix Hirn ***@***.***> wrote:
So you mean our functions should look something like a -> IO (Except
String b)? Because that's probably our best option imo...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#51 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB8SoCU092GOawOaDPycM0-cvm639ZDhks5ru9B1gaJpZM4M5Poh>
.
--
brandon s allbery kf8nh sine nomine associates
[email protected] [email protected]
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
|
Sounds good, I'll get to it then. |
All right, this is what I've got so far:
Result: There are no more exceptions thrown from Haskell code, the only occurences of Still TODO:
Thoughts? |
Wow @SirBoonami, great work! My first thought is how do we make this easy to compose? In xmonad there are several places where we call a handful of X11 functions in a row. With Perhaps it's overkill, but if it were me, I'd write a For testing, I have no idea. The best I can come up with is refactor xmonad to use these new functions and then play around in xmonad-testing. |
Pity we need to support 7.6.3, or we could use a pattern synonym to reduce the noise. (snark re testing: do it and wait for a distro maintainer to make xmonad 0.13 build against it...) |
We'll have to decide on a trade-off here:
It depends on the most common use case, but I am slightly in favour of option 2. |
Nice description of trade offs! I still like I think the Just my $0.02 though. |
@SirBoonami If you want help on this project I'd be happy to point other volunteers towards this issue. Just let me know. |
I think I'll be fine as far as the refactoring of X11 goes. Applying the changes to the xmonad core is where I'll probably need some help. (Not sure about xmonad-contrib.) But I'll need somebody with a bit more experience and authority than me to make a call on the |
@geekosaur What are your feelings on |
Could work. I've actually been thinking about something a little stronger,
but it's not happening soon and this would be a waypoint toward it anyway.
…On Sat, Apr 15, 2017 at 1:37 PM, Peter J. Jones ***@***.***> wrote:
@geekosaur <https://github.com/geekosaur> What are your feelings on newtype
X11 = X11 { unX11 :: ExceptT ...}?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#51 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB8SoNrdbESPpciEUxIQYt0wv1VKE0Dhks5rwQB1gaJpZM4M5Poh>
.
--
brandon s allbery kf8nh sine nomine associates
[email protected] [email protected]
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
|
So we agree that it's a good idea, but nobody is bold enough to say "let's do this"? Then I'll call it here:
will be it. The exact representation could still be changed at a later date without the need to rewrite everything if we use the abstract I'll start with all the unsafe functions again, in the meantime we can discuss whether using Implementing them that way would force users to write lots of dead error handling code that is absolutely guaranteed to never run. We could document which functions are safe and provide a On the other hand, the only real costs of leaving safe functions as
Am I missing something? |
I'm going to be bold: There should be no difference between "safe" and "unsafe" functions. Doing so breaks composability. If you look in the xmonad source you will see several X11 calls in a row inside a To make porting code easier we should have a couple helper functions:
|
I don't see how that would break composability. All you'd have to do is lift the safe function(s):
Maybe even with a custom lifting function ( It's a bit more cumbersome, yes. But I don't see how taking out exceptions only to replace them with partial functions like |
I think we should avoid using the terms safe and unsafe, I'm getting confused. We all agree that functions that might throw exceptions should return a variant of IMO the whole point of this abstract type is to defer error handling until the end of a series of computations. If I'm already "in" the I'll let @geekosaur weigh in, but I think any function calling into libx11 should be prepared to fail and should have the same interface. |
Alright Gentlemen, I'd like to direct your attention towards this once more.
|
@SirBoonami Just a note that I haven't had a chance to review your recent changes but I still care and will do so as soon as I can. Thanks. |
No worries, take your time =) |
What's the status of this? taffybar/taffybar#105 Needs this to be fixed for rawGetWindowProperty and its various flavors. |
There is another sense in which all the X11 calls need to be safed (this has nothing to do with return types on in haskell exceptions): To properly handle exceptions from X11, a proper error handler needs to be set as in: but this will only work at all if calls like @geekosaur @pjones I'm willing to do some of this work, but I think one thing we need to think about is whether or not we want X11 to be responsible for installing the error handler. xmonad currently sets its own error handler, and things like this could interfere with this libraries handling of errors https://github.com/ivanmalison/xmonad/blob/bb13853929f8f6fc59b526bcc10631e1bac309ad/src/XMonad/Main.hs#L191 My opinion is that the best thing to do would be to stop exposing any ability to set the error handler, and handle all error internally in X11 and then expose haskell values to indicate what went wrong in those cases. It might be difficult to do something like this without having some sort of signaling mechanism as in SafeX11, so this could be a quite significant change. There also might be some performance implications to marking functions interruptible/safe over unsafe. I think it does need to be done though. |
The only calls that should be The error handler is set in |
Yes, but atm as far as I can tell, literally everything is marked unsafe, and as such, I actually don't think there is much point in setting a non C error handler.
Yes I agree, but the current reality, is that you can actually only set the C error handler which mentions xmonad, because this was not factored out properly, and this actually occurs in the X11 library: Line 19 in 9f6df0d
We actually have this: X11/Graphics/X11/Xlib/Extras.hsc Line 1661 in 9f6df0d
But the comment explains that it is experimental, and in fact, it actually doesn't work, becase things really need to be marked interruptible if we are going to be calling back into the haskell runtime.
Again, my proposal is this:
|
Yes, I was agreeing with you. But X11 isn't "mine" and in any case I am not in a position to do anything useful with xmonad or anything else, and won't be any time soon. :/ |
@liskin Why was this removed from 2.0. IMO this is one of the most important things that could be done to the x11 lib. |
@IvanMalison I just removed the milestone itself because we don't really have any plan or hope to actually work towards a 2.0 X11 Haskell bindings. It's not the sort of thing that's got a high return on investment in 2021. An xcb binding would be more valuable, but even that might be seen by many as silly in a world that's increasingly moving towards Wayland. That being said, if someone comes with a PR that implements all of this I'll be happy to help review it and guide the release process and make sure we don't break any dependencies. It's just not something I'd allocate any resources on, myself. |
I'm creating this ticket to help us track the work going on over at xmonad/xmonad-contrib#146.
Starting with the
getWindowAttributes
function, start creating versions that returnMaybe a
instead of throwing an exception. I'm not sure what the new naming scheme should be, but the original functions should just call the new version and throw if they getNothing
back.The text was updated successfully, but these errors were encountered: