Python vs. Ruby per la metaprogrammazione [chiuso]


90

Attualmente sono principalmente un programmatore D e sto cercando di aggiungere un altro linguaggio alla mia cassetta degli attrezzi, preferibilmente uno che supporti gli hack di metaprogrammazione che semplicemente non possono essere eseguiti in un linguaggio compilato staticamente come D.

Ho letto un po 'di Lisp e mi piacerebbe trovare un linguaggio che consenta alcune delle cose interessanti che fa Lisp, ma senza la strana sintassi, ecc. Di Lisp. Non voglio iniziare una guerra di fiamma linguistica e sono sicuro che sia Ruby che Python hanno i loro compromessi, quindi elencherò ciò che è importante per me personalmente. Per favore dimmi se Ruby, Python o qualche altro linguaggio sarebbe meglio per me.

Importante:

  1. Buona metaprogrammazione. Capacità di creare classi, metodi, funzioni, ecc. In fase di esecuzione. Preferibilmente, distinzione minima tra codice e dati, stile Lisp.
  2. Sintassi piacevole, pulita, sana e semantica coerente e intuitiva. Fondamentalmente un linguaggio moderno e ben congegnato, divertente da usare.
  3. Paradigmi multipli. Nessun paradigma è giusto per ogni progetto, o anche per ogni piccolo sottoproblema all'interno di un progetto.
  4. Un linguaggio interessante che effettivamente influenza il modo in cui si pensa alla programmazione.

Abbastanza importante:

  1. Prestazione. Sarebbe bello se le prestazioni fossero decenti, ma quando le prestazioni sono una vera priorità, userò invece D.
  2. Ben documentato.

Non importante:

  1. Dimensioni della comunità, disponibilità di biblioteche, ecc. Nessuna di queste è caratteristica della lingua stessa e tutte possono cambiare molto rapidamente.
  2. Disponibilità di lavoro. Non sono un programmatore professionista a tempo pieno. Sono uno studente laureato e la programmazione è tangenzialmente rilevante per la mia ricerca.
  3. Qualsiasi funzionalità progettata principalmente con progetti di grandi dimensioni su cui hanno lavorato in mente un milione di scimmie del codice.

1
+1 Per una domanda generalmente ben fatta.
Trittico

Purtroppo le risposte più votate dicono tutte "dipende" e le risposte più basse sono fondamentalmente una guerra tra Python e Ruby.
Dan Burton

Hai considerato Clojure?
Mark Thomas

La risposta è Julia ! Semplicemente non esisteva allora: bit.ly/julia_meta ... rallegrati! Julia copre tutti i punti importanti elencati da @dsimcha, oltre alle prestazioni e tutti gli altri punti si stanno avverando mentre Julia continua a maturare.
SalchiPapa

Risposte:


15

Non c'è davvero un'enorme differenza tra python e ruby ​​almeno a livello ideologico. Per la maggior parte, sono solo sapori diversi della stessa cosa. Pertanto, consiglierei di vedere quale corrisponde di più al tuo stile di programmazione.


30
Ci sono sicuramente non la stessa cosa. L'aspetto è simile in superficie, ma se eserciti le funzionalità più potenti di Ruby capisci che Python non è all'altezza. Ad esempio, prova a scrivere un DSL in Ruby rispetto alla scrittura di un Python o alla creazione di funzioni, metodi, classi, ecc. In fase di esecuzione. È molto più semplice in Ruby.
FelipeC

14
Non è raro che tu abbia bisogno di fare la metaprogrammazione, è solo raro che sia fatto. Tutti i programmi, tranne il più banale, hanno schemi di ripetizione che non rientrano nei soliti strumenti di refactoring ma potrebbero essere facilmente eliminati dalla metaprogrammazione.
Wayne Conrad,

10
Ruby e Python sono estremamente diversi anche nelle idee che governano il loro design. Python ne vogliono uno e, si spera, un modo ovvio per fare le cose. Ciò generalmente rende il linguaggio meno espressivo di Ruby, ma lo rende più coerente. Ruby deriva un po 'di più dal modo di fare Perl dove ci sono molti modi per fare le cose. Anche Ruby rende alcune cose super facili e in realtà include l'idea di membri privati. Python d'altra parte al massimo rende solo qualcosa più difficile da fare, quindi devi essere più esplicito (come aggiungere o sovrascrivere il comportamento sulle classi).
Sean Copenhaver

