Tullio Nicolussi. Il COBOL. J u r a s s i c B o o k s



Documenti analoghi
4 3 4 = 4 x x x 10 0 aaa

CREAZIONE DI UN DATABASE E DI TABELLE IN ACCESS

STAMPA UNIONE DI WORD

Siamo così arrivati all aritmetica modulare, ma anche a individuare alcuni aspetti di come funziona l aritmetica del calcolatore come vedremo.

NUOVA PROCEDURA COPIA ED INCOLLA PER L INSERIMENTO DELLE CLASSIFICHE NEL SISTEMA INFORMATICO KSPORT.

Convertitori numerici in Excel

Esercizi su. Funzioni

Excel. A cura di Luigi Labonia. luigi.lab@libero.it

ARCHIVI E DATABASE (prof. Ivaldi Giuliano)

Funzioni in C. Violetta Lonati

PROCEDURA INVENTARIO DI MAGAZZINO di FINE ESERCIZIO (dalla versione 3.2.0)

Il database management system Access

I file di dati. Unità didattica D1 1

Corso di Informatica

Cosa è un foglio elettronico

Esempi di algoritmi. Lezione III

Pagina 1 di 10

Dimensione di uno Spazio vettoriale

Appunti sulla Macchina di Turing. Macchina di Turing

risulta (x) = 1 se x < 0.

Introduzione alla programmazione in C

APPUNTI DI MATEMATICA LE FRAZIONI ALGEBRICHE ALESSANDRO BOCCONI

Database. Si ringrazia Marco Bertini per le slides

Obiettivo Principale: Aiutare gli studenti a capire cos è la programmazione

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

GESGOLF SMS ONLINE. Manuale per l utente

Automatizzare i compiti ripetitivi. I file batch. File batch (1) File batch (2) Visualizzazione (2) Visualizzazione

Mon Ami 3000 Varianti articolo Gestione di varianti articoli

2 Fortino Lugi. Figura Errore. Nel documento non esiste testo dello stile specificato Finestra attiva o nuovo documento

GUIDA RAPIDA PER LA COMPILAZIONE DELLA SCHEDA CCNL GUIDA RAPIDA PER LA COMPILAZIONE DELLA SCHEDA CCNL

Corso di Access. Prerequisiti. Modulo L2A (Access) 1.1 Concetti di base. Utilizzo elementare del computer Concetti fondamentali di basi di dati

Access. P a r t e p r i m a

Introduzione. Alberto Fortunato Pag. 1 di 137

Strutturazione logica dei dati: i file

Il calendario di Windows Vista

USARE JOOMLA 1.7/2.5 per gestire il vostro sito.

RISOLUTORE AUTOMATICO PER SUDOKU

GHPPEditor è un software realizzato per produrre in modo rapido e guidato un part program per controlli numerici Heidenhain.

Corso di Informatica Generale (C. L. Economia e Commercio) Ing. Valerio Lacagnina Rappresentazione in virgola mobile

Uso di base delle funzioni in Microsoft Excel

Access. Microsoft Access. Aprire Access. Aprire Access. Aprire un database. Creare un nuovo database

Complemento al corso di Fondamenti di Informatica I corsi di laurea in ingegneria, settore dell informazione Università la Sapienza Consorzio Nettuno

Indice. 1 Il monitoraggio del progetto formativo di 6

per immagini guida avanzata Organizzazione e controllo dei dati Geometra Luigi Amato Guida Avanzata per immagini excel

Sommario. Prefazione...9. Introduzione...11

Il funzionamento di prezzipazzi, registrazione e meccanismi

EXCEL FUNZIONI PRINCIPALI

LUdeS Informatica 2 EXCEL. Seconda parte AA 2013/2014

Cos è ACCESS? E un programma di gestione di database (DBMS) Access offre: un ambiente user frendly da usare (ambiente grafico)

Visual basic base Lezione 01. L'ambiente di sviluppo

PROMUOVERSI MEDIANTE INTERNET di Riccardo Polesel. 1. Promuovere il vostro business: scrivere e gestire i contenuti online» 15

Alessandro Pellegrini

Sistemi Operativi IMPLEMENTAZIONE DEL FILE SYSTEM. D. Talia - UNICAL. Sistemi Operativi 9.1

Come modificare la propria Home Page e gli elementi correlati

INTRODUZIONE I CICLI DI BORSA

Informatica B a.a 2005/06 (Meccanici 4 squadra) PhD. Ing. Michele Folgheraiter

Word processor funzione Stampa Unione

Capitolo 13. Interrogare una base di dati

Funzioni non documentate Openoffice.org. 3 Base mini-howto

Dispensa di database Access

Dispensa di Informatica I.1

Introduzione. Classificazione di Flynn... 2 Macchine a pipeline... 3 Macchine vettoriali e Array Processor... 4 Macchine MIMD... 6

Matematica in laboratorio

INFORMATICA 1 L. Mezzalira

AD HOC Servizi alla Persona

lo PERSONALIZZARE LA FINESTRA DI WORD 2000

Soluzione dell esercizio del 2 Febbraio 2004

5.2.1 RELAZIONI TRA TABELLE Creare una relazione uno-a-uno, uno-a-molti tra tabelle 9

Capitolo 2. Operazione di limite

Le basi della Partita Doppia in parole Facile e comprensibile. Ovviamente gratis.

COMUNICAZIONE UTENTI SISTEMI-PROFIS INSTALLAZIONE GE.RI.CO e PARAMETRI2015

UNA LEZIONE SUI NUMERI PRIMI: NASCE LA RITABELLA

NOZIONI BASE PER ESERCITAZIONI

EXCEL PER WINDOWS95. sfruttare le potenzialità di calcolo dei personal computer. Essi si basano su un area di lavoro, detta foglio di lavoro,

Dispense di Informatica per l ITG Valadier

Il concetto di Dare/Avere

Progettazione di un Database

II.f. Altre attività sull euro

Alla scoperta della nuova interfaccia di Office 2010

Mon Ami 3000 Lotti e matricole Gestione della tracciabilità tramite lotti/matricole

ControlloCosti. Cubi OLAP. Controllo Costi Manuale Cubi

Corso di PHP. Prerequisiti. 1 - Introduzione

Lezioni di Matematica 1 - I modulo

