Fork me on GitHub
#clojure
<
2015-09-12
>
sanitar4eg10:09:28

hello everyone, i new in clojure. I start learn it by 4clojure puzzles. And i have trouble with varargs, please give me referens to few examples with it. Thank PS Sorry for miss chanel

dottedmag10:09:47

Is there a more idiomatic way to calculate "map difference" (map with keys which are not in another map) than (select-keys a (clojure.set/difference (set (keys a)) (set (keys b))))? It works, but it looks ugly.

timvisher11:09:20

@beppu: agreed that it’s weirdly opaque simple_smile

timvisher11:09:10

@dottedmag: useful has a filter-keys function which you could use to do (filter-keys a (set (keys b)) or summat https://github.com/amalloy/useful/blob/develop/src/flatland/useful/map.clj#L223-L227

dottedmag11:09:49

@timvisher: Thanks. Useful looks, uhm, useful.

timvisher11:09:05

it doesn’t look like plumbing has anything

timvisher11:09:25

(key-difference a b)

dottedmag11:09:36

It definitely does. Thanks.

dottedmag11:09:21

Oh, (apply dissoc). Clever.

timvisher11:09:40

@dottedmag: if you weren’t already familiar, useful, plumbing, and suchwow are the defacto bag-o-stuff libraries. i generally check them before i implement my own thing

timvisher11:09:49

there may be others. i just haven’t heard of them yet

timvisher11:09:29

i have some memory of @ztellman wanting to release one. he might have

dottedmag11:09:33

@timvisher: I had hoped that clojure is not infected with underscore.js-ism, but alas.

timvisher11:09:02

yeah. i hear you simple_smile

dottedmag11:09:42

By the way, is there a way to reexport symbols from the namespace? I'm thinking about project.util, pulling in useful functions from bag-o-stuff libraries.

timvisher11:09:45

fwiw any of the libraries i listed above are not that defacto (they’re not jquery/underscore). but i hate re-implementing things so if someone else already has, 🤷

timvisher11:09:42

fwiw, i wouldn’t bother. if you want it for the docs then maybe just a basic wrapper function would do. if you don’t want it for the docs then the extra weight in the jar doesn’t matter that much simple_smile

timvisher11:09:46

but it depends

daniel.keogh11:09:18

What's underscore.js-ism? (And what's wrong with it?)

dottedmag11:09:05

It's a disease of languages with such a stagnant standard libraries that a bunch of "you-ought-to-put-it-into-stdlib-but-can't-be-bothered-so-I-wrote-a-separate-one" libraries spring into an existence.

dottedmag11:09:52

Drawback (as usual) is an increased complexity.

daniel.keogh13:09:05

Is there any language where you can say the standard libraries are so complete?

akiva14:09:28

I think it’s a bit of an unfair comparison, really, and highly personal. Libraries like underscore and lodash present for JavaScript more than just ‘this should be in baked in’. I like the fact that, for the most part, Clojure’s core libraries are fairly lean. At the same time, I can understand why they’re in 1.8 adding a bunch of wrappers, for instance, in core.string for standard activities (e.g., starts-with? and index-of).

meow15:09:47

speaking of all these back-o-stuff libraries, I'm wondering if this is a common pattern at all?

(defn gen
  "Returns a function that, when called, will call f with an incremented
   generation value."
  [f]
  (let [generation (volatile! -1)]
    (fn []
      (vswap! generation inc)
      (f @generation))))

meow15:09:56

I had a recursive process where I didn't want to introduce the logic to increment the counter each time through the loop so I put that logic in this wrapper.

meow15:09:37

Where the heck is the documentation on volatiles? I know I read something about them, but can't find anything on http://clojure.org

amacdougall15:09:43

I know it's not a great state of affairs when SO answers are more informative than the official documentation, but on the other hand, thank God for SO.

meow15:09:08

@amacdougall: Yeah, that was about all I found as well. Was hoping to find more examples, especially when used outside of a transducer, such as I'm doing here.

meow15:09:45

In my case I could use an atom as well, since performance isn't really an issue where I'm using this function.

amacdougall15:09:00

That's way beyond me, I'm afraid. Probably someone on here can help, but you might need to ask again later. Depends on who's on.

meow15:09:08

Really just wanted to generalize it and/of see if anyone else is doing similar.

bronsa16:09:23

@meow: a clojure volatile! is just a container for a jvm volatile field

bronsa16:09:47

you'll get tons of documentation if you google for "java volatile"

meow16:09:39

