Firwat Go ass schlecht fir onsmart Programméierer

Den Artikel gouf geschriwwen als Äntwert op eng virdru publizéiert antipodean Artikel.

Firwat Go ass schlecht fir onsmart Programméierer

An de leschten zwee-plus Joeren hunn ech Go benotzt fir e spezialiséierte RADIUS Server mat engem entwéckelte Rechnungssystem ëmzesetzen. Niewt dem Wee léieren ech d'Intricacies vun der Sprooch selwer. D'Programmer selwer si ganz einfach a sinn net den Zweck vun dësem Artikel, awer d'Erfahrung vu Go selwer verdéngt e puer Wierder a senger Verteidegung. Go gëtt eng ëmmer méi Mainstream Sprooch fir sérieux, skalierbare Code. D'Sprooch gouf vu Google erstallt, wou se aktiv benotzt gëtt. Bottom Line, ech mengen éierlech datt den Design vun der Go Sprooch schlecht ass fir UNintelligent Programméierer.

Entworf fir schwaach Programméierer?

Déi schwaach schwätzen vu Problemer. Déi staark Diskussioun iwwer Iddien an Dreem ...

Go ass ganz einfach ze léieren, sou einfach datt Dir de Code quasi ouni Training liese kënnt. Dës Feature vun der Sprooch gëtt a ville globalen Firmen benotzt wann de Code zesumme mat Net-Kär Spezialisten (Manager, Clienten, etc.) gelies gëtt. Dëst ass ganz bequem fir Methodologien wéi Design Driven Development.
Och Ufänger Programméierer fänken zimmlech anstänneg Code no enger Woch oder zwou ze produzéieren. D'Buch aus deem ech studéiert hunn ass "Go Programming" (vum Mark Summerfield). D'Buch ass ganz gutt, et beréiert vill Nuancen vun der Sprooch. No onnéideg komplizéierte Sprooche wéi Java, PHP, ass de Mangel u Magie erfrëschend. Awer fréier oder spéider, vill limitéiert Programméierer hunn d'Iddi al Methoden an engem neie Feld ze benotzen. Ass dat wierklech néideg?

De Rob Pike (den Haaptideolog vun der Sprooch) huet d'Go Sprooch als Industriesprooch erstallt, déi einfach ze verstoen an effektiv ze benotzen ass. D'Sprooch ass fir maximal Produktivitéit a groussen Teams entwéckelt an et gëtt keen Zweiwel doriwwer. Vill Ufänger Programméierer beschwéieren datt et vill Funktiounen sinn déi se fehlen. Dëse Wonsch fir Einfachheet war eng bewosst Entscheedung vun den Designer vun der Sprooch, a fir voll ze verstoen firwat et gebraucht gouf, musse mir d'Motivatioun vun den Entwéckler verstoen a wat se probéiert hunn am Go z'erreechen.

Also firwat gouf et sou einfach gemaach? Hei sinn e puer Zitater vum Rob Pike:

De Schlësselpunkt hei ass datt eis Programméierer keng Fuerscher sinn. Si sinn, an der Regel, zimlech jonk, kommen no engem Studium bei eis, vläicht hu se Java studéiert, oder C/C++, oder Python. Si kënne keng grouss Sprooch verstoen, awer gläichzäiteg wëlle mir datt se gutt Software kreéieren. Dofir sollt d'Sprooch einfach ze verstoen an ze léieren sinn.

Hie sollt vertraut sinn, ongeféier ähnlech wéi C. Programméierer, déi bei Google schaffen, fänken hir Carrière fréi un a si meeschtens mat prozedurale Sprooche vertraut, besonnesch d'C Famill. D'Ufuerderung fir séier Produktivitéit an enger neier Programméierungssprooch bedeit datt d'Sprooch net ze radikal sollt sinn.

Schlau Wierder, oder?

Artefakte vun der Einfachheet

Einfachheet ass eng noutwendeg Bedingung fir Schéinheet. Lev Tolstoi.

Et einfach ze halen ass ee vun de wichtegsten Ziler an all Design. Wéi Dir wësst, ass e perfekte Projet net e Projet wou et näischt ze addéieren ass, mee een aus deem et näischt ze läschen ass. Vill Leit gleewen datt fir komplex Problemer ze léisen (oder souguer auszedrécken), e komplext Tool gebraucht gëtt. Allerdéngs ass et net. Loosst eis d'PERL Sprooch zum Beispill huelen. Sproochideologen hunn gegleeft datt e Programméierer op d'mannst dräi verschidde Weeër sollt hunn fir ee Problem ze léisen. D'Ideologe vun der Go-Sprooch hunn en anere Wee gemaach, si hunn décidéiert datt ee Wee, awer e wierklech gutt, duergeet fir dat Zil z'erreechen. Dës Approche huet e seriöse Grondlag: deen eenzege Wee ass méi einfach ze léieren a méi schwéier ze vergiessen.

Vill Migrante beschwéieren datt d'Sprooch keng elegant Abstraktiounen enthält. Jo, dat ass richteg, awer dëst ass ee vun den Haaptvirdeeler vun der Sprooch. D'Sprooch enthält e Minimum vu Magie - sou datt keen déif Wëssen erfuerderlech ass fir de Programm ze liesen. Wat d'Verbositéit vum Code ugeet, ass dëst guer kee Problem. E gutt geschriwwene Golang Programm liest vertikal, mat wéineg oder guer keng Struktur. Zousätzlech ass d'Geschwindegkeet fir e Programm ze liesen op d'mannst eng Uerdnung vun der Gréisst méi grouss wéi d'Geschwindegkeet vum Schreiwen. Wann Dir bedenkt datt de ganze Code eenheetlech Formatéierung huet (mat dem agebaute gofmt Kommando gemaach), da liesen e puer extra Zeilen guer net e Problem.

Net ganz expressiv

Konscht toleréiert net wann hir Fräiheet ageschränkt ass. Genauegkeet ass net seng Verantwortung.

Wéinst dem Wonsch no Simplicitéit feelt Go Konstruktiounen, déi an anere Sprooche vun de Leit, déi hinnen gewinnt sinn, als eppes natierlech ugesi ginn. Am Ufank kann et e bëssen onbequem sinn, awer da mierkt Dir datt de Programm vill méi einfach a méi eendeiteg ze liesen ass.

Zum Beispill, e Konsol-Utility deen stdin liest oder eng Datei aus Kommandozeilargumenter géif esou ausgesinn:

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

D'Léisung vum selwechte Problem am D, obwuel se e bësse méi kuerz ausgesäit, ass net méi einfach ze liesen

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

Hell vun Kopie

De Mënsch dréit d'Häll a sech selwer. Martin Luther.

Ufänger beschwéieren dauernd iwwer Go wat de Mangel u Generika ugeet. Fir dëst Thema ze léisen, benotzen déi meescht vun hinnen direkten Code Kopie. Zum Beispill, eng Funktioun fir eng Lëscht vun ganz Zuelen ze summéieren, sou géifen Professionnelen gleewen datt d'Funktionalitéit net op eng aner Manéier ëmgesat ka ginn wéi duerch einfach Kopie-Paste fir all Datentyp.

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

D'Sprooch huet genuch Moyene fir esou Konstruktiounen ëmzesetzen. Zum Beispill, generesch Programméierung wier gutt.

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

An och wann eise Code e bësse méi laang war wéi de fréiere Fall, ass et generaliséiert ginn. Dofir wäert et fir eis net schwéier sinn all arithmetesch Operatiounen ëmzesetzen.

Vill wäert soen datt e Programm an D däitlech méi kuerz ausgesäit, a si wäerte richteg sinn.

import std.stdio;
import std.algorithm;

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

Wéi och ëmmer, et ass nëmme méi kuerz, awer net méi korrekt, well d'D Implementatioun de Problem vum Fehlerhandhabung komplett ignoréiert.

Am richtege Liewen, wéi d'Komplexitéit vun der Logik eropgeet, gëtt de Spalt séier enk. D'Lück gëtt nach méi séier zou wann Dir eng Handlung maache musst déi net mat Standardsproochoperateuren ausgefouert ka ginn.

Wat d'Ënnerhaltbarkeet, d'Erweiderbarkeet an d'Liesbarkeet ugeet, menger Meenung no, gewënnt d'Go Sprooch, obwuel se u Verbositéit verléiert.

Generaliséiert Programméierung an e puer Fäll gëtt eis onbestreideg Virdeeler. Dëst ass kloer duerch d'Sort Package illustréiert. Also, fir all Lëscht ze sortéieren, brauche mir just d'Sort.Interface Interface ëmzesetzen.

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

Wann Dir en Open Source Projet hëlt an de grep "Interface{}" -R Kommando leeft, gesitt Dir wéi dacks duerchernee Interfaces benotzt ginn. Enk-minded Komeroden wäert direkt soen, datt all dat ass wéinst dem Mangel vun Generics. Allerdéngs ass dat net ëmmer de Fall. Loosst eis DELPHI als Beispill huelen. Trotz der Präsenz vun deene selwechte Generika enthält et e speziellen VARIANT Typ fir Operatiounen mat arbiträren Datentypen. D'Go Sprooch mécht datselwecht.

Vun enger Kanoun zu Spatzen

An d'Sträitjacket muss d'Gréisst vum Wahnsinn passen. Stanislav Lech.

Vill extrem Fans kënne behaapten datt Go en anere Mechanismus huet fir Generika ze kreéieren - Reflexioun. A si wäerte richteg sinn ... awer nëmmen a rare Fäll.

De Rob Pike warnt eis:

Dëst ass e mächtegt Tool dat sollt mat Vorsicht benotzt ginn. Et soll vermeit ginn, ausser streng néideg.

Wikipedia seet eis déi folgend:

Reflexioun bezitt sech op de Prozess wärend e Programm seng eege Struktur a Verhalen während der Ausféierung iwwerwaache kann an änneren. D'Programméierungsparadigma ënnerierdesch Reflexioun gëtt reflektiv Programméierung genannt. Dëst ass eng Zort Metaprogramméierung.

Allerdéngs, wéi Dir wësst, musst Dir alles bezuelen. An dësem Fall ass et:

  • Schwieregkeeten Programmer ze schreiwen
  • Programm Ausféierung Vitesse

Dofir muss d'Reflexioun mat Vorsicht benotzt ginn, wéi eng grouss Kaliber Waff. Duerchduechte Notzung vu Reflexioun féiert zu onliesbare Programmer, konstante Feeler a gerénger Geschwindegkeet. Just d'Saach fir e Snob-Programméierer fir säi Code virun aneren, méi pragmateschen a bescheidenen Kollegen ze weisen.

Kulturgepäck vum Xi? Nee, aus enger Rei vu Sproochen!

Zesumme mam Verméigen ginn och Scholden un d'Ierwen hannerlooss.

Trotz der Tatsaach, datt vill gleewen datt d'Sprooch ganz op de C Patrimoine baséiert, ass dat net de Fall. D'Sprooch integréiert vill Aspekter vun de beschten Programméierungssproochen.

Siwebiergen

Als éischt ass d'Syntax vu grammatesche Strukture baséiert op der Syntax vun der C Sprooch. D'DELPHI Sprooch hat awer och e wesentlechen Afloss. Sou gesi mer datt déi iwwerflësseg Klammern, déi d'Liesbarkeet vum Programm staark reduzéieren, komplett ewechgeholl goufen. D'Sprooch enthält och den ":=" Bedreiwer inherent zu der DELPHI Sprooch. D'Konzept vu Packagen ass aus Sprooche wéi ADA geléint. D'Deklaratioun vun onbenotzten Entitéite gëtt aus der PROLOG Sprooch geléint.

Semantik

