Ri: è possibile passare un riferimento a una funzione?Non esiste un modo semplice per passare per riferimento, ma è possibile incapsulare funzioni e dati in classi o spazi dei nomi e passare il puntatore all'oggetto o il nome dello spazio dei nomi. Dai un'occhiata all'immagine in alto Programmazione funzionale tramite oggetti JSL per avere un'idea di come potrebbe funzionare per le classi.
Ri: è possibile passare un riferimento a una funzione?Uso molto qualcosa di simile e, dalla mia esperienza, usando il NomeEspr() funzione funziona abbastanza bene.Può essere complicato quando si restituisce una funzione da un'altra funzione e @Craige_Hales metodo è di solito una scelta migliore.
Ho una vasta esperienza in Qt e apprezzo molto i loro segnali / slot: ho creato qualcosa di abbastanza simile in JSL ed è necessario spostare le funzioni in giro per riferimento e non è così pratico farlo con namespace / wrapper di classe, quindi uso qualcosa di molto simile a questo.
someFunc = Function( {arg},
{},
Print( "Within One Function" );
Print( arg );
);
executor = Function( {fn, arg},
{},
Print( "Executing..." );
fn( arg );
);
executor( Name Expr( someFunc ), "this string" )Ri: è possibile passare un riferimento a una funzione?Sembra più semplice e più facile da capire. C'è un compromesso che farà la differenza solo per le funzioni di grandi dimensioni che vengono chiamate molto. NameExpr sta clonando l'albero delle espressioni per la funzione e passando la copia, non un riferimento. Non penso che ci sia alcun modo per dire che si tratta di una copia rispetto a un riferimento (come puoi fare per gli array che non vengono modificati al ritorno) oltre a cronometrarlo:
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
L'aumento delle prestazioni di ~ 2x per una funzione di grandi dimensioni svanisce come 0;0;0; le istruzioni fittizie vengono rimosse; per le funzioni brevi che potresti usare in un modo simile a Qt non farà differenza.
È possibile passare un riferimento a una funzione?Ad esempio quando eseguo questo script:
someFunc = Function( {arg},
{},
Print( arg );
);
executor = Function( {fn, arg},
{},
fn( arg );
);
executor( someFunc, "this string" )Ottengo un errore, che sembra implicare che sto chiamando someFunc quando intendo passare un riferimento ad esso all'executor.
Sono in grado di passare un riferimento definendo la funzione nell'invocazione, ad es
executor = Function( {fn, arg},
{},
Print(arg);
fn();
);
executor( Function({}, {}, Print("anonymous function"); ), "wut" );Uscite:
"wut"
"anonymous function"
Il che realizza ciò di cui ho bisogno, ma sarebbe conveniente poter passare le funzioni usando i loro nomi di variabile.
Modellazione statistica avanzataAutomazione e scriptingConsumatori e ricerche di mercatoQualità e ingegneria di processoRi: È possibile passare un riferimento a una funzione?Dove posso trovare ulteriore documentazione su PassByRef opzione?
argh.
Ri: È possibile passare un riferimento a una funzione?@hogi - scusa, ho seppellito la parte importante nel mezzo di quel codice! Per chiunque altro,
Define Class(
"PassByRef",
mFn = .;
_init_ = Method( {fn},
mFn = Name Expr( fn )
);
);
somefuncRef = New Object( PassByRef( Name Expr( someFunc ) ) );
sta creando una definizione di classe denominata PassByRef e un'istanza di quella classe denominata qualchefunzioneRif . L'istanza è un wrapper attorno a mFn, che contiene un clone di alcuniFunz . Ma quel clone viene riutilizzato ancora e ancora, senza creare altri cloni. L'esecutore testamentario fa quella chiamata qui
executor = Function( {fnRef, arg}, {},
If( print,
Print( "Executing for class..." )
);
fnRef:mFn( arg );
);