Fork me on GitHub
#clojure
<
2016-12-06
>
richiardiandrea02:12:20

@shaun-mahood my 2c I found that using the actual namespace + field name did not work for me, even with an alias, so I now use something like :receipt/id and :order/id ... which might end up in the same map (and a lot of times do)

richiardiandrea02:12:14

Other opinions/reports are welcome on this too

richiardiandrea02:12:58

Another idea that emerged at the Conj by talking with someone was to have a repo of specs + generators for common domains

shaun-mahood02:12:56

@richiardiandrea: that's how I do it for some things within my projects, but I'm not sure of what I should be doing otherwise or how it should look across the whole spectrum - like com.whatever.something and how that goes from there and all the way through a project, with specs as well. Like of there was a reference to make it all work nicely the whole way from top to bottom.

richiardiandrea02:12:28

My experience with the above approach has been smooth, I have been bitten by the "package name in namespaced keyword" problem and never went back to it...but yes, no real reference here, just opinion :D

jrheard03:12:53

i do the same thing as you so far in my toy projects, @richiardiandrea

jrheard03:12:38

i don’t refer to the file’s ns or the project’s name, just to concepts, like :event/id or :weapon/shots-per-second

richiardiandrea03:12:25

Yes I think it all comes from how Datomic does it as well

jrheard03:12:14

(i’ve never used datomic - one of these days! also to everyone else, i have no idea what i’m doing, don’t read my lines above and think “boy this guy knows what’s up, i’ll just do what he’s doing”)

richiardiandrea03:12:45

Ah ah now this makes to me too anyways :)

jrheard03:12:29

it’ll be nice once best practices are established and written down - i think right now we’re in a “everyone go ahead and try things out and see what works best” stage

shaun-mahood03:12:17

My big problem is that I mainly work on projects where I'm the only developer, so noone else notices when I do things completely backwards.

dpsutton04:12:27

oh that's a bummer. i'm lucky enough to be in a room of four developers and we are constantly talking about style and correctness

dpsutton04:12:46

speaking of which, is there a way to stop a reduction and return without reducing the whole collection?

dpsutton04:12:13

i'm pretty sure there is if i reify an interface, but is there a way to do it with just a standard reduce call?

dpsutton04:12:37

and is there a multiple bind values in clojure by any chance?

dpsutton04:12:43

that would make extra info for testing really easy

jrheard04:12:13

> speaking of which, is there a way to stop a reduction and return without reducing the whole collection?

jrheard04:12:17

reduced i think

jrheard04:12:25

ok cat got off my other hand, i can google for it now

dpsutton04:12:58

i'll look into it. thanks jrheard

roelofw13:12:32

some who can tell me what selmer uses as root when placing a image with <img src = "?? "> . I tried /img/image.jpg and img/image.jpg but no image is seen

mpenet13:12:23

depends on your http server setup, it's not really a selmer concern

roelofw13:12:35

oke, I use a luminus template so I think a http server is included

mpenet13:12:56

you then need to check luminus documentation about file resources/routing etc

roelofw13:12:25

oke, thanks

hunter13:12:29

@bhauman thanks for pointing to advent of code, i was lamenting there was no "perl advent calendar" for clojure this year

roelofw14:12:58

Is this advent of code for beginners like me , or more for experienced programmers

poooogles14:12:06

Anyone, kinda like code golf. Everyone who can program can brute force all the challenges, it's about how elegant/efficient you want to be.

roelofw14:12:06

@poooogles thanks, maybe I take a look at it

dacopare14:12:12

Hello, I'm trying to transform a vector of maps to a map of the keys to a set of their values. Something like this:

