Open EvanKirshenbaum opened 8 months ago
This issue was referenced by the following commit before migration:
I think I'm going to delay dealing with future
parameters for a bit, because the correct behavior will depend on whether the function is expecting to produce a value using the parameter or to wait on a value being produced by the parameter. In the former case, the provided argument should be contravariant with respect to the declared parameter type, and in the latter it should be covariant. So I will probably have to add some sort of in
or out
specification, and that's more than I need to support paths (#282), which is what I really need at the moment.
The most straightforward way to support future
types would seem to have future T
convert to T
by waiting for the value. Unfortunately, Type.convert_to()
assumes that it's an immediate action, so in order to support this, I'll have to change convert_to()
to return a Delayed
object.
Okay, that wasn't too bad. DML now supports
future drop;
future drop : up : right 2;
The latter form creates the variable immediately, and then performs the injection, which will wait for it to get the value. Note that because the declaration doesn't end until the injection does, this should only be done in a parallel block (at least until task
s are implemented (#286).)
When a future
-valued variable is read, the read doesn't complete until a value has been asserted, and the value is of the contained type. I decided that the write-once notion was confusing (I may revisit this), so you can assign multiple times. Note that setting an already set future
variable won't trigger anything, since anything waiting on the future
would already have triggered.
You can also reset the value to unbound. There's currently no way to do this from DML, but if I can figure out how to do it, I may want to have this happen when a path
(#282) includes the notion of merging into another drop, walking with it for a while and then being split out again to walk further. To support this, I'll probably need to have some notion of the drop knowing what future drop
s it's assigned to and having the merge reset them. (I guess that should probably happen for any variable.)
The current implementation complains "not yet implemented" on
= val
initializer on the declaration.future
valued macro parameters (see above)future
valued macro returns
When looking at how to support paths in a way that users can wrap their heads around (#282), one of the hardest questions was "How does the user split a single drop in two and do something with each resulting drop?"
The answer I've come up with is to take advantage of
Delayed[T]
and add a new meta-type,future T
to DML. This would be something that can hold aT
(and which has avalue
attribute that can be queried, i.e.,has a value
), but which actually holds aPostable[T]
and which converts to aT
by waiting to get a value. This would allow something likeThe two paths work in parallel, but
walk_after_split
doesn't happen until the split is done.If I'm going to do this, it should generalize to any type, because doing so gives me the ability to have out parameters. The basic notions are
future T
converts to aT
, waiting until it gets a value.T n
.future
is contravariant: afuture T
is afuture U
if aU
is aT
.future int
, you can pass in afuture float
, because the macro will (may?) assign it anint
, which is okay.T
variable into a macro that wants afuture T
, the value asserted will be assigned to the variable.future
returns.future
parameter probably creates a new variable that's linked to its passed parameter.future
itself, the linkage should probably go in both directions, so either can be asserted.future
values can only be assigned once, and only withT
values. (Assigning afuture
value will wait.)Migrated from internal repository. Originally created by @EvanKirshenbaum on Jul 03, 2023 at 5:03 PM PDT.