Skip to content

Proposal: Mailbox Revamp #7

@mgold

Description

@mgold

This proposal attempts to codify the ideas from this thread. This would be a breaking change to core, but no change to the language itself.

Motivation

As is clear from reading the thread, "mailbox" is has failed as a metaphor. This part of the language is, empirically, one of the hardest for newcomers to understand. A few other issues with the API:

  • The Address type is completely opaque, and hard to gain intuition about. However, it's really the only thing tying the API together.
  • That is, there's message to create a Message, and send to create a Task, but neither of these seem to fit very well.
  • forwardTo : Address b -> (a -> b) -> Address a is really confusing. It took me several tries to get my head around it. The average JS or Ruby dev is not comfortable with the phrase "contravariant functor".

Proposed Change

I'm not 100% on the names yet; please focus on the types.

type alias Dispatcher a = 
    { dispatch : a -> Message -- the big change
    , signal : Signal a 
    }

dispatcher : a -> Dispatcher a -- just renamed mailbox
send : Message -> Task x ()

Let's start by what's not in the API. There's no explicit message function aside from dispatch itself. This encourages people to use messages, which are safer (they can't perform arbitrary actions e.g. Http). And forwardTo drops out entirely, replaced by dirt standard function composition.

Finally, send takes a Message. Currently, send and message are both Address a -> a -> ..., implying parity. Now, it's clearly extra work to use a task. This implies (correctly) that a message is the primary type at play here. The exposed function plays very well with Graphics.Input, every function in which takes either a Message or an (a -> Message).

Next Steps

This proposal had support from both newcomers and regulars on the thread, though you're welcome to oppose here. As mentioned above, I think the biggest remaining hurdle is to find the right names. I think implementation will be fairly straightforward, although it's important to get the docs right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions