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?

  • $\begingroup$ 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? $\endgroup$ – Kuba Oct 20 '15 at 14:25
  • $\begingroup$ I didn't know about Trace. Great, this gets me on the right track! $\endgroup$ – akrodha Oct 20 '15 at 16:03
  • $\begingroup$ 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. $\endgroup$ – akrodha Oct 20 '15 at 16:09
  • $\begingroup$ 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? $\endgroup$ – akrodha Oct 20 '15 at 16:14
  • $\begingroup$ 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. $\endgroup$ – Szabolcs Oct 20 '15 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"|>}]


   <|"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".

| improve this answer | |
  • $\begingroup$ 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/… $\endgroup$ – akrodha Oct 21 '15 at 14:02
  • $\begingroup$ 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. $\endgroup$ – akrodha Oct 21 '15 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.