多くの Java 関係者が JVM で実行される Scala に注目し始めていることを知っています。また、Microsoft の世界では多くの人が F# に注目していますが、Ruby には自然な機能の後継者として何が備わっているのでしょうか?
純粋な FP の意味では、Ruby に欠けているものは何もありません。関数型言語では、プログラマーはグローバル変数やその他のイディオムをあまり使用しないように強制されます (ただし、関数型言語でグローバルを使用することは可能です)。
多くの Java 関係者が JVM で実行される Scala に注目し始めていることを知っています。また、Microsoft の世界では多くの人が F# に注目していますが、Ruby には自然な機能の後継者として何が備わっているのでしょうか?
純粋な FP の意味では、Ruby に欠けているものは何もありません。関数型言語では、プログラマーはグローバル変数やその他のイディオムをあまり使用しないように強制されます (ただし、関数型言語でグローバルを使用することは可能です)。
「関数型プログラミング」の意味には、2 つのまったく異なる定義があります。Ruby では 1 つを実行できますが、もう 1 つを実行することはできません。
これらの 2 つの定義は次のとおりです。
Ruby では、一流の関数を使って一種のプログラミングを行うことができます。ファーストクラスの関数をサポートしています。実際、それらのサポートが多すぎProc.new
ます。 、proc
、lambda
、Method
、UnboundMethod
ブロック、#to_proc
および->()
(おそらく私が忘れている他のいくつか) があります。
これらはすべて、わずかに異なる動作をし、わずかに異なる構文、わずかに異なる動作、およびわずかに異なる制限を持っています。たとえば、これらのうち、実際に密集して使用できるほど構文的に軽量な唯一のものは、ブロックです。ただし、ブロックにはかなり厳しい制限があります。メソッドに渡すことができるブロックは 1 つだけです。ブロックはオブジェクトではありません (「すべてがオブジェクトである」というオブジェクト指向言語では、これは非常に厳しい制限です)。少なくとも Ruby では。 1.8 には、パラメーターに関していくつかの制限もあります。
メソッドを参照することは、かなり扱いにくいもう 1 つのことです。たとえば、 PythonやECMAScriptでは、オブジェクトのメソッドbaz = foo.bar
を参照すると言えます。Ruby では、はメソッド呼び出しです。 のメソッドを参照したい場合は、 と言わなければなりません。そして、そのメソッドを呼び出したい場合は、単に と言うだけではなく、またはまたは (Ruby 1.9 の場合)と言わなければなりません。bar
foo
foo.bar
bar
foo
baz = foo.method(:bar)
baz()
baz.call
baz[]
baz.()
したがって、Ruby のファーストクラス関数は、実際にはファーストクラスではありません。それらは二流よりもはるかに優れており、十分に優れています™ ですが、完全に一級ではありません。
しかし一般的に、Rubyist は第一級の関数のためだけに Ruby を離れることはありません。Ruby のサポートは十分に優れているため、別の言語でのより優れたサポートから得られる利点は、通常、新しい言語のトレーニングの努力や、慣れていてあきらめなければならない何かによって食い尽くされます。たとえば、RubyGems、Unix との緊密な統合、Ruby on Rails、構文など…</p>
しかし、FP の2 番目の定義は、Ruby が面目を失うところです。Ruby で数学関数を使ったプログラミングをしたい場合、苦痛の世界に直面しています。ほとんどの Ruby ライブラリは、ステートフルで効果的であり、突然変異を促進するか、その他の点で不純であるため、絶対多数の Ruby ライブラリを使用することはできません。同じ理由で、標準ライブラリを使用することはできません。コア ライブラリは使用できません。コア データ型はすべて変更可能であるため、使用できません。「変更可能であることは気にしません。単に変更せず、常にコピーします」と言うだけでもかまいませんが、問題は、他の誰かがまだそれらを変更できることです。また、それらは可変であるため、Ruby はコピーを最適化できず、ガベージ コレクターはその種のワークロードに合わせて調整されていません。
うまくいきません。
また、実際には関数型プログラミングとは何の関係もないが、ほとんどの関数型言語には備わっている傾向にある、Ruby には欠けている機能がいくつかあります。たとえば、パターン マッチング。Enumerator
また、Ruby 1.9 で s がより積極的に使用される前は、怠惰を達成するのはそれほど簡単ではありませんでした。Enumerable
また、 strictやArray
s では機能するが lazy では機能しないものがまだいくつかありますが、厳密性を必要とするEnumerator
理由は実際にはありません。
このFP の定義では、Ruby を置き去りにすることは間違いなく理にかなっています。
Rubyist が群がってきた 2 つの主な言語は、ErlangとClojureです。これらは両方とも動的に型付けされ、Ruby と同様の REPL 文化を持ち、(これは Ruby というよりは Rails に関するものです) Web でも非常に優れているため、どちらも Ruby に比較的適しています。彼らはまだ非常に小規模で歓迎的なコミュニティを持っており、元の言語の作成者はまだコミュニティで活動しており、新しい、刺激的でエッジの効いたことを行うことに重点が置かれています。これらはすべて、Ruby コミュニティにも備わっている特徴です。
Erlang への関心は、誰かが 1993 年のオリジナルの紹介ビデオ「Erlang: The Movie」を RubyConf 2006 で見せたときに始まりました。PowerSetやGitHubなど、いくつかの有名な Rails プロジェクトが Erlang を使い始めました。Erlang はHaskellやCleanほど純粋さを必要としないため、Rubyist にとってマスターするのも簡単です。アクターの内部はかなり純粋ですが、メッセージを送信するという行為自体はもちろん副作用です。Erlang を理解しやすくしているもう 1 つの点は、Alan Kay のオブジェクト指向プログラミングの定義に従うと、Actors と Objects は実際には同じものであるということです。
最近、Clojure が Rubyist のツールベルトに加わりました。その人気は、Ruby コミュニティが最終的に JVM ≠ Java という考えに慣れ、 JRubyを受け入れ、JVM に他にどんな興味深いものがあるかを調べ始めたという事実によって主に推進されていると思います。繰り返しになりますが、Clojure は、Haskell のような他の関数型言語や、 Schemeのような他の Lisp よりもはるかに実用的であり、CommonLisp よりもはるかにシンプルでモダンであるため、Rubyist に自然に適合します。
Clojure のもう 1 つの優れた点は、Clojure と Ruby の両方が JVM 上で実行されるため、それらを組み合わせることができることです。
「プログラミング Clojure 」の作者(Stuart Halloway) は (元?) Rubyist です。たとえば、 Clojure 用のLeiningenビルド ツールの作者であるPhil Hagelbergと同様です。
ただし、Rubyist はScala (より実用的な静的型付け FP 言語の 1 つとして) と Haskell (よりエレガントな言語の 1 つとして) の両方にも注目しています。次に、Ruby を Scala および Haskell とそれぞれ統合できるようにするブリッジであるScubyやHubrisなどのプロジェクトがあります。低レベルのメッセージング インフラストラクチャの一部を最初に MySQL から Ruby に移行し、次に Ruby から Scala に移行するという Twitter の決定も、かなり広く知られています。
F#はまったく役割を果たしていないようです。おそらく、Microsoft の Ruby コミュニティが持っているすべてのものに対する不合理な恐怖が原因です。(ところで、F# チームが常にMono で使用できるバージョンを作成してきたことを考えると、これはほとんど根拠がないように思えます。)
Java の人々は JVM で言語を使用しており、ランタイムと互換性のあるより機能的な言語を求めているため、Scala を使用しています。
C# の人々は CLR で言語を使用しており、ランタイムと互換性のあるより機能的な言語を求めているため、F# を使用しています。
Ruby の人々は、すでにかなり機能的な言語を使用しており、その言語を基盤となる多くのランタイム (JRuby、IronRuby、MRI、MacRuby、Rubinius など...) で使用しています。自然な機能の後継者がいるとは思いませんし、必要だとさえ思いません。
Lisp のどのバージョンでも問題ありません。
Ruby 自体は関数型プログラミング言語の一種なので、Ruby を使用した FP 用の特別な方言は見当たりません。
Ruby のユーザーが JVM 自体を使用するだけでなく、別の動的型付け言語である Erlang を採用する人がほとんどだと思います。
誇大広告レベルでは、Haskell.
Ruby は Lisp のように機能的ではありませんが、関数型プログラミングを楽しい方法で行うには十分機能的です。(C# などで関数型プログラミングを行うのとは異なります)
また、実際には、ブロックや利回りの多用など、一部の構文で機能的なパラダイムを強制します。(Rubyを学んだ後に恋に落ちました)。