(foo [{:a 1 :b 2} {:a 1 :b 3}])
;; => {:a #{1} :b #{2 3}}
Because I'm going from a collection of maps to a single map, I'm thinking that reduce will be the best option for this. Am I looking in the right direction?

wotbrew14:12:01

@dacopare ignore me reduce is the best bet

dacopare14:12:39

Thanks @danstone, I'll have a go.

jcromartie15:12:04

I'm having a massive argument in a pull request review with someone who wants to store empty strings instead of nil in a map that serves as a cache. They don't want to call "contains?" on the map because of "performance" and would rather check if the string is empty by calling seq on it.

jcromartie15:12:16

am I being a pedant?

robert-stuttaford15:12:29

"why worry when you can measure” — Rich Hickey

dominicm15:12:51

Unless contains? is provably slower than (= (get x k) "") (which I would expect the reverse), I think contains? is significantly more idiomatic.

jcromartie15:12:47

Not to mention "the value associated with this key is nil" is better than "the value associate with this key is nil but we store an empty string and check for that instead of nil because of unfounded assumptions about performance"

robert-stuttaford15:12:59

i would use nil as well, because that’s idiomatic, but to convince your colleague who is basing this on perf; just measure it. test a million seqs on strings and a million contains? and see which is faster, and then see whether the difference actually matters

robert-stuttaford15:12:16

i suspect you’ve spent more time arguing about it than you’d have saved in cpu cycles 🙂

robert-stuttaford15:12:09

… unless you’re both on the team that built http://hollow.how/

dpsutton15:12:06

and wouldn't that make three cases for keys in your cache? It is not present and you get nil. It was at some point present but no longer and it is now "", it is present and has a string value

dpsutton15:12:15

that seems like a really weird invariant

jcromartie15:12:10

we have spent far more time arguing about it than any approach could possibly save

robert-stuttaford15:12:27

@jcromartie we all know a Sheldon 🙂

jcromartie15:12:02

I just had to unsubscribe and let him get someone else to approve it.

jcromartie15:12:10

I can't be bothered

dpsutton15:12:36

is this open source?

dpsutton15:12:49

he's a volunteer? and this isn't a terrible idea, just a not great one

dpsutton15:12:07

is it perhaps easier to swallow this pull request now and put it on the back burner to correct it later?

dpsutton15:12:20

perhaps life is better for everyone if you accept

jcromartie15:12:22

it's not open source

dpsutton15:12:31

do you outrank this person in your organization then?

jcromartie15:12:32

well, not yet... he's a paid team member

dpsutton15:12:37

i mean, you are approving, no?

dpsutton15:12:52

well, is it unreasonable to just firmly end the argument then?

jcromartie15:12:02

there are plenty of other people who can review

jcromartie15:12:08

he's obstinate

jcromartie15:12:14

I already made my case

dpsutton15:12:14

"as my position as approver of pull requests, I have to deny this change"

dpsutton15:12:22

well you're arguing.

dpsutton15:12:27

but you are the decider

dpsutton15:12:30

so decide and deny?

jcromartie15:12:09

nah, I'm not the gatekeeper, just one of many possible reviewers

mpenet15:12:14

@dpsutton calling (get foo :x ::not-found) is essentially the same

mpenet15:12:32

without feeding useless "" to your map

mpenet15:12:45

then I am not sure it really matters in practice

dpsutton15:12:54

i agree. the developer on the other end of the pull request is arguing a performance argument

dpsutton16:12:04

i don't like it for it making three states for keys in the cache

mpenet16:12:09

you'd probably not even be using clojure if that was an issue imho

dpsutton16:12:25

but if someone has planted their flag i was wondering if it was easier to just accept

dpsutton16:12:42

i think performance arguments always have to come with metrics and a problem statement

dpsutton16:12:59

you have to demonstrate that you are improving performance and improving it at a part where performance is a hindrance

dpsutton16:12:10

just about all of the code that i do fails one or both of those tests

dpsutton16:12:43

I try to make O(n^3) algos whenever I can so if we need speedups later we can quickly impress the higher-ups

jcromartie16:12:00

their performance argument is null and void BTW

jcromartie16:12:12

I've demonstrated that

jcromartie16:12:55

they responded by abstracting out the logic that stores "" in two place into a call to a function that takes a value and returns "" if nil

jcromartie16:12:07

so they've doubled down by adding more code

jcromartie16:12:19

and a function that takes a value and returns nil if it's ""

jcromartie16:12:26

with docstrings and everything!

jcromartie16:12:39

I should tell them they need to add unit tests for these functions 😆

bja16:12:48

is there a bot that is logging channel conversation and mirroring it somewhere public by any chance?

robert-stuttaford16:12:21

@jcromartie "No problem can be solved from the same level of consciousness that created it.” — Albert Einstein

robert-stuttaford16:12:32

move on, buddy 🙂

devn17:12:26

@jcromartie: so, one way to deal with this depending on how engineering works where you're at is to accept and just change it later

devn17:12:51

I know that sounds passive aggressive

jcromartie17:12:54

of course, I could just open my own PR

devn17:12:57

But last one in wins

stephenmhopper18:12:21

So, I have a collection and a series of functions. These functions will filter the data, transform it, filter it again, and then emit it to a core.async channel. Is comp the way to go on this or is there some way or reason to use transduce even though I don't really have a reduction step (unless you want to consider removing an item from the collection and emitting it a reduction operation)?

jr18:12:02

use comp to create the xform and use it with a core.async channel

jr18:12:13

(chan 1 (comp (map ..) (filter ..) (map ..)))
the channel will apply those operations when you put to it

stephenmhopper18:12:46

okay, thank you

zentrope18:12:47

Does anyone have a link to how to handle pgarray when querying postgres?

kanwei18:12:26

if you just want a few lines to copy, the (extend-protocol jdbc/IResultSetReadColumn part

zentrope18:12:47

Ah, that seems familiar. I could swear there was a gist or something illustrating this.

borkdude19:12:34

When using line-seq, should one use it within a with-open per se?

jcromartie19:12:55

If you are opening a resource, you should use with-open.

jcromartie19:12:26

If the reader is passed in from somewhere else, you probably shouldn't close it. It all depends on the context.

borkdude20:12:45

Is there something like line-seq but suitable for transducer composition - does that make sense at all?

noisesmith20:12:45

@borkdude clearly you wouldn't feed a transducer into line-seq, so I guess the alternative would be special casing line-seq as a transducing source like we do with range?

borkdude20:12:08

@noisesmith can you give the range example?

noisesmith20:12:09

@borkdude it's nothing that would show up in your source code

noisesmith20:12:41

when range is used in a transducing context, it's optimized - @puredanger described this to me and may be able to provide better info about this than I

bhauman20:12:57

I was sure there was a clojure.core fn that lets you walk through every nth element ex. (every? odd? (?core-fn? 2 (range 10)))

borkdude21:12:39

nice, didn’t know that one either

dpsutton21:12:51

someone was recreating it the other day in beginners. only reason i know

jr21:12:11

partition + step?

dpsutton21:12:20

map first over the partition i guess

jcromartie21:12:18

huh, I wonder... is the .reduce(IFn) method called when calling normal "reduce"?

noisesmith21:12:06

@jcromartie my understanding is that reduce uses it (checking for whether you implement IReduce protocol) as well as transducing contexts

noisesmith21:12:18

and it's a way to avoid creating lazy-seqs that are not needed

jcromartie21:12:21

yes indeed, just checked (source reduce)

jcromartie21:12:36

that must be new since I last looked at ranges 🙂

jcromartie21:12:41

they have always been a bit questionable...

Alex Miller (Clojure team)21:12:31

the self-reducing versions of range, iterate, cycle, and repeat were added in 1.7 along with transducers

noisesmith21:12:49

aha, I tagged you by the wrong handle, thanks for chiming in

Alex Miller (Clojure team)21:12:32

much blood was spilled to bring you self-reducing range :)

Alex Miller (Clojure team)21:12:24

http://dev.clojure.org/jira/browse/CLJ-1515 will give you a sense of the work that went into it

Alex Miller (Clojure team)21:12:34

I felt silly spending weeks on counting :)

