Random in 0.17 and purity

291 перегляд
Перейти до першого непрочитаного повідомлення

David Legard

не прочитано,
15 трав. 2016 р., 19:58:5315.05.16
Кому: Elm Discuss
Looking through the Random section of the guide (http://guide.elm-lang.org/architecture/effects/random.html), I notice there is no discussion on creating and passing round a random seed, as has been the case up to now.

Specifically, the type is given as

Random.generate : (a -> msg) -> Random.Generator a -> Cmd msg


, used in the 'update' function as:

 Roll ->
     
(model, Random.generate NewFace (Random.int 1 6))


Is 'Roll', therefore, an impure function, giving a different result each time? If so, then the whole 'update' function (of which Roll is one branch) is impure. And so on throughout the program.

And does it matter?

Max Goldstein

не прочитано,
15 трав. 2016 р., 20:56:2515.05.16
Кому: Elm Discuss
Random seeds are still available for use with Random.step.

The new function uses commands or Cmd a which are impure. Or rather, update is still stateless (aka "pure") because the same arguments Roll and model produce the same result, a tuple of the model and a command. (Well, if a tuple with a Cmd can be said to be "the same" when Cmds don't support equality...)

The benefit of the new Cmd system is that you no longer have to pass seeds around or figure out how to initialize them. The downside is that they're not reproducible, the random value is returned asynchronously as another Msg (formerly Action), and you have to wire them up to the main component.

BTW, if you're doing serious work with Random you should check out Random.Pcg - although I haven't been able to duplicate generate in a satisfactory way. 

David Legard

не прочитано,
15 трав. 2016 р., 21:19:3315.05.16
Кому: Elm Discuss
It's a worthwhile tip -- if you don't want to seriously change your Random implementation from 0.16 to 0.17, you just need to change Random.generate to Random.step.

I agree with the benefits of the new approach, but I'm not sure about this explanation:

Or rather, update is still stateless (aka "pure") because the same arguments Roll and model produce the same result, a tuple of the model and a command.

Is that enough to maintain purity? Returning the same types is part of it, but if the values of those types are different each time, is that really purity?

And the second part -- does it matter either way?

Max Goldstein

не прочитано,
15 трав. 2016 р., 21:27:0915.05.16
Кому: Elm Discuss
Or rather, update is still stateless (aka "pure") because the same arguments Roll and model produce the same result, a tuple of the model and a command.

Is that enough to maintain purity? Returning the same types is part of it, but if the values of those types are different each time, is that really purity?

It's returning the same values (which are therefore of the same type) every call with the same arguments. Random.generate (in 0.17) doesn't return a random value; it returns a description of the work to be done. Specifically, it contains a Generator a that describes how to produce a value, and a function that describes how to feed that value back into the program. (The "fed back into" part is why I said it's asynchronous.) Those descriptions are always the same. The randomness comes from a global, hidden random seed managed by the runtime.
 
And the second part -- does it matter either way?
Can you elaborate please? 

David Legard

не прочитано,
15 трав. 2016 р., 22:51:0315.05.16
Кому: Elm Discuss
Can you elaborate please? 

My impression (coming from Haskell) is that the purity of functions is regarded as being of fundamental importance.

That is, when you call a function with designated arguments, the function will always return exactly the same answer. Anything where that does not hold must be handled in the monadic system (I/O principally, but also Random).

That is not the case with this function: 

update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of Roll -> (model, Random.generate NewFace (Random.int 1 6)) NewFace newFace -> (Model newFace, Cmd.none)

If you call it repeatedly with identical arguments (msg=Roll , model=model) it will return different values on each iteration -- it might return (model, Cmd 1) or (model,Cmd 2) etc.

Certainly, from a theoretical Haskell perspective, that is breaking purity. In 0.16, this was not the case, as a different seed was passed in as an argument each time.

I'm asking whether, in the Elm environment, this is regarded as a significant departure from core principles.

Joey Eremondi

не прочитано,
15 трав. 2016 р., 22:54:5815.05.16
Кому: elm-d...@googlegroups.com
Think of Cmd as being like Haskell's IO.

A Cmd is just a description of an action to be run. Update takes a message and a model, and returns a new model, as well as a description of an action to be run, a Cmd. This description depends only on the inputs to the function.

Now, come runtime, the runtime system looks at this description and runs imperative code based on it, and uses the result of the imperative computation.

Elm doesn't have "no side effects", it has managed side effects. But if there's no Task or Cmd or Sub in the type, you can be sure that the function is side-effect free. This way, when there's problems with side-effects, it's easy to track down which functions are causing them, since you know pure ones will never be the problem.


--
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.

David Legard

не прочитано,
15 трав. 2016 р., 23:05:5815.05.16
Кому: Elm Discuss
Many thanks for the clarification -- the concept is much clearer to me now.

Max Goldstein

не прочитано,
15 трав. 2016 р., 23:23:0415.05.16
Кому: Elm Discuss
*nonverbal frustration* ... isn't that what I said?

 it might return (model, Cmd 1) or (model,Cmd 2) 

It always makes the same command, but the command might do different things. 

Richard Feldman

не прочитано,
16 трав. 2016 р., 01:17:4016.05.16
Кому: Elm Discuss
Elm doesn't have "no side effects", it has managed side effects. But if there's no Task or Cmd or Sub in the type, you can be sure that the function is side-effect free. This way, when there's problems with side-effects, it's easy to track down which functions are causing them, since you know pure ones will never be the problem.

To be totally clear on this, even if the function returns a Task or Cmd or Sub, the function is still side-effect free! It's just returning a value. You really can't write an Elm function that has side effects (without involving the Debug or Native modules), and that includes functions that return Task, Cmd, or Sub.

As it happens, the purpose of the values Cmd, Task, and Sub is to describe various effects that we'd like Elm's runtime to carry out eventually, but they are still just values nonetheless. Instantiating them is precisely as side-effectful as instantiating a String. ;)

Andrew Radford

не прочитано,
25 вер. 2016 р., 10:56:2725.09.16
Кому: Elm Discuss
At the risk of necroposting, just thought I'd mention that today is the day that I first needed Random-ness in elm. After accidentally reading the old Random docs, encountering and wondering about the function signatures that pass the random seed around, having the lightbulb moment about this being related to FP purity, I then read the latest (0.17) docs where "generate" has been renamed to "step", and the new "generate" does the Cmd tag thing, with no seed curation. Well then of course I was de-railed and was wondering where the seed state lived until I read this post.

Long story short, I think this is an important point to have in the docs/Guide. People with an FP background get thrown by the lack of purity of generate, and people who are new to FP probably wonder why they have to worry about dealing with the seed when using 'step'; they are used to just calling Random.Next() or something. As long as this thread is google-able it will be OK, but I wonder if there is a nice way to outline this stuff in the docs?
Повідомлення видалено

Max Goldstein

не прочитано,
25 вер. 2016 р., 20:44:0725.09.16
Кому: Elm Discuss
Hi Andrew,

The official docs are harder to change than I'd like, but I welcome docs issues and PRs to my library:

https://github.com/mgold/elm-random-pcg

Eventually the RNG will replace core's, and hopefully I'll be able to update the docs at that time.

Відповісти всім
Відповісти автору
Переслати
0 нових повідомлень