This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-05-06
Channels
- # admin-announcements (6)
- # beginners (147)
- # boot (9)
- # braveandtrue (5)
- # cider (11)
- # cljsjs (1)
- # cljsrn (4)
- # clojure (82)
- # clojure-greece (9)
- # clojure-poland (9)
- # clojure-russia (288)
- # clojure-taiwan (2)
- # clojure-uk (73)
- # clojurescript (123)
- # consulting (3)
- # cursive (26)
- # datascript (4)
- # datomic (32)
- # dirac (56)
- # emacs (11)
- # flambo (2)
- # hoplon (425)
- # jobs-rus (1)
- # lein-figwheel (3)
- # leiningen (16)
- # luminus (42)
- # mount (7)
- # om (1)
- # om-next (2)
- # onyx (8)
- # other-languages (146)
- # quil (3)
- # re-frame (17)
- # reagent (6)
- # spacemacs (2)
- # uncomplicate (8)
- # untangled (71)
- # vim (2)
- # yada (49)
FWIW, clj-webdriver is a great, solid library and the maintainer is currently working on a major overhaul with a streamlined API.
One of the key things about many Clojure libraries is that they’re rock solid, laser-focused, and they hardly need any maintenance.
In addition, that stability makes them much safer to rely on for production use.
@prokaktus: We’ve had Clojure in production for near five years now. It’s been so solid we’ve been able to run pre-release versions of it safely — in production — and we’ve had almost no problems with any of the upgrade releases over that time. We started with a prerelease of 1.3 and we’re on 1.8 now.
@seancorfield: thanks a lot! I’m really appreciate your experience!
@seancorfield: I didn't intend to malign clj-webdriver, I'm thinking of trying to use it for some testing automation soon. I actually almost suggested that clj libraries were qualitatively less in need of maintenance than other languages' libs, but went with suggesting that they needed fewer maintainers which I guess is a small difference in ways and a large one in others.
@bwstearns: I didn’t take your comment as maligning the library, I just wanted to note that there’s a lot of (re-)design work being done (so it’s just not visible). We use it pretty heavily at World Singles.
@roberto: Java interop is probably your best bet for that...
@roberto: Looks like the easiest way is Apache Commons IO:
(! 1316)-> boot -d commons-io repl
Retrieving commons-io-2.5.jar from
…
boot.user=> (import '( IOUtils))
org.apache.commons.io.IOUtils
boot.user=> (require '[ :as io])
nil
boot.user=> (def snow (io/input-stream "./drawing/images/white_flake.png"))
#'boot.user/snow
boot.user=> (def bb (IOUtils/toByteArray snow))
#'boot.user/bb
boot.user=> (count bb)
6732
The dependency would be [commons-io "2.5"]
Hi all, I am trying to understand how does require and import work under the hood. The following blog post was linked several times as a good starting point to learn about the topic https://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html , but I can’t understand this paragraph:
"One important detail here is that the initial require is necessary—without it, you’ll get a ClassNotFoundException. Defypes work identically, though their printed representation will of course vary. You can use the same vector notation as with Java classes, but here you’d specify a namespace rather than a Java package as the first element of the vector."
Requiring a namespace will cause the corresponding source file to be loaded and compiled (if it isn’t already loaded).
Import just declares an alias for the class in the current namespace — so the class must already be loaded.
As of Clojure 1.8, defrecord
can have :load-ns true
in it which will cause its defining namespace to be automatically loaded when you import
the record’s class. I haven’t tried that (and I don’t know how it does it) but that’s what the docs say.
I doubt that’s very common out in the wild tho’ since libraries tend to continue supporting older versions of Clojure for a while.
(FWIW, I can’t get :load-ns true
to work locally for me so I’m missing some subtlety of it)
Did that help @rcanepa ?
Yes, totally. Thanks @seancorfield ! … I wasn’t aware of :load-ns, I will try it too.
I’m building a library foo
where some functionality, say foo.database
, is opt-in, and applications that need foo.database
need to have clojure.java.jdbc
in the classpath. Now, for applications that don’t need foo.database
, I’d like to not even load/require the namespace, so that there’s no complaint of clojure.java.jdbc
not being in the classpath.
I currently have this:
(when (matches-some-condition?)
(eval '(require 'foo.database))
(eval '(foo.database/some-function)))
The eval
around the require line is not needed, as long as the code doesn't get there at runtime it won't cause a problem
Hello Clojurians I’m struggling with IntelliJ and Cursive… I don’t get how to evaluate function from editor to the REPL interactively.
There may be a better way, but send XXX to REPL
in the REPL menu will allow you to play with function XXX in the REPL. Interested to learn alternatives BTW.
That's one thing I find annoying about IntelliJ: I have to add the REPL through "Edit Configurations" for every new project. In Emacs I can start a new project and the REPL is always right there.
@nkraft: you shouldn’t need to go via “Edit configurations” each time. Don’t you have a green arrow (on the top right) ?
There’s no such “thing” “SEND XXX to REPL" in my cursive key-binding. 1. SEND top from REPL 2. SEND form before caret to REPL. I can load file but I want to execute a function at a time…
Thank you for suggestion. I had heavy customized keymap, my kind of mix of IntelliJ and Emacs, but with Dvorak makes it hard to cope with IntelliJ…
@plexus: this does not need ns-resolve
, and ns-resolve
is often misused. ns-resolve
is when you want to ask "what symbol would this resolve to when used in some other specific ns" - eg, in your repl (ns-resolve *ns* '+)
should return clojure.core/+
. You can just use resolve when you know the ns you are looking for eg. (resolve 'clojure.core/+)
I’m trying to write a tail-recursive function which takes two collections(not vector) and returns the collection of common elements (duplicates included)
Which book do you guys recommend for picking up clojure? (with already experienced java experience)
@giga: the if
statements you have written are not nested and return nil
on their 'else' portion
i.e. (if (empty? list-one) commons)
will return commons value if list-one is empty and nil
if it's not empty but then the second if
gets executed regardless of what the first if
returns so if list-one
was empty commons would be disgarded and you'd execute the second if
regardless.
if
expressions work like this: (if (predicate) true false)
where if you omit the false portion it returns nil
Therefore you need to nest the two if
expressions
(if (empty? list-one)
commons ;; return this on true
(if (some #(= (first list-one) %) list-two)
(find-commons-tail (rest list-one)
list-two
(conj commons (first list-two)))
;; what do you want to return if you don't get a match? if it's nil then consider using when instead
))
(defn do-some-thing [entity]
(entity/save {:a 2}))
I'm attempting to solve a problem whereas I can pass in whatever entity to the above method and the action is performed on it. Is this possible in clojure?@byron-woodfork: what is entity?
remember Clojure works by executing a function on data... there aren't really objects that encapsulate data and function.
Some data that resides at the DB level. I want to be able to pass in different entities. They all have the same save
method on them.
so you could do (save entity)
@byron-woodfork: how are you associating the save
fn with the entity? defprotocol
?
Correction: The entity
would be a namespace value.
Ah, ok
Sorry about the confusion
The save
function resides on the entities namespace
so you would have to require the namespace and eval it dynamically
assuming you are passing a different name space for each entity?
Correct
There's a much simpler way of doing this though
I'm all ears
You could use either protocols or multi methods to dispatch on a type or key representing the entity with a different implementation for each entity for the save fn
Ah, I gotcha. I knew of the multi method option already. I'll look into protocols as well.
Thanks!
no prob
remember multi methods can dispatch on things other than type which is more powerful than pure OO polymorphism which is only by type.
Just realized that as I was reading the docs on multimethods. Haha. Thanks again.
@agile_geek: thank you so much. It’s takes a time and practice to get use to Functional world when Java/Python point of view where return stops the function… It still returns nil and I think issue is with carrying a value. I want to keep all common items in “commons” and perhaps (conj commons (first list-two)) doesn’t do the job…
@giga I think you are on the right lines. I am a reformed Java developer so I completely understand the 'return from end of s-expression' takes learning
@agile_geek: yeah, perhaps I should read more about common lisp and not just Clojure
@giga: take a look at Structure and Interpretation of Computer Programs (the original MIT talks are on youtube and are funny if only for the clothes - I remember wearing similar and the hair cuts too). Also my friend Tommy Hall has converted some of the book to Clojure - http://www.sicpdistilled.com/
@agile_geek: wow, thank you for this resource. I glanced a few pages a year ago but never dived into.
I forgot about SICP Distilled. I saw that back when chapter 1 was barely done. It's shaping up nicely, though slowly. I wish that had been around when I was learning Clojure, as that's the book I used to learn Lisp and Scheme back in the day.
I think Tom has been busy in 'real' life so it's been on back burner.
@agile_geek: one more question - let's take this simple function as an example:
`(defn tail
[one two sum]
(or (empty? one) (empty? two) sum
(if (= (first one) (first two))
(tail (rest one) (rest two) (conj sum (first one))))))`
how should I “call” it? the first example that comes in mind is this:
(tail [1 2 3 4] [1 2] [])
but I want to emphasize on the third argument. It’s just an empty vector but but but… I’m lost ^^
1 new message since 10:52 PM
Mark as read (esc)Mark as read
Team Directory
@giga your call is fine but that or
is not what you intended.
I've got to get off my train in 5 mins so I'm going to drop off internet but take a look at doc's and examples for or
@agile_geek: it’s ok, thank you
@giga what are you trying to do with that function? Are you trying to add the elements of one
and two
together one at a time and then return the result in the sum
vector?
@jswart: I’ve named that foolishly, my apologies, I want to return a vector of intersected elements
yep, just for learning purposes, but before I solve it via reduce, I’d like to complete this using “recur"
so loop/recur
is tail recursion in clojure. You don’t do tail recursion by using a recursively defined function by name.
@giga i'd overload the function so that you can call it like: (tail [1 2 3 4] [1 2])
(defn tail
([one two] (tail one two [])
([one two sum] ...same code you posted above...))
is that what you were asking about here: "but I want to emphasize on the third argument..."
http://clojure.org/reference/special_forms#recur, and avoiding the urge to pass in an empty datastructure to be “filled” is a bit more idiomatic
Assuming you use loop
with it. You example will work, but on functions that generate a lot of calls on the stack it will blow up. Instead you can use loop
and recur
to do the same thing but you get a couple benefits: compiler verification, and constant space usage.
"Note that recur is the only non-stack-consuming looping construct in Clojure. There is no tail-call optimization and the use of self-calls for looping of unknown bounds is discouraged. recur is functional and its use in tail-position is verified by the compiler.” extract from docs
hi, i`m reading the "living clojure" and see this function - (def animal-print (map #(println %) animals)) ;; -> #'user/animal-print and printout - animal-print ;; mouse ;; :duck ;; :dodo ;; :lory ;; :eaglet ;; -> (nil nil nil nil nil) why here we have this nil`s? and when using "doall" before map, in result we have only (nil,nil,nil,nil), why it happens?
so the 3 arity one needs to change to use loop/recur, but the 2 arity one is ok since it's bounded to 1 self-call?
those nils are the return type. Everything in clojure is an expression and has a value. The value of printing something is nil
. So the REPL shows you that.
try this @agi_underground change #(println %)
to #(do (println %) %)
yes, here output without nil`s, but after definition, symbol that we define equal (nil,nil,nil,nil)
user=> (def animal-print (doall (map #( do (println %)) animals))) :mouse :cat :rabbit :eliphant #'user/animal-print user=> animal-print (nil nil nil nil) user=>
Basically in the REPL
you can “print” and see stuff but the last line
of output from running something is the return
value of that expression.
If println were a function in another language its type would be public void println(object x)
(well, println is variadic :)
ooooomy
i think now i understand, i was want to define symbol with action(function), but really i`m define symbol with results of function work
(def foo (+ 1 2))
binds foo
to the VALUE of the expression (+ 1 2)
so user> foo
returns 3
ok, thank you @jswart all this simple things, but maybe i`m little tired)