jcromartie21:12:44

that's pretty great though

Alex Miller (Clojure team)21:12:08

but it’s remarkably subtle given that range can return things that are walked per-element, per-chunk, or via self-reduction

Alex Miller (Clojure team)21:12:17

and making all of those fast

jcromartie21:12:31

yeah, it sounds tricky, in terms of retrofitting a core part of the language

dpsutton21:12:31

patches ranging from 9/14 to 3/15

dpsutton21:12:35

that's a lot of cpu cycles

Alex Miller (Clojure team)21:12:06

seemed like an easy win at first :)

Alex Miller (Clojure team)21:12:30

it is interesting to note that none of them actually realizes and holds in memory the actual numbers in the range

Alex Miller (Clojure team)21:12:03

hat tip to Rich for that suggestion

jcromartie21:12:29

I assumed as much, though one can certainly do other things that defeat that thoughtful detail

bhauman21:12:45

@dpsutton thanks! I knew it was there, just couldn't see it

bhauman21:12:01

range as transducer source is v/cool

dpsutton21:12:05

i just happened across it recently. no prob

Alex Miller (Clojure team)21:12:56

the cycle,repeat,iterate ones are a bit simpler to understand and had some nice improvements too

vlad_poh22:12:51

There is an old SOAP based webservice i’d like to consume with clj-http. Is it the right library or can someone kindly point me in the right direction.

