24 Dec 2014, 12:03

プロクラミングパラダイムの意義と 2014 年のプログラミング言語の勉強まとめ

はじめに

edX で プログラミングパラダイムの講義を受けたのでその記録.

実は, この講座は受講が今回で 2 回目だ.前回受けたときの記録は以下.

なぜ 2 回も受けた?

理由は以下だ, 前回の講座で,

  • 単位を落とした…
  • 内容があまりにも素晴らしかった
  • 内容の理解をもっと深めたかった.

内容

内容は, 前回とまったく同じだった. スライドも動画も, そして問題も.

前回は 12week 連続で講義があったのに対して, 今回は 6week x 2 というように 2 つの講座に分かれていた.

あらためてパラダイムの整理

以下のようなパラダイムとコンセプトを順に説明していく.

Paradigms Concepts Features


Functional Programming Functions and recursion Hihger-order programming Single-assigned variables Object-Oriented Programming + cell Data Abstraction Polimorphism Inheritance Deterministic Dataflow Programming + thread No race conditions Concurrent transparency Streams and agents Multiagent Dataflow Programming + port Deterministic dataflow Nondeterminism where needed Active Object Programming + local cell Object-oriented programming Multi-agent dataflow

パラダイムを身につけることでどんな言語にも対応できる

この一年での言語の勉強記録

この 1 年で, たくさんの言語に触れた.

  • VBA (1 月)
  • Oz (3-4 月)
  • Scala (5 -6 月)
  • x86-x64 Assembly (7-8 月)
  • Python (9-10 月)
  • Haskell (11,12 月)
  • R (12 月)

2 ヶ月に 1 回は, 新しい言語に挑戦していた気がする.

また, 仕事で Ruby と Java をつかうようになって, オブジェクト指向言語を 利用することに対して抵抗がなくなった.

2 年前は C 言語しかできなかった

思い返せば, 2 年前は C 言語ただ一つしか使いこなすことができなかった.

このブログを始めたのが 2 年半前くらい. なんとなく, このままではダメだと思っていた.

去年はオブジェクト指向言語に触れようと思い, C++ と Ruby を独学で学んだ.

今年は関数型言語に触れようと思い, Scala や Haskell に触れた.

今では, 2 年前に感じていたような, 単一言語しかしらない劣等感がなくなっていた.

プログラミングを極める最良の方法とは

一つ一つ, 新しい言語に触れる度に, 理解するまでの時間が短くなっていくことを感じた. 言語のもつコンセプトの差異や共通点が見えてくるのが楽しい.

そして, そういう言語の妙を味わうための審美眼は, 間違いなくこの講座を受けることによって得たものだった.

プログラミング言語のコンセプトやパラダイムを身につけることが, 数多くの言語を身につけたり, 言語の本質を理解するための 効率のよい方法だということを, たくさんの言語に触れることで実感した.

この 1 年の最大の出会いは, CTMCP 本 (ガウディ本) に出会ったことだった.

これからどうするか?

CTMCP 本はいったん寝かせる

さらにプログラミングのコンセプトの理解を深めていきたい.

CTMCP 本を 2 回繰りかえして読んだのだが, まだまだ理解したとはいえない. 後半の方は読んでもいない.

ただ, edX があったからこそ読み進めることができたけれども, 一人じゃなんだかこの先を読むにも心が折れて挫折しそうだ.

この本は, この先も何度も何度も読み返していくことになるだろう. なので, いったん読むのを止めて, 別の本を読んでみようと思う.

最近発売された軽めの本

最近, コーディングを支える技術という本の電子書籍版 が出たのでこれを読んでみる.

電子書籍版は技術評論社の HP から.

目次を読む限り, 内容的にも重量的にも軽そうだ.

ガウディ本のライバル魔術師本

この CTMCP 本の前に出版された, 似たようなコンセプトでかかれた本がある.

通称, SICP 本, 魔術資本.これを来年読んでみる.

この本を扱った edX の講座と MIT のオンライン講義を見つけた. この講座のどちらかをベースにしつつ, 読んでみるつもりだ.

UC Berkeley: CS 61AS Structure and Interpretation of Computer Programs :SICP:

MIT courseware: Structure and Interpretation of Computer Programs

14 Dec 2014, 08:51

データフロー変数 (Oz) で実現する Producer-Consumer Pattern

