Leaving aside the wisdom of modifying System functions this is an interesting question.
I would not have been surprised to see this behavior had the input list been packed as I have already learned about low-level optimizations on packed arrays. See:
However that does not appear to be the issue here since (typed in) {1, 2, 3} is not packed. Apparently the "listable" behavior of Sqrt is not (only) implemented in terms of the attribute Listable. As an example here is function without Listable that still threads over lists:
f[x_List] := f /@ x
f[{1, 2, 3}]
{f[1], f[2], f[3]}
Leonid writes about Listability here:
Quoting:
There are two types of listability - the one in built-in functions,
which pushes threading into the kernel and is fast, and the top-level
one (setting Listable for some functions by the user).
You can not achieve built-in listability by simply setting a
Listable attribute. The reason is that, while the end result is the
same - automatic threading over lists, the underlying mechanisms to
achieve it are different for built-ins vs user-defined. When a
built-in Listable function (particularly numerical) is passed lists
as arguments, it dispatches to the special branch which internally
runs the loop, and returns a list of results. So, for a built-in
function, Listable is rather a signal to pick the internal branch
which deals with lists automatically.
It seems that the absence of Listable does not prevent this "internal branch" from being used.
Listable,because trace it will give me{f[{1,2,3}],f/@{1,2,3},{f[1],f[2],f[3]}}. – luyuwuli Jan 12 '15 at 13:33fdoes not have theListableattribute, it only behaves (somewhat) like it does, and that was my point. – Mr.Wizard Jan 12 '15 at 13:34Listableattributes? – luyuwuli Jan 12 '15 at 13:37Listableattribute in these cases as mainly a courtesy to user code rather than a requirement for proper evaluation. After all, if a function behaves as ifListable, it's not really helpful if the attribute is missing, but you can of course always have a function with specialized definitions for different types of inputs regardless of that. Or, perhapsSqrtimplements an explicit loop over depth-1 lists, but not for higher-dimensional structures, so that it is part specialized, and part top-levelListable. This would be a reasonable optimization, IMO. – Oleksandr R. Jan 12 '15 at 13:41