FONDAMENTI di INFORMATICA L. Mezzalira

LA TRASMISSIONE DELLE INFORMAZIONI QUARTA PARTE 1

Sistemi Operativi IMPLEMENTAZIONE DEL FILE SYSTEM. Implementazione del File System. Struttura del File System. Implementazione

SISTEMI DI NUMERAZIONE E CODICI

CORSO ACCESS PARTE II. Esistono diversi tipi di aiuto forniti con Access, generalmente accessibili tramite la barra dei menu (?)

Manuale Terminal Manager 2.0

Corso di Archivistica

MANUALE EDICOLA 04.05

Raggruppamenti Conti Movimenti

4. Operazioni aritmetiche con i numeri binari

Software per Helpdesk

Le query di raggruppamento

Sistema operativo. Sommario. Sistema operativo...1 Browser...1. Convenzioni adottate

IL MIO PRIMO SITO: NEWS

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi

Biblioteca di Cervia NOZIONI BASE DI INFORMATICA

Registratori di Cassa

Transcript:

Tullio Nicolussi Il COBOL J u r a s s i c B o o k s

Title: Il COBOL Author: Tullio Nicolussi Acquisitions Editor: Bes Delsec Technical Editor: Tullio Nicolussi Production Editor:Bes Delsec Production Manager: Tullio Nicolussi Book Designer: Anna Cover Designer: Anna Copyright 2008 by Jurassic News Published in Italy First edition 2009 ISBN: na This publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, only in integral form. Distribution on-line from http://www.jurassicnews.com Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including without limitation warranties of fitness for a particular purpose. For general information on our other products and services or to obtain technical support, please contact our Customer Care Department at marketing@jurassicnews.com Library of Congress Cataloging-in-Publication Data Nicolussi, Tullio. Il COBOL / Tullio Nicolussi. - 1st ed. ISBN na 1. Computer programming 2. Computer language 3. Computer manual. TRADEMARKS: Jurassic News, is not associated with any product or vendor mentioned in this book. 10 9 8 7 6 5 4 3 2 1 0 2

Sommario Introduzione...4 Overview...6 Il primo programma...10 Il Bubble Sort in COBOL...12 Le Variabili Strutturate...19 La Gestione dei File...26 La Gestione del Video...32 Conclusione...37 3

COBOL Introduzione Rileggendo la prima stesura di questo articolo ho visto (con orrore) che avevo scritto le solite cose che si dicono quando si spolvera un vecchio software e in particolare un linguaggio di programmazione che non gode più dei favori degli sviluppatori, cioè qualcosa come: - che questo è un peccato, che in realtà il linguaggio non ha nulla da invidiare ai più moderni idiomi, che ancora viene usato con profitto,... e via di questo passo fra un rammarico e un sospiro. Il bello è che per il COBOL tutto questo corrisponde alla verità! Ma perché allora quando se ne sussurra il nome gli studenti sghignazzano, i guro della programmazione si fanno due volte il segno della croce (che vuol dire che invocano il dio C++) e i colleghi più giovani scuotono il capo e mentre si allontanano si coglie chiara la frase...pronto per la pensione...? Ehi, un po di rispetto, che diamine! Per essere onesti non si deve negare che qualche acciacco ahinoi il linguaggio per eccellenza della programmazione gestionale non riesce a nasconderlo. Qualche iniezione di Gerovital in forma di query SQL è valsa a migliorarne taluni aspetti nascondendo le artriti reumatoidi dei file indexed. Parimenti le stampelle della programmazione per eventi sono valse a traghettare l idioma nelle acque assai agitate della programmazione Windows. Per finire la clonazione sotto forma di linguaggi embedded nei sistemi ERP (vedi ad esempio SAP), hanno arginato il fuggi fuggi generale dei cervelli programmatoidi che rischiava di lasciare milioni di righe di codice prive di qualsiasi possibilità di manutenzione. Eppure ancora oggi dove l idea di classe regna indiscussa, il COBOL rimane una buona scelta in molte circostanze. Questa considerazione è valida per la quasi totalità dei linguaggi di programmazione che sono stati inventati nella storia dell informatica (parecchie centinaia se contiamo anche i dialetti). Dipende tutto dalle circostanze in cui si opera, dai sistemi di cui si dispone e dalle prestazioni dei tool di sviluppo dei quali possiamo avvalerci. La fortuna di un linguaggio è determinata da una serie di circostanze contingenti che dipendono molto anche dalle mode, oltre che naturalmente dallo scopo con il quale esso viene progettato. L Assembly ad esempio nasce con i microprocessori e rimane l indiscusso re della programmazione a basso livello. Non è stato inventato niente di meglio perché è perfetto 4

così com è. I problemi di concorrenza si pongono quando più linguaggi si sovrappongono per funzionalità specifiche dell ambiente in cui operano. Ad esempio VBSCRIPT piuttosto che PHP, Python piuttosto che Ruby, etc, nella programmazione Web. Il COBOL ha rappresentato per un paio di decenni la soluzione indiscussa nell ambito della programmazione gestionale e rimane tutt ora uno strumento molto usato in questo ambito. Fino a pochi anni fa si calcolava esistessero molte più righe di COBOL al mondo di quante ne potesse vantare il C. Non sono a conoscenza del rapporto esistente in questo momento ma credo che sebbene il C possa vantare la palma del vincitore in questa gara, il COBOL non sia molto distante dal podio. 5

