funzionali di programmazione (o funzioni che generano funzioni)Ho un problema in cui la soluzione che voglio è utilizzare una funzione per generare una funzione diversa. Ecco un esempio di giocattolo. Mi aspetto che ritorni [3,4,5]. non funziona come speravo perché apparentemente l'argomento passato (offset) non è disponibile per la funzione anonima che viene restituita. La mia ipotesi è che ci sia un modo per farlo con la sostituzione, ma non sono riuscito a capirlo.
funWrapper = Function({array, fun},
fun(array);
);
funFunctional = Function({offset},
Function({x},
x + offset;
);
);
funWrapper([1,2,3], funFUnctional(2));ScriptingOggetto: programmazione funzionale (o funzioni che generano funzioni)Ho fatto alcuni esperimenti: Come usare Define Class e Programmazione funzionale utilizzando oggetti JSL
Postare indietro se si risolve di più del puzzle; a questo punto non sto usando molto le classi JSL, ma potrebbero essere il modo migliore per fare quello che vuoi. Gli spazi dei nomi possono essere equivalenti, senza alcune idee di sottoclasse. Entrambi ti consentiranno di impacchettare una funzione e dati insieme e di passare il pacchetto a un'altra funzione per riferimento.
Oggetto: programmazione funzionale (o funzioni che generano funzioni)Grazie per aver condiviso queste vignette penetranti, Craige.
Ecco le soluzioni che utilizzano entrambi gli approcci. Le classi mi sembrano più intuitive (e "this" è certamente più facile da digitare rispetto allo spazio dei nomi (expr (ns << get name))).
Testato sia in JMP 14 Pro che in JMP 12 Pro. Le classi non sono disponibili in JMP 12 Pro.
funOffsetAdder = Function({offset},
ns = NewNamespace();
ns:offset = offset;
ns:theMethod = EvalExpr(
Function({x},
this = namespace(expr(ns<<GETNAME></GETNAME>Oggetto: programmazione funzionale (o funzioni che generano funzioni)Ciao @ Mittman ,
Non sono sicuro che sia esattamente quello che vuoi, ma funziona per risolvere almeno l'esempio che fornisci nel tuo post originale.
Names Default to Here (1);
fWrap = Function({array, offset}, fFun(array offset));
fFun = Function({x, offset}, x + offset);
fWrap([3, 4, 5, 6], 5 );Questo restituirà [8, 9, 10, 11].
È una questione interessante da esaminare. Se puoi condividere il motivo per cui dovresti farlo in questo modo, sono piuttosto curioso.
Spero che sia di aiuto!,
DS
Oggetto: programmazione funzionale (o funzioni che generano funzioni)Ciao @DiedrichSchmidt , Grazie per la risposta. Tuttavia, questo non funziona per il mio caso d'uso reale. Voglio essere in grado di passare una funzione arbitraria (monotona) come argomento a una funzione che trova lo zero. Questo è abbastanza semplice se definisco esplicitamente ogni funzione, ma ho avuto problemi quando volevo scrivere una funzione per creare un'istanza di una funzione da una classe parametrizzata. Sono cresciuto in R, che non è proprio OO, ma dove le regole di scoping consentono un codice come quello che avevo nel post originale.
- EM
Oggetto: programmazione funzionale (o funzioni che generano funzioni)Ciao @ Mittman ,
Sembra che tu stia cercando di risolvere le radici di un'equazione (funzione in questo caso, non funzione JSL ()), è corretto?
C'è una funzione JSL incorporata chiamata Minimize () a cui puoi passare la funzione con i punti di partenza per la funzione Minimize () per iniziare la sua routine di ottimizzazione. Questo potrebbe essere un percorso più semplice da seguire che scrivere la tua funzione JSL () per quello. Puoi leggere un post sul blog a riguardo Qui .
Spero possa aiutare!,
DS
Re: funzioni di programmazione (o funzioni che generano funzioni)Tieni presente che le classi JMP14 non sono completamente funzionanti e potresti essere bruciato se fai troppo affidamento su di esse; tuttavia, in JMP12+ è possibile creare classi (inclusi ereditarietà, costruttori, distruttori, ecc.) con spazi dei nomi e un po' di metaprogrammazione.
Per rispondere alla domanda iniziale dell'OP - puoi raggiungere il tuo obiettivo con solo modifiche minime al tuo script - tieni presente che il valore restituito da una funzione JSL viene valutato (con l'istruzione Eval()) prima di essere restituito.Quindi, se la tua ultima istruzione è un'espressione non valutata (come un Expr( Function( _definition_ ) ), allora restituirà la funzione come previsto.È necessario solo un piccolo trucco nella seconda funzione per poter chiamare la funzione (l'istruzione "fun = fun").
funWrapper = Function({array, fun},
fun = fun;
fun(array);
);
funFunctional = Function({offset},
Substitute(
Expr(
Function({x},
x + _offset_;
)
)
,
Expr( _offset_ ), offset
)
);
funWrapper([1,2,3], funFUnctional(2));