Squiggle functions are not exactly pure because they act as generators when they produce randomness; f() = (2 to 3) -> sample; f() == f() is false
in JS land, f.call() will give you the same number both times
I don't like this; we should have parity between evaluating Squiggle scripts and calling same Squiggle builtins from JS
so I guess in JS it should be [result, rngState] = f.call(params, rngState)?
otherwise things won't be nice in React land, e.g. const value = useMemo(() => f.call(), [f]) won't work
btw one more complication is that rngState is not a seed; seed -> rngState is kinda slow, and also irreversible
maybe rngState could be a reducer instance, same as in our common function registry APIs
but, anyway, right now reducer is not an SqProject, because reducer objects short-lived
also note that in some cases we'll want to invoke f.call() in multiple code locations, e.g. by passing f to multiple React components; so there should be something for "splitting out RNG into multiple sub-RNGs with unique predictable states" (we'll also need it for parallel execution of Squiggle programs)
bottom line, we should be explicit about rng state in more places than we expected, and also we'll have to spend more effort on educating users about this if "calling Squiggle from JS" ever becomes popular
Discussion in Discord: https://discord.com/channels/1130609991993274510/1223854334761238601
I'll copy my main comment from it here:
Observations:
f() = (2 to 3) -> sample; f() == f()
is falsef.call()
will give you the same number both times[result, rngState] = f.call(params, rngState)
?const value = useMemo(() => f.call(), [f])
won't workrngState
is not a seed; seed -> rngState is kinda slow, and also irreversiblerngState
could be areducer
instance, same as in our common function registry APIsreducer
is not anSqProject
, because reducer objects short-livedf.call()
in multiple code locations, e.g. by passingf
to multiple React components; so there should be something for "splitting out RNG into multiple sub-RNGs with unique predictable states" (we'll also need it for parallel execution of Squiggle programs)