This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-13
Channels
- # atlanta-clojurians (1)
- # beginners (148)
- # boot (13)
- # capetown (1)
- # cider (38)
- # cljs-dev (92)
- # clojure (61)
- # clojure-brasil (1)
- # clojure-dev (6)
- # clojure-italy (21)
- # clojure-losangeles (1)
- # clojure-nl (7)
- # clojure-norway (20)
- # clojure-spec (70)
- # clojure-uk (64)
- # clojurescript (69)
- # core-async (11)
- # cursive (6)
- # data-science (2)
- # datomic (50)
- # docker (2)
- # duct (12)
- # figwheel (1)
- # fulcro (81)
- # graphql (19)
- # jobs (3)
- # jobs-discuss (44)
- # keechma (1)
- # leiningen (1)
- # mount (2)
- # off-topic (10)
- # onyx (19)
- # parinfer (3)
- # portkey (6)
- # re-frame (4)
- # reagent (145)
- # reitit (1)
- # ring (1)
- # ring-swagger (2)
- # specter (1)
- # sql (4)
- # tools-deps (43)
- # unrepl (29)
- # vim (1)
If I have a bunch of futures in a list, is it a good idea to (map deref)
on it to wait for everyone?
Or is there a better way?
If you just want to wait, and aren't going to consume the future values as a result of the map
call, yeah run!
is about as succinct as it can get
I'm concatenating them all and then writing the result to a file, but it may be better for each future to write to the file since order doesn't matter...? Or may it cause problems if I do that?
if they are in futures for performance reasons, consider that writing to a file might be the slowest part
So I did it, I scraped the entire MTGMarket website for card names and their price. Each future was meant to deal with one specific page of a giant table.
Is :gen-class
’s :methods
still the only way to add annotations to methods, as shown here: https://github.com/clojurebook/ClojureProgramming/blob/master/ch09-annotations/src/main/clojure/com/clojurebook/annotations/junit.clj
It’d be nice if the annocations can be added to the functions instead…
@xiongtx functions aren't methods, they are objects that extend IFn (which has an invoke method and applyTo)
@xiongtx you can make an annotated method without a gen-class, but then you need something that defines a method (eg. reify, proxy, defrecord ...)
@noisesmith What I’m wondering is if, by using :gen-class
, I have to add the annoations in the :gen-class
bit, like:
(:gen-class
:name foo.bar.WithdrawalApprovedTest
:methods [[^{cucumber.api.java.en.Given {:value #"^a withdrawal is in the DB$"}}
a-withdrawal-is-in-the-db [] void]])
Or whether the annotation can be added to the function instead.what would you annotate on a function?
if you need an annotated method, you can't use a function for that - you don't have control over how function objects create methods
Hmm, yeah, that makes sense. Then :gen-class
doesn’t know anything about the function until it looks it up, so annotations on the function can’t inform :gen-class
, I suppose.
the gen-class ends up creating a stub method that just uses the function, and it won't use annotations on the function (even if you figured out how to put it here)
as far as I know at least
I'll go ahead and use the eval, resolve seems harder, since it can't work with locals and non symbols
@xiongtx I've written (Java) annotated functions in Clojure for New Relic agent tracing... let me get the blog post about that...
See if this helps http://seancorfield.github.io/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/
I used definterface
and deftype
to create a framework in which to place annotated methods.
When using :extends
in a :gen-class
, is there a way to access fields of the extended class?
Seems that :exposes
is the way: https://stackoverflow.com/a/44832808/864684
greetings! is https://github.com/scgilardi/slingshot still a thing? is it actually noticeably useful compared to regular try/catch? and when?
it is most common to use normal try/catch. But additionally, slingshot provides additional functionality that is useful and I’ve gotten a lot of value out of that too.
for instance, with clj-http
I found this pattern useful:
(try+
,,,
(catch [:status 401] {:keys [request-time headers body]}
))
does anyone have a repo they can point me to w/ a test suite they love? i want to get a sense for how the clojure community thinks about granularity of tests, organization of tests, etc
What is the CLJ view of https://www.lively-kernel.org/ ? An idea worth copying, or no fundamental ideas / misguided ?
Has benefits. The environment becomes a first class thing you can pass around, but then you end up with incompatible environments, as became the case with lisp and smalltalk "images"
@U8ZA3QZTJ: I'm missing somethihng, what does smalltalk/clojure have to do with storing entire documents in an URL ?
Hmm? I was replying to your post - your post is the one that asked opinions of lively-kernel, and I mentioned something closely related
Storing stuff in a URL isn’t the point, it’s that self-contained bots are a possible future
thats.... unpleasant
In Clojure is there a way to do protocol composition? Being able to create new protocols out of other protocols similar to how you can create new Go interfaces using composition?
protocols are maps. it’s possible to programmatically manipulate them.
@dnaeon: the way it's typically done is to make protocols that represent each aspect of a data type, then implement a group of them, you can look at the protocols / interfaces implemented by built in clojure types with supers
user=> (supers (class {}))
#{clojure.lang.IFn clojure.lang.IObj clojure.lang.IMapIterable java.lang.Runnable java.io.Serializable clojure.lang.APersistentMap clojure.lang.AFn java.util.concurrent.Callable clojure.lang.ILookup clojure.lang.Seqable java.lang.Iterable clojure.lang.IHashEq clojure.lang.Counted clojure.lang.IPersistentCollection clojure.lang.Associative clojure.lang.IKVReduce clojure.lang.IMeta java.util.Map clojure.lang.MapEquivalence clojure.lang.IPersistentMap clojure.lang.IEditableCollection java.lang.Object}
I'm working on project which would need to abstract things on the storage backend side, so that we can have different storage backend implementations. Currently the storage backend protocol consists of a few functions for getting a particular thing (e.g. get-user
, put-user
, etc.).
While still evolving I suspect other things would show up as well (e.g. more functions like get-foo
, put-foo
, etc.), so my concern is to keep the whole protocol small and tight and was hoping to use some kind of composition. Another possibility I was thinking of is having a protocol for each type, e.g. defprotocol User
with it's functions, another one defprotocol Foo
, etc.
Which way is better to go? Should I go with one big protocol, or separate protocols for each type and have each backend implementation implement only the protocols it is concerned about? What is considered most idiomatic in Clojure? Or am I going in the wrong direction as a whole? 🙂
separate protocols is definitely better
right - in this case encestors and supers return the same thing
user=> (= (ancestors (class {})) (supers (class {})))
true
ancestors appears to be supers + derive
ancestors calls supers, and adds to the results
derive is what creates the global multimethod heirarchy
@noisesmith is having separate protocols for each type something that is considered idiomatic in Clojure? Thanks for all the feedback so far! 🙂
@dnaeon: yes, in idiomatic clojure the only reason to include two methods on one protocol or interface is if they are coupled
clojure.core is made of a large number of very thin interfaces
@noisesmith thanks a lot, I know what to do now. Was having some doubts myself, but your answers made things clear for me on how to move forward. Thanks again!
It seems that the :exposes-methods
option of :gen-class
requires that the exposed-name
be different from the super-method-name
; otherwise the generated class will have methods w/ duplicate names / sigs.
Is this just the way gen-class
works? Don’t really see anything in the documentation about it.