Lists of Functions

Discussion of Common Lisp
Post Reply
BIOS
Posts: 15
Joined: Sun Apr 04, 2010 1:55 pm

Lists of Functions

Post by BIOS » Thu Apr 08, 2010 6:47 pm

Is it possible to structure lists of functions and then call those functions from the list with a function like nth or assoc? Take the following:

Code: Select all

(let* ((functions*
		 (list (random 5))))
	   (loop for i below 10 do
		(print (nth 0 functions*))))

I want this to return me 10 random values between 0 and 4. Instead i get the first value random comes up with 10 times. This is obviously because the variable functions* is being set as a one element list, the output of the random function, and i am then just calling the value held by the variable and not the function itself. Is there a way to store a function so that it is not evaluated until you call it with something like nth?

BIOS

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Lists of Functions

Post by ramarren » Thu Apr 08, 2010 10:40 pm

There is a chapter about functions as first class objects in Practical Common Lisp. There is not much point in someone rewriting it in a forum post.

Paul Donnelly
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: Lists of Functions

Post by Paul Donnelly » Fri Apr 09, 2010 1:11 am

BIOS wrote:Is it possible to structure lists of functions and then call those functions from the list with a function like nth or assoc?
Sure, but you didn't make a list of functions.

BIOS
Posts: 15
Joined: Sun Apr 04, 2010 1:55 pm

Re: Lists of Functions

Post by BIOS » Fri Apr 09, 2010 1:43 am

Thanks for the link Ramarren. I don't recall seeing how to do it in that chapter. I've tried funcall etc. I'll have another look.
Paul Donnelly wrote:
BIOS wrote:Is it possible to structure lists of functions and then call those functions from the list with a function like nth or assoc?
Sure, but you didn't make a list of functions.
I know. I don't know how. I mean the only thing i can think of is to quote it so it doesnt get it evaluated when going into the list but then how do i get it evaluated later when calling it Ex:

Code: Select all

(let* ((functions* '((random 5)
			            (random 10)
			            (random 20))))
	   (nth 0 functions*))
Returns me a list with (random 5) in it.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Lists of Functions

Post by ramarren » Fri Apr 09, 2010 2:10 am

BIOS wrote:I know. I don't know how. I mean the only thing i can think of is to quote it so it doesnt get it evaluated when going into the list but then how do i get it evaluated later when calling it Ex:
What you want is to create a list of functions. Those either have to be preexisting function, which can be retrieved from the function namespace with FUNCTION, or anonymous functions. You can then call them with FUNCALL.

Also, if you want random access the arrays/vectors are better than lists. Remember that NTH is linear in n.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: Lists of Functions

Post by Jasper » Fri Apr 09, 2010 5:49 am

Not sure what you mean.. You might mean to do

Code: Select all

(let ((functions (list (lambda () (random 5)))))) ;Or (alexandria:curry #'random 5)
  (dotimes (i 10) ;But this will autoput differently each time.
    (print (funcall (nth 0 functions)))))
Or you could be meaning that you want some sort of memoization, this is likely going to be slower than just storing random once:

Code: Select all

(defun memoized-random (upto)
   (let ((mem -1))
      (lambda () (if (< mem 0) (setq mem (random upto)) mem))))
It might be better just to make an array and store random values there when they arrive. Or do memoization automatically, but that afaik uses an hash-table.(much slower than that array, which doesn't take much space if the numbers are dense..)
Note that if you want to in effect 'store' a sequence of random states, you could also just store the seed those came from(something like):

Code: Select all

(let (random-state)
  (defun with-one-consistent-random (do) ;This only gives you one though.
    (let ((*random-state* (or random-state (setq random-state *random-state*))))
      (funcall do))));Or maybe
(defmacro with-consistent-random ((store-random) &body body)
  "Stores the and uses the first *random-state* it encounters.
Be warned, Store-random could be called twice (once the setf-version), avoid having side-effects in it/it being slow."
  `(let ((*random-state* (or ,store-random (setf ,store-random *random-state*)))
     ,@body))
Useful if you're making random trees or something, you'd only have to store the random seed to generate them. (Although the random generator changing/being implementation dependent might be an issue.)

BIOS
Posts: 15
Joined: Sun Apr 04, 2010 1:55 pm

Re: Lists of Functions

Post by BIOS » Fri Apr 09, 2010 2:12 pm

Ramarren wrote: What you want is to create a list of functions. Those either have to be preexisting function, which can be retrieved from the function namespace with FUNCTION, or anonymous functions. You can then call them with FUNCALL.

Also, if you want random access the arrays/vectors are better than lists. Remember that NTH is linear in n.
Hey thanks for the links. That's been very helpful :) Haven't tried making an array before. What are it's main advantages?

@Jasper thanks for the code. Never looked into memoization before. Very interesting. It'll take me some time to digest that code ;)

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Lists of Functions

Post by ramarren » Fri Apr 09, 2010 2:23 pm

BIOS wrote:Haven't tried making an array before. What are it's main advantages?
This is so elementary computer science that I haven't even got any idea what is a good reference... Wikipedia, maybe. Look at the end of that article for a series of links about other basic data structures. Understanding data structures and their time/space complexity is crucial for any sort of programming beyond most trivial.

BIOS
Posts: 15
Joined: Sun Apr 04, 2010 1:55 pm

Re: Lists of Functions

Post by BIOS » Fri Apr 09, 2010 3:53 pm

Ah yes this is what my computer scientist friend told me i should really focus on. Data structure. Thanks for the direction.

Paul Donnelly
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: Lists of Functions

Post by Paul Donnelly » Sat Apr 10, 2010 3:11 am

BIOS wrote:Thanks for the link Ramarren. I don't recall seeing how to do it in that chapter. I've tried funcall etc. I'll have another look.
Paul Donnelly wrote:
BIOS wrote:Is it possible to structure lists of functions and then call those functions from the list with a function like nth or assoc?
Sure, but you didn't make a list of functions.
I know. I don't know how.
I figured between the PCL link and my post you'd be able to get what you needed.

Post Reply