This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-14
Channels
- # aleph (16)
- # bangalore-clj (4)
- # beginners (19)
- # boot (27)
- # cider (81)
- # clara (2)
- # cljs-dev (343)
- # cljsrn (97)
- # clojure (224)
- # clojure-hk (1)
- # clojure-italy (25)
- # clojure-russia (5)
- # clojure-serbia (2)
- # clojure-spec (7)
- # clojure-uk (27)
- # clojurescript (97)
- # cursive (8)
- # datomic (48)
- # docker (1)
- # emacs (15)
- # hoplon (39)
- # jobs (4)
- # lumo (13)
- # off-topic (2)
- # om (66)
- # onyx (7)
- # parinfer (5)
- # pedestal (2)
- # play-clj (10)
- # protorepl (2)
- # quil (1)
- # re-frame (38)
- # reagent (33)
- # spacemacs (1)
- # specter (4)
- # sql (19)
- # test-check (31)
- # unrepl (4)
- # untangled (3)
Hi all, I'd like to fan out the same input sequence to several transducers and collect the results into a single sequence... is there a function for that?
Any one experience with Lanterna? I'm looking into making a snake game, and would like to know if it can do a non blocking ui
@shidima_ I believe it does, haven’t used it in a while, but I see from the docs it has both get-key
and get-key-blocking
— the first returns nil if there’s no keypress waiting to be read.
Hi all, Is there any way to mock a function in clojure. For example I have this function:
(defn a [x]
(utils/count x))
I need to write a test, but I do not know how to mock the utils/count (for example)@alricu, you can use with-redefs
to "re-bind" a symbol
here is a useful testing pattern: https://stackoverflow.com/questions/31157889/clojure-unit-testing-with-redefs#31309070
i'm saying that because if its not too many, i would make a function that accepts those and calls them inside it self, and you can create your production one with (create-a [count count2 other] (fn a [x] (utils/count ...)))
I'm looking for a way to remove/clear protocol implementations during testing. Is there a common way of doing this? I came across mention in Stuart Sierra's LazyTest where he says his method is broken. https://github.com/stuartsierra/lazytest/blob/master/modules/clojure-language-tests/test/clojure/test_clojure/protocols.clj#L18-L28
Looking in Clojure core, I suspect something similar to that would work: https://github.com/clojure/clojure/blob/f572a60262852af68cdb561784a517143a5847cf/src/clj/clojure/core_deftype.clj#L791
@grzrm so your test needs to eliminate the extensions of your protocol?
yup. The library I'm testing provides alternative implementations, so I'm testing each one. Right now I'm running separate test suites, but that's a bit of a hassle.
why do other extensions need to be deleted? can’t the individual extensions be tested independently of one another?
do you mean it’s two extensions of one type to a protocol?
on one type?
my temptation would be to either replace the type or protocol when testing
because clearly both implementors can’t own both the type and the protocol, which would be good reason to make it modular…
I'm not following. In this case the I'm trying to test specifically the implementation on that type. Swapping it out, like for a mock, would defeat the purpose in this case.
it could be as simple as a proxy that uses proxy-super for every method you call
user=> (str (proxy [Object] [] (toString [] (proxy-super toString))))
"user.proxy$java.lang.Object$ff19274a@6e0ed78c"
you extend the supertype, and call the supertype’s method on method calls
it’s a different class, but has the same behaviors
another alternative is to use composition (a deftype with a Foo, which re-calls every method on that Foo)
Thanks for the alternatives. I'll ponder those for a bit to see if I can make them work. Cheers!
what's wrong with this spec expression that it doesn't return an explanation ?
(s/explain (s/cat :this (s/* (s/coll-of :q/o)) :that :q/test-map) '((7 3 1) (9 7 3) {:q/b [2 4 6] :q/c ["abc" "xyz"] :q/d [:q :w] :q/a [1 3 5]}))
IllegalArgumentException Argument must be an integer: [:q/b [2 4 6]] clojure.core/even? (core.clj:1383)
...each part of the s/cat works:
(s/explain (s/cat :this (s/* (s/coll-of :q/o))) '((7 3 1) (9 7 3)))
Success!
(s/explain (s/cat :that :q/test-map) '({:q/b [2 4 6] :q/c ["abc" "xyz"] :q/d [:q :w] :q/a [1 3 5]}))
Success!
(where
(s/def :q/test-map (s/keys :req [:q/b :q/a] :opt [:q/c :q/d]))
and the various keys :q/a etc are simple odd? even? string? keyword?
sorry I should have said :q/a and q:b are
(s/+ odd?)
and (s/+ even?)
(s/def :q/o odd?)
Hey guys can someone help with this problem, I am new to clojure, may be I am missing something: https://stackoverflow.com/questions/45107883/clojure-reducers-foldcat-not-working
serg: I saw you deleted this. I noticed if you removed into []
and just used the seq instead of a vector, it works. Did you solve it?
@U1ALMRBLL Hi Josh, actually the problem was in my mac, prev I ran this func with long running async task in map, it was like fetch 6k items and insert into db values for each one, so seems like it was running all this time consuming all available threads, that's why it didn't work, once it has finished I got my code working as expected.
The strange thing is that I ran this in REPL and I am sure I have cancelled this task, but somehow it was still running in background consuming all available threads
what do you mean by "total" ?
I suspect the problem here is that s/+
is a regex matcher, not a collection matcher...?
Change :q/b
to (s/coll-of even?)
(you can specify a minimum length of 1 to require at least one element)
right now the error from feeding a non-number to odd? is bubbling out and killing the checking
Ah, I see where you're going now. I was jumping ahead.
@octo221 "total" means "defined for all inputs"
even?
and odd?
are only defined for numeric inputs.
Hence @hiredman's suggestion to use (s/and number? odd?)
ok a simpler version works:
(s/explain (s/cat :this (s/* (s/coll-of odd?)) :that (s/coll-of even?)) '((7 3 1) (9 7 3) [2 4 6]))
using
(s/def :q/b (s/coll-of (s/and number? even?)))
does not work(s/explain (s/cat :this (s/* (s/coll-of odd?)) :that (s/keys :req [:q/b])) '((7 3 1) (9 7 3) {:q/b [2 4 6]}))
IllegalArgumentException Argument must be an integer: [:q/b [2 4 6]] clojure.core/even? (core.clj:1383)
however,
(s/explain (s/cat :that (s/keys :req [:q/b])) '({:q/b [2 4 6]}))
Success!
ah yes that works ok
(s/explain (s/cat :this (s/* (s/coll-of (s/and number? odd?))) :that (s/keys :req [:q/b])) '((7 3 1) (9 7 3) {:q/b [2 4 6]}))
Success!
please explain why!?
because odd? and even? as predicates aren't total, so they will throw exceptions when not passed numbers instead of returning false
yes but why should they be passed non-numbers ?
oh yes I see!
(odd? {})
IllegalArgumentException Argument must be an integer: {} clojure.core/even? (core.clj:1383)
i had misunderstood how s/* worked
thanks so much!
this is perhaps a little convoluted.. but now i’m curious just for curiosity’s sake. if I had a function that maps over some collection, invokes a provided fn, and returns the value of that invoked fn as a different shape, how does this work with compose?
(defn do-map [f coll]
(map (fn [[foo val baz]] [foo (f val) baz]) coll)) ;; <- notice the [a b c]
;; wont work unless xform-2 and xform-1 are "aware" of the [a b c] shape
(do-map (comp xform-2 xform-1) coll)
is there a generic way to compose transformations and, after each xform, re-shape the data?
the do-map
couldn’t really know whether f
was composed or not, it just sees a function. so it would be hard to do something like (-> coll f0 reshape f1 reshape ...)
@lwhorton sounds like you want (fn [f] (fn [[a b c]] [a (f b) c])
then you can wrap your functions in it?
and -> isn’t a composer of functions, it’s a rewriter of forms, if you use comp
it’s easier to get the right behavior via wrapping functions without jumping through syntactic hoops
not quite, but the more i think about it the less possible it seems. i essentially want an interface where I can pass in a single function (composed or not), and that function will be applied piecemeal. if the provided fn is a composed fn, it will invoke the first composed, reshape the results, invoke the second composed, etc… regardless of how many steps belong to that composed function.
I think it’s impossible to do it from the “inside”; there’s no way to call 1 step of a composed function and “steal” the result before calling the 2nd step.
i would have to make the interface something like (do-map [coll f & maybe-more-fns] (if maybe-more-fns (compose f reshape (first maybe-more-fns) reshape (second maybe-more-fns ...))
and do the composing on the inside, I think
@lwhorton #(apply comp (map (fn [f] (fn [[a b c]] [a (f b) c])) (reverse %))
will take the functions in the order -> would accept them, and return a composed function that does what you describe
or you could write a macro that inserts that function around or inside each function in the form
that’s pretty neat. i considered macros, too, but thats a whole ‘nother can of worms i havent opened yet.
this becomes more clear if you name that function eg.
(defn to-middle
[f]
(fn [[a b c]]
[a (f b) c]))
(apply comp (map to-middle functions))
yea that’s much more clear. funny now that you point that out I realize this is expressed in a protocol, which doesn’t support variadic arguments. so either enforce a seq like (do-map v [f])
and use the fn above^, or I think something like (-> coll (do-map xform-a) (do-map xform-b)
(though more inefficient) works too
that -> form will break
that’s why I mentioned using comp to avoid syntactic hoops - since ->
is a form rewriter, it will put the coll in the wrong place
I am trying to rename the keys from a hashmap with rename-keys I have
(def a {a "A", b "B"}
well for one, a
and b
are both unquote symbols which evaluate to some value where :a
and :b
are keywords that evaluate to themselves
sounds like your real problem is that you aren’t using the return value of rename-keys
nothing in clojure actually modifies the built in maps, vectors, lists, etc. - they return new ones you can use
don’t use println to look at data, use prn
I bet a is actually “a” yeah
so you need rename-keys {“a” :aa} etc.
java.lang.ClassCastException: clojure.core$map$fn__4781 cannot be cast to clojure.lang.IPersistentMap
that means you used (map f)
where it expected a hash-map
for future reference, this is the difference between println
and prn
kingfisher.core=> (println {"a" 0 "b" 1})
{a 0, b 1}
nil
kingfisher.core=> (prn {"a" 0 "b" 1})
{"a" 0, "b" 1}
nil
There’s probably other option — you can get json with keys as keywords, just look to documentation of your json lib.
that’s sloppy though - there are valid json keys that are not valid keywords, so then you end up creating keywords that shouldn’t exist
but generally, turning keys in to keywords all the time is something every project (I have worked on) does, and I hate it
"valid keywords" are those that follow the rules in the docs imo, but the reader will create some keywords that don't if asked
I've seen this discussion play out over and over again in chat, on the mailing list, and in jira issues, and it seems like the core team's general stance is what the reader excepts doesn't define what is valid
the reader accepts more than those docs, but those docs do give a guarantee of what the reader will accept. so for me they make sense as a definition of valid. not the same thing as "whatever the reader accepts"
but it's not documented that that will always work (or become reserved for some special system/core usage) so I wouldn't use it
the point is, just because the reader only constructs certain kinds of symbols and keywords, that doesn't restrict the Symbol and Keyword data types to only construct those types of symbols and keywords
And at one point, very specifically, the Clojure/core team made :1
(numeric keywords) illegal in the reader on the grounds that they weren't sanctioned by the docs -- and they broke a bunch of code out there in the wild so they reverted the reader change.
I was affected by that change (one of the OSS libraries I maintain) but I would have been perfectly happy to change :1
to (keyword "1")
-- which they said they would not break... but they still reverted the change 🙂
So we have prior art for the reader being publicly known to accept things that are not considered "correct" and not getting fixed -- and a statement that keyword
(and, similarly, symbol
) being able to produce "junk" output from arbitrary input 😐
the issue isn't that the reader and the reader docs are not in 100% agreement about what is a readable keyword (that is another issue) the issue is that a valid readable keyword is not the same as a valid keyword
for example, the keywords json libraries create for map keys never pass through the reader
Exactly my point, yes.
which negates the purpose of turning them in to keywords in the first place, because the only reason people turn them in to keywords is since most maps in clojure use keyword keys, they more comfortable with them
Speed of lookup over plain strings. In theory.
(identical? :abc (keyword (str "a" "bc")))
=> true
So map lookup will be faster if it can check for identical?
before falling back to "equal".
what am I missing here?
user=> (defn foo [args] (apply hash-map args))
#'user/foo
user=> (binding [*data-readers* {'foo #'user/foo}] #foo [1 2 3 4])
java.lang.RuntimeException: No reader function for tag foo
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: No reader function for tag foo
java.lang.RuntimeException: Unmatched delimiter: )
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )
Good question, given that converting arbitrary strings to keywords can open you up to a denial of service attack.
I mean, you will likely be fine, and keyword's intern a weakreference, so the they will get cleared
Ya, but... 🙂
user=> (defn foo [args] (apply hash-map args))
#'user/foo
user=> (binding [*data-readers* {'foo #'user/foo}] (read-string "#foo [1 2 3 4]"))
{1 2, 3 4}
@hiredman ahh, so you need this? (binding [*data-readers* {'foo #'user/foo}] (read-string "#foo [1 2 3 4]"))
while on the topic of tagged literals: is there anything special you need to do to get it to work with tools.namespace
?
I’ve placed a data_readers.clj
in my classpath root, but when I try to use it in the REPL I get something like “Can’t call unbound Var”
data_readers.clj sets up the tag, but doesn't actually cause the namespace where the function is defined to load
and every place where you read something using that tag, before that does a require of that namespace execute?
okay, I see the problem: if I use (require 'kleinheit.pg.impl :reload)
first thing in the REPL, it works
the prevailing wisdom on the internet when having problems with data readers is to call (#'clojure.core/load-data-readers)
, but then I get:
dev=> (#'clojure.core/load-data-readers)
clojure.lang.ExceptionInfo: Conflicting data-reader mapping
if you look at the ex-data on *e that should show you what went wrong, right?
OK - so the data readers are already loaded, you have to reload the code they refer to, right?
(which refresh would do if you properly required that code before using the readers)
so find all the places you use the tag, ensure in that namespace you require the namespace where the function the tag maps to is
dev=> (dev/refresh)
:reloading (... kleinheit.pg.impl ...)
:ok
dev=> #foo [1 2 3 4]
java.lang.IllegalStateException: Attempting to call unbound fn: #'kleinheit.pg.impl/foo
clojure.lang.LispReader$ReaderException: java.lang.IllegalStateException: Attempting to call unbound fn: #'kleinheit.pg.impl/foo
and it works if I just skipped the refresh
and do the regular (require ...)
, so I’m at a loss ¯\(ツ)/¯
rlwrap is very handy when doing it that way
put a println at the top of the kleinheit.pg.impl namespace to see if it is actually getting reloaded
ah, I bet refresh breaks var interning, so you end up with two vars with the same name
yeah, it destroys namespaces which might also include doing something wacky with vars that other code has captured…
you might just want to blacklist the namespaces that define readers from auto-reload
@schmee it’s documented here https://github.com/clojure/tools.namespace#disabling-refresh-in-a-namespace
yeah, the problem with that is if I call disable-unload!
in the file, the “do not refresh” metadata will be added on the first refresh and I’m stuck again
yeah- iirc it makes tools.namespace unhappy though (and various tools that use that, like eastwood)
but maybe that’s old info…
talking about interning got me thinking about a great clojure talk I need to rewatch: https://www.youtube.com/watch?v=8NUI07y1SlQ