makeset & makelist



I was looking for a solution to bug 3439895: 

  
http://sourceforge.net/tracker/?func=detail&aid=3439895&group_id=4933&atid=104933

I guess the issue is that makelist is a defmspec function and makeset is a 

defun function. For inspiration, I looked at the source for makelist :(

(1) Possibly makelist is too flexible; for example (midly silly)

 (%i1) makelist(i+j, i+j, [1,2,3]);
 (%o1) [1,2,3]

But (total weirdness)

 (%i2) makelist(integrate(f(x),x), integrate(f(x),x), [1,2,3]);
 (%o2) [integrate(f(x),x),integrate(f(x),x),integrate(f(x),x)]

Quoting the first integrate allows this to return [1,2,3]. Try explaining 
that in the 
user documentation. Finally,

 (%i4) makelist(2,2,[1,2,3]);
    Only symbols can be bound; found: 2

Compare this to makelist(i+j, i+j, [1,2,3]) --> [1,2,3] (i+j can be bound 
either).

(2) The call to $ev in makelist had bothered me since the Clinton 
administration. 
The unredacted: (unlike current makelist, no calls to $ev; runs the 
testsuite & share testsuite OK)

(defmspec $makelist (l)
  (let* ((fn (pop l))
                  (e (if l (pop l) nil))
                  (k (if l (pop l) nil))
                  (lo (if l (meval (pop l)) nil))
                  (hi (if l (meval (pop l)) nil))
                  (step (if l (meval (pop l)) 1))
                  (lf) (n) (q nil))
    (if l (wna-err (car fn)))

    (if (and k (not (or (symbolp k) ($subvarp k)))) 
                 (merror (intl:gettext "makelist: second argument must be 
symbol; found: ~M") k))

    (if lo (setq lf (let (($opsubst t)) (maxima-substitute (gensym) k 
`((lambda) ((mlist) ,k) ,e)))))
    ;;(if lo (setq lf (subst (gensym) k `((lambda) ((mlist) ,k) ,e) :test 
#'alike1)))
 
    (cond (hi
           (setq n (add 1 (take '($floor) (div (sub hi lo) step))))
           (if (not (integerp n)) (merror (intl:gettext "makelist: 
noninteger number of list members")))
           (dotimes (i n) (push (mfuncall lf (add lo (mul i step))) q))
           (setq q (reverse q)))
          (lo (setq q (mapcar #'(lambda (s) (mfuncall lf s)) (margs lo))))
          (t
           (setq k (cond (k k)
                         (e 1)
                         (t 0)))
           (if (integerp k) (dotimes (i k) (push e q)) (merror 
(intl:gettext "makelist: noninteger number of list members")))))
 
    (push '(mlist) q))) ;; defmspec automatically simplifies, I think.
 
(3) One difference between this makelist and the current makelist:

(%i1) a : 6$

(%i2) makelist(a[i], a[i], [1,2,3]);
apply: found a evaluates to 6 where a function was expected.

 
(%i3) load("stuff-and-junk/makelist.lisp")$
(
(%i4) makelist(a[i], a[i], [1,2,3]);
(%o4) [1,2,3]

(4) Advice? Makeset is a function that didn't need to be written, I think. 
And so it goes.
I could pattern makeset off my version of makelist?

--Barton