2010-11-21 28 views
9

Esistono lingue in cui l'ambito è definito in modo tale che non si estenda alle funzioni incluse? In altre parole, c'è un linguaggio in cui un codice come il seguente (sintassi Python-like):Esistono linguaggi di programmazione senza variabili globali?

>>> x = 3 
>>> def fact(n): 
...  print x 
...  return reduce(lambda u, v: u*v, xrange(1, n+1), 1) 
...  

darebbe un errore perché x non è definito all'interno della funzione fact?

In generale, ci sono lingue in cui l'ambito della funzione di qualsiasi non include le funzioni definite all'interno di esso?

Modifica: Grazie per i commenti informativi. La ragione per cui ho pensato di questo è che la situazione di una funzione interna avendo accesso a tutti l'ambiente fornito dalla sue funzioni contenenti suona sospettosamente vicino a me alla situazione descritta da Joe Armstrong nel suo argument against OOP:

Perché il problema con lingue orientate agli oggetti è che hanno ottenuto tutto questo ambiente implicito che portano con loro. Tu volevi una banana, ma quello che hai ottenuto era un gorilla con in mano la banana e l'intera giungla .

anche rilevante è che sento che la lingua Newspeak non ha alcuna namespace globale, anche se non ho idea di come funziona.

Posso immaginare che il problema, sollevato nel commento di Brian di seguito, delle funzioni incorporate (funzioni importate da __builtins__ in Pythonspeak o Sistema in molte altre lingue) sia introdotto artificialmente dall'interprete/compilatore in ogni funzione. Dopo tutto sono quasi sempre trattati in modo speciale nella lingua in primo luogo. Un'altra opzione è quella di averli come metodi di un oggetto passato come parametro alla funzione o importati come modulo dall'interno.

+1

Cosa comporterebbe? – Blindy

+4

Si noti che anche 'print',' reduce' e 'xrange' sembrano identificatori risolti da un ambito esterno. Il che dimostra perché questo è raramente utile. – Brian

risposta

8

Proverò a delineare approssimativamente come funziona in Newspeak.

Qualsiasi codice scritto deve essere in un modulo . Il modulo è un tipo di classe, poiché nelle classi di Newspeak può contenere altre classi, un modulo è essenzialmente una classe di livello superiore, una che non è contenuta in un'altra classe. La particolarità di Newspeak è che non è possibile fare riferimento a qualcosa all'esterno del modulo.

