cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically project function

erichards
New Contributor II

Two questions on function projection 🙂

Firstly, how can I project a function to one with no args, i.e. deferred execution.

fn: {[x] x+1};

Obviously fn[1] or fn @ 1 will invoke the function now. Is there a way without wrapping it in another fn?

 

Secondly, how can I dynamically project a function, e.g.

fn: {[x;y;z] x+y-z};
args: (1; ::; 3);

I'd like to achieve the equivalent of fn[1; ; 3], however fn . args invokes the function now with the second parameter as null rather than returning a projection.

 

Thanks

1 ACCEPTED SOLUTION

gyorokpeter-kx
Contributor
Contributor

In reality there is no such thing as a "zero-argument function" in q. Even if you don't have an argument list and you don't use any of x, y and z in your function, or if you specify the argument list as [], the function still has one argument. If you call a function with "no arguments" [], that actually means calling it with :: as an argument.

Projection for the purpose of a deferred function call is achieved by adding a dummy argument, e.g. instead of

fn: {[x] x+1};

you would have

fn: {[x;u] x+1};

then fn[1] creates a projection that will execute the calculation with any argument passed.

For the second question, one possible way is by composing a projection of enlist with the dot-apply of your function:

q)proj:(')[fn .;(1; ; 3)];
q)proj
.[{[x;y;z] x+y-z}]enlist[1;;3]
q)proj 2
0
q)proj 10
8

 

View solution in original post

1 REPLY 1

gyorokpeter-kx
Contributor
Contributor

In reality there is no such thing as a "zero-argument function" in q. Even if you don't have an argument list and you don't use any of x, y and z in your function, or if you specify the argument list as [], the function still has one argument. If you call a function with "no arguments" [], that actually means calling it with :: as an argument.

Projection for the purpose of a deferred function call is achieved by adding a dummy argument, e.g. instead of

fn: {[x] x+1};

you would have

fn: {[x;u] x+1};

then fn[1] creates a projection that will execute the calculation with any argument passed.

For the second question, one possible way is by composing a projection of enlist with the dot-apply of your function:

q)proj:(')[fn .;(1; ; 3)];
q)proj
.[{[x;y;z] x+y-z}]enlist[1;;3]
q)proj 2
0
q)proj 10
8