Af hverju Go er slæmt fyrir ósmarta forritara

Greinin var skrifuð sem svar við áður birtri antipodean grein.

Af hverju Go er slæmt fyrir ósmarta forritara

Undanfarin tvö ár eða meira hef ég notað Go til að innleiða sérhæfðan RADIUS netþjón með þróuðu innheimtukerfi. Á leiðinni er ég að læra ranghala tungumálsins sjálfs. Forritin sjálf eru mjög einföld og eru ekki tilgangur þessarar greinar, en reynslan af notkun Go sjálf á skilið nokkur orð henni til varnar. Go er að verða sífellt almennara tungumál fyrir alvarlegan, stigstærðan kóða. Tungumálið var búið til af Google, þar sem það er virkt notað. Niðurstaðan, ég held satt að segja að hönnun Go tungumálsins sé slæm fyrir UNintelligent forritara.

Hannað fyrir veikburða forritara?

Hinir veiku tala um vandamál. Hið sterka tal um hugmyndir og drauma...

Go er mjög auðvelt að læra, svo auðvelt að þú getur lesið kóðann nánast án þjálfunar. Þessi eiginleiki tungumálsins er notaður í mörgum alþjóðlegum fyrirtækjum þegar kóðinn er lesinn ásamt sérfræðingum sem ekki eru kjarna (stjórnendur, viðskiptavinir osfrv.). Þetta er mjög þægilegt fyrir aðferðafræði eins og Design Driven Development.
Jafnvel nýliði forritarar byrja að framleiða alveg ágætis kóða eftir viku eða tvær. Bókin sem ég lærði úr er „Go Programming“ (eftir Mark Summerfield). Bókin er mjög góð, hún snertir mörg blæbrigði tungumálsins. Eftir óþarflega flókin tungumál eins og Java, PHP, er skortur á töfrum hressandi. En fyrr eða síðar hafa margir takmarkaðir forritarar þá hugmynd að nota gamlar aðferðir á nýju sviði. Er þetta virkilega nauðsynlegt?

Rob Pike (aðal hugmyndafræðingur tungumálsins) skapaði Go tungumálið sem iðnaðarmál sem er auðvelt að skilja og áhrifaríkt í notkun. Tungumálið er hannað fyrir hámarks framleiðni í stórum teymum og það er enginn vafi á því. Margir nýliði forritarar kvarta yfir því að það séu margir eiginleikar sem þá vantar. Þessi þrá eftir einfaldleika var meðvituð ákvörðun hönnuða tungumálsins og til að skilja til hlítar hvers vegna þess var þörf verðum við að skilja hvata þróunaraðilanna og hvað þeir voru að reyna að ná í Go.

Svo hvers vegna var þetta gert svona einfalt? Hér eru nokkrar tilvitnanir í Rob Pike:

Lykilatriðið hér er að forritarar okkar eru ekki rannsakendur. Þeir eru að jafnaði frekar ungir, koma til okkar eftir nám, kannski lærðu þeir Java, eða C/C++ eða Python. Þeir geta ekki skilið frábært tungumál en á sama tíma viljum við að þeir búi til góðan hugbúnað. Þess vegna ætti tungumálið að vera auðvelt að skilja og læra.

Hann ætti að vera kunnugur, í grófum dráttum svipað og C. Forritarar sem starfa hjá Google hefja feril sinn snemma og þekkja að mestu málsmeðferðarmál, sérstaklega C fjölskylduna. Krafan um skjóta framleiðni í nýju forritunarmáli þýðir að tungumálið ætti ekki að vera of róttækt.

Vitur orð, er það ekki?

Artifacts of Simplicity

Einfaldleiki er nauðsynlegt skilyrði fyrir fegurð. Lev Tolstoj.

Að hafa það einfalt er eitt mikilvægasta markmiðið í hvaða hönnun sem er. Eins og þú veist er fullkomið verkefni ekki verkefni þar sem engu er við að bæta, heldur verkefni sem ekkert er að fjarlægja úr. Margir telja að til að leysa (eða jafnvel tjá) flókin vandamál þurfi flókið tæki. Hins vegar er það ekki. Tökum til dæmis PERL tungumálið. Málhugmyndafræðingar töldu að forritari ætti að hafa að minnsta kosti þrjár mismunandi leiðir til að leysa eitt vandamál. Hugmyndafræðingar Go-málsins fóru aðra leið, þeir ákváðu að ein leið, en mjög góð, væri nóg til að ná markmiðinu. Þessi nálgun hefur alvarlegan grunn: eina leiðin er auðveldara að læra og erfiðara að gleyma.

Margir innflytjendur kvarta yfir því að tungumálið innihaldi ekki glæsilegar abstraktmyndir. Já, þetta er satt, en þetta er einn helsti kostur tungumálsins. Tungumálið inniheldur lágmarks töfra - svo ekki þarf djúpa þekkingu til að lesa forritið. Hvað varðar orðræðu kóðans er þetta alls ekki vandamál. Vel skrifað Golang forrit les lóðrétt, með litla sem enga uppbyggingu. Að auki er hraði lestrar forrits að minnsta kosti stærðargráðu meiri en hraði þess að skrifa það. Ef þú telur að allur kóðinn sé með samræmdu sniði (gert með innbyggðu gofmt skipuninni), þá er alls ekki vandamál að lesa nokkrar aukalínur.

Ekki mjög svipmikill

List þolir ekki þegar frelsi hennar er takmarkað. Nákvæmni er ekki á hans ábyrgð.

Vegna þrá eftir einfaldleika skortir Go smíðar sem á öðrum tungumálum eru álitnar sem eitthvað eðlilegt af fólki sem er vant þeim. Í fyrstu gæti það verið nokkuð óþægilegt en svo tekur maður eftir því að forritið er miklu auðveldara og ótvíræðara aflestrar.

Til dæmis, stjórnborðsforrit sem les stdin eða skrá úr skipanalínurökum myndi líta svona út:

package main

import (
    "bufio"
    "flag"
    "fmt"
    "log"
    "os"
)

func main() {

    flag.Parse()

    scanner := newScanner(flag.Args())

    var text string
    for scanner.Scan() {
        text += scanner.Text()
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }

    fmt.Println(text)
}

func newScanner(flags []string) *bufio.Scanner {
    if len(flags) == 0 {
        return bufio.NewScanner(os.Stdin)
    }

    file, err := os.Open(flags[0])

    if err != nil {
        log.Fatal(err)
    }

    return bufio.NewScanner(file)
}

Lausnin á sama vandamáli í D, þótt hún líti nokkuð styttri út, er ekki auðveldari að lesa

import std.stdio, std.array, std.conv;

void main(string[] args)
{
    try
    {
        auto source = args.length > 1 ? File(args[1], "r") : stdin;
        auto text   = source.byLine.join.to!(string);

        writeln(text);
    }
    catch (Exception ex)
    {
        writeln(ex.msg);
    }
}

Helvítis afritun

Maðurinn ber helvíti innra með sér. Marteinn Lúther.

Byrjendur kvarta stöðugt yfir Go hvað varðar skort á samheitalyfjum. Til að leysa þetta mál nota flestir beina kóðaafritun. Til dæmis fall til að leggja saman lista yfir heiltölur, slíkir tilvonandi fagmenn telja að ekki sé hægt að útfæra virknina á annan hátt en með einfaldri copy-paste fyrir hverja gagnategund.

package main

import "fmt"

