Page 1 of 1

Hash problems - clashing with newLISP's own symbols

Posted: Tue Dec 13, 2005 2:01 pm
by cormullion
I'm trying to learn about hash tables (or newLISP's way of doing them). I think I need to learn how to avoid clashes with newLISP's reserved words.

Here's a short test case:

Code: Select all

(context 'hash) ; create hash container

(dolist (the-word (parse "Set the controls for the heart of the sun. 
	It looks like it's time for a sharp exit, but don't make a hash of it!" " "))
	(set 'the-word (lower-case the-word))
	(replace "[^A-Za-z]" the-word "" 0) ; tidy the string
	(set 'occurrences (eval (sym the-word hash))) ; number of occurrences of word in list
	(if (> occurrences 0)
		(set (sym the-word hash (+ 1 occurrences))) ; increase count for this word
		(set (sym the-word hash ) 1 ) ; or add new word
		))
(dolist (s (symbols hash))
	(println (sym s hash) ":" (eval (sym s hash))))
(exit)
which gives the output:

Code: Select all

:1
a:1
but:1
controls:1
dont:1
hash:exit:1
hash:for:1
heart:1
it:1
its:1
like:1
looks:1
make:1
occurrences:1
of:1
s:s
hash:set:1
sharp:1
sun:1
the:1
the-word:nil
hash:time:1

invalid function : (hash:exit)

Posted: Tue Dec 13, 2005 3:58 pm
by Lutz
I haven't looked through the code you posted (sorry I am in a hurry at the moment). But reserved words in a dictionary should work, because they get explicitely overwitten.

Code: Select all

newLISP v.8.7.4 on OSX, execute 'newlisp -h' for more info.

> (set (sym "exit" 'MyHash) 123)
123
> (eval (sym "exit" 'MyHash))
123
> 

;; try the new shorter/faster form since 8.7.4
;; with an expanded syntax of 'context'

> (context 'MyHash "time" 456)
456
> (context 'MyHash "time")
456
> 
A different problem arises when you save the context (save "myhash.txt" 'MyHash) and then load it again with (load "myhash.txt") with words like 'set'. Because of this in the projects I am invloved (indexing/parsing huge numbers of documents), we prepend every word token with a "_" underscore, but if your dictionaries are never saved to disk this should not be a problem. There must be something different going one here.

Lutz

Posted: Tue Dec 13, 2005 4:25 pm
by Lutz
After looking into the code I see the following:

After (context 'hash) you should go back into MAIN doing a (context 'MAIN). If not all the code will be translated under context 'hash.

So just do:

Code: Select all

(context 'hash) ; create hash
(context 'MAIN)

(dolist (the-word ...)

now all your code gets defined and executed under MAIN and will not clash/be overwitten with words going into your dictionary 'hash.

Lutz

ps: your code runs fine after this change

Posted: Tue Dec 13, 2005 8:51 pm
by cormullion
Thanks again, Lutz. It looks reasonably obvious, in hindsight, but problems look harder before you see their solution!

Posted: Wed Dec 14, 2005 8:05 am
by cormullion
OK, now I've got a nice big 'hash' table. Is there an easy way to sort them by value?

HASH:a 1
HASH:a 3
HASH:a 2

=>

HASH:a 3
HASH:a 2
HASH:a 1

Otherwise I'll have to go through and create an array, I think...