[bof?] ++ nil val in hashmap fails -> feature

Q&A's, tips, howto's
Locked
hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

[bof?] ++ nil val in hashmap fails -> feature

Post by hartrock »

Code: Select all

sr@mad:~$ newlisp
newLISP v.10.6.2 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h

> (new Tree 'hm)
hm
> (hm "foo" (+ (or $it 0) 1))
1
> (++ (hm "foo"))
2
> ; OK, but:
> (++ (hm "bar"))

ERR: invalid parameter in function ++
> 
Is this a bug, or is there a reason for this behavior?

It would be nice, if checking for nil could be avoided here.
Last edited by hartrock on Sat Jul 25, 2015 9:00 am, edited 1 time in total.

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: [bof?] ++ nil val in hashmap fails

Post by xytroxon »

Just use this direct form, no need for (new Tree 'hm), it is created auto-magically ;o)

Code: Select all

> (++ iter:baz)
> 1
-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: [bof?] ++ nil val in hashmap fails

Post by TedWalther »

That is a surprising (until you think about it) difference in behavior.

(ctx "bar") returns a setf-able place, or nil. but referencing an unbound symbol always returns a setf-able place.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

Re: [bof?] ++ nil val in hashmap fails

Post by hartrock »

Thanks for clearifying the difference between symbols and Tree or (ctxt "someKey") hashmap values.

My usecase is a state machine modeled by a hash map with string state IDs as keys, where I want to count state changes. So I have two Tree hash maps: one for the states, another for the counters; both with same string keys.
Best solution I think is to init the corresponding counter hash map val with 0, just with adding a new state to state machine hashmap (which will be done by a func); so above check for nil can be omitted.

Using symbol keys for states like sm:someState would be possible, too; but then there could be a conflict with funcs like sm:add-state, located in same context as state hashmap.
Last edited by hartrock on Thu Jul 02, 2015 1:35 am, edited 1 time in total.

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: [bof?] ++ nil val in hashmap fails

Post by TedWalther »

Yes, the way I do it is to override the default functor.

Code: Select all

(context 'ctx)
;; override default functor
(define (ctx:ctx a)
  (let (b (sym (string "_" a)))
    (if (args) 
      (set b (first (args)))                   ; set the value
      (if (eval b) (eval b) (set b 0))))) ; retrieve the value
(context MAIN)
Now references to an unbound symbol will be automatically set to 0, and setf-able. With this default functor, now your original code, (++ (hm "foo")) will properly return "1", as you expected.

This seems like it might be a useful design pattern, perhaps suitable for the CodePatterns document if it isn't in there already; I similarly changed the default functor to use a database as a backing store, if a symbol is unbound, it looks it up with SQL and stores it client-side, references thereafter are very speedy.

The way contexts work in newlisp, with this idiom, you still get all the speed advantages of redblack trees that contexts have. Right Lutz?
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: [bof?] ++ nil val in hashmap fails

Post by xytroxon »

You could also use newLISP eval-string.

Code: Select all

> (setq id "bar")
> (eval-string (string "(++ hm:" id ")")))
> 1

> (define (++hm id) (eval-string (string "(++ hm:" id ")")))
> (++hm "foo"))
> 1

-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

Locked