# A puzzle with Compile

49 views

### Leonid Shifrin

Jun 6, 2009, 3:45:55 AM6/6/09
to
Hi everyone,

I stumbled upon a strange behavior for which I have no good explanation.

Consider the following perverse way to imitate Range:

In = Module[{i = 0}, Function[x, Table[x, {10}], HoldAll][++i]]

Out = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Now I attempt to speed it up with Compile:

In = Compile[{{n, _Integer}},
Module[{i = 0}, Function[x, Table[x, {n}], HoldAll][++i]]]

Out = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

Now, I am not a Compile expert, but to me it looks like it does not respect
the Hold
attribute I have given to the Function inside (this can also be confirmed by
using something
like (Print[i];++i) instead of (++i)) - printing occurs just once. Note by
the way that Table
is not a culprit either - it is HoldAll, and we may use explicit list in its
place and get the
same results.

In = Module[{i = 0}, Function[x, {x, x, x, x, x}, HoldAll][++i]]

Out = {1, 2, 3, 4, 5}

In = Compile[{{n, _Integer}},
Module[{i = 0}, Function[x, {x, x, x, x, x}, HoldAll][++i]]]

Out = {1, 1, 1, 1, 1}

where in this case the <n> dependence is at all spurious, and the whole
structure
is known at compile-time (unlike the previous one where the length of the
list was
a parameter to the function). It looks like Compile's treatment of this
kind of
code is not consistent with the general principles of Mathematica evaluation
/
attributes mechanics.

Note that it is not like Compile can not handle held arguments at all:

In = Compile[{{n, _Integer}}, Module[{i = 0}, Table[++i, {n}]]]

Out = {1, 2, 3, 4, 5}

in which case ++i is held by Table. We can go even further:

In = Module[{i = 0}, {++i, ++i, ++i}]

Out= {1, 2, 3}

In = Compile[{{n, _Integer}}, Module[{i = 0}, {++i, ++i, ++i}]]

Out = {3, 3, 3}

where again, in the last example, there is no real n-dependence.

My own guess is that this sort of problems occur when Hold attributes are
used to make
a function act like a macro in some sense - that is, when effectively some
code
expansion must happen (to get correct results) before the code is executed
(like the above examples). But the In example, which is treated
correctly, is
different only in Table being a built-in rather than user-defined, with
HoldAll also,
so I am still puzzled. Besides, for the very last example I have no
explanation whatsoever -
this one just looks like a plain bug.

Anyone having better ideas / explanation?

Regards,
Leonid