Goのシンプルさが難しい

Goについて読むと、「シンプル」という言葉をよく耳にします。 しかし、特にソフトウェア開発のコンテキストでは、さまざまな人々がこの言葉をさまざまな方法で解釈し、多くの場合、これが言語の特性として使用される理由さえ理解していません。 この記事では、ソフトウェア開発における「複雑さ」と「単純さ」の問題に概念的にアプローチし、Goが設計の基礎として単純性を設定した理由と理由を確認します。









複雑さについて。



シンプルさは複雑さの反対です。



ソフトウェア開発の複雑さは、長い間エンジニアや科学者の心を悩ませてきたトピックであり、この問題に対する最も概念的なアプローチの1つは、有名な本Mythical Man-Monthの著者であるFrederick Brooksの別の作品「No Silver Bullet」「No Silver Bullet」 箇条書き」 )。 この作品は1987年に書かれましたが、このトピックを概念的に見ると、30年経っても関連性があります。



特に、ブルックスは、複雑さと「必須」および「導入」 (または「偶発的」- 偶発的 )を重要に区別しています。 固有の複雑性とは、問題のまさにその領域、その性質から生じる複雑さです。 たとえば、FTPプロトコルを実装する必要がある場合は、どの言語またはツールキットを選択しても、実装する必要がある一連のコマンド、アクション、リターンコード、およびロジックがあります。 1行で実装するタスクを単純化する方法はありません。 複雑さは与えられたとおりに(この場合はプロトコル仕様から)与えられ、通常、このコンポーネントに影響を与える方法はありません。

導入された複雑さ -それどころか、私たちが使用するツールに起因するのは複雑さです。 これは、私たちが自分自身のために作成する複雑さです。 私たちはそれに影響を与え、減らすことができます。



ソフトウェア開発業界の歴史は、まさにこの偶然の複雑さの減少に帰着します。



複雑さはなぜ悪いのですか?



すべてをできるだけシンプルにする必要があります。 しかし、簡単ではありません。

アルバート・アインシュタイン


質問への答えは「良い」または「悪い」ですか? -善行と悪行の認識または非認識の分野にのみある。 「グローバル変数」が良いか悪いかを証明する正式な方法はありません。 特定の例を考慮すると、各政党の支持者はあなたに賛成と反対の100の説得力のある議論を見つけるでしょう。 しかし、少なくとも部分的には、多種多様なプログラマーや言語を扱う多くの多くのソフトウェア開発者の経験を集めて、「グッドプラクティス」または「悪いプラクティス」についての声明をどうにか聞くでしょう。



紙に自分の考えを述べた何千人ものエンジニアとプログラマーの経験的経験が集合して初めて、「複雑さ」は可能な限り避けるべきものであると理解するようになります。 複雑さは、すぐには明らかではない効果の雪崩につながります。これは、正式に証明することもしばしばであり、確率で測定されます-エラーの可能性が高い、コードを理解する時間が長い、必要に応じてソフトウェア設計を変更するのに必要な時間と労力(リファクタリング) 、順番に、これらの変更を行わないインセンティブを発生させ、開発者が回避策などを探し始めるという事実につながります。



最終的に、コードは単に問題を解決するためのツールであり、その結果、「良い」と「悪い」を区別する主な基準は生産性、つまりこれらの問題を解決するスピードと品質です。 複雑さは生産性の致命的要因であり、開発業界全体が複雑さを軽減する方向に動いているのはそのためです。



プログラミング言語はどうですか?



複雑さの管理は、プログラミングの本質です。

ブライアン・カーニガン


プログラミング言語の選択は、ソフトウェア開発の世界における「複雑さの追加」の非常に良い例ですが、最良ではありません。 プログラミング言語自体も、開発の複雑さを軽減するツールです。 そして、開発の各ラウンドは、何らかの形で、ソフトウェア開発の複雑さの1つの側面を解決しますが、それによって複雑さの新しい要素を導入します。



彼らの開発の全歴史は、その時代の現実のためのよりシンプルなツールの探求の歴史です。 プログラミング言語の理論は、例えば神経生物学と同じ発展科学であり、プログラミング言語がどうあるべきかについての単一の標準的な知識はありません。 これは確率論的なプロセスであり、市場の法則、決定の成功、大企業の形での優れたバックアップ(ほとんどすべての一般的な言語にはその背後に大企業があります)およびその他の多くの要因に関係しています。



