News for hackers. Stuff that matters.
Re:Problems with Lisp by pmjordan on Sunday January 25, 2009 @03:17PM (#449449)
And hashtable lookups are possible by just function-calling the table itself with the key:

  => ({ :foo 1  :bar 2 } :foo)
  1
the common pattern of defaulting to a value if the key isn't found is easy too:

  => ({ :foo 1  :bar 2 } :baz 4)
  4
The above is a hash map, #{ ... } creates a hash set which otherwise has similar semantics. Sets, being function-callable, can be used directly for checking if something is one of a bunch of values:

  (if (#{301 302 303 307} response-code)
    ; we've been redirected
Maps and sets (you also have sorted maps and sets and a compact struct-map, all of which have identical semantics as the hash variants where appropriate) can additionally be used with most functions accepting a seq (list) or can be converted to a list explicitly using the seq function.

Basically, maps and sets really are first-class citizens in clojure. Some of the flexibility is down to the fact that Clojure is a Lisp-1: these features are therefore hard to replicate in CL. (and yes, hash tables also bothered me somewhat in CL, altough other things probably bothered me more)

Re:Problems with Lisp by whacked_new on Sunday January 25, 2009 @04:02PM (#449514)
Something I find strange about hashes in Clojure, is that you can access them using the key as a function. So instead of

    ({ :foo 1  :bar 2 } :foo) ;; => 1
You get the equivalent by doing

    (:foo { :foo 1  :bar 2 }) ;; => 1
For default values:

    (:baz { :foo 1  :bar 2 } 3) ;; => 3
I vaguely remember this is because keys act as functions, and hashes act as functions as well. Out of habit and similarity to other languages, I never use the key-first notation, nor can I see where it is better to use it.
Re:Problems with Lisp by tokipin on Sunday January 25, 2009 @04:32PM (#449566)
it's likely for usage in higher-order functions. i haven't used clojure but i assume you can do something like this:

  (map :foo hashofhashes)
which would get the element :foo of every hash in hashofhashes
Re:Problems with Lisp by pmjordan on Sunday January 25, 2009 @04:41PM (#449582)
That's another good point, although the alternative isn't much longer:

  (map #(% :foo) hashofhashes)
or if % has a chance of being nil:

  (map #(get % :foo) hashofhashes)
Re:Problems with Lisp by pmjordan on Sunday January 25, 2009 @04:39PM (#449573)
Yep, the funcall semantics of symbols and keywords are to forward the symbol and key itself along with the arguments to the get function.

I do sometimes use this notation, mostly when:

- the map could be nil. (get nil :foo) and (:foo nil) will return nil, but (nil :foo) will throw an exception.

- dealing with struct-maps, where the key can effectively be seen as an accessor function. (cf structs in CL)

- (rarely) when the expression evaluating to the map is long and complex. A keyword in the function position (a) makes it clear that what follows must be a map or set and (b) you don't have to start counting parens.

Re:Problems with Lisp by jrockway on Monday January 26, 2009 @12:09AM (#450047)
Clojure definitely has nice data structures.

Does anyone do this sort of hash-table-as-function thing in Scheme?