func int64Sum(list []int64) (uint64) {
    var result int64 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func int32Sum(list []int32) (uint64) {
    var result int32 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func main() {

    list32 := []int32{1, 2, 3, 4, 5}
    list64 := []int64{1, 2, 3, 4, 5}

    fmt.Println(int32Sum(list32))
    fmt.Println(int64Sum(list64))
}

Tungumálið hefur næga burði til að útfæra slíkar byggingar. Til dæmis væri almenn forritun í lagi.

package main

import "fmt"

func Eval32(list []int32, fn func(a, b int32)int32) int32 {
    var res int32
    for _, val := range list {
        res = fn(res, val)
    }
    return res
}

func int32Add(a, b int32) int32 {
    return a + b
}

func int32Sub(a, b int32) int32 {
    return a + b
}

func Eval64(list []int64, fn func(a, b int64)int64) int64 {
    var res int64
    for _, val := range list {
        res = fn(res, val)
    }
    return res
}

func int64Add(a, b int64) int64 {
    return a + b
}

func int64Sub(a, b int64) int64 {
    return a - b
}

func main() {

    list32 := []int32{1, 2, 3, 4, 5}
    list64 := []int64{1, 2, 3, 4, 5}

    fmt.Println(Eval32(list32, int32Add))
    fmt.Println(Eval64(list64, int64Add))
    fmt.Println(Eval64(list64, int64Sub))
}

Og þó að kóðinn okkar hafi reynst vera nokkuð lengri en fyrra tilvikið hefur það orðið almennt. Því verður ekki erfitt fyrir okkur að útfæra allar reikniaðgerðir.

Margir munu segja að prógramm í D líti út fyrir að vera umtalsvert styttra og þeir munu hafa rétt fyrir sér.

import std.stdio;
import std.algorithm;

void main(string[] args)
{
    [1, 2, 3, 4, 5].reduce!((a, b) => a + b).writeln;
}

Hins vegar er það aðeins styttra, en ekki réttara, þar sem D útfærslan hunsar algjörlega vandamálið við villumeðferð.

Í raunveruleikanum, þegar flækjustig rökfræði eykst, minnkar bilið hratt. Bilið lokast enn hraðar þegar þú þarft að framkvæma aðgerð sem ekki er hægt að framkvæma með því að nota venjulegt tungumál.

Hvað varðar viðhald, stækkanleika og læsileika, þá vinnur Go tungumálið að mínu mati, þó það tapi í orðræðu.

Almenn forritun gefur okkur í sumum tilfellum óneitanlega ávinning. Þetta er greinilega sýnt af flokkunarpakkanum. Svo, til að flokka hvaða lista sem er, þurfum við bara að innleiða sort.Interface viðmótið.

import "sort"

type Names []string

func (ns Names) Len() int {
    return len(ns)
}

func (ns Names) Less(i, j int) bool {
    return ns[i] < ns[j]
}

func (ns Names) Swap(i, j int) {
    ns[i], ns[j] = ns[j], ns[i]
}

func main() {
    names := Names{"London", "Berlin", "Rim"}
    sort.Sort(names)
}

Ef þú tekur eitthvert opið verkefni og keyrir grep „viðmót{}“ -R skipunina, muntu sjá hversu oft ruglingslegt viðmót eru notuð. Nánir félagar munu strax segja að allt sé þetta vegna skorts á samheitalyfjum. Þetta er þó ekki alltaf raunin. Tökum DELPHI sem dæmi. Þrátt fyrir tilvist þessara sömu samheitalyfja, inniheldur það sérstaka VARIANT gerð fyrir aðgerðir með handahófskenndar gagnategundir. Go tungumálið gerir það sama.

Frá fallbyssu til spörva

Og spennitreyjan verður að passa við stærð brjálæðisins. Stanislav Lec.

Margir öfgafullir aðdáendur kunna að halda því fram að Go hafi annan búnað til að búa til almenn lyf - spegilmynd. Og þeir munu hafa rétt fyrir sér... en aðeins í mjög sjaldgæfum tilfellum.

Rob Pike varar okkur við:

Þetta er öflugt tæki sem ætti að nota með varúð. Það ætti að forðast nema brýna nauðsyn beri til.

Wikipedia segir okkur eftirfarandi:

Íhugun vísar til þess ferlis þar sem forrit getur fylgst með og breytt eigin uppbyggingu og hegðun meðan á framkvæmd stendur. Forritunarhugmyndin sem er undirliggjandi íhugun er kölluð hugsandi forritun. Þetta er tegund af metaforritun.

Hins vegar, eins og þú veist, þú þarft að borga fyrir allt. Í þessu tilfelli er það:

  • erfiðleikar við að skrifa forrit
  • framkvæmdarhraði forritsins

Þess vegna verður að nota spegilmynd af varkárni, eins og stórgæða vopn. Hugsunarlaus notkun íhugunar leiðir til ólæsilegra forrita, stöðugra villna og lágs hraða. Bara málið fyrir snobbforritara að geta sýnt kóðann sinn fyrir framan aðra, raunsærri og hófsamari samstarfsmenn.

Menningarfarangur frá Xi? Nei, frá mörgum tungumálum!

Samhliða auðhringnum eru skuldir einnig skildar eftir við erfingjana.

Þrátt fyrir að margir telji að tungumálið sé alfarið byggt á C-arfleifðinni er það ekki raunin. Tungumálið inniheldur marga þætti bestu forritunarmálanna.

Setningafræði

Í fyrsta lagi byggist setningafræði málfræðilegrar uppbyggingar á setningafræði C tungumálsins. Hins vegar hafði DELPHI tungumálið einnig veruleg áhrif. Þannig sjáum við að óþarfi sviga, sem draga mjög úr læsileika forritsins, hafa verið fjarlægðir algjörlega. Tungumálið inniheldur einnig „:=“ rekstraraðila sem felst í DELPHI tungumálinu. Hugmyndin um pakka er fengin að láni frá tungumálum eins og ADA. Yfirlýsingin um ónotaðar einingar er fengin að láni frá PROLOG tungumálinu.

Merkingarfræði

Pakkarnir voru byggðir á merkingarfræði DELPHI tungumálsins. Hver pakki inniheldur gögn og kóða og inniheldur einkaaðila og opinbera aðila. Þetta gerir þér kleift að draga úr pakkaviðmótinu í lágmarki.

Innleiðingaraðgerðin með framsalsaðferð var fengin að láni frá DELPHI tungumálinu.

Samantekt

Það er ekki að ástæðulausu að það er brandari: Go var þróað á meðan verið var að taka saman C forrit. Einn af styrkleikum tungumálsins er ofurhröð samantekt þess. Hugmyndin var fengin að láni frá DELPHI tungumálinu. Hver Go pakki samsvarar DELPHI einingu. Þessir pakkar eru endursamdir aðeins þegar raunverulega er nauðsynlegt. Þess vegna, eftir næstu breytingu, þarftu ekki að þýða allt forritið, heldur endursamsetja aðeins breytta pakka og pakka sem eru háðir þessum breyttu pakka (og jafnvel þá, aðeins ef pakkaviðmótin hafa breyst).

Byggingar á háu stigi

Tungumálið inniheldur margar mismunandi háttsettar byggingar sem eru á engan hátt tengdar lágstigi tungumálum eins og C.

  • Strengir
  • Hash töflur
  • Sneiðar
  • Duck vélritun er fengin að láni frá tungumálum eins og RUBY (sem, því miður, margir skilja ekki eða nota til fulls).

Minnisstjórnun

Minnisstjórnun á almennt skilið sérstaka grein. Ef í tungumálum eins og C++ er stjórnin algjörlega eftir til þróunaraðilans, þá var á síðari tungumálum eins og DELPHI notað tilvísunartalningarlíkan. Með þessari nálgun voru hringlaga tilvísanir ekki leyfðar, þar sem munaðarlausir klasar voru myndaðir, þá er Go með innbyggða uppgötvun slíkra klasa (eins og C#). Að auki er sorpið skilvirkara en flestar þekktar útfærslur og er nú þegar hægt að nota í mörg rauntímaverkefni. Tungumálið sjálft þekkir aðstæður þegar hægt er að úthluta gildi til að geyma breytu á stafla. Þetta dregur úr álagi á minnisstjórann og eykur hraðann á forritinu.

Samhliða og samhliða

Samhliða og samkeppnishæfni tungumálsins er ofar lofi. Ekkert tungumál á lágu stigi getur jafnvel keppt við Go í fjarska. Til að vera sanngjarnt er rétt að taka fram að líkanið var ekki fundið upp af höfundum tungumálsins heldur var það einfaldlega fengið að láni úr gamla góða ADA tungumálinu. Tungumálið er fær um að vinna úr milljónum samhliða tenginga með því að nota alla örgjörva, á sama tíma og það hefur stærðargráðu og minna flókin vandamál með dauðalás og keppnisaðstæður sem eru dæmigerð fyrir fjölþráða kóða.

Viðbótarhlunnindi

Ef það er arðbært verða allir óeigingjarnir.

Tungumálið veitir okkur einnig ýmsa ótvíræða kosti:

  • Ein keyranleg skrá eftir byggingu verkefnisins einfaldar mjög dreifingu forrita.
  • Stöðug innsláttur og tegundaályktun getur dregið verulega úr fjölda villna í kóðanum þínum, jafnvel án þess að skrifa próf. Ég þekki nokkra forritara sem gera það án þess að skrifa próf yfirleitt og gæði kóðans þeirra skerðast ekki verulega.
  • Mjög einföld krosssamsetning og framúrskarandi flytjanleiki staðlaða bókasafnsins, sem einfaldar mjög þróun þverpallaforrita.
  • RE2 reglulegar tjáningar eru þráðaröruggar og hafa fyrirsjáanlegan keyrslutíma.
  • Öflugt staðlað bókasafn sem gerir flestum verkefnum kleift að gera án ramma þriðja aðila.
  • Tungumálið er nógu öflugt til að einblína á vandamálið frekar en hvernig eigi að leysa það, en samt nógu lágt til að hægt sé að leysa vandamálið á skilvirkan hátt.
  • Go vistkerfið inniheldur nú þegar þróuð verkfæri úr kassanum fyrir öll tækifæri: prófanir, skjöl, pakkastjórnun, öflugar linters, kóðagerð, skynjara fyrir keppnisskilyrði o.s.frv.
  • Go útgáfa 1.11 kynnti innbyggða merkingarfræðilega ávanastjórnun, byggð ofan á vinsæla VCS hýsingu. Öll verkfærin sem mynda Go vistkerfið nota þessa þjónustu til að hlaða niður, smíða og setja upp kóða úr þeim í einni svipan. Og það er frábært. Með komu útgáfu 1.11 var vandamálið með útgáfu pakka einnig leyst að fullu.
  • Vegna þess að kjarnahugmynd tungumálsins er að draga úr töfrum, hvetur tungumálið forritara til að gera villumeðferð beinlínis. Og þetta er rétt, því annars mun það einfaldlega gleyma villumeðferðinni. Annað er að flestir forritarar hunsa villumeðhöndlun vísvitandi og kjósa frekar í stað þess að vinna úr þeim að senda villuna einfaldlega upp á við.
  • Tungumálið innleiðir ekki klassíska OOP aðferðafræðina, þar sem í hreinu formi er engin sýndarmennska í Go. Hins vegar er þetta ekki vandamál þegar viðmót eru notuð. Skortur á OOP dregur verulega úr aðgangshindrunum fyrir byrjendur.

Einfaldleiki í þágu samfélagsins

Það er auðvelt að flækja, erfitt að einfalda.

Go var hannað til að vera einfalt og það tekst því markmiði. Hún var skrifuð fyrir snjalla forritara sem skilja kosti teymisvinnu og eru þreyttir á endalausum breytileika fyrirtækja á stigi tungumála. Með tiltölulega lítið sett af setningafræðilegum byggingum í vopnabúrinu er það nánast ekki háð breytingum með tímanum, þannig að forritarar hafa mikinn tíma losað til þróunar, en ekki til endalaust að rannsaka tungumálanýjungar.

Fyrirtæki fá einnig ýmsa kosti: Lítil aðgangshindrun gerir þeim kleift að finna sérfræðing fljótt og óbreytanleiki tungumálsins gerir þeim kleift að nota sama kóða jafnvel eftir 10 ár.

Ályktun

Stór heilastærð hefur aldrei gert nokkurn fíl að Nóbelsverðlaunahafa.

Fyrir þá forritara sem hafa persónulegt egó fram yfir liðsanda, sem og fræðimenn sem elska fræðilegar áskoranir og endalausar „sjálfsbætur“, er tungumálið mjög slæmt, þar sem það er almennt handverksmál sem leyfir þér ekki að fá fagurfræðilega ánægju af niðurstöðu vinnu þinnar og sýndu sjálfan þig fagmannlegan fyrir framan samstarfsmenn (að því gefnu að við mælum greind út frá þessum viðmiðum en ekki greindarvísitölu). Eins og allt í lífinu er þetta spurning um persónulega forgangsröðun. Eins og allar verðmætar nýjungar er tungumálið þegar komið langt frá alhliða afneitun til fjöldasamþykkis. Tungumálið er sniðugt í einfaldleika sínum og eins og þú veist er allt sniðugt einfalt!

Heimild: www.habr.com

Bæta við athugasemd