an emulation of enum

This is a moderated forum that collects tutorials, guides, and references for creating Transcendence extensions and scripts.
Post Reply
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

There are some cool things in the change log that alterecco found.

We are going to use that to emulate enum.

first the code then I will explain it :D

Code: Select all

(setq metaEnum (lambda (enumlist %Itemvar %exp)
	(block (counter func)
		(setq func (eval (list lambda (list %Itemvar) %exp)))
		(setq counter 0)
		(loop (ls counter (count enumlist))
			(block nil
				(setq counter (add 1 counter))
				(func (item enumList (subtract counter 1)))

			)
		)

	)	
))
First thing that is happening is we are creating a lambda function with three arguments. The % will tell it not to evaluate them so if you pass in name the % argument will have the string name whereas a normal argument would have whatever the variable name contained.

Then we make a block with two temporary variables counter (saying where we are on the list) and func (to contain the function that happens to every item on the list).

Counter gets setq to 0 and func gets a lambda function made out of the variable name and the code to be evaluated. Note that nothing is ran yet but it is evaluated to turn it into a lambda function.

Now we just have a simple loop so we can run the function with every item. Also note that because enum returns the last thing evaluated we need to increment the counter before running the function.

We now have a function that acts just like enum. You can do
(metaEnum '(a b c d) myItem (dbgOutput myItem))
and it would do the same thing as
(enum '(a b c d) myItem (dbgOutput myItem))

Slightly altered enums can be very useful and now we have a way to do them.
Crying is not a proper retort!
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

This is very useful. I have rewritten several of my enumerating functions to use this syntax. I will post them here:

Code: Select all

;; Transform each element of a list by applying them
;; to a function
;;
;; @param lst:  the list to transform
;; @param %var: variable the current iteration will be available as
;; @param %exp: the expression used for the transform

;; @return: a new list of transformed values
(setq dsf_ListMap (lambda (lst %var %exp)
    (block (mapped (exp (eval (list lambda (list %var) %exp))))
        (setq mapped (list))
        (enum lst el
            (lnkAppend mapped (exp el))
        )
        mapped
    )
))

;; Reduce the list to one element by using a lambda
;;
;; @param lst:      initial list
;; @param memo:     initial value of memo
;; @param %memovar: name of memo variable
;; @param %var:     current value of iteration
;; @param %exp:     the expression used to reduce the list
;;
;; @return: the last value returned by the expression
(setq dsf_ListReduce (lambda (lst memo %memovar %var %exp)
    (block ((exp (eval (list lambda (list %var %memovar) %exp))))
        (enum lst el
            (setq memo (exp el memo))
        )
    )
))

;; Look through each value of a list and return the
;; first that passes a truth test (fun). Does not
;; loop further through the list after that
;;
;; @param lst:      list to test
;; @param %var:     current value of iteration
;; @param %exp:     the expression used to detect
;;
;; @return: the first value that tests true
(setq dsf_ListDetect (lambda (lst %var %exp)
    (block (found (exp (eval (list lambda (list %var) %exp))))
        (enumWhile lst (not found) el
            (if (exp el) (block Nil
                (setq found True)
                el
            ))
        )
    )
))
The use of these functions is cleaner now, similar to the built in enum. They even seem to be faster than their lambda counterparts.

Here is how to use them

Code: Select all

(dsf_ListMap '(1 2 3) el (add 1 el)) -> (2 3 4)

(dsf_ListReduce '(1 2 3) 0 memo i (add memo i)) -> 6

(dsf_ListDetect '(a b c) i (eq i 'b)) -> b
Nice and simple. Thanks george! :D
Post Reply