To be clear, uDLang execution should in general be deterministic, and always produce the same output for the given input.
This is a problem when we might want it to change.
random numbers for procedural content
system time
Couple of approaches to handle it:
for system time, capture it at script start. Time appears frozen within each iteration. "All parts of the program are in the same frame of reference".
cheat, and simply let these be the exception to the rule.
come up with weird hacks outlined below that feel less like cheating.
insist that it's the user's problem to pass these values in the input.
for PRNGs: embrace monads.
for PRNGs: cheat, but force the user to decide how they want to seed -- if you want content changing over time, then you must seed from the input, for example. Vs if you want content stable over time, you give a static seed. Either way the presence of even this might have serious consequences for optimizations.
Language level support for PRNGs: treat them as at least iterable, and hide the state in the loop iteration.
The bigger problem is unique IDS. One idea is to have a Atom<T> type in the language, which would be a unique integer ID that is opaque. The issue here is that, whether generated by a counter, or a PRNG, we don't want to allow the script to
observe the value, since it would violate some pretty big assumptions in the language. But then, how can we actually use it? One strategy would be to treat Atom<T> as an "output only" value. The only thing we would be able to do within uDLang is compare two atoms for equality, and use them somewhere in an out statement expression.
This would force you to use Token<T> in your output declaration, and you would have to rely on the implementation to serialize. Explicitly, you can't do anything with these that might leak the internal value, in particular, you can't convert it to a string that would be visible in the code.
Another idea is to have a resource declaration statement, so we can shove whatever nasty hacks we want to use under the rug.
To be clear, uDLang execution should in general be deterministic, and always produce the same output for the given input.
This is a problem when we might want it to change.
Couple of approaches to handle it:
Language level support for PRNGs: treat them as at least iterable, and hide the state in the loop iteration.
The bigger problem is unique IDS. One idea is to have a
Atom<T>
type in the language, which would be a unique integer ID that is opaque. The issue here is that, whether generated by a counter, or a PRNG, we don't want to allow the script to observe the value, since it would violate some pretty big assumptions in the language. But then, how can we actually use it? One strategy would be to treatAtom<T>
as an "output only" value. The only thing we would be able to do within uDLang is compare two atoms for equality, and use them somewhere in anout
statement expression.This would force you to use
Token<T>
in your output declaration, and you would have to rely on the implementation to serialize. Explicitly, you can't do anything with these that might leak the internal value, in particular, you can't convert it to a string that would be visible in the code.Another idea is to have a
resource
declaration statement, so we can shove whatever nasty hacks we want to use under the rug.