F#

『火薬学の基礎』なんて言う、ちょっと恐い本が有ったので読んでみた。こういう本が 図書館に新刊として置いてあるって事は、近くに隠れテロリストが居るのかしらん。 一体、どういう基準で本を購入してるのやら?

内容はいたって真面目。爆弾の作り方なんて隅から隅まで読んでみても出てこないので 安心。燃焼とは何かから始まって、化学反応の式が出てきたり、運動方程式が出てきたり、 奥が深いんですなあ。火薬は固体ロケットには、かかす事が出来ない素材なんで、いろ いろと研究されている。

何かの本で読んだ事があるんだけど、固体燃料と液体燃料のどちらを使ったロケットの 比較が出てたけど、固体ロケットは、圧倒的に機構が簡単。点火したら、もう消化する 手段は無し。運を天に任せるしか無い。燃料注入とかの面倒な作業もいらないので、 比較的簡単に作れるとか。

件の本に面白い事が書いてあった。黒煙火薬の原料は、炭と硝石と硫黄。火薬が日本に 渡ってきた時、時の権力者は自作しようとした。けど、硝石だけは日本に産出しない。 代替は出来ないか? いろいろ実験して、魚のはらわたを土の中に埋めて、、、って やって、やっと自作出来るようななったそうな。執念ですね。

火薬と爆薬はどう違うか? なんてのも解説されてたなあ。爆薬と言うと小説の読みすぎで プラスチック爆弾C4ってのを思い出したんだけど、C4ってのはこの本には出ていなかった。

ぐぐるさんに聞いてみると、プラスチック爆弾 作り方なんてのをサゼッションされて、 恐い世の中だと思ったぞ。で、C4はRDX系の爆弾なのね。アメリカ軍での呼称みたい。 自衛隊も、勿論使っている。

こういう風に爆弾の作り方なんて単語が混じっていると、NSAから眼を付けられますかね? そんな事が無いように、関係無い事も一杯書いておこう。で、次は詐欺の話。おっと、 これも危ないな。サツに眼をつけられそう。

F sharp

前回に引き続いて、F#が熱いようなので、首を突っ込んでみる。 何はなくても、総本山Visual F# ですな。政府広報の、 関数型プログラミングの .NET 開発者向け概要 とか .NET Framework で関数型プログラミング手法を使用する なんてのもあるぞ。

民間だと F#言語の基礎文法 とか F#を学ぼうと思う時見るべきサイト かな。まあ、ML(メタ言語)系だからと言って、おいらがML(メタ リンク)する事はあるまい。 各自、好きにやってくらはい。

FreeBSDでWinもどき

民間の方が書かれたF#関係F#入門にあった、GUIのアプリ、簡単なエディタが 果たしてmonoで動くやら? 早速行ってみよー。

コピペしてきて、やばそうな日本語文字が 入ってる所は、除去もしくは英語に翻訳(こう書くとカッチョイー)して下準備しとく。 余計な文字コードに起因するエラーは避けたいですからね。

[sakae@pcbsd ~/fs]$ fsharpc ed.fsx
F# Compiler for F# 3.0 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

/usr/home/sakae/fs/ed.fsx(41,4): error FS0010: Unexpected symbol ';;' in implemen
tation file

/usr/home/sakae/fs/ed.fsx(41,1): error FS0010: Unexpected keyword 'end' in type d
efinition. Expected incomplete structured construct at or before this point or ot
her token.

/usr/home/sakae/fs/ed.fsx(40,1): error FS1161: TABs are not allowed in F# code un
less the #indent "off" option is used
    :
/usr/home/sakae/fs/ed.fsx(8,34): error FS0564: 'inherit' declarations 
cannot have 'as' bindings. To access members of the base class when 
overriding a method, the syntax 'base.SomeMember' may be used; 'base' 
is a keyword. Remove this 'as' binding.

