Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Ich habe ein Problem, bei dem die gewünschte Lösung darin besteht, eine Funktion zu verwenden, um eine andere Funktion zu generieren. Hier ist ein Spielzeugbeispiel. Ich erwarte, dass es zurückkommt [3,4,5]. es funktioniert nicht wie ich gehofft habe, weil anscheinend das übergebene Argument (Offset) für die zurückgegebene anonyme Funktion nicht verfügbar ist. Ich vermute, dass es einen Weg gibt, dies mit Substitution zu tun, aber ich konnte es nicht herausfinden.
funWrapper = Function({array, fun},
fun(array);
);
funFunctional = Function({offset},
Function({x},
x + offset;
);
);
funWrapper([1,2,3], funFUnctional(2));SkriptingBetreff: Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Ich habe einige Experimente gemacht: Verwendung von Define Class und Funktionale Programmierung mit JSL-Objekten
Poste zurück, wenn du mehr über das Rätsel herausfindest. Derzeit verwende ich die JSL-Klassen nicht häufig, aber sie sind möglicherweise der beste Weg, um das zu tun, was Sie wollen. Namespaces können ohne einige der Unterklassifizierungsideen gleichwertig sein. In beiden Fällen können Sie eine Funktion und Daten zusammen verpacken und das Paket als Referenz an eine andere Funktion übergeben.
Betreff: Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Vielen Dank für das Teilen dieser aufschlussreichen Vignetten, Craige.
Hier sind Lösungen, die beide Ansätze verwenden. Klassen fühlen sich für mich intuitiver an (und "dies" ist sicherlich einfacher zu tippen als der Namespace (expr (ns << get name))).
Getestet sowohl in JMP 14 Pro als auch in JMP 12 Pro. Klassen sind in JMP 12 Pro nicht verfügbar.
funOffsetAdder = Function({offset},
ns = NewNamespace();
ns:offset = offset;
ns:theMethod = EvalExpr(
Function({x},
this = namespace(expr(ns<<GETNAME></GETNAME>Betreff: Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Hallo @Mittman ,
Ich bin mir nicht sicher, ob dies genau das ist, was Sie wollen, aber es funktioniert, um zumindest das Beispiel zu lösen, das Sie in Ihrem ursprünglichen Beitrag angegeben haben.
Names Default to Here (1);
fWrap = Function({array, offset}, fFun(array offset));
fFun = Function({x, offset}, x + offset);
fWrap([3, 4, 5, 6], 5 );Dies wird [8, 9, 10, 11] zurückgeben.
Es ist ein interessantes Thema. Wenn Sie mitteilen können, warum Sie dies auf diese Weise tun müssten, bin ich ziemlich neugierig.
Hoffe das hilft!,
DS
Betreff: Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Hallo @DiedrichSchmidt , danke für die Antwort. Dies funktioniert jedoch nicht für meinen tatsächlichen Anwendungsfall. Ich möchte in der Lage sein, eine beliebige (monotone) Funktion als Argument an eine Funktion zu übergeben, die die Null findet. Dies ist einfach genug, wenn ich jede Funktion explizit definiere, aber ich hatte Probleme, als ich eine Funktion zum Erstellen einer Instanz einer Funktion aus einer parametrisierten Klasse schreiben wollte. Ich bin in R aufgewachsen, was nicht wirklich OO ist, aber wo die Scoping-Regeln Code zulassen, wie ich ihn im ursprünglichen Beitrag hatte.
- EM
Betreff: Programmieren von Funktionen (oder Funktionen, die Funktionen generieren)Hallo @Mittman ,
Es hört sich so an, als würden Sie versuchen, nach den Wurzeln einer Gleichung zu suchen (Funktion in diesem Fall, nicht JSL-Funktion ()). Ist das richtig?
Es gibt eine integrierte JSL-Funktion namens Minimize (), an die Sie Ihre Funktion mit Startpunkten übergeben können, damit die Minimize () -Funktion ihre Optimierungsroutine startet. Dies ist möglicherweise ein einfacherer Weg als das Schreiben einer eigenen JSL-Funktion (). Sie können einen Blog-Beitrag darüber lesen Hier .
Hoffentlich hilft das!,
DS
Betreff: Programmierfunktionen (oder Funktionen, die Funktionen generieren)Bitte beachten Sie, dass JMP14-Klassen nicht voll funktionsfähig sind und Sie möglicherweise verbrannt werden, wenn Sie sich zu sehr auf sie verlassen; in JMP12+ können Sie jedoch Klassen (einschließlich Vererbung, Konstruktoren, Destruktoren usw.) mit Namensräumen und etwas Metaprogrammierung erstellen.
Um die anfängliche Frage des OP zu beantworten – Sie können Ihr Ziel mit nur minimalen Änderungen an Ihrem Skript erreichen – beachten Sie einfach, dass der Rückgabewert einer JSL-Funktion (mit der Eval()-Anweisung) ausgewertet wird, bevor er zurückgegeben wird.Wenn Ihre letzte Anweisung also ein nicht ausgewerteter Ausdruck ist (z. B. ein Ausdr( Function( _definition_ ) ), dann wird die Funktion wie beabsichtigt zurückgegeben.In der zweiten Funktion ist nur ein kleiner Trick nötig, um die Funktion aufrufen zu können (die "fun = fun"-Anweisung).
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));