読者です 読者をやめる 読者になる 読者になる

JavaScript勉強会

JavaScriptの学習日記

1.3 ラムダ式とは? 【関数型プログラミングの基礎】

JavaScriptの学習メモ。

今日は「関数型プログラミングの基礎 JavaScriptを使って学ぶ」の第1章を読んでみます。

 

jsstudy.hatenablog.com

 

 

ラムダ式」という記法(書き方)の発明

(p.15)

 

数学者、アロンゾ・チャーチ Alonzo Church

チューリング機械が発表されたほぼ同時期に、アメリカの数学者であるアロンゾ・チャーチは、全く別のアプローチで「計算」を定義しました。

それは「λ(ラムダ)計算」と呼ばれる数学の理論です。

 

アロンゾ・チャーチ - Wikipedia

アロンゾ・チャーチ(Alonzo Church, 1903年6月14日 - 1995年8月11日)はアメリカの論理学者、数学者。

ラムダ計算の創案者、「チャーチ=チューリングのテーゼ」の提唱者として知られる。

 

f:id:jsstudy:20170510203507j:plain

 

関数型プログラミングのもとになっているラムダ計算は、アロンゾ・チャーチさんという方が考えました。

ラムダ計算で使う、「ラムダ式」という関数の書き方について学んでみます。

 

ラムダ式

この理論では、「計算」とは「関数を適用して値を得る」(適用は、呼び出しと同じ意味です)ことと考えます。

λ計算ではλ式という記法で関数を表現します。

λ式とは、いわゆる数学の関数から、名前を省略したものです。

 

  • ラムダ式は、チャーチさんが考えた関数の書き方(記法)
  • 関数から名前を省略したもの
  • いわゆる「無名関数」

 

無名関数

無名関数 - Wikipedia

無名関数(anonymous function、nameless function)とは、名前付けされずに定義された関数のことである。

無名関数を表現するための方法には様々なものがあるが、近年主流なのはラムダ式による記法である。

無名関数を表現するリテラル式は、関数リテラル(function literal)とも呼ばれる。

 

ラムダ式(lambda expression)はラムダ計算と関係が深く、関数型言語で特によく採用されている。

 

JavaScriptの無名関数

JavaScriptではfunctionというキーワードを用いて記述する。

(function(a,b){return a+b;})(2,3) == 5 //二つの引数を取ってその和を返す関数

 

(ES2015のJavaScriptでは「アロー演算子」(=>)で無名関数を書けます。)

 

(参考)JavaScriptの関数の書き方(関数宣言、無名関数、即時関数)

» JavaScriptの無名関数・即時関数の使い方技術の犬小屋

 

関数宣言の問題点

数学ではf(x)=2x+1というように、定義された関数に必ず名前(ここではf)を付けます。

しかし関数にとって最も大切なのはその内容であり、名前は単なるラベルにすぎません。

またこの記法には曖昧さがあります。

つまり、f(x)と書かれたとき、それがf関数そのものなのか、あるいはf関数を変数xに適用したものなのかが、字面から判断できないのです。

この両者は似て非なるものです。

なぜならば、関数自体はある値を別の値に変換するための対応付けです。

それに対して、関数適用はその変換が施されたあとの何かしらの具体的な値だからです。

 

ある関数に「f」という名前を付けて、f(x)=2x+1と宣言(定義)してみる。

この「f(x)」という記述は2つの意味を表せるので、場合によっては紛らわしい?

 

  • 1つ目の意味: f関数そのもの (関数の定義
  • 2つ目の意味: 変数xにf関数を適用したもの (関数を使った計算

 

普通は、1つ目の意味=「変数xを引数に持つfという関数」という内容を表します。

しかし、話の流れによっては、2つ目の意味=「f関数に変数xを入れて計算する」という内容も表します。

 

関数の書き方(記法)を改良して、上記の2つを別々に表現できるようにしたほうが、意味がハッキリして分かりやすくなりますね?

 

関数定義と関数適用を分ける書き方

そこでチャーチは、関数自体を表現する記法としてλ式を考案しました。

この記法では関数に名前は不要となり、上記のf関数はλx.2x+1と表記されます。

また関数適用は(λx.2x+1)(3)と表現されます。

これで関数定義と、関数適用の記法上の曖昧さがなくなりました。

なお、λ式のことを「関数抽象(function abstraction)」と呼ぶこともあります。

これは名前という枝葉末節をとりのぞいて、計算の本質のみを抽出したという意味で用いられます。

 

ラムダ式では、「変数」と「関数の本体」を「.」(点、ドット)でつなげて書くんですね。

 

  • 関数宣言: 関数名(変数) = 関数の本体 (例)f(x)=2x+1
  • ラムダ式: λ変数.関数の本体 (例)λx.2x+1

 

変数xが3の場合、関数適用(関数を使って実際に計算すること)は、以下のようになります。

 

  • 関数適用: f(3) = 2*3+1 = 7
  • ラムダ式: (λx.2x+1)(3) = 2*3+1 = 7

 

こういうかんじの理解で良いのでしょうか?

→ まあ、書き方(形式)の問題なので、慣れたら違和感がなくなるかな?(・∀・)

 

ラムダ式の詳細は、Wikipediaなどをご参照くださいw

ラムダ計算 - Wikipedia

 

まとめ

  • ラムダ式は、関数の書き方の一種
  • ラムダ式で書くと、「関数定義」と「関数適用」がハッキリと区別できる
  • ラムダ式は「変数」と「関数の本体」を「点」でつないで書く

 

ここまでは、関数の書き方~単なる形式の話なので、「まあ、そういうもんかな?」というかんじです。

先々、もっと難しい話が出てくるのでしょうか?

 

 

関数型プログラミングの基礎 JavaScriptを使って学ぶ

関数型プログラミングの基礎 JavaScriptを使って学ぶ