jcromartie22:12:23

clj-http will make the HTTP requests for you, but it won't help you construct SOAP XML bodies if that's what you mean

vlad_poh22:12:55

yeah that’s what i was hoping for

borkdude22:12:43

Is there something like max-key that takes a comparator?

borkdude22:12:50

so you are not restricted to comparing numbers

noisesmith22:12:46

#(comp first (partial sort %))

jcromartie22:12:58

I would name the function you are about to write "max-by" 🙂

borkdude22:12:08

@noisesmith that one is not so efficient

borkdude22:12:35

@jcromartie yeah, or just write a reduce

noisesmith22:12:56

yeah, a reduce would do it

jcromartie22:12:01

and I think sort-by is what you want, to use a key fn

jcromartie22:12:20

(first (sort-by keyfn your-coll))

noisesmith22:12:20

sort accepts an optional comparator

jcromartie22:12:26

a comparator, yes

jcromartie22:12:29

but he asked about a key fn

noisesmith22:12:30

he wants a comparefn not keyfn

jcromartie22:12:56

it's right there. takes a comparator

noisesmith22:12:00

I thought of sort-by too, but I didn't see him say anything about keyfns

noisesmith22:12:07

sort takes a comparator, yes

jcromartie22:12:09

I saw "max-key" and thought keyfn

jcromartie22:12:35

apparently that is a bowing emoji

jcromartie22:12:37

I wouldn't have guessed

bfabry22:12:06

doesn't a comparator only return :greater :same :less? how do you get a max out of that?

bfabry22:12:00

ah I see, ignore me

jcromartie22:12:05

using reduce to find a max is better, but for a first shot at it, sort is probably fine

jcromartie22:12:15

unless you are doing it a whole lot

bfabry22:12:11

looks to me like max-key is just a reduce, so you could just wrap the comparator in #(.compare c %1 %2)

mikerod22:12:12

found something weird: (set! *warn-on-reflection* true) (fn [x] (.toString x)) = reflection warning

mikerod22:12:19

(fn [[x]] (.toString x)) = no reflection warning

mikerod22:12:35

I think it does need to be an Object method to work here

mikerod22:12:51

However, I don’t see why the destructuring is effectively giving a “Object” type hint perhaps

mikerod22:12:13

(I’ve always thought it was odd that an Object type hint wasn’t implicit always, but I can see why it may not be the case in the compiler)

jjfine22:12:52

just a guess but i don't think you could destructure a list and get a primitive type

jjfine22:12:56

since lists are generics and generics don't support primitives

hiredman22:12:28

type hinting has some weird behavior with .toString

bfabry22:12:06

oh that totally doesn't work I'm an idiot

mikerod22:12:07

jjfine that’s true in theory

hiredman22:12:15

my guess is, when all is said and done, the destructuring expands out to a java method call declared to return Object

mikerod22:12:24

hiredman yeah, I’ve never seen an automatic discover of an Object method without a hint

mikerod22:12:44

yeah, I figured it was some chain reaction of things

mikerod22:12:47

it surprised me

hiredman22:12:15

[x] becomes (let [x (nth X 0)] ...), the call to nth is inlined as a call to RT/nth etc

mikerod22:12:33

Ah yes, the inlining of nth makes sense

mikerod22:12:50

so then it just gets the compiler inference on Java methods

mikerod22:12:38

I was wondering if this has ever came up.

mikerod22:12:03

I’ve seen many reflection warnings brought on by toString calls (I typically just advocate to use str)