This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-01
Channels
- # adventofcode (30)
- # announcements (51)
- # aws (27)
- # babashka (1)
- # beginners (16)
- # calva (6)
- # cider (10)
- # clj-kondo (2)
- # clojure (94)
- # clojure-dev (27)
- # clojure-italy (1)
- # clojure-taiwan (1)
- # clojure-uk (5)
- # clojurescript (18)
- # clojutre (2)
- # cursive (14)
- # data-science (8)
- # emacs (2)
- # joker (5)
- # off-topic (3)
- # shadow-cljs (31)
- # sql (2)
- # vim (2)
- # yada (11)
Hi, I am trying to write a test for this function:
(defn find-copyright-statements-in-file
"Find copyright statements in the given file"
[file]
(let [re #".*[Cc]opyright.*(19|20)[0-9][0-9].*"]
(with-open [r (io/reader file)]
(remove nil? (map first (map (partial re-find re) (line-seq r)))))))
I have this in my test:
(deftest test-find-copyright-statements-in-file
(let [output (c/find-copyright-statements-in-file file)]
(is (= (count output) 1))
(is (= (first output) expected))))
This gives me an error:
ERROR in (test-find-copyright-statements-in-file) (BufferedReader.java:122)
expected: (= (count output) 1)
actual: .IOException: Stream closed
at .BufferedReader.ensureOpen (BufferedReader.java:122)
.BufferedReader.readLine (BufferedReader.java:317)
.BufferedReader.readLine (BufferedReader.java:389)
I was playing around in the REPL... I found that if I do (def x (find-copyright-statements-in-file some-file))
then I can do things like x
, (count x)
, (first x)
and they work fine, but if I try to do it in a let
instead of a def
I get these same errors - e.g.
copyright=>
(let [y (find-copyright-statements-in-file file)]
(print (count y))
(print (first y)))
Execution error (IOException) at .BufferedReader/ensureOpen (BufferedReader.java:122).
Stream closed
class .IOException
I do not understand why it works in the def
but not in the let
. I assume it has something to do with then the lazy seq is actually evaluated... any help appreciated! Thanks in advance
Oh - answering my own question - I guess typing it out suggested the answer.... I change the function to this
(defn find-copyright-statements-in-file
"Find copyright statements in the given file"
[file]
(let [re #".*[Cc]opyright.*(19|20)[0-9][0-9].*"]
(with-open [r (io/reader file)]
(doall (remove nil? (map first (map (partial re-find re) (line-seq r))))))))
Now it works like I expected đ
BTW I hink you can replace (remove nil? (map ...)
with keep
Also take a look at transducers. You can put together all the mapping functions by calling them without the collection argument, then you can use that xf with into
instead of doall, because it is eager when used with a transducer. It may give you some performance gain.
Without the doall
, the rest of the functions you are using there are lazy, which prevents them from being evaluated within the scope of the with-open
, and if you try to force the lazy sequence after leaving the scope of the with-open
, the file is closed and gives an error.
Hello there! Anyone using Datomic in production? How much space will it accumulate over time? I mean, we donât lose data, which is a pretty fancy cool thing, but what about when I donât have more space? Are there some functions to reset the database every month for example. So the state one month ago will be the âfirst stateâ of the database?
If you're planning on putting that much data into datomic, you might struggle. There's a soft limit on the data you can put in, and you'll need to speak with cognitect for capacity planning.
thank you!
Also consider Leiningen, in particular in combination with https://github.com/ztellman/virgil
clojure itself and older clojure contrib libs are built with Maven: https://github.com/clojure/clojure/blob/master/pom.xml and https://clojure.org/community/contrib_libs
When AOT-ing a project with JDK 11 and deploying it to clojars, will the project be able to run with JDK 8? I may have accidentally done that
Whether a .class file works on certain JDK version depends on the bytecode version that .class files have. https://clojure.org/community/devchangelog says that clojure 1.10 generates Java 8 bytecode.
It wonât work if you used parts of JDK libraries that are in JDK 9 or later. Otherwise it could work.
and is there a way to check which java version has been used for a specific artifact?
If you have class files, javap can tell you which version they are
bug or feature?
(defn var
([name] (var name nil nil)) ;;=> always returns #'clojure.core/name
([name init-val] (var name init-val nil ))
([name init-val meta] (SciVar. init-val name meta)))
Probably using var as a function name in a public API (or at all) is not a very good ideaI don't know if that's correct or not, but I like to think of them as read time macros
Hum... well ya that doesn't seem to be the case. But oh well. I'm not too sure what the semantics are for special forms and when they are processed exactly. But I'd avoid shadowing them đ
I don't think Eastwood does so.
I think they're processed directly by the compiler. And depending which special form it is, they'll have the compiler do something different. But in the context where you shadowed a special form. I guess you could consider it a bug that the compiler misidentifies the code as a special form when it isn't referring to one. At the same time, I don't know if it's possible (or just way too hard) to detect the difference.
I have this inside a clojure interpreter:
;; derived from (keys (. clojure.lang.Compiler specials))
;; (& monitor-exit case* try reify* finally loop* do letfn* if clojure.core/import* new deftype* let* fn* recur set! . var quote catch throw monitor-enter def)
(def special-syms '#{try finally do if new recur quote catch throw def . var set!})
I mean, just imagine the confusion that one could create by trying to name a function .
I had fun debugging Eastwood running on a Clojure library that defined, I believe, a macro named catch
which I believe worked as the authors intended it to.
user=> (def throw [])
#'user/throw
user=> (throw)
Syntax error compiling throw at (REPL:1:1).
Too few arguments to throw, throw expects a single Throwable instance
something like that, yeah.
@U0K064KQV it could work with a namespace prefix, but what if the function is recursive like in my original post?
`(def def (fn [] "lol"))
(def) ; too few args to def
(def a 10) ; #'a
a ; 10
(user/def) ; lol`
It does not come up very often in live code examples, but there might be something out there.
oh yes, this works:
user=> (defn var ([x] (user/var x nil)) ([x y] [x y]))
#'user/var
user=> (user/var 1)
[1 nil]
still probably good to avoid. I bet I will trip some edge case in CLJS or something when I go ahead with this
Ya. I also don't really understand the underlying mechanism. I guess the compiler probably just first checks if the symbol in first position is a special form, if so treats it as one. If not, performs var resolution in the given namespace. And when the symbol is fully qualified, it does not equal any special form so that probably works.
i don't know if the details are still accurate but there is a bit in the "clojure for java programmers" (part 1) rich hickey talk that mentions about the order -- around 1:03:00 or so (the op slide)
Yes, although that might be a somewhat simplified explanation vs. what the compiler actually does, even at the time that talk was given.
The details of name conflicts can get pretty finicky here, I suspect.
Eh, if you get insanely curious, I would recommend adding several System.out.println
calls into likely-looking places in the Clojure compiler implementation, then come up with several example forms to compile and evaluate that should exhibit different behaviors in that area. It can be time consuming, but on the order of hours, not weeks.
well, perhaps hours stretching into days đ
it's something I've been thinking of quite a bit recently, given past experience using Clojure for DSLs/compilers and a new work focus on SV
is it bad practice to shadow a variable via a let binding that's out of scope?
granted not a core clojure function
Not sure what you mean by "that's out of scope" there. Do you have an example of what you mean?
I mean, how can you shadow something unless it is visible in the scope of where the let
expression is?
for example, I often use key destructuring, but if I need to process a key before passing it thoruhg, I often shadow
(let [{:keys [a b c]} some-obj
a (if (= b 2) a 0)],,,)
sorry, you're right, not out of scope
In a small enough let
, I would think the meaning is pretty clear to all all slightly experienced Clojure developers.
The larger the let
gets, the harder everything is to follow, not just shadowing.
I often do a'
or something, but evil-cleverparens has some annoyances with stray single-quotes
I am not familiar with evil-cleverparens, but if that is intended to be a Clojure or Lisp-specific mode, it might be advisable to report that and see if they can improve on it.
interesting list, wasn't expecting this: https://www.techrepublic.com/article/the-20-fastest-rising-and-sharpest-declining-tech-skills-of-the-past-5-years/
i wouldnât read into that too much. may just mean many clojurians are happily employed, effective in small numbers, and anti-hype đ
Don't know what to say... Clojure is amazing, but the battle for mindshare is tough, and Clojure puts little focus on it and doesn't really care. Or should I say, wouldn't compromise its goals to make itself more attractive, for good reasons.
Those are based on very small percentage differences at one online job site
My impression is that there are more companies hiring more people now than ever
Was just at Clojure Conj, full of people at companies hiring Clojure devs
I wonder what's the threshold for being included on that list. I can imagine the job postings mentioning clojure went from 5 to 1, just by chance of the measuring date.
It's kind of weird to see Clojure (a relatively new and popular technology) among other dinosaurs like jsp, solaris (!), vba, flash, windows XP (!!) ...
I don't necessarily pay too much attention to such reports but I still find it peculiar that among all possibile niche technologies that exist and are declining it's Clojure has the taken first position.
Compared to flash it was particularly surprising for me as well. That suggests, according to the worlds largest jobhunting site, that more people are interested in sticking with flash for their work than clojure?
Maybe that's because there are few corporate jobs and companies are simply no longer posting their positions on that website anymore. Maybe most recruitment these days happens in other forms (other hiring platforms, this slack's channels, conferences ect).
But it could be as well just an anomaly in the way they processed their data. I doubt that people are sticking more with Flash than with Clojure.
Also I remember that in the past many backend -positions would list Clojure as a "nice-to-have" technology in their description. Maybe it's no longer the case nowadays and this highly influenced the final result.
list of companies hiring at #reclojure (London) from today ... https://clojurians.slack.com/archives/CQ4R1R96V/p1575294494200600