newLISP Fan Club

Forum => newLISP newS => Topic started by: xytroxon on April 08, 2011, 11:41:06 AM

Title: dotree, or not to dotree, that is the question!
Post by: xytroxon on April 08, 2011, 11:41:06 AM
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
Title: Re: dotree, or not to dotree, that is the question!
Post by: cormullion on April 08, 2011, 12:32:34 PM
(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.
Title: Re: dotree, or not to dotree, that is the question!
Post by: Lutz on April 08, 2011, 02:58:10 PM
(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.
Title: Re: dotree, or not to dotree, that is the question!
Post by: Lutz on April 08, 2011, 03:48:51 PM
The crash bug with the 'true' parameter in 'dotree' is fixed here:



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.