స్మార్ట్ ప్రోగ్రామర్‌లకు గో డిజైన్ ఎందుకు చెడ్డది

గత నెలల్లో నేను అమలుల కోసం గోని ఉపయోగిస్తున్నాను. కాన్సెప్ట్ యొక్క రుజువు (సుమారు: ఆలోచన యొక్క కార్యాచరణను పరీక్షించడానికి కోడ్) అతని ఖాళీ సమయంలో, పాక్షికంగా ప్రోగ్రామింగ్ భాషను అధ్యయనం చేయడానికి. ప్రోగ్రామ్‌లు చాలా సరళమైనవి మరియు ఈ కథనం యొక్క ఉద్దేశ్యం కాదు, కానీ గోను ఉపయోగించిన అనుభవం దాని గురించి కొన్ని పదాలకు అర్హమైనది. గో వాగ్దానం చేస్తుంది (సుమారు: 2015లో వ్రాసిన వ్యాసం) తీవ్రమైన స్కేలబుల్ కోడ్ కోసం ఒక ప్రసిద్ధ భాష. భాష Google ద్వారా సృష్టించబడింది, ఇక్కడ అది చురుకుగా ఉపయోగించబడుతుంది. బాటమ్ లైన్, గో భాష రూపకల్పన స్మార్ట్ ప్రోగ్రామర్‌లకు చెడ్డదని నేను నిజాయితీగా భావిస్తున్నాను.

బలహీనమైన ప్రోగ్రామర్ల కోసం రూపొందించబడిందా?

గో నేర్చుకోవడం చాలా సులభం, కాబట్టి పరిచయం నాకు ఒక సాయంత్రం పట్టింది, ఆ తర్వాత నేను ఇప్పటికే ఉత్పాదకంగా కోడ్ చేయగలను. నేను గో నేర్చుకునే పుస్తకాన్ని అంటారు గోలో ప్రోగ్రామింగ్‌కు ఒక పరిచయం (అనువాదం), ఇది ఆన్‌లైన్‌లో అందుబాటులో ఉంది. ఈ పుస్తకం, గో సోర్స్ కోడ్ లాగా, చదవడం సులభం, మంచి కోడ్ ఉదాహరణలను కలిగి ఉంది మరియు దాదాపు 150 పేజీలను కలిగి ఉంది, వీటిని ఒకేసారి చదవవచ్చు. ఈ సరళత మొదట్లో రిఫ్రెష్‌గా ఉంటుంది, ప్రత్యేకించి చాలా సంక్లిష్టమైన సాంకేతికతతో నిండిన ప్రోగ్రామింగ్ ప్రపంచంలో. కానీ చివరికి, ముందుగానే లేదా తరువాత ఆలోచన పుడుతుంది: "ఇది నిజంగా అలా ఉందా?"

గో యొక్క సరళత దాని అమ్మకపు పాయింట్ అని Google పేర్కొంది మరియు భాష పెద్ద జట్లలో గరిష్ట ఉత్పాదకత కోసం రూపొందించబడింది, కానీ నాకు అనుమానం ఉంది. తప్పిపోయిన లేదా చాలా వివరంగా ఉన్న లక్షణాలు ఉన్నాయి. మరియు డెవలపర్‌లపై నమ్మకం లేకపోవడం వల్ల, వారు సరిగ్గా ఏమీ చేయలేకపోతున్నారనే భావనతో. సరళత కోసం ఈ కోరిక అనేది భాష యొక్క రూపకర్తల చేతన నిర్ణయం, మరియు అది ఎందుకు అవసరమో పూర్తిగా అర్థం చేసుకోవడానికి, డెవలపర్‌ల ప్రేరణ మరియు వారు గోలో ఏమి సాధించడానికి ప్రయత్నిస్తున్నారో మనం అర్థం చేసుకోవాలి.

కాబట్టి ఇది ఎందుకు చాలా సరళంగా చేయబడింది? ఇక్కడ కొన్ని కోట్స్ ఉన్నాయి రాబ్ పైక్ (సుమారు: గో భాష యొక్క సహ-సృష్టికర్తలలో ఒకరు):

ఇక్కడ ముఖ్య విషయం ఏమిటంటే మా ప్రోగ్రామర్లు (సుమారు: గూగ్లర్లు) పరిశోధకులు కాదు. వారు, ఒక నియమం వలె, చాలా చిన్నవారు, చదువుకున్న తర్వాత మా వద్దకు వస్తారు, బహుశా వారు జావా, లేదా C/C++, లేదా పైథాన్‌ని చదివారు. వారు గొప్ప భాషను అర్థం చేసుకోలేరు, కానీ అదే సమయంలో వారు మంచి సాఫ్ట్‌వేర్‌ను సృష్టించాలని మేము కోరుకుంటున్నాము. అందుకే వారి భాష సులువుగా అర్థం చేసుకుని నేర్చుకునేలా ఉండాలి.
 
