Espro

From Esolang
Jump to navigation Jump to search
Espro (short for Esperanta Programado) is a 2015 unfinished idea by user:Timwi for a programming language whose syntax is based on the grammatical rules and inflection of Esperanto. It is a high-level, object-oriented, imperative, statically-typed, garbage-collected language that could be straightforwardly compiled to a managed environment such as .NET or JavaVM. Espro (mallongigo por Esperanta Programado) estas nekompleta ideo de user:Timwi el jaro 2015 pri programlingvo, kies sintakso estas bazita sur la gramatikaj reguloj kaj inflektoj de la Lingvo Internacia, Esperanto. Ĝi estas altnivela, objektorientema, imperativa, statike tipigita, rubaĵkolektanta lingvo, kiu estas simple tradukebla al iu mastrumata ĉirkaŭaĵo, ekz. .NET aŭ JavaVM.

Types / Tipoj

Built-in types include entjero (32-bit signed integer), nombro (double-precision float), signo (character), ĉeno (string) and ĉuo (boolean).

Arrays can be formed by using the -ar- particle: entjeraro (int[]), ĉenaro (string[]).

Nullables can be formed by using the keyword ebla: ebla entjero (nullable int).

A class can be defined by giving its name, then listing (in fairly natural Esperanto) first the fields (storage members) and then the methods (procedures, functions). In the declaration, the field names use the accusative noun form (-on); their types the accusative adjective form (-an); and the methods the infinitive verb form (-i). The method parameters can be declared using either an accusative form or any of a set of allowed prepositions. This makes sense when you see it written, as it forms a fairly readable, grammatical sentence:

Provizitaj tipoj inkludas entjero (32-bita signata entjero), nombro (duoble-preciza flosnombro), signo (tekstsigno), ĉeno (aranĝo de tekstsignoj) kaj ĉuo (jes-aŭ-ne-valoro).

Ordigataj aroj haveblas uzante la -ar- finaĵon: entjeraro, ĉenaro.

Neniigeblaj valoroj haveblas per la termino ebla: ebla entjero (entjero, kiu eble ne ekzistas).

Klasoj difineblas donante nomon kaj listante (en pli-malpli natura Esperanto) unue la kampojn (memorlokojn) kaj poste la metodojn (procedurojn, funkciojn). En la deklaracio, la kamponomoj uzas la akuzativan substantivan formon (-on); iliaj tipoj la akuzativan adjektivan formon (-an); kaj la metodoj la infinitivan verbformon (-i). La metodparametroj deklareblas uzante aŭ akuzativa formo aŭ iuj el aro de specifaj permesitaj prepozicioj. Ĉi tio pli sencos, kiam oni legas ĝin skribite, ĉar konstruiĝas pli-malpli legebla, gramatike ĝusta frazo:

   Grandeco enhavas
       publikan entjeran Larĝecon kaj
       publikan entjeran Altecon
   kaj ebligas
       publike krei laŭ entjera larĝeco kaj entjera alteco jene:
           /* statement/ordono */,
           /* statement/ordono */ kaj
           /* statement/ordono */,
       publike Adicii kun Grandeca aliaĵo donante Grandecon jene:
           /* statement/ordono */,
           /* statement/ordono */ kaj
           /* statement/ordono */
       kaj
       publike DiagonalonKomputi donante nombron jene:
           /* statement/ordono */ kaj
           /* statement/ordono */.
Note the syntax elements comprising a method declaration: Notu la sintakselementoj, el kiuj konsistas metoddeklaraĵo:
publike Adicii    kun    Grandeca         aliaĵo          donante Grandecon    jene:
       └──────┘         └────────┘       └──────┘                └─────────┘
          ↑                  ↑              ↑                         ↑
      method name     parameter type   parameter name            return type
       metodnomo      parametra tipo   parametra nomo            rezulttipo
Within a type declaration, the fields and methods are separated by the comma character (,) except the last, which is set off with the keyword kaj (and). The declaration ends with a period (.). The method name krei is a reserved keyword for declaring a constructor of a class (whose return type is not specified, as it is implicitly the class it’s in).

Types can be generic using the keyword de:

Ene de tipdeklaraĵo, la kampoj kaj metodoj apartigendas per komo (,) krom la lasta, kiu apartigendas per la termino kaj. La deklarado finiĝas per punkto (.). La metodnomo krei estas rezervita termino por deklari konstruilojn de klasoj (kies rezulttipo estas forlasita, ĉar ĝi ja implice estas la klaso, kiu ĝin enhavas).

Povas multtipemigi klasojn uzante la terminon de:

Listo de Elementoj enhavas
    // Fields // Kampoj
    privatan Elementaran _aron kaj
    privatan entjeran _longecon
kaj ebligas
    // Methods // Metodoj
    publike krei jene: /* ... */,
    publike Aligi Elementan aĵon jene: /* ... */ kaj
    publike Forigi Elementan aĵon donante ĉuon jene: /* ... */
For a method whose body consists of a single statement (rather than a series of statements), a declaration must be written differently; see the statements section about this.

If more than one consecutive parameter have the same type, you can abbreviate the declaration by pluralizing the type (adding -j). For example:

Metodo, kies korpo enhavas nur unu ordonon (ne plurajn), devas esti deklarita malsame; vidu la sekcion ordonoj pri tio.

Se pli ol unu sinsekvaj parametroj havas la saman tipon, oni povas mallongigi la deklaraĵon pluraligante la tipon (aldonante -j). Ekzemple:

    publike Eltiri laŭ entjeraj indekso kaj nombro donante Elementaron jene:

Statements / Ordonoj

Methods are called by using the accusative form of a variable name and the imperative form (-u) of the method. For example, if your class Aŭto (car) has a method hupi (honk), you would first create an instance and store it in a local variable as follows: Metodoj alvokeblas per la akuzativa formo de iu variablonomo kaj la imperativa formo (-u) de la metodo. Ekzemple, se onia klaso Aŭto enhavus metodon hupi, oni povas unue krei novan instancon kaj deponi ĝin en loka variablo jene:
Aŭta aŭto iĝu nova Aŭto
and then call the method thusly: kaj poste alvoki la metodon tiel:
aŭton hupu
The keyword iĝu (let be) is used both for variable initialization and for assignment. Thus, La termino iĝu uzeblas ambaŭ por komencvalorigi kaj por postvalorigi iun variablon. Do,
aŭto iĝu nenio
assigns null to the variable (nenio is the keyword for null and thus not allowed as a variable name).

Arguments can be passed to methods using the accusative case or any of the allowed prepositions. They do not have to be the same cases/prepositions as in the declaration, but the arguments have to be in the same order. For example, let’s paint our car in a nice new color:

valorigas nenion (la maleston de valoro) al la variablo. nenio estas termino kaj malpermesatas kiel variablonomo.

Argumentoj transdoneblas al metodoj uzante la akuzativan kazon aŭ iu el la permesataj prepozicioj. Ne necesas uzi la samajn kazojn/prepoziciojn ol en la deklaraĵo, sed la argumentoj devas esti ordigitaj same. Ekzemple, pentru ni nian aŭton laŭ ĉarma nova koloro:

Kolora koloro iĝu /* ... */,
aŭton pentru laŭ koloro
Variable declarations can also be implicitly typed (not dynamically typed) by using the keyword ia (some type of): Variablodeklaraĵoj povas esti implice tipigitaj (ne dinamike tipigitaj) uzante la terminon ia:
ia aŭto iĝu nova Aŭto
Multiple variables can be declared in a single statement by pluralizing the type: Eblas deklari plurajn variablojn en unu ordono pluraligante la tipon:
entjeraj unuaNombro iĝu 0 kaj duaNombro iĝu 1
Aŭtoj miaAŭto iĝu nova Aŭto kaj viaAŭto iĝu nenio
Within a block, statements are separated by the comma character (,) except the last, which is set off with the keyword kaj (and).

A method can be halted using the keyword ĉesu. If the method returns a value, use the preposition kun:

Ene de bloko, ordonoj apartigendas per komo (,) krom la lasta, kiu apartigendas per la termino kaj.

Eblas ĉesigi plenumadon de metodo per la termino ĉesu. Se la metodo havas rezultvaloron, uzendas la prepozicio kun:

ĉesu kun aŭta koloro
Block constructs for loops, conditionals etc. look as follows: Blokokonstruaĵoj (ripetaĵoj, kondiĉaĵoj, ktp.) aspektas jene:
se /* condition/kondiĉo */, /* statement/ordono */
se /* condition/kondiĉo */: /* statement/ordono */, /* statement/ordono */ kaj /* statement/ordono */
Note that the first variant uses a comma (,) while the second uses a colon (:). This is important as otherwise the use of the keyword kaj is ambiguous when several of these are nested. In the following, only a comma variant is shown, but a colon must be used instead when the block contains multiple statements. Notu, ke la unua vario uzas komon (,), sed la dua uzas dupunkton (:). Tio gravas, ĉar aliokaze la uzo de la termino kaj estus dusenca, kiam pluraj blokoj estas ingitaj. La sekvontaj ekzemploj uzas la komo-varion, sed necesas anstataŭ uzi la dupunkton, se la bloko enhavas pli ol unu ordonon.
// if, then, else // se, do, aliokaze
se /* condition/kondiĉo */, /* statement/ordono */, aliokaze /* statement/ordono */
se /* condition/kondiĉo */, /* statement/ordono */, aliokaze: /* statements/ordonoj */

// while // dum
dum /* condition/kondiĉo */, /* statement/ordono */

// until (while with condition negated) // ĝis (dum kun negita kondiĉo)
ĝis /* condition/kondiĉo */, /* statement/ordono */

// forever (while true; infinite loop) // dum vero; senĉesa ripeto
senĉese, /* statement */

// count from a to b (for loop) // nombrigi de a ĝis b
por /* variable/variablo */ inter /* expression/esprimo */ kaj /* expression/esprimo */, /* statement/ordono */

// iterate elements of a collection (foreach loop) // trairi elementojn de aro
por /* variable/variablo */ en /* expression/esprimo */, /* statement/ordono */
You can break out of a loop using eliru or jump to the next iteration using daŭrigu.

A declaration for a method whose body consists of a single statement (rather than a series of statements) must be written using the -ante ending instead of -u. For example, assuming Eldoni is a print function, instead of:

Eblas elsalti ripetaĵon per eliru kaj salti al la sekvonta ripeto per daŭrigu.

Deklaraĵo por metodo, kies korpo enhavas nur unu ordonon (ne plurajn) skribiĝendas per la -ante-finaĵo anstataŭ -u. Ekzemple — supozante, ke Eldoni estas funkcio por eldoni iun valoron — anstataŭ

// Wrong! // Maltaŭga!
publike Nomigi jene:
    Eldonu _nomon
you have to write: oni skribu
publike Nomigi
    Eldonante _nomon
If the single statement is a block statement, the keyword farante must be used: Se la sola ordono estas bloko, necesas skribi la terminon farante:
publike Nombrigi de entjera subo ĝis entjera supro
    farante por ia nombro inter subo kaj supro,
        Eldonu nombron
Some more statements: Jen pli da ordonoj:
variablon plialtigu laŭ /* expression/esprimo */      // +=
variablon malplialtigu laŭ /* expression/esprimo */   // -=
variablon alkrementu                                  // ++
variablon dekrementu                                  // --

Expressions / Esprimoj

Calling a method as an expression is different from doing it as a statement. This time, the variable becomes its adjective form and the method gets the ending -aĵo. Thus, if we want to use our method Adicii in the Grandeco class and assign the result to a new variable, we’d do so as follows: Alvoki metodon kiel esprimo estas malsama ol kiel ordono. En ĉi tia okazo la variablo metiĝas en adjektivan formon, kaj la metodo ricevas finaĵon -aĵo. Do, se oni volas alvoki la metodon Adicii el la klaso Grandeco kaj valorigi novan variablon laŭ la rezulto, tio eblas sekve:
ia grandeco iĝu nova Grandeco laŭ 4 kaj 7,
ia novgrandeco iĝu grandeca Adiciaĵo kun nova Grandeco laŭ 20 kaj 40
Here, we create a 4×7 size and put it in a variable; then we create a 20×40 size in-line and pass it into the Adicii method. The result will be 24×47.

Array elements are accessed using the ending -ano. For example, if we have an array and an integer:

Tio kreus grandecon de 4×7 kaj stokas ĝin en variablon; poste grandeco de 20×40 en-linie kreiĝas kaj transdoniĝas al la metodo Adicii. La rezulto estos 24×47.

Elementoj de aroj atingeblas per la finaĵo -ano. Ekzemple, se oni havus aron kaj entjeron:

ĉenara nomaro iĝu /* ... */,
entjera nombro iĝu /* ... */
then we can access the nombro’th element of nomaro as follows: oni nun povas atingi la valoron numero nombro en nomaro sekve:
ĉena nomo iĝu nombra nomarano
This syntax is very similar to that of method calls, but since method calls always have -aĵo while element access has -ano, there is no ambiguity.

If an integer literal is used to access an array element, the adjective ending is added to it with a hyphen:

Ĉi tiu sintakso tre similas al tiu de metodalvokoj, sed metodalvokoj ĉiam havas -aĵo-finaĵon kaj elementatingado havas -ano, do multsenco ne estas.

Se necesas atingi elementon de aro laŭ entjera rektvaloro, la adjektiva finaĵo aligiĝas al ĝi per streko:

ĉena unuaNomo iĝu 0-a nomarano
Arithmetic operators used in expressions are the normal familiar characters (+, -, *, /, %, &, |, ^, <<, >>). Integer and string literals are also just the same as in every other normal language. However, instead of && and || the short-circuiting boolean operators are called kaj krome and . The relational operators are called egalas al, estas pli ol, estas malpli ol, estas pli ol aŭ egalas al, etc. The ternary operator is called ĉu ..., do ..., alie ..., as demonstrated here: Aritmetikaj operatoroj uzataj en esprimoj estas la kutimaj, konataj signoj (+, -, *, /, %, &, |, ^, <<, >>). Entjeraj kaj ĉenaj rektvaloroj ankaŭ estas simple la sama ol ĉe ĉiu alia normala programlingvo. Tamen, anstatŭ && kaj ||, la kurtcirkvitaj ĉuaj operatoroj nomiĝas kaj krome kaj . La rilataj operatoroj nomiĝas egalas al, estas pli ol, estas malpli ol, estas pli ol aŭ egalas al, ktp. La triuma operatoro nomiĝas ĉu ..., do ..., alie ..., demonstrata ĉi tie:
ia unuaElemento iĝu ĉu listo egalas al nenio aŭ lista Longeco egalas al 0, do nenio, alie 0-a listano
Methods can be accessed as first-class functions by using the ending -ado instead of -aĵo: Metodoj atingeblas kiel unuarangaj funkciovaloroj per la finaĵo -ado anstataŭ -aĵo:
ia funkcio iĝu grandeca Adiciado laŭ Grandeco
The variable funkcio now contains a function of type Grandeco → Grandeco. Since multiple overloads of the same method name but with different parameter types could exist, the parameter types must be listed as shown so that a specific method overload can be selected. The variable can then be invoked the same way as a method. As a statement: La variablo funkcio nun enhavas funkcion de tipo Grandeco → Grandeco. Ĉar eblas, ke pluraj superaĵoj de la sama metodnomo ekzistas kun malsamaj parametraj tipoj, la parametraj tipoj devas esti listataj kiel montrite, por ke specifa metodsuperaĵo elekteblas. La variablon alvoki eblas sammaniere ol metodon. Kiel ordono:
funkciu laŭ grandeco
or as an expression: kaj kiel esprimo:
funkciaĵo laŭ grandeco
If a variable with the name funkciaĵo is already in scope, creating an ambiguity, a compile-time error occurs. Se iu variablo havanta la nomon funkciaĵo jam enampleksas, kreante dusencaĵon, tradukadtempa eraro okazu.

Properties and Indexers / Ecoj kaj Indeksiloj

In addition to fields and methods, a class can also have properties. A settable property would look like this (the first bit is a private field): Krom kampoj kaj metodoj, klasoj ankaŭ povas enhavi ecojn. Valorigebla eco aspektus jene (la unua deklaro estas privata kampo):
Aŭto enhavas
    privatan Koloran _koloron kaj
    publikan Koloran Koloron
        akireblan per _koloro
        ŝanĝeblan laŭ valoro _koloro iĝante valoro.
Note that the syntax for the setter specifies a name for the parameter, but not its type. The type is already specified by the property. Only one parameter name is allowed.

