Skip to main content
I corrected the Updated version of partialEvaluate to work as the OP advertised: there was a comma missing after `totargs` and `args` must not be indexed by i.
Source Link

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) g, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{numargsEvaluated = 1, newArgs = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]]args[[argsEvaluated++]], Slot[num++]]Slot[newArgs++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

The main reason the OP's original code didn't work is that Function has the Attribute HoldAll:

Attributes[Function]
(* {HoldAll, Protected} *)

If you want the insides of Function to be evaluated, you have to explicitly Evaluate it, as I've done.

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) g, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

The main reason the OP's original code didn't work is that Function has the Attribute HoldAll:

Attributes[Function]
(* {HoldAll, Protected} *)

If you want the insides of Function to be evaluated, you have to explicitly Evaluate it, as I've done.

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) g, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{argsEvaluated = 1, newArgs = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[argsEvaluated++]], Slot[newArgs++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

The main reason the OP's original code didn't work is that Function has the Attribute HoldAll:

Attributes[Function]
(* {HoldAll, Protected} *)

If you want the insides of Function to be evaluated, you have to explicitly Evaluate it, as I've done.

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &
Updated to be more in line with what OP wanted. Included brief explanation of why OP's original code didn't work.
Source Link
march
  • 24.2k
  • 2
  • 46
  • 102

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) fg, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

The main reason the OP's original code didn't work is that Function has the Attribute HoldAll:

Attributes[Function]
(* {HoldAll, Protected} *)

If you want the insides of Function to be evaluated, you have to explicitly Evaluate it, as I've done.

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) f, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) g, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

The main reason the OP's original code didn't work is that Function has the Attribute HoldAll:

Attributes[Function]
(* {HoldAll, Protected} *)

If you want the insides of Function to be evaluated, you have to explicitly Evaluate it, as I've done.

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &
Updated to be more in line with what OP wanted.
Source Link
march
  • 24.2k
  • 2
  • 46
  • 102

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) f, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &

Updated version

To be more in line with what the OP wanted, we have the following updated code. Given inputs (in order) f, totargs = 5, args = {x[1],x[4]}, and targets = {1,4}, if we call the function

partialEvaluate[func_, totargs_ args_, targets_] := Block[{num = 1}
 , Evaluate[func @@ Table[
    If[MemberQ[targets, i], args[[i]], Slot[num++]]
    , {i, 1, totargs}]
   ] &
]

the result is

g[x[1], #1, #2, x[4], #3] &

Original post

I'm not sure of exactly what the inputs and outputs should be, but here's my best guess as to what you want, with minimal changes to your code. For the purpose of concreteness, let's suppose that totargs = 5, args = {x[1],x[2],x[3],x[4],x[5]}, and the target variables to which the function is going to be applied to are targets = {1,4}. Then if we call the function

partialEvaluate[func_, totargs_, args_, targets_] := Block[{tmp}
  , tmp = Table[Slot[i], {i, 1, totargs}]
  ; tmp[[targets]] = args[[targets]]
  ; Evaluate[func @@ tmp] &
]

with the input

partialEvaluate[g, 5, {x[1], x[2], x[3], x[4], x[5]}, {1, 4}]

we get the pure function

g[x[1], #2, #3, x[4], #5] &
Source Link
march
  • 24.2k
  • 2
  • 46
  • 102
Loading