Hi. Need help with creating the ‘for’ macro. It must take a parameter, an initial value, an end value, and a loop step. Macro must return amount of iteration. Various operations should take place inside it. It should be designed without leaks.The preliminary version looks like this:

(defmacro for ((param-name start-value end-value &optional (step1 1)) &body body)
  (let* ((func-name (gensym))
(start (gensym))
(param-name (gensym))
(comparison (if (< step1 0) '< '>))
(end (gensym))
(step (gensym))
(k (gensym)))
'(labels ((,func-name (,param-name ,start ,end ,step ,k)
(let ((new-exprs (progn ,@body))
(newK (+ 1 ,k)))
(if (,comparison ,end ,param-name)
(,func-name (+ ,param-name ,step) ,start ,end ,step newK)
newK))))
(,func-name ,param-name ,start-value ,end-value ,step1 0))))

I understand that it looks terrible. I don’t understand how you can access the parameter without violating the rule about leaks.

  • jacobb11@alien.topB
    link
    fedilink
    English
    arrow-up
    1
    ·
    11 months ago

    Here it is necessary to refer to the modified sh. Therefore, it is passed to the recursive param-name call.

    You can bind a variable outside the function and still refer to it inside the function. Here is an example that does so with “,end”:

    (defmacro for ((param-name start-value end-value &optional (step1 1)) &body body)
      (let* ((func-name (gensym))
             (start (gensym))
             (param-name (gensym))
             (comparison (if (< step1 0) '< '>))
             (end (gensym))
             (step (gensym))
             (k (gensym)))
        `(let ((,end ,end-value))
          (labels ((,func-name (,param-name ,start ,step ,k)
                       (let ((new-exprs (progn ,@body))
                             (newK (+ 1 ,k)))
                         (if (,comparison ,end ,param-name)
                             (,func-name (+ ,param-name ,step) ,start ,step newK)
                             newK))))
             (,func-name ,param-name ,start-value ,step1 0)))))
    
    • Revolutionary_Utena@alien.topOPB
      link
      fedilink
      English
      arrow-up
      1
      ·
      11 months ago
      (defmacro for ((param start-value end-value &optional (step1 1)) &body body)
        (let* ((func-name (gensym))
               (start (gensym))
               (param-name (gensym))
               (comparison (if (< step1 0) '< '>))
               (end (gensym))
               (step (gensym))
               (k (gensym)))
          `(let ((,end ,end-value)
                 (,step ,step1)
                 (,start ,start-value))
            (labels ((,func-name (,param-name ,k)
                         (let ((new-exprs (progn ,@body))
                               (newK (+ 1 ,k)))
                           (if (,comparison ,end ,param-name)
                               (,func-name (+ ,param-name ,step) newK)
                               newK))))
               (,func-name ,param 0)))))
      
      (let ((s 0))
      (for (i 2 5)
      (incf s (sin i)))
      s)
      

      I made some changes but when I try to call macros with parameter (i 2 5) compiler give me error about unbound variable i.