I’m doing a db query using the monger library like so:
(q/with-collection db "videos"
(q/find {})
(q/sort {:date 1})
(q/paginate :page page :per-page 5))
However, when I do page 1, I get the following ids:
("6011a14028dacb0004d7475c"
"6011a1ea28dacb0004d7475d"
"60119fe128dacb0004d7475a"
"602a15665273b0b82c3ded1c"
"6011a0b428dacb0004d7475b")
when I do page 2, I get these:
("6011a14028dacb0004d7475c"
"60119fe128dacb0004d7475a"
"602a15665273b0b82c3ded1c"
"6011a0b428dacb0004d7475b"
"60124ed4afa8e90004ab71a0")
The problem is that there’s an overlap of ids between the two pages. I expect the pages to show ids with no overlap. How to fix this?What would you suggest for using Graphql in Clojure?
Take a look a Lacinia
@nilern About yesterday's discussion: I guess Clojure has the same kind of issue but smaller in scope and more apparent to a user who defines things with proxy:
user=> (ifn? (proxy [clojure.lang.APersistentMap] []))
true
So the predicate returns true, while at runtime you will get an UnsupportedOperationException
when trying to call it as a functionOh. But much more tolerable since it is so rare and already annoying to have to use proxy
.
yeah, and the scope for which this will give "false" positives is much smaller
puzzle: given a vector of vectors like [[1 5 3][4 10 35 9][2 7 19]]
, I want to pick the one that contains the highest single value. In this case, it would be [4 10 35 9]
since 35 is the highest number in any of the vectors.
How about
(last (sort-by #(apply max %) [[1 5 3] [4 10 35 9] [2 7 19]]))
there are ways to do it with a couple of let-bindings and .indexOf
at the end, but ...
Definitely not the most optimized version
this is mine - also not really optimised. It does handle the case that there can be more than 1 vectors to return, though.
(defn max-vecs
[coll]
(let [n (apply max (flatten coll))]
(filter (partial some #{n}) coll)))
or the code golf version:
(defn max-vecs
[coll]
(filter (partial some #{(apply max (flatten coll))}) coll))
user=> (max-key #(apply max %) [1 5 3] [4 10 35 9] [2 7 19])
[4 10 35 9]
beware of empty collections, since max
requires at least one arg
https://clojurians.slack.com/archives/C03S1KBA2/p1615554762053600
TIL max-key
@borkdude
Weird naming
indeed
thanks for all the replies guys! I didn't know about max-key either, that one is quite elegant.
Late to the party, this takes the input as requested and delivers the output too (not optimised)
(defn max-vec [v]
(let [res (map #(vector (apply max %) %) v)
m (into {} res)] (get m (apply max (keys m)))))
I have a weird issue coming up when I try to test a generated class that uses a gen-interface. The interface has a method that’s overloaded a few times, but the one in question is supposed to take and return a string. If I go into the REPL and create an instance of the class, then call the method with a string, everything’s totally fine and it gives me the right result. But for some reason when I run a test that does, as far as I can tell, the exact same thing, I get an AbstractMethodError and it’s saying giving the method signature as (Ljava/lang/String;)Ljava/lang/String, which I don’t understand at all. Maybe this is my inexperience with Java showing, but I just don’t understand what it’s doing differently between the test and calling it from the REPL. Is there something obvious going on here that a Java person might pick up on immediately?
that L
prefix means it wants an array of string, which can be implicit if the method takes varargs
you probably need to share your code (or a simplified version), but another issue is that gen-interface doesn't reload like normal clojure code, so your repl might not reflect the current code even if you reloaded the code
Hm, okay. I don’t have my Leiningen REPL set up right, so it doesn’t reload correctly and I always end up exiting it and starting it again when I try testing it like this.
My entire gen-interface is here:
(gen-interface
:name XSLTTransformer
:methods [[transform [java.io.File java.io.File] void]
[transform [javax.xml.transform.Source java.io.File] void]
[transform [java.io.File] String]
[transform [javax.xml.transform.Source] String]
[transform [String] String]
[updateConfiguration [java.util.Map] void]
[getConfiguration [] java.util.Map]
[setConfiguration [java.util.Map] void]])
I have the signature set as String, so I don’t get why it would be looking for an array of stringsalso gen-interface is a weird corner of the language, I've never needed it, there could be gotchas that I'm unaware of still. what's your use case - you need java code to use your lib via an interface?
or a java lib is written such that it takes an interface as a parameter?
Safe version (also makes sure the original input vector is not empty, which also fails.
(when-let [coll (not-empty (remove empty? [[1 5 3][4 10 35 9][2 7 19]]))]
(apply max-key #(apply max %) coll))
I don't see how any of those methods would end up taking or returning an array
Well, I ended up creating this in a Java-ish way, but basically I have two XSLT transformers that I need to wrap with a consistent API that will be used from Java.
You can also fold the empty?
check into the predicate
I have a hunch this would be much easier using a gen-class, plus a implementation object that extends a clojure protocol
(in clojure land, each instance of the object would own as member data an implementation of the protocol)
Oh, okay, something weird is happening because I’m trying to delegate. This is probably a stupid approach, but I didn’t have a lot of time to get it done. Basically there are two gen-classes that implement the interface and then there’s a third class that implements the interface and uses its constructor to choose one of the other two classes to delegate to.
Ah, okay, so I’d want a protocol like “Transformable” or something, then define the methods from there?
right, you can still do the delegation with protocols, but protocols play nicer with the rest of clojure I think -the big gotcha here is that protocols don't differentiate methods for dispatch based on type, only name plus arg count
(I don't have proof that gen-interface doesn't have the same issue...)
Is there an example of an abstract class in the Java stdlib that takes arguments in the constructor?
Interesting, thanks. I’ll have to reread the documentation for protocols - I’ve used them a bit, but I don’t have the experience to necessarily know when/why to use them. I still need to figure out what’s going wrong with my delegation for now, but what you’re suggesting seems like a better direction that’s more Clojure-ish.
the docs say that if you aren't compiling gen-interface is a no-op, are you using a separate aot step?
Yeah, I have the classes set to aot in my project file
I feel a bit irresponsible trying to weigh in here when I haven't used it (and also know it will be weird), but I don't think there are many people who use the function so I hope some answer is better than none
Aha, replacing the gen-interface with a protocol seems to have fixed the immediate issue - I’ll have to go back later and try to rearrange things to take better advantage of the protocol, but this gets me to where I need to be. Thanks!
consider writing a doc on http://clojuredocs.org or a blog post if you figure out how to make gen-interface work- it feels like a dark corner of the language currently
maybe somewhere in swing
java.lang.AbstractStringBuilder
java.lang.VirtualMachineError
, if you need a public constructor.
cool, I wondered if the args to the super contructor can be dynamic and they can be:
(defn foo [m]
(proxy [java.lang.VirtualMachineError] [(:msg m)]))
(prn (.getMessage (foo {:msg "bar"})))
Wasn’t sure if there was a channel for core.match
. Had one very specific question: Is it possible to dynamically generate patterns from data at runtime (i.e. what is contained in the match
form) or would it require some macro magic? All the examples that I have seen look to be static/“hard coded” into the source code.
@mafcocinco core.match/match is a macro. the only way to make this more dynamic is to use eval
Hi there, I have a question, if I have an implementation like this
(s/fdef delete-by-id!
:args (s/cat :impl any?
:file-id ::id)
:ret number?)
(defn delete-by-id!
[impl file-id]
(...)
(defmethod ig/init-key ::impl [_ {:keys [db]}]
(with-meta
{:db db}
{`interfaces.file-repository/append-files append-files!
`interfaces.file-repository/find-info-by-id file-info-by-id
`interfaces.file-repository/find-content-by-id file-content-by-id
`interfaces.file-repository/delete-file delete-by-id!}))
Should I expect the instrumented delete-by-id!
to throw (cause it does not)FYI this was answered here https://ask.clojure.org/index.php/10347/spec-instrumentation-does-not-work-with-extend-with-metadata
$ bb -e "(defn dyn-match [pat & clauses] (eval \`(clojure.core.match/match ~pat ~@clauses))) (dyn-match [(+ 1 2 3)] [(+ 1 2 3)] :yo)"
:yo
yeah, that is what I figured. Doable but kind of a bummer that we have to know the patterns ahead of time (or use eval
). Would be cool if core.match
had a data driven interface.
I think the main reason it's a macro is that the pattern can be compiled to something efficient
Take a look at matchete if you need something more basic and fn-driven: https://github.com/xapix-io/matchete
or maybe even malli
the usage of the patterns is going to be time sensitive, so I would like the benefit of the efficient compilation. If eval
works, I would be fine with it as I run the compilation “offline”.
I will check out your other suggestions too and see if one of those might be a better fit.
Also #meander has an interpreter which accepts data instead of compile time patterns (it does both)
AFAIK s/fdef
will be checked against only if the corresponding function have been instrumented: https://clojure.org/guides/spec#_instrumentation
With malli:
user=> (m/parse [:catn [:a [:= 1]] [:b :any] [:c [:= 3]]] '[1 2 3])
{:a 1, :b 2, :c 3}
@p-himik yeah the function is instrumented