Generating a function with named slots

Say I have an association:

a = <|"a" -> "albatross", "b" -> "barbecue", "c" -> "champagne"|>


And say I want a function with named slots to transform this association to a list:

In:  a // {#a, #b, #a, #c, #a <> "-" <> #c} &
Out: {"albatross", "barbecue", "albatross", "champagne", "albatross-champagne"}


I want to programmatically create a function like this, rather than write it out explicitly in code. One hurdle I've come across is working with the Slot function. The following inputs all give the same, desired output:

In:  a // {#a, #b} &
In:  a // {#["a"], #["b"]} &
In:  a // {Slot["a"], Slot["b"]} &
In:  a // ToExpression["{#a, #b}&"]
In:  a // Function[assoc, assoc[[#]] & /@ {"a", "b"}]
Out: {"albatross", "barbecue"}


I could roll with the fifth option. But I'm surprised the following code doesn't return what I expect:

In:  a // (Slot /@ {"a", "b"}) &
Out: {#a, #b}


I am surprised this one returns neither what I expect, nor agrees with the above code:

In:  a // Function[assoc, assoc[Slot /@ {"a", "b"}]]
Out: Missing["KeyAbsent", {#a, #b}]


Reading this led me to try the following option— no luck:

In:  a // With[{v1 = "a", v2 = "b"}, Slot /@ {v1, v2} &]
Out: {#a, #b}


I want to make this code work, or at least understand why the above code doesn't work. What am I missing in my understanding of the Slot function?

• Try a // Evaluate[Slot /@ {"a", "b"}] &. You can use Trace to get what's wrong. Moreover your input seems to be an association and key names, why not using Lookup/Query etc?
– Kuba
Oct 20, 2015 at 14:25
• I didn't know about Trace. Great, this gets me on the right track! Oct 20, 2015 at 16:03
• The context behind my question is that I want to add many columns to a dataset. Each of the new columns is a combination of other columns. The relations that define these new columns quickly become complicated. It's easier and more readable for me to define these relations with a set of rules, which I then use to build a set of functions that I can apply on the dataset. I'll try out Lookup/Query, should be doable too. Oct 20, 2015 at 16:09
• To make sure I understand right: in a // (Slot /@ {"a", "b"}) &, Apply evaluates before Slot. But in a // Evaluate[Slot /@ {"a", "b"}] &, using Evaluate forces Slot to be evaluated before Apply. Correct? Oct 20, 2015 at 16:14
• I wanted to note that Slot["a"] is precisely the same thing as #a. There is absolutely no difference. Once Mathematica reads either, it uses the very same internal representation. Oct 20, 2015 at 22:10

I am not at all sure I understand what you are asking, From your comment, it would seem your ultimate goal is to extend a data set by adding new fields based on the current ones. That task can be done directly, without building a new extended value list as you seem to be attempting.

ds = Dataset[{<|"a" -> "albatross", "b" -> "barbecue", "c" -> "champagne"|>,
<|"a" -> "fee", "b" -> "fye", "c" -> "foe"|>}]


ds[All,
<|"a" -> #a, "b" -> #b, "a2" -> #a, "c" -> #c, "combo" -> #a <> "-" <> #c|> &]


Because datasets and their underlying associations don't permit duplicate keys, I introduced two new keys, "a2" and "combo".

• Thanks for your comment. I didn't provide enough context here. I wrote a new question which better explains what I had in mind: mathematica.stackexchange.com/questions/97533/… Oct 21, 2015 at 14:02
• In short: I am aware you can write something like <|"a" -> #a, "b" -> #b, "a2" -> #a, "c" -> #c, "combo" -> #a <> "-" <> #c|> &. But how can you write code that produces a function like that? I answer this question in the link above. Oct 21, 2015 at 14:04