Possibly Related to Unexpected behavior of KeyTake.

Consider the following example, where I input #11 (last) is the misbehaving one. Am I missing something or do you agree there is a bug?

In[1]:= assoc = <|1 -> "x", 2 -> "y"|>

Out[1]= <|1 -> "x", 2 -> "y"|>

In[2]:= KeyTake[{1}][assoc]

Out[2]= <|1 -> "x"|>

In[3]:= <|2 -> #[2]|> &[assoc]

Out[3]= <|2 -> "y"|>

In[4]:= f1 = KeyTake[{1}];

In[5]:= f2 = <|2 -> #[2]|> &;

In[6]:= f3[x_] := KeyTake[x, {1}];

In[7]:= f4[x_] := KeyTake[{1}][x];

In[8]:= Join[f1[assoc], f2[assoc]]

Out[8]= <|1 -> "x", 2 -> "y"|>

In[9]:= Through[Join[f4, f2][assoc]]

Out[9]= <|1 -> "x", 2 -> "y"|>

In[10]:= Through[Join[f3, f2][assoc]]

Out[10]= <|1 -> "x", 2 -> "y"|>

In[11]:= Through[Join[f1, f2][assoc]]

During evaluation of In[11]:= Join::heads: Heads KeyTake and Function at positions 1 and 2 are expected to be the same.

Out[11]= <|1 -> "x", 2 -> "y"|>

Inexplicably we still get the correct result. Why is that?

I think the error is caused by the fact that Through Does not have Hold* Attribute, which I find to be strange given what it is supposed to do.

In[12]:= Attributes[Through]

Out[12]= {Protected}

An alternative implementation that does hold arguments seems to work fine, though I haven't tested it too much and it may have other bugs:

SetAttributes[through, HoldAll]
through[head_[args__][arg__]] := Apply[head, Map[#[arg] &, {args}]];

In[31]:= through[Join[f1, f2][assoc]]

Out[31]= <|1 -> "x", 2 -> "y"|>

Come to think about it, it is simple enough to pass arguments Unevaluated to Through, so perhaps everything works correctly.

|improve this answer|||||

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.