Hi TC, thanks for your proposal.
However, as I explained in another mail, I would definitely not change the current behavior of 'list' or 'cons' (and most other functions in picoLisp). > I'm uncertain if '() is actually (NIL . NIL) so I'm not going to list > the cons' examples. No, these are different things. () is converted by the reader as a reference to the internal symbol 'NIL'. (NIL . NIL), which is the same as (NIL), is a cell containing references to NIL in the CAR and CDR parts. (cons) is my standard way to create a fresh cell. > I know why this works this way. In pL's VM, every list is parsed until > there's an empty CDR (retreiving CDR returns NIL). Since there are ^ call this "atomic CDR" > functions that MUST take at least one argument; when they are called > with no argument, they will try to read NIL's CDR, and therefore use NIL > as arguments, since (cdr NIL) -> NIL Correct. > Here are a couple of solutions for this issue, you pick: > 1. Make it error when (cdr NIL) (increases complexity and decreases > flexibility). > 2. Make pL check on every step if the current argument is actually the last > CAR (naive and maybe slow). > 3. Make pL check the amount of arguments provided and return NIL if they > are not enough for the function to do it's job. (slightly increases > complexity) > 4. Bury the topic. A good roundup :-) Points (1) and (2) would actually be rather stupid and useless, but can be seen in some Lisp and Scheme implementations. The original design of picoLisp put a lot of effort into the handling of NIL. While NIL is in other Lisps just a symbol, it has a dual nature in picoLisp (see "doc/structures" and "doc64/structures"): NIL: / | V +-----+-----+-----+-----+ |'LIN'| / | / | / | +-----+--+--+-----+-----+ While it is a symbol physically (the pointer is at an multiple of the cell size plus half a cell), accessing the pointer with CAR (offset zero) and CDR (offset half a cell size) is legal and will always return NIL again. This allows a very fast traversal of lists, without the need for checking for end-of-list. So (3) comes without any cost. > Anyway, I just couldn't resist the temptation to try to implement > solution nÂș 3, so I grabbed the sources, segfaulted the hell out of it Great! :-) > when I tried to avoid repeating code, and after a long while of ERTCL > (edit, recompile, test, cuss, loop), I decided to leave it like that for > now, and ask for a revision. Well, first of all, a function that counts arguments before evaluating them should be avoided like hell. This was the main reason for rewriting picoLisp in assembly language (explained in "doc64/README"). And, fortunately, it is also not necessary. Usually a simple atom (X CDR) will tell you if there are any (or more) arguments. Besides this, what you wrote looks really good! > +### Internal function ### > +(code 'argLen 2) > + push X > + push Y > ... > + ld Y (X CDR) # Next cell > + cmp Y X # Circular? > + jz lengthT # Yes > ... > + add E (hex "10") # Increment counter > + loop > + ld Y X # Keep list head <- This should be before the "Circular?" > check? > + ret Cheers, - Alex -- UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe