Kāpēc Go ir kaitīgs negudriem programmētājiem

Raksts tika uzrakstÄ«ts kā atbilde uz iepriekÅ” publicētu antipodisks raksts.

Kāpēc Go ir kaitīgs negudriem programmētājiem

Pēdējo divu gadu laikā esmu izmantojis Go, lai ieviestu specializētu RADIUS serveri ar izstrādātu norēķinu sistēmu. Pa ceļam es mācos paÅ”as valodas smalkumus. PaÅ”as programmas ir ļoti vienkārÅ”as un nav Ŕī raksta mērÄ·is, taču pati Go lietoÅ”anas pieredze ir pelnÄ«jusi dažus vārdus aizstāvÄ«bai. Go kļūst par arvien populārāku valodu nopietnam, mērogojamam kodam. Valodu izveidoja Google, kur tā tiek aktÄ«vi izmantota. Secinājums, es godÄ«gi domāju, ka Go valodas dizains ir slikts UNintelligent programmētājiem.

Paredzēts vājiem programmētājiem?

Vāji runā par problēmām. Spēcīgā runa par idejām un sapņiem...

Go ir ļoti viegli iemācÄ«ties, tik vienkārÅ”i, ka varat izlasÄ«t kodu praktiski bez apmācÄ«bas. Å Ä« valodas funkcija tiek izmantota daudzos globālos uzņēmumos, kad kods tiek lasÄ«ts kopā ar speciālistiem, kas nav pamata speciālisti (vadÄ«tāji, klienti utt.). Tas ir ļoti ērti tādām metodoloÄ£ijām kā dizaina virzÄ«ta izstrāde.
Pat iesācēju programmētāji pēc nedēļas vai divām sāk ražot diezgan pienācÄ«gu kodu. Grāmata, no kuras es mācÄ«jos, ir ā€œGo Programmingā€ (autors Marks SamerfÄ«lds). Grāmata ir ļoti laba, skar daudzas valodas nianses. Pēc nevajadzÄ«gi sarežģītām valodām, piemēram, Java, PHP, maÄ£ijas trÅ«kums ir atsvaidzinoÅ”s. Bet agrāk vai vēlāk daudziem ierobežotiem programmētājiem rodas doma izmantot vecās metodes jaunā jomā. Vai tas tieŔām ir vajadzÄ«gs?

Robs Paiks (valodas galvenais ideologs) izveidoja Go valodu kā industriālu valodu, kas ir viegli saprotama un efektÄ«va lietoÅ”anā. Valoda ir paredzēta maksimālai produktivitātei lielās komandās, un par to nav Å”aubu. Daudzi iesācēju programmētāji sÅ«dzas, ka viņiem trÅ«kst daudz funkciju. Å Ä« vēlme pēc vienkārŔības bija apzināts valodas dizaineru lēmums, un, lai pilnÄ«bā saprastu, kāpēc tas bija vajadzÄ«gs, mums ir jāsaprot izstrādātāju motivācija un tas, ko viņi mēģināja sasniegt Go.

Tātad, kāpēc tas tika izveidots tik vienkārÅ”i? Å eit ir daži citāti no Roba Paika:

Galvenais Å”eit ir tas, ka mÅ«su programmētāji nav pētnieki. Viņi, kā likums, ir diezgan jauni, nāk pie mums pēc studijām, iespējams, viņi ir apguvuÅ”i Java, C/C++ vai Python. Viņi nevar saprast lielisku valodu, bet tajā paŔā laikā mēs vēlamies, lai viņi izveidotu labu programmatÅ«ru. Tāpēc valodai jābÅ«t viegli saprotamai un apgÅ«stamai.

Viņam vajadzētu bÅ«t pazÄ«stamam, rupji runājot, lÄ«dzÄ«gi kā C. Programmētāji, kas strādā Google, sāk savu karjeru agri un pārsvarā pārzina procesuālās valodas, jo Ä«paÅ”i C saimi. PrasÄ«ba pēc ātras produktivitātes jaunā programmÄ“Å”anas valodā nozÄ«mē, ka valodai nevajadzētu bÅ«t pārāk radikālai.

Gudri vārdi, vai ne?

VienkārŔības artefakti

VienkārŔība ir nepiecieŔams skaistuma nosacījums. Ļevs Tolstojs.

VienkārŔība ir viens no svarÄ«gākajiem mērÄ·iem jebkurā dizainā. Kā zināms, ideāls projekts ir nevis projekts, kuram nav ko pievienot, bet gan tāds, no kura nav ko izņemt. Daudzi cilvēki uzskata, ka, lai atrisinātu (vai pat izteiktu) sarežģītas problēmas, ir nepiecieÅ”ams sarežģīts instruments. Tomēr tā nav. Ņemsim, piemēram, PERL valodu. Valodas ideologi uzskatÄ«ja, ka programmētājam ir jābÅ«t vismaz trÄ«s dažādiem veidiem, kā atrisināt vienu problēmu. Go valodas ideologi izvēlējās citu ceļu, viņi nolēma, ka mērÄ·a sasniegÅ”anai pietiek ar vienu, bet patieŔām labu ceļu. Å ai pieejai ir nopietns pamats: vienÄ«gais veids ir vieglāk mācÄ«ties un grÅ«tāk aizmirst.

Daudzi migranti sÅ«dzas, ka valodā nav elegantu abstrakciju. Jā, tā ir taisnÄ«ba, taču tā ir viena no galvenajām valodas priekÅ”rocÄ«bām. Valoda satur maÄ£ijas minimumu - tāpēc programmas lasÄ«Å”anai nav nepiecieÅ”amas dziļas zināŔanas. Kas attiecas uz koda daudznozÄ«mÄ«gumu, tā nemaz nav problēma. Labi uzrakstÄ«ta Golang programma lasa vertikāli, ar nelielu struktÅ«ru vai bez tās. Turklāt programmas lasÄ«Å”anas ātrums ir vismaz par kārtu lielāks nekā tās rakstÄ«Å”anas ātrums. Ja uzskatāt, ka visam kodam ir vienots formatējums (kas tiek darÄ«ts, izmantojot iebÅ«vēto komandu gofmt), tad dažu papildu rindiņu lasÄ«Å”ana nemaz nav problēma.

Ne pārāk izteiksmīgs

Māksla nepanes, kad tās brīvība ir ierobežota. Precizitāte nav viņa atbildība.

VienkārŔības tieksmes dēļ Go trÅ«kst konstrukciju, ko citās valodās pieraduÅ”ie uztver kā kaut ko dabisku. Sākumā tas var bÅ«t nedaudz neērti, bet pēc tam pamanāt, ka programmu ir daudz vieglāk un nepārprotamāk lasÄ«t.

Piemēram, konsoles utilÄ«ta, kas nolasa stdin vai failu no komandrindas argumentiem, izskatÄ«tos Ŕādi:

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)
}

Tās paÅ”as problēmas risinājums D, lai gan tas izskatās nedaudz Ä«sāks, nav vieglāk lasāms

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);
    }
}

KopēŔanas elle

Cilvēks sevÄ« nes elli. MārtiņŔ Luters.

Iesācēji pastāvÄ«gi sÅ«dzas par Go, jo trÅ«kst Ä£enērisko zāļu. Lai atrisinātu Å”o problēmu, lielākā daļa no tiem izmanto tieÅ”o koda kopÄ“Å”anu. Piemēram, veselu skaitļu saraksta summÄ“Å”anas funkcija, tādi potenciālie profesionāļi uzskata, ka funkcionalitāti nevar ieviest citādi, kā vien ar vienkārÅ”u kopÄ“Å”anu-ielÄ«mÄ“Å”anu katram datu tipam.

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))
}

Valodai ir pietiekami lÄ«dzekļi Ŕādu konstrukciju Ä«stenoÅ”anai. Piemēram, vispārēja programmÄ“Å”ana bÅ«tu piemērota.

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))
}

Un, lai gan mÅ«su kods izrādÄ«jās nedaudz garāks nekā iepriekŔējā gadÄ«jumā, tas ir kļuvis vispārināts. Tāpēc mums nebÅ«s grÅ«ti Ä«stenot visas aritmētiskās darbÄ«bas.

Daudzi teiks, ka programma D izskatās ievērojami īsāka, un viņiem būs taisnība.

import std.stdio;
import std.algorithm;

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

Tomēr tas ir tikai Ä«sāks, bet ne pareizāks, jo D ievieÅ”ana pilnÄ«bā ignorē kļūdu apstrādes problēmu.

Reālajā dzīvē, pieaugot loģikas sarežģītībai, plaisa strauji samazinās. Plaisa samazinās vēl ātrāk, ja jums ir jāveic darbība, ko nevar veikt, izmantojot standarta valodas operatorus.

UzturamÄ«bas, paplaÅ”ināŔanas un lasāmÄ«bas ziņā, manuprāt, Go valoda uzvar, lai gan tā zaudē daudzvārdÄ«bā.

Ä¢eneralizēta programmÄ“Å”ana dažos gadÄ«jumos sniedz mums nenoliedzamas priekÅ”rocÄ«bas. To skaidri parāda ŔķiroÅ”anas pakotne. Tātad, lai sakārtotu jebkuru sarakstu, mums vienkārÅ”i jāievieÅ” sort.Interface interfeiss.

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)
}

Ja izmantojat jebkuru atvērtā pirmkoda projektu un palaižat komandu grep "interfeiss{}" -R, jÅ«s redzēsit, cik bieži tiek izmantotas mulsinoÅ”as saskarnes. Pietuvināti biedri uzreiz teiks, ka tas viss ir Ä£enērisko lÄ«dzekļu trÅ«kuma dēļ. Tomēr tas ne vienmēr notiek. Ņemsim par piemēru DELPHI. Neskatoties uz Å”o paÅ”u vispārÄ«go datu klātbÅ«tni, tajā ir Ä«paÅ”s VARIANT tips darbÄ«bām ar patvaļīgiem datu tipiem. Go valoda dara to paÅ”u.

No lielgabala līdz zvirbuļiem

Un Å”auruma jakai ir jāatbilst neprāta izmēram. Staņislavs Lec.

Daudzi ekstrēmu cienÄ«tāji var apgalvot, ka Go ir vēl viens Ä£enērisko zāļu radÄ«Å”anas mehānisms - refleksija. Un viņiem bÅ«s taisnÄ«ba... bet tikai retos gadÄ«jumos.

Robs Paiks mūs brīdina:

Å is ir spēcÄ«gs rÄ«ks, kas jāizmanto piesardzÄ«gi. No tā jāizvairās, ja vien tas nav absolÅ«ti nepiecieÅ”ams.

Wikipedia stāsta mums sekojoŔo:

Refleksija attiecas uz procesu, kura laikā programma izpildes laikā var uzraudzÄ«t un modificēt savu struktÅ«ru un uzvedÄ«bu. ProgrammÄ“Å”anas paradigmu, kas ir refleksijas pamatā, sauc par reflektÄ«vo programmÄ“Å”anu. Å is ir metaprogrammÄ“Å”anas veids.

Tomēr, kā zināms, par visu ir jāmaksā. Šajā gadījumā tas ir:

  • grÅ«tÄ«bas rakstÄ«t programmas
  • programmas izpildes ātrums

Tāpēc refleksija ir jāizmanto piesardzÄ«gi, piemēram, liela kalibra ierocis. Nepārdomāta refleksijas izmantoÅ”ana noved pie nelasāmām programmām, pastāvÄ«gām kļūdām un zema ātruma. TieÅ”i tā, lai snobs programmētājs varētu parādÄ«t savu kodu citu, pragmatiskāku un pieticÄ«gāku kolēģu priekŔā.

Kultūras bagāža no Sji? Nē, no vairākām valodām!

Līdz ar bagātību mantiniekiem tiek atstāti arī parādi.

Neskatoties uz to, ka daudzi uzskata, ka valoda pilnÄ«bā balstās uz C mantojumu, tas tā nav. Valoda ietver daudzus labāko programmÄ“Å”anas valodu aspektus.

sintakse

Pirmkārt, gramatisko struktÅ«ru sintakse balstās uz C valodas sintakse. Tomēr arÄ« DELPHI valodai bija bÅ«tiska ietekme. Tādējādi mēs redzam, ka liekās iekavas, kas ievērojami samazina programmas lasāmÄ«bu, ir pilnÄ«bā noņemtas. Valoda satur arÄ« DELPHI valodai raksturÄ«go operatoru ā€œ:=ā€. PakeÅ”u jēdziens ir aizgÅ«ts no tādām valodām kā ADA. Neizmantoto entÄ«tiju deklarācija ir aizgÅ«ta no PROLOG valodas.

Semantika

Pakotņu pamatā bija DELPHI valodas semantika. Katra pakotne iekapsulē datus un kodu un satur privātas un publiskas personas. Tas ļauj samazināt pakotnes saskarni līdz minimumam.

ÄŖstenoÅ”anas darbÄ«ba ar deleģēŔanas metodi tika aizgÅ«ta no DELPHI valodas.

Kompilācija

Ne velti ir kāds joks: Go tika izstrādāts, kamēr tika kompilēta C programma. Viena no valodas stiprajām pusēm ir tās Ä«paÅ”i ātra apkopoÅ”ana. Ideja tika aizgÅ«ta no DELPHI valodas. Katra Go pakotne atbilst DELPHI modulim. Å Ä«s paketes tiek pārkompilētas tikai tad, kad tas patieŔām ir nepiecieÅ”ams. Tāpēc pēc nākamās rediģēŔanas jums nav jākompilē visa programma, bet gan jāpārkompilē tikai mainÄ«tās pakotnes un pakotnes, kas ir atkarÄ«gas no Ŕīm mainÄ«tajām pakotnēm (un pat tad, tikai tad, ja ir mainÄ«juÅ”ies pakotņu saskarnes).

Augsta līmeņa konstrukcijas

Valoda satur daudz dažādu augsta līmeņa konstrukciju, kas nekādā veidā nav saistītas ar zema līmeņa valodām, piemēram, C.

  • StÄ«gas
  • Hash tabulas
  • Šķēles
  • Pīļu rakstÄ«Å”ana ir aizgÅ«ta no tādām valodām kā RUBY (kuru diemžēl daudzi nesaprot vai neizmanto pilnÄ«bā).

Atmiņas pārvaldība

Atmiņas pārvaldÄ«ba parasti ir pelnÄ«jusi atseviŔķu rakstu. Ja tādās valodās kā C++ vadÄ«ba ir pilnÄ«bā atstāta izstrādātāja ziņā, tad vēlākās valodās, piemēram, DELPHI, tika izmantots atsauces skaitÄ«Å”anas modelis. Izmantojot Å”o pieeju, cikliskas atsauces nebija atļautas, jo tika izveidotas bezsaimnieka kopas, tad Go ir iebÅ«vēta Ŕādu klasteru noteikÅ”ana (piemēram, C#). Turklāt atkritumu savācējs ir efektÄ«vāks nekā lielākā daļa paÅ”laik zināmo implementāciju, un to jau var izmantot daudziem reāllaika uzdevumiem. Valoda pati atpazÄ«st situācijas, kad kaudzē var pieŔķirt vērtÄ«bu mainÄ«gā glabāŔanai. Tas samazina atmiņas pārvaldnieka slodzi un palielina programmas ātrumu.

Vienlaicība un vienlaicība

Valodas paralēlisms un konkurētspēja ir neslavējama. Neviena zema lÄ«meņa valoda nevar pat attālināti konkurēt ar Go. TaisnÄ«bas labad gan jāatzÄ«mē, ka modeli nav izgudrojuÅ”i valodas autori, bet gan vienkārÅ”i aizgÅ«ts no vecās labās ADA valodas. Valoda spēj apstrādāt miljoniem paralēlu savienojumu, izmantojot visus CPU, vienlaikus tai ir daudz mazāk sarežģītas problēmas ar strupceļiem un sacensÄ«bu apstākļiem, kas raksturÄ«gi daudzpavedienu kodam.

Papildu priekŔrocības

Ja tas ir izdevīgi, visi kļūs nesavtīgi.

Valoda sniedz mums arī vairākas neapŔaubāmas priekŔrocības:

  • Viens izpildāms fails pēc projekta izveides ievērojami vienkārÅ”o lietojumprogrammu izvietoÅ”anu.
  • Statiskā rakstÄ«Å”ana un veida secinājumi var ievērojami samazināt kļūdu skaitu jÅ«su kodā, pat ja neraksta testus. Zinu dažus programmētājus, kuri vispār iztiek bez testu rakstÄ«Å”anas un viņu koda kvalitāte bÅ«tiski necieÅ”.
  • Ä»oti vienkārÅ”a standarta bibliotēkas savstarpēja kompilācija un lieliska pārnesamÄ«ba, kas ievērojami vienkārÅ”o starpplatformu lietojumprogrammu izstrādi.
  • RE2 regulārās izteiksmes ir droÅ”as pavedieniem, un tām ir paredzams izpildes laiks.
  • JaudÄ«ga standarta bibliotēka, kas ļauj lielākajai daļai projektu iztikt bez treŔās puses ietvariem.
  • Valoda ir pietiekami spēcÄ«ga, lai koncentrētos uz problēmu, nevis uz to, kā to atrisināt, tomēr pietiekami zema lÄ«meņa, lai problēmu varētu atrisināt efektÄ«vi.
  • Go eco sistēma jau satur izstrādātus rÄ«kus visiem gadÄ«jumiem: testi, dokumentācija, pakotņu pārvaldÄ«ba, jaudÄ«gi ieliktņi, kodu Ä£enerÄ“Å”ana, sacensÄ«bu apstākļu detektors utt.
  • Go versija 1.11 ieviesa iebÅ«vētu semantiskās atkarÄ«bas pārvaldÄ«bu, kas izveidota, izmantojot populāro VCS mitināŔanu. Visi rÄ«ki, kas veido Go ekosistēmu, izmanto Å”os pakalpojumus, lai vienā rāvienā lejupielādētu, izveidotu un instalētu kodu no tiem. Un tas ir lieliski. LÄ«dz ar versijas 1.11 ienākÅ”anu pilnÄ«bā tika atrisināta arÄ« problēma ar pakotņu versiju izveidi.
  • Tā kā valodas galvenā ideja ir samazināt maÄ£iju, valoda mudina izstrādātājus nepārprotami rÄ«koties ar kļūdām. Un tas ir pareizi, jo pretējā gadÄ«jumā tas vienkārÅ”i aizmirsÄ«s par kļūdu apstrādi. Vēl viena lieta ir tāda, ka lielākā daļa izstrādātāju apzināti ignorē kļūdu apstrādi, nevis tos apstrādātu, lai vienkārÅ”i pārsÅ«tÄ«tu kļūdu uz augÅ”u.
  • Valoda neÄ«steno klasisko OOP metodoloÄ£iju, jo tās tÄ«rā veidā Go nav virtualitātes. Tomēr, izmantojot saskarnes, tā nav problēma. OOP neesamÄ«ba ievērojami samazina iesācēju ienākÅ”anas barjeru.

VienkārŔība sabiedrības labā

To ir viegli sarežģīt, grūti vienkārŔot.

Go tika izstrādāts tā, lai tas bÅ«tu vienkārÅ”s, un tas izdodas sasniegt Å”o mērÄ·i. Tas tika rakstÄ«ts gudriem programmētājiem, kuri saprot komandas darba priekÅ”rocÄ«bas un ir noguruÅ”i no uzņēmuma lÄ«meņa valodu bezgalÄ«gās mainÄ«guma. Tā kā arsenālā ir salÄ«dzinoÅ”i neliels sintaktisko struktÅ«ru kopums, tas laika gaitā praktiski nav pakļauts izmaiņām, tāpēc izstrādātājiem ir daudz laika, kas tiek atbrÄ«vots attÄ«stÄ«bai, nevis bezgalÄ«gai valodas jauninājumu izpētei.

Uzņēmumi saņem arÄ« vairākas priekÅ”rocÄ«bas: zemā ienākÅ”anas barjera ļauj ātri atrast speciālistu, un valodas nemainÄ«gums ļauj izmantot vienu un to paÅ”u kodu arÄ« pēc 10 gadiem.

Secinājums

Lielais smadzeņu izmērs nekad nevienu ziloni nav padarījis par Nobela prēmijas laureātu.

Tiem programmētājiem, kuru personÄ«gais ego ir svarÄ«gāks par komandas garu, kā arÄ« teorētiÄ·iem, kuriem patÄ«k akadēmiskie izaicinājumi un nebeidzama "paÅ”pilnveidoÅ”anās", valoda ir patieŔām slikta, jo tā ir vispārējas nozÄ«mes amatniecÄ«bas valoda, kas neļauj iegÅ«t estētisku baudu no sava darba rezultāta un parādiet sevi profesionālu kolēģu priekŔā (ja mēs mēram intelektu pēc Å”iem kritērijiem, nevis pēc IQ). Tāpat kā viss dzÄ«vē, tas ir personÄ«go prioritāŔu jautājums. Tāpat kā visas vērtÄ«gās inovācijas, valoda jau ir nogājusi garu ceļu no vispārēja nolieguma lÄ«dz masveida pieņemÅ”anai. Valoda ir Ä£eniāla savā vienkārŔībā, un, kā zināms, viss Ä£eniālais ir vienkārÅ”s!

Avots: www.habr.com

Pievieno komentāru