このコメントでは、Ruby には関数がなく、メソッドしかないと述べられていました。Ruby に関数がなければ、関数型プログラミングを行うことはできませんか? または、「関数」という用語について混乱していますか?
「関数型プログラミング」とは、変更可能な状態を禁止するという意味ではなく、ファーストクラスのオブジェクトとしての関数という意味で意味します。
このコメントでは、Ruby には関数がなく、メソッドしかないと述べられていました。Ruby に関数がなければ、関数型プログラミングを行うことはできませんか? または、「関数」という用語について混乱していますか?
「関数型プログラミング」とは、変更可能な状態を禁止するという意味ではなく、ファーストクラスのオブジェクトとしての関数という意味で意味します。
ブロックとProcsはファーストクラス関数です。それらをメソッドや関数に渡すことができます。このようにして、RubyはmapやreduceなどのFP風のものをサポートできます。
より一般的には、メソッドは追加の状態(its)が関連付けられた関数と見なすことができself
ますが、Rubyでメソッドが渡されることはめったにありませんが、実際には、FP風のイディオムにとってブロックやProcs。
はい。メソッドと関数はかなり細かい違いです。
それぞれの特定のメソッドの実装を関数として見るのは簡単です。メソッドが呼び出されたオブジェクトを追加のパラメーターとして取得するだけです(言語が明示的に渡さない場合; Rubyにあまり慣れていない場合)。これでは、仮想メソッド呼び出し (つまり、実行時に呼び出される特定の実装がオブジェクトによって決定される場所) は得られません。しかし、仮想メソッド呼び出しが、最初のパラメーター ( self
、this
、呼び出されたものは何でも) を検査し、それを使用して呼び出すメソッド実装を決定するだけの関数を呼び出すことを想像するのは非常に簡単です。これらの慣習が確立されているため、 は単純な構文上の方法でのみobject.method(param1, param2)
と異なります。method(object, param1, param2)
個人的には、上記は「真実」であり、オブジェクト指向言語は、オブジェクト指向プログラムの作成/実行の中核部分であるため、シンタックス シュガーと最適化された実行を提供するだけだと考えています。この種のシステムは、関数はあるが真のクラス/メソッドがない場合に OO を行う方法とまったく同じです。
メソッドが関数ではないと考える場合、メソッドを使用して関数を実装することも自明のことです。単一のメソッドを持ち、属性を持たないオブジェクトを作成するだけです! これは、すべてがオブジェクトであることを主張し、メソッド/関数をファーストクラスの値として渡すことを許可しない Java のような言語で関数型プログラミングを行う方法でもあります。
関数型プログラミングを行うために必要なのは、ファーストクラスの値として渡すことができるものだけです。これは、「もの」の作成者によって決定されたコードを実行するために使用できます (「もの」を使用しているコードによって決定されるのではなく)。 「もの」にアクセスできるコードによるオンデマンド。この機能を持たないプログラミング言語は考えられません。
関数 (より正確には、ここでは参照透過性について話していないため、手続き) は、メソッドが 1 つしかないオブジェクトと同型です。
これが、いわゆるSAMインターフェイス (Single Abstract Method) を使用して、Java でファーストクラスのプロシージャを偽造する方法です。これは、Ruby でファーストクラスの手続きが「偽造」される方法でもあります。応答するものcall
(およびおそらくto_proc
) はすべてファーストクラスの手続きです。Proc
カリー化などの「プロシージャ」に追加機能を提供する便利なクラスが呼び出され-> (x, y) { x + y }
、クラスのインスタンスを作成するプロシージャのリテラル構文 ( ) がありますがProc
、これら 2 つは厳密には必要ありません。
def (i_am_a_first_class_procedure = Object.new).call(x) p x end
i_am_a_first_class_procedure.(42)
# 42
apply
メソッドがではなくで呼び出されることを除いて、Scala は似ていcall
ます。Python では、 と呼ばれる「魔法の」メソッド__call__
です。
注: ここでは閉鎖を無視しています。クロージャーは状態を持つ手続きであり、もちろんオブジェクトも状態を持つことができるので、それらを表現することに実際の問題はありませんが、インスタンス変数を持つオブジェクトの観点から自由変数の語彙的なキャプチャを表現することはかなり毛むくじゃらになります。
言語がチューリング完全である限り、もちろんそうです。
後で追加:
実際、Ruby は典型的な関数型プログラミングのいくつかのケースをサポートしています。Ruby 1.9 で Proc クラスに #curry メソッドを追加していたとき、Matz 自身が「関数型プログラミングの子供たちにおもちゃを提供する」ことについて述べていますが、メソッドを使用して関数型プログラミングを行うこともできます。