Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?
@j_kugiya

ClojureのProtocol

More than 5 years have passed since last update.

Clojureのdefprotocolについて調べてみた。Javaでいうインターフェースのようなものなんだけど、Clojureは動的型の言語なので、インターフェース(のようなもの)があることで、何がよいのか、というのが今回のテーマです。

まずは使ってみるところから。

Protoclの定義

(defprotocol Hoge
  (foo [this])
  (bar [this a b]))

これで、defprotocolを呼び出したネームスペースにfooという関数とbarという関数が定義されます。(ns-internsで確認できます。)

protocolの実装

このプロトコルに対する実装を与えるコードは以下のようになります。

(defrecord Hoge1 []
  Hoge
  (foo [this] "this is Hoge 1")
  (bar [this a b] (str a b)))

(defrecord Hoge2 []
  Hoge
  (foo [this] "this is Hoge 2")
  (bar [this a b] (str b a)))

関数を実行すると以下のようになります。

(foo (Hoge1.))
=> "this is Hoge1"

(foo (Hoge2.))
"this is Hoge2"

(bar (Hoge1.) "a" "b")
=> "ab"

(bar (Hoge2.) "a" "b")
=> "ba"

プロトコルを通じて、fooやbarという同一のネームスペース・名前の関数に多態性(第一引数のインスタンスによって関数の振る舞いが変わる)が与えられたのがわかると思います。

protocolの作成単位

protocolは標準実装を定義することはできないので、一つのプロトコルに沢山の関数を用意すると、レコードを一つ作るたびに実装を行うコードを書かなければいけません。
このため、1つのプロトコルに用意する関数は少なくしたほうが、分かり切った実装を何度も書かなくて済むようになります。

参考文献

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
7
Help us understand the problem. What is going on with this article?