Sunday, May 4, 2014

Towards a Multiple Value SETF in ECL

Today, I've started working on a fork of McCLIM, for adding support for ECL in McCLIM --  nothing too ostentatious, perhaps simply towards implementing CLIM on thin client architectures such as BeagleBoard Black (BBB) and Raspberry Pi (RPi) with the respective TFT display implementations. (Those two platforms, BBB and RPi, those use ARM MCUs. So does my Samsung Chromebook)

As ever, it's proving to be an invaluable learning experience. This evening, in particular, I've been studying the specifications about SETF forms for ANSI CL, and moreso the implementation of the same, in ECL. I've discovered that in ECL 11.1.1 -- broadly -- a multiple value SETF implementation is possible via DEFINE-SETF-EXPANDER, such that a message in the c.l..l newsgroup had once denoted.

The following form may serve to demonstrate something towards how a multiple value SETF may be implemented, in ECL 11.1.1
(in-package #:cl-user)

(defun foo* (x)
  (values (1+ x)
   (1- x)))

;; (foo* 5)

(define-setf-expander foo*  (x &environment env)
  (multiple-value-bind (dx vx nvx sx gx)
      (get-setf-expansion x env)
    (let ((misc-x (gensym "X-"))
          (misc-y (gensym "Y-")))
      (values
       (list misc-x misc-y)
       (list x)
       (list misc-x misc-y)
       ;;  ^ KEY. The third return value is where
       ;;   to specify the multiple value bindings
       ;;   for a multiple-value setf in ECL 11.1.1.
       ;;
       ;; Those bindings may then be utilized in the
       ;; Lisp form specified in the fourth retv :
       `(progn (setf ,gx (1+ ,misc-x))
               (values ,gx ,misc-x ,misc-y))
       `(foo* ,gx)))))


(let ((a 1) (b 2) (c 3))
  (get-setf-expansion
   '(foo* a)))


(let ((a 1) (b 2) (c 3))
  (setf (foo* a) (values b c))
  #+NIL a)
=> 3, 2, 3

Towards implementing multiple-value-setf in McCLIM + ECL, it seems that the main "Work area," for that, is in the  McCLIM source file, `setf-star.lisp`, namely in regards to the implementation of the CLIM specification's defgeneric*  and defmethod* macros. Those macros are then used in the McCLIM source file, `region.lisp`

Certainly, such an application of the third return value for DEFINE-SETF-EXPANDER, it would serve to sort of obviate the application of the setf-expander's lambda list -- perhaps, it introducing, in effect, another variable binding, within the closure of the setf expander, such that the variable to which the binding is made would not be indicated in the explicit lambda list for the setf expander.

Though not explicitly prevented in ANSI CL (as per the CLHS), it is neither  explicitly supported nor specified by the same. Inasmuch, that methodology may or may not be applicable in every ANSI CL implementation, and might not be consistently applicable, in any singular ANSI CL implementation.

As towards the CLIM + ECL regards: "More to follow," perhaps, after a pause -- as towards a "Second wind" -- so to speak -- and then implementing CLIM:DEFGENERIC* and CLIM:DEFMETHOD* in ECL, onto McCLIM. Then perhaps, towards developing some regression tests for the same implementation -- there's an "RT" in a CXML+Contribs toolchain, at that. In a "Blue sky" timeline, perhaps something towards defining a CLIM graft for a direct TFT display (not using X.org or framebuffers, though of course using an interface in the Linux kernel) on the single board computer platform, BeagleBone Black, ostensibly in ECL.