(apply-generic op . args)

教育者, 将軍, 栄養士, 心理学者, 親はプログラムする. 軍隊, 学生, 一部の社会はプログラムされる. - 計算機プログラムの構造と解釈 序文

MacでMozart Programming Systemを実行するために

コンピュータプログラミングの概念・技法・モデル(CTMCP / ガウディ本)がまだ途中までしかやっていなかったなぁと思い、1ページからやろうとMacMozartを入れたら

Aquamacs Not Found

が出た。 あぁ、そういえば最初にこれ買った当時もこれあったわー。。。と思い、まぁ動かすようにしましたよっと。

出版された年が2007年なのでversion1.4.0を選択。 version2なら問題ないのかも?(未検証)

必要なものをDL

http://mozart.github.io/ から remain available to downloadをクリックして1.4.0のdmgをDLする。 クリックしたらaquamacsがないよ〜って言われるのでaquamacsをDLする。 でもまだ起こられる。

scriptを編集する

/Applications/Mozart.app/Contents/Resources/script

これでaquamacsを探したりしているみたいだが、aquamacsのPATHが間違っている(Aquamacsが多分変わって、それに対応していないと思われる). 上記ファイルの10行目と61行目を以下のように修正

...
if [ ! -e "/Applications/Aquamacs.app" ]; then
...
exec /Applications/Aquamacs.app/Contents/MacOS/Aquamacs --eval '(setq load-path (cons "'$OZHOME'/share/elisp" load-path))' -l oz.elc -f run-oz $2 &

これでMozartを実行出来ます:)

Common LispのTestingFrameworkを2つほど触ってみる

昨日に引き続きCLネタです。

引っ越しの準備で大江戸Ruby会議に行けなくて寂しいので、家で一人でLISP妖精さんとお話して*1戯れて寂しさを紛らわせています。

で、CLでも当たり前の如くテスト書きたいよねーってことで http://quickdocs.org/ でライブラリを調べて、取り敢えず2つ試して見ました。

当然のごとくVimで書いていますemacsLISPとか今どきないわー(煽 *2

CL-TEST-MORE

perlのtest-moreに影響を受けているとのこと。 perlわからんので似てる〜とか言えない。 僕的にはあまり馴染みのない感じでしたけどとてもわかり易かったです。

;;; CL-TEST-MORE
(ql:quickload :cl-test-more)
(in-package :cl-test-more)

(print "ok Function")
(ok (eq 1 1) "description") ; ok
(ok (eq 1 2) "description") ; not ok

(print "is Function")
(is 1 1 "description") ; ok
(is 1 2 "description") ; not ok

(print "isnt Function")
(isnt 1 2 "description") ; ok
(isnt 1 1 "description") ; not ok

(defun fib (n) (if (< n 2) n (+ (fib (- n 2)) (fib (- n 1)))))
(print "TEST Fibonacci Function")
(is (fib 0) 0)
(is (fib 1) 1)
(is (fib 2) 1)
(is (fib 3) 2)
(is (fib 4) 3)
(is (fib 5) 5)
(is (fib 6) 8)

詳しくはこちら

lisp-unit

こっちのほうが僕の好みでした。 個人的に何か開発するときはこっちを使うかな。

;;; LISP-UNIT
(ql:quickload :lisp-unit)
(in-package :lisp-unit)

(define-test fib
   (assert-equal 0 (fib 0))
   (assert-equal 1 (fib 1))
   (assert-equal 1 (fib 2))
   (assert-equal 2 (fib 3))
   (assert-equal 3 (fib 4))
   (assert-equal 5 (fib 5))
   (assert-equal 8 (fib 6)))

(defun fib (n) (if (< n 2) n (+ (fib (- n 2)) (fib (- n 1)))))
(run-tests '(fib))

(define-test my-sqrt
   (dotimes (i 5)
      (assert-equal i (my-sqrt (* i i)))))

(defun my-sqrt (n) (/ n 2)) ; これはテストコケます
(run-tests '(my-sqrt))

(run-tests :all)

詳しくはこちら

*1:ダグラス・ホフスタッターによるとREPL(対話型評価環境)の>や?はLISPの妖精で、REPLを使うことはLISPの妖精との対話である(ダグラス・ホフスタッター頭良すぎてぶっ飛んでる) メタマジック・ゲーム―科学と芸術のジグソーパズル

*2:冗談なのでマサカリ禁止

Common LispライブラリShellyを試してみた

MakeやRakeみたいなことが出来るLispライブラリShellyを試してみました。 おもしろいので貴方も試してみましょう(今回は一回もエディタを開いていないので、Emacsじゃないと、、、みたいなことは一切ないよ!!!)。

Shellyのサイトはこちら.

昔シェリーというイタリア人と付き合っていた事があって、Shellyという単語をみて懐かしいなーと思ったのが切っ掛けです(実話).

Common Lispは素晴らしい言語ですが縁が無い方が結構おられると思いますので、処理系のインストールから始めてみましょう。 以下、環境はMacOSX 10.9.2です。

Common Lispのインストール

Common Lispに限らず、Lisp族は沢山の処理系が存在するのでまず,どの処理系を使うのか選ばなくてはいけません。 今回はModernCommonLisp 第1回 Common Lisp処理系のインストールを参考に、Clozure CLを選択します。

~ iori:λ brew search clozure
clozure-cl
~ iori:λ brew install clozure-cl

こんだけ.

ライブラリを利用するためにQuciklispをインストールする

Rubyでいうgemとかそういうの。 これもインストールは簡単で

~ iori:λ wget http://beta.quicklisp.org/quicklisp.lisp
~ iori:λ ccl
Welcome to Clozure Common Lisp Version 1.9-r15758  (DarwinX8632)!
? (load "quicklisp.lisp")
? (quicklisp-quickstart:install :path ".quicklisp/")
? (ql:add-to-init-file)

こんだけ.

Shellyをインストールする

http://shlyfile.org/ に書いてある

$ curl -L http://shlyfile.org/shly | perl - install
$ PATH=$HOME/.shelly/bin:$PATH

を実行するだけ

なんか試してみる

~/work iori:λ mkdir shelly
~/work iori:λ cd shelly
~/work/shelly iori:λ echo '(defun fib (n) (if (< n 2) n (+ (fib (- n 2)) (fib (- n 1)))))' > shlyfile
~/work/shelly iori:λ shly fib 10

55

わーい、RakeとかMakeみたいなことがCLで出来たぞ!

Turbolinksを有効にしたままでangularjsを使用する

Turbolinks and Angularjs

最近はangularjsとRails4の組み合わせであそ、、、仕事しています。 まだまだangularjs触り始めて数日ですが、Turbolinksを有効にしているとng-showなどが画面遷移した際に上手く動かなかったのにハマったので、解決方法を自分用にメモ。

htmlからng-appを削除する

普通(?)はhtmlタグに

<html ng-app='MyApp'>

とか書くと思うんですが、これを削除します。

<html>

app.js.coffeeでbootstrapする

 window.App = angular.module('myApp', ['ngResource'])
$(document).on('ready page:load', ->
  angular.bootstrap(document.body, ['myApp'])
)

2~4行目を追記することで、turbolinkを有効にしていてもangularjsがbootstrapingされるので正常にng-showなどが動作しました。

備考

まだそこまでガッツリangularjsで書きまくっている訳ではないので、なにか問題でるかもしれませんが、

  1. inputに名前を入力
  2. /api/hoge/fugaにgetしてその名前が既に存在しているかチェック
  3. 既に存在していたら「その名前は既に使われています」みたいなalertを表示

くらいのは上記の方法でも正常に動作しました。

Good Luck!

werckerで自分のBOXを作ってみた

werckerで自分のBOXを作ってみました。 割りと簡単だったのでみんなももっと作るといいと思った(自分達のプロジェクトに最適なBOXって中々ないよね)。

作ったリポジトリはこちらです。 https://github.com/iori/box_iori_wercker

やったこと

  • Ruby2.1.1のインストール
  • ImageMagickのインストール

作り方

  • GitHubで専用のリポジトリを作る
  • WerckerとGitHubをいつもどおりに連携する
  • この辺を参考に、wercker-box.ymlを作成してPushする
  • MyApp -> 今作ったアプリ -> Settings -> Admin -> PublicAppにチェックを入れてSave

f:id:Iori_Nishizawa:20140316133050p:plain

  • AddDeployTargetでWerckerDirectoryを選択する

f:id:Iori_Nishizawa:20140316133251p:plain

  • DeployTargetNameになんか適切な名前をいれてSaveする

f:id:Iori_Nishizawa:20140316133327p:plain

  • 普段通りにBuildして、Buildが終わったらDeployする

f:id:Iori_Nishizawa:20140316133421p:plain

  • 無事デプロイが終われば、BOXに自分のBOXが出てくる!

f:id:Iori_Nishizawa:20140316133457p:plain

Rubyで無名再帰

http://kouyatakao.hatenablog.com/entry/2014/02/28/152153

を書いてて、あれ?Rubyって無名再帰どうすんの?と思って調べたらできたのでメモ

class Proc
  def self_curry
    self.curry.call(self)
  end 
end

def fib_closure
  cache = []
  lambda{|f,n| cache[n] ||= n <= 1 ? n : f.call(f, n-2) + f.call(f, n-1) }
end

fib_o = fib_closure
fib_o.self_curry.call(1000) # => 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

Rubyでフィボナッチのメモ化

仕事つかれたー、なんかリフレッシュしたーい。 なんて時によくフィボナッチを書いて、それをメモ化してにやにやします。 で、今も仕事の合間にそんなことをしていたのですが、需要少しはあるかなーと記事にしてみた。

普通にフィボナッチ

irb(main):001:0> def fib n
irb(main):002:1>   n <= 1 ? n : fib(n-2) + fib(n-1)
irb(main):003:1> end
=> nil
irb(main):006:0* fib 10
=> 55
irb(main):007:0> require 'benchmark'
=> true
irb(main):011:0> Benchmark.measure { fib 40 }
=> #<Benchmark::Tms:0x007f84932ef3c8 @label="", @real=31.694596, @cstime=0.0, @cutime=0.0, @stime=0.04000000000000001, @utime=31.199999999999996, @total=31.239999999999995>

40とかすると遅いですね。

メモ化

irb(main):014:0* def fib_memo n
irb(main):015:1>   @memo ||= []
irb(main):016:1>   @memo[n] ||= n <= 1 ? n : fib_memo(n-2) + fib_memo(n-1)
irb(main):017:1> end
irb(main):020:0> Benchmark.measure { fib_memo 40 }
=> #<Benchmark::Tms:0x007f8493305858 @label="", @real=3.5e-05, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.0, @total=0.0>

メモ化、サラマンダーよりはや〜(ry 1000でも1瞬で終わります。

さって仕事しよう。