అతను సుపరిచితుడై ఉండాలి, ఇంచుమించుగా సి లాగానే మాట్లాడాలి. Googleలో పనిచేస్తున్న ప్రోగ్రామర్లు తమ కెరీర్‌ను ముందుగానే ప్రారంభిస్తారు మరియు ఎక్కువగా విధానపరమైన భాషలతో, ముఖ్యంగా C కుటుంబానికి బాగా తెలుసు. కొత్త ప్రోగ్రామింగ్ లాంగ్వేజ్‌లో శీఘ్ర ఉత్పాదకత అవసరం అంటే భాష చాలా రాడికల్‌గా ఉండకూడదు.

ఏమిటి? కాబట్టి గూగుల్‌లోని డెవలపర్‌లు అంత మంచివారు కాదని, అందుకే వారు ఇడియట్స్ కోసం ఒక భాషను సృష్టించారని రాబ్ పైక్ ప్రాథమికంగా చెబుతున్నారు (సుమారు: మూగబోయింది) తద్వారా వారు ఏదైనా చేయగలరు. మీ స్వంత సహోద్యోగులను ఎలాంటి అహంకారపూరితంగా చూస్తారు? Google డెవలపర్‌లు భూమిపై అత్యంత ప్రకాశవంతమైన మరియు ఉత్తమమైన వారి నుండి ఎంపిక చేయబడతారని నేను ఎల్లప్పుడూ నమ్ముతున్నాను. ఖచ్చితంగా వారు మరింత కష్టమైనదాన్ని నిర్వహించగలరా?

మితిమీరిన సరళత యొక్క కళాఖండాలు

ఏదైనా డిజైన్‌లో సరళంగా ఉండటం విలువైన లక్ష్యం, మరియు ఏదైనా సరళంగా చేయడానికి ప్రయత్నించడం కష్టం. అయినప్పటికీ, సంక్లిష్ట సమస్యలను పరిష్కరించడానికి (లేదా వ్యక్తీకరించడానికి) ప్రయత్నిస్తున్నప్పుడు, కొన్నిసార్లు సంక్లిష్టమైన సాధనం అవసరమవుతుంది. సంక్లిష్టత మరియు సంక్లిష్టత ప్రోగ్రామింగ్ భాష యొక్క ఉత్తమ లక్షణాలు కాదు, కానీ భాష అర్థం చేసుకోవడానికి మరియు ఉపయోగించడానికి సులభమైన సొగసైన నైరూప్యతను సృష్టించగల మధ్యస్థం ఉంది.

చాలా వ్యక్తీకరణ కాదు

సరళతకు దాని నిబద్ధత కారణంగా, ఇతర భాషలలో సహజంగా భావించే నిర్మాణాలు గోకి లేవు. ఇది మొదట మంచి ఆలోచనగా అనిపించవచ్చు, కానీ ఆచరణలో ఇది వెర్బోస్ కోడ్‌కు దారి తీస్తుంది. దీనికి కారణం స్పష్టంగా ఉండాలి - డెవలపర్‌లు ఇతరుల కోడ్‌ను చదవడం సులభం కావాలి, అయితే వాస్తవానికి ఈ సరళీకరణలు చదవడానికి మాత్రమే హాని కలిగిస్తాయి. గోలో సంక్షిప్తాలు లేవు: చాలా లేదా ఏమీ లేదు.

ఉదాహరణకు, కమాండ్ లైన్ ఆర్గ్యుమెంట్‌ల నుండి stdin లేదా ఫైల్‌ని చదివే కన్సోల్ యుటిలిటీ ఇలా కనిపిస్తుంది:

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

ఈ కోడ్ కూడా సాధ్యమైనంత సాధారణమైనదిగా ఉండటానికి ప్రయత్నించినప్పటికీ, గో యొక్క బలవంతపు వెర్బోసిటీ దారిలోకి వస్తుంది మరియు ఫలితంగా, ఒక సాధారణ సమస్యను పరిష్కరించడం వలన పెద్ద మొత్తంలో కోడ్ వస్తుంది.

ఇక్కడ, ఉదాహరణకు, అదే సమస్యకు పరిష్కారం 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);
    }
}

మరియు ఇప్పుడు ఎవరు ఎక్కువ చదవగలరు? నేను నా ఓటును Dకి ఇస్తాను. అతను చర్యలను మరింత స్పష్టంగా వివరించినందున అతని కోడ్ మరింత చదవగలిగేలా ఉంది. D చాలా క్లిష్టమైన భావనలను ఉపయోగిస్తుంది (సుమారు: ప్రత్యామ్నాయ ఫంక్షన్ కాల్ и నమూనాలను) గో ఉదాహరణలో కంటే, కానీ వాటిని అర్థం చేసుకోవడంలో సంక్లిష్టంగా ఏమీ లేదు.

