ASM development log 4: Tiny MOP

Posted on by Idorobots

Finals are comming, so I might as well hack around a bit with ASM...

It's been a while since the last status update and I hate to admit it, but not much has changed in ASM repo. I was messing around with combinators in an attempt to simplify ASM' environments, and I was experimenting with new immutability semantics, since at the moment it's pretty much a one big copy-vs-alias mess. There are still a bunch of unresolved issues here and there concerning efficiency mainly, but if ASM is to be relevant in 100 years of time I'd much rather sacrifice efficiency for simpler semantics and expressive power.

Lastly, I was thinking about a way of exposing as much of ASM' semantics as possible and allowing their run-time overriding, using a Metaobject protocol:

Tiny... MOP...

(import 'samples.tinyclos)

(defmethod apply ((v Vector) n)
  (write "Applying a vector to something? Are you " n "?"))

(apply '[1 2 3 4] '(nuts))

TinyCLOS

TinyCLOS is an object system that includes a metaobject protocol developed by Gregor Kiczales at Xerox for the Scheme programming language. It's relatively simple yet immensely powerful and porting it to ASM was both great fun and a nice test for the capabilities of the language. Running rather slowly as ASM's testing interpreter is very cons-and-copy-happy it continues to amuse me even with its basic features such as generic methods with multiple dispatch:

(import 'samples.tinyclos)

(defclass Point (Object)
  'x 'y)

(defmethod initialize ((p Point) initargs)
  (call-next-method)
  (initialize-slots p initargs))

(defclass Point3D (Point)
  'z)

(defvar p1 (new Point 'x 1 'y 2))
(defvar p2 (new Point 'x 2 'y 3))
(defvar p3 (new Point3D 'x 5 'y 5 'z 5))

(defgeneric distance)
(defmethod distance ((a Point) (b Point))
  (write "Point * Point\n")
  (distance (new Point3D 'x (a 'x) 'y (a 'y) 'z 0)
            (new Point3D 'x (b 'x) 'y (b 'y) 'z 0)))

(defmethod distance ((a Point) (b Point3D))
  (write "Point * Point3D\n")
  (distance b a))

(defmethod distance ((a Point3D) (b Point))
  (write "Point3D * Point\n")
  (distance a (new Point3D 'x (b 'x) 'y (b 'y) 'z 0)))

(defmethod distance ((a Point3D) (b Point3D))
  (write "Point3D * Point3D\n")
  (defvar dx (- (b 'x) (a 'x)))
  (defvar dy (- (b 'y) (a 'y)))
  (defvar dz (- (b 'z) (a 'z)))
  (pow (+ (* dx dx) (* dy dy) (* dz dz) 0.5)))

(distance p1 p2)
(distance p3 p1)
(distance p2 p3)
(distance p3 p3)

Output:

Point * Point
Point3D * Point3D
Point3D * Point
Point3D * Point3D
Point * Point3D
Point3D * Point
Point3D * Point3D
Point3D * Point3D

F(ea|u)ture?

I once were an OOP enthusiast, but grew to hate it for various reasons. Most of all, I fell in love with functional programming and OOP (at least the Java-flavour) suddenly started looking clumsy and awkward. The world wasn't made of objects anymore, it was made of foldr and foldl instead. Now, although I still don't see ASM as an OOP-heavy language, I'm sure it'll make some use of it - for example implementing ranges with all their benefits comes naturally in an OOP-enabled language. Furthermore, to extend ASM's expressiveness beyond what any other language has to offer I will need a meta-language protocol of sorts, perhaps Tiny MOP is a good start towards that... Thing...

2016-02-05: Adjusted some links & tags.