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

added toMessage and doMessage #320

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

wygulmage
Copy link
Contributor

Description

toMessage wraps an instance of MessageClass in SomeMessage unless it's already SomeMessage; this can be
used in other functions to avoid excessive wrapping and re-wrapping.

doMessage acts as handleMessage but with error "handling" (userCodeDef)
and using toMessage to automatically wrap with SomeMessage when
necessary (see XMonad.Layout for why that's nice.)

I was wondering why XMonad.Operations.sendMessageWithNoRefresh was using catchX while general use of handleMessage could still throw on a poorly defined instance of LayoutClass. This puts the error "handling" (semi-ignoring) in as basic a function as possible and then use that as much as possible, rather than handleMessage.

XMonad.Layout defines an internal function handle to wrap with SomeMessage before calling handleMessage. doMessage as defined here can be used instead.

Possible complications of this include making SomeMessage an instance of Message (technically you could wrap SomeMessage arbitrarily deep if you didn't use toMessage), and the larger API of doMessage and handleMessage with identical signatures and equivalent function.

This would also slightly simplify the code in #291 by moving the error handling out of sendMessageWithNoRefresh.

Checklist

  • I've read CONTRIBUTING.md

  • I've confirmed these changes don't belong in xmonad-contrib instead

  • I tested my changes with xmonad-testing

  • I updated the CHANGES.md file

@wygulmage
Copy link
Contributor Author

With the PatternSynonyms extension, it's possible to do this even more nicely and transparently. Rather than exporting toMessage, you:

  • Change SomeMessage (..) to SomeMessage (SomeMessage) in the export list.
  • Change data SomeMessage = forall a. Message a => SomeMessage a to data SomeMessage = forall a. Message a => Message a.
  • add pattern SomeMessage x <- Message x where SomeMessage x = toMessage x.

Now you use SomeMessage just as before, except now when you do SomeMessage (foo :: SomeMessage), it gives back foo.

@slotThe
Copy link
Member

slotThe commented Aug 17, 2021

With the PatternSynonyms extension, it's possible to do this even more nicely and transparently. Rather than exporting toMessage

I really like this idea 👍 I think we should go for that

@wygulmage
Copy link
Contributor Author

Great, I like it better too!

Also, a quick bikeshedding question: Which do you like better: doMessage, passMessage, something else, or remove that from the pull request entirely to focus on the SomeMessage pattern synonym?


-- |
-- A wrapped value of some type in the 'Message' class.
--
data SomeMessage = forall a. Message a => SomeMessage a
data SomeMessage = forall a. Message a => AMessage a
deriving (Typeable)
Copy link
Member

Choose a reason for hiding this comment

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

GHC derives Typeable automatically for every type now, so this is probably superfluous

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's good news.

...and derive (Typeable) is now gone.

@slotThe
Copy link
Member

slotThe commented Aug 18, 2021

Also, a quick bikeshedding question: Which do you like better: doMessage, passMessage, something else, or remove that from the pull request entirely to focus on the SomeMessage pattern synonym?

Well I do love me some bikeshedding :) My gut feeling was that doMessage sounds better, because passMessage almost sounds like "pass on the message to something else". But then we are passing the message onto the layout... Ultimately, both are probably fine—names are hard.

@wygulmage
Copy link
Contributor Author

My gut feeling was that doMessage sounds better, because passMessage almost sounds like "pass on the message to something else". But then we are passing the message onto the layout... Ultimately, both are probably fine—names are hard.

With that in mind, passMessage would have made more sense for a flipped variant. I'll keep it as doMessage.

Copy link
Member

@slotThe slotThe left a comment

Choose a reason for hiding this comment

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

LGTM; I'll wait for someone else to look at this before merging, but I've no more complaints myself

`toMessage` wraps an instace of `MessageClass` in `SomeMessage`; this can be
used in other functions to avoid excessive wrapping and re-wrapping.

`doMessage` acts as `handleMessage` but with error "handling" (`userCodeDef`)
and using `toMessage` to automatically wrap with `SomeMessage` when
necessary (see XMonad.Layout for why that's nice.)
Using `AMessage` as the constructor makes it easier for Haddock to know that we
want to link to the class rather than the constructor.
I also moved the definition of `doMessage` above `fromMessage` to avoid messing
with the flow of class definitions.
At this point it seems safe to remove the `DeriveDataTypeable` language pragma
as well, but I have not.
Looks like `where` indentation is usually 2 spaces xmonad.
@liskin
Copy link
Member

liskin commented Sep 4, 2021

I'll be much more comfortable merging this if the newly added function(s) had some actual usage somewhere. That way it's easier to gauge the benefits and possible problems.

Also, I noticed that you fork has a lot of extra commits, some of which get submitted as PRs, sometimes. I wonder if that's just your experiments or if you eventually intend all of that to be upstreamed? Would you perhaps like to join the IRC channel so that we can coordinate efforts?

@wygulmage
Copy link
Contributor Author

I'll be much more comfortable merging this if the newly added function(s) had some actual usage somewhere. That way it's easier to gauge the benefits and possible problems.

Good point. I didn't want to touch existing code (yet...), but there are a number of places where I think it would be useful, both in xmonad and for folks writing extensions (one less thing to be confused by). For example, it would marginally simplify the message-handling code in XMonad.Operations.

Also, I noticed that you fork has a lot of extra commits, some of which get submitted as PRs, sometimes. I wonder if that's just your experiments or if you eventually intend all of that to be upstreamed? Would you perhaps like to join the IRC channel so that we can coordinate efforts?

It's totally experimental. Occasionally something seems useful, small, and clear enough that I split it out into a PR, but for the most part I'd be terrified of accidentally introducing a bug into the venerable xmonad codebase.

@slotThe
Copy link
Member

slotThe commented Sep 9, 2021 via email

@geekosaur
Copy link
Contributor

Keep in mind that you can submit a PR with that change and mark it as a draft, so it won't be considered as an official PR.

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.

None yet

4 participants