# Strange Behavior when making Equal Listable in Pick

While trying to make this problem more efficient I tried different methods and dabbled with making Greater and Equal Listable. To my surprise, while Greater worked as expected, Equal on the other hand showed a strange behavior. Let's dig deeper:

First let's look at Greater

Pick[#, DivisorSigma[1, #] > 2 #] &@Range[6]


Gives the error:

Pick::incomp: Expressions {1,2,3,4,5,6} and {1,3,4,7,6,12}>{2,4,6,8,10,12} have incompatible
shapes. >>


Now we make Greater Listable

SetAttributes[Greater, Listable]


And we can now evaluate the above command successfully

Pick[#, DivisorSigma[1, #] > 2 #] &@Range[20]


{12, 18, 20}

Okay, let's move on to Equal

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]


Sequence[]

We now make Equal Listable

SetAttributes[Equal, Listable]
Attributes[Equal]


{Listable, Protected}

Now let's try again:

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]


Sequence[]

Hmmm, what's going on here?

Well, let's explicitly provide the list and see what happens:

Pick[{1, 2, 3, 4, 5, 6, 7, 8},
DivisorSigma[1, {1, 2, 3, 4, 5, 6, 7, 8}] == 2 {1, 2, 3, 4, 5, 6, 7, 8}]


{6}

Interesting, this works!

okay now let's textually substitute using With, this should technically be the same thing right?

With[{p = Range[8]}, Pick[p, DivisorSigma[1, p] == 2*p]]


Sequence[]

I guess not.

Finally, let's look at Trace. I'll shorten the input list here.

First with explicit input of list:

Pick[{4, 5, 6}, DivisorSigma[1, {4, 5, 6}] == 2 {4, 5, 6}] // Trace


Pick[Range[4, 6], DivisorSigma[1, Range[4, 6]] == 2 Range[4, 6]] // Trace


We see that only in the explicit case does Equal act Listable What is going on here? Sorry about the tiny images.

• @PinguinDirk. I have a workaround that works if you look at my answer in the link. Just wondering why greater works but Equal doesn't work properly. Oct 21, 2013 at 20:12
• I think this is related to this question. Range gives a packed array, for which Equal has special handling which bypasses the main evaluator. Oct 21, 2013 at 20:16
• I missed this question before but I agree with what @Simon wrote. Simon, do you care to post that as an answer? I think someone should. Sep 11, 2014 at 11:28
• @Mr.Wizard, done. Sep 11, 2014 at 12:27

This is a manifestation of the issue raised in this question, that Equal for packed arrays is handled in a non-standard way, causing the Listable attribute to be ignored.

Range[8] returns a packed array, so for that case the non-standard evaluation kicks in. But the explicitly entered list {1, 2, 3, 4, 5, 6, 7, 8} is not a packed array, so you get the desired result.

EDIT

My original answer posted below was a naive misunderstanding.

However,

For what its worth (apologies again for previous misconception):

SetAttributes[Equal, Listable]
Pick[#, Release@(Hold[DivisorSigma[1, #] == 2 #])] &@Range[8]


works...

OLD

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]


your test applies to elements whereas you expect your Pick to apply to list. When you 'replace' # with list it works.

Note (for illustration purposes):

Function[x, Pick[x, DivisorSigma[1, #] == 2 # & /@ x]][Range[8]]


works.

In contrast the following works without modification:

Select[#, DivisorSigma[1, #] == 2 # &] &@Range[8]


or

Cases[#, _?(DivisorSigma[1, #] == 2 # &)] &@Range[8]

• Actually, the point is that if you put the list explicitly it works. You can see that it works with Greater only when you make Greater Listable, note that I made Equal Listable. Also look at the Trace to see what's happening. Oct 22, 2013 at 10:53
• apologies, I take your point and as such have learned something, however i believe we are making the same point despite my poor explanation...when Greater is make listable the second argument of of Pick is a list of True,False from Pick will select. I apologise for not appreciating that you made Equal listable and hence your dilemma...rendering Equal listable for test produces desired list outside Pick but malfunctions inside Pick... Oct 22, 2013 at 11:45