@bronsa: Thanks. I'm actually good with volatile, just surprised there were no real docs on http://clojure.org is all.

amacdougall19:09:43

Say, has anyone used the (is (thrown? ExceptionClass <body>)) form in clojure.test to catch SQL exceptions during invalid database usage? I've got this test:

; user-values was used to create a user earlier in the test, so this creation attempt violates a unique value constraint
(testing "creating user with duplicate email fails"
  (is (thrown? SQLException (db/create-user<! user-values))))
But instead of catching the exception and reporting a success, the test runner surfaces the exception and reports an error. The actual exception type is org.postgresql.util.PSQLException, but since that extends java.sql.SQLException, it should be caught (and is caught, when I try/catch it in the REPL). And of course I've got (:import java.sql.SQLException) in my ns declaration.

amacdougall19:09:06

Just as a smoke test, I verified that the usual example, (is (thrown? ArithmeticException (/ 1 0))), does work.

amacdougall19:09:39

Hm... when I change it to (thrown? Error, it gives me slightly more useful console output:

ERROR in (test-user-creation) (QueryExecutorImpl.java:2270)
  │creating user with duplicate email fails                                              
  │expected: (thrown? Error (db/create-user<! user-values))                              
  │  actual: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "users_username_key"                                                     │
  │  Detail: Key (username)=(tbogard) already exists.
...but since PSQLException is an Error, I'd think this assertion would pass. In Java, subclasses are considered instances of their superclass, right?

amacdougall19:09:09

Anyway, if I test (thrown org.postgresql.util.PSQLException, it fails just the same, but it's worth noting that when ... oh. I get it. Since there was an exception, the transaction is aborted, so further tests can't occur!

amacdougall19:09:34

Clearly I need to think carefully about when (or whether) to do multiple tests in one transaction.

timgilbert20:09:22

@amacdougall: someone I work with just ran into a very similar issue, we have most of our db-affecting tests running in transactions (also against postgres)

timgilbert20:09:57

He just figured out what was happening at the end of the day, hasn’t thought of a solution yet for it

amacdougall20:09:22

Perhaps it should have been obvious when I noticed that I was not seeing the exception I expected, because it was correctly being caught by (is (thrown?... but I was seeing later exceptions stating that the transaction had been aborted. But it took a while for it to come into focus.

timgilbert20:09:25

But yeah, he was intenionally running code to throw a pgsql exception

amacdougall20:09:51

I've solved it by simply doing one test per transaction, or a few tightly focused ones that don't expect to generate exceptions.

timgilbert20:09:12

Cool, that seems like a good idea

timgilbert20:09:59

Hey, I have a random question everybody: I’m trying to find a concise way to go from a map {:a true :b false :c false :d true} to a seq of the just the keys whose values are true: (:a :d)

timgilbert20:09:28

Not hard to do but I keep thinking I’m missing an obvious clojure-ism

amacdougall20:09:19

(->> (vec m)
  (filter (fn [[_ v]] v))
  (map first))
Not exactly Shakespeare. It does seem like maybe there would be a standard library way of doing it.

timgilbert20:09:16

What I’ve got now is (map first (filter (fn [[k v]] (when v k)) m))

timgilbert20:09:44

Pretty similar but I still feel like it could be simpler

timgilbert20:09:50

Er, (map first (filter (fn [[_ v]] v) m))

timgilbert20:09:53

I guess (keep (fn [[k v]] (when v k)) m) works. I still hope to find a way to do it without destructuring inside of a (fn) argument though

manytrees20:09:04

Maybe (map first (filter val m))?

amacdougall21:09:05

Oh hey, here's a real beginner question... in languages with infix notation, it's wrong to use "Yoda conditions", like saying if (1 == x). But in Clojure, it doesn't seem as obvious whether to say (= 1 x) or (= x 1). Is there a consensus?

blueberry21:09:31

just for the record, i find yoda conditions convenient in C, since then you will not make a if (x = 1) mistake (that you'll get warned, but anyway

blueberry21:09:56

In Clojure, I prefer to write (< 5 x) and (< x 10) or (< 5 x 10 y 20)

blueberry21:09:13

for =, I usually write it yoda style...

timgilbert21:09:02

I like that best @manytrees, thanks!

timgilbert21:09:49

Oh, actually: (keys (filter val m))

timgilbert21:09:41

I’m a little surprised that keys can turn ([:a true] [:d true]) back into a map and then get the keys out of it though

Alex Miller (Clojure team)23:09:07

It doesn't - keys works on a seqable of map entries