Why does Slot[1][colname]&
work when Slot[colname]&
doesn't?
As noted in a comment, it is interesting to contrast the behaviours of Slot[1][colname]&
and Slot[colname]&
.
We will use simplified examples with the following definition:
a = <| "x" -> 123 |>;
Recall that keys can be extracted from associations by using function call syntax, or by using part syntax:
a["x"]
(* 123 *)
a[["x"]]
(* 123 *)
This works even if the key name is stored in a variable:
colname = "x";
a[colname]
(* 123 *)
a[[colname]]
(* 123 *)
This behaviour remains valid even if the association is passed as an argument to a pure function:
#[colname]&[a]
(* 123 *)
#[[colname]]&[a]
(* 123 *)
In these cases, colname
remains unevaluated within the function body but is evaluated when the function is executed.
We can also write these expressions using the full form of #
:
# // FullForm
(* Slot[1] *)
Slot[1][colname]&[a]
(* 123 *)
Slot[1][[colname]]&[a]
(* 123 *)
These expressions all work because both function call syntax and part syntax evaluate their keys as a matter of course.
All of this is in contrast to the use of Slot[colname]
which, as noted in the first section, never evaluates the slot value and is thus invalid syntax. We are informed of this error even if simply try to define a function that uses it:
Slot[colname]&
(* Function::slot:Slot[colname](in Slot[colname]&) should contain a non-negative integer.
Slot[colname] &
*)
If we go so far as to define and call the function, we get the error twice:
Slot[colname]&[a]
(* Function::slot:Slot[colname](in Slot[colname]&) should contain a non-negative integer.
Function::slot:Slot[colname](in Slot[colname]&) should contain a non-negative integer.
(Slot[colname]&)[<|x->123|>]
*)
The first message comes from defining the function, and the second from calling the function. colname
remains unevaluated within the function body and also when the function is executed.