How to create Functions that have Compiled functions effectively

Here's one possibility. Write out the body as a separate block wrapped in Hold[], and then use either of Compile[] or Function[] as needed. This approach has been used in some of the add-on packages that accompany Mathematica:

(* for more complicated cases, you'd have something like Hold[Module[(* stuff *)]] *)
SATBody := Hold[{a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]),
                 a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]}]

SATCompiled = Function[body, 
                       Compile[{{a, _Real}, {i, _Real}, {W, _Real}, {v, _Real}}, body, 
                               CompilationOptions -> {"InlineCompiledFunctions" -> True},
                               CompilationTarget -> "C"], {HoldAll}] @@ SATBody;

SATUncompiled = Function[body, Function @@ Hold[{a, i, W, v}, body], {HoldAll}] @@ SATBody;

SAT[a_, i_, W_, v_] := If[Apply[And, NumericQ /@ {a, i, W, v}], (* or some other test *)
                          SATCompiled[a, i, W, v], 
                          SATUncompiled[a, i, W, v]]

I believe that what you are doing is fine and that the Temporary attributes may be ignored. Symbols created by Module bear this by default but it should not affect the definitions you create.

Using Block in place of Module will clean up the definitions somewhat, but understand what it does before applying it blindly.

Block[{code, a, v, i, W}, 
  code = {a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]), 
    a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]};

  SATFast = 
   Compile[{{a, _Real}, {i, _Real}, {W, _Real}, {v, _Real}}, #, 
      CompilationOptions -> {"InlineCompiledFunctions" -> True}] &[code];

  (SAT[a_?NumericQ, i_?NumericQ, W_?NumericQ, v_?NumericQ] := #[a, i, W, v]) &[
   SATFast];

  SAT[a_, i_, W_, v_] = code;
];


FullDefinition[SAT]
SAT[a_?NumericQ, i_?NumericQ, W_?NumericQ, v_?NumericQ] := 
 CompiledFunction[Argument count : 4 Argument types : {_Real, _Real, _Real, _Real}][
  a, i, W, v]

SAT[a_, i_, W_, v_] = {a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]), 
  a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]}     

Attributes[Compile`$4] = {Temporary}

Attributes[Compile`$2] = {Temporary}

Attributes[Compile`$5] = {Temporary}

Attributes[Compile`$1] = {Temporary}

Attributes[Compile`$6] = {Temporary}

Possibly of interest:

  • How to make a function like Set, but with a Block construct for the pattern names
  • Expressions containing globally undefined symbols inside a function where they are defined