Paste number 78132: macrolet confusion

Index of paste annotations: 1 | 2

Paste number 78132: macrolet confusion
Pasted by: rswarbrick
When:1 year, 4 months ago
Share:Tweet this! | http://paste.lisp.org/+1OAC
Channel:#lisp
Paste contents:
Raw Source | XML | Display As
(defun add-row/column (mx i k mult row? width-or-height)
  "Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
  similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
  iterate."
  (declare (optimize (debug 3)
                     (speed 0)
                     (safety 3)))
  (macrolet ((r/c-element (index subindex by-row?)
               (if by-row?
                   `(aref mx ,index ,subindex)
                   `(aref mx ,subindex ,index))))
    (loop
       for j from 0 to (1- width-or-height)
       doing (setf (r/c-element i j row?)
                   (+ (r/c-element i j row?) (* mult (r/c-element k j row?))))))
  (values))

(let ((mat (make-array
            '(4 4)
            :initial-contents '((1 0 0 0) (0 2 5 4) (0 1 5 6) (0 3 1 2)))))
  (add-row/column mat 0 1 1 nil 4)
  mat)

;; I would expect a matrix like '((1 0 0 0) (2 2 5 4) (1 1 5 6) (3 3 1 2)) to
;; be the result of this (add the 1st column to the 0th column). Instead, the
;; code appears to completely ignore ROW? and add by rows.
;;
;; SBCL complains as follows:
;;
;; ; compiling (DEFUN ADD-ROW/COLUMN ...)
;; 
;; ; file: /tmp/file6XuwAV.lisp
;; ; in: DEFUN ADD-ROW/COLUMN
;; ;     (DEFUN MAXIMA::ADD-ROW/COLUMN
;; ;            (MAXIMA::MX MAXIMA::I MAXIMA::K MAXIMA::MULT MAXIMA::ROW?
;; ;             MAXIMA::WIDTH-OR-HEIGHT)
;; ;       "Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
;; ;     similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
;; ;     iterate."
;; ;       (DECLARE (OPTIMIZE (DEBUG 3) (SPEED 0) (SAFETY 3)))
;; ;       (MACROLET ((MAXIMA::R/C-ELEMENT
;; ;                      (MAXIMA::INDEX MAXIMA::SUBINDEX MAXIMA::BY-ROW?)
;; ;                    (IF MAXIMA::BY-ROW? `# `#)))
;; ;         (LOOP MAXIMA::FOR MAXIMA::J MAXIMA::FROM 0 MAXIMA::TO
;; ;               (1- MAXIMA::WIDTH-OR-HEIGHT) MAXIMA::DOING
;; ;               (SETF (MAXIMA::R/C-ELEMENT MAXIMA::I MAXIMA::J MAXIMA::ROW?)
;; ;                       (+ # #))))
;; ;       (VALUES))
;; ; --> PROGN EVAL-WHEN 
;; ; ==>
;; ;   (SB-IMPL::%DEFUN 'MAXIMA::ADD-ROW/COLUMN
;; ;                    (SB-INT:NAMED-LAMBDA MAXIMA::ADD-ROW/COLUMN
;; ;                                         (MAXIMA::MX MAXIMA::I MAXIMA::K
;; ;                                          MAXIMA::MULT MAXIMA::ROW?
;; ;                                          MAXIMA::WIDTH-OR-HEIGHT)
;; ;                                         (DECLARE
;; ;                                          (OPTIMIZE (DEBUG 3) (SPEED 0)
;; ;                                           (SAFETY 3)))
;; ;                                         (BLOCK MAXIMA::ADD-ROW/COLUMN
;; ;                                           (MACROLET (#)
;; ;                                             (LOOP MAXIMA::FOR MAXIMA::J
;; ;                                                   MAXIMA::FROM 0 MAXIMA::TO #
;; ;                                                   MAXIMA::DOING #))
;; ;                                           (VALUES)))
;; ;                    "Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
;; ;   similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
;; ;   iterate."
;; ;                    'NIL (SB-C:SOURCE-LOCATION))
;; ; 
;; ; caught STYLE-WARNING:
;; ;   The variable ROW? is defined but never used.
;; ; 
;; ; compilation unit finished
;; ;   caught 1 STYLE-WARNING condition
;; STYLE-WARNING: redefining ADD-ROW/COLUMN in DEFUN

Annotations for this paste:

Annotation number 1: defining macro
Pasted by: rswarbrick
When:1 year, 4 months ago
Share:Tweet this! | http://paste.lisp.org/+1OAC/1
Paste contents:
Raw Source | Display As
(defmacro define-row/column-adder (row?)
  (flet ((r/c-element (index subindex)
           (if row?
               `(aref mx ,index ,subindex)
               `(aref mx ,subindex ,index))))
    `(defun ,(intern (concatenate 'string "ADD-" (if row? "ROW" "COLUMN")))
         (mx i k mult width-or-height)
       "Set MX(I,) or MX(,I) to be MX(I,)+MULT*MX(K,) or similarly for
  columns. Takes WIDTH-OR-HEIGHT to know over which indices to iterate."
       (loop
          for j from 0 to (1- width-or-height)
          doing (setf ,(r/c-element 'i 'j)
                      (+ ,(r/c-element 'i 'j)
                         (* mult ,(r/c-element 'k 'j)))))
       (values))))

Annotation number 2: the sensible way to do it?
Pasted by: rswarbrick
When:1 year, 4 months ago
Share:Tweet this! | http://paste.lisp.org/+1OAC/2
Paste contents:
Raw Source | Display As
(defun add-row/column (mx i k mult width-or-height row?)
  "Set MX(I,) or MX(,I) to be MX(I,)+MULT*MX(K,) or similarly for
  columns. Takes WIDTH-OR-HEIGHT to know over which indices to iterate."
  (loop
     for j from 0 to (1- width-or-height)
     doing
       (if row?
           (setf (aref mx i j)
                 (+ (aref mx i j) (* mult (aref mx k j))))
           (setf (aref mx j i)
                 (+ (aref mx j i) (* mult (aref mx j k))))))
  (values))

Colorize as:
Show Line Numbers
Index of paste annotations: 1 | 2

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.