並列プログラミングカンファレンス
- 並カン : ATND
- 主催のmootohさんと会場を貸してくださったIIJのみなさま、ありがとうございました
- 仕事がかなり忙しい時期だったけど、参加してよかった
- 懇親会も豪華メンバーだった
carをつかわずにリストの先頭要素を取り出す
@baal5084さんの出題
スキームクーイズ!さて突然ですがここで Schemer の皆さんに問題です。 Q1. リストの最初の要素を car と list-ref を使わず取り出してください。
http://twitter.com/baal5084/status/8226643131
@athos0220さんの模範解答(http://twitter.com/athos0220/status/8227286234)
(apply (lambda (x . _) x) lst)
自分もやってみた
(define (my-car lst) (set-cdr! lst '()) (apply (lambda (x) x) lst))
リストをぶっ壊すとかちょっとありえない。2度とcdrできないし
ということで元のリストが壊れないようにしてみた
(define (my-car lst) (let ((temp (append lst '()))) (set-cdr! temp '()) (apply (lambda (x) x) temp)))
第185回 素人くさいSICP読書会(at 三田某所)
- 会場提供ありがとうございました
- 間違えて月島に行った人が約1名
- 佐野さんがSchemeバトンで苦しんでいるのを横目に黙々と問題5.19を解いていました
- 問題5.19
- 先週書いた「命令列にブレークポイントを書き込む関数」がきちんと動作することを確認
- search-labelでラベルを検索し、見つかったらset-bpでオフセットの位置のブレークポイント(instの4要素目)を書き換え
(define (write-breakpoint-to-insts insts label n bp) (define (set-bp insts i) (if (null? insts) (error "Out of range -- BREAKPOINT" label n) (let ((inst (car insts))) (if (= i 1) (set-cdr! (cddr inst) (list bp)) (set-bp (cdr insts) (- i 1)))))) (define (search-label insts) (if (null? insts) (error "Label not found -- BREAKPOINT" label n) (let ((inst (car insts))) (if (eq? (caddr inst) label) (set-bp insts n) (search-label (cdr insts)))))) (search-label insts)) (define (set-breakpoint-to-insts insts label n) (write-breakpoint-to-insts insts label n (cons label n))) (define (reset-breakpoint-to-insts insts label n) (write-breakpoint-to-insts insts label n #f))
- 次にinstのコンストラクタとアクセサを4要素対応に書き換え
- make-new-machineにブレークポイントの追加機能とブレークポイントがあったら停止する処理を追加。とりあえずブレークポイントで止まるところまで確認してタイムアップ
【追記】
よく見ると
(set-cdr! (cddr inst) (list bp))
とかむごいな。
(set-car! (cdddr inst) bp)
だろJK。というか、あとでちゃんとinstに対するセッターを定義しました
第184回 素人くさいSICP読書会(at 三田某所)
- 会場提供ありがとうございました
- 電気アンカをつけっぱなしで寝ると体に悪いという話
- 内部関数の名前について
- Common Lispでは内部defineはあまり使わないらしい。名前空間はパッケージ単位で考えるとのこと。Schemeでは一番外側のdefineがパッケージの役割を果たしてる感じか
これまでに観測されたidの変種
- yadokarielectric
- yadokarielectri
- y14c
- y13i
- yad-EL
- yad_el
- yado-el
- yadokariさん
- ヤドカリデンキさん
- ヤドカリさん
- ヤドカリの人
- ヤドさん
変異の激しさがRNAウイルス並ですね
どれが正解というのは別にないです
Gaucheの入出力の順番について
(display "please input: ") (let ((m (read))) (display "your input is ") (display m))
このようなコードがあった場合、以下のような順番の入出力になるように見えますし、実際に多くのScheme処理系ではこのような実行結果になります。
please input: hoge your input is hoge
ところがGaucheでは以下のような順番になります。最初の入力プロンプトが表示されず、入力後に入力プロンプトと結果のメッセージがまとめて出力されます。
hoge please input: your input is hoge
恥ずかしながら、この問題にずっと悩まされてきました。例えば、FLTVの発表でのGaucheによるデモでは、メッセージの表示の順番がおかしいままデモしたりしていました。
でも、これが不具合ならGaucheが実用的なプログラムで使われるわけはないし、単なる解釈の問題だという話を読んだ記憶もうっすらとあったり。そこで、Schemeコードバトンを機会にがんばってググってみました。
で、見つけたのがこれ↓
http://www.shido.info/gb/guestbook.php?id=1823
バッファリングの問題なんですね。これを防ぐには出力バッファの内容を強制出力するためにGaucheが用意しているflushを使えばOK。つまり、上のプログラムはこのように書き換えれば意図通りに動きます。
(display "please input: ") (flush) (let ((m (read))) (display "your input is ") (display m))
おそらくGaucheを使っている人には常識なんだろうなーと思いつつ、同じ問題で悩んでいる人向けに書いておきます。