I want to be able to programatically define a docstring for one of my functions in clojure.
For example, I want to be able to do something like this:
(defn my-function
(str "Here are some numbers " (range 10))
[]
(println "This function does nothing right now."))
However, when I attempt to do this, I get "Parameter decleration str should be a vector". Is this just not possible in clojure or is there some sneaky way to do this? It would be useful to me to programatically generate parts of the docstring.
Yep, it's definitely possible. The thing you're running into here is that defn (or rather, the def special form that it expands to) attaches a docstring to the symbol iff the argument in second place is a string.
You can circumvent this by setting the :doc metadata yourself.
(defn ^{:doc (apply str "Here are some numbers " (range 10))} my-function
[]
(println "This function does nothing right now."))
Or potentially by writing your own macro - but I think the above is the most straightforward way of doing it.
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.
Example. We have very easy funcs.
(defn func1 []
(println "i'm func1"))
(defn func2 []
(println "i'm func2"))
And I create list with names of this functions.
(def listOfFunc '(func1 func2))
How I can run this functions, when I get name of functions from list?
Sorry for my bad english and very noob question.
Is there a specific reason why these functions are stored in a list?
If no, then you can use a vector which will result into something like this:
(def fns [func1 func2])
(map #(%) fns)
Note that this will result into a lazy seq of two nils: (nil nil). If however your functions are only for side-effects, as the ones you listed, then you can wrap them into a dorun:
(dorun (map #(%) fns))
which will return a single nil.
Now, if you still prefer using a list, you will have to resolve your symbols into the corresponding functions. So I guess something like this would work:
(map #((ns-resolve 'foo.core %)) listOfFunc)
where 'foo.core should be replaced with the namespace that has your functions.
the code following code does not work because re-find accepts a string as the first argument and a regex as the second.
(-> "hello"
.toUpperCase
(re-find #".$"))
The code would work if I wrapped re-find like this:
(defn re-find2 [s r]
(re-find r s))
If I replace re-find with re-find2 now, I get what I expected: a capitalized "O".
How could I solve this without wrapping re-find?
As mentioned, you can use thread-last if all your functions only have one argument or take the result as the last argument. However, if you also have functions which have multiple arguments and you must pass the result in a specific position which cannot be handled by -> or ->>, then possibly the as-> macro would be your best bet.
This macro allows you to specify a binding for the result from each function call. As the result now has a name, you can control where that parameter is positioned. Have a look at this blog post on threading macros
For this specific case you could use the thread-last macro instead.
(->> "hello" .toUpperCase (re-find #".$"))
If you really need to switch between passing as first and last argument you can chain the threading macros:
(-> "hello" .toUpperCase (->> (re-find #".$")))
What's the (most) idiomatic Clojure representation of no-op? I.e.,
(def r (ref {}))
...
(let [der #r]
(match [(:a der) (:b der)]
[nil nil] (do (fill-in-a) (fill-in-b))
[_ nil] (fill-in-b)
[nil _] (fill-in-a)
[_ _] ????))
Python has pass. What should I be using in Clojure?
ETA: I ask mostly because I've run into places (cond, e.g.) where not supplying anything causes an error. I realize that "most" of the time, an equivalent of pass isn't needed, but when it is, I'd like to know what's the most Clojuric.
I see the keyword :default used in cases like this fairly commonly.
It has the nice property of being recognizable in the output and or logs. This way when you see a log line like: "process completed :default" it's obvious that nothing actually ran. This takes advantage of the fact that keywords are truthy in Clojure so the default will be counted as a success.
There are no "statements" in Clojure, but there are an infinite number of ways to "do nothing". An empty do block (do), literally indicates that one is "doing nothing" and evaluates to nil. Also, I agree with the comment that the question itself indicates that you are not using Clojure in an idiomatic way, regardless of this specific stylistic question.
The most analogous thing that I can think of in Clojure to a "statement that does nothing" from imperative programming would be a function that does nothing. There are a couple of built-ins that can help you here: identity is a single-arg function that simply returns its argument, and constantly is a higher-order function that accepts a value, and returns a function that will accept any number of arguments and return that value. Both are useful as placeholders in situations where you need to pass a function but don't want that function to actually do much of anything. A simple example:
(defn twizzle [x]
(let [f (cond (even? x) (partial * 4)
(= 0 (rem x 3)) (partial + 2)
:else identity)]
(f (inc x))))
Rewriting this function to "do nothing" in the default case, while possible, would require an awkward rewrite without the use of identity.
I want to keep a list of normalizing functions for a text. How do I store .toLowercase?
I was thinking of something like this:
(def normalizing-functions (list remove-punctuations .toLowerCase))
It looks like your making a list of functions to apply to something on a regular basis. the java method is not quite a clojure function in this sense though its really
easy to wrap it up just like you would if you where going to feed it to the map function.
#(. tolowercase %)
Rather than keeping them in a list which you'll have to unpack some way later, it may just be easier to wrap .toLowerCase in a clojure function (edit: using my or Arthur's syntax) and compose it with the functions you're planning to use to normalize your data using comp:
user=> (defn remove-punctuation [st] ...removing puncutation mechanics...)
user=> (defn lower-case [st]
(.toLowerCase st))
user=> ((comp remove-punctuation lower-case) "HELLO THERE!")
"hello there"
user=> (defn normalize-data [data]
((comp remove-punctuation lower-case) data))
The memfn macro will do this in a more readable way.
(def f (memfn toLowerCase))
(f "Hello")
would return "hello". (doc memfn) has the details.