Description
command-apply-spec - Returns value of :commando/apply.
Use :=> driver to post-process the result.
Example (:instruction (commando/execute [command-apply-spec] {:commando/apply {:value 10} :=> [:get :value]})) ;; => 10
See Also
commando.core/execute
commando.commands.builtin/command-fn-spec
Description
command-apply-spec - Returns value of `:commando/apply`.
Use `:=>` driver to post-process the result.
Example
(:instruction
(commando/execute
[command-apply-spec]
{:commando/apply {:value 10}
:=> [:get :value]}))
;; => 10
See Also
`commando.core/execute`
`commando.commands.builtin/command-fn-spec`(command-context-spec ctx)Creates a CommandMapSpec that resolves references to external context data captured via closure. Context is immutable per registry and resolves before other commands (dependency mode :none).
ctx — a map with arbitrary structure to look up values from.
Instruction usage (keyword keys): {:commando/context [:path :to :data]} {:commando/context [:path :to :data] :=> [:get :key]} {:commando/context [:path :to :data] :default 0}
Instruction usage (string keys, JSON-compatible): {"commando-context" ["path" "to" "data"]} {"commando-context" ["path" "to" "data"] "=>" ["get" "key"]} {"commando-context" ["path" "to" "data"] "default" 0}
Parameters: :commando/context — sequential path for get-in on ctx :=> — optional driver for post-processing [:get :key], [:fn inc], etc. :default — optional fallback value when path is not found in ctx. Without :default, missing path throws an error.
Example: (def my-ctx {:rates {:vat 0.20} :codes {"01" "Kyiv"}})
(:instruction (commando/execute [(command-context-spec my-ctx) command-from-spec command-fn-spec] {:vat {:commando/context [:rates :vat]} :city {:commando/context [:codes "01"]} :missing {:commando/context [:nonexistent] :default "N/A"} :total {:commando/fn * :args [{:commando/from [:vat]} 1000]}})) ;; => {:vat 0.20 :city "Kyiv" :missing "N/A" :total 200.0}
See Also
commando.core/execute
commando.commands.builtin/command-from-spec
Creates a CommandMapSpec that resolves references to external context data
captured via closure. Context is immutable per registry and resolves before
other commands (dependency mode :none).
ctx — a map with arbitrary structure to look up values from.
Instruction usage (keyword keys):
{:commando/context [:path :to :data]}
{:commando/context [:path :to :data] :=> [:get :key]}
{:commando/context [:path :to :data] :default 0}
Instruction usage (string keys, JSON-compatible):
{"commando-context" ["path" "to" "data"]}
{"commando-context" ["path" "to" "data"] "=>" ["get" "key"]}
{"commando-context" ["path" "to" "data"] "default" 0}
Parameters:
:commando/context — sequential path for get-in on ctx
:=> — optional driver for post-processing [:get :key], [:fn inc], etc.
:default — optional fallback value when path is not found in ctx.
Without :default, missing path throws an error.
Example:
(def my-ctx {:rates {:vat 0.20} :codes {"01" "Kyiv"}})
(:instruction
(commando/execute
[(command-context-spec my-ctx)
command-from-spec command-fn-spec]
{:vat {:commando/context [:rates :vat]}
:city {:commando/context [:codes "01"]}
:missing {:commando/context [:nonexistent] :default "N/A"}
:total {:commando/fn * :args [{:commando/from [:vat]} 1000]}}))
;; => {:vat 0.20 :city "Kyiv" :missing "N/A" :total 200.0}
See Also
`commando.core/execute`
`commando.commands.builtin/command-from-spec`Description
command-fn-spec - execute :commando/fn function/symbol/keyword
with arguments passed inside :args key.
Example (:instruction (commando/execute [command-fn-spec] {:commando/fn #'clojure.core/+ :args [1 2 3]})) ;; => 6
(:instruction (commando/execute [command-fn-spec] {:commando/fn (fn [& [a1 a2 a3]] (* a1 a2 a3)) :args [1 2 3]})) ;; => 6
See Also
commando.core/execute
commando.commands.builtin/command-apply-spec
Description
command-fn-spec - execute `:commando/fn` function/symbol/keyword
with arguments passed inside `:args` key.
Example
(:instruction
(commando/execute
[command-fn-spec]
{:commando/fn #'clojure.core/+
:args [1 2 3]}))
;; => 6
(:instruction
(commando/execute
[command-fn-spec]
{:commando/fn (fn [& [a1 a2 a3]]
(* a1 a2 a3))
:args [1 2 3]}))
;; => 6
See Also
`commando.core/execute`
`commando.commands.builtin/command-apply-spec`Description
command-from-spec - get value from another command or existing value
in Instruction. Path to another command is passed inside :commando/from
key, optionally you can apply :=> driver to the result.
Path can be sequence of keywords, strings or integers, starting absolutely from the root of Instruction, or relatively from the current command position by using "../" and "./" strings in paths.
[:some 2 "value"] - absolute path, started from the root key :some ["../" 2 "value"] - relative path, go up one level and then down to [2 "value"]
Example (:instruction (commando/execute [command-fn-spec command-from-spec] {"value" {:commando/fn (fn [& values] (apply + values)) :args [1 2 3]} "value-incremented" {:commando/from ["value"] :=> [:fn inc]}})) => {"value" 6, "value-incremented" 7}
(:instruction (commando/execute [command-from-spec] {:a {:value 1 :result {:commando/from ["../" :value]}} :b {:value 2 :result {:commando/from ["../" :value]}}})) => {:a {:value 1, :result 1}, :b {:value 2, :result 2}}
(:instruction (commando/execute [command-from-spec] {"a" {"value" {"container" 1} "result" {"commando-from" ["../" "value"] "=>" ["get" "container"]}} "b" {"value" {"container" 2} "result" {"commando-from" ["../" "value"] "=>" ["get" "container"]}}}))
=> /{"a" {"value" {"container" 1}, "result" 1},
/ "b" {"value" {"container" 2}, "result" 2}}
See Also
commando.core/execute
commando.commands.builtin/command-fn-spec
commando.commands.builtin/command-from-spec
Description
command-from-spec - get value from another command or existing value
in Instruction. Path to another command is passed inside `:commando/from`
key, optionally you can apply `:=>` driver to the result.
Path can be sequence of keywords, strings or integers, starting absolutely from
the root of Instruction, or relatively from the current command position by
using "../" and "./" strings in paths.
[:some 2 "value"] - absolute path, started from the root key :some
["../" 2 "value"] - relative path, go up one level and then down to [2 "value"]
Example
(:instruction
(commando/execute [command-fn-spec command-from-spec]
{"value"
{:commando/fn (fn [& values] (apply + values))
:args [1 2 3]}
"value-incremented"
{:commando/from ["value"] :=> [:fn inc]}}))
=> {"value" 6, "value-incremented" 7}
(:instruction
(commando/execute [command-from-spec]
{:a {:value 1
:result {:commando/from ["../" :value]}}
:b {:value 2
:result {:commando/from ["../" :value]}}}))
=> {:a {:value 1, :result 1}, :b {:value 2, :result 2}}
(:instruction
(commando/execute [command-from-spec]
{"a" {"value" {"container" 1}
"result" {"commando-from" ["../" "value"] "=>" ["get" "container"]}}
"b" {"value" {"container" 2}
"result" {"commando-from" ["../" "value"] "=>" ["get" "container"]}}}))
=> /{"a" {"value" {"container" 1}, "result" 1},
/ "b" {"value" {"container" 2}, "result" 2}}
See Also
`commando.core/execute`
`commando.commands.builtin/command-fn-spec`
`commando.commands.builtin/command-from-spec`Description
command-macro-spec - help to define reusable instruction template,
what execute instruction using the same registry as the current one.
Macro id is passed inside :commando/macro or "commando-macro"
key and arguments to mutation passed inside rest of map.
Example Asume we have two vectors with string numbers:
(:instruction (commando/execute [command-fn-spec command-from-spec command-apply-spec] {:= :dot-product :commando/apply {:vector1-str ["1" "2" "3"] :vector2-str ["4" "5" "6"] ;; ------- ;; Parsing :vector1 {:commando/fn (fn [str-vec] (mapv #(Integer/parseInt %) str-vec)) :args [{:commando/from ["../" "../" "../" :vector1-str]}]} :vector2 {:commando/fn (fn [str-vec] (mapv #(Integer/parseInt %) str-vec)) :args [{:commando/from ["../" "../" "../" :vector2-str]}]} ;; ----------- ;; Dot Product :dot-product {:commando/fn (fn [& [v1 v2]] (reduce + (map * v1 v2))) :args [{:commando/from ["../" "../" "../" :vector1]} {:commando/from ["../" "../" "../" :vector2]}]}}})) => 32
But what if we need to calculate those instruction many times with different vectors? It means we need to repeat the same instruction many times with different input data, what quickly enlarges our Instruction size(every usage) and makes it unreadable.
To solve this problem we can use command-macro to define reusable instruction template
(defmethod command-macro :vector-dot-product [_macro-type {:keys [vector1-str vector2-str]}] {:= :dot-product :commando/apply {:vector1-str vector1-str :vector2-str vector2-str ;; ------- ;; Parsing :vector1 {:commando/fn (fn [str-vec] (mapv #(Integer/parseInt %) str-vec)) :args [{:commando/from ["../" "../" "../" :vector1-str]}]} :vector2 {:commando/fn (fn [str-vec] (mapv #(Integer/parseInt %) str-vec)) :args [{:commando/from ["../" "../" "../" :vector2-str]}]} ;; ----------- ;; Dot Product :dot-product {:commando/fn (fn [& [v1 v2]] (reduce + (map * v1 v2))) :args [{:commando/from ["../" "../" "../" :vector1]} {:commando/from ["../" "../" "../" :vector2]}]}}})
and then just use it
(:instruction (commando/execute [command-macro-spec command-fn-spec command-from-spec command-apply-spec] {:vector-dot-1 {:commando/macro :vector-dot-product :vector1-str ["1" "2" "3"] :vector2-str ["4" "5" "6"]} :vector-dot-2 {:commando/macro :vector-dot-product :vector1-str ["10" "20" "30"] :vector2-str ["4" "5" "6"]}})) => {:vector-dot-1 32, :vector-dot-2 320}
See Also
commando.core/execute
commando.commands.builtin/command-macro
Description
command-macro-spec - help to define reusable instruction template,
what execute instruction using the same registry as the current one.
Macro id is passed inside `:commando/macro` or `"commando-macro"`
key and arguments to mutation passed inside rest of map.
Example
Asume we have two vectors with string numbers:
1) ["1", "2", "3"], 2) ["4" "5" "6"]
we need to parse them to integers and then calculate dot product.
Here the solution using commando commands with one instruction
(:instruction
(commando/execute
[command-fn-spec command-from-spec command-apply-spec]
{:= :dot-product
:commando/apply
{:vector1-str ["1" "2" "3"]
:vector2-str ["4" "5" "6"]
;; -------
;; Parsing
:vector1
{:commando/fn (fn [str-vec]
(mapv #(Integer/parseInt %) str-vec))
:args [{:commando/from ["../" "../" "../" :vector1-str]}]}
:vector2
{:commando/fn (fn [str-vec]
(mapv #(Integer/parseInt %) str-vec))
:args [{:commando/from ["../" "../" "../" :vector2-str]}]}
;; -----------
;; Dot Product
:dot-product
{:commando/fn (fn [& [v1 v2]] (reduce + (map * v1 v2)))
:args [{:commando/from ["../" "../" "../" :vector1]}
{:commando/from ["../" "../" "../" :vector2]}]}}}))
=> 32
But what if we need to calculate those instruction many times with different vectors?
It means we need to repeat the same instruction many times with different input data,
what quickly enlarges our Instruction size(every usage) and makes it unreadable.
To solve this problem we can use `command-macro` to define reusable instruction template
(defmethod command-macro :vector-dot-product [_macro-type {:keys [vector1-str vector2-str]}]
{:= :dot-product
:commando/apply
{:vector1-str vector1-str
:vector2-str vector2-str
;; -------
;; Parsing
:vector1
{:commando/fn (fn [str-vec]
(mapv #(Integer/parseInt %) str-vec))
:args [{:commando/from ["../" "../" "../" :vector1-str]}]}
:vector2
{:commando/fn (fn [str-vec]
(mapv #(Integer/parseInt %) str-vec))
:args [{:commando/from ["../" "../" "../" :vector2-str]}]}
;; -----------
;; Dot Product
:dot-product
{:commando/fn (fn [& [v1 v2]] (reduce + (map * v1 v2)))
:args [{:commando/from ["../" "../" "../" :vector1]}
{:commando/from ["../" "../" "../" :vector2]}]}}})
and then just use it
(:instruction
(commando/execute
[command-macro-spec command-fn-spec command-from-spec command-apply-spec]
{:vector-dot-1
{:commando/macro :vector-dot-product
:vector1-str ["1" "2" "3"]
:vector2-str ["4" "5" "6"]}
:vector-dot-2
{:commando/macro :vector-dot-product
:vector1-str ["10" "20" "30"]
:vector2-str ["4" "5" "6"]}}))
=> {:vector-dot-1 32, :vector-dot-2 320}
See Also
`commando.core/execute`
`commando.commands.builtin/command-macro`Description
command-mutation-spec - execute mutation of Instruction data.
Mutation id is passed inside :commando/mutation or "commando-mutation"
key and arguments to mutation passed inside rest of map.
To declare mutation create method of command-mutation multimethod
Example (defmethod commando.commands.builtin/command-mutation :generate-string [_ {:keys [length]}] {:random-string (apply str (repeatedly (or length 10) #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))})
(defmethod commando.commands.builtin/command-mutation :generate-number [_ {:keys [from to]}] {:random-number (let [bound (- to from)] (+ from (rand-int bound)))})
(:instruction (commando/execute [command-mutation-spec] {:a {:commando/mutation :generate-number :from 10 :to 20} :b {:commando/mutation :generate-string :length 5}})) => {:a {:random-number 14}, :b {:random-string "5a379"}}
Example with-string keys (defmethod commando.commands.builtin/command-mutation "generate-string" [_ {:strs [length]}] {"random-string" (apply str (repeatedly (or length 10) #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))})
(defmethod commando.commands.builtin/command-mutation "generate-number" [_ {:strs [from to]}] {"random-number" (let [bound (- to from)] (+ from (rand-int bound)))})
(:instruction (commando/execute [command-mutation-spec] {"a" {"commando-mutation" "generate-number" "from" 10 "to" 20} "b" {"commando-mutation" "generate-string" "length" 5}})) => {"a" {"random-number" 18}, "b" {"random-string" "m3gj1"}}
See Also
commando.core/execute
commando.commands.builtin/command-mutation-spec
commando.commands.builtin/command-mutation
Description
command-mutation-spec - execute mutation of Instruction data.
Mutation id is passed inside `:commando/mutation` or `"commando-mutation"`
key and arguments to mutation passed inside rest of map.
To declare mutation create method of `command-mutation` multimethod
Example
(defmethod commando.commands.builtin/command-mutation :generate-string [_ {:keys [length]}]
{:random-string (apply str (repeatedly (or length 10) #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))})
(defmethod commando.commands.builtin/command-mutation :generate-number [_ {:keys [from to]}]
{:random-number (let [bound (- to from)] (+ from (rand-int bound)))})
(:instruction
(commando/execute
[command-mutation-spec]
{:a {:commando/mutation :generate-number :from 10 :to 20}
:b {:commando/mutation :generate-string :length 5}}))
=> {:a {:random-number 14}, :b {:random-string "5a379"}}
Example with-string keys
(defmethod commando.commands.builtin/command-mutation "generate-string" [_ {:strs [length]}]
{"random-string" (apply str (repeatedly (or length 10) #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))})
(defmethod commando.commands.builtin/command-mutation "generate-number" [_ {:strs [from to]}]
{"random-number" (let [bound (- to from)] (+ from (rand-int bound)))})
(:instruction
(commando/execute
[command-mutation-spec]
{"a" {"commando-mutation" "generate-number" "from" 10 "to" 20}
"b" {"commando-mutation" "generate-string" "length" 5}}))
=> {"a" {"random-number" 18}, "b" {"random-string" "m3gj1"}}
See Also
`commando.core/execute`
`commando.commands.builtin/command-mutation-spec`
`commando.commands.builtin/command-mutation`cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |