I have a couple of questions about Hello World in Clojure:
(println "Hello, world!")
Since 'println' is used, does this mean some Java libraries are included in the default namespace by default, just as in Grails?
Why are the braces needed around the statement? Judging by other examples (below), braces are commonplace:
(let [i (atom 0)]
(defn generate-unique-id
"Returns a distinct numeric ID for each call."
[]
(swap! i inc)))
Any evidence so far that Clojure is likely to catch on?
println is a built-in function in Clojure, and just happens to have the same name as in Java (check out the source). Some Java libraries are imported by default (java.io and java.lang I think).
The parentheses are syntax for calling a function and come from Lisp. For example, this function call in Java:
addTwoNumbers(4, 5);
would be written as follows in Clojure (and Lisp):
(addTwoNumbers 4 5)
Clojure's community is vibrant and growing. Check out the Google Group
Related
I'm starting to learn clojure and I've stumbled upon the following, when I found myself declaring a "sum" function (for learning purposes) I wrote the following code
(def sum (fn [& args] (apply + args)))
I have understood that I defined the symbol sum as containing that fn, but why do I have to enclose the Fn in parenthesis, isn't the compiler calling that function upon definition instead of when someone is actually invoking it? Maybe it's just my imperative brain talking.
Also, what are the use cases of let? Sometimes I stumble on code that use it and other code that don't, for example on the Clojure site there's an exercise to use the OpenStream function from the Java Interop, I wrote the following code:
(defn http-get
[url]
(let [url-obj (java.net.URL. url)]
(slurp (.openStream url-obj))))
(http-get "https://www.google.com")
whilst they wrote the following on the clojure site as an answer
(defn http-get [url]
(slurp
(.openStream
(java.net.URL. url))))
Again maybe it's just my imperative brain talking, the need of having a "variable" or an "object" to store something before using it, but I quite don't understand when I should use let or when I shouldn't.
To answer both of your questions:
1.
(def sum (fn [& args] (apply + args)))
Using def here is very unorthodox. When you define a function you usually want to use defn. But since you used def you should know that def binds a name to a value. fn's return value is a function. Effectively you bound the name sum to the function returned by applying (using parenthesis which are used for application) fn.
You could have used the more traditional (defn sum [& args] (apply + args))
2.
While using let sometimes makes sense for readability (separating steps outside their nested use) it is sometimes required when you want to do something once and use it multiple times. It binds the result to a name within a specified context.
We can look at the following example and see that without let it becomes harder to write (function is for demonstration purposes):
(let [db-results (query "select * from table")] ;; note: query is not a pure function
;; do stuff with db-results
(f db-results)
;; return db-results
db-results)))
This simply re-uses a return value (db-results) from a function that you usually only want to run once - in multiple locations. So let can be used for style like the example you've given, but its also very useful for value reuse within some context.
Both def and defn define a global symbol, sort of like a global variable in Java, etc. Also, (defn xxx ...) is a (very common) shortcut for (def xxx (fn ...)). So, both versions will work exactly the same way when you run the program. Since the defn version is shorter and more explicit, that is what you will do 99% of the time.
Typing (let [xxx ...] ...) defines a local symbol, which cannot be seen by code outside of the let form, just like a local variable (block-scope) in Java, etc.
Just like Java, it is optional when to have a local variable like url-obj. It will make no difference to the running program. You must answer the question, "Which version makes my code easier to read and understand?" This part is no different than Java.
Common Lisp has a function called progv, which establishes dynamic bindings for a form given a list of symbols and values. I'm for something similar for Clojure. I'm pretty sure this doesn't exist in the core language. I'm wondering what my best option would be.
here's an example using binding:
user> (def ^:dynamic add +)
#'user/add
user> (binding [add -]
(add 42 41))
1
because there is an efficiency cost to dynamic binding, recent versions of clojure require you to add metadata
to each symbol that expects to be dynamically bound.
binding is just a wrapper around the functions push-thread-bindings and pop-thread-bindings, so if you want to build such binding dynamically you can call these functions yourself like so:
user> (defn with-alternate-addition [number1 number2 addition-function]
(push-thread-bindings {#'add addition-function})
(try
(add number1 number2)
(finally (pop-thread-bindings))))
#'user/with-alternate-addition
user> (with-alternate-addition 42 41 -)
1
just make sure you get the pushes and pops right or things get really hard to debug.
I read that data > functions > macros
Say you want to evaluate code in a postfix fashion.
Which approach would be better?
;; Macro
(defmacro reverse-fn [expression]
(conj (butlast expression) (last expression)))
(reverse-fn ("hello world" println))
; => "hello world"
;; Function and data
(def data ["hello world" println])
(defn reverse-fn [data]
(apply (eval (last data)) (butlast data)))
(reverse-fn ["hello world" println])
; => "hello world"
Thanks!
If you require different evaluation behavior for any kind of data in your code macros are your best choice because they can transform unevaluated data at compile time to the code you'd like to be evaluated instead.
Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. (http://clojure.org/macros)
The example you provide has specifically that requirement ("evaluate code in a postfix fashion") which is why a macro is the correct choice.
Your macro is better than your function: a macro is better than a function employing eval.
However, the function need not employ eval. You could write it
(defn reverse-fn [data]
(apply (last data) (butlast data)))
Then, for example, as before,
(reverse-fn [3 inc])
=> 4
On a related topic, you might find this explanation of transducers interesting.
Edit:
Notice that functions are literals, in the sense that a function evaluates to itself:
((eval +) 1 1)
=> 2
In general:
Macros have their use however; macros expand at the point they are encountered so you will have one or more code blocks being inlined in the resulting byte code. They are ideal for encapsulating High Order DSL terminologies.
Functions, on the other hand, are wonderful for reuse where you localize the purity of the function and it can be called from multiple other functions without increasing the code footprint. They are ideal for localized or global usage.
REPL behavior consideration: A single function is easier to rework without worrying about fully evaluating the entire source file(s) to ensure all macro reference expansions get updated.
Hope this helps
Simple rules are the best: Use a function if you can, a macro if you must.
I'm doing my first steps with Clojure today and I encountered the first confusing obstacle right off the bat!
I've built a new Leiningen(2.5.1) project and just want to run the default code, which is:
(ns wavescript.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
Problem is the Lighttable(0.7.2) console tells:
WARNING: unsigned-bit-shift-right already refers to:
#'clojure.core/unsigned-bit-shift-right in namespace: cljs.core,
being replaced by: #'cljs.core/unsigned-bit-shift-right
I found some Google entries but none brought me further. What this is about?
This is caused by the symbol unsigned-bit-shift-right being found in the clojure.core namespace as well as a cljs.core. The clojure.core namespace is compiled/loaded before cljs.core, and the introduction of the new symbol is throwing the warning. It looks like, from the namespace, you are writing clojurescript. If you look at this file cljs.core on line 2147, you will see this form:
(defn unsigned-bit-shift-right
"Bitwise shift right with zero fill"
[x n] (cljs.core/unsigned-bit-shift-right x n))
in the cljs.core namespace. So, apparently, lighttable is importing both clojure.core and clj.core.
Honestly, I am not even sure how the cljs implementation is working, as it is completely self-referential. Additionally, there are uses of unsigned-bit-shift-right starting at line 451 that are not prefixed, so they must be using the clojure.core implementation. Bizarre. The above form appears after all the previous uses. It looks safe to say that symbol can be safely excluded. In fact, this may deserve a patch...
To resolve this, you might want to try to explicitly state your namespace importations and exclude that import. The refer function affords that.
So, you would have a namespace that looks like this
(ns my.namespace.hello-world
[:require
[cljs.core :exclude [unsigned-bit-shift-right]]])
The clojure.core implementation looks like this:
(defn unsigned-bit-shift-right
"Bitwise shift right, without sign-extension."
{:inline (fn [x n] `(. clojure.lang.Numbers (unsignedShiftRight ~x ~n)))
:added "1.6"}
[x n] (. clojure.lang.Numbers unsignedShiftRight x n))
Alternately, since they are wrapping the functionality, perhaps cljs.core is designed to not need to expose clojure.core. If that is the case, then exclude clojure.core, and see if you code will function properly.
In fact, from looking at the cljs.core namespace:
(ns cljs.core
(:refer-clojure :exclude [-> ->> .. amap and areduce alength aclone assert binding bound-fn case comment cond condp
declare definline definterface defmethod defmulti defn defn- defonce
defprotocol defrecord defstruct deftype delay destructure doseq dosync dotimes doto
extend-protocol extend-type fn for future gen-class gen-interface
if-let if-not import io! lazy-cat lazy-seq let letfn locking loop
memfn ns or proxy proxy-super pvalues refer-clojure reify sync time
when when-first when-let when-not while with-bindings with-in-str
with-loading-context with-local-vars with-open with-out-str with-precision with-redefs
satisfies? identical? true? false? number? nil? instance? symbol? keyword? string? str get
make-array vector list hash-map array-map hash-set
aget aset
+ - * / < <= > >= == zero? pos? neg? inc dec max min mod
byte char short int long float double
unchecked-byte unchecked-char unchecked-short unchecked-int
unchecked-long unchecked-float unchecked-double
unchecked-add unchecked-add-int unchecked-dec unchecked-dec-int
unchecked-divide unchecked-divide-int unchecked-inc unchecked-inc-int
unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int
unchecked-subtract unchecked-subtract-int unchecked-remainder-int
unsigned-bit-shift-right
bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set
bit-test bit-shift-left bit-shift-right bit-xor
cond-> cond->> as-> some-> some->>
if-some when-some test ns-interns var vswap!])
You can see that unsigned-bit-shift-right is supposed to be excluded from the namespace. So, you will want to exclude clojure.core to resolve the problem.
Occasionally when looking at other people's Clojure code, I see a function defined via defn and then called using the var-quote syntax, e.g.:
user> (defn a [] 1)
#'user/a
user> (a) ; This is how you normally call a function
1
user> (#'a) ; This uses the var-quote syntax and produces the same result
1
For the life of me I can't figure out the difference between these two ways of calling a function. I can't find anything in the evaluation documentation to say what happens when the operator of a call is a var that might suggest why the second form would be preferred. They both seem to respond in the same to binding assignments and syntax-quoting.
So, can somebody please provide a code sample that will illustrate the difference between (a) and (#'a) above?
Edit: I know that var-quote can be used to get to a var that's shadowed by a let lexical binding, but that doesn't seem to be the case in the code that I'm looking at.
(#'a) always refers to the var a, while (a) can be shadowed by local bindings:
user> (defn a [] 1)
#'user/a
user> (let [a (fn [] "booh")] [(a) (#'a)])
["booh" 1]
But most actual uses of var-quote / function call are not calling the var-quote expression directly, but instead cache its value so that higher-order constructs refer to the current value of var a instead of its value when passed in:
(defn a [] 1)
(defn my-call [f] (fn [] (+ 1 (f))))
(def one (my-call a))
(def two (my-call #'a))
(defn a [] 2)
user> (one)
2
user> (two)
3
This is mostly useful for interactive development, where you're changing some function that gets wrapped in a bunch of other functions in other packages.
The second form allows you to circumvent the privacy restrictions that clojure puts in place.
So, for instance, if you develop a library with private functions, but want to test them from a separate namespace, you cannot refer to them directly. But you can get to them using the var quote syntax. It's very useful for this.
Privacy is clojure is, in essence, a form of automatic documentation, as opposed to the privacy you see in Java. You can get around it.
user> (defn- a [] 1)
#'user/a
user> (ns user2)
nil
user2> (user/a)
CompilerException java.lang.IllegalStateException: var: #'user/a is not public, compiling:(NO_SOURCE_PATH:1)
user2> (#'user/a)
1
user2>