Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
edited tags
Link
Michael E2
  • 244.8k
  • 18
  • 351
  • 774
Source Link
Shwouchk
  • 517
  • 3
  • 8

Through does not have hold attribute?

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:

ClearAll[through]
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"|>
```