COBOL - Overview L insegnamento del linguaggio COBOL è stato per anni appannaggio della scuola secondaria a indirizzo tecnico. Qualunque istituto pretendesse di sfornare programmatori doveva tenerne conto ed approntare per esso specifici corsi. Le banche e la finanza in genere hanno assorbito moltissima forza lavoro dedicata al settore dell elaborazione dei dati e se andavi a lavorare lì non avevi speranza: era COBOL a pranzo e cena! Appena possibile le scuole si sono liberare da questo fardello, perché? A mio giudizio le cause sono diverse ma fra le principali non mancano le seguenti: - una pretesa di modernità, visto che ad un certo punto, come detto prima, se parlavi di COBOL venivi deriso; - la mancanza di insegnanti preparati unita ad una certa difficoltà, peraltro obiettiva, di insegnare la programmazione usando questo linguaggio; - la diffusione del Personal Computer e la conseguente diffusione di linguaggi più semplici, anche e meno potenti, come ad esempio il Basic. Delle tre a mio giudizio l ultima è quella chiave: se trovi il Basic nella macchina finirai per usare solo quello! Che dire della difficoltà di apprendimento della quale il linguaggio è stato accusato? Il problema nasce tutto dalla sua prolissità. Infatti il COBOL nasce con intenti molto ambiziosi come la cross-compilation ad esempio; è possibile sviluppare su un sistema e trasferire su un altra macchina, purché supportata. Il contesto dove viene messo a punto è quello dei sistemi mainframe e mini dipartimentali e soprattutto per i primi la cross-compilation è essenziale. La pesantezza della sintassi viene, diciamo così, aggravata dalla ricchezza delle estensioni. Una istruzione può essere usata in forma semplice ma può essere estremamente strutturata per svolgere molteplici compiti, essenzialmente di tipo ripetitivo. Facciamo un esempio per capire meglio questo punto. Prendiamo l istruzione di addizione che si può scrivere con l seguente sintassi: ADD A TO B. che tradotto sarebbe somma il contenuto della variabile A con il contenuto della variabile B e metti il risultato in B. Qualcosa come: B = B + A Per incrementare un contatore di una unità si userebbe: ADD 1 TO INDICE Fino a qui nulla di particolarmente sconvolgente, la sintassi è leggermente diversa rispetto ai linguaggi correnti che per la maggior parte 6

utilizzano una notazione tipo formula, che fra l altro è possibile utilizzare anche in COBOL scrivendo l istruzione precedente come: COMPUTE IND = IND + 1. E se dobbiamo sommare una serie di numeri? ADD N1 N2 N3 TO RIS. ADD 123,67 TO R1 ROUNDED R2 R3. Ancora, è anche possibile che non si voglia sporcare il valore dell operando ottenendo un comportamento più classico che prevede lo store del risultato in una variabile a parte. Per fare ciò si usa una variante dell istruzione ADD: Che, come avrete certo capito significa: ADD IMPORTO IVA GIVING IMPORTO-IVATO. RIS = RIS + N1 + N2 + N3 Ma le possibilità non si esauriscono qui. Consideriamo lo statement seguente: ADD A1 A2 A3 TO B1 B2 B3 B4. Questa sintassi è meno intuibile e significa: somma i valori A1, A2 e A3 poi aggiungi questo risultato alle variabile B1, B2, B3 e B4. Ovviamente è sempre possibile espandere l istruzione in più statement ottendeno ad esempio: ADD A1 A2 A3 TO R. ADD R TO B1. ADD R TO B2. ADD R TO B3. ADD R TO B4. Qualcuno degli operandi che accoglieranno il risultato possono essere arrotondati aggiungendo la specifica opzione ROUNDED dopo i nome, come in: Si capisce che la sintassi del linguaggio è molto articolata e questo mette sicuramente in difficoltà chi cerchi di utilizzarlo leggendo un manuale. L istruzione MOVE è l esempio più eclatante, se vogliamo, ad onta della sua semplicità (serve per caricare i valori nelle variabili), infatti essa è ricchissima di varianti, al punto che le pagine dei manuali ad essa dedicata scoraggiano il malcapitato che volesse imparare il linguaggio da autodidatta basandosi solo sulla documentazione tecnica. L istruzione MOVE carica i valori nelle variabili, come in: MOVE 1 TO INDICE. MOVE N1 TO R2. Niente di più semplice, apparentemente. Però qualsiasi manuale COBOL che ne riporta la descrizione e sintassi completa occuperà pagine e pagine! Un altro aspetto del linguaggio può essere chiamato in causa per 7

giustificarne la difficoltà di apprendimento, ed è la sintassi rigida detta in gergo informatico a campi. Significa che ogni elemento del linguaggio deve stare in certe zone definite della riga. Retaggio derivato dall uso delle schede perforate come la lunghezza di 72 caratteri massima e la necessità di distinguere fisicamente gli elementi di un programma. Per creare un programmatore COBOL professionista una azienda deve essere disposta ad investire almeno tre anni di formazione/ affiancamento e questo oggigiorno viene considerato un costo, piuttosto che un investimento. C è da dire un ultima cosa sull uso del linguaggio, che è la seguente: pochi, se non addirittura pochissimi, programmatori utilizzano la ricchezza sintattica del linguaggio. Nel tempo si è creato in tutte le aziende una sorta di lessico famigliare, per dirla alla Gizburg, che prevede l utilizzo di costrutti il più elementare possibile, anche per una ragione di manutenzione del software stesso. Le nuove generazioni di programmatori e i tempi di consegna sempre più stringenti non lasciano speranze di procedere altrimenti. Forse esiste un assioma che implica la longevità di un linguaggio di programmazione direttamente correlata con la ricchezza sintattica. Succede che all inizio esce una versione spartana e minimale, poi a furia di aggiungere features si finisce per snatuare l idea originale e si rende la curva di apprendimento sempre più ripida e lunga. Autorevoli esempi li troviamo nel Perl, nel PHP e nel Basic. Dovuta alla ricchezza della sintassi deriva la difficoltà nel costruire un compilatore, aumentata dal fatto che il linguaggio possiede obbligatoriamente embedded capacità di gestione per i file indicizzati (che come vedremo nel prosieguo di questa serie è la vera forza del COBOL). I compilatori professionali sono costosi e inizialmente indisponibili sulle piattaforme micro, con la lodevole eccezione dei sistemi che supportano il CP/M. La diffusione del personal computer in ambito professionistico ha cambiato molto le cose. In fondo una rete di PC vale quanto un mainframe (non sempre, ma è un discorso che ci porterebbe lontano). Per quanto accennato sopra il COBOL si è fatta una cattiva fama e gli ambienti, diciamo così, progressisti non hanno esitato a vituperarne l utilizzo. Se questo è stato un bene o il contrario non sta a me decidere. Da un lato si è persa una professionalitè elevata, dall altro i nuovi idiomi, più facili all approccio, hanno permesso a molte persone l avvicinarsi alla programmazione. Ci sono dei pro e dei contro, come in tutte le cose. Dopo questa lunga ma doverosa panoramica sulla filosofia del linguaggio COBOL veniamo a parlare di cose pratiche. Prima di tutto 8

