2010-12-10 1 views
11

Con F # è a mia conoscenza che è possibile utilizzare la parola chiave inline per eseguire la specializzazione del tipo nel sito di chiamata. Cioè ::Come funziona F # inline?

val inline (+) : ^a -> ^b -> ^c 
     when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) 

Vincola che ^a o ^b deve avere un membro statico come op_Addition, o uno del costruito in primitive, che può essere utilizzato per riempire il vuoto.

Quindi se si ha un metodo che ha + e si passa in un int e un breve come parametri si svolge + su un'istruzione per utilizzare la primitiva incorporata per int e se si passa un float e un byte usa l'opcode dell'aggiunta primitiva float.

Come esattamente questo è fatto al momento della compilazione? Come si può avere un metodo nel CLR che cambia l'opcode o il metodo che utilizza in base al tipo?

Questo comportamento è possibile con Reflection.Emit? Capisco che l'inlining sia eseguito sul call-site, vuol dire che il codice non funziona con C#?

+0

Non so molto sull'interno, ma sembra il codice sorgente F # che definisce l'operatore '+' (C: \ Programmi (x86) \ FSharp-2.0.0.0 \ source \ fsharp \ FSharp .Core \ prim-types.fs riga 3527) attiva i tipi di argomento in fase di compilazione ed emette direttamente il codice IL. – Juliet

risposta

8

Come suggerito da inline, il codice è in linea nel sito di chiamata. In ogni sito di chiamata, si conosce il parametro di tipo concreto ^T, quindi viene inserito il codice specifico per quel tipo.

Questo è fatto dal compilatore F #, non è possibile farlo facilmente in un altro contesto (come C# o Ref.Emit).

La libreria F # ha alcune funzioni inline che possono ancora essere chiamate da altri linguaggi, il runtime per tali implementazioni è dispatch dinamico basato sul tipo di runtime, vedere ad es. il codice per AdditionDynamic in prim-types.fs nel codice della libreria F # Core per avere un'idea.

+0

Quindi stai dicendo che è fondamentalmente un elaborato trucco per compilatori? Se chiamo "FSharpFunc <,>" da C# otterrei il comportamento desiderato? –

+2

Qualsiasi istanza del tipo 'FSharpFunc' (o anche la maggior parte dei tipi) non è (e non può) essere' in linea'. 'inline' si applica a metodi e funzioni e solo una manciata di essi nella libreria F #. La maggior parte delle cose può essere chiamata bene da C#, ma alcune funzioni F # 'inline' che non supportano l'invocazione dinamica (come' sin') possono essere chiamate solo da F #, poiché il compilatore F # deve incorporare il codice nel sito di chiamata. – Brian