13 settembre, 2019

Visibilità (scope) lessicale e dinamica - 2


Continuo dal post precedente, e --forse-- altri seguiranno sull'argomento.

Una correzione al suddetto post: la pic che ho ottenuto da Ming-Ho non era psceudocodice ma codice vero in R, linguaggio che non ho mai frequentato (solo una volta ci sono passato vicino ma è una storia personale (e dimenticata)).

Intanto è arrivata la continuazione promessa da Ming-Ho, ben 2 post: New blog post by @mhyee Scoping in R.

Ming-Ho entra nel dettaglio del codice proposto e ci illustra come in R lo scope sia --come dire-- non tanto semplice: "All of this might make you a little uncomfortable, and uncertain about R’s scoping rules". Chiaro, esaustivo ma non quello che m'interessa.
E ci rimanda alla continuazione (terzo post, il secondo della giornata) dove "I’d like to discuss a paper by the creators of R, where they motivate the need for lexical scoping in a statistical programming language. This is a “bonus” blog post, because I’m going to dive into some of the hairier R features to show how four different kinds of scoping can be simulated in R". Esaustivo, @mhyee l'ho followato su Twitter, rockz! 💥

Io invece mi sono dedicato a linguaggi di script che uso (o ho usato in passato) dinamici. Espongo quanto trovato, confessando che non ne ero pienamente cosciente finora.

bc
bc lo uso da sempre, anche se ultimamente molto meno.

#!/usr/bin/bc

x = 1
define f(a) { return x + a }
define g() {
    x = 2
    return f(0)
}
print(g())
print "\n"
quit


$ bc dl.bc
2
$


Come si vede è dinamico, le variabili sono globali ma c'è l'opzione auto che le rende locali. Il risultato però non cambia resta dinamico, ossia nel caso in questione f() usa il valore corrente di x:

#!/usr/bin/bc

x = 1
define f(a) { return x + a }
define g() {
    auto x /* <- x locale */
    x = 2
    return f(0)
}
print g(), "\n"
print "(x = ", x, ")\n"
quit


$ bc dla.bc
2
(x = 1)
$


Calc
Calc - C-style arbitrary precision calculator è un tool cui sono affezionato anche se --ammetto-- ultimamente frequento di meno, mi sono costruito un piccolo sostituto in Python.

#!/usr/bin/calc

x = 1
define f(a) {
    return (x + a)
}
define g() {
    /* local x; */
    x = 2;
    return f(0)
}
print g(), "\n( x = ", x, ")"


$ calc -f ld.cal
2
( x =  2 )
$


Scommnentando l'istruzione commentata x diventa locale e lo scope diventa lessicale:

$ calc -f ld.cal
1
( x =  1 )
$


newLISP
Altro linguaggio di scripting che sto trascurando. Pare non solo io e nel mio caso c'è anche uno cui posso dare la colpa Racket. newLISP ha dei punti di forza, è piccolo, veloce, potente, ... Ma ci sono tanti Lisp (e successori) e --secondo me-- Racket vince anche per il supporto. Ma intanto ecco lo script:

#!//usr/bin/newlisp

(set 'x 1)
(define (f a) (+ x a))
(define (g)
  (set 'x 2)
  (f 0))
(println (g))
(println "x = " x)
(exit)


$ newlisp ld.nl
2
x = 2
$


OK, dinamico, come da manuale, ma è possibile renderlo lessicale (non l'ho fatto ma è immediato).

OK, resto dell'idea che il lexical scope sia migliore anche se per script molto piccoli l'importanza è relativa. Ma devo leggermi quanto segnalato da Ming-Ho. E, inoltre, non so se confessare un pensiero che mi è venuto fin da subito, una cosa che però rivelerebbe quanto sono vecchio. Ma questo nella continuazione. Probabilmente. Forse 🙂
🔴

Nessun commento:

Posta un commento