5
Probabilmente dovresti fare un corso accelerato in entrambi, ma per una facile metaprogrammazione sembra che Ruby sia più adatto. Non ho molta esperienza, quindi prendila con le pinze.
Sean Copenhaver

7
Ruby e Python sono simili solo nel fatto che predicano "codice stupendo". Hanno solo punti di vista completamente diversi su quella cosa della bellezza (che IMO è buona)
Gabi Purcaru

69

Ho letto un po 'di Lisp e mi piacerebbe trovare un linguaggio che consenta alcune delle cose interessanti che fa Lisp, ma senza la strana sintassi, ecc. Di Lisp.

Non lo faremmo tutti.

distinzione minima tra codice e dati, stile Lisp

Purtroppo, la minima distinzione tra codice e dati e la sintassi "strana" sono conseguenze l'una dell'altra.

Se vuoi una sintassi di facile lettura, hai Python. Tuttavia, il codice non è rappresentato in nessuna delle strutture di dati incorporate di uso comune. Non riesce, come la maggior parte delle lingue, nell'elemento n. 1 dell'elenco "importanti". Ciò rende difficile fornire un aiuto utile.

Non puoi avere tutto. Ricorda, non sei il primo ad avere questo pensiero. Se esistesse qualcosa come il tuo linguaggio ideale, lo useremmo tutti. Poiché il mondo reale non è all'altezza dei tuoi ideali, dovrai assegnare una nuova priorità alla tua lista dei desideri. La sezione "importante" deve essere riorganizzata per identificare ciò che è veramente importante per te.


3
Ho scoperto che molti linguaggi implementano macro simili a Lisp in sintassi non Lispy e ciò che finisce per accadere è che scrivere macro lì è molto difficile, perché nessuno conosce naturalmente le strutture dati in cui è rappresentato il codice, quindi scrivere macro diventa troppo difficile e nessuno lo fa.
pupeno

11
Le persone trovano il Lisp difficile da leggere perché non hanno familiarità con la sintassi. Trovo Lisp molto più facile da leggere rispetto a C # (ma più difficile di Python).
Jules

1
Sono in gran parte d'accordo con il punto, ma la mia esperienza sia di Ruby che di Lisp mostra che il primo è buono per la metaprogrammazione come si ottiene senza le parentesi. Altre alternative che si avvicinano potrebbero essere TCL e JavaScript, ma non le preferirei per altri motivi.
inger

Molto tempo fa c'era una lingua chiamata Dylan che dovrebbe essere esattamente quella.
Friedrich

17

Onestamente, per quanto riguarda le strutture di metaprogrammazione, Ruby e Python sono molto più simili di quanto alcuni dei loro aderenti amano ammettere. Questa recensione di entrambe le lingue offre un confronto / recensione abbastanza buono:

Quindi, scegline uno in base ad alcuni criteri. Forse ti piace Rails e vuoi studiare quel codice. Forse SciPy è la tua passione. Guarda l'ecosistema di biblioteche, comunità, ecc. E scegline uno. Sicuramente non perderai alcun nirvana di metaprogrammazione basato sulla tua scelta di entrambi.


quel post sul blog sembra avere più a che fare con le preferenze personali (abbastanza giusto, ma la bellezza è negli occhi di chi guarda), piuttosto che con la metaprogrammazione - che era il punto principale dell'OP.
inger

16

Disclaimer: mi diletto solo in entrambe le lingue, ma ho almeno scritto piccoli programmi di lavoro (non solo script rapidi, per i quali uso Perl, bash o GNU make) in entrambi.

Ruby può essere davvero utile per i "paradigmi multipli" punto 3, perché lavora duramente per rendere facile la creazione di linguaggi specifici del dominio. Ad esempio, naviga online e guarda un paio di bit di codice Ruby on Rails e un paio di bit di codice Rake. Sono entrambi Ruby e puoi vedere le somiglianze, ma non assomigliano a quello che normalmente penseresti come la stessa lingua.

Python mi sembra un po 'più prevedibile (possibilmente correlato a' pulito 'e' sano 'punto 2), ma non so se sia a causa del linguaggio stesso o semplicemente che è tipicamente usato da persone con valori diversi . Non ho mai tentato la magia profonda in Python. Direi sicuramente che entrambe le lingue sono ben pensate.

Entrambi ottengono buoni risultati in 1 e 4. [Modifica: in realtà 1 è abbastanza discutibile - c'è "eval" in entrambi, come comune nei linguaggi interpretati, ma difficilmente sono concettualmente puri. È possibile definire chiusure, assegnare metodi agli oggetti e quant'altro. Non sono sicuro che questo vada quanto vuoi.]

Personalmente trovo Ruby più divertente, ma in parte è perché è più facile distrarsi pensando a modi fantastici di fare le cose. In realtà ho usato di più Python. A volte non vuoi essere cool, vuoi andare avanti così è fatto prima di andare a dormire ...

Nessuno dei due è difficile da affrontare, quindi potresti decidere di svolgere il tuo prossimo compito minore in uno e quello successivo nell'altro. Oppure prendi un libro introduttivo su ciascuno dalla biblioteca, leggili entrambi e guarda cosa ti cattura.


15

Hai considerato Smalltalk? Offre una sintassi molto semplice, chiara ed estensibile con capacità di riflettività e introspezione e un ambiente di sviluppo completamente integrato che sfrutta tali capacità. Dai un'occhiata ad alcuni dei lavori svolti in Squeak Smalltalk, ad esempio. Molti ricercatori che usano Squeak si trovano nella mailing list di Squeak e #squeak su freenode, quindi puoi ottenere aiuto su questioni complesse molto facilmente.

Altri indicatori della sua attuale rilevanza: funziona su qualsiasi piattaforma tu voglia nominare (incluso l' iPhone ); Gilad Bracha sta basando il suo lavoro in neolingua su Squeak; il team V8 si è fatto le ossa sulle VM Smalltalk ; e Dan Ingalls e Randal Schwartz sono recentemente tornati a lavorare su Smalltalk dopo anni nella natura selvaggia.

Buona fortuna con la tua ricerca: facci sapere cosa decidi alla fine.


14

Lisp soddisfa tutti i tuoi criteri, comprese le prestazioni, ed è l'unico linguaggio che non ha una (strana) sintassi. Se lo eviti su una base così sorprendentemente mal informata / sbagliata e di conseguenza perdi l'esperienza dell'uso, ad esempio, Emacs + SLIME + CL, ti renderai un grande disservizio.


4
Oppure puoi provare Clojure, che trovo molto carino.
pupeno

1
Fortemente d'accordo. Se vuoi il potere del Lisp, tuffati e fallo! In realtà è abbastanza facile abituarsi ai genitori; non sono un grosso problema come la maggior parte delle persone pensa che siano.
Dan Burton

11

I tuoi 4 punti "importanti" portano esattamente a Ruby, mentre i 2 punti "un po 'importanti" sono governati da Python. Così sia.


11

Stai descrivendo Ruby.

  • Buona metaprogrammazione. Capacità di creare classi, metodi, funzioni, ecc. In fase di esecuzione. Preferibilmente, distinzione minima tra codice e dati, stile Lisp.

È molto facile estendere e modificare le primitive esistenti in fase di esecuzione. In ruby ​​tutto è un oggetto, stringhe, interi, persino funzioni.

Puoi anche costruire scorciatoie per lo zucchero sintattico, ad esempio con class_eval .

  • Sintassi piacevole, pulita, sana e semantica coerente e intuitiva. Fondamentalmente un linguaggio moderno e ben congegnato, divertente da usare.

Ruby segue il principio della minore sorpresa e, confrontando il codice Ruby con l'equivalente in un altro linguaggio, molte persone lo considerano più "bello".

  • Paradigmi multipli. Nessun paradigma è giusto per ogni progetto, o anche per ogni piccolo sottoproblema all'interno di un progetto.

Puoi seguire imperativo, orientato agli oggetti, funzionale e riflessivo.

  • Un linguaggio interessante che effettivamente influenza il modo in cui si pensa alla programmazione.

Questo è molto soggettivo, ma dal mio punto di vista la capacità di utilizzare molti paradigmi contemporaneamente consente idee molto interessanti.

Ho provato Python e non si adatta ai tuoi punti importanti.


11
-1 Sto usando Python e si adatta perfettamente, le differenze tra Python e Ruby risiedono in altri aspetti. Rumore da fanboy, lo sei.
gorsky

6
Si parla molto ma non si cammina. Ti interessa fornire un esempio in Python di aggiungere dinamicamente un metodo per dire, la classe String?
FelipeC

6
@john Questo è precisamente il mio punto; è molto complicato e brutto (per non parlare dell'impossibilità per la classe String). OTOH in Ruby è molto semplice: "self.class.send (: define_method,: method_name) {method_code}"
FelipeC

2
Ruby potrebbe provare a seguire il PoLS, ma non direi che lo fa . Ad esempio, il lambda/ Proc.newmess è stato chiamato "comportamento sorprendente" e "altamente controintuitivo" qui su SO. :-) Qualsiasi linguaggio grande e complesso come Ruby è destinato ad avere aree così confuse.
Ken il

2
@Token ecco un esempio di patch di scimmia Stringin Ruby per scopi di metaprogrammazione: coldattic.info/shvedsky/pro/blogs/a-foo-walks-into-a-bar/posts/… . La sottoclasse non funzionerebbe; tuttavia, una semplice funzione a due argomenti lo farebbe.
P Shved

8

Confronta esempi di codice che fanno la stessa cosa (unisci con una nuova riga descrizioni non vuote di elementi da un myListelenco) in lingue diverse (le lingue sono disposte in ordine alfabetico inverso):

Rubino :

myList.collect { |f| f.description }.select { |d| d != "" }.join("\n")

O

myList.map(&:description).reject(&:empty?).join("\n")

Python :

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions)) 

