5 ms·
It's worth noting that Clojure has native support for hashes via the {} syntax. (http://clojure.org http://clojure.org)
by burke 18y ago
It's worth noting that Clojure has native support for hashes via the {} syntax. (http://clojure.org http://clojure.org)
- pmjordan 18y agoAnd 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)
- whacked_new 18y agoSomething 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.
- tokipin 18y agoit'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
- pmjordan 18y agoThat'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)
- pmjordan 18y agoYep, 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.
- jrockway 18y agoClojure definitely has nice data structures. Does anyone do this sort of hash-table-as-function thing in Scheme?
- jrockway 18y agoMy article was actually a response to all of the "CL sucks, I'm switching to Clojure" articles I've read this week. While Clojure is certainly a good language, I think people are "switching" to it from CL due to hype, rather than their deep understanding of the problems with CL. Clojure gives you a few nice features, like immutable data structures, "nicer" reader syntax, and JVM compatibility. In exchange, you give up CLOS in favor of Java's broken object model. All I'm saying is that I don't think the popular community is really considering CL's advantages before switching, they are only considering the disadvantages. If you are going to consider disadvantages, it's important to keep in mind that Clojure has them too. (Another often-cited reason for switching to Clojure is Java's libraries. In my experience working with Java, its libraries are pretty bad. Read the URLConnection class that comes with Java 6. It is clear that the API designer has no idea what OOP is, and it's clear that those implementing the library had no idea how to program. CL libraries, I've found, are usually better-done.) But with that in mind, I really like Clojure. I have the occasional client that insists on JVM applications, and Clojure is significantly less painful than pure Java (or JRuby, or Scala). But it is not my first choice when the JVM is not a requirement.
- weavejester 18y agoClojure provides several ways of interfacing with Java's object model, but generally this is just for compatibility purposes. The equivalent to CLOS in Clojure would be multimethods and hierarchies.