Writing a destructive macro or function like incf?

前端 未结 2 565
小鲜肉
小鲜肉 2020-12-11 23:57

I need an incf function which does some bounds checking during the increment:

val := val + delta
if val >= 1.0
   then return 1.0
   else ret         


        
2条回答
  •  鱼传尺愫
    2020-12-12 00:23

    You may want to be careful about val, if you want it to be a place which can have side effects:

    (defmacro incf-bounded (form delta &environment env)
      (multiple-value-bind (temps vals vars writer reader)
          (get-setf-expansion form env)
        `(let* (,@(mapcar #'list temps vals)
                (,(first vars) (min (+ ,delta ,reader) 1.0))) ;Edited, see comments.
           ,writer)))
    

    Try it with e.g.

    (let ((list (list 0 0.5 1)))
      (loop with i = -1 repeat 3 do (incf-bounded (nth (incf i) list) 0.5))
      list)
    

    (This looks needlessly complicated, because I wanted a side effect in the first argument to incf-bounded.)

提交回复
热议问题