Systemi programmeerimise keel Nim 2.2.6 on välja antud. Uuendus ilmus kuus kuud pärast versiooni 2.2.4 väljalaskmist ning sisaldab 141 paranduse ja jõudluse täiustuse kommit. Nim on staatiliselt tüpiseeritud kompileeritav programmeerimiskeel, mille süntaks on inspireeritud Pythonist ja pakub Lisp-taseme meta programmeerimisvõimalusi. Keel kompileerib C, C++ ja JavaScripti, tagades C-taseme jõudluse kõrgetasemeliste keelte väljendusrikkuse. Projekti kood on litsentseeritud MIT litsentsi alusel.
Nimi olulised omadused hõlmavad võimsat makrosüsteemi, mis töötab AST-l kompileerimise ajal, arenenud üldprogrammimise süsteemi kontseptidega, mitmikülekande (multiple dispatch), määratletud mälu haldamist mitmete strateegiate (ARC/ORC, refc, märgistamine ja koristamine) toega, sisseehitatud tugifunktsiooni async/await asünkroosse programmeerimise jaoks ja FFI, et lihtsustada integreerimist C/C++/JavaScriptiga. Nim positsioneeritakse süsteemikeeleks, sobides alates manustatud süsteemide arendamisest kuni veebi.serverite, rõhutades tõhusust, mälu ohutust ja arendamise mugavust.
Olulised muudatused:
- Objektide väljade move-semantika optimeerimine. Kompilaator on õppinud tuvastama võimalust rakendada move-operatsioone objektide väljade tagastamisel. Varem sellised konstruktsioonid nagu «return obj.field» tõid andmete kopeerimise, nüüd rakendab kompilaator õigesti liikumist: proc getField(obj: MyObject): string = return obj.field # Nüüd move asemel copy
See on eriti oluline raskete andmetüüpide (stringid, järjestikud, ressursiga objektid) puhul, kus liigse kopeerimise eemaldamine toob märgatava jõudluse kasvu ilma koodi muutmata.
- Closure-iteratsioonide täielik ülevaatus koos erandite töötlemisega. Sulgemiste iteratsioonide transformatsioonimehhanism on täielikult ümber kirjutatud, mis on oluliselt parandanud async-koodi stabiilsust erandite töötlemisel. On parandatud kriitilised probleemid, sealhulgas SIGSEGV kasutamisel try/except mitteülemisel tasemel: iterator problematicIterator(): int {.closure.} = for i in 0..10: try: if i == 5: raise newException(ValueError, «test») yield i except ValueError: discard # Varem põhjustas SIGSEGV
Samuti on lahendatud probleem erandite vale edastamisega finally-blokkides sees closure-iteratsioonides.
- Mäluhaldusega seotud parandused
- Käitamise ajal leiti, et rikkevaba kogumishalduriga seotud fundamentaalne probleem töötleb tsüklilisi andmestruktuure, mis võis viia 'Ebaseaduslik mälu ligipääs' veani. Probleem püsis alates keele loomise hetkest ja ilmus keerukatel objekti graafikutel, kus oli omavahelisi viiteid.
- Parandatud vale objektide hävitamise järjekord, mis võis põhjustada juurdepääsu juba vabastatud mälule: type Resource = object data: ptr Data Container = object resource: Resource other: OtherResource # Nüüd kutsutakse destruktoreid õigesse järjekorda: # esmalt other, seejärel resource
- ORC kogumishaldur märkis ekslikult mõnede sulgude keskkonnad tsüklilisteks, mis põhjustas mälule vabastamise viivitusi või lekkeid. Nüüd töötas tsüklite analüüs korrektselt.
- Asyncnetis parandatud sokkide leke TLS-ühenduse kooskõlastamise vigade korral: proc handleClient() {.async.} = var socket = await server.accept() try: await socket.setupSSL() # Siin söövitamisel suletakse sokket nüüd korrektselt except SSLError: discard # Sokket ei leki enam
- Kriitilised parandused kompilaatoris.
- Parandatud regressioon, mille korral globaalmuutujad, mis olid deklareeritud protseduurides, kus on statiilsed parameetrid, initsialiseerusid iga kutsumise korral uuesti: proc test[N: static int]() = var global {.global.}: array[N, int] global[0] += 1 echo global[0] test[5]() # Väljund: 1 test[5]() # Peaks: 2, aga väljund oli: 1 (oli uuesti initsialiseeritud)
- Parandatud koodigeneratsioon globaalsete muutujate jaoks rekursiivsetes funktsioonides, mis viis ebaselge käitumiseni.
- Lahendatud vana probleem, mis tekkis ebaõige C-koodi genereerimise tõttu globaalsete muutujate kasutamisel konstruktorites konverterite sees: converter toInt(x: MyType): int = let global {.global.} = MyType() # Generatsioon ebaõiget C-koodi result = global.value
- Eemaldatud kompilaatori kokkuvarisemine Defect tüüpi erandite genereerimisel ja doAssert kasutamisel teatud kontekstides.
- Tüübihalduse täiustused
- Parandatud lent-väärtuste tagastamise võimatust case/if väljenditest: proc getBest(a, b: string): lent string = if a.len > b.len: return a # Varasem: kompileerimise viga else: return b
- Probleem lahendatud lentväljade väärtuste ebatäpsest salvestamisest üldistes tüüpides: type Wrapper[T] = object data: lent T proc process[T](w: Wrapper[T]) = echo w.data # Väärtus salvestatakse nüüd õigesti
- Muudetud on initsialiseeriva muutuja result kontrolli taastamine tüüpide jaoks, kus on requiresInit, mis katkestati versioonis 2.2: type MustInit {.requiresInit.} = object value: int proc test(): MustInit = discard # Nüüd annab õigesti veateate initsialiseerimata result'i kohta
- Parandatud alamtüübi eiramine („.noCopy“) põhietüübist: type Base {.noCopy.} = object Derived = object of Base var a: Derived var b = a # Nüüd on see õigesti keelatud
- Jõudluse optimeerimised
- Operaatore „@“ kiirus triviaalsete tüüpide jaoks: kriitilise jõudluse halvenemise kõrvaldamine, kui luuakse järjestusi lihtsatest tüüpidest koosnevatest massiividest: let arr = [1, 2, 3, 4, 5] let s = @arr # Olid äärmuslikult aeglased, nüüd on optimaalsed
- vmgen.sameConstant optimeerimine: kompileerimist kiiruselt oluliselt parandatud konstantide võrdlemise optimeerimise kaudu virtuaalmasinas kompilaatoris ja mäluhaldusoperatsioonide vähendamise kaudu.
- Cast tulemuse de-referentimine ühes väljendis ei põhjusta enam tarbetut kopeerimist: let data = cast[ptr MyType](address)[] # Nüüd ilma kopeerimiseta
- Tagumise spetsiifilised parendused
- JavaScript
- =destroy mitte-var tüüpide jaoks: parendatud hävitajate genereerimine, mis varem viis kompileerimisvigadeni.
- cast[char] väärtuste jaoks > 255: nüüd toimub lõikekorrektselt, nagu C-tagumise puhul.
- Kontseptsioonid varargsis: eemaldatud „internaalne viga” teate esitamine kontseptsioonide edastamisel varargs
- C++: L-valuelisus taastatud ühilduvatele tüüpidele, mis oli vigane regressioonis versioonide 2.2.2 ja 2.2.4 vahel: # nim cpp var x: CppCompatibleType takeRef(x) # Taas töötab nagu lvalue
- C (refc)
- pthread teatud platvormidel: parandatud koodi genereerimine pthread_mutex_t kasutades .abi;
- Üldist tüüpi GC-mäluga: eemaldatud vale C-koodi genereerimine üldistest tüüpidest, mis sisaldavad hallatavat mälu;
- JavaScript
- Virtuaalne masin
- Globaalsete muutujate ja määrangute käsitsemine: mitmed parandused globaalsete muutujate käsitlemiseks kompileerimise etapis.
- Case-objektid compileTime proc-st: parandatud valikute edastamine kui statilised parameetrid.
- repr pika stringi jaoks refc: eemaldatud RangeDefect kasutades repr.
- Parandused standardbiblioteegis
- Funktsioonis strutils.formatSize on parandatud suure väärtuse töötlemist, mis on lähedane int64.high: echo formatSize(9223372036854775807) # Nüüd on tulemus korrektne
- Dequesi puhul on taastatud iteratsiooni itemite käitumise ühilduvus versioonide 2.0.16 ja 2.2.0 vahel.
- Lists.SinglyLinkedList.remove funktsioonis on kõrvaldatud AssertionDefect, mis esines elementide eemaldamisel ühe-suunalisest loendist.
- Tables.withValue makros on parandatud tingimus, et kontrollida makros withValue muutumatute tabelite puhul.
- Pragma ja nähtavus
- Pragma «{.push raises: [].}» puhul on parandatud ebaõige leksikaalsete piirkondade ignoreerimine push-pragma puhul, millel on raises.
- Parandatud on «lekke» nähtus, kui hoiatusi on välja lülitatud pragma-blokkide piiridest: {.push warning[UnusedImport]: off.} import module1 {.pop.} import module2 # Nüüd on hoiatused korrektselt sisse lülitatud
- Muud olulised parandused
- CStringi võrdlemine: on lisatud puuduolevad operaatorid «<» ja «cmp» cstring jaoks.
- Floatide vahemike kontroll: on lisatud korrektne vahemike kontroll ujukomaarvude puhul
- filterIt ja rvalue: on parandatud vale rvalue tagastamine lvalue asemel
- FieldDefect on kõrvaldatud, kui võrreldi näidikuid kompileerimise etapis.
- hasCustomPragma pärast tüüpide descriptorite kopeerimist: töövõime naasmine tüübidesskriptorite kopeerimise järel.
- nim doc ja privaatväljad: parandatud kommentaaride kasutamine privaatväljade jaoks avalikes.
Allikas: opennet.ru
