:settable slots
<-Previous | ^UP^ | Next->
In the Getting Started with GendL tutorial, we identified on of the biggest differences between GendL and other programming languages was that slot evaluation was always demand driven and the inbuilt dependency tracker will always ensure slot values are current whenever any input changes. This removes a big burdon from the developer and also ensures run times are fast, as we are never calculating any values we don't need to use.
However, there may be times when we need to make programatic changes to values an over-ride this default behaviour. To do this, we identify either slots as :settable and then we use the set-slot! function to programaically alter the value of the selected slot.
When we make a change to a slot value by programatically setting it, the dependency tracker is aware of this and any changes which would ordinarily cause the value to be updated are suspended. If we want to reverse this behaviour (back to default) we can use either of the restore-slot-default! or restore-slot-defaults! functions
As with a lot of different techniques, programatically altering slot values and over-riding the default behaviour has its place and is a useful additoon to the tools and techniques available to the programmer. However, we need to be aware that at the point we do this, and until we revert to default behaviour, it becomes to responsibility of the developer to manage dependencies. For this reason it is recommended to use this technique sparingly and only when a solution using the default behaviour will not give the desired results
Consider the following code
(define-object settable-slots (base-object):computed-slots((speed 25 :settable)(time 15 :settable)(distance (* (the speed) (the time)) :settable)):functions((set-speed! (&key (value 20)) (the (set-slot! :speed value)))(set-time! (&key (value 10)) (the (set-slot! :time value)))(set-distance! () (the (set-slot! :distance 100)))(reset-distance! () (the (restore-slot-default! :distance)))(reset-all! () (the (restore-slot-defaults! (list :speed :time :distance))))))
3 :computed slots, speed, time and distance have been tagged as :settable. 5 functions have been defined, 3 which set new values (using set-slot!) for the respective slots and 2 which will restore default values and behaviours (using :restore-slot-default! and :restore-slot-defaults!). If we make the object and evaluate distance we get the following
GDL-USER> (make-self 'settable-slots)
#<SETTABLE-SLOTS #x2104DC5DFD>GDL-USER> (the distance)
375
- The value has changed
- But the underlying calculation is being performed as specified
GDL-USER> (the set-speed!)
NILGDL-USER> (the distance)
300
GDL-USER> (the set-time!)
NILGDL-USER> (the distance)
200
GDL-USER> (the set-distance!)
NILGDL-USER> (the distance)
100GDL-USER> (the (set-speed! :value 30))
NILGDL-USER> (the distance)
100
GDL-USER> (the reset-distance!)
:DISTANCEGDL-USER> (the distance)
300
GDL-USER> (the reset-all!)
(:SPEED :TIME :DISTANCE)GDL-USER> (the speed)
25GDL-USER> (the time)
15GDL-USER> (the distance)
375
Resources
settable-slots.lisp |