O

"\n".join(f.description() for f in mylist if f.description())

Perl :

join "\n", grep { $_ } map { $_->description } @myList;

O

join "\n", grep /./, map { $_->description } @myList;

Javascript :

myList.map(function(e) e.description())
      .filter(function(e) e).join("\n")

Io :

myList collect(description) select(!="") join("\n")

Ecco una guida Io .


3
(format nil "~ {~ a ~ ^ ~% ~}" (remove nil (mapcar # 'description mylist)))
Rainer Joswig

bello, ma dov'è la metaprogrammazione qui? sembra essere uno stile leggermente funzionale, lontanamente correlato alla domanda.
inger

6

Ruby sarebbe migliore di Lisp in termini di "mainstream" (qualunque cosa significhi veramente , ma una preoccupazione realistica è quanto sarebbe facile trovare risposte alle tue domande sulla programmazione Lisp se dovessi andare con quello.) In ogni caso , Ho trovato Ruby molto facile da prendere. Nella stessa quantità di tempo che avevo passato ad imparare Python (o altri linguaggi per quella materia), stavo presto scrivendo un codice migliore in modo molto più efficiente di quanto avessi mai fatto prima. Questa è solo l'opinione di una persona, però; prendilo con le pinze, immagino. So molto di più su Ruby a questo punto rispetto a Python o Lisp, ma dovresti sapere che ero una persona Python per un bel po 'prima di cambiare.

Lisp è decisamente interessante e vale la pena esaminarlo; come hai detto, le dimensioni della comunità, ecc. possono cambiare abbastanza rapidamente. Detto questo, le dimensioni in sé non sono importanti quanto la qualità della comunità. Ad esempio, il #ruby-langcanale è ancora pieno di persone incredibilmente intelligenti. Lisp sembra attrarre anche alcune persone davvero intelligenti. Non posso parlare molto della comunità Python perché non ho molta esperienza diretta, ma a volte sembra essere "troppo grande". (Ricordo che le persone erano piuttosto scortesi sul loro canale IRC, e da quello che ho sentito da amici che sono veramente interessati a Python, questa sembra essere la regola piuttosto che l'eccezione.)

Ad ogni modo, alcune risorse che potresti trovare utili sono:

1) La serie Pragmatic Programmers Ruby Metaprogramming ( http://www.pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming ) - non gratuita, ma gli episodi successivi sono piuttosto intriganti. (Il codice è gratuito, se vuoi scaricarlo e vedere cosa impareresti.)

2) On Lisp di Paul Graham ( http://www.paulgraham.com/onlisp.html ). È un po 'vecchio, ma è un classico (e scaricabile gratuitamente).


5

Sto usando Python per molti progetti e penso che Python fornisca tutte le funzionalità richieste.

importante:

  1. Metaprogrammazione: Python supporta metaclassi e generazione di classi / metodi di runtime, ecc
  2. Sintassi: Beh, questo è in qualche modo soggettivo. Mi piace la sintassi di Python per la sua semplicità, ma alcune persone si lamentano che Python è sensibile agli spazi.
  3. Paradigmi: Python supporta la programmazione funzionale procedurale, orientata agli oggetti e di base.
  4. Penso che Python abbia uno stile molto pratico, è stato molto stimolante per me.

Abbastanza importante:

  1. Performance: Beh, è ​​un linguaggio di scripting. Ma scrivere estensioni C per Python è una pratica di ottimizzazione comune.
  2. Documentazione: non posso lamentarmi. Non è così dettagliato come qualcuno potrebbe sapere da Java, ma è abbastanza buono.

Dato che sei uno studente laureato potresti voler leggere questo articolo sostenendo che Python è tutto ciò di cui uno scienziato ha bisogno . Sfortunatamente non posso confrontare Python con Ruby, poiché non ho mai usato quel linguaggio.

Saluti, Dennis


3
Python non è sensibile agli spazi bianchi È sensibile al rientro.
jfs

5

@ Jason I rispettivamente in disaccordo. Ci sono differenze che rendono Ruby superiore a Python per la metaprogrammazione, sia filosofica che pragmatica. Per i principianti, Ruby ottiene l'eredità giusta con Single Inheritance e Mixin . E quando si tratta di metaprogrammazione devi semplicemente capire che si tratta di te stesso . La differenza canonica qui è che in Ruby hai accesso all'oggetto self in fase di esecuzione - in Python no!

A differenza di Python, in Ruby non esiste una fase separata di compilazione o runtime. In Ruby, ogni riga di codice viene eseguita su un particolare oggetto self . In Ruby ogni classe eredita sia da object che da una metaclasse nascosta. Ciò crea alcune dinamiche interessanti:

class Ninja
  def rank
    puts "Orange Clan"
  end

  self.name #=> "Ninja"
end

Utilizzando self.name si accede al metodo del nome della metaclasse delle classi Ninja per restituire il nome della classe di Ninja. La metaprogrammazione è così bella in Python? Ne dubito sinceramente!


4

Bene, se non ti piace la sintassi lisp forse l'assembler è la strada da percorrere. :-)

Certamente ha una distinzione minima tra codice e dati, è multi-paradigma (o forse non è un paradigma) ed è un'esperienza che espande la mente (se noiosa) sia in termini di apprendimento che di trucchi che puoi fare.


Penso di aver fatto più meta programmazione in linguaggio assembly che in qualsiasi altro linguaggio. Il codice è dato e i dati possono tentare di essere codice. E i dati non sono firmati o non firmati, è il codice operativo che decide.
Nosredna

1
Ho un codice assembler che potresti affermare di essere OO. Ha cose che sembrano piuttosto metodi: tu chiami quello che dipende dalla "classe".
justintime

4

Io soddisfa tutti i tuoi punti "Importanti". Non credo che ci sia un linguaggio migliore là fuori per fare folli meta hacker.


Grazie per quello, non lo sapevo. Sembra divertente a prima vista, forse un sacco di (()) ma comunque. Spero di trovare presto il tempo per dare un'occhiata.
flq

3

uno che supporta gli hack di metaprogrammazione che semplicemente non possono essere eseguiti in un linguaggio compilato staticamente

Mi piacerebbe trovare un linguaggio che consenta alcune delle cose interessanti che fa Lisp

Lisp può essere compilato.



3

La mia risposta non sarebbe né l'uno né l'altro. Conosco entrambi i linguaggi, ho seguito un corso su Ruby e ho programmato in Python per diversi anni. Lisp è bravo nella metaprogrammazione perché il suo unico scopo è trasformare le liste, il suo codice sorgente è solo un elenco di token, quindi la metaprogrammazione è naturale. Le tre lingue che mi piacciono di più per questo tipo di cose sono Rebol, Forth e Factor. Rebol è un linguaggio di composizione molto potente che prende il codice dal suo flusso di input, esegue un'espressione contro di esso e lo trasforma usando regole scritte nella lingua. Molto espressivo ed estremamente bravo nel dialetto. Factor e Forth sono più o meno completamente separati dalla sintassi e li programmate definendo e chiamando parole. Di solito sono scritti principalmente nella loro lingua. Non scrivi applicazioni in senso tradizionale, estendi la lingua scrivendo le tue parole per definire la tua particolare applicazione. Factor può essere particolarmente utile in quanto ha molte funzionalità che ho visto solo in Smalltalk per valutare e lavorare con il codice sorgente. Uno spazio di lavoro davvero carino, documenti interattivi, ecc.


2

Non c'è davvero molto per separare Python e Ruby. Direi che la comunità Python è più grande e più matura della comunità Ruby, e questo è molto importante per me. Il rubino è un linguaggio più flessibile, che ha ripercussioni positive e negative. Tuttavia, sono sicuro che ci saranno molte persone che entreranno nei dettagli su entrambe queste lingue, quindi lancerò una terza opzione sul ring. Che ne dici di JavaScript?

JavaScript è stato originariamente progettato per essere Scheme per il web ed è basato su prototipi, il che è un vantaggio rispetto a Python e Ruby per quanto riguarda il multi-paradigma e la metaprogrammazione. La sintassi non è bella come le altre due, ma è probabilmente il linguaggio più diffuso esistente e le prestazioni migliorano ogni giorno.


2

Se ti piace il concetto di codice in stile lisp, ma non ti piace la sintassi Lispy, forse Prolog sarebbe una buona scelta.

Se questo si qualifica come un "linguaggio moderno e divertente", lo lascerò giudicare ad altri. ;-)


2

Ruby è la mia scelta dopo aver esplorato Python, Smalltalk e Ruby.


2

E OCaml?

Caratteristiche di OCaml: un sistema di tipo statico, inferenza di tipo, polimorfismo parametrico, ricorsione della coda, corrispondenza di modelli, chiusure lessicali di prima classe, funtori (moduli parametrici), gestione delle eccezioni e raccolta automatica generazionale incrementale dei rifiuti.

Penso che soddisfi quanto segue:

Importante:

  1. Sintassi piacevole, pulita, sana e semantica coerente e intuitiva. Fondamentalmente un linguaggio moderno e ben congegnato, divertente da usare.
  2. Paradigmi multipli. Nessun paradigma è giusto per ogni progetto, o anche per ogni piccolo sottoproblema all'interno di un progetto.
  3. Un linguaggio interessante che effettivamente influenza il modo in cui si pensa alla programmazione.

Abbastanza importante:

  1. Prestazione. Sarebbe bello se le prestazioni fossero decenti, ma quando le prestazioni sono una vera priorità, userò invece D.
  2. Ben documentato.

OCaml ti permette di creare classi / metodi in fase di esecuzione? Come funziona?
Jason Creighton

Ho appena letto di OCaml e forse non può creare roba in fase di esecuzione, quindi l'ho rimosso.
Robert Vuković


1

Per la sintassi in stile Python e le macro simili a lisp (macro che sono codice reale) e un buon DSL vedi Converge .


1

Non sono sicuro che Python soddisfi tutto ciò che desideri (specialmente il punto sulla distinzione minima tra codice e dati), ma c'è un argomento a favore di Python. C'è un progetto là fuori che ti rende facile programmare estensioni per python in D, così puoi avere il meglio di entrambi i mondi. http://pyd.dsource.org/celerid.html



1

Ti consiglierei di andare con Ruby.

Quando ho iniziato a impararlo, l'ho trovato davvero facile da imparare.


1

Non mescolare il linguaggio di programmazione Ruby con le implementazioni di Ruby, pensando che i thread POSIX non siano possibili in ruby.

Puoi semplicemente compilare con il supporto di pthread, e questo era già possibile al momento in cui è stato creato questo thread , se scusate il gioco di parole.

La risposta a questa domanda è semplice. Se ti piace il lisp, probabilmente preferirai il rubino. Oppure, qualunque cosa tu voglia.




0

Per quanto riguarda il tuo punto principale (meta-programmazione): la versione 1.6 di Groovy ha la programmazione AST (Abstract Syntax Tree) incorporata come funzionalità standard e integrata. Ruby ha RubyParser, ma è un componente aggiuntivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.