はじめに

以下の記事の続編です.

前回は, Java の 共有メモリモデルを利用して Producer-Consumer Pattern を実装した.

今回は, Oz のもつ決定性データフローモデルを利用して実装してみる.

決定性データフローモデル

データフロー変数をもつモデル.

データフロー変数

<div class="outline-text-3" id="text-unnumbered-3">
  <p>
    変数に値が束縛されるまでプログラムの実行を待ち合わせるような宣言的変数.
  </p>

  <p>
    あるスレッドがデータフロー変数を利用しようとしたとき, その変数に値が束縛されていない場合は, 別のスレッドが束縛するまで待ち合わせを行う.
  </p>

  <p>
    束縛されたときの実行を データフロー実行 という.
  </p>
</div>

実行例

Java

<div class="outline-text-3" id="text-unnumbered-5">
  <p>
    まずは, Java でのサンプル. 平行性を実現するためには, キューを共有する.
  </p>

  <p>
    結構コードがながくなってしまった&#x2026;
  </p>

  <p>
    [sourcecode language=&#8221;java&#8221; title=&#8221;&#8221;]<br /> import java.util.concurrent.LinkedBlockingQueue;<br /> import java.util.concurrent.BlockingQueue;<br /> import java.util.LinkedList;<br /> import java.util.List;
  </p>

  <p>
    public class ProducerConsumerPattern {<br /> public static void main (String args[]) {<br /> BlockingQueue<List<Integer>> queue = new LinkedBlockingQueue<List<Integer>>();
  </p>

  <p>
    Producer producer = new Producer (queue, 10);<br /> Consumer consumer = new Consumer (queue);
  </p>

  <p>
    producer.start ();<br /> consumer.start ();<br /> }<br /> }
  </p>

  <p>
    class Producer extends Thread {<br /> BlockingQueue<List<Integer>> queue;<br /> List<Integer> list;<br /> int limit;
  </p>

  <p>
    public Producer (BlockingQueue<List<Integer>> queue, int limit) {<br /> this.queue = queue;<br /> this.limit = limit;<br /> list = new LinkedList<Integer>();<br /> }
  </p>

  <p>
    public void run () {<br /> try {<br /> for (int i=1; i <= limit; i++) {<br /> System.out.println (i);<br /> sleep (1000);<br /> list.add (i);<br /> }<br /> queue.put (list);<br /> }<br /> catch (Exception e) {}<br /> }<br /> }
  </p>

  <p>
    class Consumer extends Thread {<br /> BlockingQueue<List<Integer>> queue;<br /> Integer sum;<br /> public Consumer (BlockingQueue<List<Integer>> queue) {<br /> this.queue = queue;<br /> this.sum = 0;<br /> }
  </p>

  <p>
    public void run () {<br /> try {<br /> List<Integer> list = queue.take ();<br /> for (Integer i: list) {<br /> sum += i;<br /> }<br /> System.out.println (sum);<br /> }<br /> catch (Exception e) {}<br /> }<br /> }<br /> [/sourcecode]
  </p>
</div>

Oz

<div class="outline-text-3" id="text-unnumbered-6">
  <p>
    つづいて, データフロー変数をサポートする Oz.
  </p>

  <p>
    とてもシンプルにかつ安全に書くことができる. データフロー変数の未来を感じることができるコード.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221;]<br /> declare<br /> fun {Producer N}<br /> fun {Producer1 X N}<br /> {Delay 1000}<br /> if X < N+1 then<br /> {Show X}<br /> X|{Producer1 X+1 N}<br /> else nil<br /> end<br /> end<br /> in<br /> {Producer1 1 N}<br /> end
  </p>

  <p>
    fun {Consumer S}<br /> fun {Sum S Acc}<br /> case S of X|Xr then {Sum Xr Acc+X}<br /> [] nil then Acc<br /> end<br /> end<br /> in<br /> {Sum S 0}<br /> end
  </p>

  <p>
    local Xs Ys S in<br /> thread Xs = {Producer 10} end<br /> thread<br /> Ys = {Consumer Xs}<br /> {Show Ys}<br /> end<br /> end<br /> [/sourcecode]
  </p>
</div>

23 Nov 2014, 13:14

データ抽象と抽象データ型 (ADT) について調べたまとめ (Java)

はじめに

