Regarding the function - I don't know what's behind "Factorize()" but would assume that it will not include the value "1" in the list.
Correct, since 1 is not a prime.
If that than the exception you raise for an empty list is probably incorrect, as N is a prime then and Phi( p ) := p-1 iff p prime by definition.
No, if there are no elements in it (which b.t.w. should never happen,I'm just insanely paranoid about my math skills), N does not have prime factors.
If N is a prime there will be 1 element, namely N itself.
Regarding efficiency - hard to say if the above is more efficient than the function from rabbit_dance as nearly all time will be spend in "Factorize()". Depending on the size of N different factorization algorithms are the most efficient. Assuming you'd always select the best fitting one your code is optimal with respect to calculation of a single number. However the question was "calculate Phi for 1..N" and this can be speeded up significantly if one computes the factorization for the numbers 1..N in parallel.
Without testing it will be impossible to say (and rabbit_dance's code does not run properly).
My Factorize() function uses a lookputable for primes (at least for the first 10000 primes), but the algoritme could probably be more optimized.
E.g. it uses a series of div and mod, where a DivMod() would probably more efficient, but this is not available for UInt64 types.
Anyway, for me the fun is not in who writes the fastest, or most efficient, of better scale-able code, the fun is in understanding and figuring out the algorithm and in the programming itself.
Chances are I will never ever need this in my real live programs.
Thanks for your input/feedback.
Bart