2
$\begingroup$

I have a list of three lists of strings. Thus, MatchQ[{{__String}, {__String}, {__String}}] is True. I would like to extract all the strings which are present in the first two lists but not in the third.

According to the documentation, the following two expressions using Through should be logically equivalent. Yet, the first one runs without error, while the second one produces the message shown below, before producing the correct output anyway:

ClearAll[lst];
lst = {CharacterRange["a", "h"], CharacterRange["d", "k"], CharacterRange["g", "n"]};

lst // Through[{Most /* Apply[Intersection], Last}[#]] & // Apply[Complement]
(* Output: {d, e, f} *)

lst // Through[Complement[Most /* Apply[Intersection], Last][#]] &
(*
    Complement::normal: Nonatomic expression expected at position 2 in Complement[Most/*Apply[Intersection],Last].
    {d, e, f}
*)

Why is the second expression generating an error message?

$\endgroup$
1
  • $\begingroup$ Isn't this exactly the same as the first expression (which does not produce an error)? The operator @@ is the same as Apply. I am trying to understand why the second one would produce an error message, since the documentation suggests that I should be able to apply the head Complement in Through directly. $\endgroup$ Commented Nov 5, 2018 at 19:25

1 Answer 1

3
$\begingroup$

Through does not have any Hold attributes:

Attributes[Through]

{Protected}

Hence, Complement tries to evaluate before Through performs its function. For a simpler example:

Through[Complement[Most, Rest][Range[10]]]

Complement::normal: Nonatomic expression expected at position 1 in Complement[Most,Rest].

{1}

Since Complement[Most, Rest] doesn't evaluate, Through will still do its thing, and then Complement will evaluate. Another way of seeing this is to give Through the HoldAll attribute:

SetAttributes[Through, HoldAll]
Through[Complement[Most, Rest][Range[10]]]
ClearAttributes[Through, HoldAll]

{1}

No error messages.

$\endgroup$
2
  • $\begingroup$ Thanks a lot for the explanation. $\endgroup$ Commented Nov 5, 2018 at 20:10
  • $\begingroup$ Is there any conceivable benefit to not having this as the default setting? Why would the designers have chosen not to give Through the HoldAll attribute? $\endgroup$ Commented Nov 5, 2018 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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