reify

The reify macro lets you create an anonymous instance of a datatype that implements either a protocol or an interface. Note that you get access by closure, not by declaration. This is because there are no declared members.

 (reify & opts+specs)

reify, like deftype and defrecord, takes the name of one or more protocols, or interfaces, and a series of method bodies. Unlike deftype and defrecord, it doesn’t take a name or a vector of fields; datatype instances produced with reify don’t have explicit fields, relying instead on closures.

Let’s compose some John Cage--style[38] aleatoric music[39] or, better yet, create an aleatoric music generator. We’ll use reify to create an instance of a MidiNote that will play a different random note each time its play method is called.

 (import '[examples.datatypes.midi MidiNote])
 (​let​ [min-duration 250
  min-velocity 64
  rand-note (reify
  MidiNote
  (to-msec [this tempo] (+ (rand-int 1000) min-duration))
  (key-number [this] (rand-int 100))
  (play [this tempo midi-channel]
  (​let​ [velocity (+ (rand-int 100) min-velocity)]
  (.noteOn midi-channel (key-number this) velocity)
  (Thread/sleep (to-msec this tempo)))))]
  (perform (repeat 15 rand-note)))

The first thing we need to do is import (not use or require) our MidiNote protocol from the examples.midi namespace. Next we bind two values, min-duration and min-velocity, that we will use in the MidiNote method implementations. Then we use reify to create an instance of an anonymous type, which implements the MidiNote protocol, that will select a random note, duration, and velocity each time its play method is called. Finally, we use the repeat function to create a sequence of 15 notes, consisting of a single instance of rand-note, and perform it. Voila, you now have a virtual John Cage!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.250.11