Fork me on GitHub
#clojure
<
2017-04-11
>
benzap00:04:33

I"m noticing an interesting issue, and i'm not sure if it's a bug or not. When I create a profiles.clj in my projects folder, and add stuff to override things for my :dev environment, it doesn't appear to be merging with the project.clj's :profile section, and instead overwrites the entire section. Is this intentional behaviour?

benzap00:04:54

I was expecting the project.clj's :profile :dev section to be merged with the profile.clj's :dev section. It seems to be completely wipe out my project.clj's :profile :dev section

benzap00:04:47

ie. my profile.clj has {:dev {:env { :secret-key "abc" }}} and my project.clj has {:profiles {:dev {:dependencies [...]}}}

benzap00:04:55

when I start up a repl, the dependencies disappear, and my user.clj can't find them. If I rename profiles.clj --> _profiles.clj, everything works again, minus the secret-key that I wanted to define

benzap00:04:36

>Remember that if a profile with the same name is specified in multiple locations, only the profile with the highest "priority" is picked – no merging is done

benzap00:04:46

i'll be damned

hiredman00:04:16

merging is hard

hiredman00:04:31

precedence rules are the worst

benzap00:04:23

Alright, so I did what it suggested right below. Seemed to do the trick

quan05:04:34

hi, do anyone know how to query in jdbc with array input

quan05:04:49

something like (jdbc/query db-spec ["select * from table where id in (?)" ids])

pesterhazy07:04:46

generate a string where id in (?,?,?,?) and then (apply jdbc/query ... ids)?

quan07:04:40

ah, oki, so there is no built-in support in jdbc?

pesterhazy07:04:58

not that I know but would be happy to learn if there is

pesterhazy08:04:49

I'm not sure if all databases support this feature (`?` placeholders that expand to multiple values)

raspasov08:04:51

can a de-structuring expert please enlighten me 🙂 here:

raspasov08:04:12

