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

Started by xytroxon, April 08, 2011, 11:41:06 AM

Previous topic - Next topic

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.



(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
\"Many computers can print only capital letters, so we shall not use lowercase letters.\"

-- Let\'s Talk Lisp (c) 1976

cormullion

#1
(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.

Lutz

#2
(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:


> 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:


(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:


(dolist (pet (pet-db)) (pet-db (pet 0) (upper-case $it))) ; faster


But 'dotree' with a properly working 'true' parameter would be even faster.

Lutz

#3
The crash bug with the 'true' parameter in 'dotree' is fixed here:



http://www.newlisp.org/downloads/development/inprogress/">http://www.newlisp.org/downloads/develo ... nprogress/">http://www.newlisp.org/downloads/development/inprogress/



There is also a newlisp.exe for MS Windows.



BTW, to delete the entire tree, you also can do:
(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:
(dotree (p pet-db true) (delete p))
will also work.