そして、このプロセスはまだ止まっておらず、新しい概念は新しい問題を引き起こし、新しいレベルの抽象化、集合的な経験と理解が成長すると同時に、ハードウェアとソフトウェアのエコシステムは発展し、急速に変化します、妥協とリソース節約の優先順位は変化します、そしてすべてこれはきついです人間の脳と教育システムの慣性に結びついています。 つまり、これは非常に複雑な巨像です。 ここには単純で1つの解決策はありません。



しかし、確実に保証できるのは、一部の言語は一般的な複雑さのプールにさらに複雑さを追加し、他の言語はそれよりも少ないことです。 言語によって課せられるいくつかのプラクティスとパターン(「パターンはあなたの言語のバグレポート」)は、開発の全体的な複雑さを増し、他はそれを減らします。



そして、エンジニアとして、私たちは最終的にこの「導入された複雑さ」を避けるように努力しなければなりません。



外出困難



Goは、既存の言語の「複雑さ」の増大への対応として生まれました。 少なくともGoogleを心配した主題分野-システム、ネットワーク、サーバーソフトウェアの開発。 彼の主な目標は、最初はすべてのコストでこの複雑さを減らすことでした。 これは最初から最優先事項でした。



ここでは、Unix、C言語、UTF-8の起源に立ち、現在は主要なGoogle製品に取り組んでいるGoの著者であるパイク、トンプソン、および会社の膨大な実務経験が大きな役割を果たしました。 いずれにせよ、Goはある程度まで複雑な振り子を別の方向に振り回し、ソフトウェア開発の世界の既存の状況を調整しようとする過激な言語でした。



そして、これはまさに、Goのコンテキストで「シンプルさ」という用語が意味するものです。 難易度を減らします。 平均的な静的プログラマーが他の人によって書かれた平均的な静的プロジェクトを理解するのに必要な時間を短縮します。 エラーのリスクを減らします。 「グッドプラクティス」の時間とコストを削減します。 コードを記述する可能性を減らすことは悪いことであり、見苦しくなります。 言語取得時間の短縮。 などなど。



フィギュア



しかし、十分な言葉で、言語によってもたらされる複雑さを本当に評価してみましょう。 以前の記事へのコメントでは、「正式な証拠」の欠如が白熱した議論の原因でした。 このタスクの複雑さを認識していることをすぐに言わなければなりません。 実際の評価は、主観的な実務経験と測定困難な確率の面にあります。 すべてを1桁に減らし、「言語Aの複雑さは言語Bの複雑さよりも大きい」と言う簡単な方法はありません。 それでも、2つ以上の言語を熟知していれば、どちらの言語がより簡単かを自分で簡単に判断できます。 あなたの脳は、どの言語をより複雑に評価し決定するかをどういうわけか知っています。



したがって、より良いオプションがないため、いくつかのテクニックを試して、どのような絵が描かれるのかを見てみます。 各手法には重大な欠陥がありますが、結果に大きな違いがない場合、これはランダムな分布以上のものであると想定できます。



同時に、幅広い問題を解決するのに十分普遍的な言語を分析し、かなり大きなコミュニティを持ち、それらに関する情報が利用可能です。 Brainfuckのような異国情緒は考慮しません。



方法1


最も単純な方法の1つは、言語のキーワードをカウントすることです。 実際、言語が導入する概念を評価する方が正確ですが、検討するのがより難しく、同時にキーワードの数と相関します。 評価は非常に大雑把ですが、非常に示唆的で論理的です。 論理的です。知識が少ないほど、脳への認知的負荷が少ないからです。



ここに私たちが持っているものがあります:

Python 2.7 31 docs.python.org/2.7/reference/lexical_analysis.html
Python 3 33 docs.python.org/3.4/reference/lexical_analysis.html
ルア 21 www.lua.org/manual/5.1/manual.html
C(C99) 32 en.wikipedia.org/wiki/C_syntax#Reserved_keywords
C(C11) 37 en.wikipedia.org/wiki/C_syntax#Reserved_keywords
C ++ 11 85 en.cppreference.com/w/cpp/keyword
行く 25 golang.org/ref/spec
JS(ECMAScript 5.1) 41 www.ecma-international.org/ecma-262/5.1/#sec-7.6.1
ハスケル 55 www.haskell.org/haskellwiki/Keywords
Java 50 en.wikipedia.org/wiki/List_of_Java_keywords
C# 79 msdn.microsoft.com/en-us/library/x53a06bb.aspx
Php 58 www.php.net/manual/en/reserved.keywords.php
Ruby 1.9 42 ruby-doc.org/docs/keywords/1.9
スカラ 41 www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html
アーラン 27? erlang.org/doc/reference_manual/introduction.html




