Fork me on GitHub
#clojure
<
2017-10-13
>
xtreak2911:10:12

How do I sort by the list of lists to make sure they are in sorted order ? I have '((1) (2) (3) (2 1) (1 2) (3 1) (1 3) (3 2) (2 3) (3 2 1) (2 3 1)) and I want it to be ((1) (2) (3) (1 2) (1 3) (2 1) (2 3) (3 1) (3 2) (2 3 1) (3 2 1)) . Is there an idiomatic way to do this ? sort doesn't help. In sort-by how can I compare two lists. (juxt first second) doesn't help. It can have any number of elements for every sub-list. Expecting something like Python's sorted sorted([[1], [2, 1], [1, 2]]) # [[1], [1, 2], [2, 1]]

rauh11:10:41

@xtreak29 Vectorize your inner lists, then the sort be like you want

lovuikeng11:10:53

neat, repl-driven clojure slack šŸ™‚

tjtolton14:10:19

hey, does anyone know where clojure.contrib.duck-streams went?

seancorfield14:10:30

@tjtolton I don't see it listed here https://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go so maybe it disappeared from Contrib before 1.3 appeared?

tjtolton14:10:59

hrm. must be something that it got folded into or something though right?

bja14:10:16

July 23, 2010: DEPRECATED in 1.2. Use instead.

tjtolton14:10:44

oh, how about that

tjtolton14:10:33

I only actually need slurp* from there

tjtolton14:10:36

so that's perfect

tjtolton14:10:04

just assembling this really neat pattern from an article back in 2009

tjtolton14:10:18

string interpolation/super templating

tjtolton14:10:33

really nice for dev tooling/scripting against a ring server running in a docker environment. just set up all my things using some constants i defined up at the top, etc

tjtolton14:10:56

like the new f'{variable} strings' in python

seancorfield14:10:39

What does duck-streams/slurp* give you that the built-in slurp does not?

seancorfield14:10:37

