F# 談話室の15回に参加し、艦これ 司令部室について発表してきました。これに合わせてGitHubでリポジトリも公開しました。
COMの素晴らしさを力説し、また布教してきました。比較的に好感触でした。
たいしたことをは書いていませんが、発表に使ったプレゼンテーションはこちら
COMダメ、絶対! #fsroom
— 赤ペン先生テラモナギ (@teramonagi) June 8, 2014
.NETとWin32ネタが主です。UNIXもいじるのでその辺りも混じるかも。
F# 談話室の15回に参加し、艦これ 司令部室について発表してきました。これに合わせてGitHubでリポジトリも公開しました。
COMの素晴らしさを力説し、また布教してきました。比較的に好感触でした。
たいしたことをは書いていませんが、発表に使ったプレゼンテーションはこちら
COMダメ、絶対! #fsroom
— 赤ペン先生テラモナギ (@teramonagi) June 8, 2014
WinFormsのTextBox Controlの話題です。とても基本的なControlですが落とし穴がありました。IMEで漢字変換中にフォーカスを失うと未確定文字はそのままIMEが持って行ってしまいます。 WinFormsがこのような挙動をすることを知らず何も制御していなかったために、自作のアプリケーションがクソ呼ばわりされる事態に陥ってしまいました。 とても悲しかったのでTextBoxを派生して挙動を改良してみました。 IMEが開いているかどうかはImeContext.IsOpen()で調べることができますが、そのあと同じハンドルを使用して処理することになるため、IsOpenは使いませんでした。
C# は高級アセンブラ、続 C# は高級アセンブラの続きです。
C#ではおよそ最適化できることろがなくなってきていて、最後のブレイクスルーとして、altriveさんの
@haxe さんのコード見て、これ以上最適化できそうもないので、自分のコードも公開。https://t.co/rnekjQyrjx 工夫してるのは下記の2点。
・標準入力が遅かったので、PInvokeでCのライブラリを呼び出し
・RadixSortを条件に合わせて最適化
— altrive (@altrive) December 6, 2013
を真似させてもらいました。標準入出力を扱うConsoleクラスはstaticメソッドになっているため、マルチスレッドセーフにするためにどうしても処理が重くなっていることはわかっていました。LEA EBX, [EAX * 4 + EAX] ; EBX = EAX * 5 LEA EAX, [EBX * 8 + EAX] ; EAX = EBX * 8 + EAX = EAX * 41と2命令で表現できます。そしてx * 205も3命令です。
LEA EBX, [EAX * 4 + EAX] ; EBX = EAX * 5 LEA EAX, [EBX * 8 + EAX] ; EAX = EBX * 8 + EAX = EAX * 41 LEA EAX, [EAX * 4 + EAX] ; EAX = EAX * 205やりだすと本当に奥が深くなります。
この記事はF# Advent Calendar 2013に参加しています。14日目を担当させてもらいます。
F# は、従来のオブジェクト指向プログラミングと命令型 (手続き型) プログラミングに加えて、関数型プログラミングをサポートするプログラミング言語です。 Visual F# 製品は、F# アプリケーションの開発と F# コードを使用した他の .NET Framework アプリケーションの拡張をサポートします。 F# は、.NET Framework 言語のファースト クラスのメンバーであり、関数型言語の ML ファミリに著しく似ています。…と説明されています。MLファミリと書かれていますが、中でもオブジェクト指向的要素が追加されたOCamlとはかなりの類似点していて、F#で提供されるコアライブラリの基本部分はOCamlのモジュールと一致しています。そこでOCamlとF#の違い、その理由について探ってみようと思います。
$ ocamlc -I +camlp4 -pp camlp4rf -c Camlp4FSharpPrinter.mlでCamlp4FSharpPrinter.cmoが生成されます。
$ cp Camlp4FSharpPrinter.cmo $ocaml/lib/camlp4/Camlp4Printers/とコピーします(尚、パッチ元のOCaml.mlのあるディレクトリとは別です)。その上で、OCamlソースコードをF#コードに変換するには
$ camlp4of -printer Camlp4FSharpPrinter -o fsharp-source.ml ocaml-source.mlと実行します。
C# は高級アセンブラの続きです。
何とかして高速化しようと思い試してみました。まずはボツ案から。
あ、はい、ごめんなさい。
@haxe メモリが余裕ありそうなので、バケツぶっかけてどーなるか今から試してみよっかなって
— 時計屋 (@NetSeed) December 7, 2013
@haxe ソート自体をO(n)で完了してるんですが、逆に定数が若干多めって言うかなんていうか。。。その辺が問題じゃないかなって
— 時計屋 (@NetSeed) December 7, 2013
これを元にソート方法を見直し…というよりソート行為がほぼ不要になったためについでにzero copyも取り入れたところ、逆にコードがキレイになってしまいました。
スコアも上々で、0.02 / 0.02 / 0.03となりました。
タイトルに意味はありません。
今、新人女子プログラマの書いたコードを直すだけの簡単なお仕事です!|というオンラインハッカソンがアツいです。特に野田さんのニーソは素晴らしいです。
私はC#言語しか使えないので頑張って書いてみました。採点結果は0.02秒 / 0.02秒 / 0.05秒の100点になりました。これが私の限界のようなのでgistにソースコードを公開しておこうかと思います。
特筆することはない至極素直なコーディングに心がけましたが…ちょっとだけ解説を。
F#のPrintfモジュールはある程度の書式指定ができるようになっていますが、基になっているOCamlが貧弱なせいもあってString.Format()ほどの表現力はありません。 何か手はないかと考えたところ %a 書式指定を思い出しました。Core.Printf モジュールには
2 つの引数を必要とする一般的な書式指定子。 1 つ目の引数は、2 つの引数を受け取る関数です。この関数の 1 つ目の引数は、指定した書式設定関数 (TextWriter など) に対応する型のコンテキスト パラメーターです。2 つ目の引数は出力する値であり、この値によって、該当するテキストを出力するか、返すかを指定します。
2 つ目の引数は、出力する特定の値です。
とあります。いまいちわかりづらいので英語版ドキュメントも確認しましたが同じ内容で意味がよくわかりません。念のためOCamlのmodule Printfも確認します。
user-defined printer. Take two arguments and apply the first one to outchan (the current output channel) and to the second argument. The first argument must therefore have type out_channel -> 'b -> unit and the second 'b. The output produced by the function is inserted in the output of fprintf at the current point.
なるほどわかりません。
とりあえずF#で書いてみたところ、非常に面倒くさいことが判明しました。1つ目の引数の説明「TextWriter など」が罠です。 なんとprintfとsprintfとで要求される関数が違いました。具体的に関数を挙げた方がわかりやすいので、現在時刻をコンソール出力してみます。
let formatter_for_printf (textWriter : TextWriter) (dateTime : DateTime) = textWriter.Write("{0:MM/dd HH:mm}", dateTime) let formatter_for_sprintf () (dateTime : DateTime) = String.Format("{0:MM/dd HH:mm}", dateTime) printfn "%a" formatter_for_printf DateTime.Now sprintf "%a" formatter_for_sprintf DateTime.Now |> Console.WriteLine
つまり同じ %a でも
ということのようです。
OCaml側は確認していませんがドキュメントからはそう読み取れないため、F#の(限りなくバグに近い)仕様かなと思います。