Betreff: Ist es möglich, einen Verweis auf eine Funktion zu übergeben?Es gibt keine einfache Möglichkeit zur Referenzübergabe, aber Sie können Funktionen und Daten in Klassen oder Namespaces kapseln und den Objektzeiger oder Namespacenamen übergeben. Schauen Sie sich das Bild oben an Funktionale Programmierung mit JSL-Objekten um eine Vorstellung davon zu bekommen, wie das für den Unterricht funktionieren könnte.
Betreff: Ist es möglich, einen Verweis auf eine Funktion zu übergeben?Ich benutze so etwas oft und meiner Erfahrung nach verwende ich das NameExpr() Funktion geht ganz gut.Es kann schwierig sein, eine Funktion von einer anderen Funktion zurückzugeben, und @Craige_Hales Methode ist in der Regel die bessere Wahl.
Ich habe umfangreiche Kenntnisse in Qt und schätze deren Signale/Slots sehr. Ich habe in JSL etwas ganz Ähnliches erstellt und es ist notwendig, Funktionen per Referenz zu verschieben, und es ist nicht so praktisch, dies mit Namespace-/Klassen-Wrappern zu tun, also verwende ich etwas ganz Besonderes ähnlich wie dies.
someFunc = Function( {arg},
{},
Print( "Within One Function" );
Print( arg );
);
executor = Function( {fn, arg},
{},
Print( "Executing..." );
fn( arg );
);
executor( Name Expr( someFunc ), "this string" )Betreff: Ist es möglich, einen Verweis auf eine Funktion zu übergeben?Das sieht tatsächlich einfacher und leichter zu verstehen aus. Es gibt einen Kompromiss, der nur bei großen Funktionen, die häufig aufgerufen werden, einen Unterschied macht. NameExpr klont den Ausdrucksbaum für die Funktion und übergibt die Kopie, keine Referenz. Ich glaube nicht, dass es eine andere Möglichkeit gibt, festzustellen, dass es sich um eine Kopie oder eine Referenz handelt (wie es bei Arrays der Fall ist, die bei der Rückgabe nicht geändert werden), als die Zeit festzulegen:
loops=1e5; // ~10 seconds/100K loops
print = (loops==1e0);
someFunc = Function( {arg}, {},
If( print,
Print( "Within One Function" );
Print( arg );
);
Return( 0 );
// this creates a stiff penalty for nameexpr
// needing to clone this function. These
// statements are simple and never executed but still
// must be copied to the nameExpr result by allocating
// a bunch of memory objects.
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
);
/////////////////////////////////////
Write( "\!nUsing NameExpr" );
executor = Function( {fn, arg}, {},
If( print,
Print( "Executing for NameExpr..." )
);
fn( arg );
);
start = HP Time();
For( i = 1, i <= loops, i += 1,
executor( Name Expr( someFunc ), "this string" )
);
stop = HP Time();
Show( stop - start ); // ~7 seconds
/////////////////////////////////////
Write( "\!nUsing class" );
Define Class(
"PassByRef",
mFn = .;
_init_ = Method( {fn},
mFn = Name Expr( fn )
);
);
// grab the identical function into a reference object >>>>> requires JMP 17, a bug was fixed after 16.2
somefuncRef = New Object( PassByRef( Name Expr( someFunc ) ) );
<BR />/* for JMP < 17 use this work-around: <BR />somefuncRef = New Object( PassByRef( 0 ) );<BR />somefuncRef:mFn=Name Expr( someFunc );<BR />*/
/********** this also works and looks ... better?
somefuncRef = New Object( PassByRef( Function( {arg}, {},
If( print,
Print( "Within One Function" );
Print( arg );
);
Return( 0 );
// this creates a stiff penalty for nameexpr
// needing to clone this function. These
// statements are simple and never executed but still
// must be copied to the nameExpr result by allocating
// a bunch of memory objects.
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
);
));
*********/
executor = Function( {fnRef, arg}, {},
If( print,
Print( "Executing for class..." )
);
fnRef:mFn( arg );
);
start = HP Time();
For( i = 1, i <= loops, i += 1,
executor( somefuncRef, "this string" )
);
stop = HP Time();
Show( stop - start ); // ~3 seconds
Die ~2-fache Leistungssteigerung für eine große Funktion verschwindet, wenn 0;0;0; Dummy-Anweisungen werden entfernt; Für die kurzen Funktionen, die Sie möglicherweise auf Qt-ähnliche Weise verwenden, macht das keinen Unterschied.
Ist es möglich, einen Verweis auf eine Funktion zu übergeben?Wenn ich zum Beispiel dieses Skript ausführe:
someFunc = Function( {arg},
{},
Print( arg );
);
executor = Function( {fn, arg},
{},
fn( arg );
);
executor( someFunc, "this string" )Ich erhalte eine Fehlermeldung, die darauf hindeutet, dass ich someFunc aufrufe, wenn ich beabsichtige, einen Verweis darauf an den Executor zu übergeben.
Ich kann eine Referenz übergeben, indem ich die Funktion im Aufruf definiere, z
executor = Function( {fn, arg},
{},
Print(arg);
fn();
);
executor( Function({}, {}, Print("anonymous function"); ), "wut" );Ausgänge:
"wut"
"anonymous function"
Damit wird erreicht, was ich brauche, aber es wäre praktisch, Funktionen mithilfe ihrer Variablennamen übergeben zu können.
Erweiterte statistische ModellierungAutomatisierung und SkripterstellungVerbraucher- und MarktforschungQualitäts- und VerfahrenstechnikBetreff: Ist es möglich, einen Verweis auf eine Funktion zu übergeben?Wo finde ich weitere Dokumentation zum PassByRef Möglichkeit?
argh.
Betreff: Ist es möglich, einen Verweis auf eine Funktion zu übergeben?@hogi - Entschuldigung, ich habe den wichtigen Teil irgendwie mitten im Code vergraben! Für alle anderen:
Define Class(
"PassByRef",
mFn = .;
_init_ = Method( {fn},
mFn = Name Expr( fn )
);
);
somefuncRef = New Object( PassByRef( Name Expr( someFunc ) ) );
erstellt eine Klassendefinition mit dem Namen PassByRef und eine Instanz dieser Klasse mit dem Namen somefuncRef . Die Instanz ist ein Wrapper um mFn, der einen Klon von enthält someFunc . Dieser Klon wird jedoch immer wieder verwendet, ohne dass weitere Klone erstellt werden. Der Testamentsvollstrecker macht diesen Aufruf hier
executor = Function( {fnRef, arg}, {},
If( print,
Print( "Executing for class..." )
);
fnRef:mFn( arg );
);