グラフと同じ:





方法2


言語の文法の評価を試みることができます 。その多くはBackus-Naur Formを使用して説明されています 。 この形式の文法(BNF / EBNF)はすべての言語で使用できるわけではありませんが、ネットワークには半自動で構成されたさまざまな文法があります。 たとえば、ここからいくつかの文法を取りました: slps.github.io/zoo/index.html ルールの数を単純な1行のプレーヤーとして評価します。 たとえば、Goの場合、言語仕様を含む公式ページからENBFルールを抽出するのは非常に簡単です。

$ curl -s http://golang.org/ref/spec | grep pre.*ebnf | wc -l
      
      





. , , .



C 65
Go 58
Python 83
Haskell 78
JS (ECMAScript 5.1) 128
Ruby ( 1.4) 37
Java (JRE 1.9) 216
C++ (2008) 159
C# 4.0 314
Lua 5.1 25
PHP 146
Rust 115
Erlang 219
Scala 143


:

C curl -s www.cs.man.ac.uk/~pjj/bnf/c_syntax.bnf | grep ": " | wc -l

Go curl -s golang.org/ref/spec | grep pre.*ebnf | wc -l

Python manually copy text from docs.python.org/2/reference/grammar.html, then “cat py.bnf | grep ": " | wc-l”

Haskell www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17500010

JS (ECMAScript 5.1) curl -s www.ecma-international.org/ecma-262/5.1 | grep '.*::'| tr -d ' ' | sort -u | wc -l

Ruby ( 1.4) curl -s docs.huihoo.com/ruby/ruby-man-1.4/yacc.html | grep ": " | wc -l

Java (JRE 1.9) curl -s docs.oracle.com/javase/specs/jls/se8/html/jls-19.html | grep '' | wc -l

C++ (2008) curl -s slps.github.io/zoo/cpp/iso-n2723.bnf | egrep ":$" | wc -l

C# 4.0 curl -s slps.github.io/zoo/cs/csharp-msft-ls-4.0.bnf | egrep ":$" | wc -l

Lua 5.1 curl -s wiki.luajit.org/Extended-BNF | grep "::=" | wc -l

PHP curl -s slps.github.io/zoo/php/cordy.bnf | egrep ":$" | wc -l

Rust curl -s doc.rust-lang.org/grammar.html | grep "[a-z_]* :" | wc -l

Erlang curl -s raw.githubusercontent.com/ignatov/intellij-erlang/master/grammars/erlang.bnf | grep "::=" | wc -l

Scala curl -s www.scala-lang.org/files/archive/spec/2.11/13-syntax-summary.html | grep "::=" | wc -l



:





, , .



3.


— StackOverflow . , , RedMonk : redmonk.com/sogrady/2015/01/14/language-rankings-1-15



StackOverflow , , , , , , , , — — SODD, Stack-Overflow Driven Development. , — , (, , ). StackOverflow : stackoverflow.com/tags?page=2&tab=popular



, , , GitHub 2014, : githut.info .



— StackOverflow Github. , .



:

GitHub SO
Go 22264 10272 0,46
Ruby 132848 136920 1,03
Lua 8123 8502 1,04
Rust 4383 2478 1,76
C 73075 184984 2,53
Haskell 8789 22930 2,60
Python 2.7 164852 439994 2,66
JS 323938 880188 2,71
Java 222852 879064 3,94
C++ 86505 377834 4,36
PHP 138771 768018 5,53
C# 56062 811952 14,48
Erlang 2961 5571 1,88
Scala 10853 38302 3,52




:







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



, , , — “”, “” “” . Rust- — , Rust : ( 1.0 ), , , rust- — Stack Overflow. , , . , , .



. , :

) , ( )?

) , — ?



— — . Go, , . Go , — .





, Go , , , . — “ , ” — . , Go ( , )), “” Go — .



, , , . , , , . , . , Go “Go makes programming fun again”. Hello, World, , , , .



, . , Go — Go , .





No Silver Bullet — faculty.salisbury.edu/~xswang/Research/Papers/SERelated/no-silver-bullet.pdf

Less Is Exponentially More — commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html

Less is more — lambda-the-ultimate.org/node/4852



All Articles