Additionally, the keyword akiri can be used as a method name (not property name!) to give a class the ability to act like a collection. For example, a Listo class for a list of integers, containing a private _ujo of type entjeraro, would contain a get-only indexer as follows:

Notu, ke la sintakso de la valorigilo donas nomon al la parametro, sed ne tipon. La tipo ja estas jam specifita per la eco. Nur unu parametro estas permesata.

Krome, la termino akiri uzeblas kiel metodnomo (ne ecnomo!) por ebligi al klaso agi kiel aro. Ekzemple, iu klaso Listo por listo de entjeroj, enhavanta privatan entjeraran _ujon, povus deklari nurakiran indeksilon jene:

publike akiri laŭ entjera indekso donante entjeron per
    indeksa _ujano.
Now you can use the -ano syntax to retrieve elements from the list: Nun eblas uzi -ano-sintakson por akiri elementojn el la listo:
Lista listo iĝu /* ... */,
entjera elemento iĝu 0-a listano
To allow the setting of elements, use ŝanĝi: La valorigado de elementoj ebligeblas per ŝanĝi:
publike ŝanĝi laŭ entjera indekso kaj entjera aĵo
    indeksa _ujano iĝante aĵo.

Examples / Ekzemploj

We can now complete our implementation of a generic Listo de Elementoj class. Nun eblas kompletigi la efektivigadon de la multtipema klaso Listo de Elementoj.
Listo de Elementoj enhavas

    // Fields // Kampoj
    privatan Elementaran _ujon,
    privatan entjeran _longecon kaj

    // Get-only property // Nurakira eco
    publikan entjeran Longecon
        akireblan per _longeco

kaj ebligas

    // Constructor // Kreilo
    publike krei jene:
        _ujo iĝu nova Elementaro laŭ 4 kaj
        _longeco iĝu 0,

    // Methods // Metodoj
    publike Aligi Elementan aĵon jene:
        se _longeco egalas al _uja Longeco:
            ia novujo iĝu nova Elementaro laŭ 2*_uja Longeco,
            _ujon Kopiu ekde 0 ĝis _longeco-1 al novujo ĉe 0 kaj
            _ujo iĝu novujo,
        _longeca _ujano iĝu aĵo kaj
        _longecon alkrementu,

    publike Forigi Elementan aĵon donante ĉuon jene:
        por ia indekso inter 0 kaj _longeco-1,
            se indeksa _ujano egalas al aĵo:
                ia novujo iĝu nova Elementaro laŭ _uja Longeco,
                _ujon Kopiu ekde 0 ĝis indekso-1 al novujo ĉe 0,
                _ujon Kopiu ekde indekso+1 ĝis _longeco-1 al novujo ĉe indekso,
                _ujo iĝu novujo,
                _longecon dekrementu kaj
                ĉesu kun vero kaj
        ĉesu kun malvero,
        
    publike Eltiri laŭ entjeraj indekso kaj nombro donante Elementaron jene:
       ia novujo iĝu nova Elementaro laŭ nombro,
       _ujon Kopiu ekde indekso ĝis indekso+nombro-1 al novujo ĉe 0 kaj
       ĉesu kun novujo,

    publike Malplenigi
        _longeco iĝante 0,

    // Indexers // Indeksiloj
    publike akiri laŭ entjera indekso donante Elementon per
        indeksa _ujano kaj
    publike ŝanĝi laŭ entjera indekso kaj Elementa aĵo
        indeksa _ujano iĝante aĵo.
The following static method implements binary search on an array of integers that is presumed to be in sorted order. Note the return type is a nullable integer. La sekvonta statika metodo efektivigas duumserĉadon tra entjeraro supozante, ke ĝi estas jam ordigita. Notu, ke la rezulttipo estas ebla entjero.
statike Duumserĉi entjeraran liston por entjera valoro donante eblan entjeron jene:
    ia subo iĝu 0,
    ia supro iĝu lista longeco - 1 kaj
    senĉese:
        se subo estas pli ol supro,
            ĉesu kun nenio,
        ia mezo iĝu (subo + supro)/2 kaj
        se meza listano egalas valoron,
            ĉesu kun mezo,
        aliokaze se meza listano estas pli ol valoro,
            supro iĝu mezo - 1,
        aliokaze
            subo iĝu mezo + 1.