I have come across a function in Clojure named condp which takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either.Two examples of it's usage are:
(defn foo [x]
(condp = x
0 "it's 0"
1 "it's 1"
2 "it's 2"
(str "else it's " x)))
(foo 0) => "it's 0"
(defn baz [x]
(condp get x {:a 2 :b 3} :>> (partial + 3)
{:c 4 :d 5} :>> (partial + 5)
-1))
(baz :b) => 6
The first example is very understandable, but the scond usage of the function uses a special syntax in the form of :>> which I have not seen before. Can anybody explain why this keywords is used with the condp function and whether it has uses outside the scope of condp.
Let's have a look at condp documentation:
=> (doc condp) ; in my REPL
-------------------------
clojure.core/condp
([pred expr & clauses])
Macro
Takes a binary predicate, an expression, and a set of clauses.
Each clause can take the form of either:
test-expr result-expr
test-expr :>> result-fn
Note :>> is an ordinary keyword.
For each clause, (pred test-expr expr) is evaluated. If it returns
logical true, the clause is a match. If a binary clause matches, the
result-expr is returned, if a ternary clause matches, its result-fn,
which must be a unary function, is called with the result of the
predicate as its argument, the result of that call being the return
value of condp. A single default expression can follow the clauses,
and its value will be returned if no clause matches. If no default
expression is provided and no clause matches, an
IllegalArgumentException is thrown.
So, :>> is just an ordinary keyword used in condp macro as some kind of syntactic sugar:
=> (class :>>)
clojure.lang.Keyword
=> (name :>>)
">>"
:>> keyword is used in condp macro to indicate that the following thing is a function to be called on the result of (pred test-expr expr) call, rather than the value to be returned.
Related
Is there a way in lisp-family (EDIT: lisp-1) languages to differentiate symbol evaluation with regard to its position as as function or as an argument (i.e. override eval of this symbol in regard to when it is evaluated)?
As an example (I don't need this functionality, this is an example), I wanted to implement some sort of infix operation on a set of objects, which can be called by an object itself
(my-obj some-operator arg1 ...)
which will actually apply function some-operator to my-obj and arguments.
But when this object is used anywhere else in code as an argument, like:
(some-function my-obj &args...)
it will evaluate to a value of my-obj.
Thank you.
In Racket it is possible to do a couple things in this spirit:
You can define a struct and give it a prop:procedure. When an instance of the struct is supplied in an application, the procedure will be called.
You can override the default #%app with your own function, to redefine application generally, and including things that aren't structs. For example you can do things like emulate Clojure's (key map) syntax, so that ('symbol dict) is actually (hash-ref dict 'symbol).
Being a lisp-1 basically means that you do not evaluate the first slot of a combination any differently than any other slots. To get such behavior for code you write anyway, you need to transform it to code that does what you want under the rules of a lisp-1. Thus you will need to implement a macro that performs this transformation.
For example if you want infix operators you need to write some macro infix and then perhaps you could write:
(infix (+ - * /) (1 + 2 * 5 - 3) / 4)
and have it evaluate to 2.
I have been playing around with the idea of a default procedure in a OO CLOS-like Scheme. eg. that writing
(obj 5 10)
Would validate obj and apply it with arguments if obj is a procedure or method, but if it isn't it would be the same as the default dispatcher eg.
(default-dispatcher obj 5 10)
In such Scheme one could make vector accessors:
(define-method default-dispatcher
"Default dispatcher for vectors"
([obj %vector] [index %number]) -> (vector-ref obj index)
([obj %vector] [index %number] value) -> (vector-set! obj index value)
(args ...) -> (error "No such method"))
; example usage
(define vec (vector 4 5 6 7))
[vec 1] ; => 5
[vec 1 10]
[vec 1] ; => 10
In Racket this is possible by changing the languages #%app syntax.
In the TXR Lisp dialect, the problem is approached from the other end. Starting with Lisp-2 dialect as a basis, can we robe ourselves with some of the expressivity advantages of a Lisp-1 dialect, like eliminating the (function ...), #' and funcall noise from programs that make extensive use of higher order functions?
The design is centered around a special operator called dwim, which stands for either "Do What I Mean" or "Dispatch, in a Way that is Intelligent and Meaningful".
Invocations of the dwim operator are sugared over using square brackets, which are called "DWIM Brackets"
The dwim operator isn't just a macro over Lisp-2; it actually changes the name lookup rules. When we have
(dwim a b c (d e f) g)
Or equivalently:
[a b c (d e f) g]
all of the argument forms which are symbolic (a, b, c and g) are resolved using a special rule which conflates together the function and variable namespaces. This is built into the heart of the language. The operator has direct access to the environment to make this possible.
The special treatment does not recurse into (d e f), which is an ordinary Lisp-2 form. You have to put the DWIM Brackets on that if you want the semantics.
Also, the dwim operator is properly handled by macro expansion. For instance, given:
(symacrolet ((localfun whatever))
(flet ((localfun () ...)))
[a b c localfun] ;; refers to the flet as a function object!
(a b c localfun))) ;; refers to the symbol macro!
The macro expander knows about dwim and its semantics, and so it considers the possibility that localfun refers to the function and variable namespace. The closest lexical binding in either namespace is the flet and so the symbol macro expansion is suppressed (shadowed).
The dwim semantics is implicitly used in the partial evaluating op macro and its "cousins" derived from it.
Range Extraction task from Rosetta Code:
(defun range-extract (numbers)
`#{(mapcar [iff [callf > length (ret 2)]
(ret `#[#1 0]-#[#1 -1]`)
(ret `#{#1 ","}`)]
(mapcar (op mapcar car)
(split [window-map 1 :reflect
(op list #2 (- #2 #1))
(sort (uniq numbers))]
(op where [chain second (op < 1)])))) ","}`)
Y Combinator:
;; The Y combinator:
(defun y (f)
[(op #1 #1)
(op f (op [##1 ##1]))])
;; The Y-combinator-based factorial:
(defun fac (f)
(do if (zerop #1)
1
(* #1 [f (- #1 1)])))
;; Test:
(format t "~s\n" [[y fac] 4])
Moreover, various useful things are function callable in TXR Lisp. For instance, every sequence (list, vector or character string) is regarded as a function which maps numeric indices to elements. Thus we can do:
(mapcar "abc" #(2 1 0)) -> #(#\c #\b #\a)
The accepted answer describes a Racket mechanism for treating structures as functions. TXR has this in the form of lambda methods. This is demonstrated in the "OOP-Based" solution to the Accumulator Factory task in Rosetta:
(defstruct (accum count) nil
(count 0))
(defmeth accum lambda (self : (delta 1))
(inc self.count delta))
We can instantiate a (new (accum 9)) which will produce the values 10, 11, 12, ... when invoked as a function. An optional delta argument can be supplied for an increment other than 1:
(let ((acc (new (accum 0))))
(list [acc 5] [acc 5] [acc])) -> (5 10 11)
I feel curious about clojure's lazy sequence. In REPL, I defined a variable foo:
user> (def foo (map println [1 2 3]))
#'user/foo
At the first time evaluating foo, it seems to work:
user> foo
1
2
3
(nil nil nil)
But after the first time, why it becomes lazy?
user> foo
(nil nil nil)
println is not a pure function, what you're seeing in the first time you evaluate foo is the side effect of println. When you evaluate foo for the second time println is not called again, because the result of (map println [1 2 3]) is cached.
And you can see that map is lazy because when you defined foo nothing gets printed in the console. Only when evaluating foo something is printed.
Please see Laziness in Clojure.
If you use a pure function like inc:
(def foo (map inc [1 2 3]))
> foo
(2 3 4)
> foo
(2 3 4)
The result is always the same without any side effects. map, filter, etc in Clojure are designed to be used with pure functions but the language doesn't forbid you from using them with functions with side effects. In Haskell, for example you can't even write an equivalent expression, the code won't compile.
Collections hold values. The value returned by println is nil. The side-effect of println is to make something show up on your screen.
The values created by mapping println are stored in your var. This is a lazy-seq of nil values, which were returned by println.
Just to elaborate on your question.
println is only having a side effect on the *out* stream which is bound by default to the standard output.
You can have both the printing and some value returned from the function you map, e.g.
user> (defn print-and-inc [n]
(do
(println "called with n= " n)
(inc n)))
#'user/print-and-inc
do will execute each expression in sequence and return the result of the last, (inc n) in this case.
If you define now foo as a mapping of print-and-inc over a vector of int
user> (def foo (map print-and-inc [1 2 3 4 5]))
#'user/foo
user>
user> foo
called with n= 1
called with n= 2
called with n= 3
called with n= 4
called with n= 5
(2 3 4 5 6)
user>
user> foo
(2 3 4 5 6)
And you see the lazyness of map, since the printing occurs only the first time foo is called. But now foo holds the results which are the incremented values of the initial collection.
Note : this can be used to log/trace infos into your code, but there is a standard library tools.logging
In addition to what has been pointed out by others, note that experimenting with laziness within the repl is a little problematic. Lazy sequences don't actually have values until they are realised by some action that uses the value. The repl has an implicit doall to do this when printing results. This means the sequence is often realised when your using it in the repl, but may not be when using it in your real code. When you run your code, you get an unexpected result because the sequence has not been realised at a point where you expected it to be because the repl implicit doall has not been called. As an example of how this can cause moments of confusion, have a look at http://nicksellen.co.uk/2013/10/26/clojure-lazy-repl.html
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.
I have written a program in clojure but some of the functions have no arguments. What would be the advantages of coding such functions as a "def" instead of a "defn" with no arguments?
(def t0 (System/currentTimeMillis))
(defn t1 [] (System/currentTimeMillis))
(t1)
;; => 1318408717941
t0
;; => 1318408644243
t0
;; => 1318408644243
(t1)
;; => 1318408719361
defs are evaluated only once whereas defns (with or without arguments) are evaluated (executed) every time they are called. So if your functions always return the same value, you can change them to defs but not otherwise.
(defn name ...) is just a macro that turns into (def name (fn ...) anyway, not matter how many parameters it has. So it's just a shortcut. See (doc defn) for details.
https://clojure.org/guides/learn/functions#_defn_vs_fn
The def special form creates a Var object identified by a symbol given as its first argument. Identification is created by associating the given symbol with a Var in a map called namespace.
The Var holds a reference to some value, which could be expressed (among others):
as a constant form, which always evaluates to its own value:
(def x 1)
x
;; => 1 ; x holds a reference to a number 1
as a function form, which at first is evaluated to its resulting value:
(def x (+ 2 2))
x
;; => 4 ; x holds a reference to a number 4
as a Java method form, which at first is evaluated to its resulting value:
(def x (System/currentTimeMillis))
x
;; => 1417811438904 ; x holds a reference to a number 1417811438904
x
;; => 1417811438904 ; still the same number!
as a lambda form (anonymous function), which at first is evaluated to a function object:
(def x (fn [] (System/currentTimeMillis)))
x
;; => #<user$x user$x#4c2b1826>
(x) ; function form, function evaluated
;; => 1417811438904
(x) ; function form, function evaluated
;; => 1417812565866
There is a simple rule for all of the above. In case of def special form an S-expression given as its second argument is recursively evaluated before binding is created, so the resulting Var is bound to the result of this evaluation.
Even fn is evaluated before, but its resulting value is a function object that holds a code. This code will be executed (and evaluated) each time the function is called. That's why there are different results.
The defn macro is just like def but internally it creates an anonymous function and then binds a Var object to it. Its second argument becomes a body of this function and it's not evaluated in a "regular" way. One could also say it is evaluated but as a lambda form – the result of the evaluation is a function object, not the result of some instant calculation.
So writing:
(defn fun [] 1)
Is synonymous to:
(def fun (fn [] 1))
The following expression in clojure works great:
(doseq [x '(1 2 3 4)] (println x))
This one gives me a nullpointer:
(doseq [x '(1 2 3 4)] ((println x)(println "x")))
It produces the following output:
user=> (doseq [x '(1 2 3 4)] ((println x)(println "x")))
1
x
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4639)
at clojure.core$eval__5182.invoke(core.clj:1966)
at clojure.main$repl__7283$read_eval_print__7295.invoke(main.clj:180)
at clojure.main$repl__7283.doInvoke(main.clj:197)
at clojure.lang.RestFn.invoke(RestFn.java:426)
at clojure.main$repl_opt__7329.invoke(main.clj:251)
at clojure.main$legacy_repl__7354.invoke(main.clj:292)
at clojure.lang.Var.invoke(Var.java:359)
at clojure.main.legacy_repl(main.java:27)
at clojure.lang.Repl.main(Repl.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at jline.ConsoleRunner.main(ConsoleRunner.java:69)
Caused by: java.lang.NullPointerException
at user$eval__266.invoke(NO_SOURCE_FILE:26)
at clojure.lang.Compiler.eval(Compiler.java:4623)
... 14 more
nil
Just adding an extra set of parentheses around the body of a doseq gives me that nullpointer.
What am I doing wrong?
Well, you already figured out the solution, so just a few hints to explain the behavior:
In Clojure (just like in Lisp, Scheme, etc) everything is an expression and an expression is either an atom or a list. With regard to lists, the Clojure manual says
Non-empty Lists are considered calls
to either special forms, macros, or
functions. A call has the form
(operator operands*).
In your example, the body ((println x) (println x)) is a list and the operator is itself an expression which Clojure has to evaluate to obtain the actual operator. That is, you're saying "evaluate the first expression and take its return value as a function to invoke upon the second expression". However, println returns, as you noticed, only nil. This leads to the NullPointerException if nil is interpreted as an operator.
Your code works with (do (println x) (println x)) because do is a special form which evaluates each expression in turn and returns the value of the last expression. Here do is the operator and the expressions with println ar the operands.
To understand the usefulness of this behavior, note that functions are first-class objects in Clojure, e.g., you could return a function as a result from another function. For instance, take the following code:
(doseq [x '(1 2 3 4)] ((if (x > 2)
(fn [x] (println (+ x 2)))
(fn [x] (println (* x 3)))) x))
Here, I am dynamically figuring out the operator to invoke upon the element in the sequence. First, the if-expression is evaluated. If x is larger than two, the if evalutes to the function that prints x + 2, else it evaluates to the function that prints x * 3. This function is than applied to the x of the sequence.
I see you've already realised the problem, however please note you don't need a do:
(doseq [x '(1 2 3 4)] (println x) (println "x"))
doseq is (as the name suggests) a do already :)