Open kostmo opened 1 year ago
This is not a bug, and has been discussed in some detail in #738 . The basic explanation is that the arguments to require
need to be statically known since requirements checking happens prior to running a program. That is, we have to be able to figure out what a newly built robot will need before we run its program.
Potentially, I could imagine doing something like this:
let quantity = 500 in
build { require quantity "rock"; ... }
That is, as long as quantity
is already known at the time we execute the build we might be able to make it work. But I expect it would be complicated.
The workaround to ensure that "child" robots receive a programmatic quantity from inventory seems to be for the "parent" to
give
items repeatedly while the child polls usingcount
.
Yes, that is annoying. Once we have #115 this will probably become easier since you can e.g. stuff a bunch of rocks in a box
and then just give
the box
.
At least for the application I had in mind, the quantity can be known outside of the build
context, i.e.
let quantity = 500 in
build { require quantity "rock"; ... }
However, it's merely an issue of convenience now, as I've successfully employed the polling workaround.
@byorgey do we have a way to get something like Ctx Term
to see what the current variable name points to?
AFAIK we only have Env = Ctx Value
that will be used at runtime.
I guess requirements
would have to create the map itself. 🤔
do we have a way to get something like Ctx Term to see what the current variable name points to?
No, that would be something extra we'd have to keep track of while doing typechecking & requirements analysis.
I'm going to close this soon, since there's no general solution and anything we did to make it slightly better would be an ugly hack. However, I wanted to summarize the current state of things and maybe spark some discussion of other ways to improve the situation.
require 500 "rock"
, where the number and the entity name are literals. This is because require
is analyzed at compile time and we cannot wait until runtime to find out what the number and entity are.
require
looks like a regular command, but it is actually special syntax for declaring a requirement, not a command that does something.require
to make this more clear, e.g. change it to #require
.let n = 500 in require n "rock"
, but only with some hacky effort, and is this really better than just writing require 500 "rock"
? I suppose if you wanted to write a lot of require
statements with the same number, it would make the program more readable.n <- foo; build {require n "rock"; ...}
where the number is determined at runtime.
give
the rocks to it after it has been built.build
ing. e.g. maybe a command get : Int -> Text -> Cmd Unit
which tries to grab a certain number of a given entity from your parent
robot. So you could write n <- foo; build {get n "rock"; ...}
. The difference is that whereas require
is analyzed at compile time, and the build
will not succeed at all if the requirements cannot be met, get
is executed at runtime and can throw an exception if there is not enough of the requested entity.
Describe the bug
I am not able to compile the following:
The error message is:
The workaround to ensure that "child" robots receive a programmatic quantity from inventory seems to be for the "parent" to
give
items repeatedly while the child polls usingcount
.