lambdas in objData (or: the evasive lambda)

This is a moderated forum that collects tutorials, guides, and references for creating Transcendence extensions and scripts.
Post Reply
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

For a long time we have tried to store functions on objects, for the purpose of saving them across sessions. Up until now this has not been possible, but as a side effect of the new long listing of lambdas, it turns out we can recreate any functions stored on an object. An example

Code: Select all

(block (func1 funcLiteral func1Again)
  (setq func1 (lambda Nil (dbgOutput "test")))
  (objSetData gPlayerShip 'func func1)

  ;; now retrieve it as a literal
  (setq funcLiteral (objGetData gPlayerShip 'func))
  ;; now, to convert it, we do some evalling
  (setq func1Again (eval (eval funcLiteral)))
  (func1Again)
)
Ummm.... woohoooo :D

(func1Again) happily outputs "test" to the console.

Now, func1Again is not the same object as func1, so stuff like closures are not preserved, but otherwise it feels and acts the same.

All in all, good news for dynamic modding :)
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

now we can have different functions on different ships dynamically with the same name 8)

plus it allows us to use local lambda functions at a later date 8)

all in all this is a great discovery

edit: this also allows you to create dynamic events
Crying is not a proper retort!
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

Just did a stress test with a 60k line function and it outputs the correct answer. So we know that code length is not a problem.

warning if you do run this code expect there to be a large pause, the game is not hung it just takes awhile to eval all that code.

Code: Select all

(setq dataStressTest (lambda Nil 
	(block (func1)
		(setq func '(lambda nil (block (a) (setq a 1))))

		(for i 0 60000
			(lnkAppend (item func 2) '(setq a (add 1 a)))
		)

		(objSetData gplayership "stress" func)
		(dbgOutput ((eval (eval (objGetData gplayership "stress")))))


		)
))
minor note I also found that you can make your own lambda functions :twisted:
Crying is not a proper retort!
Post Reply