もう一人のY君

主にiPhoneのショートカットアプリのレシピやTipsなどを書いています. たまに数学の記事も書きます.

もう一人のY君 MENU  MENU

LISPによる数式処理アプリ「lambda LISP」

 

  こんにちは, @the_theorierです.

 

  今回紹介するのはLISPと呼ばれるプログラミング言語を使って数式処理が出来る「labmda LISP」です.

 

Lambda LISP

Lambda LISP

  • Gaurav Menghani
  • 仕事効率化
  • 無料

 

LISPとは

  LISPは歴史上初の関数型プログラミング言語で, 現在も利用されているプログラミング言語の最古のものの一つだそうです.

 我々がよく使うC言語などと違い, ポーランド記法による対話型言語です.

 

LISP - WikipediaLISP - Wikipedia

 

ポーランド記法 - Wikipediaポーランド記法 - Wikipedia

 

  我々が普段扱っている数式記法は「中置記法」と呼ばれ, 例えば 1+2 のような書き方です.

 ポーランド記法ではこれが + 1 2 となります.

 ポーランド記法では演算子などとの区別を付けるためにそれぞれの間に半角スペースを入れる手間が必要です(区切るために使用する記号をデリミタと言います, 今回は半角スペースですが別の場合もあります)が, 中置記法では間に入れた演算子がその役割を果たすため, 必ずしもデリミタとして間に追加する必要はありません.

 その分ちょっとだけ面倒ですね.

 

 LISPではここから更に括弧を付けます, つまり (+ 1 2) ですね.

 "("の右, ")"の左にデリミタを付ける必要はありません.

 

 より複雑な式を書こうとすると, 例えば中置記法での 1+(2*3) はポーランド記法では (+ 1 (* 2 3)) となります.

 なんとなく分かりましたか?

 

 

lambda LISP の使い方

  lambda LISP はその名の通りで LISP に準じた数式処理アプリケーションですが, 一部 LISP と異なる…というか"機能制限"のようなものがあるのでそれを含めて簡単に紹介したいと思います.

 ガッツリ調べたかったんですが思いの外簡単には理解できなかったので不足な部分が多々あると思います.

 

起動画面

 151108_01

  起動するとこのような画面になります.

 

 151108_02

  とてもシンプルで, 下の「type expression」をタップするとキーボードが出てくるのでそこから命令を書いて実行します.

 

 また一度実行したものを編集したり削除することは現時点ではできないようです.

 

 

四則演算

  まずは基本中の基本である四則演算からです.

 

 151108_03

  基本的な使い方は先程の通りで括弧つきのポーランド記法です.

 

(+ 1 1)
(- 1 1)
(* 1 1)
(/ 1 1)

 

 151108_04

 半角英数字が基本ですから × や ÷ は使えません, それぞれ半角の * , / を使います.

  また 演算子とオペランドがくっついた場合もエラーになります(それをまとめて演算子を見做してしまうため).

 

 151108_05

 (+ 1 2 3)
(* 2 3 4)
(* (+ 2 3) (+ 4 5))

  またオペランドはこのように2つ以上に増やしてもOKです.

 組み合わせてより複雑な計算もできます.

 

 151108_06

  しかし乗法 * と除法 / についてはダメのようです.

 

 151108_07

  また, 除法では例えば  (/ 7 3) とすると上の画像のように小数点以下が丸められてしまいます.

 小数以下を表示するためには以下のどちらかで記法します.

 (/ 7 3.0)
(/ 7.0 3)

  つまり除数ないし被除数に ".0" を書きくわえるわけですね.

 ここは本来のLISPとは仕様が異なります.

 

 

変数定義

 151108_08

  (defvar a 2)

  変数定義は defvar という演算子を用いて例えば上のように書き表します.

 

 151108_08a

  本来のLISPでは例えば

 > (defvar a 2)
2
> a

 となるんですが, lamba LISP では画像の通りで定義した変数値を表示はしてくれないようです.

 

 151108_09

 > (devar a 2)
2
> (devar pi 3.1415926535)
3.1415926535
> (* pi (* a a))
12.566370614

  上手いこと使うとこのように円の面積なども求められます.

 

 

関数定義

 151108_10

 (defun ff (x y) (+ (* 2 x) y)))

  関数は例えば上のように定義します.

defun 関数名 (変数) (式)

 という構造ですね.

 

 

関係演算子

 151108_13

 (= オペランド オペランド)
(< オペランド オペランド)
(> オペランド オペランド)
(<= オペランド オペランド)
(>= オペランド オペランド)

 という構造になります.

 真であるなら true を, そうでないなら false を返します.

 (/= オペランド オペランド)

  見ての通りで演算子 /= は使用できませんでした, 重要な関係演算子の一つなのに…

 

 

 151108_14

  またこちらもオペランドは2つまでのようで, 3つ以上になるとエラーになりました.

 ついでに not や nil も確かめたんですがこれらも使えませんでした.

 

 

ifとcond

 151108_15

  条件分岐として一番使われるのが if ですが, ここでは使えないようです.

 

 151108_16

 (cond (= 1 2) (+ 1 2) (- 1 2))

  代わりに使用できるのが cond です.

 cond (条件) (条件が真の場合の処理) (条件が偽である場合の処理)

 という構造になります.

  上の例では (= 1 2) が偽ですから (- 1 2) の方が実行されています.

 

 

使えない?演算子など

 調べるには量が多いので一部断定できないものだったり, まだ他にもあったりしますがおおよそ「これはここでは使えなさそう」な演算子などは以下のようです.

/=

/< ( /<= )

/> ( />= )

mod

round

ceiling

abs

sqrt

sin

cos

tan

log

exp

expt

random

max

min

gcd

lcm

nil

list

 

 もしかしたら文字が違うだけかもしれませんし用法を間違えただけかもしれません.

 

 

  ちょっと本来とは使い方が異なる感じもしますが, こういうのが好きな方にはお勧めです.

 

 因みに一度実行したものは編集などは出来ませんがコピーすることは出来ます.

 うっかり括弧忘れたりしてイラつく…みたいなのはプログラミングでは良くあることですね…コピー出来るだけでもありがたいです.

 

 贅沢を言えば MuPad みたいに大きな数字などが扱えると嬉しいです.

 どうやら演算結果が20桁程度を超えるとオーバーフローして滅茶苦茶な値を返すようです.

 例えば (* 10000000 1000000000000) の結果が -8446744073709551616 だったり, (* 10000000 10000000000000) の結果が 7766279631452241920 だったりと明らかに間違っていますね.