仕事の開発プロジェクトのメンバ (正確にはメンバではなくてアドバイザー) でこわーい人がいて,毎日のようにおびやかされてビクビクしている.

その人が書いたクラス図の意味がわからなかったから質問しにいったときのお話.

やりとり

<div class="outline-text-3" id="text-unnumbered-2">
  <p>
    (hoge さん) 「このクラスがなにを現しているか, そもそもわかってる?? 」
  </p>

  <p>
    (Me) (わかっていないから質問をしにいった)
  </p>

  <p>
    (Me) 「データとそれを扱うための便利な操作をまとめたクラスですか? 」
  </p>

  <p>
    (hoge さん) 「それって, ただオブジェクト指向の一般論を言っているだけでは? 」
  </p>

  <p>
    (Me) (にが笑い&#x2026;)
  </p>

  <p>
    (hoge さん) 「わかってないのに, わかったふりをしているよね? 」
  </p>

  <p>
    (hoge さん) 「便利な操作ってなに? そんなことだから, いつも考え方が手続的なんだ!! 」
  </p>

  <p>
    そんなこんなで, 今回もひどい目にあい, あたくしは週末に心療内科にいって坑うつ剤を増量してもらうはめになった.
  </p>
</div>

Answer

<div class="outline-text-3" id="text-unnumbered-3">
  <p>
    その人のいうことには,
  </p>

  <p>
    「このクラスは, アプリケーションのためのデータ型. アプリケーションのベースになるもの. Integer 型や String 型と同じようなもの. 」
  </p>

  <p>
    「アプリケーションを設計するということは, まずそのアプリケーションで利用される データ型を定義するということからはじめる.」
  </p>

  <p>
    「その後, 自分が定義したデータ型を操作するインタプリタを設計する. Java をつかっているものの, Java はそれらのデータ型のインタプリタでしかない」
  </p>

  <p>
    だそうだ.というわけで, 今回は抽象データ型について調べてみた.
  </p>

  <p>
    情報元は, Wikipedia だったり, CPMCP 本だったり.
  </p>
</div>

データ型とは

互いに関係する値の集合.

大きく, 2 種類に分けられる.

基本型は, よく知っているので, 今回は抽象データ型に注目.

抽象データ型とは

  • 自身で定義した型.
  • 状態を持たない.
  • Abstract Data Type (ADT) という.
  • 値の集合とそれらに関係する操作の集合, それぞれ別々に保持しているもの. (別々というところが Object の違い)

ラッパー

<div class="outline-text-4" id="text-unnumbered-6">
  <p>
    値の集合に直接アクセスさせないための操作.(CPMCP p210)
  </p>

  <ul class="org-ul">
    <li>
      値を安全に保持するためには, 鍵 (key) を利用して (包む) 操作を追加する.
    </li>
  </ul>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> Key={NewName}<br /> SS={Chunk.new w (Key:S)}<br /> [/sourcecode]
  </p>

  <p>
    包み, ほどきを行うデータ抽象をラッパーと定義する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> proc {NewWrapper ?Wrap ?Unwrap}<br /> Key={NewName} in<br /> fun {Wrap X}<br /> {Chunk.new w{Key:X}}<br /> end<br /> fun {Unwrap X}<br /> try W.Key catch _ then raise error (unwrap (W)) end end<br /> end<br /> end<br /> [/sourcecode]
  </p>

  <p>
    以下のように, Wrap, Unwrap する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> S={a b c}<br /> SS={Wrap S}<br /> S={Unwrap SS}<br /> [/sourcecode]
  </p>
</div>

データ抽象 (Data Abstraction)

データを抽象的に使う, 使い方.実装にとらわれずにデータを使うこと. インタフェースと呼ばれる規則にしたがって使用される具体化の集合.

データ抽象を型 (Type) といって済ますこともある. 抽象データ型 (ADT) は, 特殊なデータ抽象. 値の集合と, それに関する操作の集合.(CPMCP p431)

Data Abstruction は 操作が値にバインディングされているかいなかで, 2 つの種類に分けられる.

  • Abstruct Data Type (ADT) 値と操作をベツベツに保持する
  • Object 値と操作を一緒に保持する.

オブジェクト

<div class="outline-text-3" id="text-unnumbered-8">
  <p>
    値と操作をひとつのまとまりとしたもの.
  </p>

  <p>
    現在オブジェクト指向言語と呼ばれているものは,実際には,
  </p>

  <ul class="org-ul">
    <li>
      Abstruct Data Type (Java Integer 型)
    </li>
    <li>
      オブジェクト (Java Object 型)
    </li>
  </ul>

  <p>
    の 2 つを合わせもっている.
  </p>

  <p>
    その意味で, オブジェクト指向言語と言うよりは, 抽象データ言語というほうが正しい.
  </p>
</div>

クラス

<div class="outline-text-3" id="text-unnumbered-9">
  <p>
    抽象データからなるデータ構造.
  </p>

  <p>
    属性とメソッドはレコードデータ構造によって管理されているだけ.
  </p>

  <p>
    Class とは, Pair ( attrs[属性の集合] : methods[メソッドの集合]) )
  </p>

  <p>
    Class の 生成 (new) メソッドで オブジェクトが生成される.(インスタンス化)
  </p>

  <p>
    Class という概念によって, オブジェクトの&#8221;宣言&#8221;と&#8221;生成 (new)&#8221;を分離する.
  </p>
