| There seems to be a dearth of functions that can handle dotted lists correctly within the main Arc source, apparently there is only the dotted predicate and makeproper that converts a dotted list into an ordinary one. In particular, join and map die with a cryptic error message if they are used with dotted lists. I was hoping, in particular, that join would have the semantics of Common Lisp append, but unfortunately that doesn't seem to be the case: arc> (join '(a b c) '(d e . f))
Error: "Can't take car of f"
Neither does map it seems. arc> (map idfn '(a b . c))
Error: "Can't take car of c"
I can't think of any logical reason why these sorts of functions should be restricted to operating only on proper lists. I also notice that there doesn't seem to be an equivalent of the Common Lisp list* function, which makes the last cons of the constructed list dotted.I have had to write my own versions, based on the Common Lisp append from the SBCL source: (def join* args
(with (jinto
(afn (last-cons current rest)
(if (acons current)
(self (= (cdr last-cons) (list (car current)))
(cdr current) rest)
(~no current)
(err "current expected to be a list")
(no (cdr rest)) (= (cdr last-cons) (car rest))
(self last-cons (car rest) (cdr rest)))))
((afn (lists)
(with (cur (car lists) rest (cdr lists))
(if (no rest) cur
(acons cur)
(let result (list (car cur))
(do
(jinto result (cdr cur) rest)
result))
(no cur) (self rest)
(err "cur is not a list")))) args)))
and map: (def map* (f xs)
(if (atom xs)
(f xs)
(cons (f (car xs)) (map* f (cdr xs)))))
I think that the standard functions ought to behave at least as reasonably as their Common Lisp equivalents when confronted by dotted lists, as these sorts of lists do appear from time to time. |