I want to make a function that I can pass a map of functions and apply those functions to another map--think of it as coercing a map of strings to arbitrary types. (I'd love to do something higher level like fmap, but one step at a time, right?)
So along the way I figure I will need to do something like
user=> (apply Long. "1")
But I get this when I try:
CompilerException java.lang.ClassNotFoundException: Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:1)
I can certainly find the class this way:
user=> (Long. "1")
1
If I do
user=> (apply #(Long. %1) "1")
I see
IllegalArgumentException No matching ctor found for class java.lang.Long clojure.lang.Reflector.invokeConstructor (Reflector.java:183)
which is confusing because I just used the constructor. I think I did, anyway. It even finds the right class, just not the constructor of the class.
This also fails, though differently:
user=> (apply #(new Long. %1) "1")
CompilerException java.lang.ClassNotFoundException: Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:9)
I can get it to not find java.lang.Long, which is interesting:
user=> (apply #(new java.lang.Long. %1) "1")
CompilerException java.lang.ClassNotFoundException: java.lang.Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:9)
This works, though:
user=> (defn l [x] (Long. x))
#'user/l
user=> (apply l ["1"])
1
And I could write my code this way, though it seems a little... off?
Anyway, what's going on here? Why would this make sense?
Java functions, including constructors, are not legal Clojure functions and cannot be passed directly to higher-order-functions like apply unless they are wrapped inside a Clojure function.
Also, note that apply expects an collection of args, as it "unwraps" them from the array. This works for a vector with one string:
(Long. "1") -> 1
(apply #(Long. %) ["1"] ) -> 1
But what you really probably want is mapv or map:
(mapv #(Long. %) ["1" "2" "3"] ) -> [1 2 3]
I'll let you figure out whats wrong with these failing cases:
; failing cases
; (apply Long. ["1"] )
; (apply #(Long. %) ["1" "2" "3"] )
; (apply #(Long. %) "1" "2" ["3"] )
Related
I am going to call the .toUpperCase method within a doto macro like follows but the doto returns the small letters:
(doto (java.lang.String. "clojure")
(.toUpperCase))
returns "clojure". I do the macroexpansion and as the return value is the object created:
(clojure.core/let [G__7359 (java.lang.String. "cojure")] (.toUpperCase G__7359) G__7359)
, but why i don't get the uppercased answer?
doto is part of Clojure's Java interop features. It is designed to make it possible to write java with out soooo darn many parens. so
Foo foo = new Foo;
foo.setX().setY().makeFactory().applyPhaseOfMoon();
which has 8 parens becomes:
(doto foo .setY .makeFactory .applyPhaseOfMoon)
which has a total of two.
In this case if we dig into the expanstion of your example:
user> (doto "hi" .toUpperCase)
"hi"
expands to:
user> (macroexpand-1 '(doto "hi" .toUpperCase))
(clojure.core/let [G__110453 "hi"]
(.toUpperCase G__110453)
G__110453)
where the second line does this:
user> (.toUpperCase "hi")
"HI"
and then throws the answer away and returns the saved value form the start. I personally never see doto used in practice outside of places where people are translating java to clojure inorder to call some API.
From the documentation:
Evaluates x then calls all of the methods and functions with the value
of x supplied at the front of the given arguments. The forms are
evaluated in order. Returns x.
doto returns the original argument, not any the result of functions performed using it. I believe the doto function is generally intended for side-effects. This is why you get the original string back.
What you are looking for is the .. threading macro ( https://clojuredocs.org/clojure.core/_.. ):
Expands into a member access (.) of the first member on the first
argument, followed by the next member on the result, etc. For
instance:
(.. System (getProperties) (get "os.name"))
expands to:
(. (. System (getProperties)) (get "os.name"))
but is easier to write, read, and understand.
In your case:
(doto "clojure" .toUpperCase)
; => "clojure"
(.. "clojure" toUpperCase)
; => "CLOJURE"
I was searching for a Clojure logarithm function and concluded there really isn't one for v1.3+. What took me so long to invoke Math/log was this:
user=> Math/log
CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)
I tried variations like (use 'java.lang.Math) and so forth. It wasn't until I tried an example that I found it's there after all:
user=> (Math/log 10)
2.302585092994046
This must be by design, but what is the reason?
A static method imported from Java is not a Clojure function or any other kind of Clojure object. The compiler reports any misfit as a missing field, even where the context is looking for a function. All of these ...
Math/log
(Math/log)
(map Math/log (range 1 5))
... produce such errors.
For a corresponding Clojure function:
inc returns the function;
(inc) reports ... wrong number of args(0) ...;
(map inc (range 1 5)) returns (2 3 4 5).
You can wrap a Java method as a Clojure one:
(defn log [x] (Math/log x))
... getting the expected result:
(map log (range 1 5))
;(0.0 0.6931471805599453 1.0986122886681098 1.3862943611198906)
The Clojure Java Interop page recommends
(map #(Math/log %) (range 1 5))
... in such cases.
Clojure provides some forms for interoperating with Java classes, methods, and fields. When you access static field in a class, you can do it like this:
user=> Integer/MAX_VALUE
;=> 2147483647
user=> Math/PI
;=> 3.141592653589793
And when you want to invoke static method, you can use the following form
user=> (Math/log 10)
;=> 2.302585092994046
user=> (Math/sin 1)
;=> 0.8414709848078965
When you try to evaluate just Math/log, clojure think it's static field, which is not true.
user=> Math/log
;=> CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math, compiling:(/private/var/folders/jh/q738l9dn0hxg0vvwbty7m5hw0000gp/T/form-init145007798854806400.clj:1:5845)
You can see it from the error message(Unable to find static field:...) that the clojure REPL try to find static field log from Math class, then failed.
In Java, one uses parentheses to invoke a function:
println("hi");
Clojure also uses parentheses to invoke a function, but with a different placement:
(println "hi")
In either Java or Clojure, just typing:
println
is an error, because you don't have the parentheses to indicate a function call.
In your first example, you use the name of the function Math/log, but you had no parentheses to tell the REPL that you wanted to invoke a function.
Also, in Java, parentheses can indicate either a function call or a grouping operator:
println(2 + (3 + 4))
In Clojure, parentheses only indicate function calls, and never indicating simple grouping.
I am creating a Clojure interface to a Java API with a method that returns a java.util.LinkedHashSet.
Firstly, is the idiomatic Clojure way of handling this to convert the LinkedHashSet to a clojure data structure?
Secondly, what is the best method for converting Java collections into Clojure data structures?
There are lots of options, since Clojure plays very nicely with Java collections. It depends on exactly what data structure you want to use in Clojure.
Here's some examples:
;; create a HashSet
(def a (java.util.HashSet.))
(dotimes [i 10] (.add a i))
;; Get all the values as a sequence
(seq a)
=> (0 1 2 3 4 5 6 7 8 9)
;; build a new HashSet containing the values from a
(into #{} a)
#{0 1 2 3 4 5 6 7 8 9}
;; Just use the HashSet directly (high performance, no copy required)
(.contains a 1)
=> true
(.contains a 100)
=> false
Regarding when to use each of these, I'd suggest the following advice:
If you are trying to wrap a Java library and present a clean Clojure API, then I'd suggest converting to the equivalent Clojure data structures. This is what Clojure users will expect, and you can hide the potentially messy Java interop details. As a bonus, this will make things immutable so that you don't run the risk of Java collections mutating while you use them.
If you just want to use the Java API quickly and efficiently, just use Java interop directly on the Java collections.
The idiomatic way to convert java collections to clojure is to use the (seq) function, which is already called by most functions operating on sequences.
(def s (java.util.LinkedHashSet.))
#'user/s
user> (seq s)
nil
user> (.add s "foo")
true
user> (seq s)
("foo")
user>
I honestly don't know if there's a universally accepted practice, but here's Chris Houser arguing against Java to Clojure adapters as you break compatibility with the original Java API.
To perform the translation you asked for, simply use into:
user=> (import java.util.LinkedHashSet)
java.util.LinkedHashSet
user=> (def x (LinkedHashSet.))
#'user/x
user=> (.add x "test")
true
user=> (def y (into #{} x))
#'user/y
user=> y
#{"test"}
I'm trying to use Clojure to dynamically generate functions that can be applied to large volumes of data - i.e. a requirement is that the functions be compiled to bytecode in order to execute fast, but their specification is not known until run time.
e.g. suppose I specify functions with a simple DSL like:
(def my-spec [:add [:multiply 2 :param0] 3])
I would like to create a function compile-spec such that:
(compile-spec my-spec)
Would return a compiled function of one parameter x that returns 2x+3.
What is the best way to do this in Clojure?
Hamza Yerlikaya has already made the most important point, which is that Clojure code is always compiled. I'm just adding an illustration and some information on some low-hanging fruit for your optimisation efforts.
Firstly, the above point about Clojure's code always being compiled includes closures returned by higher-order functions and functions created by calling eval on fn / fn* forms and indeed anything else that can act as a Clojure function. Thus you don't need a separate DSL to describe functions, just use higher order functions (and possibly macros):
(defn make-affine-function [a b]
(fn [x] (+ (* a x) b)))
((make-affine-function 31 47) 5)
; => 202
Things would be more interesting if your specs were to include information about the types of parameters, as then you could be interested in writing a macro to generate code using those type hints. The simplest example I can think of would be a variant of the above:
(defmacro make-primitive-affine-function [t a b]
(let [cast #(list (symbol (name t)) %)
x (gensym "x")]
`(fn [~x] (+ (* ~(cast a) ~(cast x)) ~(cast b)))))
((make-primitive-affine-function :int 31 47) 5)
; => 202
Use :int, :long, :float or :double (or the non-namespace-qualified symbols of corresponding names) as the first argument to take advantage of unboxed primitive arithmetic appropriate for your argument types. Depending on what your function's doing, this may give you a very significant performance boost.
Other types of hints are normally provided with the #^Foo bar syntax (^Foo bar does the same thing in 1.2); if you want to add them to macro-generated code, investigate the with-meta function (you'll need to merge '{:tag Foo} into the metadata of the symbols representing the formal arguments to your functions or let-introduced locals that you wish to put type hints on).
Oh, and in case you'd still like to know how to implement your original idea...
You can always construct the Clojure expression to define your function -- (list 'fn ['x] (a-magic-function-to-generate-some-code some-args ...)) -- and call eval on the result. That would enable you to do something like the following (it would be simpler to require that the spec includes the parameter list, but here's a version assuming arguments are to be fished out from the spec, are all called paramFOO and are to be lexicographically sorted):
(require '[clojure.walk :as walk])
(defn compile-spec [spec]
(let [params (atom #{})]
(walk/prewalk
(fn [item]
(if (and (symbol? item) (.startsWith (name item) "param"))
(do (swap! params conj item)
item)
item))
spec)
(eval `(fn [~#(sort #params)] ~#spec))))
(def my-spec '[(+ (* 31 param0) 47)])
((compile-spec my-spec) 5)
; => 202
The vast majority of the time, there is no good reason to do things this way and it should be avoided; use higher-order functions and macros instead. However, if you're doing something like, say, evolutionary programming, then it's there, providing the ultimate flexibility -- and the result is still a compiled function.
Even if you don't AOT compile your code, as soon as you define a function it gets compiled to bytecode on the fly.
I need something like this, a collection of elements which contains no duplicates of any element. Does Common Lisp, specifically SBCL, have any thing like this?
For a quick solution, just use hash tables, as has been mentioned before.
However, if you prefer a more principled approach, you can take a look at FSet, which is “a functional set-theoretic collections library”. Among others, it contains classes and operations for sets and bags.
(EDIT:) The cleanest way would probably be to define your set-oriented operations as generic functions. A set of generic functions is basically equivalent to a Java interface, after all. You can simply implement methods on the standard HASH-TABLE class as a first prototype and allow other implementations as well.
Look at cl-containers. There is a set-container class.
You could use lists, though they can prove to be inefficient for representing large sets. This is done using ADJOIN or PUSHNEW to add a new element to a list, and DELETE or REMOVE to do the opposite.
(let ((set (list)))
(pushnew 11 set)
(pushnew 42 set)
(pushnew 11 set)
(print set) ; set={42,11}
(setq set (delete 42 set))
(print set)) ; set={11}
One thing to watch out for is all that these operators use EQL by default to test for potential duplicates in the set (much as Java uses the equals method). That's OK for sets holding numbers or characters, but for sets of other objects, a `deeper' equality test such as EQUAL should be specified as a :TEST keyword parameter, e.g. for a set of strings :-
(let ((set (list)))
(pushnew "foo" set :test #'equal)
(pushnew "bar" set :test #'equal)
(pushnew "foo" set :test #'equal) ; EQUAL decides that "foo"="foo"
(print set)) ; set={"bar","foo"}
Lisp's counterparts to some of Java's Set operations are:
addAll -> UNION or NUNION
containsAll -> SUBSETP
removeAll -> SET-DIFFERENCE or NSET-DIFFERENCE
retainAll -> INTERSECTION or NINTERSECTION
Yes, it has sets. See this section on "Sets" from Practical Common Lisp.
Basically, you can create a set with pushnew and adjoin, query it with member, member-if and member-if-not, and combine it with other sets with functions like intersection, union, set-difference, set-exclusive-or and subsetp.
Easily solvable using a hash table.
(let ((h (make-hash-table :test 'equalp))) ; if you're storing symbols
(loop for i from 0 upto 20
do (setf (gethash i h) (format nil "Value ~A" i)))
(loop for i from 10 upto 30
do (setf (gethash i h) (format nil "~A eulaV" i)))
(loop for k being the hash-keys of h using (hash-value v)
do (format t "~A => ~A~%" k v)))
outputs
0 => Value 0
1 => Value 1
...
9 => Value 9
10 => 10 eulaV
11 => 11 eulaV
...
29 => 29 eulaV
30 => 30 eulaV
Not that I'm aware of, but you can use hash tables for something quite similar.
Lisp hashtables are CLOS based. Specs here.
Personally, I would just implement a function which takes a list and return a unique set. I've drafted something together which works for me:
(defun make-set (list-in &optional (list-out '()))
(if (endp list-in)
(nreverse list-out)
(make-set
(cdr list-in)
(adjoin (car list-in) list-out :test 'equal))))
Basically, the adjoin function prepends an item to a list non-destructively if and only if the item is not already present in the list, accepting an optional test function (one of the Common Lisp "equal" functions). You can also use pushnew to do so destructively, but I find the tail-recursive implementation to be far more elegant. So, Lisp does export several basic functions that allow you to use a list as a set; no built-in datatype is needed because you can just use different functions for prepending things to a list.
My data source for all of this (not the function, but the info) has been a combination of the Common Lisp HyperSpec and Common Lisp the Language (2nd Edition).