そしてCOBOLerへ…

仕事でCOBOLを扱うことになった。少し勉強中。とりあえずオブジェクト指向してみる。

まず、speakメソッドを有するAnimalインタフェースを定義する。

      *>「Animal」インタフェース
       identification division.
       interface-id. Animal.

       procedure division.
         identification division.
         method-id. speak.
         procedure division.
         end method speak.
       end interface Animal.

で、それを実装するのがDogクラスとDuckクラス。

続きを読む

非決定性 with 例外

『On Lisp』の非決定性が面白い。

(define (two-numbers)
  (list (choose '(0 1 2 3 4 5))
        (choose '(0 1 2 3 4 5))))

(define (parlor-trick sum)
  (let ((nums (two-numbers)))
    (if (= (apply + nums) sum)
        `(the sum of ,@nums)
        (fail))))

> (parlor-trick 7)
(THE SUM OF 2 5)
On Lisp - 非決定性

 choose関数が正しい選択を行うと仮定したコードになっている。カラクリは単純。choose関数に指定された数値分の継続を順番に実行しているだけ。継続の実行をfail関数で行うことでfail関数が呼ばれないパスが求めるべき解になる。
 実は継続を使わなくても例外でできる。というわけで、D言語で実装してみる。

続きを読む

Perlで継続

現在、『On Lisp』が3巡目の終盤に差し掛かっている。でも、いまいち継続を理解できていない。分かり易い解説を見つけたのでPerlに翻訳してみた。(本を読む FizzBuzzとGaucheで学ぶ継続の基礎)

use strict;
use warnings;

sub fizzbuzz {
  my ($next, ($n)) = @_;
  my $answer = $n % 15 == 0 ? "FizzBuzz"
             : $n %  3 == 0 ? "Fizz"
             : $n %  5 == 0 ? "Buzz"
             : $n;

  # $nextを挟んで再帰呼び出し
  $next->(\&fizzbuzz, ($n + 1, $answer));
}

sub continuation {
  my ($next, ($n, $answer)) = @_;

  # 状態を閉じ込めた状態で関数終了
  my $cc = sub {
    my ($fun) = @_;
    $fun->($answer) if (ref $fun eq 'CODE');
    $next->(\&continuation, ($n));
  };
}

# 1〜100のfizzbuzz継続を生成してリストに保存
my @restart = fizzbuzz(\&continuation, (1));
push @restart, $restart[$#restart]->() for 2..100;

# 1〜100のfizzbuzz継続を実行
$restart[$_]->( sub{ print @_, $_ != $#restart ? '|' : '' } ) for 0..$#restart;

100までのFizzBuzzが表示される。

続きを読む

副作用関数のユニットテスト

ユニットテストの自動化で困るのが副作用を起こすコード。例えば、ファイルのI/Oを含む関数は自動テスト化に少し悩む。

# hoge.pl
use strict;
use warnings;

package HOGE;
use IO::File;

main(@ARGV) if ($0 eq __FILE__);

# テストしたい関数
sub main {
  my (@args) = @_;
  return 1 unless (@args >= 2);
  return 2 unless defined( my $io = IO::File->new($args[0], 'w') );
  unless ( defined $io->print($args[1]. "\n") ) {
    $io->close;
    return 3
  };
  return 4 unless defined $io->close;
  return 0;
}
1;

この場合、テストドライバから"use lib"でモジュール参照先を変更してIO::Fileを強制的にテストスタブにしてやれば良い。

続きを読む

Perlで遅延評価

遅延評価とは、HaskellD言語なんかにある「アレ」のことだ。

遅延評価(ちえんひょうか、lazy evaluation、delayed evaluation)とは、計算機科学におけるプログラムの評価手法の一つ。主に関数型言語で使用される。対義語は先行評価(eager evaluation、strict evaluation)。

評価しなければならない値が存在するとき、実際の計算を値が必要になるまで行わないことをいう。評価法が指示されているが実際の計算が行われていない中間状態の時それをプロミス (promise) や、計算の実体をさしてサンク (thunk) といい、プロミスを強制(force)することで値が計算される。一旦計算された値はキャッシュをすることが可能であり、遅延プロミスは最大で一度しか計算されないようにすることができる。ただし、Haskellの実装によっては、何度でも同じ計算を行う。

http://ja.wikipedia.org/wiki/%E9%81%85%E5%BB%B6%E8%A9%95%E4%BE%A1

要するに式の評価を結果が必要になる時点まで遅らせるテクニックである。
Perlでやってみた。定番のFizzBuzz

続きを読む

Lispお勉強中

 心に余裕が出てきたこともあってLispを再学習中。今は『実践Common Lispを読んでいる。やっと第12章が終わった。
 思い返すと腰を落ち着けてプログラミング言語の勉強をやってない。何とか使いこなしているのはC言語とPerlくらい。どちらも仕事で使っているおかげだ。他は書籍を斜め読みしてわかった気になっているだけ。実践が足りない。広く浅くは土地勘を養うためも重要だ。でも身につけるには狭く深く追求することが必要になる。

 興味がある言語はたくさんある。手始めにLispをマスターしたい。Lispといえばマクロ。マクロによる抽象化を習得できたらプログラミングの幅が広がると期待している。

 どうやって勉強しようか?まずは書籍を1冊に絞って繰り返し読む。そして、何か実装してみる。後は、ひたすらソースを読み書きする。

 余裕が大事と感じる今日この頃。今だから言えるけど、精神を壊すまで働くのはNG。人生は1度しかない。自分を大事にしたほうが良い。一度ダウンすると結構長引くし医療費もかさむ。

 ある程度のゆとりがないと生産性はあがらない。会社的にもマイナスになる。当たり前だと思うけど当たり前じゃない現実。

 愚痴ばかり・・・