Oberon | |
---|---|
Jazyková třída | imperativní , strukturovaný , modulární |
Objevil se v | 1986 |
Autor | Niklaus Wirth |
Typový systém | statický , silný |
Byl ovlivněn | Modula-2 , Pascal |
ovlivnil | Active Oberon , Component Pascal , Go , Java [1] [2] , Modula-3 , Oberon-2 , Zonnon , Nim |
Licence | BSD |
webová stránka | projectoberon.com |
Oberon je vysokoúrovňový programovací jazyk navržený Niklausem Wirthem pro spouštění programů na stejnojmenném operačním systému , jehož autory jsou Niklaus Wirth a Jürg Gutknecht .
Programy napsané v programovacím jazyce Oberon vyžadují určitou podporu za běhu – potřebují dynamický zavaděč a centrálně spouštěný automatický garbage collector, k čemuž programy Oberon potřebují speciální operační prostředí. Obvyklým způsobem implementace je přidat do systému sadu knihoven, které implementují potřebné komponenty, ačkoli obecně operační prostředí nutně nepotřebuje samostatný operační systém: může to být samo o sobě operační systém. Jedná se o systémy Native Oberon pro původní Oberon a A2 pro Active Oberon . V současné době existují kompilátory Oberon pro bytecode Java Virtual Machine a CLI pro .NET Virtual Machine .
Operační systémy a prostředí pro spouštění programů v jazycích rodiny Oberon, které se vyvinuly z původního systému Oberon, jsou ETH Oberon, BlackBox Component Builder , WinOberon , A2 atd.
Oberon-0, Oberon-X a další projekty byly vyvinuty na základě Oberon [3] . Jednoduchost Oberonu a dostupnost zdrojových kódů původní implementace umožňují snadné přizpůsobení pro speciální třídy problémů. Ale všichni tito Oberonové mají k sobě velmi blízko, protože původní Oberon je velmi jednoduchý.
Programovací jazyk Oberon vytvořil Niklaus Wirth v roce 1988 na základě programovacích jazyků Modula-2 , Pascal a Algol-60 [4] .
Podle Wirtha původně chtěli napsat systém přímo na Modul, ale došli k závěru, že je potřeba jej zpřesnit a zredukovat, což vedlo k objevení Oberona [5] .
Cílem projektu ( Eng. Project Oberon ) Niklause Wirtha a Jürga Gutknechta v letech 1986-1989 [6] bylo vytvořit od základu viditelný a spolehlivý operační systém pro jednouživatelskou pracovní stanici.
Pro realizaci tohoto projektu navrhl Niklaus Wirth v roce 1988 univerzální vysokoúrovňový programovací jazyk, nazývaný také Oberon [7] .
V roce 1989 byla na ETH Zurich (ETH) vydána první implementace Oberonu pro rodinu procesorů NS32000 . Byl vytvořen jako součást operačního prostředí Oberon. Tento kompilátor vyžaduje méně než 50 KB paměti, skládá se ze 6 modulů o celkovém objemu cca 4000 řádků a sám se zkompiluje za 15 sekund na počítači s procesorem NS32532 (taktovací frekvence - 25 MHz).
Zavděčit se všem, kteří tak či onak svými nápady přiživili to, čemu se dnes říká Oberon, je prostě nemožné. Většina nápadů vzešla z používání a učení se z existujících jazyků, jako je Modula-2, Ada, Smalltalk a Cedar, které nás často varovaly před tím, co bychom neměli dělat.Niklaus Wirth [5]
Jazyk si zachoval hlavní rysy syntaxe Modula a byl rozšířením objektu . To umožnilo opustit mechanismus variantních záznamů Moduly, které jsou ústupem od původního silného statického typování , což umožnilo zavést automatický mechanismus správy paměti - garbage collection : možnost uvolnění dynamicky alokované paměti pomocí speciálního operátoru byl z jazyka vyloučen a místo toho samotný runtime obsahuje modul A, který vrací nevyužitou paměť do systému. Automatická správa paměti je prostředkem ke zlepšení spolehlivosti programů s dynamickými datovými strukturami, protože eliminuje lidské chyby, které jsou typické například pro jazyky jako C / C++ .
Aby bylo dosaženo co největší spolehlivosti a výkonnosti překladu, došlo k výraznému zjednodušení jazyka odstraněním prvků, které byly považovány za zbytečné (na základě zkušeností s vývojem, implementací a používáním jiných jazyků), buď komplikovaly kompilátor bez dostatečného zdůvodnění. z hlediska výkonu nebo byly dostatečně složité na to, aby mohly být dodány do externích knihoven, nebo nebyly kompatibilní s modularitou a mechanismy automatické správy paměti: variantní záznamy , výčtové typy , typy rozsahů , generické sady , typ celého čísla bez znaménka, lokální moduly, definiční moduly, export seznamy, operátor pro, dřívější verze příkazu with, speciální syntaxe pro definování hlavního programu. Základní prostředky podpory paralelního programování, které byly k dispozici v Modulu-2, se do jazyka nedostaly, protože sloužil operačnímu systému pro jednoho uživatele. Zpracování výjimek bylo kvůli jednoduchosti vypuštěno .
Popis polí byl zjednodušen (indexy polí mohou být pouze celá čísla a vždy začínat od nuly, jako jazyk C), použití ukazatelů je omezeno - ukazatele mohou existovat pouze na záznamech a polích, v importu je specifikován pouze importovaný modul seznamy a při použití importovaných názvů povinná kvalifikace (výslovné uvedení názvu modulu vývozce). V článku „From Modula to Oberon“ [5] , Wirth podrobně vysvětlil důvody pro odstranění každého z prvků.
Z důvodů „dostatečného minima“ nebyly metody (procedury a funkce spojené s typem) zahrnuty do jazyka jako explicitní syntaktický koncept, protože tento mechanismus ve své nejobecnější podobě lze snadno modelovat vytvořením polí procedurálního typu v objektů (záznamy v jazyce Oberon) a přiřazování jim procedur odpovídajících metodám. Objektově orientované programování je tedy v Oberonu podporováno s minimálními prostředky pro zjednodušení procesu překladu kódu a urychlení tohoto procesu.
Díky provedeným změnám se Oberon syntakticky zjednodušil. Popis jeho syntaxe se vešel na jednu stránku, úplný popis jazyka zabere asi 20 stran, což je o polovinu méně než popis Modula-2 . Oberon je, když ne minimální, tak alespoň jeden z nejmenších univerzálních vysokoúrovňových programovacích jazyků.
Einsteinův výrok byl vybrán jako epigraf k popisu původního Oberona: "Udělejte to tak jednoduché, jak je to možné, ale ne jednodušší než to . "
Definováno v následujících návrzích RBNF [8] :
Modul = MODULE id ";" [ ImportList ] Poslední deklarováno [ BEGIN Last Statements ] END id "." . ImportList = IMPORT [ id ":=" ] id { "," [ id ":=" ] id } ";" . LastDeclared = { CONST { DeclaredConst ";" } | TYPE { Typedeclaration ";" } | VAR { DeclaredVar ";" }} { DeclaredProc ";" | ForwardDeclared ";" }. DeclaredConst = IdentDef "=" ConstExpression . TypeDeclare = IdentDef "=" Typ . DeclaredVar = ListIdentifier ":" Typ . DeclaredProc = PROCEDURE [ Receiver ] IdentDef [ FormalParam ] ";" Naposledy deklarováno [ ZAČÁTEK Poslední prohlášení ] END Ident . ForwardDeclare = PROCEDURE "^" [ Receiver ] IdentDef [ FormalParam ]. FormalParam = "(" [ Sekce FP { ";" Sekce FP }] ")" [ ":" SpecIdent ]. SectionFP = [ VAR ] id { "," id } ":" Typ . Receiver = "(" [ var ] id ":" id ")" . Typ = QualID | ARRAY [ ConstExpression { "," ConstExpression }] OF Type | RECORD [ "(" QualIdent ")" ] FieldList { ";" FieldList } END | Ukazatel na typ | POSTUP [ FormalParam ]. FieldList = [ ListIdent ":" Typ ]. AfterOperators = Operátor { ";" Operátor }. Operátor = [ Zápis ":=" Výraz | Zápis [ "(" [ ListExpression ] ")" ] | IF Expr THEN Příkaz Seq { ELSIF Expr THEN Příkaz Seq } [ ELSE Příkaz Seq ] END | CASE výraz možnosti { " | " Varianta } [ ELSE StatementSeq ] END | WHILE Express DO Statement Seq END | REPEAT StatementSeq UNTIL Expression | LOOP AfterStatements KONEC | WITH Guard DO prohlášení Seq END | EXIT | RETURN [ Expresní ] ]. Option = [ Štítky možností { "," Štítky možností } ":" StatementLast ]. VariantLabels = ConstExpression [ ".." ConstExpression ]. Stráž = SpecId ":" SpecId . ConstExpression = Express . Výraz = SimpleExpression [ Relation SimpleExpression ]. SimpleExpression = [ "+" | "-" ] Termín { Termín OperSlog }. Termín \ u003d Multiplikátor { OperMul Multiplier }. Násobitel = Zápis [ "(" [ ListExpression ] ")" ] | číslo | symbol | řetězec | NIL | Set | "(" Výraz ")" | " ~ " Násobitel . Set = "{" [ Element { "," Element }] "}" . Element = Express [ ".." Express ]. Vztah = "=" | "#" | "<" | "<=" | ">" | ">=" | V | IS . OperaSlog = "+" | "-" | NEBO . OperaUmn = "*" | "/" | DIV | MOD | "&" . Označení = kvalifikátor { "." ident | "[" ListExpression "]" | "^" | "(" Kvalifikovaný ")" }. ListExpr = Výraz { "," Express }. ListIdent = IdentDef { "," IdentDef }. QualID = [ identifikátor "." ] ID . IdentDef = ident [ "*" | "-" ].Program Oberon je sada modulů. Obecně modul vypadá takto:
Název modulu ; IMPORT ImportList ; Definice ; BEGIN Příkazy END Jméno .Seznam importů určuje, ze kterých modulů budou externí názvy importovány . Mezi definice patří definice typů, procedur, funkcí, proměnných, konstant. V tomto případě jsou definice názvů označených hvězdičkou exportovány tímto modulem, to znamená, že budou viditelné pro ostatní moduly, které tento modul importují. V Oberonu-2 je také možné označit jména znaménkem mínus, v takovém případě se exportují v režimu pouze pro čtení.
Tělo modulu se provede při jeho načtení. BEGIN..ENDV Component Pascal je nyní možné do těla modulu (v sekci ) přidat sekci CLOSE:
Příkazy BEGIN CLOSE Příkazy END Jméno .Zde jsou příkazy mezi BEGINa CLOSEprovedeny, když je modul načten, a příkazy mezi CLOSEa jsou provedeny, když END je uvolněn z paměti. Takové rozšíření bylo shledáno užitečným pro dílčí programy, které dynamicky načítají a uvolňují moduly .
Datové typy vytvořené programátorem jsou omezeny na následující sadu: typy polí ARRAY , typy záznamů RECORD , procedurální typy PROCEDURE , typy ukazatelů POINTER . Ukazatel lze deklarovat pouze do pole nebo záznamu.
Syntaxe vnitřní části programu je poměrně tradiční a jednoduchá. Jazyk podporuje tradiční sadu konstrukcí: podmíněný operátor IF, výběrový operátor CASE, cykly (s předběžnou podmínkou - WHILE, s postpodmínkou REPEAT..UNTIL, nepodmíněnou - LOOP). Podobně jako u Modulu-2 se rozlišují velká a malá písmena v identifikátorech, všechna vyhrazená slova jsou velká. Všechny jazykové konstrukce, kromě smyčky REPEAT..UNTIL, končí klíčovým slovem ENDa umožňují vnoření do více příkazů bez použití složeného příkazu BEGIN..END. Přirozeně, stejně jako v Modulu-2, zde nejsou žádné nepodmíněné skoky.
Paradigma objektově orientovaného programování je podporováno mechanismem rozšíření záznamu (jazyk nemá samostatné klíčové slovo pro popis tříd, jako je „třída“ nebo „objekt“, má se za to, že obvyklý koncept „typu záznamu“ je docela dostatečný). Každý typ záznamu je v podstatě popisem třídy a pole záznamu jsou datové členy třídy.
V původním Oberonu nejsou vůbec žádné metody (procedury a funkce spojené s třídou ). Mechanismus metody lze použít deklarováním polí procedurálního typu v záznamu, kterým jsou přiřazeny specifické procedury, když je vytvořena instance třídy. Volání takových procedur se provádí tradičním způsobem přístupu k poli záznamu, procedura standardně neví o instanci třídy, pro kterou byla volána ( thisv C ++ nebo Javě podobný mechanismus neexistuje), a pokud takový je pro něj nezbytná informace, musí být odkaz na instanci předán explicitně (například prostřednictvím parametru ). Absence explicitně popsaných metod byla jednou z vlastností původního Oberonu, což vyvolalo kritiku programátorů zvyklých na tradiční hybridní jazyky. Na druhou stranu mechanismus navržený Oberonem umožňuje implementovat vše, co lze implementovat tradičními prostředky jazyků s metodami, a ještě více - v Oberonu může mít každá instance třídy svou vlastní verzi metody ( hodnota pole procedurálního typu), zatímco při popisu metod jako součásti třídy operují všechny instance na jediné variantě metody. V Oberonu 2 byly metody ještě zavedeny. Metody jsou popsány odděleně od typu záznamu s uvedením typu, ke kterému jsou přidruženy.
Nový typ záznamu lze deklarovat jako rozšíření existujícího. V tomto případě je rozbalovaný typ uveden v popisu položky v závorce za klíčovým slovem RECORD. Rozšířený typ automaticky přijímá všechna pole rozšířeného typu a (v Oberonu 2) je spojen se všemi procedurami spojenými s rozšířeným typem. Procedury přidružené k novému typu mohou mít stejný podpis jako procedury přidružené k rozšiřovanému typu – tím je zajištěno, že metody v odvozených typech budou přepsány. Aby bylo možné v Component Pascal poskytnout plnou statickou kontrolu nad konzistencí hierarchií dědičnosti (a tím obnovit princip úplného statického typování, který odlišoval původní Oberon), záznamy nejsou ve výchozím nastavení rozšiřitelné a metody nelze přepsat. Speciálně zavedená klíčová slova se používají k řízení rozšíření záznamů a přepisování metod EXTENSIBLE, ABSTRACT, LIMITED, EMPTY. V tomto případě musí být nově zaváděné metody označeny klíčovým slovem NEW(srov. povinná definice nově zaváděných proměnných).
Oberon je zaměřen na komponentově orientovaný vývoj softwaru [9] . Zapouzdření je podporováno výhradně na úrovni modulu – všechny typy deklarované uvnitř modulu jsou vzájemně naprosto transparentní. Z ostatních modulů je dostupné to, co je v definici deklarováno jako exportovatelné.
Polymorfismus zajišťuje mechanismus metody (jak procedurální pole v Oberonu, tak metody v Oberonu-2 se chovají jako virtuální , v terminologii většiny hybridních objektově orientovaných jazyků), a také rozšířený konstrukt WITH, který umožňuje spouštět různé skupiny příkazy, podle toho, ke kterému z rozšířených typů patří jeho argument.
V jazyce neexistuje žádný speciální konstruktorový mechanismus. Doporučenou metodou pro vytváření a inicializaci objektů je popis generujících modulů a procedur (továrna v tradiční terminologii OOP).
Program v této technologii je soubor relativně nezávislých komponent (v tomto případě modulů), které mají vnitřní strukturu skrytou před okolním světem a jasně definované rozhraní. Moduly lze dynamicky načítat a uvolňovat za běhu programu, systém poskytuje pokročilé nástroje pro kontrolu typu za běhu, které umožňují psát univerzální algoritmy pro zpracování dat, které nejsou závislé na konkrétních typech těchto dat (například knihovna pro práce s DBMS může poskytnout metody, které zapisují výsledek dotazu z databáze do záznamu libovolné struktury, pokud množina a typy polí v tomto záznamu odpovídají množině a typům polí v databázi).
V paradigmatu komponent je považováno za nešťastné architektonické rozhodnutí spojené s rozšířeným používáním dědičnosti implementace z typů deklarovaných v jiné komponentě, protože to vede k jevu známému jako „křehkost základního typu“ - poté, co je odvozeno velké množství odvozených typů základní typ (a některé z nich mohou být vývojáři základního typu dokonce neznámé), jakékoli změny v implementaci základního typu se stávají extrémně riskantními, protože mohou ovlivnit typy potomků nepředvídatelným způsobem.
Je známo, že jedním z problémů používání objektově orientovaného programování v systémovém programování je potřeba mít skupiny malých tříd, které mohou interagovat bez další režie. Oberon tento problém nemá - všechny typy definované v jednom modulu se navzájem vidí, a to nezpůsobuje problémy se spolehlivostí, protože modul je stále vyvíjen, testován a udržován jako celek.
Typický systém vyvinutý na Oberonu je sada modulů s procedurálními rozhraními, pomocí kterých si moduly vyměňují data, včetně objektů. Všechny nástroje pro zapouzdření přitom fungují pouze v mezimodulové interakci, což usnadňuje programování systému pomocí objektů.
Objektově orientované programováníNástroje objektového programování jsou v Oberonu interpretovány jako přirozený vývoj nástrojů pro práci se záznamy v modulárním systému, přesněji jako technická sada nástrojů pro řešení konkrétního architektonického problému: zajistit efektivní „rozdělení práce“ mezi různé moduly při práci s dynamickými typy a datovými strukturami: například v jednom modulu lze skrýt (spolu s odpovídajícími poli) práci s ukazateli v seznamu a v jiném specifikovat definici a práci s konkrétním „vyplněním“ prvků seznamu (nebo častěji jiné). V tomto smyslu je Oberonova technologie objektového programování podřízena konceptu modularity: zde je spíše prostředkem k popisu dat než prostředkem k budování aplikační architektury jako celku.
Podle Wirtha [10] vývojáři jazyka Java několik let před jeho vytvořením „prostudovali zdrojové kódy Oberonu a zejména zdrojové kódy Oberonových popelářů. Potom Oberon zpackali syntaxi C a nazvali to Java." Přestože nelze od ústního projevu vyžadovat absolutní přesnost formulace, každopádně nepochybná podobnost ideologií Oberonu a Javy (touha po minimalismu a silném psaní, omezení vícenásobné dědičnosti, automatická správa paměti) naznačuje, že existuje určitý konsenzus o tom, které nástroje by měly tvořit jádro moderního univerzálního programovacího jazyka. Pokud však minimalismus zůstane v Oberonu a jeho přímých nástupcích v popředí, vývojáři Javy se vydali cestou rozsáhlého budování schopností jazyka.
Samotná jazyková rodina Oberon zahrnuje také Oberon-07 , Oberon-2 , Component Pascal ( Component Pascal ), Active Oberon , OberonScript atd.
Původní verze Oberonu („klasický Oberon“) je nejvýstižnější, s nejmenším počtem klíčových slov a syntaktických konstrukcí. Byl použit jako základ pro vytvoření rodiny jazyků, z nichž každý v určitém směru rozšiřuje ten klasický nebo se od něj v některých detailech liší.
V roce 1992 jsou Niklaus Wirth a jeho student Hanspeter Mössenböck nyní profesory na univerzitě. Johannes Kepler v Linci - publikoval popis rozšířené verze Oberonu s názvem Oberon-2 . Je to rafinovaná verze klasického Oberona. Doplňky provedené v Oberonu 2 a provedené velmi střídmě jsou následující:
Navzdory rozšíření jazyka je objem formálního popisu syntaxe Oberonu-2 menší než u klasického Oberonu kvůli optimalizaci popisu syntaxe. Pro Oberon-2 existuje optimalizační kompilátor XDS [13] ; existuje také kompilátor [ 14] bytecode Java .
ETH Oberon , jehož implementace jsou dostupné pro mnoho počítačových platforem.
Oberon SA je verze jazyka Oberon vyvinutá N. Wirthem pro procesor Strong-ARM používaný v bezpilotním vrtulníku .
Na základě zkušeností z vývoje Oberon SA připravil N. Wirth v roce 2007 změny a doplňky klasického Oberonu [15] [16] pro přísnější podporu strukturovaného programování než např. v Oberon-2 nebo Component Pascal. Nová verze jazyka dostala název Oberon-07 [17] . Existuje překlad "Programovacího jazyka Oberon, Revize 1.11.2008" do ruštiny [18] . Ale pokud jde o podporu objektově orientovaného programování , jazyk Oberon-07 nenavazuje na Oberon-2, ale pokračuje v minimalistické linii klasického Oberonu, včetně chybějící podpory procedur spojených s typy záznamů.
Oberon-07 má následující hlavní rozdíly od klasického Oberonu:
Australská společnost CFB Software (Brisbane) na University of Queensland vyvinula Astrobe IDE [21] pro jazyk Oberon-07 pro mikrokontroléry NXP (Philips) ARM7 a také syntaktická schémata jazyka Oberon-07 [22] . jako vodítko pro styl programů v Oberon-07 [23] .
Ihned po svém zveřejnění v roce 1992 byl Oberon-2 zvažován jako kandidát na roli jazykového standardu (Oakwood Conference, Croydon, 1993), ale praktické zkušenosti získané při vytváření velkých softwarových systémů odhalily některé slabiny inovací a vhodnost další vylepšení (což opět zdůrazňuje moudrost konzervatismu, který Wirth ukázal při definování klasického Oberona). Tato vylepšení byla provedena ve variantě Oberon-2 nazvané Component Pascal a publikovaná v roce 1999 společností Oberon microsystems [24] , vytvořenou v roce 1992 Wirthovými studenty (Wirth se sám stal členem představenstva). Stejně jako při přechodu z Oberonu na Oberon-2 jsou tato vylepšení prováděna nejšetrněji [25] . Konkrétně tento jazyk nyní plně podporuje metodologii programování orientovanou na komponenty . Díky poslední okolnosti je Component Pascal v současnosti zřejmě nejdokonalejší mezi přímými potomky klasického Oberona. Lze ji však zredukovat nejen na podmnožinu ekvivalentní původnímu Oberonu, ale i na další plnohodnotnou minimalistickou podmnožinu, ve které je dědičnost a přepisování metod povoleno pouze pro čistě typy a metody rozhraní (definované atributem ABSTRACT). Tato okolnost odhaluje poněkud střední povahu Oberonu-2.
Komponenta Pascal přidává funkce, které umožňují vývojáři mít plnou kontrolu nad rozšířením typu exportu a přepsáním metody (atributy EXTENSIBLE, ABSTRACT, NEW, EMPTY, stejně jako možnost omezeného exportu metody „pouze implementace“). Přidán blok dokončení těla modulu (klíčové slovo CLOSE) a předdefinovaná prázdná metoda FINALIZE. Systém základních (elementárních) typů je sladěn s typy Java. Byl zaveden implicitní typ řetězce. Společnost Oberon Microsystems, která definovala Component Pascal , také vydala BlackBox Component Framework a vizuální programovací prostředí BlackBox Component Builder [26] , malé velikosti a nenáročné na zdroje, zcela postavené na Component Pascal.
Následně byl kompilátor BlackBox zabudován do multiplatformního programovacího prostředí Denia , zejména pro operační systém JBed v reálném čase , napsaný výhradně v Component Pascal.
Tyto jazyky již z dobrého důvodu nelze nazvat rozšířeními nebo verzemi Oberonu, ale nezávislými jazyky. Výrazně rozšířili syntaxi, zavedli konstrukce pro popis klasických „vlastností“ (vlastností) s řízením čtení/zápisu, číselné typy se zadanou velikostí v bitech. Zavedena podpora aktivních objektů vyměňujících si zprávy ve formátu definovaném popisem RBNF, zpracování výjimek [27] .