Posted 2014-09-28 15:00:00 GMT
(LISP Library 365参加エントリ)
LISP Library 365 の272日目です。
mcsは、Juergen Kopp氏が中心となって開発していたCLOSやTELOSの流れを汲むMOPを具備したオブジェクト指向システムです。
かつてドイツにあった、GMD(Gesellschaft für Mathematik und Datenverarbeitung mbH)で開発されていたようです。
配布サイト | Package: lang/lisp/oop/non_clos/mcs/ |
パッケージ名 | mcs |
Quicklisp | × |
上記の配布サイトからダウンロードしてきて適当にANSI CLで動くようにします。
もしくは、GitHub上にSBCLで動くようにしたものがありますので良かったらどうぞ。
Quicklispのlocal-projects以下に配置すれば
(ql:quickload :mcs)
できるかと思います。
mcsは以前も紹介したことがありましたが、主にMOP的なところを紹介してみていました。
今回は、毎度お馴染のBankAccountです。
(defpackage :mcs.demo
(:use :mcs))
(cl:in-package :mcs.demo)
(defabstract bank-account ()
((dollars :initform 0 :accessor dollars :initarg dollars)))
(defclass normal-bank-account (bank-account) ())
(defmethod deposit ((a normal-bank-account) (n number))
(incf (dollars a) n))
(defmethod withdraw ((a normal-bank-account) (n number))
(setf (dollars a)
(max 0 (- (dollars a) n))))
(defparameter *my-account* (make-instance 'normal-bank-account 'dollars 200))
(dollars *my-account*)
;=> 200
(deposit *my-account* 50)
;=> 250
(withdraw *my-account* 100)
;=> 150
(withdraw *my-account* 200)
;=> 0
(defclass stock-account (normal-bank-account)
((num-shares :initform 0 :accessor num-shares :initarg num-shares)
(price-per-share :initform 30 :accessor price-per-share :initarg price-per-share)))
(defmethod dollars ((a stock-account))
(* (num-shares a) (price-per-share a)))
(defmethod (setf dollars) ((n number) (a stock-account))
(setf (num-shares a) (/ n (price-per-share a)))
(dollars a))
(defparameter *my-stock* (make-instance 'stock-account 'num-shares 10))
(dollars *my-stock*)
;=> 300
(setf (dollars *my-stock*) 600)
;=> 600
(deposit *my-stock* 60)
;=> 660
(num-shares *my-stock*)
;=> 22
(withdraw *my-stock* 120)
;=> 540
(num-shares *my-stock*)
;=> 18
見ての通り、殆どCLOSと変わらないことが分かると思います。
上記のコードで目立った違いといえば、:initargにキーワードが使えないこと位でしょうか。
defabstractは全然必要ないのですが、mcsが標準で備えているのこともあり折角なので使ってみました。他にdefmixin等があります。
今回は、mcsを紹介してみました。
PCL(Portable Common Loops)よりは小さくまとまっているようなのでCLOSがないレガシーなシステムへ載せるものとしては結構良いかなと思ったりします。