clojure way on flow control statement - clojure

Suppose I have a python function like this:
def required(value):
if value is None:
throw Exception
if isintance(value, str) and not value:
throw Exception
return value
Basically I want to check if the value is null or not. If the value is a String, also check if it's empty or not.
What is the clojure way of doing something like this?

The Clojure way of doing something like this is not to throw exceptions or so. The idiomatic way would be something that returns nil and nothing else.
So my advise: Do this without exceptions.
Your function will then look like this:
(defn required [value]
(when (string? value)
value))
It checks for the type of value and returns nil if it is not a String. Otherwise return your value.
Or if you want an error message in your terminal:
(defn required [value]
(if (string? value)
value
(println "Value must be a String.")))
Note that println prints the String and then returns again nil.

Preconditions would do the trick nicely in this instance. Otherwise use Clojure's control flow special forms/macros, e.g. if, cond with throw.
user=> (defn required
[value]
{:pre [(string? value) (not-empty value)]}
value)
#'user/required
user=> (required nil)
AssertionError Assert failed: (string? value) user/required ...
user=> (required "")
AssertionError Assert failed: (not-empty value) ...
user=> (required "foo")
"foo"

Both previous answers are slightly wrong on the assertions. I what Budi is asking for is:
(defn required [value]
(if (or (nil? value)
(and (string? value) (clojure.string/blank? value)))
(throw (Exception.))
value))

A. Webb is right on the money in that pre-conditions are a great, idiomatic way to represent what you're trying to do here.
For what it's worth, here is how you would do the same thing using explicit exception-throwing and a condition statement:
(defn required [value]
(cond
(not (string? value))
(throw (IllegalArgumentException. "Value must be a string."))
(empty? value)
(throw (IllegalArgumentException. "String cannot be empty."))
:else
value))
Or, perhaps more idiomatically, handle the errors first using when, then return the value at the end:
(defn required [value]
(when (not (string? value))
(throw (IllegalArgumentException. "Value must be a string.")))
(when (empty? value)
(throw (IllegalArgumentException. "String cannot be empty.")))
value)

Related

clojure function call hides type information

I have a small function used for debugging:
(set! *warn-on-reflection* true)
(defn debug [x] (doto x (->> println :>)))
When I call my function in a loop, I get the following reflection warning:
(loop [i 5] (when (pos? i) (recur (debug (dec i)))))
form-init14269737395101875093.clj:1 recur arg for primitive local: i is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: i
I want to solve the reflection warning. How can I make my function "inherit" the type information from the parameter without explicitly specifying it or replacing it with a macro?
Here is a way that works:
(loop [i (Integer. 5)]
(when (pos? i)
(recur (debug (dec i)))))
with a warning-free result:
lein test tst.demo.core
4
3
2
1
0
It looks like using just plain 5 causes the compiler to use a primitive, which can't be type hinted. Explicitly creating an Integer object sidesteps the problem. I also tried (int 5) which didn't work.
Is there a reason you want to turn on reflection warnings? I normally never use them, especially for debugging.
Update
Note that if you wrap the code in a function like so:
(defn stuff
[arg]
(loop [i arg]
(when (pos? i)
(recur (debug (dec i))))))
there is no problem calling (stuff 5) since function args must always be passed as objects (via autoboxing if necessary).
the problem is that the return type of debug can't be deduced.
this is usually solved with type hints
in your case the following should do the trick:
(defn debug ^long [x] (doto x (->> println :>)))
user> (loop [i 5] (when (pos? i) (recur (debug (dec i)))))
4
3
2
1
0
nil
If, for whatever the reason, you do not want to use a macro, you may want to have a look at definline which seems to preserve type information:
(definline debug2 [x] (doto x (->> println :>)))
The call below, for instance, does not result in a reflection warning:
(.add (debug2 (ArrayList.)) 5)
My initial thought would have been to use a Java class with overloaded methods to achieve something along these lines, of which one method would take a generic argument T and return a T. In addition to this generic method, you would have had to overload that method for the few primitive types because generics only work with boxed values AFAIK. You could then reuse the class below for your debugging purposes:
import clojure.lang.IFn;
public class PassThrough {
private IFn _fn;
public PassThrough(IFn fn) {
_fn = fn;
}
public <T> T invoke(T x) {
_fn.invoke(x);
return x;
}
public long invoke(long x) {
_fn.invoke(x);
return x;
}
public double invoke(double x) {
_fn.invoke(x);
return x;
}
}
This will not work for reference types, though, because of type erasure. So if I would do something like this, I would still get a warning:
(defn debug [x] (doto x (->> println :>)))
(def pt-debug (PassThrough. debug))
(.add (.invoke ^PassThrough pt-debug (ArrayList.)) 9) ;; <-- Reflection warning here when calling .add

Clojure function/macro to apply functions until one returns something other than nil

Currently I have some code like this:
(defn compute-issue [some args] (or (age-issue some args) (name-issue some args)))
More issue types are coming.
Is there something like this:
(defn compute-issue [some args] (first-not-nil [age-issue name-issue] some args))
; Where first-not-nil would be something like
(defn first-not-nil [fs & args]
(if (empty? fs)
nil
(let [result (apply (first fs) args)]
(if (nil? result)
(recur (rest fs) args)
result))))
I'm new to Clojure. Am I reinventing an existing function?
There is a similar function some-fn in clojure.core:
Takes a set of predicates and returns a function f that returns the first logical true value
returned by one of its composing predicates against any of its arguments, else it returns
logical false. Note that f is short-circuiting in that it will stop execution on the first
argument that triggers a logical true result against the original predicates.
The key differences are some-fn returns another function for the actual function application, and that function will also discard false results, which it sounds like you may not want. This is another simple way to phrase it:
(defn first-not-nil [fs & args]
(first
(for [f fs
:let [r (apply f args)]
:when (some? r)]
r)))

In defn macro, what does an argument starting with caret before the name of a function mean?

In a function definition:
(defn ^boolean =
;;other arities omitted...
([x y]
(if (nil? x)
(nil? y)
(or (identical? x y)
^boolean (-equiv x y))))
what does the ^boolean part in function definition mean? Does it only extend the metadata and signify the type of return, or does it have any deeper meaning? In other words, does it add any more value than simply making the code more self-described?
It is a type hint. See
https://www.safaribooksonline.com/library/view/clojure-programming/9781449310387/ch09s05.html
http://clojure-doc.org/articles/language/functions.html
or your favorite book. PLEASE NOTE: the compiler does not enforce that the actual type matches the type hint! Example w/o type hint:
(defn go []
"banana" )
(println (go))
;=> banana
(defn ^long go []
"banana" )
(println (go))
;=> Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number,

constantly function not workint in syntax quote

If I do this:
(eval (let [f (fn [& _] 10)]
`(~f nil)))
It returns 10 as expected.
Although if I do this:
(eval (let [f (constantly 10)]
`(~f nil)))
It throws an exception:
IllegalArgumentException No matching ctor found for
class clojure.core$constantly$fn__... clojure.lang.Reflector.invokeConstructor
Since both are equivalent why is the code with constantly not working?
This question has two answers, to really get it.
First, to clarify why your eval form is not giving you the expected result in the second case, note that f has been assigned to be equal to the function (fn [& _] 10). This means when that form is evaluated, the function object is again evaluated--probably not what you had in mind.
tl;dr: f is evaluted when it is bound, and again (with ill-defined results) when the form you create is eval'd.
The reason why one (the anonymous function) works, while the other fails means we have to look at some of the internals of the evaluation process.
When Clojure evaluates an object expression (like the expression formed by a function object), it uses the following method, in clojure.lang.Compiler$ObjExpr
public Object eval() {
if(isDeftype())
return null;
try
{
return getCompiledClass().newInstance();
}
catch(Exception e)
{
throw Util.sneakyThrow(e);
}
}
Try this at the REPL:
Start with an anonymous function:
user=> (fn [& _] 10)
#<user$eval141$fn__142 user$eval141$fn__142#2b2a5dd1>
user=> (.getClass *1)
user$eval141$fn__142
user=> (.newInstance *1)
#<user$eval141$fn__142 user$eval141$fn__142#ee7a10e> ; different instance
user=> (*1)
10
Note that newInstance on Class calls that class' nullary constructor -- one that takes no arguments.
Now try a function that closes over some values
user=> (let [x 10] #(+ x 1))
#<user$eval151$fn__152 user$eval151$fn__152#3a565388>
user=> (.getClass *1)
user$eval151$fn__152
user=> (.newInstance *1)
InstantiationException user$eval151$fn__152 [...]
Since the upvalues of a closure are set at construction, this kind of function class has no nullary constructor, and making a new one with no context fails.
Finally, look at the source of constantly
user=> (source constantly)
(defn constantly
"Returns a function that takes any number of arguments and returns x."
{:added "1.0"
:static true}
[x] (fn [& args] x))
The function returned by constantly closes over x so the compiler won't be able to eval this kind of function.
tl;dr (again): Functions with no upvalues can be evaluated in this way and produce a new instance of the same function. Functions with upvalues can't be evaluated like this.

What is the difference between seq and seq?

-------------------------
clojure.core/seq
([coll])
Returns a seq on the collection. If the collection is
empty, returns nil. (seq nil) returns nil. seq also works on
Strings, native Java arrays (of reference types) and any objects
that implement Iterable.
-------------------------
clojure.core/seq?
([x])
Return true if x implements ISeq
-----
Obviously empty? is based on seq. what is the difference between empty? and nil? I'm soooo confused.
clojure.core/empty?
([coll])
Returns true if coll has no items - same as (not (seq coll)).
Please use the idiom (seq x) rather than (not (empty? x))
And more:
(not (seq? ())) ;;false
(not (seq ())) ;;true
(not nil) ;;true
seq converts collection to sequence and returns nil if the collection is empty; also returns nil if the argument is nil.
seq? returns true if the argument is a sequence (implements the ISeq interface).
empty? will return true if the argument is either nil or an empty collection.
nil? will return true if the argument is nil.
I guess the bit about the (seq x) idiom in the docstring for empty? applies to common practice of using if-let like so:
(defn print-odd-numbers [coll]
(if-let [x (seq (filter odd? coll))]
(println "Odd numbers:" x)
(println "No odd numbers found.")))