Reputation: 12580
I have a task and a list of arguments. I'd like to apply the task to the list of arguments. Is the only way to do this by using strings instead of tasks and just concatenating? Basically, I'm looking for the equivalent of apply
in other languages.
Upvotes: 2
Views: 273
Reputation: 2305
I expanded on this to create a procedure that allows you to apply commands. It works both with anonymous commands and with regular commands.
to test
let worldsize [0 5 0 5]
apply-command "resize-world" worldsize
end
to apply-command [command inputlist]
; Takes two inputs
; 1: Anonymous command/string containing anonymous command/string containing regular command
; 2: A list of inputs, corresponding in length to the number of inputs the command takes
; Applies the command with the different items of the list as input
; Heavily inspired by stackoverflow-user Bryan head
set command anonimify-command command length inputlist ; Using non-anonymous commands gave issues, hence they are anonimified
(run listify-command command length inputlist inputlist)
end
to-report listify-command [ command num-args ]
; Takes an anonymous command and the length of a list as input
; Outputs an anonymous command that takes the different items of the list as inputs
; Heavily inspired by stackoverflow-user Bryan head
if (not is-anonymous-command? command) [error "The first input for listify-command has to be an anonymous command"]
let args (reduce word n-values num-args [ x -> (word " item " x " ?") ])
;show (word runresult (word "[ ? -> (run command " args ") ]"))
report runresult (word "[ ? -> (run command " args ") ]")
end
to-report anonimify-command [ command number-of-inputs]
; Takes two inputs
; 1: Takes an anonymous command, a string containing an anonymous command or a string containing a regular command
; 2: Takes a number that corresponds to the number of inputs the anonimified command should take
; Returns anonymous commands unaltered
; Returns strings containing an anonymous command as an anonymous command
; Returns strings containing a regular command as an anonymous command
if (is-anonymous-command? command) [ ; Anonymous commands get returned
report command
]
if (is-string? command) [ ; Strings are processed
carefully [ ; Using run-result on a string that does not contain an anonymous command causes an error, hence carefully
if (is-anonymous-command? run-result command) [
set command run-result command
]
]
[
let inputs n-values number-of-inputs [ i -> word " x" i]
let inputs-as-string reduce word inputs
let command-string (word "[ [" inputs-as-string " ] -> " command inputs-as-string" ]")
set command run-result command-string
]
report command
]
error "The inputted command must be either an anonymous command, a string containing an anonymous command or a string containing a command"
;If the input is neither anonymous command nor string, an error is displayed
end
Upvotes: 0
Reputation: 12580
I came across this problem again, and actually figured out a solution!
to-report listify-task [ tsk num-args ]
let args (reduce word n-values num-args [ (word " (item " ? " ?)") ])
report runresult (word "task [ (runresult tsk " args ") ]")
end
This converts a reporter task from something that takes a number of arguments to one that takes a list. You use it like so:
observer> show (runresult (listify-task task [?1 + ?2] 2) [4 5])
observer: 9
apply
could be implemented on top of this like:
to-report apply [ tsk args ]
report (runresult (listify-task tsk length args) args)
end
though it would be somewhat inefficient. Better to store the result of listify-task
and the run that whenever you need to.
It essentially creates a task of the following form: task [ (runresult tsk item 0 ? item 1 ? ...)]
.
Upvotes: 2
Reputation: 30498
Can't be done (except by an extension).
I would support this as an addition to the core language, actually. There would need to be separate prims for command tasks and reporter tasks, just as run
and runresult
are separate.
Writing them (either as extension prims, or as core prims) wouldn't be very hard; it would only involve writing boilerplate and glue, not any "real" code, and looking at how run
and runresult
are implemented would show you exactly what to do.
Upvotes: 1