(it says it's "like slurp but opens f with reader" -- but slurp also seems to call reader on f...)

tjtolton14:10:35

it actually seems to define its own reader, which is possibly obsolete now. I'm going to be honest, I just kind of wanted to make it work blackbox without inspecting the internals. And I'm getting what I deserve šŸ˜‚

seancorfield14:10:37

It's telling that duck-streams was deprecated even before the break-up of monolithic contrib that came with Clojure 1.3 šŸ™‚

tjtolton14:10:47

yeah for real

seancorfield14:10:43

Looks like you can just use the built-in slurp (based on limited playing in the REPL).

seancorfield14:10:13

boot.user=> ((juxt read slurp) (-> "Hello, World!" java.io.StringReader. java.io.PushbackReader.))
[Hello ", World!"]
(that's basically silent-read without the try/`catch`)

lovuikeng15:10:35

@seancorfield could you elaborate silent-read without the try/`catch`?

seancorfield15:10:21

@lovuikeng Based on the code in the blog that @tjtolton linked to. The blog uses old, outdated libraries but has a function that takes a string and tries to return a pair of the first readable (Clojure) form from the string and the rest of the (unread) string.

seancorfield15:10:51

The full function (using built-in slurp) would be

(defn silent-read
  [s]
  (try
    ((juxt read slurp) (-> s java.io.StringReader. java.io.PushbackReader.))
    (catch Exception _)))
So it returns nil if it can't read a form from the string.

seancorfield15:10:31

@tjtolton Did you get that interpolation example working?

tjtolton15:10:47

Oh, yeah I did! It's real neat.

seancorfield15:10:32

So you can just depend on [org.clojure/core.incubator "0.1.4"] and then require [clojure.core.strint :refer [<<]] and use that?

tjtolton15:10:25

whaat, oh man

tjtolton15:10:29

I did not see that!

tjtolton15:10:03

that's great! thanks!

lovuikeng15:10:50

thank you <@U04V70XH6>! `strint.clj`: _"originally proposed/published at <http://cemerick.com/2009%22_|http://cemerick.com/2009"_>, you just got to love Hickey :slightly_smiling_face:

seancorfield15:10:39

sean@sean-xps:~$ boot -d org.clojure/core.incubator repl
nREPL server started on port 64540 on host 127.0.0.1 - 
...
boot.user=> (require '[clojure.core.strint :refer [<<]])
nil
boot.user=> (<< "It is ~(java.util.Date.) right now!")
"It is Fri Oct 13 15:58:41 GMT 2017 right now!"
boot.user=>
(edited to remove the { } since they aren't needed)

lovuikeng16:10:08

man, it just gets better and better šŸ™‚

tjtolton16:10:56

man, this is so slick

tjtolton16:10:00

feels like cheating

seancorfield16:10:08

(I love that Boot lets me just pull in an arbitrary library without needing to create a project etc)

lovuikeng16:10:11

thanks for the great tips @seancorfield!

seancorfield16:10:25

Now I must go grab lunch before the sessions start back up in 50 minutes!

lovuikeng16:10:23

no wonder clojurians channels been quite these couple of days... šŸ™‚

eraserhd16:10:45

Hey is there a map with a stable key order?

noisesmith16:10:20

sorted-map and sorted-map-by - thereā€™s also one from a github project that preserves insertion order

eraserhd16:10:32

The insertion order is what I'm looking for.

noisesmith16:10:33

you can also use the various java mutable hash-maps of course

eraserhd16:10:56

Do you remember anything about the github project?

noisesmith16:10:07

@eraserhd I have a lot of respect for the author, but havenā€™t tried this code https://github.com/amalloy/ordered

nooga16:10:48

@bpiel Watching your talk about Guildsman right now. Super interesting but pleeease start thinking about writing readmes! šŸ˜„

bpiel16:10:21

@nooga ha! Thanks. I promise there'll be docs and examples once this is ready for the public. Missing README is not remotely the biggest problem

nooga16:10:17

@bpiel some would argue that having a readme could attract more hands or heads to help you out šŸ™‚

bpiel16:10:36

@nooga Those hands/heads will be critical to success. But, I don't think anyone can help yet. Ex. there's no tests

bpiel16:10:05

I promise there will be a readme ā˜ŗļø

nooga16:10:43

google could help by fixing their C api šŸ˜‰

bpiel16:10:17

@nooga that's very true. Actually, people can help, just not via the guildsman code yet

bpiel16:10:36

Maybe the readme (for now) could just explain what contributions to focus on in TF

bpiel16:10:54

I like that

bpiel16:10:01

Ok. I'll do that soon

bpiel16:10:23

Thanks for reaching out

nooga17:10:36

my pleasure šŸ™‚

wpcarro18:10:56

Does anyone know of a forum for asking Cider specific questions? Or perhaps this is the right place..?

wpcarro18:10:16

oh thereā€™s a dedicated IRC channel? thatā€™s lovely

dominicm18:10:09

@wpcarro slack channel šŸ™‚

wpcarro18:10:56

@dominicm thank you for clarifying ā€¦ the IRC channel had 3 members haha

qqq20:10:09

does clojure have a builtin whee I provide: state f :: state -> state still-run :: state -> bool and it iteratively call 'f' on 'state' until (still-run state) becomes false ?

noisesmith20:10:06

would (take-while still-run (iterate f state)) count?

qqq20:10:37

does this keep around all the old states ?

noisesmith20:10:48

only if you capture them

noisesmith20:10:07

if you donā€™t bind them, they are gcd

qqq20:10:20

I guess I'll just do a loop ` (loop [state state] (if (still-run state) (recur (f state)) state)))

dpsutton20:10:05

(reduce (fn [prevoius-states current-state] (if (still-run current-state) (conj previous-states (f current-state)) (reduced previous-states)))

dpsutton20:10:07

something like that

noisesmith20:10:26

but thereā€™s nothing to reduce over

qqq20:10:35

(range) šŸ™‚

noisesmith20:10:58

that does a lot of extra work and a lot of extra syntax to do something like the take-while / iterate except itā€™s not lazy and always holds all states in memory whether you need them or not, I donā€™t see any advantage

noisesmith20:10:17

@qqq if range was the input current state would always be a number

noisesmith20:10:49

(yes you could fix that by changing the binding vector to [previous-states _] but that doesnā€™t really make things much better)

dpsutton20:10:31

yeah his suggestion is way better

noisesmith20:10:42

now, if f took a second arg, eg. one that delivers an event or message (a common design for me at least) (reduce f state (repeatedly get-event)) can be a decent way to do that (reductions instead of reduce if you need all the values in a sequence as they are produced)

noisesmith20:10:35

this is a good setup if you have an external data source because it means you can unit test by passing in a lazy-seq of events that provoke the behavior you care about

Bravi21:10:43

is there a good read about web app security for Clojure?

Bravi21:10:21

Almost every tutorial explains basic routes using compojure and they donā€™t really go into details of middlewares and such

Bravi21:10:30

and actually connecting to the database

dominicm21:10:37

@bravilogy what sort of thing are you looking for?

Bravi21:10:46

Iā€™m trying to build a SPA and I have an SQL database. And basically was wondering whatā€™s the best approach to creating RESTful apis and working with databases?

taylor21:10:23

#luminus is a good way to get started http://www.luminusweb.net

taylor21:10:16

You can use the options for ClojureScript, Re-frame, Reagent, etc. for the SPA stuff, and I believe thereā€™s some DB stuff too

Bravi21:10:58

just what I needed, thank you šŸ™‚

Bravi21:10:35

for example, letā€™s say Laravel offers its own ORM, which I understand is for OOP programming but perhaps thereā€™s something similar approach in Clojure too?

nooga22:10:22

Will clojure compiler optimize stuff like (let [a (-> foo :x :y :z) b (-> foo :x :y :q)] ...) by noticing common expression?

nooga22:10:17

@bronsa funny thing, Iā€™m actually watching your talk from conj right now šŸ˜„

bronsa22:10:24

hope you like it :)

nooga22:10:04

@bronsa I sure do! ā¤ļø compiler tech. About the common expression. I wonder is that something that JVM could optimize later onā€¦

bronsa22:10:03

mhh, i don't know, that would require some hardcore purity analysis which I don't think hotspot does

bronsa22:10:32

hotspot never ceases to amaze me but i'd be really surprised if it did this

nooga22:10:36

yeah, that is what Iā€™d expect

nooga22:10:59

good to know, I need to refactor several fns now šŸ˜„

bfabry22:10:06

if those expressions are actually like what you're doing then the cost of it not being "optimised" is likely close enough to zero

bfabry22:10:11

function indirection is cheap

nooga22:10:01

okay, so roughly what does (:x y) compile into?

bfabry22:10:01

(let [thing {:a {:b {:c 3}}}]
  (time (dotimes [_ 10000000] (-> thing :a :b :c))))
"Elapsed time: 282.271115 msecs"

bfabry22:10:35

(:x y) compiles to xsingletonobject.invoke(y)

bfabry22:10:56

which might even be inlined by the jit

noisesmith22:10:05

@nooga the best way to find the answer to a question like that is to use no.disassemble https://github.com/gtrak/no.disassemble

bronsa22:10:21

clojure emits inline caches for (:foo <whatever>)

bfabry22:10:57

ah, so even better than I thought

bronsa22:10:21

yeah but they're only useful for records :)

bronsa22:10:47

the inline caches are there so that if you're doing keyword access on a record, it'll get optimized into a direct field access

bronsa22:10:55

no difference for maps other than some extra indirection

nooga22:10:05

that I heard of, smart move

bronsa22:10:27

i'm actually not 100% sure those inline caches make an actual difference in real life

nooga22:10:36

I know V8 does a lot to optimize field lookups away

bronsa22:10:48

but i've honestly never benchmarked that

nooga22:10:49

but thatā€™s a bit different

nooga22:10:13

ok, be back in 6 months, started reading clojure compilerā€™s src šŸ˜„

bronsa22:10:17

there be monsters

noisesmith22:10:38

no.disassemble helps too šŸ˜„

nooga22:10:16

I contributed to pixie-lang once so Iā€™m sorta prepared šŸ˜‚

nooga22:10:37

heh, I have to admit that I almost never care about optimizing anything when writing clojure because everything runs fast enough ā€œout of boxā€ - even stuff like async proxy that parses megabytes/s of binary from the wire, grinds huge maps and unparses them to other wire. It just warms up and does its job.

epmor23:10:22

Are there any good libraries to create CLI applications?

taylor23:10:13

Do you need to do anything special besides parse CLI args?

madstap00:10:00

And tools.cli is cljc, so you can use it with lumo, which I recommend.

Mudge23:10:56

Is there a boot channel?

Mudge23:10:18

Is there a way to change the font colors of the boot repl on windows 10?