Shorthand Combined Functions
JavaScript (ES6), 174 171 bytes
(d,o,f,v,g=(f,V=v)=>f?V.map(v=>f+`(${v})`):V)=>f+f&&v+v?(d<'»'?f[1]?f.map(f=>g(f).join``):g(f[0]):v.map((_,i)=>v.map((_,j)=>g(f[j],[v[i++%v.length]])).join``)).join(o):''
Try it online!
Commented
( d, // d = direction
o, // o = operator
f, // f[] = list of functions
v, // v[] = list of variables
g = (f, V = v) => // g = helper function taking (f, V[])
f ? // if f is defined:
V.map(v => // for each variable v in V[]:
f + `(${v})` // return f, followed by '(v)'
) //
: // else:
V // just return V[] as-is
) => //
f + f && v + v ? // if both f[] and v[] are non-empty:
( d < '»' ? // if the direction is '«':
f[1] ? // if there are at least 2 functions:
f.map(f => // for each function f_i in f[]:
g(f).join`` // return 'f_i(v_0)f_i(v_1)...'
) // end of map()
: // else:
g(f[0]) // return [ 'f_0(v_0)', 'f_0(v_1)', ... ]
: // else (the direction is '»'):
v.map((_, i) => // for each variable at position i:
v.map((_, j) => // for each variable at position j:
g( // return [ 'f_j(v_k)' ]
f[j], // where k = i mod v.length
[v[i++ % v.length]] // and increment i
) //
).join`` // end of inner map(); join the list
) // end of outer map()
).join(o) // join the final list with the operator
: // else:
'' // just return an empty string
05AB1E, 63 bytes
UÇ`θiVεY€…(ÿ)«}ëDg©DIgα+>∍Œ®ùεζεðK'(ýyðå≠i')«]Dg≠iJ}¸˜Xý³gIg*Ā×
Four loose inputs in the order operator, direction, [variables], [functions]
.
Try it online or verify all test cases.
Explanation:
U # Pop and store the 1st (implicit) input `operator` in variable `X`
Ç # Convert the 2nd (implicit) input `direction` to a list of codepoint
` # Push this codepoint to the stack
θ # Only leave its last digit
i # If this digit is 1 (so the direction is "«"):
V # Pop and store the 3rd (implicit) input `variables` in variable `Y`
ε } # Map over the 4th (implicit) input `functions`:
Y # Push the `variable`-list from variable `Y`
€…(ÿ) # Surround each variable with parenthesis
« # And append it to the current `function` we're mapping
ë # Else (so the direction is "»" instead):
D # Duplicate the 3rd (implicit) input `variables`
g # Pop and push the length to get the amount of `variables`
© # Store it in variable `®` (without popping)
D # Duplicate this length
I # Push the fourth input `functions`
g # Pop and take its length as well
α # Take the absolute difference between the two amounts
+ # And add it to the duplicated amount of `variables`
> # And increase it by 1
∍ # Then extend the duplicated `variables` list to that length
Œ # Get all sublists of this list
®ù # Only leave the sublists of a length equal to variable `®`
ε # Map each remaining sublist to:
ζ # Create pairs with the 4th (implicit) input `functions`,
# with a default space as filler character if the lengths differ
ε # Map each pair:
ðK # Remove the spaces
'(ý '# Join the pair with a ")" delimiter
yðå≠i # If the current pair did NOT contain a space:
')« '# Append a ")"
] # Close all open if-statements and maps
D # Duplicate the resulting list
g≠i } # Pop and if its length is NOT 1:
J # Join the inner-most list together to a string
¸ # Then wrap it into a list (in case it wasn't a list yet)
˜ # And deep flatten the list
Xý # Join it by the operator we stores in variable `X`
³g # Get the length of the 3rd input-list `variables`
Ig # And the length of the 4th input-list `functions`
* # Multiply them with each other
Ā # Truthify it (0 remains 0; everything else becomes 1)
× # And repeat the string that many times
# (so it becomes an empty string if either list was empty,
# or remains unchanged otherwise)
# (after which this is output implicitly as result)