Julia (ohjelmointikieli)

Julia on ohjelmointikieli, jota on kehitetty erityisesti tieteelliseen laskentaan, tavoitteenaan yhdistää hitaiden dynaamisten kielten helppokäyttöisyys ja perinteisten staattisten kielten suorituskyky. 
Julian keskeisin piirre ja ohjelmointitapa on "multiple dispatch" eli funktion koko tyyppijälki määrittää, mitä toteutusta eli metodia tietystä funktiosta kutsutaan. Monissa muissa kielissä metodit kuuluvat yhdelle objektille, eli vain ensimmäisen parametrin (esim. codice_1) tyypillä on merkitystä (engl. "single dispatch"). 
Käyttöaiheet.
Lineaarialgebra on yksi numeerisen laskennan keskeisistä alueista, joten tähän löytyy hyvä tuki Julian perus- ja standardikirjastosta (codice_2):
Käyttö.
Julia-komentoriviohjelman voi ladata kielen virallisilta web-sivuilta valmiina ajotiedostona ohjeiden mukaan. Kieli voidaan asentaa myös juliaup-työkalulla, joka helpottaa myös kielen päivittämistä ja useiden eri versioiden rinnakkaista käyttöä.
codice_27 näyttää saatavilla olevat asetukset ja codice_28 käynnistää REPL-konsolin. Komentoriviä voidaan käyttää poistumatta REPL-tilasta codice_29-komennolla ja paketinhallintatilaan päästään codice_30-komennolla. codice_31 näyttää kaikki Pkg-pakettienhallinnan REPL-tilan komennot, jotka vastaavat Pkg-paketin funktioita. REPL-ohjelmasta poistutaan codice_32. Julia-kääntäjää käytetään yhdelle lähdetiedostolle yksinkertaisesti codice_33. (Tämä Julia-kääntäjä toimii ns. JAOT-periaatteella (engl. "just-ahead-of-time") eli Julia-koodi käännetään tyypitetyn ja LLVM-välikoodin kautta konekielelle, mutta tämä tapahtuu ajon aikana eikä erillisessä käännösvaiheessa.)
Julia REPL mahdollistaa interaktiivisemman ohjelmointitavan, missä kehitettävät ohjelmat ovat omassa moduulissaan ja tiedostossaan, testit ovat omassa moduulissaan ja tiedostossaan, testit ajetaan Julia-konsolissa tyylillä codice_34 ja tämän lisäksi tehdään interaktiivista testaamista konsolissa. Kun interaktiivisesti löydetään jotain uutta testaamisen arvoista, tämä voidaan lisätä testimoduuliin. Muuten kehityksen aikana tehdään moduuleihin muutoksia palautteen mukaan ja toistetaan kehityssilmukkaa. codice_35-paketti mahdollistaa päivitettyjen ohjelmien testaamisen käynnistämättä Juliaa uudelleen.
Pluto.jl on Julialla Julialle kehitetty, Jupyter-työkirjojen kaltainen web-selaimeen ja ajettaviin soluihin perustuva kehitysympäristö, joka mahdollistaa interaktiivisen kirjallisen ohjelmoinnin (engl. "literate programming"). Työkirjat ovat aina toistettavia, sillä Pluto automatisoi pakettienhallinnan codice_36- ja codice_37-lauseiden perusteella.
Esimerkki.
Fibonaccin luvut.
function fibonacci(n)
 f = [0, 1]
 # Julia-listojen indeksit alkavat ykkösestä.
 n in [0, 1] &amp;&amp; return f[n + 1]
 # Ajon fibonacci(n = 2) tulos tulee listan indeksiin 3, jne. 
 for i = 3:(n + 1)
 # Huutomerkkiin päättyvät funktiot muokkaavat parametrejaan.
 append!(f, f[i - 1] + f[i - 2])
 end
 # end-sana viittaa listan vimeiseen indeksiin.
 return f[end]