bisogna procurarsi un compilatore se si vuole seguire con profitto il corso che proponiamo. - Bravo! E dove ne trovo uno?. Tranquilli, è più semplice di quanto si creda. Rivolgendosi all Open Source è possibile recuperare un buon compilatore che gira con GCC (che erroneamente viene considerato un compilatore di codice C, in realtà è uno dei cross compiler più flessibili che ci sono in giro). Se decidete di seguire questa strada il prodotto si chiama OpenCobol e si possono scaricare i sorgenti da questo link: http://www.opencobol.org/modules/mydownloads/ Scelte alternative possono essere le versioni datate che qualche utente a volte svende (anche se teoricamente non sarebbe legalmente ineccepibile) su ebay. La Microsoft ha commercializzato per un certo tempo un compilatore per Windows chiamato Microsoft COBOL. Altra ditta specializzata è la MicroFocus che costruisce compilatori per tutte le piattaforme ed ha anche una versione educational molto bella chiamata Personal COBOL che viene venduta in libreria (non in Italia). Si veda la prova software in questo fascicolo. Un compilatore molto diffuso all epoca delle reti Novell era un certo MBP COBOL, prodotto da una ditta tedesca (la MBP, appunto), il cui acronimo non chiedetemi per cosa sta :-). Una fonte alternativa ma molto valida è fornita dal retro computing (se no che ci staremmo a fare?). E possibile che se il vostro retro computer preferito supporta il CP/M, troviate in giro le immagini di un compilatore. magari non sarà una scheggia, ma che importa? Ad esempio per Apple IIe sotto CP/M la Microsoft (sì, sempre lei) ha commercializzato un compilatore chiamato COBOL-80, elemento di una serie di prodotti il cui esponente più famoso è il BASIC-80. Su SurgeForce.org si possono reperire vari progetti che hanno a che fare con l argomento. Uno di questi propone un compilatore minimale per Windows, chiamato Tiny Cobol. Lo abbiamo scaricato e provato trovandolo per la verità non troppo esaltante... Ancora, all indirizzo: http://www.netcobol.com/products/windows/netcobol.html si trova un prodotto commerciale chiamato NETCobol, adatto all ambiente.net che sfrutta la IDE di Visual Studio. Ne esiste anche una versione Student, se volete provarci... Insomma non ci sono scuse del tipo non trovo un compilatore in giro :-) 9

10 Il primo programma A seconda dell ambiente operativo che avete scelto dovete cominciare a scrivere il sorgente dei programmi. Alcuni tools prevedono un input guidato, ad esempio con i tab impostati per muoversi fra le varie zone nelle quali è divisa la riga. Vi ricordo che i primi sei catarreri della riga sono riservati alle label. Il settimo carattere contiene un eventuale controllo di riga: il simbolo - per la continuazione dalla riga precedente, * per una riga di commento (da qui il verbo asteriscare che usano i veri programmatori), / per ordinare il salto pagina alla stampante sulla quale andiamo a ottenere il listing del sorgente. Dall ottavo carattere inizia la ZONA A e al 12 carattere la ZONA B. Il primo programma è visibile nel riquadro Listato 1 che ora andiamo ad eseminare in dettaglio. 0-----78---2-------2---------3---------4--- -------AAAABBBBBBBBBBBBBBBBBBBB... IDENTIFICATION DIVISION. PROGRAM-ID HELLOWORLD. ENVIRONMENTAL DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. DECIMAL POINT IS COMMA. DATA DIVISION. PROCEDURE DIVISION. MAIN SECTION. INIZIO. DISPLAY HELLO WORLD. Abbiamo scritto il classico programma hello World e come si vede l idea della prolissità colpisce abbastanza. Rispetto ad un Basic che con una semplice istruzione: 10 PRINT HELLO WORLD avrebbe fornito lo stesso risultato, in COBOL sono state necessarie molte più righe. L utilità dell organizzazione del sorgente con molte parti dichiarative sarà molto più chiara nel prosieguo del corso che abbiamo per ora solo introdotto. C è da dire comunque, a consolazione di chi si è spaventato da subito, che i programmatori si limitano fare un copia incolla da un template. Oserei dire che moltissimi di essi nemmeno sarebbero capaci di scrivere da zero l intera parte dichiarativa: semplicemente non la possono ricordare, dopo anni che non se ne preoccupano! Esaminando il primo sorgente evidenziamo gli aspetti essenziali del linguaggio. Prima di tutto il token di chiusura di uno statement è il punto e ogni riga, come si diceva, deve concludersi entro 72 caratteri, punto compreso. La regola dei compilatori è ignorare tutto ciò che eccede il 72-simo carattere. Il sorgente è diviso in DIVISION che ne indi-

viduano le quattro parti principali. L IDENTIFICATION DIVISION come dice il nome è deputata a contenere delle meta-istruzioni che servono all identificazione del programma. Una di queste informazioni è il nome del programma stesso la cui composizione segue le regole dell ambiente operativo. Non necessariamente il PROGRAM-ID corrisponde al nome del binario compilato sul file system, esso è un nome interno al quale fare riferimento ad esempio se il sorgente fosse in una libreria di funzioni. La ENVIRONMENT DIVISION specifica l ambiente dove il programma viene sviluppato rispetto alla sua destinazione finale. Ricordate che il COBOL è crossplatform? In ambiente Personal Computer queste specifiche hanno ormai poco senso e anzi i compilatori sono stati di fatto alleggeriti della capacità di compilare per diversa piattaforma. Rimane quindi sostanzialmente una divisione figurativa che serve al più per specificare alcune particolarità che si intendono usare, come ad esempio l utilizzo della virgola come separatore dei decimali. La DATA DIVISION non è altro che la parte di sorgente dove si dichiarano le variabili. In COBOL variabili e costanti devono essere dichiarate tutte in questa divisione dove trovano posto anche altre strutture informative come ad esempio i file sequenziali o con chiave, le specifiche di ordinamento, etc... Infine la PROCEDURE DIVISION ospita il codice che viene organizzato in sezioni. Tradizionalmente si nomina la prima sezione MAIN SECTION, anche se il nome MAIN non è obbligatorio (potrebbe essere chiamata INIZIO o qualsiasi altra cosa piaccia). Poi abbiamo inserito anche la parola INIZIO che funge da label. Si usa, ma anche questo non è obbligatorio. Per completare la disamina del primo sorgente diciamo che l istruzione DISPLAY stampa a video una costante letterale (è il nostro caso) o il valore di una variabile. Il programma viene eseguito dalla prima sezione che si incontra fino al termine della stessa o fino alla conclusione del sorgente. Esiste una specifica istruzione STOP PRO- GRAM o semplicemente STOP che conclude l elaborazione. Tradizionalmente i sorgenti vengono scritti in maiuscolo in omaggio ai vecchi terminali dei mainframe anni 60. I compilatori oggigiorno accettano anche il minuscolo che negli ultimi anni è diventata una pratica seguita da moltissimi programmatori, specialmente se appartenenti alle nuove generazioni, abituati ai linguaggi correnti. Il Cobol rimane però unsensitive, come il Basic: non distingue fra maiuscole e minuscole. Pur esistendo qualche approccio alla pratica dell interpretazione, il COBOL nasce come linguaggio 11

