Let:
NB. an example gerund
] g=: *:`<:`+:`>:
┌──┬──┬──┬──┐
│*:│<:│+:│>:│
└──┴──┴──┴──┘
NB. a sentence to evoke
*: <: +: >: 4
81
1st approach (via dynamic programming)
1A. Compose the whole sentence then evoke it
Convert all elements in gerund to linear representation (LR), compose the sentence, then evoke it:
NB. utility to find out a LR from an atomic
NB. representation (AR) and parenthesize it
NB. pLR=. plr AR
plr=: 3 : 0
v=. y 5!:0
'(' , (5!:5 < 'v') , ') '
)
NB. result=. gerund v1 input
v1=: 4 : '". (; <@plr"0 x) , ": y'
NB. evoke v1 with a gerund and input applied
g v1 4
81
Pros: no
Cons:
- input data type should be exact (neither float nor complex) since Format (
":
) may truncate
- a verb applied to input can be a monad only
1B. Evoke component verbs sequentially
Take the current element from gerund, transform it to verb, apply that verb to accumulator, repeat for the next element from gerund:
NB. result=. gerund v2 input
v2=: >@(4 : '(x 5!:0)&.> y'/)@(, <)
NB. evoke v2 with a gerund and input applied
g v2 4
81
Pros:
- any data types for input are allowed
Cons:
- a verb applied to input can be a monad only
2nd approach (functional)
2A. Transform gerund to fork
NB. a fork we are going to compose, in action
([: *: [: <: [: +: >:) 4
81
NB. its structure
([: *: [: <: [: +: >:)
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│ │ ││[:│<:│┌──┬──┬──┐││
│ │ ││ │ ││[:│+:│>:│││
│ │ ││ │ │└──┴──┴──┘││
│ │ │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
NB. how to compose it
('[:' ; g)@.0 1 0 2 0 3 4
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│ │ ││[:│<:│┌──┬──┬──┐││
│ │ ││ │ ││[:│+:│>:│││
│ │ ││ │ │└──┴──┴──┘││
│ │ │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
NB. selector (ISO generator)
NB. iso=. sel gerund
sel=: (< < < _2) { (0 ,@,. #\)
NB. let's test it
sel g
0 1 0 2 0 3 4
NB. sentence to assemble a fork
('[:' ; g)@.(sel g)
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│ │ ││[:│<:│┌──┬──┬──┐││
│ │ ││ │ ││[:│+:│>:│││
│ │ ││ │ │└──┴──┴──┘││
│ │ │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
NB. an adverb executing that sentence
NB. fork=. gerund a2a
a2a=: 1 : '(''[:'' ; m)@.(sel m)'
NB. evoke that adverb to transform a gerund to a fork
g a2a
┌──┬──┬──────────────────┐
│[:│*:│┌──┬──┬──────────┐│
│ │ ││[:│<:│┌──┬──┬──┐││
│ │ ││ │ ││[:│+:│>:│││
│ │ ││ │ │└──┴──┴──┘││
│ │ │└──┴──┴──────────┘│
└──┴──┴──────────────────┘
NB. apply a fork produced to input
g a2a 4
81
Pros:
- any data types for input are allowed
- a verb applied to input can be of any valence (either monad, dyad or ambivalent)
Cons: no
2B. Transform gerund to conveyor
Join component verbs by At (@:
) somehow. A resulting verb will be an At-chained sequence of component verbs.
2B1. Via arconj utility
Join component verbs to compose AR, then convert AR to verb by Define (5!:0
).
NB. a chain we are going to compose, in action
*:@:<:@:+:@:>: 4
81
NB. its structure
*:@:<:@:+:@:>:
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││ │ │
│││*:│@:│<:││ │ ││ │ │
││└──┴──┴──┘│ │ ││ │ │
│└──────────┴──┴──┘│ │ │
└──────────────────┴──┴──┘
NB. its AR
chain=. *:@:<:@:+:@:>:
5!:1 < 'chain'
┌────────────────────────────────┐
│┌──┬───────────────────────────┐│
││@:│┌──────────────────────┬──┐││
││ ││┌──┬─────────────────┐│>:│││
││ │││@:│┌────────────┬──┐││ │││
││ │││ ││┌──┬───────┐│+:│││ │││
││ │││ │││@:│┌──┬──┐││ │││ │││
││ │││ │││ ││*:│<:│││ │││ │││
││ │││ │││ │└──┴──┘││ │││ │││
││ │││ ││└──┴───────┘│ │││ │││
││ │││ │└────────────┴──┘││ │││
││ ││└──┴─────────────────┘│ │││
││ │└──────────────────────┴──┘││
│└──┴───────────────────────────┘│
└────────────────────────────────┘
NB. we'll compose it with AR utility (arconj) from addon
load 'misc/miscutils/langexten'
NB. an adverb assembling a chain
NB. chain=. gerund a2b1a
a2b1a=: 1 : '(''@:'' arconj~/ |. m) 5!:0'
NB. evoke that adverb to transform a gerund to chain
g a2b1a
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││ │ │
│││*:│@:│<:││ │ ││ │ │
││└──┴──┴──┘│ │ ││ │ │
│└──────────┴──┴──┘│ │ │
└──────────────────┴──┴──┘
NB. apply a chain produced to input
g a2b1a 4
81
Pros:
- any data types for input are allowed
- a verb applied to input can be of any valence (either monad, dyad or ambivalent)
Cons: no
Notes:
a2b1a can be simplified to produce a chain with a slightly different structure but the same functionality:
a2b1b=: 1 : '(''@:'' arconj/ m) 5!:0'
arconj utility may be re-implemented manually as [1]:
arconj2=: (<'@:') ,@<@, <@,
a2b1c=: 1 : '({. arconj2/ m) 5!:0'
or as [1]:
arconj3=: 4 : '(x`:6)@(y`:6)`'''''
a2b1d=: 1 : '({. arconj3/ m) 5!:0'
2B2. Via Train (`:6
)
Join component verbs, then apply Train (`:6
) [2].
NB. a chain we are going to compose, in action
*:@:<:@:+:@:>: 4
81
NB. its structure
*:@:<:@:+:@:>:
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││ │ │
│││*:│@:│<:││ │ ││ │ │
││└──┴──┴──┘│ │ ││ │ │
│└──────────┴──┴──┘│ │ │
└──────────────────┴──┴──┘
NB. an adverb assembling a chain
NB. chain=. gerund a2b2
a2b2=: 1 : '(}: , m ,. <''@:'')`:6'
NB. evoke that adverb to transform a gerund to chain
g a2b2
┌──────────────────┬──┬──┐
│┌──────────┬──┬──┐│@:│>:│
││┌──┬──┬──┐│@:│+:││ │ │
│││*:│@:│<:││ │ ││ │ │
││└──┴──┴──┘│ │ ││ │ │
│└──────────┴──┴──┘│ │ │
└──────────────────┴──┴──┘
NB. apply a chain produced to input
g a2b2 4
81
Pros:
- any data types for input are allowed
- a verb applied to input can be of any valence (either monad, dyad or ambivalent)
- the simplest version
Cons: no
Notes
J Forums are the best place to ask if you prefer to get answer quicker.
References
[1]: [Jprogramming] Gerund composed application
by Raul Miller, 2017-09-25
[2]: System/Interpreter/Requests#verb pipelines by Dan Bron, 2007-12-21
*:`(+: -:)`>:
will raise error. A workaround may be to process each component verb in gerund individually. – Deborahdeborath