</div>

実例

オブジェクト指向における, メソッドの動的ディスパッチを自力で実装. なんてめんどいんだ.

本来ならば, Operation クラスで保持するものは, String ではなくてクロージャだけど, Java7 では実現できない.

hoge さんから提示されたクラス図も, 大体はこんな感じで, HashMap に値やらメソッドやらを保持していた.

[sourcecode language=”java” title=””]
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ADTSample {
public static void main (String[] args) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException {
ObjectSample obj = new ObjectSample ();
System.out.println (obj.getAttr1 () + " " + obj.getAttr2 ());

ObjectSample2 obj2 = new ObjectSample2 ();
System.out.println (obj2.call (Key.NUM) + " " + obj2.call (Key.STRING));
}
}

class ObjectSample {
int attr1 = 3;
String attr2 = "hello";

public int getAttr1 () {
return attr1;
}

public String getAttr2 () {
return attr2;
}

public void setAttr2 (String attr2) {
this.attr2 = attr2;
}
}

enum Type {
INT,
STRING
}

enum Key {
NUM,
STRING
}

class ObjectSample2 {
private Map attrs = new HashMap();
private Map methods = new HashMap();

public ObjectSample2 () {
// Attributes
attrs.put (Key.NUM, new Attribute (3, Type.INT));
attrs.put (Key.STRING, new Attribute ("hello", Type.STRING));

// Operations
methods.put (Key.NUM, new Operation ("getAttr1"));
methods.put (Key.STRING, new Operation ("getAttr2"));
}

public Object call (Key key) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException {

Operation ope = methods.get (key);
Method method = this.getClass ().getMethod (ope.method, Key.class);
return method.invoke (this, key);
}

public Object getAttr1 (Key key) {
Attribute attr = attrs.get (key);
return attr.value;
}

public Object getAttr2 (Key key) {
Attribute attr = attrs.get (key);
return attr.value;
}
}

class Attribute {
Object value;
Type type;

public Attribute (Object value, Type type) {
this.value = value;
this.type = type;
}
}

class Operation {
String method;

public Operation (String method) {
this.method = method;
}
}
[/sourcecode]

20 Apr 2014, 02:44

Mozartをemacsclientから起動する方法のメモ

以前、Oz用のプログラミング環境Mozartをインストールした。

この方法だと、mozart専用のEmacsがたちあがる。

できれば、今動いているemacs-serverにemacsclientでアクセスしたい。

Elispの取得

Oz用のElispを取得して、ロードパスの通った場所におく。

#!/bin/sh
wget https://raw.githubusercontent.com/mozart/mozart2/master/opi/emacs/oz.el
wget https://raw.githubusercontent.com/mozart/mozart2/master/opi/emacs/oz-extra.el
wget https://raw.githubusercontent.com/mozart/mozart2/master/opi/emacs/oz-server.el
wget https://raw.githubusercontent.com/mozart/mozart2/master/opi/emacs/mozart.el

詳細なドキュメントはここ

Elipsと環境変数の設定

設定ファイルに以下を書く。

OZHOMEに mozartをインストールしたパスを設定。PATHにその配下のbinを指定。

(or (getenv "OZHOME")
    (setenv "OZHOME" 
            "/mnt/win/opt/mozart"))   ; or wherever Mozart is installed