compilato. La rigida organizzazione dei sorgenti è a supporto della creazione del codice binario. Il COBOL si presenta quindi praticamente sempre con la classica configurazione di sviluppo editorcompilazione-esecuzione. L ambiente di eccellenza per l esecuzione di programmi COBOL è l interfaccia a caratteri, proprio per la forma spartana dell I/O tipica del linguaggio. Come abbiamo detto nell introduzione non mancano comunque implementazioni a finestre realizzate con opportune estensioni del linguaggio stesso che dimostra una certa dose di adattabilità grazie soprattutto alle estensioni ad-hoc che le aziende produttrici vi inseriscono a forza per dare al loro prodotto una parvenza di modernità. Già dalla nascita comunque è stata prevista una sorta di gestione a form del video. Una specifica SECTION, esattamente la SCREEN SEC- TION, è deputata alla descrizione dell interfaccia. Il bubble sort in COBOL Un esempio più articolato è riportato per intero nei box delle pagine seguenti. Si tratta di una implementazione dell algoritmo classico di bubble sort. Penso sia noto a tutti il meccanismo di questo semplice algoritmo di ordinamento: si tratta di spostare degli elementi in un vettore effettuando dei ripetuti scambi con gli elementi adiacenti fino ad ottenere un vettore ordinato. Maggiori approfondimenti si possono trovare sul fascicolo numero 1 di Jurassic News. Commentiamo ora le righe che incontriamo nel sorgente per introdurre le novità rispetto a quanto visto finora. Nella WORKING-STORAGE SECTION abbiamo dichiarato due costanti (in realtà non esiste una dichiarazione speciale per variabili immodificabili, il fatto che siano costanti lo decidiamo noi). 01 MAX COMP-1 VALUE 3. 01 LIMITE COMP-1 VALUE 10000. Il tipo COMP-1 è il classico Integer che occupa una o più coppie di byte a seconda dell implementazione del compilatore. Sono variabili numeriche senza una definizione di formato. A cominciare dalla variabile VET- TORE abbiamo il primo esempio di variabile strutturata. VETTORE è il nome della nostra variabile dichiarata a livello 01 che contiene un sotto-livello, individuato dal livello 12

05 che ne rappresenta il contenuto strutturato. 01 VETTORE. 10 ELEMENTO COMP-1 OCCURS 1000. 01 VETTORE. 05 EL-VETTORE COMP-1 OCCURS 10000. EL-VETTORE è vettore di 10.000 elementi di tipo COMP-1. Quando in una istruzione ci si riferisce alla variabile VETTORE si sta parlando dell intera struttura; quando ci si riferisce a EL-VETTORE si sta parlando di una componente che andrà individuata tramite il classico meccanismo degli indici: MOVE 12 TO EL-VETTORE(34) In questo specifico caso, cioè nella necessità di dichiarare vettori o matrici la strutturazione è obbligatoria. Infatti lo standard prevede che una variabile di livello 01 non possa essere indicizzata. C è un motivo pratico per questo: il livello 01 indica al compilatore anche la classe di storage della variabile, cioè i livelli 01 sono immagazzinati a partire dall indirizzo intero di memoria, cosa che non succede per i sotto-livelli. Se avessimo ad esempio un ambiente a 64 bit, quindi con word di quattro byte e il tipo COMP-1 fosse un intero da due byte, allora ogni dichiarazione di COMP-1 a livello 01 occuperebbe comunque una word, sprecando due byte di memoria. Una dichiarazione 01 VETTORE COMP-1 OCCURS 1000 occuperebbe 4000 byte di memoria, contro i 2000 occupati dalla dichiarazione: Un altro esempio di variabile strutturata è quella che contiene un orario: 01 ORA. 05 ORA-HH COMP-1. 05 ORA-MM COMP-1. 05 ORA-SS COMP-1. 05 ORA-CC COMP-1. In questo caso quattro variabili semplici di tipo COMP-1 sono raggruppate al solo fine di chiarezza, ma verranno elaborate singolarmente. Nella dichiarazione della variabile TOT-SECONDI troviamo un altra forma di dichiarazione di variabile numerica. 01 TOT-SECONDI PIC 9(12)V9(2) VALUE ZERO. PIC 9(12)V9(2) significa 12 cifre intere seguite da due decimali. Passiamo ora alla desamina del codice premettendo che esso è stato strutturato in maniera molto spinta (tipo Pascal per intenderci) cercando di introdurre i concetti di esecuzione dei singoli pezzi come fossero parti staccate (procedure o funzioni). INIZIO. * --- loop iterazioni PERFORM ESEGUI THRU ESEGUI-EXIT MAX TIMES. * --- calcolo della media COMPUTE MEDIA = TOT-SECONDI / MAX. * --- display dei risultati. DISPLAY TOTALE SECONDI IMPIEGATI: TOT-SECONDI. DISPLAY 13

