Fork me on GitHub
#clojure
<
2019-01-08
>
petterik00:01:55

Is there a way to know whether an object satisfies a protocol that's been extended via metadata? clojure.core/satisfies? doesn't seem to work?

(defprotocol IFoo
    :extend-via-metadata true
    (foo [this]))

  (def x (with-meta {} {`foo (fn [x] :foo)}))
  (foo x)
  ;; :foo
  (satisfies? IFoo x)
  ;; false

seancorfield01:01:32

You can query whether the metadata on a given object has entries for the protocol functions you might want to call -- but it would make satisfies? a pretty slow function if it had to walk all the metadata to look for all the protocol functions declared for a given protocol...

seancorfield01:01:58

...and you might only provide one or two of the functions (the ones you actually know will be called) rather than all of them.

seancorfield01:01:40

If IFoo had two functions, foo and bar, and you had an object whose metadata defined just foo, does it satisfy IFoo or not?

phill01:01:51

@whoneedszzz for an API server that is both a server and a client, Zach Tellman's aleph looks excellent. It's built on Netty so it does all sides of networking. It's also built on Z.T.'s rip-snorting "manifold" async library. So your non-blocking code that says "in response to this api request, go ask http://bla for something and when it comes back filter it and return it to the end user" looks perfectly procedural and natural.

WhoNeedszZz01:01:44

I'm running yada on the frontend, which uses aleph. The backend API is separate so I'm using java-http-clj on that end

petterik01:01:16

That's a good point. I don't care about performance in this case so it would have been nice if there was a function in core that made a satisfies? in the metadata. It's quite easy for me to add (contains? (meta x) `foo) in this case.

petterik01:01:34

As for the second point when an object has just defined one of the functions in IFoo, I'd expect satisfies? to work like it does on other object who hasn't implemented the protocol fully:

(defprotocol IFoo
    (foo [this])
    (bar [this]))

  (satisfies? IFoo (reify IFoo (foo [this] :foo))) ;; true

petterik01:01:30

Thanks @seancorfield as always 🙂

seancorfield01:01:16

I guess the check for protocols that can be extended via metadata needs to be

(if (or (satisfies? IFoo x) (contains? (meta x) `foo)) (foo x) (throw (ex-info "Don't know how to foo this!" {:x x})))

seancorfield01:01:52

(or just let it blow up depending on what you need to do in the non-`foo`-implementing case)

👍 5
yuhan04:01:22

Why isn't there an equivalent peek! function for transient vectors in the standard library?

yuhan04:01:42

Say I have a reducing function where each step depends on the previous result and the intermediate steps are all internal

(reduce
 (fn [acc val]
   (let [prev (peek acc)]
     (conj acc (... prev val))))
 [:init]
 coll)

yuhan04:01:35

It would be nice to easily turn it into a transient version

(persistent!
 (reduce
  (fn [acc val]
    (let [prev (peek! acc)]
      (conj! acc (... prev val))))
  (transient [:init])
  coll))

yuhan04:01:36

Is the above code un-idiomatic in some way? I just started learning about transients but I imagine this isn't a rare use case for them.

seancorfield04:01:00

Since a transient vector is both Counted and Indexed, I think the following should be O(1): (defn peek! [t] (nth t (dec (count t)) nil))

seancorfield04:01:49

Not quite as fast as having it built-in but probably good enough if you're going to get enough of a performance boost from switching from persistent to transient vectors in a reduce like that...

Alex Miller (Clojure team)04:01:00

peek is a read op. seems like it should just work on a transient vector, probably just an oversight

Alex Miller (Clojure team)04:01:19

can’t say I’ve ever seen this mentioned before, but feel free to file a jira

yuhan05:01:14

Thanks, I filed one at https://dev.clojure.org/jira/browse/CLJ-2464 - it's my first time using JIRA so I'm not sure if it's done properly.

Joshua Suskalo04:01:33

Where can I find information on how defprotocol's :on-interface directive works?

Alex Miller (Clojure team)04:01:02

that’s not a public feature of defprotocol

Alex Miller (Clojure team)04:01:33

so I don’t know of any info on it

Joshua Suskalo04:01:35

Alright. I've just seen references in some of Rich's comments pointing towards it in the case someone had a particular use case, and I wanted to know more about it.

vemv05:01:28

Is there something like the following for clojure.test (ideally not incurring in the banana-jungle problem; I don't want to change frameworks) expect { ... }.to change { ... }.from(1).to(2) that's ruby rspec in case in case it rings a bell. Else: { ... } represents code blocks (which in clj would be fns, or macro bodies) I actually implemented expect-change in clj a couple jobs ago, can't access the source unfortunately

seancorfield06:01:53

@vemv sounds like you want expectations/clojure-test 🙂

seancorfield06:01:37

https://github.com/clojure-expectations/clojure-test -- it provides an "expect" style syntax on top of clojure.test (so all your existing tooling continues to work).

seancorfield06:01:42

It's not as expressive as rspec… I believe there was actually a "port" of rspec to Clojure years ago but I don't think it is maintained now.

seancorfield06:01:26

Although I'm not sure what expect-change would be in Clojure given the general lack of side-effect-y stuff...?

vemv06:01:29

hmmm interesting! nice job on the library, I appreciate the bridging of both worlds I was familiar with Expectations, perhaps I don't like that a lot of stuff seems to rely on positional arguments, so occasionally typos might mean false positives/negatives > expect-change would be in Clojure given the general lack of side-effect-y stuff...? I'd agree with you for unit testing, but for "controller" tests (in Rails lingo) where I assert that hitting API endpoint causes side-effect x, the technique becomes more useful.

vemv07:01:01

As a random thought, a macro-based impl would rock: (expect (inc!) :to-change @foo :from 2 :to 3) Here, (inc!) and @foo are evaluated in a careful, specific order

seancorfield07:01:04

(deftest side-effect-y
  (expect 2 @foo)
  (inc!)
  (expect 3 @foo))
:rolling_on_the_floor_laughing:

vemv07:01:39

yeah... doesn't meet my standards 😜 BDD-y guy here

valerauko09:01:48

is there a way to globally mock out a function during tests?

valerauko09:01:03

like with-redefs except global

vemv09:01:35

are you using Component/Integrant? A nice approach would be to define per-environment components

5
valerauko09:01:13

i'd want to mock a helper function from a dependency that's irrelevant during tests without having to with-redefs every single time

jeroenvandijk09:01:31

I like to build it in the design of my application. Having dummy implementations for those dependencies, acting similar to the mocked dependency

valerauko09:01:01

actually it's in the dependency of a dependency and mocking that out feels like more trouble than just with-redefsing every test

jeroenvandijk09:01:15

I thought you were after an alternative testing way, but if it's about globally overriding the function.

(alter-var-root #'the-ns/the-function (constantly (fn [& args] "whatever"))
Works too

jeroenvandijk09:01:30

Be sure to not put it in production 🙂

valerauko09:01:01

oooooh that's just the kind of thing i was considering

valerauko09:01:07

be right back trying it out

valerauko09:01:23

yup just what needed! thanks a lot!

👍 5
olieidel12:01:33

what are your opinions on websocket libraries (vs. non-libraries)? I used sente for a side project and had quite some trouble getting started, many concepts to understand and quite opinionated. There’s also the possibility of just hooking into http-kit directly. Anything I’ve missed, what do you prefer?

Robert A. Randolph15:01:05

I have a simple deps.edn, and when I run clj the java process just hangs. What would be the first step to debugging this beyond making sure the dependency exists?

{:deps {org.clojure/clojure {:mvn/version "1.10.0"}
org.openjfx/javafx-fxml     {:mvn/version "11.0.1"}

ghadi15:01:40

upgrade your tools.deps, there was a bug previously

ghadi15:01:51

er, your clojure tool

Robert A. Randolph15:01:29

would explain why perfectly working code didn't work on a different computer

ghadi15:01:39

it’s actually tools.deps doing an infinite loop 100% cpu

ghadi15:01:29

@audiolabs you’re doing that for REBL?

Robert A. Randolph15:01:56

@ghadi yes, I was copying a rebl config to a different system

Robert A. Randolph15:01:09

I'm aware the deps I pasted aren't the full reqs

Robert A. Randolph15:01:21

it's just the minimum that cause the java process to hang

Robert A. Randolph15:01:40

@ghadi yes, that's what I'm using

5
Alex Miller (Clojure team)15:01:35

yeah, definitely make sure you’re using latest clj (now 1.10.0.411)

WhoNeedszZz02:01:37

Getting a maven error for that version string.

Alex Miller (Clojure team)03:01:35

that’s not a Maven artifact

Alex Miller (Clojure team)03:01:16

that’s the clj version (for the Mac brew installer or in the linux scripts at https://clojure.org/guides/getting_started)

WhoNeedszZz03:01:56

So the 1.10.0 artifact pulls the latest?

Alex Miller (Clojure team)03:01:31

they are separate things

Alex Miller (Clojure team)03:01:54

you need clojure (Maven artifact org.clojure/clojure, version 1.10.0)

Alex Miller (Clojure team)03:01:21

and the clj tool (version 1.10.0.411), which you can install with the instructions on the link above

WhoNeedszZz03:01:58

I misread what you were saying. I'm unfamiliar with the clj tool

Alex Miller (Clojure team)03:01:00

What are you trying to do?

Alex Miller (Clojure team)03:01:40

This thread started with a question about how to use the clj tool for REBL with Java 11 and Clojure 1.10

WhoNeedszZz03:01:53

I just wanted to make sure I was on the latest version. I misread what you were talking about is all.

Alex Miller (Clojure team)03:01:13

ok. 1.10.0 is the newest version of Clojure :)

WhoNeedszZz03:01:22

I am on Arch Linux and just install the clojure package. Now I'm just mainly curious if it is the latest version since it just prints out the Clojure version and not the version of the tool itself.

WhoNeedszZz03:01:05

Looks like it is on 1.10.0.408

Alex Miller (Clojure team)03:01:04

I’m not sure what the Arch package is or who makes it, but that sounds like the clj tool. You should be able to type clj at the terminal to get a repl.

Alex Miller (Clojure team)03:01:22

the version of clj is actually independent from the version of Clojure you use

Alex Miller (Clojure team)03:01:41

any version of clj can use any version of the Clojure language

WhoNeedszZz03:01:32

I understand they are two different things so we're good on that

Alex Miller (Clojure team)03:01:55

yeah, that’s just a variant of the linux installers listed at https://clojure.org/guides/getting_started

WhoNeedszZz03:01:17

Right and - usr/share/clojure/libexec/clojure-tools-1.10.0.408.jar

WhoNeedszZz03:01:25

So it's slightly behind

Alex Miller (Clojure team)03:01:49

yeah, just one fairly esoteric bugfix in 411 vs 408 so you are highly unlikely to care

dbernal16:01:13

is there an alternative to doing (merge-with (fn [x y] (or x y)) {:a nil} {:a "val"}) without having to create an anonymous function?

Alex Miller (Clojure team)16:01:08

isn’t that just (merge-with or ...)

dpsutton16:01:58

Any chance you can inhibit nils in your map to begin with?

Alex Miller (Clojure team)16:01:45

I can’t think of an alternative that’s clearer (other than to avoid having nils in the first place)

dbernal18:01:09

gotcha, thank you

eraserhd17:01:17

#(or %1 %2) seems less noisy in this case, but I haven't got anything better

👍 10
yuhan17:01:43

(fn [& vs] (some identity vs)) for the variadic case?

yuhan17:01:09

#(some identity %&)

Audrius17:01:25

Who could advice good material on integration testing on Clojure please?

g17:01:22

hey guys, tearing my hair out over this error i’m getting … some dependency load is failing with ExceptionInInitializerError. this only happens when i run the program on our aws deployment. everything works fine locally. anyone seen this sort of thing before?

g17:01:10

i’m sure the lack of deployment details probably isn’t very helpful, but any place to even start looking would be appreciated

g17:01:24

the print statements i put in all of the dependencies all appear in the logs, so it looks like they’re all getting compiled, oddly enough

g17:01:37

it’s just the encompassing require that seems to be failing somehow

hiredman17:01:06

are you aot compiling? or are any of your deps aot compiled?

hiredman17:01:32

what build tool/dependency manager/classpath builder are you using?

Quest18:01:33

Not sure where to report this, but seems that Clojure 1.9 is missing from https://clojure.org/community/downloads_older ? Spotted because https://clojure.org/community/downloads currently lists Clojure 1.10, but other page only goes up to 1.8. If someone points me in the right direction I can raise a PR (.patch?) on this later, but if it's easy to fix now then go ahead

Alex Miller (Clojure team)18:01:34

that’s my bad, I’ll fix! Thanks for the catch…

👍 5
Alex Miller (Clojure team)19:01:40

If you haven’t completed the 2019 Clojure survey, now’s a great time - takes about 5 minutes. https://www.surveymonkey.com/r/clojure2019

cider 5
10
Alex Miller (Clojure team)20:01:59

I wasn’t sure what to expect with Java usage in the survey but the early results are … interesting

the2bears01:01:19

Haha... "Common household products that can kill you instantly. More at 11" 😂 Captured our interest for sure.

😀 5
cvic09:01:03

Still stuck in Java 7 Land at work... and https://github.com/yetibot/yetibot/issues/804

mpcarolin20:01:27

Care to share what’s interesting? 😄

Alex Miller (Clojure team)20:01:49

oh, just wasn’t sure how people are rolling with the whole Java 9/10/11 and LTS release schedule

Alex Miller (Clojure team)20:01:08

I’ll refrain from details till we get through the whole survey period