ははは、盛大にエラーが出てますよ。上2つのエラーはよー分からんけど、それ以外は何とか なりそう。 まずは盛大に出てるエラーFS1161だけど、仰せに従って、ファイルの冒頭付近に、#indent "off"を 入れてあげた。

[sakae@pcbsd ~/fs]$ fsharpc ed.fsx
F# Compiler for F# 3.0 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

/usr/home/sakae/fs/ed.fsx(1,1): warning FS0062: This construct is for ML 
compatibility. Consider using a file with extension '.ml' or '.mli' instead. 
You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.

/usr/home/sakae/fs/ed.fsx(9,34): error FS0564: 'inherit' declarations 
cannot have 'as' bindings. To access members of the base class when 
overriding a method, the syntax 'base.SomeMember' may be used; 'base' 
is a keyword. Remove this 'as' binding.

エラーのFS0546(エラー番号なんて懐かしいなあ)は、何とかせんとな。

type Editor = class inherit Form
// type Editor = class inherit Form as base

こんな具合に修正した。後は仰せに従って、

[sakae@pcbsd ~/fs]$ fsharpc --mlcompatibility ed.fsx
F# Compiler for F# 3.0 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

これで、9k弱のed.exeが出来上がったよ。そしてそれはPCBSDで無事に動いた。コンパチ度が 高いと評価して良いのだろうか。全部入りのed.exeを作って(1Mに肥大化した)Windowsへ持って行ったら、 こちらも無事に動いたよ。

debianでもF#

aptになってるので、素直に入れればいい。とは言え、リポジトリィを下記のように /etc/apt/source.listに追加しとく必要が有るけど。

deb http://http.us.debian.org/debian/ unstable main contrib non-free 
deb-src http://http.us.debian.org/debian/ unstable main contrib non-free 

