soukouki’s diary

誰かの役に立つ記事をかけたらいいなあ

少しclojureに触れてみた感想

ringとか使ってました。

感想は「始めやすいlisp」という感じでした。

同じことをrubyschemeclojure(末尾再帰最適化なし・あり)で書いてみました(短いのであまり参考にはならないかもしれませんが・・・)


def power(a, b)
    power_i(a, a, b)
end

def power_i(result, a, b)
    if b <= 1
        result
    else
        power_i(result*a, a, b-1)
    end
end

# power(2, 4) => 16
# power(1, 10000) => SystemStackError: stack level too deep

2**4でいいじゃん

(define (power a b) (power-i a a b))

(define (power-i result a b)
    (if (<= b 1) result (power-i (* result a) a (- b 1))))

; (power 2 4) => 16
; (power 1 10000) => 1

初心者にはなんかややこしそうに見えます。

; シンボルをチェックするので依存するやつを先に書く
(defn power-i [result a b]
    (if (<= b 1) result (power-i (* result a) a (- b 1))))

(defn power [a b]
    (power-i a a b))

; (power 2 4) => 16
; (power 1 10000) => StackOverflowError   clojure.lang.Numbers.minus (Numbers.java:136)

; 末尾再帰最適化バージョン

(defn power-m [a b]
    (loop [result 1, b b]
        (if (<= b 0) result (recur (* result a) (- b 1)))))

; (power-m 2 4) => 16
; (power-m 1 10000) => 1

括弧の種類が複数あって初心者に優しいです。でも括弧の種類を変えるだけならschemeにもできる

今回のだとわからないですが、書き方によればリストなんて意識せずに書けます。


clojureファンの言い分

ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32] Gauche scheme shell, version 0.9.4 [utf-8,wthreads], i686-pc-mingw32 Leiningen 2.7.1 on Java 1.8.0_111 Java HotSpot(TM) 64-Bit Server VM

文章の仕上がり微妙だな・・・


追記(2017-02-11)

rubydef power(a, b)

scheme(define (power a b)

clojure(defn power [a b]

括弧の囲い方がrubyとかに近いからかな?

vivaldiのアップデート時にエラーで止まる。

エラーを撮っておけばよかったと思う。

今まで1.2.なんたらだったのを1.5.658.56にアップデートしました。

対策としては、エラーが出たらもう一度アップデートを始めるだけ。

途中からスタートするので何回か繰り返せば終わります。


とりあえず設定項目は増えたね。

scalaのパーサーコンビネーターのorでハマった

import scala.util.parsing.combinator._

object Main extends App with RegexParsers {
    def aor = a | aa
    def a = "a"
    def aa = "aa"
    println(parseAll(aor, "a"))
    println(parseAll(aor, "aa"))
}

こんな感じのを書くと・・・

[1.2] parsed: a
[1.2] failure: end of input expected

aa
 ^

失敗する。

def aor = aa | a

こうか、

def aor = a ||| aa

こう書くと

[1.2] parsed: a
[1.3] parsed: aa

成功する。

Scala 2.12.0 "scala-parser-combinators" % "1.0.4"