(let [#:omg-im-not-typing-this{:keys [display-name]} {:omg-im-not-typing-this/display-name "Mars"}]
  display-name)

raspasov08:04:16

=> “Mars”

raspasov08:04:19

so that works…

raspasov08:04:47

(let [#:omg-im-not-typing-this{:keys [display-name] :as m} {:omg-im-not-typing-this/display-name “Mars”}]
  display-name)

raspasov08:04:52

ExceptionInfo Call to clojure.core/let did not conform to spec:
In: [0 0] val: #:omg-im-not-typing-this{:keys [display-name], :as m} fails spec: :clojure.core.specs/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0] val: #:omg-im-not-typing-this{:keys [display-name], :as m} fails spec: :clojure.core.specs/seq-binding-form at: [:args :bindings :binding :seq] predicate: vector?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/local-name at: [:args :bindings :binding :map :mb 0 :sym] predicate: simple-symbol?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/seq-binding-form at: [:args :bindings :binding :map :mb 0 :seq] predicate: vector?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/map-bindings at: [:args :bindings :binding :map :mb 0 :map] predicate: coll?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/map-special-binding at: [:args :bindings :binding :map :mb 0 :map] predicate: map?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/ns-keys at: [:args :bindings :binding :map :nsk 0] predicate: (-> % name #{"syms" "keys"})
In: [0 0 1 1] val: m fails spec: :clojure.core.specs/ns-keys at: [:args :bindings :binding :map :nsk 1] predicate: vector?
In: [0 0 1 0] val: :omg-im-not-typing-this/as fails spec: :clojure.core.specs/map-bindings at: [:args :bindings :binding :map :msb 0] predicate: #{:as :or :syms :keys :strs}
:clojure.spec/args  ([#:omg-im-not-typing-this{:keys [display-name], :as m} #:omg-im-not-typing-this{:display-name "Mars"}] display-name)
  clojure.core/ex-info (core.clj:4725)

rauh08:04:12

@raspasov Just like your :keys the :as will get namespaced.

rauh08:04:36

But only :keys will be good for destructing.

raspasov08:04:55

ok so is :as not supposed to work at all in this case?

raspasov08:04:37

that feels odd, wonder if it’s on purpose/what’s the reasoning behind it

rauh08:04:55

No, also IMO namepsacing doesn't make sense in this case. It's another step to parse for the programmer, and you only use it once.

rauh08:04:19

I always just write {:foo.bar/keys [a b c]}

raspasov08:04:50

@rauh ah interesting, ok; I literally just discovered this works at all after using namespaced maps for months 🙂

mpenet08:04:01

(let [#:omg-im-not-typing-this{foo :display-name} {:omg-im-not-typing-this/display-name "Mars"}]
  foo)

mpenet08:04:10

doesn't work either

bronsa08:04:04

this is because you're using the namespaced maps syntax wrong

bronsa08:04:45

namespaced map syntax only qualifies keys in a map

bronsa08:04:05

that's producing {omg/foo :display-name} rather than {foo :omg/display-name}

clojureman08:04:15

Don’t mess too much with destructuring - it is in Clojure as an afterthought

raspasov08:04:28

@rauh but I see what you mean about namespacing the :as as to why it’s not supported in the first place

clojureman08:04:37

(let [{x (inc 2) y x} {3 8, 8 19}]
  y)
=> 19

(let [{x (inc 2) a x b 1 c 2 i a} {3 8, 8 19}]
  a)
=> 19

(let [{x (inc 2) a x b 1 c 2 d 3 e 4 f 5 g 6 h 7 i a} {3 8, 8 19}]
  a)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context

raspasov08:04:25

@clojureman I would not go that far to say it’s an afterthought 🙂

clojureman08:04:45

This shows how it is glued on to the language - and actually works quite well anyhow

clojureman08:04:26

@raspasov, the story is that it is - though I do not remember where I read it

clojureman08:04:12

Something that Rich thought about for a a day or something, then came up with the current solution

bronsa08:04:37

that's not the case at all -- you're thinking of something else and that's even a misquote

clojureman16:04:32

@bronsa, it seems you are right about this - that it is sequential map destructuring that came about in a very small commit. Still the entire destructuring has a definite “glued on" feeling to it, largely because of the “extra” application-specific semantics that are (wisely) not mentioned in the standard documentation https://clojure.org/reference/special_forms#binding-forms, and because of the non-obvious way it reads to someone new to the language. Don’t get me wrong, I love the destructuring of Clojure, but I don’t think it feels like a first class citizen of the language.

bronsa18:04:56

well, it is

raspasov08:04:16

@clojureman I think in your examples you’re kinda abusing destructuring 🙂 in real life cases I’ve never used anything like that;

clojureman08:04:52

Not abusing - just demonstrating a point

clojureman08:04:45

If you undertand what’s going on in the examples, you understand destructuring in Clojure better than most programmers

raspasov08:04:01

but what’s the point? I think you’re exploiting an implementation detail that maps are ordered a certain way up to n-elements (don’t remember how many exactly)

clojureman08:04:30

I am not exploiting anything - just demonstrating a mechanism

mpenet08:04:33

another one, my pet peeve is with :or that always eval it's args, unlike (or ..)

raspasov08:04:42

I’ve been using Clojure for almost 4 years now, so I get most of them, yes 🙂 and from my point of view that’s abuse 😄

raspasov08:04:25

ok I think we should really move this off the main chat 🙂

mpenet08:04:40

got a memory leak because of that one a few years ago

raspasov08:04:15

but just to wrap up… in this example (let [{x (inc 2) y x} {3 8, 8 19}] y)

raspasov08:04:49

if the input map was like {3 8, 8 :a}

raspasov08:04:10

there’s absolutely no guarantee that you won’t be incrementing a keyword….

raspasov08:04:30

so a code like that should never exist in the first place

clojureman08:04:17

The code demonstrates aspects of how destructuring works, it is not something that should exist in real life

raspasov08:04:33

basically you’re relying on a current implementation detail that was never guaranteed to stay like it is forever

bronsa08:04:56

that's just not how destructuring should work

bronsa08:04:19

it happens to work because of an impl detail but to use it for real is just wrong

bronsa08:04:39

the serial binding in map destructuring

rauh08:04:00

@raspasov You're relying on the way the reader generates an array map and how that is iterated over in the desctructure macro

raspasov08:04:34

it wasn’t me! 😄

rauh08:04:25

You'll lose that as soon as you're in Hash map territory.

bronsa08:04:26

it's very wrong and your code will likely break in future versions of clojure if you rely on that

mpenet08:04:36

the :or one is more insidious, I guess it might be more of a naming issue, not sure

clojureman08:04:23

The real problem is that destructuring is not as much a language feature as something that was shoehorned into the compiler as an afterthought. That is also why it takes some getting used to for beginners

bronsa08:04:36

@mpenet yeah the :or one can be argued about, contrary from the one @clojureman is talking about

bronsa08:04:40

@clojureman no that's not true

raspasov08:04:44

ok guys/gals, enough fun discussions for tonight, let’s all do something productive, ttyl 🙂 ✌️

bronsa08:04:16

destructuring wasn't shoehorned as an afterthought it was a very important feature that was added in userspace

bronsa08:04:43

and great amounts of time went into thinking about its different features during the years

bronsa08:04:06

yes, sometimes it behaves weirdly if you use it in an incorrect way but.. that's on you

bronsa08:04:27

as far as I agree with that ticket I'm afraid it's going to behard to change behaviour w/o breaking user code

mpenet08:04:47

I guessed as much yes

mpenet08:04:36

but relying on side effects in an unused :or would be wrong anyway

mpenet08:04:48

so, arguable

bronsa08:04:56

altho it's probably fair to assume that most would think :or already short-circuited so..

blane09:04:11

hey guys, i'm having trouble building lein uberjar within a container. I am getting a 502 from nexus

Return code is: 502 , ReasonPhrase:Bad Gateway.
This could be due to a typo in :dependencies or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
Uberjar aborting because jar failed: Could not resolve dependencies
It builds locally but this error occurs within the container, can someone point me in the right direction? thanks

pyr09:04:19

good morning #clojure!

pyr09:04:05

I often want to do the equivalent of transduce on a channel, with no interest in the resulting value.

pyr09:04:16

An my bad way of doing this is to do: (transduce my-transducer (constantly :foo) nil input-chan)

pyr09:04:23

The advantage I see here is that I can take on the output chan to ensure my input-chan is fully traversed

pyr09:04:33

Is there a better way to do this?

benh09:04:16

just use a go-loop that takes values off the channel and applies your (side-effect laden) functions to them ?

pyr09:04:01

I wanted to avoid using a go-loop

benh09:04:29

you might try using (into [] my-transducer input-chan)

benh09:04:33

or similar

mpenet09:04:08

sounds like loop might be more idiomatic (longer to write tho) just to apply a function to channel values

mpenet09:04:23

(loop [] (when-let [x (a/<!! ch)] (f x) (recur)))

mpenet09:04:28

or maybe not so long

mpenet09:04:43

but it's not using a transducer, but the example you provide makes me wonder if you need to use transducer at all (I guess if it used somewhere else: yes)

pyr09:04:01

yeah, that was the idea

benh09:04:21

you can pass a transducer in to the channel when you construct it; but you will still have to arrange drainage of that channel

benh09:04:41

or just use a dropping buffer

pyr09:04:52

ah, dropping buffer makes sense

pyr09:04:09

wait no, that still wouldn't give me knowledge of when the input chan is drained

pyr10:04:28

thanks anyhow!

qqq10:04:55

what clojure env is closest to squeak in terms of 'liveness' ?

mbjarland13:04:27

Hi. Somewhat noob to clojure and my first post here so Hi All! | Any suggestions for a fast non-production mostly-development-time framework for persisting clojure datastructures (maps, vectors of maps etc) on disk or in some kind of "system" (ie database or whatever the framework chooses to call itself)? Mapdb comes to mind, but maybe there are better options out there. Performance (more specifically read-performance) being the operative word here. Haven't tried datomic but I would suspect performance might be less stellar than say mapdb

lsenta13:04:51

@mbjarland I've been using replikativ/konserve for the past week. It's a "minimalist storage protocol" with various backends that seem's to be """Clojure's RocksDB"""

mbjarland13:04:03

looks interesting

lsenta13:04:14

It feel very practical and useful to me, if that fits your requirements: much recommend

mbjarland13:04:12

Hmm, initial fun with konserve 0.4.8:

user=> (load-file "src/konserve/core.clj")

CompilerException java.lang.Exception: Cyclic load dependency: [ /konserve/filestore ]->/konserve/core->[ /konserve/filestore ], compiling:(konserve/core.clj:1:1) 
user=> 

mbjarland13:04:22

from the example on their github page...

mbjarland13:04:26

@lsenta anything you've run into?

mbjarland13:04:31

seems the following is enough to trigger the error above:

(ns konserve.core
  (:require [konserve.filestore :refer [new-fs-store]]))

jrychter14:04:31

Thinking about a new computer, I found it interesting and slightly ironic, that one of the important rationale points for Clojure made by Rich several years ago was that we need to make good use of multiple cores. And yet today I'm looking for a machine with the best possible single-core performance, because when doing development work in Clojure and ClojureScript, multiple cores aren't really getting used (beyond say 2).

jstew14:04:38

Just get one with the best possible performance and don't worry about how many cores it has. Like the "old days". Even so, the other software that you're running on that same machine may use all cores.

jrychter14:04:29

Well, there are compromises to be had: more cores usually also means worse single-core performance, so it isn't as clear-cut.

timo14:04:43

has anyone have a good resource on java interop for a beginner?

mpenet14:04:03

@jrychter most impressive compile times/dev experience I've seen is with ocaml, which doesn't even support multicore (yet)

mpenet14:04:49

but the trade off matters depending on the context

yonatanel14:04:24

Will pedestal.kafka be open sourced soon? https://youtu.be/_Cf-STRvFy8?t=1835

timo15:04:57

(doto (java.util.Stack.)
  (.push "Latest episode of Game of Thrones, ho!")
  (.push "Whoops, I meant 'Land, ho!'"))

timo15:04:20

what if I want to use a final class instead of Stack?

carter.andrewj15:04:30

Is this supposed to happen? (reduce #(some-fn %1 %2) [12345] some-coll) ==> %1 = 12345 (reduce #(some-fn %1 %2) [[12345]] some-coll) ==> %1 = [[12345]]

carter.andrewj15:04:43

How can I get %1 = [12345] ??

bronsa15:04:59

the first one doesn't make any sense

carter.andrewj15:04:09

That's what I'm seeing

carter.andrewj15:04:17

(And I fully agree)

bronsa15:04:33

no that's simply impossible

bronsa15:04:47

your some-fn must be doing something else

carter.andrewj15:04:10

I replaced it with #(do (println %1) (some-fn %1 %2))

bronsa15:04:14

%1 will be [12345] on the first invocation of some-fn if that's your reduce form, there's no way it's going to be anything else

bronsa15:04:23

user=> (reduce #(do (doto %1 println) %2) [12345] [1 2 3])
[12345]
1
2
3

carter.andrewj15:04:51

Closed repl > lein clean > lein run = works

carter.andrewj15:04:56

God knows what happened there

Doug Kirk16:04:23

Is there a fn similar to Scala's collect, which takes a fn A -> B and a collection, and returns a collection of all non-nil B's? (vec (flatten (mapv fn coll))) seems too wordy (and I dislike having to convert vec -> list -> vec).

Doug Kirk16:04:07

awesome, thanks!

danp18:04:13

Hey all, I posted the following to #beginners earlier, but thought I'd repost here to subject it to more eyes!

danp18:04:52

I'm trying to pull data from Oracle using clojure.java.jdbc and then output it to csv using clojure.data.csv/write-csv.

danp18:04:58

Here's the code I have:

danp18:04:36

(with-open [out-file (io/writer "out.csv")] 
 (csv/write-csv out-file 
         (map vals 
           (j/query ora-uri ["select * from mytable"])) 
         :quote? string? 
         :quote \" ))

danp18:04:50

I'd like to be able to specify which returned fields get wrapped in double quotes, but I'm not quite sure if it's possible

tanzoniteblack18:04:23

@danp 2 things: 1, I wouldn’t recommend using select * in sql ever, but also be aware of the fact that just doing map vals does not guarantee that you’ll get the same order of columns (since the hash-maps returned from jdbc/query aren’t ordered). By happenstance, you should get the same order of columns for each run of this code, but it’s possible that CSV files generated from this code might differ in column ordering if you run this on different machines

tanzoniteblack18:04:54

better off doing a (map #(select-keys % [:column1 :column2 ...]) ...)

tanzoniteblack18:04:36

2.) with data.csv you can’t explicitly state which columns you want to double quote…but it will by default (if you don’t provide a value for :quote?) only quote when the data requires it, or you can just specify true to have it always quote (which can sometimes just be the safest option)

mtkp18:04:29

i think maybe (map (juxt :col1 :col2 :col3) ...) is a better way to get the ordering right

danp18:04:18

Cheers @tanzoniteblack - the * is more just me messing about before I write anything "proper". Definitely hear you on the map vals - will give it a whirl now, and the suggestion from @mtkp 🙂

tanzoniteblack18:04:20

@mtkp right, forgot that select-keys returns a hash-map as well; (map #(map % [:coll1 :coll2]) ...) is what generally ends up in my code for this, rather than juxt, but same idea (and juxt is probably more elegant)

mtkp18:04:38

:thumbsup:

danp18:04:25

Thanks @tanzoniteblack and @mtkp, that's looking much better now 🙂

danp19:04:14

With regard to querying using clojure.java.jdbc, willl the list items be guaranteed order if I use an ORDER BY clause in the SQL?

danp19:04:14

so it's just the field order in the hash that isn't guaranteed

tanzoniteblack19:04:05

lists/vectors are ordered in clojure, jdbc/query returns a list of maps, who’s order is based off the return order from your DB (and the order by clause), so those will be ordered

pesterhazy19:04:09

Different data structure. Maps and sets are unordered, seqs, lists and vectors are ordered

danp19:04:34

Ah yes, of course

danp19:04:22

I'm trying to do something useful with Clojure for work, so I want to make sure I don't make any lots of stupid mistakes!

tanzoniteblack19:04:06

so you can rely on the order of the rows returned…but don’t rely on the order of the columns returned within each row…though it might coincidentally happen to look like they’re ordered if you’re returning less than 16 columns, but it’s an implementation detail that you can’t rely on

danp19:04:10

Got it - I'm looking at the data dictionary so I can get the column order for the various source views. The task that I need it for needs to be able to accept a source view name and dump it out to CSV to provide to a customer, so getting the order right is important.

tanzoniteblack19:04:37

the map juxt method that mtkp send you will guarantee the order for the CSV:`

(map (juxt :coll1 :coll2)
     [{:coll1 "A" :coll2 "B"}
      {:coll2 "D" :coll1 "C" }])
;; ==> (["A" "B"] ["C" "D"])

danp19:04:17

Yeah, I'll definitely be using that in a latter step but the source views have different DDLs, so I need to be able to get a list of the specific column keys to pass to juxt in each case.

shader20:04:10

what's the right way to store a keypair used for server signatures in a web application?

shader20:04:29

I'm using caesium

andrea.crotti20:04:20

if I understood correctly, to use clojure spec to validate a map I need to use qualified keywords, right?

andrea.crotti20:04:55

I found a nice function clojure.walk/keywordize-keys that transforms a map with string as keys to a map with keywords as keys

andrea.crotti20:04:12

but it doesn't do qualified keywords

xiongtx20:04:48

(keyword “foo/bar") should give :foo/bar

andrea.crotti20:04:28

but here the actual original map is just what's read from a JSON file

andrea.crotti20:04:57

I could easily transform the keys to prepend "foo/" before keywordizing in a way

tanzoniteblack21:04:59

are you trying to generate a spec at run time based off the results of a json file? Or are you trying to read a json file at compile time to to generate a spec?

tanzoniteblack21:04:33

not that it really matters for your code, just curious what you're trying to do

andrea.crotti23:04:03

Mm neither I just wanted to parse a json and get a format that can be validated with spec straight away

andrea.crotti20:04:32

should I just implement it myself using postwalk?

andrea.crotti20:04:36

or there is another way maybe?

si.do37820:04:18

hi all! i’ve recently started to dive into clojure and would like to contribute to an open source project as a way to get more experience and improve my clojure knowledge! could somebody recommend clojure/clojurescript projects looking for contributors, but also suitable for a beginners? I’m new to contributing to open source, and i’ve got experience as a full stack developer with rails&javascript, so web based projects would probably suit me best, although i’m open to all suggestions

aaelony21:04:44

I used to source a postgres driver in the project.clj to talk to an Amazon Redshift database via jdbc, but it appears that Amazon doesn't recommend that anymore. Before I download the redshift driver and make it a localrepo thing, is anyone using amazon redshift via a dependency in clojars or maven central? tips? examples?

tanzoniteblack21:04:27

most things just kind of work still using the postgres driver (it's what http://www.metabase.com/ uses as their redshift driver still, with only a few gotchas). So despite their recommendations, I still prefer to use the postgres driver just so I don't have the whole code licensing and dependency management crap that they're forcing on us by not hosting it in a maven repo somewhere

tanzoniteblack21:04:11

depends on your use case, obviously. My understanding is that their licensing on the driver doesn't allow for it to be distributed, so maven central / clojars is out as hosting platform

aaelony21:04:29

oh, that's exactly what I wanted to know. I'll stick with the pg driver then, always worked fine in the past

andrea.crotti22:04:33

Ah nice @alexmiller I'm glad I'm not the only one that would have liked to have that

beatboxchad22:04:35

I got a super nooby clojure/JVM question. I get a stack overflow error when invoking a macro (I didn't write the code) with a somewhat long vector in a (let ...). It chokes on the vector, from what I can tell in the stacktrace. (Stuff like chunkedNext and chunkedMore in PersistentVector.java, chunk-rest and concat in core.clj). I am experienced enough to follow the breadcrumbs in a stack trace, but I have no clue how to reason about it. Anybody got cycles to help me figure out what to google? I'll spit out code and the stacktrace if so. I just have no idea what question to ask next or how to look closer. This is while using Overtone.

beatboxchad22:04:19

I tried a couple naive things like raising the JVM memory limit

noisesmith22:04:12

@beatboxchad stack overflow on concat is a sign of a clojure anti-pattern which is using concat in a recursive or accumulating function

beatboxchad22:04:40

I had read about that. Maybe I should read this macro closer. It's not obvious to me... oh wait, yes it is

noisesmith22:04:42

essentially what happens is that every call to concat adds another call the end code needs to make before accessing the value

noisesmith22:04:07

the workaround is often to force the concatenation before recurring / returning to the accumulator

noisesmith22:04:18

but it sounds like this is overtone’s error and not yours

beatboxchad22:04:50

Yeah. It's actually a macro from Sonic Pi which I'm backporting to Overtone, because it's code I would have eventually written after a ton of thinking

beatboxchad22:04:48

I don't see an explicit concat in there, but it does... how do I say this...

noisesmith22:04:55

wow that’s a dirty macro, I wonder why it even bothers using `

beatboxchad22:04:02

it's a partial definition

noisesmith22:04:09

~@ is a concat

beatboxchad22:04:49

yeah I can't even use it once without it choking

beatboxchad22:04:25

in what sense is it dirty? (if you don't mind expounding)

noisesmith22:04:48

what I mean by dirty / bothering to use

` is that just about nothing in the macro (except the @ splice I guess) is actually using the features of
`, and the macro is full of noise caused by explicit undermining ` with the ~' construct (a construct that pretty much means “I’m pulling a dirty trick here”)

beatboxchad22:04:44

haha, that's good to know

beatboxchad22:04:30

well, I suppose if I read it carefully with the things you've just told me in mind I should be able to make some progress.

beatboxchad22:04:54

I might even manage to clean it up a little and send it back upstream.

noisesmith22:04:07

I’d check out those splices, look at the forms they are splicing in (which I bet have more splices or even explicit concats in their definitions etc…)

beatboxchad22:04:24

definitely. Like I mentioned I read about that antipattern earlier but didn't recognize the concat form in the code. Now things definitely click. Thanks a ton!

noisesmith22:04:03

you can see it by sending a

`(foo ~@[1 2 3])
to your repl

noisesmith22:04:41

haha, the bot does it funny, but exposes the thing I am talking about

beatboxchad22:04:53

thanks clojurebot!

noisesmith22:04:10

anyway, ’`(foo ~@[1 2 3] :oh-like-this) totally works in your repl

beatboxchad22:04:26

I can't believe I didn't spot that concat form. I go too long between writing clojure. hhh

noisesmith22:04:33

oh wait it was a smart quote - wat

beatboxchad22:04:24

(println "Booya")

beatboxchad22:04:40

obligatory playing with the bot

lvh23:04:55

Does anyone have any suggestions for querying deeply nested data structures (small enough to fit into memory, big enough that walking it takes 100ms<x<200ms), outside of shoving them into datascript via e.g. intension?

john23:04:12

@lvh you could try specter

lvh23:04:37

yep; specter mostly works, although I feel I don’t get quite the same declarative power as I do with datascript? that might just be me misusing specter, though. Context: this is a bunch of machines with e.g. their networks, disk images; etc; I could ask questions like “show me all of the networks that had a machine that was internet-accessible and a different machine that had this version of ntpd installed on it”; whiich feels easier to express in datascript (since I get to use lvars)

noisesmith23:04:44

@lvh what about group-by on each index you care about in parallel? with structural sharing it might not be so bad space wise

lvh23:04:56

It's really more of a tree; it's not particularly balanced, but very wide as opposed to deep.

hiredman23:04:50

are you just looking to do graph walking?

hiredman23:04:02

there is always loom

nathanmarz23:04:37

@lvh if you have particular examples I could show you the best ways to handle them

hiredman23:04:23

I use clojure.set/index a lot

noisesmith23:04:46

my instinct about using a graph lib is that something simpler that assumes (correctly) that your data is directed and acyclic might perform faster

john23:04:22

there are some experimental clojure datastructure query tools, like https://github.com/halgari/odin and https://github.com/alandipert/intension, but I'm not sure if they'll be faster than specter for your job.

hiredman23:04:52

I have part of our build at work load a tools.namespace dependency graph and some other information in to an index created with clojure.set/index and do some analysis

hiredman23:04:04

it is decent, but very roll your own

lvh23:04:01

@nathanmarz I might take you up on that, but I'd need to generate some realistic sample data or scrub what I have first :)

lvh23:04:41

@hiredman I'm doing something similar to figure out how to call the entire AWS API

lvh23:04:26

(As in, to describe snapshot attributes, gotta know snapshot ids first; &c)

hiredman23:04:25

I assume skynet will result from someone being really frustrated with the aws api and trying to automate it

qqq23:04:31

is there a way to interact with the DOM via clojure, or is CLJS the only viable appraoch for that?

john23:04:12

What do you mean, interact?

qqq23:04:02

interact, as in write gui app in clj

qqq23:04:10

using dom instead of awt

john23:04:58

maybe via rhino on the jvm? Any other scenario, using asynchronous calls... you might as well just be using a server/client model, serving up rpc calls of some sort from clojure on the back end.

john23:04:44

Because you're not going get clj inside the synchronous js process either way.

john23:04:05

so, like, clj -> js/or-cljs proxy on webview -> update dom

john23:04:48

And since clj and cljs are so similar, it could feel pretty "native" to the browser I suppose.

hiredman23:04:01

there was this thing, I think it predates oracle buying sun, javafx, which was this whole new ui toolkit for java that included an embedded webkit, it may be dead now, I haven't heard anything about it in a long time