Quindi come si stampa su console in Newspeak? La stampa appartiene alla classe Console (a.k.a Smalltalk's Transcript) che fa parte del modulo Piattaforma.Per essere in grado di stampare su console, il modulo utilizza un parametro di costruzione Platform, ottiene la console dalla piattaforma, memorizza la console in uno slot e quindi la usa per stampare.

Fondamentalmente è come l'iniezione di dipendenza applicata a livello di lingua. Il linguaggio IDE e runtime ti aiutano a confezionare e avviare il tuo programma, ma se stai cercando ulteriori dettagli, vai su Gilad Bracha's blog, vedi this post per esempio, oppure consulta Newspeak Modules paper.

P.S. Newspeak non è né impraticabile né inutilizzabile, per la cronaca - è stato utilizzato nell'ambiente industriale, e ora ha una piccola (ma crescente) comunità open-source attorno ad esso. Newspeak è molto nuovo e in continua evoluzione, certo, ma per esperienza personale - è abbastanza facile e divertente scrivere programmi in.

+0

Non manca lo stato globale: la classe Console è uno stato globale, è solo gestita dal compilatore, non dall'utente. – Puppy

+0

Non proprio. La classe della console fa parte del modulo della piattaforma, non è possibile ottenerla senza prima ottenere un'istanza della piattaforma. La classe stessa è una proprietà del modulo, queste serie di post di Vassili Bykov danno una spiegazione abbastanza buona: http://blog.3plus4.org/2008/12/04/a-taste-of-nested-classes-part -1/ – Yardena

+0

Penso che l'argomento si riduce alla definizione di "non esiste in una lingua". IMHO se il compilatore e il runtime di un linguaggio di programmazione non espongono un determinato concetto al programmatore, allora "il concetto non esiste in una lingua", ad es. Java è un linguaggio senza allocazioni di memoria e goto, anche se ovviamente accadono sotto il cofano. – Yardena

-5

Realisticamente, una cosa del genere non potrebbe mai esistere. Considera - quando si stampa sulla console, da dove proviene l'handle della console? Quando fai riferimento a una funzione, da dove viene questa funzione? Di sicuro non esiste fisicamente nella pila della funzione da cui l'hai chiamata. Esatto, è globale. La realtà è che senza globali, non si potrebbe mai fare riferimento a qualcosa che non era direttamente nello stack o nell'heap - il che significa che nessuna istruzione della macchina, grazie a DEP. E per l'heap, da dove otterresti un mucchio? Non è possibile chiamare una funzione del sistema operativo per allocare una nuova memoria effettiva, che è globale.

In teoria, è possibile creare un tale linguaggio o programma, ma la realtà è che sarebbe più simile a Brainfuck di qualsiasi altra cosa effettivamente utilizzabile.

+3

Come ho detto nella domanda, Newspeak afferma di fare esattamente questo (lavoro senza uno spazio dei nomi globale). –

+0

@Muhammad: Ho letto l'articolo di Wikipedia, e non mi sembra molto non globale. Sembra anche orribilmente poco pratico e inutilizzabile. – Puppy

+4

@DeadMG: impraticabile e inutilizzabile è negli occhi di chi guarda. È un derivato di Smalltalk che è nuovo e genera un certo interesse. Indipendentemente da ciò, il concetto di solito dipende dal passaggio del messaggio, quindi vi darò un altro esempio: assumete un programma concorrente di Erlang che consiste in un numero di processi paralleli che comunicano messaggi. Tra diversi processori. Puoi dirmi qual è l'ambiente globale/condiviso? Prendere qualsiasi sistema di messaggistica condiviso-niente per quella materia. –

0

Credo che si possa creare un linguaggio di programmazione in cui l'ambito globale viene sostituito, ad esempio, da un array associativo contenente funzioni e oggetti, che sarebbero poi passati come ambiente di lavoro a ogni funzione chiamata.

Si consideri il seguente esempio. Quando in un programma Python regolare si potrebbe scrivere qualcosa di simile:

import foo 

def square(x): 
    return x*x 

print(square(int(raw_input("give a number: ")))) 

in un programma senza global si preferisce scrivere qualcosa del genere:

def main(environment): 
    environment['import']('foo') 
    environment['square'] = lambda x: x*x 
    environment['print'](environment['square'](int(environment['raw_input']("give a number:")))) 

e questo codice dovrebbe essere eseguito all'interno di un contesto qualcosa di simile:

def import_foo(modulename): 
    # dummy example 
    if modulename == 'foo': 
     import foo 

environment = { 
    'import': import_foo, 
    'print': print, 
    'raw_input': raw_input 
} 

main(environment) 

In un programma con questo tipo di approccio e non globali, le funzioni all'interno del programma potrebbe essere quasi del tutto isolato da tutto ex cosa possono accedere attraverso gli argomenti che ottengono. È quindi possibile creare anche ambienti alternativi per le funzioni e quindi eseguirli in "jail". Le librerie e le funzioni sarebbero come componenti elettronici in un circuito, dove è necessario, ma sono anche in grado di collegare i pezzi a qualsiasi cosa si desideri. Un linguaggio di programmazione progettato per questo schema potrebbe forse avere un po 'di zucchero sintattico per comodità per passare automaticamente un ambiente "predefinito" implicito alle chiamate di funzione, ma si potrebbe sempre costringerli esplicitamente a utilizzare qualsiasi ambiente alternativo desiderato.

Ad esempio, in un linguaggio globale senza less, se si dispone di una libreria progettata per accedere ai dati nel file system o nella rete del sistema operativo, è possibile fornire un ambiente alternativo e monitorare l'I/O o creare la libreria utilizzare il proprio file system virtuale o una connessione VPN al posto del normale file system e rete.

Problemi correlati