04/08: そろそろ前期開始
新入生の皆さん、入学おめでとうございます。
自分が入学したのは2年前ですが、
早いもんであと1年で卒業です。
で春休みですが、なんか作ろうかと思ってたんですが、
正直就活で暇がありませんでした。
活動始めたばっかりのころはめんどくさいなーとか思ってたんですが、
説明会でいろんな企業の話を聞いたり、
自己分析で自分の長所短所を見つけたり、
筆記対策に参考書をといてみたり、
グループワークで他大学の人としゃべったりと、
いい経験になります。楽しいですし。
まあ、まだ内定はないんですが…。
結果にかかわらず、それに納得できるような活動をしていきたいですね。
03/30: 本文の< とかをエスケープするブックマークレット
部長のエントリのソースコードの<やら>やらがエスケープされていないのがいっこうに直らないのでブックマークレットを書きました。
これをブックマークしてブログの編集画面で実行すると <pre><code> から </code></pre> を適当にエスケープします。
これは brainf**k で書かれた Hello, World ですが、
こんな感じにエスケープされます。
便利ですね。
03/27: Hackage にライブラリを上げてみました
Haskell のライブラリを書いて、Hackage にアップロードしてみました。
Haskell というのは、
Haskell is an advanced purely functional programming language.
Hackage というのは、
Haskell's CPAN wanna-be
03/19: ロゴを作ることにしました
02/09: なるべく短いコードで SEGV
Segmentation fault を確実に起こすようななるべく短いコードが書けないかと思って挑戦してみました。
まず考えたのはこれです。
main(){main();}
$ echo 'main(){main();}' > segv.c
$ gcc segv.c
$ ./a.out
Segmentation fault
再帰的に main() を呼び出してくうちにスタックがコード領域にまで入って SEGV って感じですね。
なので末尾再帰が最適化されると SEGV しなくなります。
gcc の場合オプション -O をつけると末尾再帰をジャンプに変換してくれるようです。
$ gcc -O segv.c
$ ./a.out
^C # Ctrl-C で中断するまで終わらない
アセンブリで出力してみて diff するとよくわかります。
$ gcc -S segv.c -o segv.s
$ gcc -S -O segv.c -o segvO.s
$ diff -u segv.s segvO.s
--- segv.s 2009-02-09 21:36:50.000000000 +0900
+++ segvO.s 2009-02-09 21:36:57.000000000 +0900
@@ -3,8 +3,6 @@
_main:
pushl %ebp
movl %esp, %ebp
- subl $8, %esp
- call _main
- leave
- ret
+L3:
+ jmp L3
.subsections_via_symbols
最適化に負けないようにするには、最後の main() を呼ぶときに何か引数を渡せば良いです。
main(){main(0);}
関数の引数の宣言を省略すると、その関数には何でも渡せてしまいます。しかも渡した引数はスタックに残っています。main() が引数をどう使うかを、コンパイラが解析しようとしても(引数を使っていないことがわかればその引数を渡さないようにできます)、そもそも引数の宣言がないのでどうにもできません。
これより短い(16バイト以下)のがあったら教えてください。
ちなみに、エントリポイントを変えるのは無しです。
12/31: 年賀状を書きました
#!/usr/bin/env ruby
d=:define_method;
alias :L :lambda;
h= :happy;
S= Struct;
C=Class;A=S.new(h).new(C.
new{|c|c.send(d,:year,
L{ |g|puts(
g. scan(/\S/
).inject(0){|a,c|a+=c[0]})})})
A.happy.new.year <<CINCS
(__)
(00)
/.----..\/
/ | ||
* !!----!!
^^ ^^
CINCS
保存して実行して読みます。こうなるはずです。
$ ruby greeting.rb 2009
追記: いや、こうすれば保存もしなくていいですね。
$ ruby -ropen-uri -e 'eval open("http://blog.cincs.net/item/200.html").read[%r|<code>(.+?)</code>|m, 1].gsub(/</, "<")'
2009
誰かが年賀状にいたずらしない限りですが。
年賀状の書き方
用意するもの
- どこにでもあるインタプリタ or コンパイラ
- どこにでもあるエディタ
- けっこうな時間
- 無駄な知識
では書きましょう
- 普通に書く
-
難読化を施す
- 文字が足りなかったり多かったりしたら気合いでなんとかする
- おわり
君もレッツトライ
追記: 編集してて気づいたんですがこれがこのブログの 200 個目の記事らしいです。よいお年を。
11/18: quine
みんな相変わらずマウスの追い込みで忙しそうなので、マウスとは全然違う話を書こうと思います。
自己出力プログラムと自己参照プログラム を読んだら quine が書きたくなったので書きました。
quine というのはそのプログラム自身を出力するプログラムのことです。javascript で書いてみました。
(function () {alert(arguments.callee.toSource() + "()");})()
Firefox とかで動きます。javascript の関数は自分自身を文字列で持ってるのでそれを使えば、、、って全然 quine っぽくないですね。
quine っぽいってどういうことかといえば Wikipedia に scheme で書かれた quine が載ってるんですが、それはすごく quine っぽい quine だと思います。引用しますね。
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
quine は、文字列化(クオート)された自分自身を出力するプログラムってことですが、上の scheme の例はそれをそのまま現しているように見えます。つまり、
((lambda (x) (list x (list 'quote x))) ; この部分を <1> とする。 ; <1> は 1 引数の関数。 '(lambda (x) (list x (list 'quote x)))) ; この部分を <2> とする。 ; <2> は クオートされた <1>。 ;; このプログラムは <1> を <2> で、 ;; つまり、クオートされた <1> で呼び出している。
というふうに見なすことができて、それはとてもいいなあと思うのですが、これを見た後で自分の javascript の quine を見るとなんか、ないわーって感じです。
でもせっかくなのでブックマークレットにしました。これでいつでもどこでも quine できます。
ついでに、Firefox 以外でも動くようなものを考えてみました。
(function () {alert(("(" + arguments.callee.toString() + ")()").replace(/\n|\s{2,}/g, ""));})()
こんな感じです。出力をあわせようとがんばってみました。
The Quine Page にはいろんな言語(けっこう渋めのが多い気がしますが)、いろんなアプローチで書かれた quine があります。個人的には C の quine がすごく好きです。こんなのです。
main(a){a="main(a){a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}
11/08: Pong 作った
11月祭おつかれさまでした。
とはいっても、僕は手伝いにすら行かずこんなのつくってました。(Firefox とかで見てください。いまちょっと Safari で見てみたらぜんぜんだめでした。でも Opera やったらいけるかも。IE? なんですかそれ)
というのも
3日くらい前に部長に11月祭何か出さないかとか言われる
↓
何も準備してないから無理と答える
↓
家に帰る
↓
おもむろに canvas のチュートリアルを読み始める
↓
案外簡単にいろいろできることを知る
↓
ブロック崩しでも作って11月祭に出そうとか思う
↓
ボールを作る
↓
跳ね返るところのロジックではまる(この時点で11月祭の朝)
↓
なんとなくブロック崩しじゃなくて Pong を作ることに決める
↓
雨が降ってる 自分がこんなことしてるから雨が降ってるんだとか考える
↓
でも一回寝てから急げば間に合うかもと思って寝る
↓
起きてバンパーを作る
↓
跳ね返るところのロジックではまる(2回め)
↓
いろいろ調整する
↓
なんとかそれっぽくなる
↓
でも11月祭終わってる
↓
ふてくされてAppJetにあげる←いまここ
10/16: 思いついたので 3
キャスト演算子で遊んでみました。
#include <iostream>
#include <sstream>
struct Int {
Int (int i) : i_(i) {}
operator std::string () {
std::stringstream ss;
ss << i_;
return ss.str();
}
operator int () { return i_; }
int i_;
};
struct Double {
Double (double d) : d_(d) {}
operator std::string () {
std::stringstream ss;
ss << d_;
return ss.str();
}
operator double () { return d_; }
double d_;
};
const std::string
operator, (const std::string& lhs, const std::string& rhs) {
return lhs + rhs;
}
int
main () {
Int one(1);
Double zero_point_three(0.3);
std::cout << one + zero_point_three << std::endl; // 1.3
std::cout << (one , zero_point_three) << std::endl; // 10.3
return 0;
}
暗黙のキャストばんざい。
ちなみに、
template <class T>
opetator std::string (const T& arg) {
std::sstream ss;
ss << arg;
return ss.str();
}
こんなこともしてみましたが、キャストのオーバーライドはクラスの
static じゃないメンバ関数じゃなきゃできないよ
(要約)とかコンパイラに言われ
ました。
演算子の優先順位もオーバーライドできればいいなあとおもいました。
シフト演算子より優先度高い演算子で結合っぽく見える演算子は算術系にだい たい取られちゃってて、仕方ないからカンマ使ってカッコでくくるはめになっ てます。
10/02: 思いついたので 2
このあいだは、Haskell の import qualified なんとか as かんとかな文法を Perl に移植(?) しましたが、今回も思いついたので Haskell のパターンマッチ を javascript に移植しました。
使用した javascript 処理系は SpiderMonkey 1.7.0 です。
というわけで
factorial 1 = 1
factorial n = n * factorial (n - 1)
というような階乗を求める Haskell は、いまや javascript で
function factorial() {
return bind("1").call(function (_) { return 1 }).
bind("n").call(function (b) { with(b) return n * factorial(n - 1) }).
invoke()
}
こんな感じに書けます。
他にも、
foldl i _ [] = i
foldl i f x:xs = foldl (f i x) f xs
が
function foldl() {
return bind("i,_,[]").call(function (b) { return b.i }).
bind("i,f,[x,*xs]").call(function (b) {
with (b) return foldl(f(i,x),f,xs) }).
invoke()
}
になったり、
data Foo a = Foo { getFoo :: a }
が
function Foo (a) { return { foo: a } }
function getFoo() {
return bind("{foo: x}").call(function(b){return b.x}).invoke()
}
だったりします。
追記: foldl の引数 i と f 逆だった orz
改めて使い方を説明します。
bind(pattern)で現在のargumentsをpatternの文法にそって束縛 します。patternの文法は Haskell のパターンマッチと Ruby の多重代入を混ぜた ような感じです。patternは文字列です。念のため。bind(pattern)に対してcallすると束縛が成功していればcallに渡された関数がその束縛(ハッシュ)を引数にして呼ばれます。callに対してinvokeするとcallの結果の値が得られます。bind(pattern).call(procedure).bind(pattern).call(procedure).bind...という感じでつなげて書けます。invokeで一番最初に成功した束縛に対し て呼び出された関数の返り値が取れます。なんで
invokeを呼ばなきゃ取れないようにしたかといえば遅延評価って いうかinvokeするまで初段のbindも実行されないようにしようとし ていた名残ですがすっかりそんなこと忘れてました。
案の定以下ソースなのですが、お前の書く記事はよくわからんといわれたので、 ソースを読む人の助けになると思われなくもない解説を書きます。
arguments.callee.caller.argumentsで、「その関数を呼び出した関数が 呼び出されたときの引数」が取れます。- しかし
argumentsはArrayではないのでうっかりarguments.slice(1)とかやるとエラーになります。なので受け取ったらすぐ Array に変換してます。
- しかし
javascript のクラスの書き方は適当にぐぐってコピペしたのでよくわかりま せん。でもこの書き方はインデントが深くならないので自分では好きです。
そういえば
{foo : {bar : baz}}というハッシュのネストを正しくパースできません。 つまり、ネストされたハッシュをpatternに使えません。throwの使い方がアレです。やはりネタです。うっかり使っていたい目にあっても知りません。
メソッドチェーンで非同期処理を書くライブラリ JSDeferred が非常に参考になりました。どう見てもパクリですありがとうございました。