'choice pop' for choosing FIFO semantics after standard push
Posted: Wed Aug 05, 2015 11:09 pm
cpop stands for 'choice' pop, where the cpop is able to choose, if a standard push without ix leads to FIFO semantics on cpops side.
Currently only the push has this choice of switching from standard LIFO to FIFO semantics, by pushing back using -1 ix, which is working for an empty list: on the other side pop fails, if poping from an empty list with -1 ix.
Here are two macros implementing cpop semantics:
After loading former code, there has been the following session to show its functionality:
A difference between expansion and run-time macro:
Extending pop by building in cpops FIFO semantics would only be a minor change in interpreter code: it only needs the addition of an empty? list check (so performance should be no problem).
Currently only the push has this choice of switching from standard LIFO to FIFO semantics, by pushing back using -1 ix, which is working for an empty list: on the other side pop fails, if poping from an empty list with -1 ix.
Here are two macros implementing cpop semantics:
Code: Select all
;; best in functionality
(context 'cpop)
(define-macro (cpop:cpop l (ix 0))
(if (not (empty? (eval l)))
(pop (eval l) (eval ix)))) ; returns nil, if empty list
(context MAIN)
;; this has limitations, but should be faster
(macro (emacro-cpop L (Ix 0)) ; emacro: expansion macro
(if (not (empty? L))
(pop L Ix))) ; returns nil, if empty list
Code: Select all
> ;;
> ;; choices by push for standard pop
> ;;
> ; LIFO
> (push 3 (push 2 (push 1 l))) ; standard push leading to LIFO
(3 2 1)
> (pop l) (pop l) (pop l) (pop l) ; standard pop
3
2
1
nil
> ;
> ; FIFO:
> (push 3 (push 2 (push 1 l -1) -1) -1) ; FIFO push
(1 2 3)
> (pop l) (pop l) (pop l) (pop l) ; standard pop
1
2
3
nil
> ;;
> ;;
> ;; choices by pop for standard push
> ;;
> ;; LIFO choice by pop here is the same as LIFO choice by push for standard pop above:
> ;; both with standard push'n'pop.
> ;
> ; FIFO fails, if the list has become empty:
> (push 3 (push 2 (push 1 l))) ; standard push
(3 2 1)
> (pop l -1) (pop l -1) (pop l -1) (pop l -1) ; FIFO pop (failing)
1
2
3
ERR: invalid list index in function pop
> ; -> this is the problem
> ;
> ; FIFO choice by cpop works:
> (push 3 (push 2 (push 1 l))) ; standard push
(3 2 1)
> (cpop l -1) (cpop l -1) (cpop l -1) (cpop l -1) ; FIFO cpop (working)
1
2
3
nil
>
Code: Select all
> ;; this shows a difference between the different macro types: expansion macro works in many cases:
> (push 3 (push 2 (push 1 l)))
(3 2 1)
> (em-cpop l -1) (em-cpop l -1) (em-cpop l -1) (em-cpop l -1) ; (working)
1
2
3
nil
> ;;
> ; but not in all:
> (push 3 (push 2 (push 1 l)))
(3 2 1)
> ((if true cpop "dummy") l -1) ; -> run-time macro works
1
> ((if true em-cpop "dummy") l -1) ; -> expansion macro fails
(if (not (empty? l))
(pop l -1))
>