కాపీ కొట్టడం

గోను మెరుగుపరచడానికి ఒక ప్రసిద్ధ సూచన సాధారణత. అన్ని డేటా రకాలకు మద్దతు ఇవ్వడానికి ఇది కనీసం అనవసరమైన కోడ్ కాపీని నివారించడంలో సహాయపడుతుంది. ఉదాహరణకు, పూర్ణాంకాల జాబితాను సంక్షిప్తం చేయడానికి ఒక ఫంక్షన్ ప్రతి పూర్ణాంకాల రకానికి దాని ప్రాథమిక ఫంక్షన్‌ను కాపీ-పేస్ట్ చేయడం ద్వారా తప్ప వేరే మార్గంలో అమలు చేయబడదు; వేరే మార్గం లేదు:

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

మరియు ఈ ఉదాహరణ సంతకం చేసిన రకాలకు కూడా పని చేయదు. ఈ విధానం మిమ్మల్ని పునరావృతం చేయకూడదనే సూత్రాన్ని పూర్తిగా ఉల్లంఘిస్తుంది (DRY), అత్యంత ప్రసిద్ధ మరియు స్పష్టమైన సూత్రాలలో ఒకటి, ఇది అనేక లోపాల మూలంగా ఉంది. గో ఇలా ఎందుకు చేస్తుంది? ఇది భాష యొక్క భయంకరమైన అంశం.

D లో అదే ఉదాహరణ:

import std.stdio;
import std.algorithm;

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

సరళమైనది, సొగసైనది మరియు పాయింట్‌కి సూటిగా ఉంటుంది. ఇక్కడ ఉపయోగించిన ఫంక్షన్ reduce టెంప్లేట్ రకం మరియు ప్రిడికేట్ కోసం. అవును, ఇది మళ్లీ గో వెర్షన్ కంటే చాలా క్లిష్టంగా ఉంటుంది, కానీ స్మార్ట్ ప్రోగ్రామర్‌లకు అర్థం చేసుకోవడం అంత కష్టం కాదు. ఏ ఉదాహరణ నిర్వహించడం సులభం మరియు చదవడం సులభం?

సాధారణ రకం సిస్టమ్ బైపాస్

దీన్ని చదివే గో ప్రోగ్రామర్లు నోటి నుండి నురగలు కక్కుతూ, “మీరు తప్పు చేస్తున్నారు!” అని అరుస్తారని నేను ఊహించాను. బాగా, జెనరిక్ ఫంక్షన్ మరియు రకాలను చేయడానికి మరొక మార్గం ఉంది, కానీ ఇది పూర్తిగా టైప్ సిస్టమ్‌ను విచ్ఛిన్నం చేస్తుంది!

సమస్యను పరిష్కరించేందుకు తెలివితక్కువ భాష పరిష్కారానికి ఈ ఉదాహరణను చూడండి:

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

ఈ అమలు Reduce వ్యాసం నుండి తీసుకోబడింది గోలో ఇడియోమాటిక్ జెనరిక్స్ (సుమారు: నేను అనువాదాన్ని కనుగొనలేకపోయాను, మీరు దీనికి సహాయం చేస్తే నేను సంతోషిస్తాను). సరే, ఇది ఇడియొమాటిక్ అయితే, నాన్-ఇడియొమాటిక్ ఉదాహరణను చూడటం నాకు ఇష్టం లేదు. వాడుక interface{} - ఒక ప్రహసనం, మరియు భాషలో ఇది టైపింగ్‌ను దాటవేయడానికి మాత్రమే అవసరం. ఇది ఖాళీ ఇంటర్‌ఫేస్ మరియు అన్ని రకాలు దీనిని అమలు చేస్తాయి, అందరికీ పూర్తి స్వేచ్ఛను అనుమతిస్తుంది. ప్రోగ్రామింగ్ యొక్క ఈ శైలి చాలా అసహ్యంగా ఉంది మరియు అంతే కాదు. ఇలాంటి విన్యాసాలకు రన్‌టైమ్ రిఫ్లెక్షన్‌ని ఉపయోగించడం అవసరం. రాబ్ పైక్ కూడా తన నివేదికలలో పేర్కొన్నట్లుగా దీనిని దుర్వినియోగం చేసే వ్యక్తులను ఇష్టపడడు.

ఇది జాగ్రత్తగా ఉపయోగించాల్సిన శక్తివంతమైన సాధనం. ఖచ్చితంగా అవసరమైతే తప్ప దీనిని నివారించాలి.