(setenv "PATH" (concat (getenv "OZHOME") "/bin:" (getenv "PATH")))

(add-to-list 'auto-mode-alist '("\\.oz\\'" . oz-mode))
(add-to-list 'auto-mode-alist '("\\.ozg\\'" . oz-gump-mode))
(autoload 'run-oz "oz" "" t)
(autoload 'oz-mode "oz" "" t)
(autoload 'oz-gump-mode "oz" "" t)
(autoload 'oz-new-buffer "oz" "" t)

これでもよい。

export OZHOME=/mnt/win/opt/mozart
export PATH=/opt/mozart/bin:$PATH

これで、あとは.oz拡張子がついたファイルを開けば ozモードで 編集できる。ばっちし。

Environment

<div class="outline-text-3" id="text-2-1">
  <ul class="org-ul">
    <li>
      Mint Linux 16
    </li>
    <li>
      Emacs 24.3.1
    </li>
  </ul>
</div></p>

Special Thanks

<div class="outline-text-3" id="text-2-2">
  <ul class="org-ul">
    <li>
      <a href="http://dream.inf.ed.ac.uk/computing/installed/mozart/doc/opi/node2.html">2 Invoking the OPI</a>
    </li>
    <li>
      <a href="http://www.eecs.ucf.edu/~leavens/ComS541Fall06/running_oz.shtml#">Running Oz</a>
    </li>
  </ul>
</div></p>

22 Feb 2014, 01:00

マルチパラダイム言語Ozの開発環境MozartをインストールしてHelloWorldするまで

edXでコンピュータプログラミングのパラダイムについての学習を始めた。

[//www.youtube.com/embed/D1q2dCNGDOE]

学習のための言語として、コースではOzというマルチパラダイムな言語を利用する。

この記事では、Ozとその開発環境であるMozartの導入をメモする。

インストール

事前準備

<div id="text-1-1" class="outline-text-3">
  <p>
    まずは、以下をインストール
  </p>

  <ul class="org-ul">
    <li>
      tk-dev
    </li>
    <li>
      emacs
    </li>
  </ul>

  <pre><code>sudo apt-get install tk-dev

>sudo apt-get install emacs

Mozart2をインストール

<div id="text-1-2" class="outline-text-3">
  <p>
    以下からバイナリを落とす。
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://sourceforge.net/projects/mozart-oz/files/v2.0.0-alpha.0/">Mozart-Oz Programming System &#8211; Browse /v2.0.0-alpha.0 at SourceForge.net</a>
    </li>
  </ul>

  <p>
    githubに開発版もあるのでlinkをはっておく。
  </p>

  <ul class="org-ul">
    <li>
      <a href="https://github.com/mozart/mozart2#downloads">https://github.com/mozart/mozart2#downloads</a>
    </li>
  </ul>

  <p>
    解凍して、適当なところに配置。その後binディレクトリにパスを通す。ここでは、.zshenvに以下を追記
  </p>

  <pre><code>export PATH=/opt/mozart/bin:$PATH

  <p>
    端末から$oz と起動してemacsが起動すればOK. $oz -nwで端末から開ける。
  </p>
</div>

Hello World

おきまりのHello Worldはこんな感じ。

{Browse 'Hello World'}

この行を選択して、M-x oz-feed-regionを実行すると、ブラウザが立ち上がり、Hello Worldが表示される。

oz-mode

Emacs環境のカスタマイズ。以下のようなショートカットが使えるらしいが、自分の環境ではうごかない。

C-. C-lFeed current line現在行をフィードする
C-. C-rFeed selected region選択範囲をフィードする
C-. C-bFeed whole buffer全バッファをフィードする

ということで、別のショートカットを割り当てた。

(add-hook 'oz-mode-hook
  (lambda () 
    (define-key oz-mode-map "\C-c\C-b" 'oz-feed-buffer)
    (define-key oz-mode-map "\C-c\C-l" 'oz-feed-line))
    (define-key oz-mode-map "\C-c\C-r" 'oz-feed-region)))

すべてのショートカットは以下。

環境変数OZEMACSに利用するemacsが設定できるらしい。 しかし、emacsclientは設定できなかった。

ドキュメント

日本語の情報がすくないけど、以下のベージが参考になる。

参考書はこれしか知らない。