D'Package baséieren op der Semantik vun der DELPHI Sprooch. All Package encapsuléiert Daten a Code an enthält privat an ëffentlech Entitéiten. Dëst erlaabt Iech de Package Interface op e Minimum ze reduzéieren.

D'Ëmsetzungsoperatioun duerch Delegatiounsmethod gouf vun der DELPHI Sprooch geléint.

Kompiléierung

Et ass net ouni Grond datt et e Witz gëtt: Go gouf entwéckelt wärend e C Programm kompiléiert gouf. Ee vun de Stäerkten vun der Sprooch ass hir ultra-schnell Zesummesetzung. D'Iddi gouf vun der DELPHI Sprooch geléint. All Go Package entsprécht engem DELPHI Modul. Dës Packagen ginn nëmmen nei kompiléiert wann et wierklech néideg ass. Dofir, no der nächster Ännerung, braucht Dir net de ganze Programm ze kompiléieren, mee just déi geännert Packagen a Packagen nei kompiléieren, déi vun dëse geännerten Packagen ofhängeg sinn (an och dann, nëmmen wann d'Paketschnëttplazen geännert hunn).

Héich-Niveau Konstruktiounen

D'Sprooch enthält vill verschidde High-Level Konstrukter déi op kee Fall mat nidderegen Niveau Sprooche wéi C.

  • Linnen
  • Hash Dëscher
  • Scheiwen
  • Duck Typing gëtt aus Sprooche wéi RUBY geléint (déi leider vill net verstinn oder säi vollt Potenzial benotzen).

Erënnerung Gestioun

Memory Management verdéngt allgemeng en separaten Artikel. Wann a Sprooche wéi C ++ d'Kontroll komplett dem Entwéckler iwwerlooss ass, dann a spéider Sprooche wéi DELPHI gouf e Referenzzielmodell benotzt. Mat dëser Approche waren zyklesch Referenzen net erlaabt, well Orphan Cluster geformt goufen, dann huet Go eng agebauter Detektioun vu sou Cluster (wéi C #). Zousätzlech ass de Müllsammler méi effizient wéi déi meescht aktuell bekannt Implementatiounen a ka scho fir vill Echtzäit Aufgaben benotzt ginn. D'Sprooch selwer erkennt Situatiounen wann e Wäert fir eng Variabel ze späicheren kann op de Stack zougewisen ginn. Dëst reduzéiert d'Laascht op de Memory Manager a erhéicht d'Vitesse vum Programm.

Concurrency a Concurrency

De Parallelismus an d'Kompetitivitéit vun der Sprooch ass iwwer Luef. Keng niddereg-Niveau Sprooch ka souguer op afstand mat Go konkurréiere. Fir fair ze sinn, ass et derwäert ze bemierken datt de Modell net vun den Auteuren vun der Sprooch erfonnt gouf, awer einfach aus der gudder aler ADA Sprooch geléint gouf. D'Sprooch ass fäeg Millioune vu parallele Verbindunge mat all CPUs ze veraarbechten, wärend eng Uerdnung vun der Gréisst manner komplex Probleemer mat Deadlocks a Rennbedéngungen hunn, déi typesch fir Multi-threaded Code sinn.

Zousätzlech Virdeeler

Wann et rentabel ass, wäert jiddereen selbstlos ginn.

Sprooch bitt eis och eng Rei vun zweifelhaften Virdeeler:

  • Eng eenzeg ausführbar Datei nom Bau vum Projet vereinfacht vill d'Deployment vun Uwendungen.
  • Statesch Tippen an Typinferenz kënnen d'Zuel vu Feeler an Ärem Code wesentlech reduzéieren, och ouni Tester ze schreiwen. Ech kennen e puer Programméierer déi iwwerhaapt ouni Tester schreiwen an d'Qualitéit vun hirem Code net vill leiden.
  • Ganz einfach Cross-Kompilatioun an exzellent Portabilitéit vun der Standardbibliothéik, wat d'Entwécklung vu Cross-Plattform Uwendungen immens vereinfacht.
  • RE2 regulär Ausdréck si thread-sécher an hunn prévisibel Ausféierungszäiten.
  • Eng mächteg Standardbibliothéik déi déi meescht Projeten erlaabt ouni Drëtt Partei Kaderen ze maachen.
  • D'Sprooch ass mächteg genuch fir op de Problem ze fokusséieren anstatt wéi et ze léisen, awer niddereg-Niveau genuch datt de Problem effizient geléist ka ginn.
  • De Go Öko System enthält schonn entwéckelt Tools aus der Këscht fir all Occasiounen: Tester, Dokumentatioun, Package Management, mächteg Linters, Code Generatioun, Race Conditioun Detektor, etc.
  • Go Versioun 1.11 agefouert agebaute semantesche Ofhängegkeetsmanagement, gebaut uewen op populäre VCS Hosting. All d'Tools, déi de Go-Ökosystem ausmaachen, benotzen dës Servicer fir de Code vun hinnen an engem Schlag erofzelueden, ze bauen an z'installéieren. An dat ass super. Mat der Arrivée vun der Versioun 1.11 gouf de Problem mat der Package Versioun och komplett geléist.
  • Well d'Käridee vun der Sprooch ass d'Magie ze reduzéieren, encouragéiert d'Sprooch d'Entwéckler fir explizit Fehlerhandhabung ze maachen. An dat ass richteg, well soss wäert et einfach iwwer d'Fehlerhandhabung vergiessen. Eng aner Saach ass datt déi meescht Entwéckler bewosst Fehlerhandhabung ignoréieren, léiwer amplaz se ze veraarbechten fir de Feeler einfach no uewen weiderzebréngen.
  • D'Sprooch implementéiert net déi klassesch OOP-Methodologie, well a senger reiner Form keng Virtualitéit am Go gëtt. Wéi och ëmmer, dëst ass kee Problem wann Dir Interfaces benotzt. D'Feele vu OOP reduzéiert d'Barrière fir d'Entrée fir Ufänger wesentlech.

Einfachheet fir Gemeinschaftsvirdeeler

Et ass einfach ze komplizéieren, schwéier ze vereinfachen.

Go gouf entwéckelt fir einfach ze sinn an et geléngt bei deem Zil. Et gouf geschriwwen fir intelligent Programméierer déi d'Virdeeler vun der Teamwork verstinn an midd vun der endloser Verännerlechkeet vun Enterprise-Niveau Sproochen. E relativ klenge Set vu syntaktesch Strukturen a sengem Arsenal ze hunn, ass et praktesch net mat der Zäit ënnerleien, sou datt d'Entwéckler vill Zäit fir d'Entwécklung fräigelooss hunn, an net fir endlos Sproochinnovatiounen ze studéieren.

Firmen kréien och eng Rei vu Virdeeler: eng niddereg Entrée Barrière erlaabt hinnen séier e Spezialist ze fannen, an der immutability vun der Sprooch erlaabt hinnen de selwechte Code och no 10 Joer ze benotzen.

Konklusioun

Grouss Gehirgréisst huet ni en Elefant zum Nobelpräis Gewënner gemaach.

Fir déi Programméierer deenen hire perséinlechen Ego Virrang iwwer Teamgeescht huet, souwéi Theoretiker déi akademesch Erausfuerderunge gär hunn an endlos "Selbstverbesserung" gär hunn, ass d'Sprooch wierklech schlecht, well et ass eng allgemeng Zweck Handwierkssprooch déi Iech net erlaabt ze kréien Ästhetesch Genoss vum Resultat vun Ärer Aarbecht a weisen Iech professionell virun Kollegen (virausgesat datt mir Intelligenz no dëse Critèren moossen, an net mam IQ). Wéi alles am Liewen ass et eng Saach vu perséinleche Prioritéite. Wéi all wäertvoll Innovatiounen, ass d'Sprooch scho wäit vun der universeller Verweigerung bis Massakzeptanz komm. D'Sprooch ass genial a senger Einfachheet, a wéi Dir wësst, alles genial ass einfach!

Source: will.com

Setzt e Commentaire