Għaliex Go Design Huwa Ħażin għall-Programmaturi Intelliġenti

Matul l-aħħar xhur kont qed nuża Go għall-implimentazzjonijiet. Prova tal-Kunċett (madwar.: kodiċi biex tittestja l-funzjonalità ta 'idea) fil-ħin liberu tiegħu, parzjalment biex tistudja l-lingwa ta' programmar innifsu. Il-programmi nfushom huma sempliċi ħafna u mhumiex l-iskop ta 'dan l-artikolu, iżda l-esperjenza tal-użu ta' Go stess jistħoqqilha ftit kliem dwarha. Mur iwiegħed li tkun (madwar.: artikolu miktub fl-2015) lingwa popolari għal kodiċi skalabbli serju. Il-lingwa ġiet maħluqa minn Google, fejn tintuża b'mod attiv. Bottom line, onestament naħseb li d-disinn tal-lingwa Go huwa ħażin għal programmaturi intelliġenti.

Iddisinjat għal programmaturi dgħajfa?

Go huwa faċli ħafna biex titgħallem, tant faċli li l-introduzzjoni ħaditni waħda filgħaxija, u wara kont diġà stajt nikkodifika b'mod produttiv. Il-ktieb li kont nitgħallem Go jissejjaħ Introduzzjoni għall-Ipprogrammar f'Go (traduzzjoni), huwa disponibbli onlajn. Il-ktieb, bħall-kodiċi tas-sors Go innifsu, huwa faċli biex jinqara, għandu eżempji ta 'kodiċi tajbin, u fih madwar 150 paġna li jistgħu jinqraw f'seduta waħda. Din is-sempliċità hija iġjeniċi għall-ewwel, speċjalment f'dinja tal-ipprogrammar mimlija b'teknoloġija kkumplikata żżejjed. Imma fl-aħħar, illum jew għada jqum il-ħsieb: “Dan hu tassew hekk?”

Google ssostni li s-sempliċità ta 'Go hija l-punt ta' bejgħ tagħha u l-lingwa hija mfassla għall-produttività massima f'timijiet kbar, iżda niddubitaha. Hemm karatteristiċi li huma jew neqsin jew dettaljati żżejjed. U kollha minħabba nuqqas ta' fiduċja fl-iżviluppaturi, bis-suppożizzjoni li ma jistgħux jagħmlu xejn tajjeb. Din ix-xewqa għas-sempliċità kienet deċiżjoni konxja mid-disinjaturi tal-lingwa, u sabiex nifhmu bis-sħiħ għaliex kienet meħtieġa, irridu nifhmu l-motivazzjoni tal-iżviluppaturi u dak li kienu qed jippruvaw jiksbu f'Go.

Allura għaliex saret daqshekk sempliċi? Hawn huma ftit kwotazzjonijiet Rob Pike (madwar.: wieħed mill-ko-kreaturi tal-lingwa Go):

Il-punt ewlieni hawnhekk huwa li l-programmaturi tagħna (madwar.: Googlers) mhumiex riċerkaturi. Huma, bħala regola, pjuttost żgħar, jiġu għandna wara li studjaw, forsi studjaw Java, jew C/C++, jew Python. Ma jistgħux jifhmu lingwa kbira, iżda fl-istess ħin irridu li joħolqu softwer tajjeb. Huwa għalhekk li l-lingwa tagħhom għandha tkun faċli għalihom biex jifhmu u jitgħallmu.
 
Huwa għandu jkun familjari, bejn wieħed u ieħor simili għal C. Il-programmaturi li jaħdmu ma' Google jibdew il-karriera tagħhom kmieni u huma l-aktar familjari mal-lingwi proċedurali, b'mod partikolari l-familja C. Ir-rekwiżit għal produttività ta' malajr f'lingwa ta' programmar ġdida tfisser li l-lingwa m'għandhiex tkun radikali wisq.

Xiex? Allura Rob Pike bażikament qed jgħid li l-iżviluppaturi tal-Google mhumiex daqshekk tajbin, għalhekk ħolqu lingwa għall-idioti (madwar.: dumbed down) sabiex ikunu jistgħu jagħmlu xi ħaġa. X'tip ta' ħarsa arroganti lejn il-kollegi tiegħek? Dejjem emmint li l-iżviluppaturi tal-Google jintgħażlu bl-idejn mill-isbaħ u l-aqwa fid-Dinja. Żgur li jistgħu jimmaniġġjaw xi ħaġa aktar diffiċli?

Artifacts ta 'sempliċità eċċessiva

Li tkun sempliċi hija mira denja fi kwalunkwe disinn, u li tipprova tagħmel xi ħaġa sempliċi hija diffiċli. Madankollu, meta tipprova ssolvi (jew saħansitra tesprimi) problemi kumplessi, xi drabi tkun meħtieġa għodda kumplessa. Il-kumplessità u l-kumplessità mhumiex l-aqwa karatteristiċi ta 'lingwa ta' programmar, iżda hemm triq tan-nofs li fiha l-lingwa tista 'toħloq astrazzjonijiet eleganti li huma faċli biex jinftiehmu u jintużaw.

Mhux espressiv ħafna

Minħabba l-impenn tagħha għas-sempliċità, Go m'għandhiex kostruzzjonijiet li huma pperċepiti bħala naturali f'lingwi oħra. Dan jista 'jidher bħala idea tajba għall-ewwel, iżda fil-prattika tirriżulta f'kodiċi verbose. Ir-raġuni għal dan għandha tkun ovvja - jeħtieġ li jkun faċli għall-iżviluppaturi biex jaqraw il-kodiċi ta 'nies oħrajn, iżda fil-fatt dawn is-simplifikazzjonijiet jagħmlu ħsara biss lill-leġibilità. M'hemm l-ebda abbrevjazzjonijiet f'Go: jew ħafna jew xejn.

Pereżempju, utilità tal-console li taqra stdin jew fajl mill-argumenti tal-linja tal-kmand tkun tidher bħal din:

package main

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

func main() {

    flag.Parse()
    flags := flag.Args()

    var text string
    var scanner *bufio.Scanner
    var err error

    if len(flags) > 0 {

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

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

        scanner = bufio.NewScanner(file)

    } else {
        scanner = bufio.NewScanner(os.Stdin)
    }

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

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

    fmt.Println(text)
}

Għalkemm dan il-kodiċi jipprova wkoll ikun ġenerali kemm jista 'jkun, il-verbożità sfurzata ta' Go tfixkel, u bħala riżultat, is-soluzzjoni ta 'problema sempliċi tirriżulta f'ammont kbir ta' kodiċi.

Hawnhekk, per eżempju, hija soluzzjoni għall-istess problema fil D:

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

U min jista' jinqara aktar issa? Nagħti l-vot tiegħi lil D. Il-kodiċi tiegħu jinqara ħafna aktar għax jiddeskrivi l-azzjonijiet b'mod aktar ċar. D juża kunċetti ħafna aktar kumplessi (madwar.: sejħa ta' funzjoni alternattiva и mudelli) milli fl-eżempju Go, iżda m'hemm verament xejn ikkumplikat biex tifhimhom.

Infern tal-ikkupjar

Suġġeriment popolari għat-titjib tal-Go huwa l-ġeneralità. Dan għall-inqas jgħin biex jevita l-ikkupjar bla bżonn tal-kodiċi biex jappoġġja t-tipi kollha tad-dejta. Pereżempju, funzjoni biex tinġabar lista ta' numri interi ma tista' tiġi implimentata bl-ebda mod ieħor ħlief billi tikkopja u titwaħħal il-funzjoni bażika tagħha għal kull tip ta' numru sħiħ; m'hemm l-ebda mod ieħor:

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 int16Sum(list []int16) (uint64) {
    var result int16 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

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

func main() {

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

    fmt.Println(int8Sum(list8))
    fmt.Println(int16Sum(list16))
    fmt.Println(int32Sum(list32))
    fmt.Println(int64Sum(list64))
}

U dan l-eżempju lanqas biss jaħdem għal tipi ffirmati. Dan l-approċċ jikser kompletament il-prinċipju li ma tirrepetix lilek innifsek (DRY), wieħed mill-prinċipji l-aktar famużi u ovvji, li jinjora liema huwa s-sors ta 'ħafna żbalji. Għaliex Go jagħmel dan? Dan huwa aspett terribbli tal-lingwa.

L-istess eżempju fuq D:

import std.stdio;
import std.algorithm;

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

Sempliċi, eleganti u dritta sal-punt. Il-funzjoni użata hawnhekk hija reduce għat-tip ta' mudell u l-predikat. Iva, dan huwa għal darb'oħra aktar ikkumplikat mill-verżjoni Go, iżda mhux daqshekk diffiċli għall-programmaturi intelliġenti biex jifhmu. Liema eżempju huwa aktar faċli biex jinżamm u aktar faċli biex jinqara?

Bypass tas-sistema tat-tip sempliċi

Nimmaġina li l-programmaturi ta’ Go jaqraw dan se jkunu qed jagħmlu r-ragħwa fil-ħalq u jgħajtu, “Int qed tagħmlu ħażin!” Ukoll, hemm mod ieħor biex tagħmel funzjoni u tipi ġeneriċi, iżda tkisser kompletament is-sistema tat-tip!

Agħti ħarsa lejn dan l-eżempju ta’ soluzzjoni stupida tal-lingwa biex taħdem madwar il-problema:

package main

import "fmt"
import "reflect"

func Reduce(in interface{}, memo interface{}, fn func(interface{}, interface{}) interface{}) interface{} {
    val := reflect.ValueOf(in)

    for i := 0; i < val.Len(); i++ {
        memo = fn(val.Index(i).Interface(), memo)
    }

    return memo
}

func main() {

    list := []int{1, 2, 3, 4, 5}

    result := Reduce(list, 0, func(val interface{}, memo interface{}) interface{} {
        return memo.(int) + val.(int)
    })

    fmt.Println(result)
}

Din l-implimentazzjoni Reduce ġie misluf mill-artiklu Ġeneriċi idjomatiċi f'Go (madwar.: Ma stajtx insib it-traduzzjoni, inkun kuntent jekk tgħin f’dan). Ukoll, jekk huwa idjomatiku, ddejjaqni nara eżempju mhux idjomatiku. Użu interface{} - farsa, u fil-lingwa hija meħtieġa biss biex tevita l-ittajpjar. Din hija interface vojta u t-tipi kollha jimplimentawha, li tippermetti libertà sħiħa għal kulħadd. Dan l-istil ta’ programmar huwa ikrah ħafna, u dan mhux kollox. Acrobatic feats bħal dawn jeħtieġu l-użu ta 'runtime riflessjoni. Anke Rob Pike ma jħobbx individwi li jabbużaw minn dan, kif semma f’wieħed mir-rapporti tiegħu.

Din hija għodda qawwija li għandha tintuża b'kawtela. Għandu jiġi evitat sakemm ma jkunx strettament meħtieġ.

Jien nieħu D templates minflok dan in-nonsense. Kif jista’ xi ħadd jgħid hekk interface{} aktar jinqara jew saħansitra tip sigur?

Il-gwaj tal-Ġestjoni tad-Dipendenza

Go għandha sistema ta 'dipendenza mibnija fuq fornituri ta' hosting popolari VCS. L-għodod li jiġu ma' Go jafu dwar dawn is-servizzi u jistgħu jniżżlu, jibnu u jinstallaw kodiċi minnhom f'daqqa waħda. Filwaqt li dan huwa kbir, hemm difett kbir fil-verżjoni! Iva, huwa veru li tista 'tikseb il-kodiċi tas-sors minn servizzi bħal github jew bitbucket billi tuża għodod Go, iżda ma tistax tispeċifika l-verżjoni. U għal darb'oħra sempliċità għad-detriment tal-utilità. Jien ma nistax nifhem il-loġika ta' deċiżjoni bħal din.

Wara li staqsa mistoqsijiet dwar soluzzjoni għal din il-problema, it-tim ta 'żvilupp Go ħoloq ħajt tal-forum, li ddeskriviet kif kienu se jduru din il-kwistjoni. Ir-rakkomandazzjoni tagħhom kienet li sempliċement tikkopja r-repożitorju kollu fil-proġett tiegħek jum wieħed u tħallih "kif inhu." X'inhu l-infern qed jaħsbu? Għandna sistemi aqwa ta 'kontroll tal-verżjoni b'tikkettar kbir u appoġġ għall-verżjoni li l-ħallieqa Go jinjoraw u tikkopja biss il-kodiċi tas-sors.

Bagalji kulturali minn Xi

Fl-opinjoni tiegħi, Go ġie żviluppat minn nies li użaw is-C ħajjithom kollha u minn dawk li ma ridux jippruvaw xi ħaġa ġdida. Il-lingwa tista' tiġi deskritta bħala Ċ b'roti żejda (orig.: roti tat-taħriġ). M'hemm l-ebda ideat ġodda fiha, ħlief għall-appoġġ għall-paralleliżmu (li, mill-mod, huwa sabiħ) u dan huwa tal-mistħija. Għandek paralleliżmu eċċellenti f'lingwaġġ li ma tantx jista' jintuża u zopop.

Problema oħra li tixxejjen hija li Go hija lingwa proċedurali (bħall-orrur siekta ta 'C). Tispiċċa tikteb kodiċi fi stil proċedurali li jħossu arkajku u skadut. Naf li l-ipprogrammar orjentat lejn l-oġġett mhuwiex bulit tal-fidda, iżda jkun kbir li tkun tista 'tastrat id-dettalji f'tipi u tipprovdi inkapsulament.

Sempliċità għall-benefiċċju tiegħek

Go kienet iddisinjata biex tkun sempliċi u tirnexxi f'dak l-għan. Kien miktub għal programmaturi dgħajfa, bl-użu ta 'lingwa qadima bħala mudell. Jiġi komplut b'għodda sempliċi biex tagħmel affarijiet sempliċi. Huwa faċli biex taqra u faċli biex tużah.

Huwa estremament verbose, mhux impressjonanti, u ħażin għal programmaturi intelliġenti.

Grazzi mersinvald għall-editjar

Sors: www.habr.com

Żid kumment