google / google/codeworld

Consider event-specific handlers for `activityOf`

Open
#1,244 2 comments 0 reactions 0 assignees View on GitHub
discussion
Dominant language
Haskell
Stars
1.3k
Forks
201
PR merge metrics
No merged PRs in 30d

Description

Inspired by @alphalambda's discussion of handling state at NY Haskell.

We could add these to CodeWorld:

``` haskell
onKeyPress :: (Text, state -> state) -> ((state, Event) -> state)
onAnyKeyPress :: ((state, Text) -> state) -> ((state, Event) -> state)
onKeyRelease :: (Text, state -> state) -> ((state, Event) -> state)
onAnyKeyRelease :: ((state, Text) -> state) -> ((state, Event) -> state)
onPointerPress :: ((state, Point) -> state) -> ((state, Event) -> state)
onPointerRelease :: ((state, Point) -> state) -> ((state, Event) -> state)
onPointerMovement :: ((state, Point) -> state) -> ((state, Event) -> state)
onTimePassing :: ((state, Number) -> state) -> ((state, Event) -> state)
onTextEntry :: ((state, Text) -> state) -> ((state, Event) -> state)
onAll :: [(state, Event) -> state] -> ((state, Event) -> state)
```

Implementation is trivial. Sample usage like this:

``` haskell
program = activityOf(initial, change, picture)

change = onAll([
onKeyPress("Enter", fire),
onKeyPress("W", moveUp),
onKeyPress("A", moveLeft),
onKeyPress("S", moveDown),
onKeyPress("D", moveRight),
onTimePassing(time)
])
```

Advantages:
* Encourages students to break down event handling with functions.
* Autocomplete with `on` prefix is powerful

Disadvantages:
* This is a kind of magic that applies to one specific function. Doesn't apply to functions in general.

I initially thought about something like, where the first parameter is the constructor:

``` haskell
on :: (a -> Event, (state, a) -> state) -> ((state, Event) -> state)
onExact :: (Event, state -> state) -> ((state, Event) -> state)
```

However, `on` isn't cleanly implementable. I suppose one could do something like:

``` haskell
on(constructor, f)(state, ev) = case (constructor undefined, ev) of
(PointerPress _, PointerPress pt) -> f(state, pt)
(PointerRelease _, PointerRelease pt) -> f(state, pt)
...
```

but that feels very hacky. The function will accept a bunch of non-constructor-like functions that look at their argument, and will crash at runtime. Maybe that's okay?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.