Discussion:
[elm-discuss] Proposal: move Random.Extra.constant to Random
Francesco Orsenigo
2017-09-28 01:56:34 UTC
Permalink
Currently, the user has to either install `Random.Extra` just to use `
constant`, or define `constant a = Random.map (\_ -> a) Random.bool`, which
is a non-intuitive way to express the problem.

`constant` is the *return* operator of the Random monad, and as such
constitutes a very basic block for composing generators; it's shouldn't be
an "extra".
`Random` is the *only* core monad that doesn't have a return operator
within core.
Rather than a justification for having it in core, I think there should be
a justification for excluding it.
`Json.Decode.succeed` can be defined as `succeed x = Json.Decode.map (\_ ->
x) (Json.Decode.maybe Json.Decode.value)`, yet few would make a case that
it should not exist inside `Json.Decode`.

Implementing `constant` within `Random.Extra` currently forces a contrived
(and wasteful) workaround, generating a value just to throw it away:
https://github.com/elm-community/random-extra/blob/master/src/Random/Extra.elm#L33-L39

Moving `constant` to the `Random` would allow the implementation to become
trivial:
https://github.com/mgold/elm-random-pcg/blob/5.0.1/src/Random/Pcg.elm#L365


The absence from the core libraries also makes an implicit statement: that
most problems can be solved without it, and `constant` is needed only for
very complicated Generators.
While this might be true for very trivial Generators, it is not true as
soon as a Generator is required to produce anything non trivial:


type Shape
= Point
| Circle Int
| Rectangle Int Int

int : Generator Int
int =
Random.int 1 10

shapeGenerator : Generator Shape
shapeGenerator =
[ ( 0.3, Random.constant Point )
, ( 0.4, Random.map Circle int )
, ( 0.3, Random.map2 Rectangle int int )
]
|> Random.frequency


More in general, `constant` is necessary whenever a result could be,
depending on the arguments, deterministic or randomly generated: the same
function cannot return sometimes a value and sometimes a Generator.
Many such use cases are encountered in game development, and in the
#gamedev Slack channel we quickly collected several cases:

* Depending on the game state, enemy bot AI will sometime make
deterministic choices, sometimes random ones.

* Dungeon generation:
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L98
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L106
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L159
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L165
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L167
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L185
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L190
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L205
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L241
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L327

* Lexicon-based random word generation:
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L95
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L109
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L117
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Janiczek
2017-10-25 12:13:47 UTC
Permalink
Thoughts, people?
I approve of this. `Random.constant` is a very basic building block for
defining Generators for me.

On Thursday, September 28, 2017 at 3:56:34 AM UTC+2, Francesco Orsenigo
Post by Francesco Orsenigo
Currently, the user has to either install `Random.Extra` just to use `
constant`, or define `constant a = Random.map (\_ -> a) Random.bool`,
which is a non-intuitive way to express the problem.
`constant` is the *return* operator of the Random monad, and as such
constitutes a very basic block for composing generators; it's shouldn't be
an "extra".
`Random` is the *only* core monad that doesn't have a return operator
within core.
Rather than a justification for having it in core, I think there should be
a justification for excluding it.
`Json.Decode.succeed` can be defined as `succeed x = Json.Decode.map (\_
-> x) (Json.Decode.maybe Json.Decode.value)`, yet few would make a case
that it should not exist inside `Json.Decode`.
Implementing `constant` within `Random.Extra` currently forces a
contrived (and wasteful) workaround, generating a value just to throw it
https://github.com/elm-community/random-extra/blob/master/src/Random/Extra.elm#L33-L39
Moving `constant` to the `Random` would allow the implementation to
https://github.com/mgold/elm-random-pcg/blob/5.0.1/src/Random/Pcg.elm#L365
The absence from the core libraries also makes an implicit statement: that
most problems can be solved without it, and `constant` is needed only for
very complicated Generators.
While this might be true for very trivial Generators, it is not true as
type Shape
= Point
| Circle Int
| Rectangle Int Int
int : Generator Int
int =
Random.int 1 10
shapeGenerator : Generator Shape
shapeGenerator =
[ ( 0.3, Random.constant Point )
, ( 0.4, Random.map Circle int )
, ( 0.3, Random.map2 Rectangle int int )
]
|> Random.frequency
More in general, `constant` is necessary whenever a result could be,
depending on the arguments, deterministic or randomly generated: the same
function cannot return sometimes a value and sometimes a Generator.
Many such use cases are encountered in game development, and in the
* Depending on the game state, enemy bot AI will sometime make
deterministic choices, sometimes random ones.
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L98
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L106
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L159
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L165
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L167
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L185
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L190
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L205
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L241
https://github.com/mordrax/cotwelm/blob/master/src/Dungeon/DungeonGenerator.elm#L327
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L95
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L109
https://github.com/xarvh/lexical-random-generator/blob/1.0.0/src/LexicalRandom.elm#L117
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Max Goldstein
2017-10-26 14:51:49 UTC
Permalink
I also think it’s a good idea. I’ve brought it up with Evan and Richard before. But I can tell you from experience that getting changes merged into the Random module is very difficult.

Also, shameless plug for mgold/elm-random-pcg, which includes this and many other useful functions built on a superior PRNG.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Janiczek
2017-10-26 18:18:48 UTC
Permalink
IIRC from conversations with Francesco, this thread started as a reaction to seeing that core's (to be 0.19) Random incorporated your Random.PCG's code but omitted `constant`.

Can we know the reasoning behind the "it shouldn't be there" opinion?
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...