IDENTIFICATION DIVISION. 14 PROGRAM-ID. BUBBLE. *********************************** * Titolo : Bubble Sort *********************************** DATE-WRITTEN. DATE-COMPILED. DIC/97. GEN/98. *********************************** ENVIRONMENT DIVISION. *********************************** CONFIGURATION SECTION. *---------------------------------- SOURCE-COMPUTER. PENTIUM-PC166. OBJECT-COMPUTER. PENTIUM-PC166. SPECIAL-NAMES. DECIMAL-POINT IS COMMA. /********************************** DATA DIVISION. *********************************** WORKING-STORAGE SECTION. *********************************** * ---- costanti 01 MAX COMP-1 VALUE 3. 01 LIMITE COMP-1 VALUE 10000. * --- variabili 01 VETTORE. 05 EL-VETTORE COMP-1 OCCURS 10000. 01 I COMP-1. 01 SCAMBI COMP-1. 01 TOT-ITERAZIONI PIC 9(12). 01 J COMP-1. 01 TOT-SCAMBI PIC 9(12). 01 TEMP COMP-1. 01 ORA. 05 ORA-HH COMP-1. 05 ORA-MM COMP-1. 05 ORA-SS COMP-1. 05 ORA-CC COMP-1. 01 ORA-I. 05 ORA-I-HH COMP-1. 05 ORA-I-MM COMP-1. 05 ORA-I-SS COMP-1. 05 ORA-I-CC COMP-1. 01 ORA-F. 05 ORA-F-HH COMP-1. 05 ORA-F-MM COMP-1. 05 ORA-F-SS COMP-1. 05 ORA-F-CC COMP-1. 01 TOT-SECONDI PIC 9(12)V9(2) VALUE ZERO. 01 MEDIA PIC 9(5)V9(2) VALUE ZERO. 01 DIFF-SECONDI PIC 9(12). 01 SECONDI-INIZIALI PIC 9(12). 01 SECONDI-FINALI PIC 9(12). * ---- Variabili per il generatore di numeri casuali 01 MODULO COMP-1 VALUE 36456. 01 MOLTIPLICATORE COMP-1. 01 INCREMENTO COMP-1. 01 SEME COMP-1. /**************************************** PROCEDURE DIVISION. **************************************** MAIN SECTION. **************************************** INIZIO. **************************************** * --- loop iterazioni PERFORM ESEGUI THRU ESEGUI-EXIT MAX TIMES. * --- calcolo della media COMPUTE MEDIA = TOT-SECONDI / MAX. * --- display dei risultati. DISPLAY TOTALE SECONDI IMPIEGATI: TOT-SECONDI. DISPLAY MEDIA PER VETTORE : MEDIA USCITA. STOP RUN. ESEGUI. PERFORM CARICA-VETTORE THRU CARICA-VETTORE-EXIT. * --- esecuzione sort CALL GTIME USING ORA-I. display ora iniziale: ORA-I-HH : ORA-I-MM : ORA-I-SS : ORA-I-CC. MOVE 1 TO SCAMBI. PERFORM LOOP-SCAMBIO THRU LOOP-SCAMBIO-EXIT UNTIL SCAMBI IS EQUAL ZERO. CALL GTIME USING ORA-F. display ora finale : ORA-F-HH : ORA-F-MM : ORA-F-SS : ORA-F-CC. MOVE ZERO TO DIFF-SECONDI. PERFORM CALCOLA-SECONDI THRU CALCOLA-SECONDI-EXIT. COMPUTE TOT-SECONDI = TOT-SECONDI + (DIFF-SECONDI / 100). DISPLAY TOTALE SECONDI : TOT-SECONDI. ESEGUI-EXIT. EXIT. LOOP-SCAMBIO. MOVE ZERO TO SCAMBI. PERFORM CONFRONTA THRU CONFRONTA-EXIT

LOOP-SCAMBIO-EXIT. EXIT. CONFRONTA. VARYING I FROM 1 BY 1 UNTIL I = LIMITE. IF EL-VETTORE( I + 1 ) IS < EL-VETTORE( I ) MOVE EL-VETTORE( I + 1 ) TO TEMP MOVE EL-VETTORE( I ) TO EL-VETTORE( I + 1 ) MOVE TEMP TO EL-VETTORE( I ) MOVE 1 TO SCAMBI. CONFRONTA-EXIT. EXIT. CARICA-VETTORE. CALL GTIME USING ORA. COMPUTE MOLTIPLICATORE = ORA-SS * ORA-MM. COMPUTE SEME = ORA-CC * ORA-SS. COMPUTE INCREMENTO = ORA-CC * ORA-MM. PERFORM NUMERO-RANDOM THRU NUMERO-RANDOM-EXIT VARYING I FROM 1 BY 1 UNTIL I > LIMITE. CARICA-VETTORE-EXIT. EXIT. NUMERO-RANDOM. MOVE SEME TO EL-VETTORE(I). COMPUTE SEME = (MOLTIPLICATORE * SEME + INCREMENTO). COMPUTE SEME = MODULO - (SEME / MODULO) * SEME. IF SEME < 0 COMPUTE SEME = -SEME. NUMERO-RANDOM-EXIT. EXIT. CALCOLA-SECONDI. * --- calcola il numero di secondi occorsi fra i due orari. COMPUTE SECONDI-INIZIALI = ORA-I-HH * 3600 + ORA-I-MM * 60 + ORA-I-SS. COMPUTE SECONDI-INIZIALI = SECONDI-INIZIALI * 100 + ORA-I-CC. COMPUTE SECONDI-FINALI = ORA-F-HH * 3600 + ORA-F-MM * 60 + ORA-F-SS. COMPUTE SECONDI-FINALI = SECONDI-FINALI * 100 + ORA-F-CC. COMPUTE DIFF-SECONDI = SECONDI-FINALI - SECONDI-INIZIALI. CALCOLA-SECONDI-EXIT. EXIT. 15

MEDIA PER VETTORE: MEDIA. USCITA. STOP RUN. C è una iterazione iniziale che richiama la sezione ESEGUI. La sintassi PERFORM ESEGUI THRU ESEGUI- EXIT MAX TIMES. Significa: esegui un numero di iterazioni pari al valore contenuto in MAX (che abbiamo dichiarato nella Working al valore 10.000) delle istruzioni comprese nella sezione INIZIO per finire con quelle nella sezione ESEGUI-EXIT. Fatta questa iterazione c e un calcolo dei secondi medi impiegati, la stampa a video dei risultati e l uscita dal programma. La sezione ESEGUI, che abbiamo visto viene iterata 10.000 volte, per avere un risultato medio attendibile, prevede i seguenti passaggi: caricamento del vettore con numeri pseudo-casuali, la rilevazione del tempo iniziale, il sort del vettore, la rilevazione del tempo impiegato. L algoritmo di ordinamento vero e proprio è costituito dai seguenti statement: MOVE 1 TO SCAMBI. PERFORM LOOP-SCAMBIO THRU LOOP-SCAMBIO-EXIT UNTIL SCAMBI IS EQUAL ZERO. Se vi è chiaro come procede il bubble sort, semplicemente si continua a fare scambi di elementi fino a che una spazzolatura finale del vettore non da luogo a nessuno scambio. Le istruzioni di iterazione innescate dall istruzione PERFORM vengono eseguite continuamente fino a che non si verifica la condizione descritta nell UNTIL. Si noti la sintassi usata per controllare la condizione di uscita. Si sarebbe potuto anche scrivere: UNTIL SCAMBI = 0 Concedendo un certo vantaggio ai programmatori moderni, ma perché dovremmo? La sintassi usata qui è molto più chiara per chi è avvezzo a leggere i sorgenti COBOL, infatti se ci pensate assomiglia molto di più ad una sintassi letterale. E dimostrato inoltre che molti errori di codifica nei programmi derivano dalla scrittura di condizioni al contorno errate dovute ad una errata interpretazione delle specifiche o all impiego di operatori di confronto simbolici che richiedono un quid di attenzione maggiore a chi codifica. Il caricamento dei dati nel vettore avviene nella form CARICA-VET- TORE chiamata dallo statement: PERFORM CARICA-VETTORE THRU CARICA-VETTORE-EXIT. Essa contiene un loop che interessa uno ad uno gli elementi del vettore e vi inserisce un numero pseudo-casuale. L istruzione che effettua il loop di caricamento è la seguente: PERFORM NUMERO-RANDOM THRU NUMERO-RANDOM-EXIT VARYING I FROM 1 BY 1 UNTIL I > LIMITE. 16

Questa sintassi prevede l incremento automatico di un indice rappresentato dalla variabile I che viene incrementato partendo dal valore 1 fino a superare il limite previsto, che è la dimensione del vettore stesso. Implicitamente abbiamo introdotto un ulteriore concetto: le variabili indicizzate hanno indice che inizia da 1. Il cuore dell algoritmo di bubble sort è contenuto nella form CON- FRONTA: CONFRONTA. IF EL-VETTORE( I + 1 ) IS < EL-VETTORE( I ) MOVE EL-VETTORE( I + 1 ) TO TEMP MOVE EL-VETTORE( I ) TO EL-VETTORE( I + 1 ) MOVE TEMP TO EL-VETTORE( I ) MOVE 1 TO SCAMBI. CONFRONTA-EXIT. EXIT. Qui si vede come l indicizzazione delle variabili avviene indicando l elemento con indice fra parentesi, eventualmente calcolando il valore stesso dell indice. Gli operatori di confronto in CO- BOL sono quelli classici: =, <, >, >=, <=, <>. Esiste tuttavia una forma letterale di questi operatori: altri linguaggi. Una particolarità che vale la pena spiegare è l utilizzo dello statement MOVE 1 TO SCAMBI All interno della form di confronto. Un valore diverso da zero della variabile SCAMBI serve per ordinare un ulteriore loop sugli elementi del vettore. Infatti l algoritmo si basa proprio sull iterazione dei confronti elemento per elemento del vettore fino a che un ultima iterazione non effettua alcuno scambio, segno che il vettore è ordinato. Non sarebbe stato meglio incrementare il valore di SCAMBI con una istruzione del tipo: ADD 1 TO SCAMBI In effetti se servisse anche tracciare quanti scambi vengono fatti in ogni iterazione, allora l istruzione di incremento sarebbe stata necessaria. In caso contrario è inutile una istruzione matematica, che consuma certo più tempo, rispetto ad una istruzione di assegnazione. = IS EQUAL > IS GREATHER THAN < IS LESS THAN >= IS GREATHER OR EQUAL, IS NOT LESS <= IS LESS OR EQUAL, IS NOT GREATHER <> IS NOT EQUAL La forma prolissa della sintassi è poco usata attualmente, dato che le nuove generazioni di programmatori sono ormai abituate alle forme matematiche più simili agli 17

Listato 1 L uso di variabili strutturate, come matrici e vettori, è incoraggiata in COBOL. C è chi addirittura struttura tutto, perfino i semplici contatori interi. Qualcosa come: 01 CONTATORE. 10 CONT PIC COMP-1. La multidimensionalità si ottiene inserendo una dichiarazione strutturata in un altra. Ecco un esempio: 01 MATRICE. 10 RIGA-MATRICE OCCURS 100. 20 EL-MATRICE PIC 9(5) OCCURS 100. Qui abbiamo dichiarato una matrice di dimensione 100 per 100 i cui elementi sono dei valori numerici di cinque cifre. E c c o un loop che carica gli elementi della matrice c o m e f o s s e una tavola pitagorica (listato 1). /**************************************** PROCEDURE DIVISION. **************************************** MAIN SECTION. **************************************** INIZIO. **************************************** PERFORM SCAN-RIGHE THRU SCAN-RIGHE-EXIT VARYING RIGA FROM 1 BY 1 UNTIL RIGA <= 10. USCITA. STOP RUN. SCAN-RIGA. PERFORM SCAN-COL THRU SCAN-COL-EXIT VARYING COLONNA FROM 1 BY 1 UNTIL COLONNA <= 10. SCAN-RIGHE-EXIT. EXIT. SCAN-COL. COMPUTE EL-MATRICE(RIGA, COLONNA) = RIGA * COLONNA. SCAN-COL-EXIT. EXIT. Variabili strutturate Un alt r o aspetto legato alla strutturazione del dato è la possibilità di ridefinire la memoria indirizzata da una variabile in modo che questa sia usabile con due o più nomi. Ad esempio: 01 CODICE. 02 COD-FIS PIC X(16). 02 PARTITA-IVA REDEFINES COD-FIS. 05 P-IVA PIC 9(12). 05 FILLER X(4). Incontriamo per la prima volta una parola chiave molto usata nella definizione delle variabili strutturate del COBOL: FILLER. Questa viene utilizzata come riempitivo. Nel nostro esempio, dato che la ridefinizione di un area di memoria deve essere coerente, cioè utilizzare tutto lo spazio, riempiamo con un nome simbolico FILLER quella parte di dato che nel caso stessimo trattando una partita IVA non ci interessa. E chiaro che COD-FIS e PARTI- TA-IVA condividono lo stesso spazio di memoria, è lo stesso meccanismo implementato con le union nel linguaggio C. Nel listato numero 2 riportiamo un esempio di definizione di un record anagrafico che contiene un po tutte le cose viste finora nella definizione dei tipi di dato in COBOL. 01 REC-ANAG. è la definizione del livello base, appunto 01, che identifica l inizio di un dato strutturato. 05 TIPO-RECORD PIC XX. è un tipo di secondo livello di formato due caratteri alfanumerici. 18

05 MATRICOLA. 10 NUMERO PIC 9(5). 10 CONTROLLO PIC X. MATRICOLA è un dato strutturato formato da due sotto-livelli che nell esempio sono identificato dal numero di livello 10. Ci si potrà riferire a questo dato indicando il singolo sotto-livello o il dato intero MATRICOLA. Ad esempio: MOVE 12345A TO MATRICOLA. MOVE 12345 TO NUMERO. MOVE A TO CONTROLLO. I due campi GENERALITA e NO- MINATIVO sono ridefiniti, cioè identificano la stessa locazione di memoria per una lunghezza di 50 caratteri alfanumerici. Mentre GE- NERALITA è stato sotto specificato in due sottocampi NOME e CO- GNOME, il campo NOMINATIVO, che possiamo pensare come un alias del campo GENERALITA, è definito come unico. Seguono tre livelli chiamati rispettivamente NASCITA, ASSUNZIONE e DIMISSIONI. Tutti e tre contengono una data definita con sottocampi che hanno lo stesso nome: ANNO, MESE e GIORNO. 10 DATA-NASCITA. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 GIORNO PIC 99. 10 DATA-ASSUNZIONE. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 ANNO PIC 99. 10 DATA-DIMISSIONI. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 ANNO PIC 99. Come si fa a riferirsi ad un particolare anno, mese o giorno? Purtroppo il COBOL non prevede un meccanismo di dereferenziazione del dato, come succede nei linguaggi di programmazione più moderni. Ad esempio nel C si usa il punto come separatore e indicatore di riferimento per il cosidetto Spazio di validità del dato. In C si scriverebbe qualcosa come: REC-ANAG.ASSUNZIONE.DATA-ASSUN- ZIONE.ANNO = 1975. Dato che il COBOL non dispone di questo meccanismo è fortemente consigliato differenziare i nomi dei campi in maniera nativa, cioè chiamandoli diversamente. Quando questo non è possibile si ricorre alla clausula OF come nell esempio seguente: MOVE 1975 TO ANNO OF DATA-NA- SCITA. Sembra complicato ma non lo è a f f a t t o, a n c h e considerando che la sintassi mantiene una o t t i m a leggibilità. Nel record che abbiamo esam i n a t o c o m e Listato 2 01 REC-ANAG. 05 TIPO-RECORD PIC XX. 05 MATRICOLA. 10 NUMERO PIC 9(5). 10 CONTROLLO PIC X. 05 GENERALITA. 10 NOME PIC X(25). 10 COGNOME PIC X(25). 05 NOMINATIVO REDEFINES GENERALITA. 10 FILLER PIC X(50). 05 SESSO PIC X. 05 NASCITA. 10 DATA-NASCITA. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 GIORNO PIC 99. 10 LUOGO-DI-NASCITA. 15 CITTA PIC X(25). 15 CAP PIC Z(5). 15 PROVINCIA PIC XX. 15 NAZIONE PIC X(25). 05 ASSUNZIONE. 10 DATA-ASSUNZIONE. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 ANNO PIC 99. 05 DIMISSIONI. 10 DATA-DIMISSIONI. 15 ANNO PIC 9999. 15 MESE PIC 99. 15 ANNO PIC 99. 19

esempio è presente una dichiarazione di USAGE PIC Z. Il tipo Z è un numerico che mantiene gli zeri non significativi. Serve nei casi in cui, come in questo, il valore numerico sia in realtà un alfabetico di sole cifre. Possiamo assegnare al campo il valore 00103 e la stampa ci mostrerebbe anche i due zeri leading, cioè davanti. Per chiudere il discorso sulla rappresentazione dei dati e cioè sull uso della specifica USAGE, che a volte viene omessa facciamo questo altri esempi significativi: USAGE IS PIC 9(5)V99. E in valore numerico con segno con cinque cifre intere e due cifre decimali. USAGE IS PIC AAAXX999. E un campo misto lungo otto caratteri dei quali i primi tre sono alfabetici (solo lettere), seguono due caratteri alfanumerici (lettere e numeri) e infine tre caratteri numerici. Infine USAGE IS PIC A(5)9(3)X(2). E un valore che contiene cinque caratteri alfabetici, seguiti da tre cifre ed infine due ulteriori caratteri alfanumerici. La clausula PICTURES, abbreviata in PIC, serve anche per definire una rappresentazione del dato su video al momento dell output o della stampa. PIC 999.999.999. indica che vogliamo una rappresentazione con numeri di separazione per le migliaia. PIC 999-. indica che il dato è rappresentato con il segno alla fine (trailing), un uso molto comune nelle liste di cifre dei bilanci e il simbolo sarà un meno se il dato è negativo, uno spazio altrimenti. PIC 999+. indica che vogliamo il segno in coda al numero ma questa volta il segno esisterà sia per i valori positivi che per quelli negativi. C è un altra forma possibile per la rappresentazione dei valori positivi e negativi, anche se non molto usata in Italia, ed è quella di indicare due lettere CR che starebbe per credito e DB per debito. PIC 999CR. PIC 999DB. La stampa di CR e DB avviene solo se il dato è negativo e non come si potrebbe pensare DB se negativo e CR se positivo. PIC 999Z. sta ad indicare che vogliamo stampare la cifra zero a fronte di un valore nullo. Nell assegnazione dei valori sono consentite delle abbreviazioni e l uso di due costanti figurative per lo spazio (blank) e per lo zero. VALUE IS ZERO. VALUE IS ZEROES. VALUE IS SPACE. 20