Fork me on GitHub
#clojure
<
2020-10-14
>
ccann01:10:49

does anyone know how to interpolate a vector of ids into jdbc/update! e.g. I want my WHERE clause to be where id in ? and then pass in a vector

dominicm11:10:35

You might be able to create a connection, and create parameters for that. I had a lot of trouble with this though.

👍 3
hiredman01:10:56

You cannot

👍 3
hiredman01:10:23

The underlaying java jdbc drivers expect arrays (not vectors)

hiredman01:10:51

So at the very least, you need to pass it an array not a vector

hiredman01:10:20

clojure.java.jdbc also uses setObject which if I recall doesn't work right with arrays even if you pass one in

hiredman01:10:50

I believe that is overridable though

seancorfield01:10:16

@ccann HoneySQL takes care of that for you (by building the appropriate where id in (?,?,?,?,..,?) clause given your vector of IDs.

ccann01:10:47

@seancorfield I’m working on a legacy project where we only have jdbc pulled in and trying to hotfix something

ccann01:10:57

but definitely would prefer to use honeysql

seancorfield01:10:05

If you are using PostgreSQL and next.jdbc you might be able to do this via the array syntax -- see the PostgreSQL Tips and Tricks in the next.jdbc docs.

💯 6
seancorfield01:10:35

But I think with clojure.java.jdbc you're out of luck in that case.

Darin Douglass02:10:26

if your vector gets too large, you'll quickly run into parameter count limits (for PG it's something like Short/MAX_VALUE). but you can do something like below to get around that:

(j/update! db-conn :my-table ["id = ANY(?)" (into-array TheProperClass my-ids)])

seancorfield02:10:37

@ddouglass Does that work with clojure.java.jdbc? I know it works with next.jdbc

seancorfield02:10:20

(that syntax is what is recommended in the next.jdbc Tips &amp; Tricks for PostgreSQL)

Darin Douglass11:10:16

@seancorfield it does. We’re currently using clojure.java.jdbc and that was a sanitized chunk of code from one of our apps

Ivan Fedorov11:10:59

Wishing a good day to fellow Clojurians 🌱 Does anyone know a recurrence implementation in Clojure? (as defined by https://tools.ietf.org/html/rfc5545#section-3.3.10) Or maybe in Java[Script]. Thinking about a plain rule parsing / compiling for starters. They look like RRULE:FREQ=WEEKLY;UNTIL=20110701T170000Z I’ve found http://github.com/jakubroztocil/rrule, but I hope it could be done both easier and simpler, in like 200 lines of thoughtful Clojure code. UPD: I’ve been advised to use spec or malli to build a parser. Can’t say yet if that’s a good idea or not.

markbastian13:10:37

Does anyone here recall a recent call for an upcoming virtual Clojure conference? Maybe within the past 30 days. Seems like they were asking for ~20 minute talks. I can't remember if I saw it here, on twitter, reddit, ... too many platforms.

markbastian13:10:10

Thanks! I tried euroclojure, clojuretre, clojureD,....

schmee16:10:31

is anyone aware of a DSL/macro library for Clojure bit operations?

schmee16:10:43

idk about you but I find (unchecked-byte (bit-and (bit-shift-right inv 8) 16rff) way harder to read than the Java equivalent

noisesmith16:10:26

seems like you could get pretty far with a few well chosen defs

schmee16:10:59

yeah, I’ll probably whip something up but curious to see if anyone else has dealt with this before 🙂

noisesmith16:10:09

|, >>, << are all valid function names

noisesmith16:10:29

also why use 16rff instead of 0xff?

schmee16:10:39

I thought that was not a thing in Clojure?

schmee16:10:04

ahh, it’s 0bxxxx that’s not a thing, I misremembered, thanks!

noisesmith16:10:12

user=> (= 255 0xff 16rff 2r11111111)
true

👍 3
noisesmith16:10:51

forgot to include 0377 above :D

schmee16:10:30

octal, everyone’s favorite 😁

noisesmith16:10:12

@schmee an idea:

(ins)user=> (def |b unchecked-byte)
#'user/|b
(ins)user=> (def |& bit-and)
#'user/|&
(ins)user=> (def |>> bit-shift-right)
#'user/|>>
(ins)user=> (|b (|& (|>> 292928 8) 0xff))
120

noisesmith16:10:14

actually it works without the | on every name, I didn't realize & was a valid function name but it is

quoll17:10:20

Cute… I thought that the special form would get upset with this, but it doesn’t

(def & bit-and)
(defn f [& b] (& (first b) (second b)))
=> (f 3 9)
1

noisesmith17:10:59

right, I think this is because [& ...] is a special case in arg list parsing rather than a special form

noisesmith17:10:08

since it's not used in call position

noisesmith17:10:47

though (special-symbol? '&) does return true

schmee16:10:32

I found https://github.com/rm-hull/infix, which I have seen before but it actually seems perfect for this

schmee16:10:58

normally I wouldn’t consider using infix, but when I have to write pages of byte manipulation I might make an exception

noisesmith16:10:01

having done most of my bit fiddling in assembly, I find breaking the ops into one per line more helpful than infix :D

noisesmith16:10:17

but ymmv clearly

schmee16:10:35

appreciate the input! :thumbsup:

noisesmith16:10:22

as a reader of code, I'd rather review a java file than infix in the middle of a clojure file

✔️ 3
schmee16:10:31

yeah I’m not sold on it either, but I’ll give it a try and see how it pans out

Jeff Evans18:10:00

any Clojure projects out there that actually want Hacktoberfest participation?

vlaaad19:10:46

For all practical purposes the right data structure for my problem is nested vectors. Except one thing: it needs a small piece of data attached that I want to lookup by it's key. Is it okay to put that into metadata, or should I force everything to be a map with 2 keys (data and a vector with maps of same shape)?

phronmophobic19:10:03

it might help to see an example data value, but one is the data you are considering putting in meta data actually meta data?

vlaaad19:10:34

example:

=> {:grid [[{:grid [[{:grid [[{}
                              {}]]
                      :cursor [311708 475413]}]
                    [{:grid [[{}]
                             [{:grid [[{}
                                       {}]]
                               :cursor [121699 68040]}
                              {:grid nil
                               :cursor [930988 26115]}]]
                      :cursor [136580 790398]}]]
             :cursor [162873964 1315]}
            {}]]
    :cursor [42984 203305]}

vlaaad19:10:55

the data I'm considering putting is not a meta data, it's pretty much very important data

vlaaad19:10:59

but this structure makes lookups and updates hard, since I have to switch maps and vecs all the time, instead of doing assoc-in/ get-in using only coordinates

phronmophobic20:10:58

why not just make a function that looks like assoc-in / get-in but works with these structures?

vlaaad20:10:18

that's what I did for now

vlaaad20:10:06

I just don't like it. It could be get-in, but it has to be a separate function that interposes items with :grid

hiredman20:10:33

a common problem I feel like I see a lot is entangling the kind of logical structure of data with the physical structure.

hiredman20:10:02

one way this happens a lot is people writing games with grids try to represent the logical grid structure as a physical nesting of vectors, since that is the physical structure that most closely kind of looks like a grid

hiredman20:10:37

but a grid is just an index

hiredman20:10:17

a way to look up values by column, row, and maybe a combination of column and row

hiredman20:10:05

and once you treat it as a general index/lookup function you can start hanging other data in there and other indices and ways to do lookups

hiredman20:10:01

so the common advice is to make it a map with a pair [col, row] as keys

hiredman20:10:58

and depending on what you are doing that might be enough, but it isn't a fully general indexing system (you can't lookup all the items in a colum or all the items in a row, etc)

Nassin20:10:45

looks like nested vectors is the more flexible then 😉

hiredman20:10:09

absolutely not

Nassin20:10:12

well, for you grid example, query individual columns or row is trivial

phronmophobic20:10:15

I think focusing on the data type and what abstract operations it should fulfill is a good idea. you can then change the underlying implementation as needed depending on usage and performance

vlaaad20:10:29

well, for all the uses I have nested vectors beat maps. I need to know last row. Given a row, I need to know last column. In the app there will A LOT of such data structures, so memory is also concern

hiredman20:10:41

but you can't hang any additional data anywhere, and you can't efficiently do inverted queries "give me all the column ids that a value bar somewhere in them"

vlaaad20:10:01

I don't have such use case

hiredman20:10:24

"Except one thing: it needs a small piece of data attached that I want to lookup by it's key."

vlaaad20:10:15

That one thing is "given coordinate path, I want to lookup a cursor at that path"

vlaaad20:10:55

poor wording in the initial description, sorry

hiredman20:10:10

updates another place where conflating the logical structure with the physical structure makes things tricky

hiredman20:10:00

it is a lot easier to update a "flat" index (thing a normalized database schema) then a deeply nested tree structure

vlaaad20:10:53

But I do have nesting, it's not a matrix NxM, it's a rows of varying length, where every item is itself a rows of varying length

hiredman20:10:22

that is literally the description of the logical structure of data in a graph database

hiredman20:10:38

where the data itself is stored in a flat index structure

donyorm22:10:02

Is there a way with tools.deps to list all dependencies (including transitive ones)? I want to be able to search for a specific dependency to see if it's included in my classpath?

p-himik23:10:54

clj -Stree

dpsutton23:10:08

-Stree Print dependency tree from clj --help

dpsutton23:10:17

(so you know where to find help with that in the future)

donyorm00:10:53

Wow thanks, sorry I somehow missed that.

wombawomba23:10:11

So I noticed that a library I was using (cljs-ajax) has deprecated EDN as a HTTP request format in favor of Transit, which got me thinking: what are the downsides of using EDN over HTTP? And how is Transit better?

p-himik23:10:22

https://github.com/JulianBirch/cljs-ajax/issues/47#issuecomment-51251520 Couldn't find where exactly EDN is "explicitly not recommended for browser API" though.

wombawomba23:10:03

alright, thanks

wombawomba23:10:47

sounds to me like there aren’t any clear drawbacks to using EDN per se, except that there aren’t good parsers in most languages

wombawomba23:10:13

I guess another drawback could be that there’s less tooling for e.g. routing or deep packet inspection for EDN payloads than for JSON

p-himik23:10:48

I think there were some other reasons. The one that I can remember is that compression is built into transit, which is nice to have.

Alex Miller (Clojure team)00:10:58

transit is designed for wires and should definitely be preferred for that use case

Alex Miller (Clojure team)00:10:34

in particular, it's designed to work over json and many languages (critically javascript) have very fast native json parsers. Also, it has caching built in for repeated keys etc so will generally be significantly smaller for common use cases (passing many maps with the same keys) and thus also faster.

Alex Miller (Clojure team)00:10:50

edn is designed for places humans read and write data (like config files). transit is also designed to be more extensible in efficient ways - edn has tagged literals but they're not quite as good for crossing machine/language boundaries.

p-himik00:10:37

Ah, it was the point on tagged literals that I was thinking of. Thanks!

wombawomba10:10:06

cool, thanks for the elaborate response :)