To my knowledge, one of the situations where the third argument of Compile is required is when your compiled code needs to make a MainEvaluate call. Often, the situation is the other way around: you have code and you try to compile it down completely, so that no MainEvaluate call is necessary. Honestly, most of the questions about Compile here deal to some extend with this issue.
What is, when it is out of question that some part of your code has to be run by the kernel and cannot be compiled under no circumstances? Then the task is to build this into your compiled code, so that it works and the compiler can determine the type of your external call. Let's assume a simple function which collects some prime numbers:
primes[n_] := Last[Last[Reap[Table[If[PrimeQ[i], Sow[i]], {i, n}]]]]
and now you want to have a compiled function which multiplies such a list with an integer giving you an integer list back. First, you can play around with this snipped
Compile[{{n, _Integer}}, Module[{a = 2},
a*Last[Last[Reap[Table[If[PrimeQ[i], Sow[i]], {i, n}]]]]
]
]
but this is not fun and Reap and Sow are bad for compiling anyway. The solution is the third argument to Compile:
fc = Compile[{{n, _Integer}}, Module[{a = 2},
a*primes[n]
], {{primes[_], _Integer, 1}}
]
because you can get a working and readable version of your function. Now assume that you have a compiled function where you need the result of NMinimize or some similar (uncompilable) function. This is your use-case.
As for your initial problem with y and AppendTo: The type of local variables can be coerced in other ways. For instance, if you want to say that y should be an integer list, then initialize it with Most[{1}] which gives you an empty list, but the compiler saw that you want an integer list :-)
cfu = Compile[{}, Module[{y = Most[{1}]}, AppendTo[y, 1]]];
cfu[]
(* {1} *)
ygoes out of scope beforeCompilecan use that argument. The way to solve this problem for local variables is to initialize them insideModuledeclaration to correct types, and then possibly redefine in the body ofModuleto the values you really need, like e.g.cfu = Compile[{}, Module[{y = Rest[{0}]}, AppendTo[y, 1]]]. – Leonid Shifrin Feb 28 '14 at 13:32Compilebut find the third argument to be a by mysterious. – Mark McClure Feb 28 '14 at 13:54Compiledoesn't use ordinary scoping rules (for example,Module,Block,Withare all treated exactly the same), so AIUI your explanation isn't correct. I think the real reason is that the third argument only applies to values that are obtained via calls out of the VM--it is a type hint, rather than a declaration. – Oleksandr R. Mar 01 '14 at 16:02Compilenot using the standard scoping rules, and you may be right, although I seem to remember that there were cases which actually led me to this conclusion. If / when I am able to dig out some examples, I will get back. – Leonid Shifrin Mar 01 '14 at 18:23Rest/Most), normally all the types are correctly inferred. If not, and where there is no suitable hack, I've usually found the the situation to be hopeless, sometimes even resulting in a kernel crash where types do not match what was inferred. – Oleksandr R. Mar 01 '14 at 18:57