2014-10-19 21 views
10

La domanda riguarda "best practice" in Julia. Ho letto this e this. Ho una funzioneArgomenti con nome senza valori predefiniti naturali in Julia

function discount_rate(n, fv, pmt, pv; pmt_type = 0) 
... 
end 

Il problema adesso è che devo chiamare il metodo in questo modo

discount_rate(10, 10, 10, -10) 

Non è chiaro che cosa significano questi argomenti - anche io dimentico. Quello che mi piacerebbe fare è scrivere

discount_rate(n = 10, fv = 10, pmt = 10, pv = -10) 

Più chiaro: più facile da leggere e capire. Ma non posso definire il mio metodo rendendo questi argomenti argomenti keywords o argomenti optional perché non hanno valori predefiniti naturali. Dal punto di vista del design, c'è un modo consigliato intorno a questo?

risposta

6

può fare come segue:

function discount_rate(;n=nothing,fv=nothing,pmt=nothing,pv=nothing,pmt_type=0) 
    if n == nothing || fv == nothing || pmt == nothing || pv == nothing 
     error("Must provide all arguments") 
    end 
    discount_rate(n,fv,pmt,pv,pmt_type=pmt_type) 
end 

function discount_rate(n, fv, pmt, pv; pmt_type = 0) 
    #... 
end 
+1

Grazie, Iain. Inoltre, hai trovato i tuoi video tutorial su Julia su Youtube molto utili. – vathymut

0

Come un follow-up, ha ottenuto un po 'noioso per avere a (ri) scrivere le parole chiave per soli controparti per le funzioni che ho già avuto. Ispirato dalla risposta di Iain sopra, ho scritto una macro che fa essenzialmente la stessa cosa ...

macro make_kwargs_only(func, args...) 
quote 
    function $(esc(func))(; args...) 
    func_args = [ arg[2] for arg in args ] 
    return $(esc(func))(func_args...) 
    end 
end 
end 

E così, ad esempio

f(a, b) = a/b 
@show f(1, 2) 
f(1,2) => 0.5 

Creare le sue parole chiave di sola controparte dà

@make_kwargs_only f a b 
@show f(a = 1, b = 2) 
f(a=1,b=2) => 0.5 

Nota tuttavia questo non è il caso generale. Qui l'ordine dell'argomento è cruciale. Idealmente avrei preferito che la macro funzionasse allo stesso modo sia per f(a = 1, b = 2) sia per f(b = 2, a = 1). Questo non è il caso.

@show f(b = 2, a = 1) 
f(b=2,a=1) => 2.0 

Quindi per ora, come un hack, io uso methods(f) se non riesco a ricordare l'ordine degli argomenti. Qualsiasi suggerimento su come riscrivere la macro per gestire entrambi i casi è il benvenuto ... forse un modo per ordinare func_args all'interno della definizione della funzione della macro basata sulla firma della funzione di func?

Problemi correlati