Page 1 of 1

dotree, or not to dotree, that is the question!

Posted: Fri Apr 08, 2011 6:41 pm
by xytroxon
Hi Lutz!

I'm having problems / confusion when using dotree in a database program.

dotree either doesn't work or is of little or no value. The simplified working program below creates, lists, and deletes database tree items using dotree.

Code: Select all

(new Tree 'pet-db)

(pet-db "dog" "King")
(pet-db "cat" "Fluffy")
(pet-db "hamster" "Sam")
(pet-db "fish" "Goldy")

(println "---> show the database")
(println (pet-db))

(println "--> list items")
; (dotree (pet pet-db) 	(println pet " -> " (pet) )) ; 1. Error?
; (dotree (pet pet-db true) 	(println pet " -> " (eval pet) )) ; 2, Hang and crash! 
(dotree (pet pet-db) 	(println pet " -> " (eval pet) ))

(println "---> delete ttems")
; (dotree (pet pet-db) 	(println pet " -> " (pet nil) )) ; 1. Error?
; (dotree (pet pet-db true) (println pet " -> " ((prefix pet) (1 (string (term pet))) nil) )) ; 2. Hang and crash!
(dotree (pet pet-db) (println pet " -> " ((prefix pet) (1 (string (term pet))) nil) ))

(println "--> show database")
(println (pet-db))

(exit)
The commented out error(s) of concern:

1. Using the what I expected (pet) or (pet nil) tree access forms cause an invalid function error. After much experimentation, using (eval pet) and my patent pending "messy code" ((prefix pet) (1 (string (term pet))) nil) works, but then...

2 . When trying to only list the tree items using dotree with the true flag, it somehow causes a hang and crash on Win 7. This is like a run away system memory crash of the interpreter, and not an error condition.

What is the proper way to scan through all the items in a database tree when simply trying to update and or delete itens?

dotree, or not to dotree that is the (my) question... ;>)

-- xytroxon

Re: dotree, or not to dotree, that is the question!

Posted: Fri Apr 08, 2011 7:32 pm
by cormullion

Code: Select all

(dotree (pet pet-db)    
    (println pet " -> "  (context pet-db (term pet))))

; delete
(dotree (pet pet-db)
    (context pet-db pet nil ))
I think there's a bug in the dotree ... true option.

Re: dotree, or not to dotree, that is the question!

Posted: Fri Apr 08, 2011 9:58 pm
by Lutz

Code: Select all

(dotree (pet pet-db)    (println pet " -> " (pet) )) ; 1. Error? (dotree (pet pet-db)    (println pet " -> " (pet nil) )) ; 1. Error?
you are applying a symbol which contains a string. It's like doing:

Code: Select all

> pet-db:_cat
"Fluffy"
> (pet-db:_cat) ; or (pet-db:_cat nil)

ERR: invalid function : (pet-db:_cat)
> 
But there seems to be a problem with the 'true' parameter leading to a crash. I will look into this.

As a workaround to access only the underscored hash symbols use:

Code: Select all

(dolist (pet (pet-db)) (pet-db (pet 0) (upper-case (pet 1))))
(pet-db) => (("cat" "FLUFFY") ("dog" "KING") ("fish" "GOLDY") ("hamster" "SAM"))
or this would work too:

Code: Select all

(dolist (pet (pet-db)) (pet-db (pet 0) (upper-case $it))) ; faster
But 'dotree' with a properly working 'true' parameter would be even faster.

Re: dotree, or not to dotree, that is the question!

Posted: Fri Apr 08, 2011 10:48 pm
by Lutz
The crash bug with the 'true' parameter in 'dotree' is fixed here:

http://www.newlisp.org/downloads/develo ... nprogress/

There is also a newlisp.exe for MS Windows.

BTW, to delete the entire tree, you also can do:

Code: Select all

(delete 'pet-db)
it destroys all symbols in 'pet-db' and leaves 'pet-deb' as a normal symbol (not a context). To re-create the hash tree just use (new Tree 'pet-db) again.

and using:

Code: Select all

(dotree (p pet-db true) (delete p)) 
will also work.