Quirk sul passaggio di variabili in newLISP

Uno dei miei linguaggi preferiti è il Lisp.
Nel Lisp ci sono millemila dialetti; io sono tutto per newLISP.
Però a volte si comporta in modo estremamente originale. Giudicate voi.

(define (my-func passglo , passloc)
    (println "\t\t\tin my-func I " passglo " " passloc " " glovar)
    (set 'passglo 10
         'passloc 20
         'glovar  30)
    (println "\t\t\tin my-func F " passglo " " passloc " " glovar)
)

(set 'passglo 1
     'passloc 2
     'glovar  3)
(println "in main I " passglo " " passloc " " glovar)
(my-func 5 6 7)
(println "in main F " passglo " " passloc " " glovar)
(exit)

Chiaro vero? C’è la funzione my-func che riceve fino a due variabili, passglo (globale) e passloc (locale, perché dichiarata dopo la virgola).

la funzione scrive i valori delle due variabili e della variabile globale glovar, poi ne modifica i valori e ne riscrive i valori.

Questa funzione viene chiamata nel main dopo che alle variabili sono stati assegnati valori iniziali e i loro valori visualizzati.
Dopo il ritorno dalla chiamata si rivisualizzano i valori.

Cosa pensate che succeda?
Questo:

Mysteriuoso vero?

La prima variabile viene passata correttamente, la seconda no; di questo dopo.
I valori sono poi visualizzati correttamente dopo la loro modifica all’interno della funzione e al ritorno al main i primi due sono ripristinati mentre il terzo (che non è stato coinvolto nel passaggio alla funzione) presenta il valore dato dalla modifica all’interno della funzione.
Ecco quest’ultimo caso è in accordo con la vita dinamica delle variabili ma gli altri?

Propongo una modifica al codice, ecco:

(define (my-func passx , passloc)
    (println "\t\t\tin my-func I " passx " " passloc " " glovar)
    (set 'passx 10
         'passloc 20
         'glovar  30
         'newglo  42)
    (println "\t\t\tin my-func F " passx " " passloc " " glovar)
)

(set 'passglo 1
     'passloc 2
     'glovar  3)
(println "in main I " passglo " " passloc " " glovar " " passx)
(my-func 5)
(println "in main F " passglo " " passloc " " glovar " " passx " " newglo)
(exit)

La funzione per come viene definita prevede al massimo una variabile, adesso chiamata passx. Tutto bene, OK, ho capito: le variabili passate nella definizione della funzione sono comunque locali alla funzione.
E, sempre per la vita dinamica delle variabili, newglo definita all’interno della funzione è comunque globale.

Ah! c’era un quirk nel passaggio dei dati nella prima versione. Uh! vuoi vedere che la virgola è un simbolo valido?

(define (my-func passglo , passloc)
    (println "* in my-func " passglo " " , " "passloc)
)

(set 'passglo 1
     'passloc 2)
(my-func 5 6 7)
(exit)

Esatto :-D Roba da mat? ;-)

About these ads
Post a comment or leave a trackback: Trackback URL.

Commenti

  • glipari  On 29 marzo 2012 at 00:01

    cioè, la virgola è un nome di parametro? acc, aspetta, ma viene utilizzato *anche* come simbolo riservato, oppure no?
    e poi, mi sembra di capire che tutti i parametri sono passati per valore, e mai per riferimento (ovvero si fanno le copie e non si modificano i valori originari).
    Ma c’è un modo per passarli per riferimento? (oppure, come dici tu “globali”?) (o come in pascal, con var: ?)

    • juhan  On 29 marzo 2012 at 07:53

      la virgola ha la funzione di definire quali sono i simboli (cioè le variabili) locali alla funzione. Ma può essere anche un nome di variabile (simbolo).
      Siccome a una funzione puoi passare il numero che vuoi di variabili, meno o più di quelle previste capita di assegnare un valore anche alla virgola.
      Tutto viene passato per valore e il termine globale è quello che si usa.
      Poi una volta che ti rendi conto delle regole che ci sono da quelle parti è OK, sta ad abituarsi e non pensare che valgano quelle usuali (del C, tanto per fare un esempio).
      Non so se la cosa interessa perché ci sarebbero altri aneddoti, recenti. Poi il capo ci guarda storti e ritorna a parlare di Java (che è tutto dire).

  • newlisper  On 29 marzo 2012 at 21:16

    Not mysterious really. The behaviour of the comma is well-documented in both the reference manual and the introduction:

    “Commas in parameter lists

    Some of the example programs contain functions that use a comma to separate the parameters into two groups. This is not a special syntax of newLISP, but rather a visual trick. The comma is a symbol just like any other symbol. The parameters after the comma are not required when calling the function; they simply declare local variables in a convenient way. This is possible in newLISP because parameter variables in lambda expressions are local and arguments are optional:”

    Some people use this trick, but many don’t.

    • glipari  On 29 marzo 2012 at 22:45

      Interesting. My surprise comes from my familiarity with other languages in which the comma isn’t any ordinary symbol, and from my little knowledge of newLisp, which I plan to improve in the next future. Thanks for your comment!

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 74 follower

%d blogger cliccano Mi Piace per questo: