define-values macros in Clojure - clojure

Is it possible to write a define-values macros in Clojure?
Racket language provides such a thing like define-values form which acts in this way
(define -values '(a b c) (1 2 3))
Where a, b, c are global variables now.
How can I do it in Clojure?
(defmacro defvar [x y]
`(let [a# ~x
b# ~y]
(def b# a#)))
(println (defvar 'a 2))
=> #'user/b__2__auto__
;;;It binds the value to auto generated symbol

define-values doesn't make any sense in Clojure. It makes sense in Racket because values lets one expression evaluate to multiple values. In Clojure, an expression always evaluates to exactly one value: there's no values to extract into definitions.
Of course, you can write a macro def-several-things such that
(def-several-things [x y] [1 2])
expands to
(do (def x 1)
(def y 2))
but this is less readable, not more, so nobody does it.

Related

How to bind function variables to current scope of execution in Clojure?

Given:
(defn some-fn
[]
(let [a 1
b 2
c (+ a b)]
(println c)))
and given that there are multiple such functions, where:
a and b have different values;
c is always equal to (+ a b)
is there a way to extract c without making it a function, which accepts a and b as arguments. So, I don't want:
(defn c-outside
[a b]
(+ a b))
(defn some-fn
[]
(let [a 1
b 2
c (c-outside a b)]
(println c)))
but ideally, something like:
(defn c-outside
[]
(+ a b))
(defn some-fn
[]
(let [a 1
b 2
c (c-outside)]
(println c)))
Is there a way to make c-outside look for the values of a and b in the context, in which it is called? Do I need a macro for that?
there is a way to do it using dynamic bindings:
user> (def ^:dynamic a 10)
#'user/a
user> (def ^:dynamic b 20)
#'user/b
user> (defn c-outside []
(+ a b))
user> (defn some-fn []
(binding [a 1
b 2]
(c-outside)))
#'user/some-fn
user> (some-fn)
;;=> 3
user> (c-outside)
;;=> 30
the trick is that you can temporarily rebind some dynamic vars for the 'duration' of some scope.
This is mostly used in clojure for concurrent programming: the dynamically bound vars keep their values in the threads, spawned from inside the block (as far as i remember)
Otherwise, i see more potential harm from this feature, than the profit, since it obscures the code, adding some unneeded implicit behaviour.
Also as far as i know, this is one of the most arguable features in lisps (in common lisp, to be more specific)
Almost in any case it is better to pass a and b values explicitly to the summing function, since it makes in clean and therefore testable, and helps to reason about it's correctness and performance, and increases readability
you could also think of using macro for that, like this for example:
user> (defmacro c-outside-1 []
`(+ ~'x ~'y))
#'user/c-outside-1
user> (defn some-fn-1 []
(let [x 1
y 2]
(c-outside-1)))
#'user/some-fn-1
user> (some-fn-1)
;;=> 3
but that idea is obviously even worse.

Removing the nth element of a vector in clojure

I'm trying to do a really basic problem in clojure and having some trouble wrapping my head around how vectors/lists work.
First off when I am defining the arguments of a function that has a vector as an argument, how do you represent that as an argument.
Would you just have it as a single variable say
(defn example [avector] (This is where the function goes) )
Or do you have to list each element of a vector or list beforehand?
(defn example [vectorpart1 vectorpart2 vectorpart3 vectorpart4 ] (This is where the function goes) )
Also, in terms of vectors and lists, does anyone know of commands that allow you to figure out the length of a vector or get the first/last/or nth element?
To remove the element at index n from vector v:
(defn remove-indexed [v n]
(into (subvec v 0 n) (subvec v (inc n))))
For example,
(remove-indexed (vec (range 10)) 5)
;[0 1 2 3 4 6 7 8 9]
Lots can go wrong:
v might not be a vector.
n might not be a whole number.
n might be out of range for v (we require (contains? v n).
Clojure detects all these errors at run time. A statically typed language would detect 1 and 2 but not 3 at compile time.
Your first example defines a function that takes a single argument, regardless of type. If you pass a vector then that argument will be set to a vector.
(example [1 2 3 4]) ;; (= avector [1 2 3 4])
Your second example defines a function which takes four arguments. You need to pass four separate values for calls to this function to be valid.
(example [1] [2] [3] [4])
;; (= vectorpart1 [1])
;; (= vectorpart2 [2])
;; (= vectorpart3 [3])
;; (= vectorpart4 [4])
It sounds like you might be thinking about the destructuring syntax, which allows you to destructure values directly from an argument vector.
(defn example [[a b c d]]
())
The literal vector syntax in the argument definition describes a mapping between the items in the first argument and symbols available in the function scope.
(example [1 2 3 4])
;; (= a 1)
;; (= b 2)
;; (= c 3)
;; (= d 4)
The other function that also sits in this space is apply. Apply takes a list or vector of arguments and calls a function with them in-place.
(defn example [a b c]
(assert (= a 1))
(assert (= b 2))
(assert (= c 3)))
If we call this function with one vector, you'll get an arity exception.
(example [1 2 3])
;; ArityException Wrong number of args (1) passed ...
Instead we can use apply to pass the vector as arguments.
(apply example [1 2 3])
;; no errors!
You'll find all the methods you need to work with vectors in the Clojure docs.
If you want to remove a specific element, simply take the elements before it and the elements after it, then join them together.
(def v [1 2 3])
(concat (subvec v 0 1) (subvec v 2))
The short answer is that your first example is correct. You don't want to have to name every piece of your vector because you will commonly work with vectors of indeterminate length. If you want to do something with that vector where you need its parts to be assigned, you can do so by destructuring.
The slightly longer answer is that the list of parameters sent into any clojure defn already is a vector. Notice that the parameter list uses [] to wrap its list of args. This is because in Clojure code and data are the same thing. From this article...
Lisps are homoiconic, meaning code written in the language is encoded as data structures that the language has tools to manipulate.
This might be more than you're looking for but it's an important related concept.
Here'a a quick example to get you going... Pass a vector (of strings in this case) to a functions and it returns the vector. If you map over it however, it passes the contents of the vector to the function in succession.
user=> (def params ["bar" "baz"])
#'user/params
user=> (defn foo [params] (println params))
#'user/foo
user=> (foo params)
[bar baz]
nil
user=> (map foo params)
bar
baz
(nil nil)
Additionally, look at the Clojure cheatsheet to find more about things you can do with vectors (and everything else in Clojure).

In clojure, how to map a sequence and create a hash-map

In clojure, I would like to apply a function to all the elements of a sequence and return a map with the results where the keys are the elements of the sequence and the values are the elements of the mapped sequence.
I have written the following function function. But I am wondering why such a function is not part of clojure. Maybe it's not idiomatic?
(defn map-to-object[f lst]
(zipmap lst (map f lst)))
(map-to-object #(+ 2 %) [1 2 3]) => {1 3, 2 4, 3 5}
Your function is perfectly idiomatic.
For a fn to be part of core, I think it has to be useful to most people. What is part of the core language and what is not is quite debatable. Just think about the amount of StringUtils classes that you can find in Java.
My comments were going to get too long winded, so...
Nothing wrong with your code whatsoever.
You might also see (into {} (map (juxt identity f) coll))
One common reason for doing this is to cache the results of a function over some inputs.
There are other use-cases for what you have done, e.g. when a hash-map is specifically needed.
If and only if #3 happens to be your use case, then memoize does this for you.
If the function is f, and the resultant map is m then (f x) and (m x) have the same value in the domain. However, the values of (m x) have been precalculated, in other words, memoized.
Indeed memoize does exactly the same thing behind the scene, it just doesn't give direct access to the map. Here's a tiny modification to the source of memoize to see this.
(defn my-memoize
"Exactly the same as memoize but the cache memory atom must
be supplied as an argument."
[f mem]
(fn [& args]
(if-let [e (find #mem args)]
(val e)
(let [ret (apply f args)]
(swap! mem assoc args ret)
ret))))
Now, to demonstrate
(defn my-map-to-coll [f coll]
(let [m (atom {})
g (my-memoize f m)]
(doseq [x coll] (g x))
#m))
And, as in your example
(my-map-to-coll #(+ 2 %) [1 2 3])
;=> {(3) 5, (2) 4, (1) 3}
But note that the argument(s) are enclosed in a sequence as memoize handles multiple arity functions as well.

Clojure Higher-order functions take function arguments, but what is the syntax?

I am doing the closure tutorial at http://clojurescriptkoans.com and I am stuck here: http://clojurescriptkoans.com/#functions/9
It looks like this
Higher-order functions take function arguments
(= 25 ( _ (fn [n] (* n n))))
I am supposed to fill in something at the underscore to make the expression true. I have no clue what to do.
The syntax simply consists of binding the function, and then calling it.
Since this is an exercise, I will show a similar situation rather than showing the exercise's solution:
user> ((fn [f] (f "abc")) (fn [s] (str s s s)))
"abcabcabc"
here I bind the argument of the first function to f, and call f with the argument "abc".
or you can use the short-hand notation:
#(%1 5)
Higher order functions takes functions as arguments.
Defining two functions
user=> (defn multiply [n] (* n n))
#'user/multiply
user=> (defn add [n] (+ n n))
#'user/add
Defining higher order function
user=> (defn highorderfn [fn number] (fn number))
#'user/highorderfn
Calling the higher order function
user=> (highorderfn multiply 5)
25
user=> (highorderfn add 5)
10

Higher-order functions in Clojure

Clojure is awesome, we all know this, but that's not the point. I'm wondering what the idiomatic way of creating and managing higher-order functions in a Haskell-like way is. In Clojure I can do the following:
(defn sum [a b] (+ a b))
But (sum 1) doesn't return a function: it causes an error. Of course, you can do something like this:
(defn sum
([a] (partial + a))
([a b] (+ a b)))
In this case:
user=> (sum 1)
#<core$partial$fn__3678 clojure.core$partial$fn__3678#1acaf0ed>
user=> ((sum 1) 2)
3
But it doesn't seem like the right way to proceed. Any ideas?
I'm not talking about implementing the sum function, I'm talking at a higher level of abstraction. Are there any idiomatic patterns to follow? Some macro? Is the best way defining a macro or are there alternative solutions?
Someone has already implememented this on the Clojure group. You can specify how many args a function has, and it will curry itself for you until it gets that many.
The reason this doesn't happen by default in Clojure is that we prefer variadic functions to auto-curried functions, I suppose.
I've played a bit with the functions suggested by amalloy. I don't like the explicit specification of the number of argument to curry on. So I've created my custom macro. This is the old way to specific an high order function:
(defn-decorated old-sum
[(curry* 3)]
[a b c]
(+ a b c))
This is my new macro:
(defmacro defn-ho
[fn-name & defn-stuff]
(let [number-of-args (count (first defn-stuff))]
`(defn-decorated ~fn-name [(curry* ~number-of-args)] ~#defn-stuff)))
And this is the new implicit way:
(defn-ho new-sum [a b c] (+ a b c))
As you can see there is no trace of (curry) and other stuff, just define your currified function as before.
Guys, what do you think? Ideas? Suggestions?
Bye!
Alfedo
Edit: I've modified the macro according the amalloy issue about docstring. This is the updated version:
(defmacro defhigh
"Like the original defn-decorated, but the number of argument to curry on
is implicit."
[fn-name & defn-stuff]
(let [[fst snd] (take 2 defn-stuff)
num-of-args (if (string? fst) (count snd) (count fst))]
`(defn-decorated ~fn-name [(curry* ~num-of-args)] ~#defn-stuff)))
I don't like the if statement inside the second binding. Any ideas about making it more succint?
This will allow you to do what you want:
(defn curry
([f len] (curry f len []))
([f len applied]
(fn [& more]
(let [args (concat applied (if (= 0 (count more)) [nil] more))]
(if (< (count args) len)
(curry f len args)
(apply f args))))))
Here's how to use it:
(def add (curry + 2)) ; read: curry plus to 2 positions
((add 10) 1) ; => 11
The conditional with the [nil] is meant to ensure that every application ensures some forward progress to the curried state. There's a long explanation behind it but I have found it useful. If you don't like this bit, you could set args as:
[args (concat applied more)]
Unlike JavaScript we have no way of knowing the arity of the passed function and so you must specify the length you expect. This makes a lot of sense in Clojure[Script] where a function may have multiple arities.