ラベル ClojureAdvent の投稿を表示しています。 すべての投稿を表示
ラベル ClojureAdvent の投稿を表示しています。 すべての投稿を表示

WSLでcrojure開発 (Emacs + cider)

Posted by YpsilonTAKAI On 2017年12月13日水曜日 0 コメント

普段は仕事でPCを使うことが多いし、趣味がらみでもツール類の関係で基本的にはWindowsが必要になったりするので、家でも結局はWindowsを使っています。 

とは言え、やっぱりClojureを始めとしたプログラミング関連の作業はコマンドラインでやりたいし、使い慣れたUNIX系のツールを使った作業からは離れられないのでMsys2を導入して環境を作っていたわけですが、そこはそれ、後づけの環境なので、いくつか気に入らないところもあったりするわけです。

そんな中、話題の Windows10 Fall Creators Update で正式版となったWSL、要するにWindows上のLinux に乗り換えてみたら、Msys2の問題を解決してくれてなかなかよかったので、そのあたりの事を書いてみます。





Msys2環境の問題

このMsys2というのはそもそも「UNIX系のツールをWindowsで動くようにコンパイルするため」の環境なので、コンパイルしたものはWindowsのソフトになっちゃうわけで、そのツールはMsys2環境で動くことはあまり考えていないのです。
たとえば(僕にとっては)開発環境の中核を成しているEmacssも、Windows用のバイナリはMsys2でコンパイルされているので、Windows環境でうまく動作するのであって、実はWindows環境ではないMsys2との親和性は高くないのです。
どういうことかと言うと、たとえばEmacsからMsys2のコマンドであるgitを使おうとするとちょっと工夫が必要だったり、動かなかったりするということです。

たとえば EmacsはWindowsのパスは「 C:\users 」を理解できますがgitコマンドには理解できないということになるのです。
僕が今一番困っているのが、「magitが遅い」ことです。magit-statusなど、gitとのやりとりをするコマンドを打つと、30秒から1分ほどかかります。慣れてしまいましたが、こういう作業の部分に時間を取られるのはあまり納得が行きません。

また、clojureの開発環境であるciderが不安定だったりもします。たまに、といっても2日に1回くらい、固まります。これもLinuxだったらまず発生しない現象です。

「windowsでemacsが動いているだけで幸せなんだから、外部連携などはできたらラッキーぐらいに考えておけ」というような意見もあるようですが、MacがOSXで裏でUnixが動くようになってから、開発環境としてのMacを指をくわえて見ているだけの状態はちょっと辛いものがありました。

ということで、WSLを使うことでこれらの問題が解決しているんじゃないかという期待とともに、進めていくことにしましょう。


WSL環境構築

さて、これから出てくるほとんどの手順は話題の作業内容なのでここで細かいことは書かずに何をやってどうなったかを中心に書いていくことにします。 
細かいところを知りたい場合はいろいろなところで解説されているので、検索してみてください。


Windows10 をFall Creators Updateにする

まずはこれですね。WSLが正式版になっているので。


WSLを有効にして、Ubuntuを入れます。

Windows Subsystem for Linuxを有効にして、ストアからUbuntuを入れます。
SUSEという選択肢もありますが、まずは、使ったことのあるUbuntuにしました。変なところではまりたくないですからね。


Ubuntuを最新にします。

入った Ubuntu の使い方はほんとに普通のUbuntuと同じで、アップデートするにはapt-getを使います。
sudo apt-get update && sudo apt-get upgrade
入れたばかりなので、アップデートされるパッケージはあまり無いだろうと思っ
たのは甘くて、かなり時間がかかりました。


javaを入れる

Clojureを使うには必須ですね。
Windows側にはjavaは入れてありますが、別途WSL用にも入れてやる必要があります。
以下のコマンドでjava8を入れました。

sudo add-repository ppa:webupd8team/javasudo apt updatesudo apt install -y oracle-java8-installer




ターミナルエミュレータ cmder を入れる

Windowsのターミナルのcmd.exeはWindwos10 Fall Creators Updateでよくなったと言われていますが、そもそも貧弱なのでちょっとくらい良くなってもたいして使いやすくはありません。

Msys2では付いているminttyを使っていたのですが、「cmder」というのが評判がよさそうなので、使ってみることにしました。
   http://cmder.net/
起動がちょっともたもたしている以外の使いごこちはよさそうです。




Emacs25を入れます

標準のパッケージを入れると24になります。
Msys2環境では25を自分でコンパイルして使っているので、同じようにして入れようかと思ったのですが、パッケージを公開してくれているところがあるようなので、それを使わせていただくことにしました。
    https://www.yokoweb.net/2017/03/19/emacs-25-apt-install/
25.3が入りました。

いずれは自分でコンパイルしたやつに差し替えようかと。




EmacsをGUIモードで使うには、Xサーバーが必要です。

よいターミナルエミュレータが入っていればそこでEmacsを動かす手もありますが、やっぱり複数フレーム作ったりしたいので、GUI での動作は必要です。
ところが、WSLのUbuntuではXのサポートは含まれておらず、そのままではGUIベースのツールを動かすことはできません。

できないんですが、まてよと。

そもそもLinux/UNIXではOSとGUIの機能は別の機能として実装されていて、XサーバーもOS上で動くアプリケーションの1つに過ぎません。そして、Xサーバーって言うくらいなので、クライアントサーバーモデルを取っているので、リモートで動くXサーバーに画面を表示することだって難なくできるはずなのです。
ということは、WSLでなくWindows側にXサーバーを立ててやれば、GUIのアプリケーショ
ンを動かすことができるはずです。 いえ。できます。


VcXsrvをインストールした

Windowsで動作するXサーバとしてはXmingが有名で、仕事PCには入っています。

今回環境構築にあたって、調べてみると、Xmingは最近更新が止っているらしく、代りにVcXsrvっていうのが流行っているようです。
   https://sourceforge.net/projects/vcxsrv/
流行りものには弱いので、さっそくこれをインストールします。
あちこちで言及されていますが、プログラム起動後のタスクバーのアイコンがXのものでなくそのアプリケーションのものになるっていうことだけでも乗り換える価値がありますね。



フォントも、Windowsの物が使えるようにしておきます。


これでやっと、作業の準備ができました!
そうです。 つらつら書きましたが、まだやっとClojure開発の基盤ができただけなのです。
ここから先は普通にUbunutuでClojureの開発環境を作るのと変わりありません。と言ってもLeiningenを入れるだけですがね。



Leiningenをインストール

Windows版ではありませんよ。Linux版を入れてくださいね。

注意
2017/12/11の時点での最新は2.8.0ですが、javaのエラーが出ます。
バグらしい
    https://github.com/technomancy/leiningen/pull/2324

1つ前の 2.7.1を使っています。次版には修正されているとのこと。

そのときのエラーメッセージ





yosi@mowegi:~/workspace/clojure/weasel/weasel-example$ lein cljsbuild once
Compiling ClojureScript.
Java HotSpot(TM) 64-Bit Server VM warning: Unable to open cgroup memory limit file /sys/fs/cgroup/memory/memory.limit_in_bytes (No such file or directory)


emacsのclojure開発環境を整えます

clojure開発用で入れているのは以下のパッケージです。

  • cider
  • clojure-mode
  • smartparens
  • company


さて、これで、Clojureの開発環境は整いました。


プロジェクト作っていろいろやってみる

さて、いろいろ動かしてみましょう。

REPLを使うのが目的のプロジェクト

Project Eulerを解くとか、ちょっと込み入った計算をさせるとかする時には、
REPLだけで済ませてしまうことがよくあります。
相変わらず起動には時間がかかりますが、REPLは普通に起動しまして、使っていて特に困るようなこと発生していません。


Webアプリケーション

Webアプリケーションはどうでしょう。
サンプルとして、ここにあるやつを動かしてみます。
    http://clojure-doc.org/articles/tutorials/basic_web_development.html

結論から言えば、これも特に問題無く動きます。




右がEmacsで下半分がciderの画面です。左の下のWindowsで動いているChromeで起動したプロセスにアクセスしています。
また、タスクバーにあるEmacsのアイコンがEmacsのものになっているのがVcXsrvのよいところです。


このページの記述ですが、最後の方でちょっとはまりました。
REPLを使って作って行ったのですが、最後になって、webサーバのjettyの設定
を追加することになっていて、また、REPLベースで起動する方法が書いてない。

こんな感じです。


(def srv (atom ""))(reset! srv (jetty/run-jetty app {:port 8080 :join? false})


これで、localhost:8080 にアクセスするとページが表示されます。
止めるときは


(.stop @srv)(reset! srv "")


といった感じです。



まとめ


と、いうことで、wslを使ってWindows10でより快適な clojure 開発環境を作
ることができることがわかりました。

不満だったmagitの反応についても、Linux環境と変わらない使用感で快適です。

ただ、まったく何も不満が無いかというとそうではなく、wsl上のLinuxは、
CygwinやMsys2とは違ってWindowsのファイルシステムとは基本的に別になって
いて、間には壁があります。 この壁のおかげで、快適な環境を手に入れるこ
とができるのですが、より2つのシステムで作業していることを意識してつか
わなかればならないというところがあります。


これで、また、ちょっと、Macで開発している人達への羨ましい度が減りまし
た。

READ MORE

Clojureで3D-CAD

Posted by YpsilonTAKAI On 2016年12月24日土曜日 1 コメント
これって、 2016 clojure advent calender の記事です。

CAD

Computer Aided Design ということは、コンピューターを使ってデザインをするためのツールですが、基本的には「製図」をするためのツールです。学生時代に製図をしたことが無いとなんのことかわからないかもしれませんが、機械や建造物などの設計図を書くことを製図といいます。

もともと紙とペン・定規・コンパスなどの道具で点や線を書くので、手書きのころは立体物でも2次元の図面だけ作っていました。僕も実は機械工学科だったので、「図学」とか言ってちゃんとした製図の方法を習ったりしたものです。

コンピュータを使うようになると、自由度が広がってこれまでできなかったようなことができるようになりました。
- 3DCGで立体を描画できるので物をイメージしやすくなった
- 曲線を直接扱えるようになって、自由な形が作れるようになった。
などです。 最近の3Dモデラーなども目的は同じではありますが、数値から離れて直感的に物を扱えるようになっています。

自由度を広げるという方向にはまた別のアプローチとして、例えば二次関数や表されるグラフのように数式で表される線や、特定のアルゴリズムによって定義される点や線の集まりで図を作るという方向性に行ったものもあります。
パラメータを含んだ式を使って図面を表すことで、複雑な形でも簡潔に表すことができる可能性があったり、また、そのパラメータを変更するだけで、大きさや比率の違うものが簡単に作れたりするわけです。

OpenSCAD

OpenSCADは、ものの形状を式で表しやすい形状の集まりとして扱うことに特化したCADの一つです。


ようするに、部品があって、それに対する操作があって、列挙したり、繰り返しや条件分岐などで制御したりなどして、目的のものを作っていくわけです。 そして、変数が使えることによって、各属性をパラメータにする(パラメタライズ)ことができるので、カスタマイズが楽にできるということになります。

ClojureでSCAD

LispでCADといえばAutoCADですね。使ったこと無いのですが、製図の図面に現れるオブジェクトとそれに対する操作を簡潔に表現する方法として、Lispが優れているということの証なのだろうと思ってるのですが、SCADの記述は残念ながらLispではありません。
SCADの言語というか表現方法は、ちょっと独特で、そこそこ長いプログラミング経験がある僕としても始めて見る感じの書き方で、かといって使いやすかったり、読みやすかったりするわけでもなさそうです。
そんなわけで、しばらく前に目にしてはいたものの、手は出していませんでした。

最近、久し振りに図面を引くことになり、フリーのCADの状況を調べていたときに再発見しました。 記述方法そのものも以前のより進化しているようですが、なんと、ClojureでDSLを作った人がいるようなのです
ということで、ちょっと調べてみることにしました。

scad-clj

scad-cljに出会ったのがこのサイトです。
http://adereth.github.io/blog/2014/04/09/3d-printing-with-clojure/

筆者がこんなこと書いてます。うん、そのとおりですね。
そして、そんな場合にこそDSLを作ることに意義があるのでしょう。
- Strange function application syntax (parameters in parens after the function name with an expression or block following the closing paren)

奇妙な関数の書式
関数名の後のカッコ内のパラメータに付いている記述やブロックの書式
- Unclear variable binding rules (multiple passes are made over the code and the results of changing a variable may affect things earlier in the code unexpectedly)
不明確な変数の束縛ルール
ソースコード上に変数の経路を複数作ることができ、また、変数の値の変更が予期せず変更以前の場所にも波及したりする。
- No package/namespace management
ネームスペースが無い
- Multiple looping constructs that depend on what you are going to do with the results, not on how you want to loop
いくつかあるループ構文は、どのようにループさせたいかではなく、結果をどのように使うかによって選ばなくてはならない

うんうん。 よさそうですよ。
scad-cljを使ってとりあえず何か作ってみましょう。

scadのセットアップ

本家のGithubはここです。
https://github.com/farrellm/scad-clj

なんともシンプルですね。docディレクトリがあって、中に「intro.md」なるファイルがあるので期待して空けてみると。
TODO: write great documentation
うーん残念。ドキュメントが無いようですから、使うには自力でソースなどを見てみるしかなさそうです。

ともあれ、leiningenでプロジェクトを作成してscad-cljを関連づけます。

:dependencies の ベクターに [scad-clj "0.5.2"] を追加して、lein deps を実施します。
関連パッケージを含めていくつかのパッケージがローカルに転送され、準備OKです。

さて、どこかにあるはずのサンプルを探します。ネットを探しまわるのもありですが、まずは、ソースからです。
testディレクトリがあるのでまずはそこ。テストが書いてあれば、それぞれの関数がどのような入力に対してどのような出力をするのかよくわかるはずです。

が、これも空でした。残念。

となればソースを見るしかなさそうです。
geometry.clj には、 line と lines という関数があります。その通り、線を引く関数のようです。
text.clj には、文字列を生成する text-partsという関数が定義されています。
model.clj には、$f や $fa など、scadで特殊な意味のある変数や、import や use などの指示子、あとは、square や sphere などの基本的な2Dと3Dのパーツが定義されています。
そして、scad.cljには、write-expr というメソッドが定義されていて、たぶん、これが、レンダラーですね。

と、ここまで見てきても、全くイメージが掴めません。

まあ、結局最初のサイトですね。scad-clj を知るきっかけになったサイト

やってみよう


とりあえず、書いてあることをやってみましょう。



立方体(cube)と球(sphere)と円柱(cylinder)を合成(union)したものがprimitiveとしてできあがるはずなんですが、これ、どうしたらいいんでしょう?
write-scad という関数でこのprimitiveを出力できる形にできるようなので、REPLを起動して実行してみます。 ファイル名はとりあえず、 test01.scad とでもしておきます。 できたファイルをscadで開いてみます。



表示されましたねー。

さらにこのscad、開いているファイルが変更されると自動的に読み込むようになっているので、primitiveを変えて関数を呼ぶだけで、scadの中の図形が自動で変更されます。

 ということで、scadの画面を開きながら、REPLでいろいろ試行錯誤しながらあれこれ形を作ることができるということのようです。

なかなか面白そうですよ。



こんな風に、Clojureの制御構文も使うことができます。






ということで、これでちょっと変った物をと思ったのですが、面白そうなものを思いつかず、時間も無くなってしまったので、将来の自分への宿題ということで・・・



READ MORE

clojure contrib library advent calender 投稿記事

Posted by YpsilonTAKAI On 2013年12月19日木曜日 0 コメント
clojure contrib library advent calender に記事を投稿しました。

numeric-tower と memoize です。

numeric-tower は、PEをやっているときに、何度か使っていたのだけれど、中身を見ていなかったので、今回題材にして中身を見てみた。 記事では中身のことは話題にしませんでしたけど、やっぱり参考になりますね。 普段、面倒くさがりなので、あまり他人のコードを読むことは無いのですが、いけないなーと思います。

もう一つはmemoizeです。
こちらは、このブログでも何回か取りあげた、clojureのコアに入っているmemoizeの強化版です。 作者は Joy of Clojureの著者のFogusさんです。 コアのmemoizeに苦戦しているころ、メーリングリストに新しいmemoizeの話題が出ていて作られたものです。
こっちのソースも今回初めて見てみたのですが、僕の理解の範囲を超えていて、まいったなーっていう感じです。

今回の担当分はこれで終りです。なんとか間に合いました。


READ MORE

2013 clojure系 Advent Calender

Posted by YpsilonTAKAI On 2013年12月6日金曜日 0 コメント
最近、あまり趣味プログラミンングをしていなくて、めっきり投稿していなかったわけですが、年末になったので、Advent Calenderイベントに参加してみています。

今年、参加しているのは、2つ。

  clojure contribライブラリを説明しまくってやろうというものです。athosさん主宰です。




もうひとつはclojure一般ものです。 って、あれ? こっちも担当今日じゃん!
やばいやばい。 書いてあったからいいようなものの、冷や汗ものだった。

こちらは、以前から作ろうと思っていた、zlogデータ操作ツール関連ですが、マクロの話題を取り上げました。



READ MORE

WindowsでClojure 1.3 + Emacs + SLIME

Posted by YpsilonTAKAI On 2011年12月20日火曜日 0 コメント
この記事は、Clojure Advent Calendar 2011の20日目の記事です。



[[2012/1/6 23:00 再修正]]
最新のswank-clojure (1,3.4)では、windowsのパス名の扱いの問題が解決していました。1.3.4以降のものを使えば、特に何もしないで使えます。



[[2011/12/26 23:00 修正]]

最初の投稿では、結局うまくいかなかったのですが、いろいろ調べたり方法を変えたりしてうまく行きました


これまで、Project EulerとかCode Jamとかやるときには、ClojureBoxを使ってました。ClojureBoxは、立ちあげるとすぐにREPLが使えて便利なのですが、だいぶ前にメンテナンスが終了していて、1.3になる可能性がありません。
自分で1.3に入れ替えるのもそれほど難しくなさそうですけど、1.2ベースで作っちゃったものもあるし、ソースの管理という意味でも、leiningenを使った環境にするのがいいかなと思ったので、やってみました。


READ MORE

ClojureでGUIアプリを作ってみた。

Posted by YpsilonTAKAI On 2011年12月5日月曜日 0 コメント

この記事は、Clojure Advent Calendar 2011の5日目の記事です。

Clojure界隈では、というより他でもWeb系のいろいろが沢山なわけですが、仕事がそっち系でないのでそういう指向があまりないのです。
Clojureは今のところ趣味で、主にProject Eulerとか解くのに使っているわけですが、以前、デスクトップアプリ作ってみたのでその時のことを。



環境
---------------------------------------
- マシン
自宅ではLinux機メインでやってますけど、仕事ではWin機です。

- エディタ
いつもはエディタとしてxyzzyを使っているのですが、Clojureを使うには環境があまり整備されていないし(自分でなんとかしろ?ですよねぇ。)、ClojureBoxってのがあるようなので、入れちゃうことにしました。

でも、もうメンテされていないので、1.3.0にしたければ自分でやることになります。 あまり手間もかからないとは思いますけど、そろそろ自分で一から環境作ってもいいかなと思ってます。

- shell
Leiningen使うにはコマンドラインを使うのですが、Winのcommand.comはとても使えたものじゃありません。cygwinとかmsysとか入れたらいいんでしょうけど、それはちょっとだったので、PowerShell使うことにしました。PowerShellが入っていなかったので入れました。

emacsからPowerShellを使いたいので、PowerShell-modeをここを読んで入れました
設定して起動したらと、"unrecognized shell program" って怒られます。特に問題無く動くんのでしばらく無視してたんですが、やっぱり気になって調べてみたら、ClojureBox/emacs/emacs/lisp/shell.el で出しているメッセージで、コーディングシステムを設定しているところでした。
command.comと同じ設定でいいだろうということで、PowerShell用の設定を追加して黙らせました。


587行目あたり

(cond ((w32-shell-dos-semantics) (set-process-coding-system proc cp-out-dos cp-in-unix)) ((string-match "/msys/" fullprog) (message "think it is MSYS...") (set-process-coding-system proc cp-locale-dos cp-locale-unix)) ((string-match "/cygwin/" fullprog) (message "think it is Cygwin...") (set-process-coding-system proc cp-locale-dos cp-locale-unix)) ;; 以下3行追加。 ((string-match "powershell.exe" fullprog) (message "think it is Powershell...") (set-process-coding-system proc cp-out-dos cp-in-unix)) (t (message "unrecognized shell program yosi: %s" fullprog)))))))

準備
---------------------------------------
- GUIツール
これまでJavaとか華麗にスルーして生きてきて、つい最近androidのアプリが作りたくて初めて触ったような人なので、awtとかswingとかちんぷんかんぷん。とてもそのままでは作れる気がしません。で、ちょっと調べてみたらよさそうなのがあるではないですか。

seesaw
Seesaw is a library/DSL for constructing user interfaces in Clojure. It happens to be built on Swing, but please don't hold that against it.
SeesawはUIを作るためのライブラリー/DSLで、Swingの上に構築されていますが、Swingがだめだというわけではありません。

メイン
https://github.com/daveray/seesaw

使いかた
https://github.com/daveray/seesaw/wiki


-プロジェクトの作成
1. Leiningenで新しいプロジェクトを作ります。
 lein new guitest
 cd guitest

2. project.cljを編集してseesawを追加します。

(defproject guitest "1.0"
  :description "Seesaw test project, and more."
  :dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
[seesaw "1.0.7"]]                        ;; 作ったときはこれが最新だった。
  :main guitest.core)                             ;; スタンドアロンにするにはこれが要る。


これで準備は終り。


作成
---------------------------------------
「画像処理おもしろそう」と思って作ったアプリがあるのでこれについて。
GUIが目的ではないので見た目とか適当です(なんのこっちゃ)。

  ★★
  って書いておいて、動かしてみたら動かない。
  処理を早くしようとか、保存できるようにとかしてる途中だったみたいです。
  次の番が回ってくるまでに動くようにしときます。*_*;;;;;;

  動いていたときの画像。




- ソース (github)
https://github.com/ypsilon-takai/clojure-seesaw-test001

苦しまぎれに、解説なんかを。 いや、自分用に...
こうした方がいいんじゃない?ってなことがあれば、ご指摘いただけるとうれしいです。


core.clj
----------------------
 UI部分。画像の読み込みと表示。
 画像処理部分は、別ファイル (imagetool.clj)

14行目
 * 元画像BufferedImage と 表示用画像BufferedImage と 画像処理用long-array など
   書き換えるのでmutableなデータになってます。

23-38行目
 * 入力画像の選択/結果の出力ダイアログ。
   seesawのダイアログを使ってるだけ。

43-78行目
 * 新しい画像を読み込んだときの処理関数たち。
   下の2つが、新しいデータを作る関数と、データを再表示する関数。

81-87行目
 * 画像を保存する関数たち。

91-140行目
 * 画像処理関連
   配列からBufferedImageを作る関数。
   グレースケール化とエッジ検出の処理を呼ぶ関数。

141行目からGUI関連

147-216行目
 * 各ボタンの定義。 actionはそのためのseesawの関数(マクロ?)です。
   押されたときの関数を定義したり、ボタンに表示される文字列を設定したりします。
   Clojure流に設定できるので、気持いいです。

218行目
 * ウィンドウの定義です。
   実行すると、ウィンドウのフレームを返します。
   :content で中を定義します。
   これもClojure流に設定できます。

248行目
 * このクラスのメイン関数です。
   projectファイルでこのファイルをmainとしているので、jarを実行したときに、この-main関数が呼ばれます。
   native! を呼んでおくと、見た目がプラットフォームのものになるそうな。
   上で定義したmain-windowに show!してやると表示されます。




imagetool.clj
----------------------
前半はたいしたことやっていないので割愛。

72行目からがエッジ検出のところです。
いくつかの種類のフィルタを使えるようにしてあります。

create-operationは、フィルタを与えると、どうすればいいかを返します。

transform-to-edge-imgは、画像のデータの入った配列と変換の種類を受け取って、変換後の配列を返します。

READ MORE