programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)J'ai un problème où la solution que je souhaite est d'utiliser une fonction pour générer une fonction différente. Voici un exemple de jouet. Je m'attends à ce qu'il revienne [3,4,5]. cela ne fonctionne pas comme je l'espérais car apparemment l'argument passé (décalage) n'est pas disponible pour la fonction anonyme renvoyée. Je suppose qu'il existe un moyen de faire cela avec substitution, mais je n'ai pas pu le comprendre.
funWrapper = Function({array, fun},
fun(array);
);
funFunctional = Function({offset},
Function({x},
x + offset;
);
);
funWrapper([1,2,3], funFUnctional(2));Modélisation statistique avancéeConception d'expériencesIngénierie Qualité et ProcédésRe : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Désolé de double-poster ici, mais il existe en fait une meilleure façon de procéder, qui ne nécessite que la modification de la fonctionnalité :
funWrapper = Function({array, fun},
fun(array);
);
funFunctional = Function({offset},
Eval( Substitute(
Expr(
Function({x},
x + _offset_;
)
)
,
Expr( _offset_ ), offset
) )
);
funWrapper([1,2,3], funFUnctional(2));Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)@SDF1 , j'essaie de trouver la valeur du paramètre où la fonction est nulle, similaire à uniroot fonction dans R. Je ne connais pas de fonction JMP similaire. En tout cas, j'ai volé le code pour faire ça, donc c'était assez simple 
Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Veuillez noter que les classes JMP14 ne sont pas entièrement fonctionnelles et que vous risquez d'être brûlé si vous comptez trop sur elles ; cependant, dans JMP12+, vous pouvez créer des classes (y compris l'héritage, les constructeurs, les destructeurs, etc.) avec des espaces de noms et une méta-programmation.
Pour répondre à la question initiale de l'OP - vous pouvez atteindre votre objectif avec seulement des modifications minimes à votre script - notez simplement que la valeur de retour d'une fonction JSL est évaluée (avec l'instruction Eval()) avant d'être renvoyée.Ainsi, si votre dernière instruction est une expression non évaluée (telle qu'une Expr( Function( _definition_ ) ), alors elle renverra la fonction comme prévu.Seule une légère astuce dans la deuxième fonction est nécessaire pour pouvoir appeler la fonction (l'instruction "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));Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Salut @Mittman ,
On dirait que vous essayez de résoudre les racines d'une équation (fonction dans ce cas, pas fonction JSL()), est-ce correct ?
Il existe une fonction JSL intégrée appelée Minimize() à laquelle vous pouvez transmettre votre fonction avec des points de départ pour que la fonction Minimize() commence sa routine d'optimisation. Cela pourrait être un chemin plus facile à suivre que d'écrire votre propre fonction JSL() pour cela. Vous pouvez lire un article de blog à ce sujet ici .
J'espère que cela pourra aider!,
DS
Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Salut @SDF1 , Merci pour la réponse. Cependant, cela ne fonctionne pas pour mon cas d'utilisation réel. Je veux pouvoir passer une fonction arbitraire (monotone) comme argument à une fonction qui trouve le zéro. C'est assez simple si je définis explicitement chaque fonction, mais j'ai rencontré des problèmes lorsque je voulais écrire une fonction pour créer une instance d'une fonction à partir d'une classe paramétrée. J'ai grandi dans R, qui n'est pas vraiment OO, mais où les règles de portée autorisent un code comme celui que j'avais dans le message d'origine.
-EM
Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Salut @Mittman ,
Je ne sais pas si c'est exactement ce que vous voulez, mais cela permet de résoudre au moins l'exemple que vous donnez dans votre message d'origine.
Names Default to Here (1);
fWrap = Function({array, offset}, fFun(array offset));
fFun = Function({x, offset}, x + offset);
fWrap([3, 4, 5, 6], 5 );Cela renverra [8, 9, 10, 11].
C'est une question intéressante à examiner. Si vous pouvez expliquer pourquoi vous devriez procéder de cette façon, je suis assez curieux.
J'espère que cela t'aides!,
DS
Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)Merci d'avoir partagé ces vignettes perspicaces, Craige.
Voici des solutions utilisant les deux approches. Les classes me semblent plus intuitives (et "this" est certainement plus facile à taper que namespace(expr(ns<
Testé à la fois dans JMP 14 Pro et JMP 12 Pro. Les cours ne sont pas disponibles dans JMP 12 Pro.
funOffsetAdder = Function({offset},
ns = NewNamespace();
ns:offset = offset;
ns:theMethod = EvalExpr(
Function({x},
this = namespace(expr(ns<<GETNAME></GETNAME>Re : programmation de fonctionnalités (ou fonctions qui génèrent des fonctions)J'ai fait quelques expériences : Comment utiliser Définir une classe et Programmation fonctionnelle utilisant des objets JSL
Revenez si vous comprenez davantage le puzzle ; à ce stade, je n'utilise pas beaucoup les classes JSL, mais elles constituent peut-être le meilleur moyen de faire ce que vous voulez. Les espaces de noms peuvent être équivalents, sans certaines idées de sous-classement. L’un ou l’autre vous permettra de regrouper une fonction et des données ensemble, et de transmettre le package à une autre fonction par référence.