Provate a immaginare la chimica senza il Sistema Periodico di Mendeleev (1869). Quanti elementi bisognava tenere a mente, per di più in ordine casuale... (All'epoca erano 60.)
Per questo è sufficiente pensare a uno o più linguaggi di programmazione alla volta. Le stesse sensazioni, lo stesso disordine creativo.
Ora possiamo rivivere le emozioni dei chimici del XIX secolo, quando ricevettero tutte le loro conoscenze, e un po' di più, in un'unica Tabella Periodica.

Il libro "Matryoshka C. Sistema stratificato del linguaggio di programmazione" presenta tutte le unità del linguaggio C come su un palmo della mano. Questo consente di ordinarle, correggere informazioni obsolete e persino chiarire il concetto stesso di programma.
Oggi le informazioni sulla programmazione necessitano di sistematizzazione ancora più delle sostanze chimiche di 150 anni fa.
La prima necessità è l'insegnamento. Mendeleev iniziò a creare il suo sistema quando si trovò di fronte al dilemma di quale elemento cominciare a insegnare: O, H, N, He, Au… Per lui era più semplice: insegnava chimica ai migliori - gli studenti dell'università di San Pietroburgo. Mentre la programmazione è già insegnata a scuola e presto inizieranno a insegnarla anche all'asilo.
La seconda necessità è un approccio scientifico. Con il Sistema Periodico sono stati scoperti nuovi elementi e corrette informazioni sugli elementi esistenti. Ha aiutato nella creazione del modello atomico (1911). E così via.
La terza necessità è la chiarificazione del concetto di programma.
La programmazione moderna è in parte bloccata negli anni '50 del XX secolo. All'epoca i programmi erano semplici, mentre le macchine e i linguaggi di programmazione erano complessi, quindi tutto ruotava attorno a macchine e linguaggi.
Ora è tutto l'opposto: i programmi sono complessi e primari, i linguaggi sono semplici e secondari. Questo è chiamato approccio applicato, che a tutti sembra familiare. Ma studenti e sviluppatori continuano a essere persuasi che tutto rimane uguale.
Questo ci riporta alla prima lezione del privato-docente Mendeleev. Cosa dire agli studenti del primo anno? Dove si trova la verità? Ecco la questione.
Il libro "Matryoshka C. Sistema stratificato del linguaggio di programmazione" offre la sua risposta. Inoltre, è rivolto non solo agli studenti, ma anche ai programmatori preparati, poiché sono proprio loro che devono cercare la verità e ribaltare la propria visione del mondo, cioè noi.
Segue un breve riassunto del libro.
1. Introduzione
Nel 1969 è stato creato il linguaggio C, che è diventato un linguaggio di programmazione fondamentale e continua ad esserlo da 50 anni. Perché è così? In primo luogo, perché C è un linguaggio applicativo , che conferisce al programma un aspetto umano invece di meccanico. Questo traguardo è stato consolidato dai linguaggi della famiglia C: C++, JavaScript, PHP, Java, C# e altri. In secondo luogo, è un linguaggio conciso e bello.
Tuttavia, il linguaggio C è spesso confuso con l'assemblatore, complicando e distorcendo così la sua percezione. L'altro estremo è l'imposizione di una qualche "filosofia" aggiuntiva al linguaggio: procedurale, orientata agli oggetti, funzionale, compilata, interpretata, tipizzata e così via. Questo aggiunge emozione, ma non aiuta a descrivere meglio il linguaggio.
La verità si trova nel mezzo, e per il linguaggio C sta rigorosamente a metà tra la percezione filosofica e quella meccanica.
Il linguaggio C non è autonomo, si conforma al linguaggio scritto comune e contemporaneamente controlla il linguaggio dell'assemblatore. Questa condizione è descritta da Il modello linguistico del programma, secondo il quale il programma è suddiviso in tre tipi subordinati: linguistico, codificato, comandi. Il linguaggio C si occupa del secondo, quello codificato.
Definendo il posto del linguaggio nel programma, si possono ordinare le informazioni su di esso, il che crea Un sistema stratificato del linguaggio del programma, che rappresenta il linguaggio C nello spirito del sistema periodico di Mendeleev — su un'unica pagina.
Il sistema è costruito tenendo conto della comunanza dei linguaggi applicativi, derivante dalla loro subordinazione linguistica. Un insieme di unità Matrioska in C consente di descrivere e confrontare diversi linguaggi, creando una serie di Matriosche: C++, PHP, JavaScript, C#, MySQL, Python e così via. È giusto e corretto che diversi linguaggi siano descritti in unità del linguaggio fondamentale.
2. CAPITOLO 1. Il modello linguistico del programma. C comprensibile
Nel primo capitolo è presentato il modello linguistico del programma, che riflette l'approccio applicativo. Secondo questo modello, il programma ha tre modi sequenziali ovvi:
- linguistico — la parola diretta del programmatore che risolve un compito,
- codificato — la codifica della soluzione in forma matematica nel linguaggio C (o in qualsiasi altro)
- e comandi — i comandi diretti della macchina.
Il modello linguistico spiega perché C sia un linguaggio semplice e comprensibile. C è costruito a immagine e somiglianza del linguaggio umano che conosciamo.
Il primo tipo di programma è la narrazione diretta del programmatore. Il discorso corrisponde al pensiero umano. Attraverso il linguaggio, i programmatori principianti scrivono programmi - inizialmente in russo, poi traducendo passo dopo passo le azioni nel linguaggio di codice. È proprio sulla base di questo modello che è stato creato il linguaggio C.
Le deduzioni del programmatore, espresse a parole, vengono trasformate in una forma numerica di codice. Questa trasformazione dovrebbe essere chiamata riflessione, poiché il linguaggio e il codice hanno una stessa natura (riflessione - nascita - genitore). È abbastanza ovvio se confronti il tipo di linguaggio (a sinistra) e quello di codice (a destra).

È curioso notare che la riflessione avviene in modo molto semplice - solo con due forme di espressione.
Tuttavia, la descrizione moderna del linguaggio C (dal 1978) non contiene un elenco sufficiente di nomi né per descrivere il linguaggio in generale, né per trattare specificamente la riflessione. Pertanto, siamo costretti a impegnarci nella creatività e a introdurre questi nomi.
La scelta delle parole deve essere precisa e chiara. Per questo è stato necessario un approccio particolare, riassumibile come - utilizzo rigoroso della lingua madre. Per gli inglesi sarebbe stato l'inglese, ma noi non siamo inglesi. Quindi utilizziamo ciò che abbiamo e cerchiamo di parlare in russo.
La riflessione si realizza attraverso due forme di espressione:
- elaborazione (El) - riflette la modifica delle proprietà di un oggetto. La proprietà di un oggetto è espressa da un numero, quindi l'azione sulla proprietà è l'azione su un numero - un'operazione.
- sottomissione (Sm) - riflette il cambiamento nell'ordine delle azioni. Il prototipo di Sm è la proposizione subordinata del linguaggio, pertanto la maggior parte dei tipi di Sm inizia con congiunzioni subordinanti come "se", "altrimenti", "finché", "per". Altri tipi di Sm le completano.
A proposito, puoi credere che nella descrizione del C non ci sia un nome per le espressioni di elaborazione - vengono semplicemente chiamate "espressioni"? Dopo ciò, non dovrebbe sorprendere l'assenza di un nome e di un'unione per la forma di sottomissione, così come la scarsità in generale di nomi, definizioni e generalizzazioni. Tutto ciò perché il famoso K/R ("Linguaggio C", Kernighan/Ritchie, 1978) non è una descrizione, ma una guida all'uso del linguaggio.
Tuttavia, si desidererebbe avere una descrizione del linguaggio. Pertanto, viene proposta Un sistema stratificato del linguaggio del programma.
3. CAPITOLO 2. Sistema a strati. C brevissimo
Qualsiasi descrizione deve essere precisa e estremamente concisa. Nel caso del linguaggio del programma, una descrizione diretta è difficile.
Abbiamo un programma. È composto da moduli. I moduli sono formati da sottoprogrammi e collezioni (structure). I sottoprogrammi consistono in espressioni singole: dichiarazioni, calcoli, subordinazioni. Ci sono dieci tipi di subordinazioni. Le subordinazioni collegano sotto-livelli e sottoprogrammi. Anche le dichiarazioni sono diverse. Tuttavia, le dichiarazioni vengono incluse non solo nei sottoprogrammi e nei sotto-livelli, ma anche nei moduli e nelle collezioni. La maggior parte delle espressioni è composta da parole che è così difficile descrivere, che di solito vengono solo fornite in due elenchi - parole originarie e parole derivate, con cui si dovrà fare conoscenza per tutta la durata dello studio e dell'applicazione del linguaggio. A questo si aggiungono i segni di punteggiatura e una serie di altre espressioni.
In una tale esposizione, è difficile capire chi stava su chi.
Un approccio diretto e gerarchico alla descrizione del linguaggio sarebbe eccessivamente complesso. La ricerca di vie alternative porta a descrivere il linguaggio sulla base della sua natura verbale e della parte di comando. Così è nato il Sistema Stratificato, parzialmente sovrapponendosi al Sistema Periodico di Mendeleev, che è anch'esso stratificato. Come è emerso 42 anni dopo la sua pubblicazione (1869), la periodicità del sistema è legata agli strati elettronici (1911, modello di atomo di Bohr-Rutherford). Inoltre, il Sistema Stratificato e il Sistema Periodico condividono la disposizione tabellare di tutte le unità su una sola pagina.
La descrizione delle unità di linguaggio risulta concisa: solo 10 generi di espressioni e 8 generi di altre unità, oltre a essere sostanziosa e visibile. Sebbene sia insolita per un primo incontro.
Le unità linguistiche sono suddivise in 6 livelli:
- ordini - righe della tabella
- sezioni - gruppi speciali di generi (parte della prima riga)
- generi - celle (livello principale della divisione)
- sottogeneri - separatori di tipi (livello raro)
- tipi - formule delle unità nella parte inferiore della cella o separatamente
- campioni - le unità stesse (solo per le parole)
I campioni di parole sono descritti dal dizionario un sottosistema separato composto dagli stessi sei livelli.
La componente verbale del linguaggio C è abbastanza evidente, anche se merita comunque una descrizione. La parte di comando del linguaggio è in realtà legata alla gestione della compilazione, durante la quale viene creato il terzo tipo di programma - il programma di comando. Qui ci avviciniamo all'aspetto più affascinante del linguaggio C - la bellezza.
4. CAPITOLI SUCCESSIVI. Un C bello
Il linguaggio C sta alla base della programmazione moderna. Perché? In primo luogo, per il suo maggiore allineamento con il linguaggio. In secondo luogo, perché ha superato elegantemente i limiti dell'elaborazione numerica da parte delle macchine.
Cosa ha proposto C? Immagine e alce.
La parola «immagine» è la traduzione dell'inglese «type», che deriva dal greco «prototipo» — «modello». In russo, la parola «tipo» non esprime esattamente il concetto centrale ed è spesso confusa con il significato funzionale «tipo».
Inizialmente, l'immagine ha risolto un compito puramente meccanico di calcolo, diventando poi una pista di lancio per la nascita dei linguaggi orientati agli oggetti.
L'alce ha subito risolto più problemi, sia meccanici che applicativi. Pertanto, l'analisi inizierà con un'immagine monocomputazionale e passerà a un alce multi-tasking.
Una delle caratteristiche sgradevoli della programmazione storica è che la maggior parte dei concetti, compresi quelli fondamentali, è fornita senza definizioni. «Il linguaggio di programmazione (nome dei fiumi) ha un tipo di numeri interi e flottanti…» — e il discorso continua. Cosa si intende per «tipo» (immagine) — non è necessario definirlo, poiché gli autori stessi non lo comprendono appieno e si tirano indietro «per chiarezza». Se messi alle strette, forniranno una definizione vaga e inutile. È molto utile nascondersi dietro parole straniere: per gli autori russi — dietro quelle inglesi (tipo), per gli inglesi — dietro quelle francesi (subroutine), greche (polimorfismo), latine (incapsulamento) o le loro combinazioni (polimorfismo ad hoc).
Ma questo non è il nostro destino. La nostra scelta sono definizioni chiare in un russo puro.
Immagine
Immagine — è il nome modello della grandezza, che definisce 1) le proprietà proprie della grandezza e 2) la selezione di operazioni per la grandezza.
Alla parola «tipo» (tipo) corrisponde la prima parte della definizione: «proprietà proprie della grandezza». Ma il significato principale dell'immagine risiede nella seconda parte: «selezione di operazioni per le grandezze».
Il punto di partenza per l'introduzione dell'immagine nel linguaggio C è un calcolo comune, ad esempio, l'operazione di addizione.
Carta la matematica, scritta a mano o stampata, non fa particolari distinzioni tra i tipi di numeri, considerando generalmente che siano reali. Pertanto, le operazioni su di essi sono inequivocabili.
Macchina La matematica distingue rigorosamente i numeri in interi e frazionari. I diversi tipi di numeri vengono memorizzati in modo differente e trattati da comandi diversi del processore. Ad esempio, i comandi per sommare numeri interi e frazionari sono due comandi differenti, corrispondenti a due nodi diversi del processore. Tuttavia, non esiste un comando per sommare argomenti interi e frazionari.
Applicata La matematica, cioè il linguaggio C, distingue i tipi di numeri ma unifica le operazioni: la somma per numeri interi e/o frazionari viene espressa con un unico simbolo dell'operazione.
Una chiara definizione del concetto di immagine consente di parlare con certezza di due altri concetti: quantità e operazione.
Quantità e operazione
Quantità è il numero elaborato.
Operazione è l'elaborazione dei valori delle quantità sorgente (argomenti) per ottenere il numero finale (risultato).
Quantità e operazione sono interconnesse. Ogni operazione è una quantità, poiché ha un risultato numerico. E ogni quantità è il risultato della trasmissione di un valore nel registro del processore/dal processore, cioè — il risultato dell'operazione. Nonostante questa interconnessione, comunque, la cosa principale è la possibilità della loro descrizione separata, anche se con la ripetizione della stessa parola in diverse sezioni del dizionario, che è ciò che accade in ma3.
L'approccio macchina divide tutti i numeri utilizzati dal programmatore in comandi e dati. In passato entrambi erano numeri, ad esempio, i comandi erano scritti con codici numerici. Tuttavia, nei linguaggi applicativi i comandi hanno smesso di essere numeri e sono diventati parole e simboli delle azioni. Solo "dati" sono rimasti numeri, ma continuare a chiamarli così è ridicolo, perché passando dalla prospettiva della macchina a quella matematica i numeri sono quantità che si dividono in originali (dati) e finali (cercati). "Dato sconosciuto" suonerebbe sciocco.
I comandi si sono anch'essi divisi in due tipi di azioni: matematiche e ausiliarie. Le azioni matematiche sono operazioni. Ci occuperemo in seguito di quelle ausiliarie.
Nei linguaggi C, le abituali operazioni matematiche chiare e singole, o uniche, tendono a diventare quasi tutte multiple.
Le operazioni multiple sono diverse operazioni omonime con diversi tipi di argomenti e azioni che hanno significati simili.
A un argomento intero corrisponde un'operazione intera, a un argomento frazionario un'operazione frazionaria. Questa differenza è particolarmente visibile nell'operazione di divisione, quando l'espressione 1/2 dà come risultato 0, e non 0,5. Questo formato non rispetta le regole della matematica cartacea, ma il linguaggio C non si sforza di seguirle (a differenza del Fortran) — gioca secondo le sue regole. In caso di mescolanza di numeri interi e frazionari viene attivato l'unico corretto
adeguamento dei valori degli argomenti — una trasformazione selettiva del valore da una forma all'altra. Infatti, quando si somma un numero intero a uno frazionario, il risultato è frazionario, quindi il formato dell'operazione sceglie l'operazione di trasformazione dell'argomento intero in un valore frazionario. Una serie di operazioni rimane non
multipla singola, ma . Tali operazioni sono definite solo per un tipo di argomenti: il resto della divisione — argomenti interi, bitwise operations — numeri interi naturali. Ma3 indica la molteplicità delle operazioni con segni (#^) specificando le forme per le quali l'operazione è definita. Questa è una proprietà importante, ma trascurata in precedenza, di ciascuna operazione.Tutte le funzioni sono operazioni arbitrarie singole. Un'eccezione è rappresentata dagli operatori —
funzioni senza parentesi , incorporate nel linguaggio (operazioni di base).Cooperazione
— azione associata all'operazione.
— azione associata all'operazione. Se consideriamo l'operazione come l'azione principale, possiamo identificare due azioni associate che garantiscono l'operazione e si differenziano da essa. Sono 1) gestione della variabile e 2) subordinazione. Questa azione è chiamata
cooperazione. Qui è necessario distaccarsi e discutere separatamente delle traduzioni russe dei libri di testo sulla programmazione. Nel testo K/R è stata introdotta una nuova parola.
statement (espressione), che ha tentato di separare i concetti di comando macchina in diverse azioni: 1) operazione, 2) dichiarazione e 3) subordinazione (denominata 'strutture di controllo'). Questo tentativo è stato sepolto dai traduttori russi, sostituendo 'espressione' con la parola 'operatore', che: è diventata sinonimo della parola macchina 'comando',
- si è rivelata sinonimo della frase 'simbolo di azione',
- e ha anche acquisito un numero illimitato di significati aggiuntivi. Cioè è diventata simile all'articolo inglese 'uhhh...'.
- Esaminiamo le azioni associate, o
cooperazioni. Gestione della variabile..
Gestione della variabile
Gestione della variabile (UP) — creazione/rimozione di celle variabili.
L'UP avviene in modo implicito durante la dichiarazione di una variabile, che è già scritta per un'altra ragione — per specificare il modo in cui viene misurata la grandezza. Solo un tipo è gestito esplicitamente. di variabili aggiuntive utilizzando le funzioni malloc() e free().
È importante notare che le azioni implicite sono più comode da scrivere, poiché non richiedono nulla da essere scritto, ma sono più difficili da comprendere — è più complicato tenerne conto e interpretarli.
Sottomissione
Sottomissione — connessione/disconnessione di sezioni stratificate.
Il linguaggio C ha proposto un modo pratico di gestire l'ordine delle azioni, diverso dall'assembler — sottomissione. Essa riflette e sviluppa la proposizione subordinata del linguaggio, con una chiara separazione tra la parte principale (proposizione di sottomissione) e la parte subordinata (sezioni sottolivello/sottoprogramma).
Sia la dichiarazione che la sottomissione sono completamente costruite sul concetto di strato.
Strato
Strato — è un insieme selettivo di espressioni limitato a un solo livello.
Lo strato ha chiaramente e implicitamente assunto diversi compiti:
- ordinare il programma,
- limitare la visibilità dei nomi (implicitamente),
- gestire le variabili (celle di memoria) (implicitamente),
- definire sezioni subordinate per la sottomissione,
- definizione di funzioni e raccolte e altro ancora.
Nei linguaggi macchina non esisteva il concetto di strato, quindi non è apparso nemmeno in K/R, e se qualcosa non c'era lì — sarebbe stato empio e libertino introdurlo nei libri successivi. Pertanto, il concetto di strato non è mai apparso, anche se è estremamente utile e abbastanza ovvio.
Senza strato, non è possibile spiegare brevemente e chiaramente molte azioni e regole del programma. Ad esempio, perché il semplice comando goto sia dannoso, ma il complesso while sia vantaggioso. Si può solo imprecare impotentemente, come faceva Dijkstra («la qualificazione dei programmatori è una funzione che dipende inversamente dalla frequenza di utilizzo dell'operatore goto nei loro programmi». In breve, solo gli stupidi usano il goto. Livello di giustificazione — Dio). In effetti, non è così terribile se i vostri libri non devono spiegare nulla, ma, come abbiamo già detto, non è il nostro destino.
A proposito, si potrebbe ipotizzare che Den Ritchie abbia lasciato goto proprio come chiave per la ricerca di un concetto non nominato, perché non c'era alcuna necessità o bellezza nell'espressione goto. Tuttavia, c'era bisogno di una spiegazione semplice e chiara dei nuovi principi del linguaggio, che lo stesso Ritchie non voleva fornire, e che si basano proprio sul concetto strato.
Deviazione
Deviazione — modifica delle proprietà normali del nuovo nome.
La deviazione più importante è proprio quella legata alle proprietà strato della programma, e viene descritta con una sola parola: «static», che ha significati diversi in ciascun tipo di strato.
5. ULTIMO CAPITOLO. Comunità dei linguaggi applicativi
I linguaggi applicativi sono figurativi linguaggi (che hanno un'immagine, «tipizzati»). Si basano su un utilizzo esplicito o implicito dell'immagine. Qui si manifesta di nuovo la contraddizione: l'immagine esplicita è più comprensibile, ma meno comoda, e viceversa.

(La formattazione della tabella non è stata ancora fornita, quindi la tabella è presentata come immagine.)
Dopo C, lo sviluppo dei linguaggi applicativi ha seguito la strada dell'aumento della loro figuratività. Il discendente diretto di C, il linguaggio C++, è il più importante per comprendere l'alta figuratività. Esso sviluppa l'idea di selezione arbitraria di operazioni per le quantità e la incarna sulla base dell'espressione di C nota come selezione, che riceve un nuovo nome: oggetto. Tuttavia, C++ non è così conciso ed espressivo come C, a causa del sovraccarico di nuovi tipi di selezione e delle regole ad esse associate. A proposito, parliamo del «sovraccarico».
Sovraccarico e polimorfismo
La parola «sovraccarico» (overload) è un termine obsoleto dell'approccio di macchina, che indica la creazione di operazioni multiple.
Programmiatori di macchine (sistemici) la molteplicità di operazioni poteva irritare: «Cosa significa questo segno (+): somma di numeri interi, somma di numeri frazionari o addirittura uno spostamento?! Ai nostri tempi non si scriveva così!» Da qui il tono negativo della parola scelta («ripetizione», «stanco»). Per il programmatore applicativo, le operazioni multiple sono la pietra angolare, il principale risultato e l'eredità del linguaggio C, così naturali che spesso non vengono nemmeno percepite.
Nel linguaggio C++ la molteplicità si è diffusa non solo sulle operazioni di partenza, ma anche sulle funzioni - sia separate che unite in classi - metodi. Insieme ai molteplici metodi è emersa la possibilità di ridefinirli nelle classi estese, che è stata vagamente denominata «polimorfismo». La combinazione di polimorfismo e sovraccarico ha dato una miscela esplosiva, che si è suddivisa in due polimorfismi: «vero» e «ad-hoc». Capire questo è possibile solo contro i nomi assegnati. Nomi stranieri hanno pavimentato la strada verso ad.
L'annuncio di tipo «sovraccarico» è meglio esprimere con la parola ridefinizione — annuncio aggiuntivo della funzione omonima con argomenti di un'altra forma.
L'annuncio di tipo «polimorfismo» è meglio chiamarlo con la parola ridefinizione — annuncio sovrapposto in un nuovo strato espandente della funzione omonima con argomenti della stessa forma.
Allora sarà facile capire che i metodi omonimi di diverse forme (argomenti) — vengono ridefiniti, ma di una stessa forma — vengono ridefiniti.
Le parole russe risolvono.
Pista di decollo
La considerazione dei concetti dei linguaggi altamente tipizzati conferma l'importanza di una chiara definizione dei concetti fondamentali. Con un C ben descritto, lo studio dei linguaggi altamente tipizzati sarà facile e piacevole.
Ciò è particolarmente importante per linguaggi altamente tipizzati impliciti (PHP, JavaScript). Per loro, l'importanza degli oggetti (formati compositi) diventa ancora più alta rispetto a C++, ma il concetto stesso di formato diventa implicito e sfuggente. Dal punto di vista della comodità, sono diventati più semplici, ma da quello della comprensione — più complessi.
Pertanto, si dovrebbe iniziare lo studio dei linguaggi di programmazione con il C e procedere in ordine di apparizione dei linguaggi della famiglia C.
Lo stesso vale per la descrizione dei linguaggi. Diversi linguaggi hanno un insieme di generi di unità coincidente o minore rispetto al C. Il numero di tipi e formati può variare in entrambe le direzioni: in C++ ci sono più tipi rispetto a C, in JavaScript — meno.
Merita particolare menzione il linguaggio MySQL. A prima vista — nulla in comune, ma si descrive perfettamente con Matryoshka, e fare conoscenza con esso diventa più veloce e semplice. Ciò è importante, considerando la sua rilevanza per il web — l'arteria del moderno programmazione. E dove c'è MySQL, ci sono anche gli altri SQL. Bene, anche vari Fortran-Pascal-Python vengono descritti da Matryoshka, non appena si ha l'opportunità.
Quindi, ci aspettano grandi opere: una descrizione pratica del linguaggio C e una descrizione unificata dei linguaggi successivi. «I nostri obiettivi sono chiari, i compiti definiti. Al lavoro, compagni! (Applausi entusiasti e prolungati che sfociano in un'ovazione. Tutti si alzano.)»
Le vostre opinioni saranno ascoltate con grande attenzione, il vostro aiuto nella creazione del sito delle matrioske sarà accolto con enorme gratitudine. Maggiori informazioni sul libro si trovano sul sito, astutamente nascosto nella Matrioska C.
Fonte: habr.com