నేను ఈ అర్ధంలేని దానికి బదులుగా D టెంప్లేట్‌లను తీసుకుంటాను. ఎవరైనా ఎలా చెప్పగలరు interface{} మరింత చదవగలిగేలా లేదా సురక్షితంగా టైప్ చేయాలా?

డిపెండెన్సీ మేనేజ్‌మెంట్ యొక్క బాధలు

గో ప్రముఖ హోస్టింగ్ ప్రొవైడర్ల పైన నిర్మించిన అంతర్నిర్మిత డిపెండెన్సీ సిస్టమ్‌ను కలిగి ఉంది VCS. Goతో వచ్చే సాధనాలకు ఈ సేవల గురించి తెలుసు మరియు వాటి నుండి కోడ్‌ను డౌన్‌లోడ్ చేసుకోవచ్చు, నిర్మించవచ్చు మరియు ఇన్‌స్టాల్ చేయవచ్చు. ఇది గొప్పది అయినప్పటికీ, సంస్కరణలో ఒక ప్రధాన లోపం ఉంది! అవును, మీరు Go టూల్స్‌ని ఉపయోగించి గిథబ్ లేదా బిట్‌బకెట్ వంటి సేవల నుండి సోర్స్ కోడ్‌ని పొందవచ్చు, కానీ మీరు సంస్కరణను పేర్కొనలేరు. మరియు మళ్ళీ ఉపయోగం యొక్క వ్యయంతో సరళత. నేను అలాంటి నిర్ణయం యొక్క లాజిక్ అర్థం చేసుకోలేకపోతున్నాను.

ఈ సమస్యకు పరిష్కారం గురించి ప్రశ్నలు అడిగిన తర్వాత, గో అభివృద్ధి బృందం సృష్టించబడింది ఫోరమ్ థ్రెడ్, వారు ఈ సమస్యను ఎలా అధిగమించబోతున్నారో వివరించింది. ఒక రోజు మీ ప్రాజెక్ట్‌లోకి మొత్తం రిపోజిటరీని కాపీ చేసి, దానిని "అలాగే" వదిలివేయాలని వారి సిఫార్సు. వాళ్ళు ఏమనుకుంటున్నారు? మేము గొప్ప ట్యాగింగ్ మరియు సంస్కరణ మద్దతుతో అద్భుతమైన సంస్కరణ నియంత్రణ వ్యవస్థలను కలిగి ఉన్నాము, వీటిని Go సృష్టికర్తలు విస్మరిస్తారు మరియు సోర్స్ కోడ్‌ను కాపీ చేస్తారు.

Xi నుండి సాంస్కృతిక సామాను

నా అభిప్రాయం ప్రకారం, గోను వారి జీవితమంతా C ఉపయోగించిన వ్యక్తులు మరియు కొత్తగా ప్రయత్నించాలని కోరుకోని వారిచే అభివృద్ధి చేయబడింది. అదనపు చక్రాలతో భాషను సిగా వర్ణించవచ్చు(మూలం.: శిక్షణ చక్రాలు) ఇందులో సమాంతరతకు మద్దతు తప్ప కొత్త ఆలోచనలు లేవు (ఇది, మార్గం ద్వారా, అద్భుతమైనది) మరియు ఇది సిగ్గుచేటు. మీరు ఉపయోగించలేని, కుంటి భాషలో అద్భుతమైన సమాంతరతను కలిగి ఉన్నారు.

మరొక క్రీకింగ్ సమస్య ఏమిటంటే, గో అనేది ఒక విధానపరమైన భాష (C యొక్క నిశ్శబ్ద భయానకం వలె). మీరు పురాతనమైన మరియు పాతదిగా భావించే విధానపరమైన శైలిలో కోడ్‌ను వ్రాయడం ముగించారు. ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ అనేది సిల్వర్ బుల్లెట్ కాదని నాకు తెలుసు, అయితే వివరాలను రకాలుగా సంగ్రహించి, ఎన్‌క్యాప్సులేషన్‌ను అందించడం చాలా బాగుంది.

మీ స్వంత ప్రయోజనం కోసం సరళత

గో సింపుల్‌గా ఉండేలా రూపొందించబడింది మరియు అది ఆ లక్ష్యంలో విజయం సాధిస్తుంది. ఇది పాత భాషను టెంప్లేట్‌గా ఉపయోగించి బలహీనమైన ప్రోగ్రామర్‌ల కోసం వ్రాయబడింది. ఇది సాధారణ పనులను చేయడానికి సాధారణ సాధనాలతో పూర్తి అవుతుంది. ఇది చదవడం సులభం మరియు ఉపయోగించడానికి సులభం.

ఇది చాలా వెర్బోస్, ఆకట్టుకోలేనిది మరియు స్మార్ట్ ప్రోగ్రామర్‌లకు చెడ్డది.

Спасибо మెర్సిన్వాల్డ్ సవరణల కోసం

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి