
Il linguaggio di scripting di JMP, JSL, è costituito da chiamate di funzione. Praticamente tutto ciò che puoi scrivere in JSL è una chiamata di funzione. Alcune cose non sembrano chiamate di funzione:
A = A + 3;
È abbastanza ovvio che il lato destro dell'istruzione di assegnazione è un'espressione. È meno ovvio che l'istruzione di assegnazione stessa sia un'espressione.
E = expr ( A = A + 3 );
expr è un wrapper che puoi usare attorno a un'espressione per impedire la valutazione dell'espressione. E è impostato sull'espressione, non sul risultato valutato dell'espressione. Per dare un'occhiata a E, usa la funzione testa. Head restituirà il nome della funzione alla radice dell'espressione:
show( head(E) );
Testa(E) = Assegna();
Ora vedi che c'è una funzione per fare le assegnazioni:
Assign( testing, 3+4 );
7
show(testing)
test = 7;
Le espressioni in JSL sono in realtà alberi. Ecco una foto dell'albero a=a+3, radice in alto, foglie in basso:

Simile alla funzione Testa, possiamo usare la funzione Arg per accedere ai figli della funzione Assegna:
show( arg(E,1) );
Arg(E, 1) = A; il lato sinistro
show( arg(E,2) );
Arg(E, 2) = LA + 3; il lato destro
e scavando più a fondo,
show(head(arg(E,2)))
Testa(Arg(E, 2)) = Aggiungi(); la testa del lato destro
show(arg(arg(E,2),1))
Arg(Arg(E, 2), 1) = A; il lato sinistro del più
show(arg(arg(E,2),2))
Arg(Arg(E, 2), 2) = 3; il lato destro del più
Nota come l'annidamento delle parentesi descrive l'albero. Questo albero ha solo divisioni binarie. C'è una funzione narg , che restituisce il numero di figli. Restituisce 0 per i nodi foglia.
narg(E)
2 la funzione di assegnazione ha due argomenti, il lato sinistro e il lato destro
di JMP per istruzione è una chiamata di funzione, che accetta quattro argomenti. Nota le virgole che separano gli argomenti, proprio come qualsiasi altra funzione.
halfCats = 1;
for( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
write( iCat, " ", halfCats , "\!n" )
);
1 0,5
2 0,25
3 0,125
4 0,0625
5 0,03125
6 0,015625
7 0.0078125
8 0.00390625
9 0.001953125
10 0.0009765625
Occorrono tre virgole per separare quattro argomenti. In questo per istruzione, il quarto argomento è costituito da due affermazioni, separate da un punto e virgola. Dai un'occhiata al quarto argomento per vedere se in realtà è anche una funzione:
Head(
Arg(
Expr(
For( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
Write( iCat, " ", halfCats, "\!n" );
)
),
4 /* the fourth arg */
)
);
Colla()
Colla è il nome della funzione che tiene insieme una sequenza di istruzioni.Colla Il primo argomento di è la prima affermazione, ecc.
Arg(
Arg(
Expr(
For( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
Write( iCat, " ", halfCats, "\!n" );
)
),
4 /* the fourth arg is two statements, glued together */
),
1 /* the first arg is the first of the two glued statements */
);
halfCats = halfCats / 2
Un elenco JSL è lo stesso tipo di espressione:
list={33,44,55};
show(head(list));
show(narg(list));
show(arg(list,3));
Testa(lista) = {}; list mostra parentesi graffe per la testa, invece di un nome come Assegnare
N Arg(lista) = 3;
Arg(lista, 3) = 55;
Se vuoi solo il contenuto dell'elenco, dovresti usare il normale pedice:
show(list[3]);
lista[3] = 55;
Ma a volte vuoi fare qualcosa come trasformare un elenco in argomenti per una funzione.
Nel Elefante post troverai un esempio di come trasformare una lista in un pattern (riga 5). Sto avendo difficoltà a trovare un altro esempio bello come quello, ma supponiamo che tu voglia controllare se l'elenco era in ordine alfabetico. L'operatore < di JMP può farlo in una singola chiamata di funzione:
LT = expr("a"<"b"<"c"<"d");
show(head(LT));
show(narg(LT));
Testa(LT) = Meno(); l'operatore minore di mostra un nome di funzione, Meno
N Arg(LT) = 4;
La funzione Less può richiedere molti argomenti, ma non è necessario digitarli. Sotto, NomeEspr sta recuperando l'espressione memorizzata in parole, dopo il SostituisciInto modificato il { elenco } essere Meno (). JMP visualizza quindi la funzione Less utilizzando < per renderla più leggibile.
words =
{"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India",
"Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo",
"Sierra", "Tango", "Uniform", "Victor", "Whiskey", "Xray", "Yankee", "Zulu"};
Substitute Into( words, Expr( {} ), Expr( Less() ) );
nameExpr(words);
"Alpha" < "Bravo" < "Charlie" < "Delta" < "Echo" < "Foxtrot" < "Golf" < "Hotel" <
"India" < "Giulietta" < "Kilo" < "Lima" < "Mike" < "Novembre" < "Oscar" < "Papà" <
"Quebec" < "Romeo" < "Sierra" < "Tango" < "Uniforme" < "Victor" < "Whiskey" < "Xray" < "Yankee" < "Zulù"
eval(words)
1 eval (parole) restituisce 1, indicando che il risultato di Less era vero.
Un altro esempio.
Aggiornamento del 28 febbraio 2017: ripara la formattazione per la nuova community
Craig, questo articolo mi è stato molto utile nella mia continua ricerca per capire come gestire le espressioni.
In realtà avevo una buona applicazione per il tuo trucco finale, in cui hai trasformato gli elementi in un elenco in argomenti della funzione Less(). Volevo generare una formula di colonna contenente la funzione Col Mean(), basata sull'input dell'utente da una finestra di dialogo. La funzione Col Means() accetta uno o più argomenti e non ho mai avuto un modo intelligente per sostituire un numero variabile di argomenti (spesso nomi di variabili) in una funzione. Ecco le linee chiave nel mio script:
arglist = {"altezza", "età", "sesso"}; // risulta da una finestra di dialogo
statformula = Sostituto ( arglist, Expr( {} ), Expr( Col Mean() ) ); // gli elementi in arglist diventano argomenti nella funzione Col Means()
newcol << Formula( Nome Espr( statformula ) );
Lo script vero e proprio è più complesso perché deve gestire nomi di colonne disordinati che richiedono Name(" "), ma hai un'idea. Grazie per avermi mostrato questo bel trucco.
Howard Rauch