end
Rakenne.
Modularisointi.
Julian codice_38-paketti mahdollistaa vakioitujen ympäristöjen luomisen, pääosin codice_39 ja codice_40/codice_41 funktioidensa avulla. Tietty pakettiversio voidaan vaatia syntaksilla codice_42 (semanttinen versiointi) tai codice_43 (Git). Myös suora URL toimii, jos kyseinen paketti ei ole käytetyssä rekisterissä. Nämä komennot muokkaavat kahta projektikansion juuressa olevaa tiedostoa: codice_44 (metadata) ja codice_45 (riippuvuudet). codice_46 asentaa halutun Julia-ympäristön uudelleen näiden tiedostojen pohjalta. Julia-koodin lisäksi muiden riippuvuuksien käsittelemiseksi voidaan käyttää codice_47-tiedostoa, jonka avulla kunkin riippuvuuden paikallinen tiedostopolku saadaan käyttöön projektin Julia-koodissa syntaksilla codice_48 (engl. "non-standard string literal").
Kun ympäristö koostuu useista paketeista, niin paketti muodostuu yleensä useiden moduulien hierarkiasta. Moduulit codice_49 luovat uuden globaalin nimiavaruuden, johon tuodaan nimiä codice_36 ja codice_37 lauseilla ja lähdetiedostoja codice_52-kutsulla ja josta paljastetaan nimiä codice_53-lauseilla (vain codice_37 ottaa codice_53-lauseet huomioon). Paikalliseen moduuliin viittaamiseksi tarvitaan pistesyntaksia codice_56, koska pisteetön syntaksi viittaa Julia-paketteihin.
Juliassa on moduulin luoma globaali näkymä ja tämän sisällä ns. heikkoja ja vahvoja paikallisia näkymiä. codice_57 ja codice_58 lauseet eivät luo ollenkaan uutta näkymää, kun taas codice_59, codice_60, codice_61 ja codice_62 lauseet luovat paikallisen näkymän, jossa globaalien nimien uudelleenkäyttö on kielletty (heikko näkymä). Funktiot ja makrot luovat vahvan paikallisen näkymän eli ulkonäkymien nimiin sijoittaminen on sallittua eikä muokkaa niitä. Kullakin paikallisella näkymällä on kuitenkin lukuoikeus sen ulkonäkymissä määriteltyihin muuttujiin. Esim. funktiot perivät arvot määrittelympäristöstään, eli esim. tietyn moduulin funktiot voivat lukea samoja globaaleja muuttujia moduulistaan ilman erityisiä avainsanoja.
Tyypit.
Julian tyyppijärjestelmä on dynaaminen, nominatiivinen, parametrinen ja yhtenäinen. Kaikilla rakenteilla on jokin tyyppi ajon aikana. 
Kielen mukana tulevia tietotyyppejä (codice_63) ovat muun muassa seuraavat:
Uusi yhdistelmätyyppi luodaan sanoilla codice_83. Instansseja voidaan muokata vain, kun on käytetty codice_84, ellei tyypin alkiota olla määritelty sanalla codice_85. Tyyppejä voidaan yhdistää myös tyylillä codice_86. Tyyppiparametreja käytetään syntaksilla codice_87, mikä määrittelee kerralla joukon tyyppejä. Parametrina olevien tyyppien joukko voidaan rajoittaa alatyypeihin tyylillä codice_88. Tyyppi voidaan myös parametrisoida vain osittain syntaksilla codice_89. Abstrakteja tyyppejä codice_90 taas ei voida käyttää suoraan vaan ne täytyy ensin konkretisoida. Tämän jälkeen abstraktia tyyppiä voidaan käyttää viittaamaan kaikkiin tämän alatyyppeihin. (Juliassa ei ole olioperusteisemmille kielille tyypillistä perimismekanismia.)
Luodut tyyppiobjektit toimivat itse alustajinaan codice_91. Tämä alustaja on tavallinen funktio, joten sille voidaan määritellä useita metodeja codice_92. Tyypin alustajaa voidaan käyttää myös tyypin omassa määritelmässä erityisen codice_93-funktion kautta. Alustettujen arvojen tyyppiä voidaan selvissä tapauksissa muuttaa codice_94- tai codice_95-funktiolla. (Numeroita edustaville codice_66-arvoille (codice_97) löytyy oma codice_98-funktionsa.) 
Tietylle tyypille määritellään metodeja Juliassa tavallisten funktioiden tapaan codice_99. Metodi ei kuitenkaan kuulu ainoastaan kyseiselle tyypille vaan kutsuttava metodi valitaan koko funktion tyyppijäljen perusteella (engl. "multiple dispatch"). Funktionkin tyyppijälki voidaan parametrisoida tyylillä codice_100 (eli tämä metodi valitaan, kun kolmen argumentin tyypit ovat samoja). Näin myös objekteista itsestään voidaan tehdä kutsuttavia (ns. funktoreita) antamalla niiden "tyypille" metodi tyylillä codice_101. Olemassaolevien rajapintojen toteuttaminen tapahtuu toteuttamalla tarvittavien funktioiden metodit – uudesta tyypistä voidaan tehdä muun muassa iteroitava, indeksoitava ja listamainen määrittelemällä sille metodit muutamista erityisistä funktioista kuten codice_102, codice_103 ja codice_104.
Funktiot.
Funktiot määritellään codice_105 tai yhdellä rivillä codice_106. Nimettömille funktioille voidaan käyttää syntaksia codice_107 tai codice_108 tai codice_109. codice_110 tekee anonyymin funktion codice_111-lauseen avulla ja syöttää sen edellä olevan funktion ensimmäiseksi argumentiksi. Funktion voi ns. vektorisoida eli kutsua jonkin kokoelman jokaiselle alkiolle käyttämällä pistesyntaksia kuten codice_112 (tai sama pistemakrolla codice_113, kun kaikki operaatiot vektorisoidaan). Funktioiden yhdistäminen on mahdollista muun muassa putkioperaattorilla codice_114.
Funktioiden parametrit ovat Juliassa uusia muuttujia, mutta ne vain viittaavat annettuun arvoon eli kopioita ei synny. Funktiot voidaan tyypittää tyylillä codice_115, mutta yleensä Julian tyypinpäättelyn vuoksi korkeintaan parametrien tyyppien merkitseminen on tarpeen. Funktio voi hyväksyä vaihtelevan määrän parametreja tyylillä codice_116, missä codice_117 on codice_118 funktion sisällä tai mikä tahansa iteroitava tyyppi funktion ulkona. Funktioiden tulisi palauttaa vain yhden tyypin arvoja, jolloin tulostyyppi on Julia-kääntäjän pääteltävissä. Tyyppien merkitseminen voi kuitenkin parantaa koodin luettavuutta. Destrukturointi onnistuu taas tyylillä codice_119. 
Sivuvaikutusten takia kutsutut funktiot palauttavat käytännön mukaan codice_120. Parametrejaan muuttavien funktioiden nimi päättyy huutomerkkiin codice_121. Funktioiden nimeämiskäytäntö on ilman alaviivoja kuten codice_122, kun tämä vain on luettavissa – muussa tapauksessa sanat erotetaan alaviivalla. 
Juliassa myös kaikki operaattorit ovat funktioita: esim. codice_123 kutsuu codice_103, codice_125 kutsuu codice_126 ja codice_127 kutsuu codice_128.
Metaohjelmointi.
Metaohjelmointi onnistuu suoraan käsittelemällä Julia-ohjelmien abstraktia syntaksipuuta. Tämä mahdollistaa täyden metaohjelmoinnin. Julia-koodin tyyppi on aluksi tyyppiä codice_66, joka voidaan jäsentää codice_130 lauseketyypin codice_131 arvoksi. Lausekkeita voidaan määritellä myös syntaksilla codice_132 ja usean rivin lausekkeita syntaksilla codice_133. Kaksoispisteellä tehdään myös codice_134-tyypin arvoja codice_135 (engl. "string interning"). Lausekkeet voidaan lopuksi ajaa codice_136-funktiolla. Lausekkeita voidaan siis käsitellä normaaleissa Julia-funktioissa, mutta nämä funktiot ajetaan vasta ajon aikana, kun taas metaohjelmoinnissa on yleensä tehokkaampaa tuottaa halutut lausekkeet jo käännösvaiheessa. 
Käännösaikaiseen metaohjelmointiin tarvitaan makroja. Makrot sijoittavat argumenttinsa suoraan tuloksena tuotettuun lausekkeeseen, joka käännetään sitten normaalin Julia-koodin tapaan. Makrot määritellään tyylillä codice_137 ja kutsutaan syntaksilla codice_138 tai codice_139 (tai yhdelle literaalitaulukolle codice_140). Makro saa argumenttinsa vain lausekkeina codice_131, symboleina codice_135 tai literaaleina. Koska Julia on dynaamisesti tyypittävä, makrot eivät tiedä saamiensa arvojen tyyppejä. Makrot noudattelevat muuten paljolti samoja sääntöjä kuin funktiot.
Normaalin funktion ja makron lisäksi voidaan määritellä myös ns. tuotettu funktio tyylillä codice_143, joka asettuu ominaisuuksiltaan funktion ja makron välille. Tällainen funktio ajetaan vasta, kun argumenttien tyypit tiedetään, mutta ennen kuin funktio on käännetty. Makrojen tapaan nämä erityisfunktiot lisäävät abstraktiokykyä ja suorityskykyä siirtämällä laskentaa ajovaiheesta käännösvaiheeseen.
Rinnakkaisohjelmointi.
codice_144-makro tekee annetusta lausekkeesta asynkronisesti ajettavan codice_145-tyypin objektin, jolle voidaan kutsua codice_146, codice_147 ja codice_148. Vastaavasti codice_149-makron avulla voidaan odottaa kaikkien makron sisältämien codice_144-lausekkeiden valmistumista. codice_145-objekteja voidaan luoda myös käyttämällä codice_152-makroa tai tyypin alustajaa codice_153. codice_154 on taas ikäänkuin rinnakkainen versio generaattorista; kanavan tuottaja kutsuu codice_155-funktiota ja kuluttaja codice_156-funktiota tai iteroi kanavaa muiden iteroitavien tyyppien mukaan. 
Julia käyttää oletuksena yhtä säiettä (codice_157). Julia ei myöskään varmista muistiturvallisuutta (vrt. Rust (ohjelmointikieli)) vaan tämä on ohjelmoijan vastuulla. Esim. datakisavirheiden ehkäisemiseksi tulee käyttää lukkomekanismia, kuten codice_158, codice_159 ja codice_160, tai ns. atomisia arvoja, kuten codice_161 ja codice_162. codice_163-paketti määrittelee helppokäyttöisen codice_164-makron, joka tekee annetusta silmukkalausekkeesta automaattisesti monisäikeisen.
codice_165 tekee paikallisen klusterin, jossa on annettu määrä prosesseja, ja codice_166 tekee usean koneen klusterin käyttämällä salasanatonta ssh-viestintää näiden välillä. codice_167-paketti mahdollistaa hajautetun laskennan useissa prosesseissa ja perustuu etäreferensseihin (codice_168 ja codice_169) ja etäkutsuihin (codice_170, codice_171). codice_168-tyypille kutsutaan lopulta codice_148 tuloksen saamiseksi pääprosessiin. Lähdetiedosto voidaan lisätä jokaiseen prosessiin tyylillä codice_174 tai tekemällä tästä Julia-paketti. Prosesseja voidaan lisätä, poistaa ja muokata funktioilla kuten codice_175 ja codice_176. Esimerkiksi codice_177-paketin codice_178 on taulukon hajautettu versio ja standardikirjaston codice_179 mahdollistaa hajautettujen osasten jakamisen useiden prosessien välillä. 
Grafiikkaprosessoreiden käyttöön löytyy tukea muun muassa paketeista CUDA.jl ja MPI.jl.
Muut.
Dokumentointi onnistuu Juliassa tekstiliteraaleilla kohteena olevan määritelmän yläpuolella (engl. "docstring"). Teksti voi sisältää Markdown- ja LateX-merkintöjä.
Julian tärkeimpiin siirrännän työkaluihin kuuluvat ensinnäkin codice_180- ja codice_181-virrat, jotka tukevat codice_182, codice_183, codice_184 ja codice_185 funktioita. codice_186-funktio tekee tiedostonimestä codice_187-objektin ja codice_188-sulkee virran, jos codice_186 kutsuttiin ilman funktioargumenttia. codice_190-paketti määrittelee TCP-viestintään pääfunktiot codice_191, codice_192, codice_193 ja codice_188.