Ambito JMP: ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLSe sbaglio, per favore correggimi, ma sembrerebbe che JMP abbia un ambito dinamico senza persistenza dell'ambito (ad eccezione degli pseudo-spazi dei nomi Qui , Finestra , Scatola ).Ciò contrasta con molti linguaggi di programmazione popolari che hanno ambito lessicale con persistenza completa dell'ambito utilizzando contatori di riferimento.
Ciò ha causato un sacco di confusione da parte mia fino a quando non ho acquisito l'intuizione necessaria per lavorare con lo strano sistema di ambito che ha JMP, e credo che sia un grande punto di confusione per molte persone.Non molti linguaggi di programmazione usano l'ambito dinamico (LISP è un'eccezione importante e JSL ha alcune somiglianze con LISP).
Incoraggerei il team di documentazione JSL a sottolineare questa distinzione e fornire alcune risorse/collegamenti su come comprendere meglio l'ambito dinamico poiché certamente non è il modo standard di eseguire la risoluzione dei nomi.
Ecco un esempio: l'ambito locale della funzione esterna viene cancellato immediatamente dopo l'istruzione return e la risoluzione dei nomi delle funzioni interne è dinamica (basata sullo stack di chiamate corrente):
Names Default to Here( 1 );
x = 7;
outer function = Function( {},
{x},
x = 4;
inner function = Function( {},
Print( x )
);
Return( Name Expr( inner function ) );
);
func = outer function;
func()
/*** OUTPUT ***
7Se fai qualcosa di funzionalmente equivalente in un linguaggio con ambito lessicale con persistenza dell'ambito (come Python), allora l'ambito di inclusione della funzione interna è persistente (è l'ambito locale per la funzione esterna) e la risoluzione del nome per la funzione interna la variabile x della funzione è il valore 4 dalla lettura lessicale del sistema.Poiché JMP non utilizza l'ambito lessicale, ma utilizza l'ambito dinamico, quando la funzione interna viene finalmente eseguita alla fine dello script, utilizza la risoluzione dei nomi dinamica di Local -> Here -> Global (e possibile colonna- nomi per la tabella corrente) e trova il valore 7.
Comprendere questo tipo di comportamento è fondamentale per creare programmi robusti in JSL e voglio solo farlo notare a chiunque stia imparando / lottando con JSL.
Fatemi sapere se avete pensieri/esempi poco intuitivi!
Automazione e scriptingAccesso ai datiRi: Ambito JMP: ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLQuesto è vero, e sicuramente mi ha fatto impazzire quando ho imparato la lingua.L'altra ruga è che JSL è a Linguaggio di riscrittura dei termini grazie ai suoi oggetti di espressione, il che significa che pur essendo LISP rispetto all'ambito, non è LISP rispetto a come gestisce le macro.
L'unico altro linguaggio di riscrittura dei termini di cui sono a conoscenza nell'uso popolare è Wolfram Language.Non sono abbastanza esperto in CS per dirlo con certezza, ma ho sentito alcune persone affermare che il paradigma di riscrittura dei termini è strettamente più potente delle macro di Lisp.D'altra parte, ho sentito alcuni affermare che Wolfram Language è semplicemente un'implementazione di espressioni m, dove Lisp ha deciso che le espressioni s erano abbastanza buone.
Indipendentemente da ciò, il sistema di espressione di JSL sarà estraneo a quasi tutti e l'ergonomia delle loro funzioni per lavorare con le espressioni non fa loro alcun favore.C'è una ragione per cui puoi trovare così tanti esempi in questo forum di persone che usano la manipolazione delle stringhe e Parse() invece delle funzionalità di riscrittura dei termini.
Ri: Ambito JMP: ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLIo stesso non sono una persona CS, ma questa roba sulla riscrittura dei termini è piuttosto interessante!Grazie per la citazione, ora starò sveglio tutta la notte in questa tana del coniglio...
Re: Ambito JMP - Ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLIL
func = outer function;
func();
mi ha lasciato perplesso.
Dopo l'esecuzione
func = outer function();
la definizione della funzione interna è memorizzata nella variabile func.
Ecco perché Mostra(funzione) restituisce
func = Function({},Print(x));
A questo punto, tutte le informazioni sulla funzione esterna e su quella interna sono perse.
Quindi funzione() eseguirà Print(x) e ... stamperà 7 .
modificare:
In realtà non c'è nulla di nuovo rispetto a quanto scritto nel post principale.
Solo la "vista 2D" di un programmatore JSL.
Re: Ambito JMP - Ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLJMP mantiene le variabili nella definizione della funzione così come sono, senza sostituirle automaticamente con il valore corrente.
Quindi, dopo
x = 4;
inner function = Function( {}, Print( x ));
inner function is defined as
Function( {}, Print( x ));
Per far sì che la funzione interna sostituisca la sua x con la x della funzione esterna , è necessaria una pre-valutazione come
Names Default to Here( 1 );
x = 7;
outer function = Function( {},
{x},
x = 4;
Eval(Eval Expr( inner function = Function( {},
x= Expr(x);
Print( x )
)));
Return( Name Expr(inner function));
);
func = outer function;
func() // prints 4
modifica: stessa vista 2D con altre parole.
Re: Ambito JMP - Ambito dinamico vs. lessicale e confusione generale nell'apprendimento di JSLHo dato una rapida occhiata oltre la recinzione:
def outer():
y=4
def inner():
print(y)
return inner
f = outer()
y = 7
f() # -> 4
Quindi Python restituisce 3. Perché è così che y viene definito nel contesto lessicale quando viene definito inner.
"Definito" o "restituito"?
Diamo un'altra occhiata:
def outer():
y=4
def inner():
print(y)
y=-100
return inner
f = outer()
y = 7
f()
-> -100