Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure basics: counting frequencies

Tags:

clojure

I am learning Clojure, and I saw this bit of code online:

(count (filter #{42} coll))

And it does, as stated, count occurrences of the number 42 in coll. Is #{42} a function? The Clojure documentation on filter says that it should be, since the snippet works as advertised. I just have no idea how it works. If someone could clarify this for me, that would be great. My own solution to this same thing would have been:

(count (filter #(= %1 42) coll))

How come my filtering function has parenthesis and the snippet I found online has curly braces around the filtering function (#(...) vs. #{...})?

like image 477
vim Avatar asked May 03 '14 18:05

vim


2 Answers

=> #{42}
#{42}

Defines a set...

=> (type #{42})
clojure.lang.PersistentHashSet

=> (supers (type #{42}))
#{clojure.lang.IHashEq java.lang.Object clojure.lang.IFn ...}

Interestingly the set implements IFn so you can treat it like a function. The behaviour of the function is "if this item exists in the set, return it".

=> (#{2 3} 3)
3
=> (#{2 3} 4)
nil

Other collections such as map and vector stand in as functions in a similar fashion, retrieving by key or index as appropriate.

=> ({:x 23 :y 26} :y)
26
=> ([5 7 9] 1)
7

Sweet, no? :-)

like image 121
pete23 Avatar answered Sep 18 '22 07:09

pete23


Yes, #{42} is a function,

  • because it's a set, and sets, amongst other capabilities, are functions: they implement the clojure.lang.IFn interface.
  • Applied to any value in the set, they return it; applied to anything else, they return nil.
  • So #{42} tests whether its argument is 42 (only nil and false are false, remember).

The Clojure way is to make everything a function that might usefully be one:

  • Sets work as a test for membership.
  • Maps work as key lookup.
  • Vectors work as index lookup.
  • Keywords work as lookup in the map argument.

This

  • often saves you a get,
  • allows you, as in the question, to pass naked data structures to higher order functions such as filter and map, and
  • in the case of keywords, allows you to move transparently between maps and records for holding your data.
like image 23
Thumbnail Avatar answered Sep 22 '22 07:09

Thumbnail