Goの設計がスマートプログラマにとって悪い理由

過去数か月にわたって、Goを使用して自由時間に概念実証 :アイデアをテストするためのコード)を実装し、プログラミング言語自体を部分的に学びました。 プログラム自体は非常に単純であり、記事を書くことを目的とするものではありませんが、Go自体を使用した経験からそれについて少し説明する価値があります。 Goは、本格的なスケーラブルなコードのための大規模な言語になることを約束します。 この言語はGoogleで作成され、積極的に使用されています。 要約すると、Go言語の設計はスマートプログラマにとって悪いことだと心から信じています。







弱いプログラマー向けに設計されていますか?



Goの学習は非常に簡単です。とても簡単なので、はじめに1晩で導入できました。その後、生産的にコードを書くことができました。 Goを研究した本は、Goのプログラミング入門translation )と呼ばれ、オンラインで入手できます。 Goソースコード自体と同様に、この本は読みやすく、優れたコード例があり、一度に読むことができる約150ページが含まれています。 最初は、特に洗練されたテクノロジーに満ちたプログラミングの世界では、このシンプルさが新鮮です。 しかし、最終的に、遅かれ早かれ、「これは本当にそうなのか?」という考えが生まれます。







GoogleはGoのシンプルさが魅力的な機能であり、この言語は大規模チームの生産性を最大化するように設計されていると主張していますが、それは疑問です。 欠落している機能または詳細すぎる機能があります。 そして、すべては開発者に対する信頼の欠如のためであり、彼らは正しいことを何もできないという前提で。 この単純さへの欲求は、言語開発者の意識的な決定であり、その目的を完全に理解するには、開発者の動機とGoで達成したことを理解する必要があります。







それで、なぜそんなに簡単になったのですか? Rob Pikeからの引用をいくつか紹介します( 1枚:Goの共著者の1人):







ここで重要な点は、プログラマ( googlers )は研究者ではないということです。 彼らは通常非常に若く、放課後に私たちのところに来て、多分彼らはJavaやC / C ++やPythonを勉強しました。 彼らは優れた言語を理解することはできませんが、同時に、優れたソフトウェアを作成してほしいです。 だからこそ、彼らの言語は理解し、学ぶために彼らにとってシンプルでなければならないのです。



彼はおおまかに言って、Cに似ているはずです。 Googleプログラマーはキャリアを早期に開始し、手続き型言語、特にCファミリーに精通しています。 新しいプログラミング言語の迅速な生産性に対する要求は、その言語が過激すぎるべきではないことを意味します。

なに? したがって、Rob Pikeは基本的に、Googleの開発者はそれほど上手ではないと言います。だから、彼らはバカ用の言語を作成しました( :馬鹿げた)。 自分の同僚をat慢に思う人はいますか? Googleの開発者は、地球上で最も明るく最高のものから選ばれているといつも思っていました。 もちろん、もっと複雑なものを処理できますか?







過度の単純さのアーティファクト



シンプルであることはどんなデザインにおいても価値ある願望であり、シンプルなものを作ろうとすることは困難です。 ただし、複雑な問題を解決(または表現)しようとすると、複雑なツールが必要になる場合があります。 複雑さと混乱はプログラミング言語の最良の機能ではありませんが、理解しやすく使いやすいエレガントな抽象化を言語に作成できる中間点があります。







あまり表現力がない



シンプルさを求めているため、Goには他の言語では自然なものとして認識される構造がありません。 最初はこれは良い考えのように思えるかもしれませんが、実際には冗長なコードが出てきます。 この理由は明白なはずです-開発者が他の誰かのコードを読むだけであることが必要ですが、実際、これらの単純化は読みやすさを損なうだけです。 Goには略語はありません:たくさんあるか、ないかです。







たとえば、コマンドライン引数から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)
}
      
      





, Go , .







, , 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 (..: ), Go, , .









Go — . . , , , :







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), , . Go ? .







D:







import std.stdio;
import std.algorithm;

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





, . reduce



. , Go, . ?









, , Go : " !". , , !







:







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



Idiomatic generics in Go (..: , , ). , , . interface{}



— , . , . , . . , , .







, . .

D . - , interface{}



?









Go , VCS. Go , . , ! , github bitbucket Go, . . .







, Go , , . " ". ? , Go .









- , Go , , - . (.: training wheels). , (, , ) . , .







, Go — ( ). , . , - — , .









Go , . , . . .







, .







mersinvald








All Articles