こちらの方は、emacs24なんて言う先進的なやつも置いてあるよ。但し、安定版と混ぜたら どんな化学反応を起すか知れないので、覚悟が必要。おいらは、素直に

 sudo apt-get update
 sudo apt-get install mono-devel
 sudo apt-get install fsharp
 sudo apt-get install fsharp-console
 sudo cp -p /usr/lib/cli/FSharp.*-4.3/* /usr/lib/mono/4.0/

だけをやったよ。これで、Winもどきのアプリも動くようになった。こうなると、monodevelop とか言う、visual stdio(on Linux)も入れてみるかな。きっとあるだろうな。天下のdebian様だもの。 安定版にも用意されてた。

それは、それでいいんだけど、言語選択にF#が出てこない。はて、どうすればいいの? メニューのクリック猿になって、あちこちをお触りしてたら見つけたよ。 toolsの中のAdd-in Managerをクリックして、追加すればいいんだ。後は使うだけだな。

fedoraでもF#

debianでは、軽くapt-getでF#環境が手に入った。fedoraでは、(おいらの知らない)パッケージ マネージャを使うと、簡単に環境が構築出来るっぽい。けど、ソースから素直に入れて みる事にした。

まずはmonoだけど、apt-getの例を、軽くfedoraに翻訳すればいいのね。

sudo apt-get install libtool autoconf g++ gettext make git
 git clone https://github.com/mono/mono
 cd mono
 ./autogen.sh   --prefix /usr
 make get-monolite-latest
 make
 sudo make install

いきなり /usrの下に入れるのは、あれなんで、/usr/localに入れる事にした。 時間はかかったけど、何なく完了。次はF#だな。

sudo apt-get install autoconf pkg-config make git
 git clone https://github.com/fsharp/fsharp
 cd fsharp
 ./autogen.sh --prefix /usr
 make
 sudo make install

いきなり、aotogen.shで文句を言われた。mono2.9以上が欲しいってさ。ちゃんと3.3が 入っているのに、どうなってるの? autogen.shから解剖開始。要は

autoreconf && ./configure $@

configureファイルを自動生成して、それを走らせているだけ。次は、configureを見ろって 事だな。該当箇所を見ると、

MONO_REQUIRED_VERSION=2.9
MONO_RECOMMENDED_VERSION=3.0

if ! pkg-config --atleast-version=$MONO_REQUIRED_VERSION mono; then
        AC_MSG_ERROR("You need mono $MONO_REQUIRED_VERSION")
fi

2.9ってのは、ここから出てきてるのね。monoのバージョンを調べようとした、pkg-configが 失敗したって事。次は、pkg-configのmanを見ろ。そして想像しろ! かな。

       pkg-config  retrieves  information about packages from special metadata
       files. These files are named after the package, and has  a  .pc  exten‐
       sion.    On  most  systems,  pkg-config  looks  in  /usr/lib/pkgconfig,
       /usr/share/pkgconfig,           /usr/local/lib/pkgconfig            and
       /usr/local/share/pkgconfig  for these files.  It will additionally look
       in the colon-separated (on Windows, semicolon-separated) list of direc‐
       tories specified by the PKG_CONFIG_PATH environment variable.

/usr/local/lib/pkgconfigの中にある、mono.pcってのを調べようとしてるんだな。先回りして 調べちゃえ。

[sakae@fedora pkgconfig]$ cat mono.pc
prefix=${pcfiledir}/../..
exec_prefix=${pcfiledir}/../..
libdir=${prefix}/lib
includedir=${prefix}/include/mono-2.0
sysconfdir=${prefix}/etc

Name: Mono
Description: Mono Runtime
Version: 3.3.0

pkgを作った時の各種配置やらが記録されてるんだな。それが参照出来ないって事は、fedoraは /usr/localなんて僻地の事は無視する態度なんだな。だったら、こうしてやる!

[sakae@fedora PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

これで、無事にconfigureが出来たよ。赤帽ったら、意地悪なんだから! 最後は、インストールだな。

[sakae@fedora sudo make install
  :
gacutil -i /home/sakae/z/fsharp/lib/release/4.0/FSharp.Core.dll -root /usr/local/lib/ -package 4.0
make[2]: gacutil: Command not found
make[2]: *** [install-lib-4] Error 127

またエラーだよって嘆いちゃいかん。rootさんも僻地は無視の、赤帽に右に倣えでしたから。 とにかく、ソースからのインストールは、へこたれない精神と

[sakae@fedora z]$ du -sh *
163M    fsharp
1.6G    mono

たっぷりなDISK容量と、暇な時間が必要ですだ。記念に、何か実行してみる。PCBSDでやった ed.fsxが良かろう。

[sakae@fedora fs]$ mono ed.exe

Unhandled Exception:
System.TypeInitializationException: An exception was thrown by the type initiali
zer for System.Windows.Forms.WindowsFormsSynchronizationContext ---> 
System.TypeInitializationException:
An exception was thrown by the type initializer for System.Windows.Forms.ThemeEngine --->
 System.TypeInitializationException: An exception was thrown by he type initializer 
for System.Windows.Forms.ThemeWin32Classic ---> System.TypeIn
itializationException: An exception was thrown by the type initializer for 
System.Drawing.KnownColors --> System.TypeInitializationException: An exception 
was thrown by the type initializer for System.Drawing.GDIPlus ---> 
System.DllNotFoundException: /usr/local/lib/libgdiplus.so

  at (wrapper managed-to-native) System.Drawing.GDIPlus:GdiplusStartup (ulong&,S
ystem.Drawing.GdiplusStar
tupInput&,System.Drawing.GdiplusStartupOutput&)
  :
  at System.Windows.Forms.Form..ctor () [0x00000] in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Form:.ctor ()
  at editor+Editor..ctor () [0x00000] in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) editor/Editor:.ctor ()
  at <StartupCode$ed>.$editor$fsx.main@ () [0x00000] in <filename unknown>:0

実に長ったらしいエラーが出てきた。でも、恐れる事なかれ。じっと眼を凝らして見れば libgdiplus.so が無い事に起因してるようだ。 入れてあげて、/usr/local/etc/mono/configの所で、僻地指定されてたのを、赤帽標準の 場所にしたら、動いたよ。やれやれ。

ついでなので、emacsからも何出来るようにと思って、 fsharp-mode を手動で入れようとしたら、コンパイルエラー発生。エラー内容を調べて直すのも かったるいので、

;;; Initialize MELPA
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))
(unless package-archive-contents (package-refresh-contents))
(package-initialize)

;;; Install fsharp-mode
(unless (package-installed-p 'fsharp-mode)
  (package-install 'fsharp-mode))

(require 'fsharp-mode)

をやって、お茶をにごした。コマーシャルでもやってるね。澄んだお茶とか濁ったお茶とか 、どっちでもいいけど飲んでくれーーーーってね。emacsも一頃に比べて、パッケージの 導入が楽になったわい。まるで、rubyのgemみたい。

調子に乗って、もう少しmono上で動くF#の機能を試してみる。元ネタは アベント カレンダー2011 にあった、httpのクライアント。

open System
open System.Net

//ヘッダ取得
let getHeaders (h:WebHeaderCollection) =
    [0..h.Count-1]
    |>Seq.map(fun i-> h.GetKey(i),h.[i])

//HTTPリクエスト
let req = HttpWebRequest.Create("http://www.google.co.jp/")
req.Timeout <- 15000 //タイムアウト(15秒)
//HTPレスポンス
let res = req.GetResponse():?>HttpWebResponse

printfn ""
printfn "[SEND]"
getHeaders(req.Headers)|>Seq.iter(fun(k,v)->printfn "%s: %s" k v)

printfn ""
printfn "[RECV]"
getHeaders(res.Headers)|>Seq.iter(fun(k,v)->printfn "%s: %s" k v)

printfn ""
printfn "何かのキーを押してください。"
Console.ReadKey() |> ignore

無修正のままで、動きました。素晴らしい!! 喜んでいちゃいけないね。おいらの 知らない事が結構あるぞ。|> とか、 :?> とか。 シンボルと演算子のリファレンス (F#)

ドットネットのライブラリーは、 .NET Framework クラス ライブラリ あたりを見ればいいのかな。

monodevelop

折角なので、monodevelopを使ってみる。Tutorialって型が、F#のプロジェクトに有ったので やってみた。そしたらファイルが一つ自動作成されてた。debugとかreleaseモードで ファイルが作れたり、breakpointを貼って、ステップ実行出来るのね。

[sakae@pcbsd ~/MD]$ tree first
first
├── first
│   ├── Tutorial.fs
│   ├── bin
│   │   ├── Debug
│   │   │   ├── first.exe
│   │   │   └── first.exe.mdb
│   │   └── Release
│   │       ├── first.exe
│   │       └── first.exe.mdb
│   ├── first.fsproj
│   └── obj
│       └── x86
│           └── Debug
├── first.sln
└── first.userprefs

ソースを、ちらちら見てくと

    /// A list containing all the days of the year
    let daysList =
        [ for month in 1 .. 12 do
              for day in 1 .. System.DateTime.DaysInMonth(2012, month) do
                  yield System.DateTime(2012, month, day) ]

リストの内包表記って、蛇に有ったね。

module UnitsOfMeasure =
    // Code can be annotated with units of measure when using F# arithmetic 
    // over numeric types

    open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames

    [<Measure>]
    type mile =

        /// Conversion factor mile to meter: meter is defined in SI.UnitNames

        static member asMeter = 1600.<meter/mile>


    let d  = 50.<mile>          // Distance expressed using imperial units
    let d' = d * mile.asMeter   // Same distance expressed using metric system

    printfn "%A = %A" d d'
    // let error = d + d'       // Compile error: units of measure do not match

ふむ、数学分野にも手を伸ばしてきたか。