#clojure log - Mar 17 2016

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

4:18 dysfun: rhg135: i think the last thing we need is the DoubleSplitExperiment monad

4:18 DoubleSlitExperiment*

4:19 rhg135: That's be great for OOP

4:20 dysfun: ( https://en.wikipedia.org/wiki/Double-slit_experiment )

4:20 mokuso: wow, how did quantum stuff came into clojure ?:>

4:20 dysfun: i'm learning particle physics as a hobby

4:20 rhg135: Modeling it I mean, who needs consistency or making sense?

4:20 mokuso: ah nice

4:21 if I'd deal with quantum physics again I'd focus on quantum information though, rather than particle physics

4:21 dysfun: rhg135: well it's probabilistic, so it does make a kind of sense

4:22 but it does make repeatability more challenging

4:22 mokuso: heh, i've finally gotten around to learning enough thermodynamics to just about understand entropy

4:22 rhg135: So does OOP just not at 3am :P

4:22 dysfun: (since particle physics kind of requires it)

4:22 mokuso: though it is probabilistic there are some differences between classical (kolmogorovian) probability and quantum probability

4:23 I think I've read something related somewhere, I can check if you're interested in the differences

4:23 dysfun: yeah you've lost me now :)

4:23 i mean i understand the probability wave and collapsing it, but surely that just means the distribution of results is different?

4:24 mokuso: dysfun: that's good, the entropy concept is very important and my favorite :>

4:24 dysfun: well i came across the holographic principle recently and that was just like... wow

4:24 i hated physics when i was in school because nobody told me just how fucking cool it is

4:25 mokuso: yeah well nobody told me in school that physics is the coolest application of maths, since high school math teachers always hated physics teachers and conversely

4:25 as for your question I'm not that sure

4:25 dysfun: well i hated maths too, so *shrug*

4:26 although most of my maths teachers were drier than sawdust

4:26 mokuso: I liked maths, disliked math teachers and math people :>

4:26 yeah

4:26 dysfun: nobody taught me how cool maths was either

4:26 i laughed at all the people who told me i needed to be good at maths to be good at programming

4:26 because i was not good at maths

4:27 rhg135: You don't need math much with programming

4:27 mokuso: except if you work in computer graphics and such stuff

4:28 dysfun: no. mostly you just need to know what the math operators look like

4:28 rhg135: That's what computers are for ;)

4:28 dysfun: yeah, graphics are the main exception. audio too

4:28 but even a lot of that has been sufficiently well abstracted by now. nobody codes a fourier transform by hand

4:28 mokuso: sure

4:28 dysfun: this is what i find is the real difference about physics and programming

4:29 rhg135: What's that though?

4:29 mokuso: but you'll be needing to understand why a function can be analysed to it's eigenfunctions with fourier analysis to get quantum mechanics

4:29 dysfun: when physics gets 'simpler', they introduce more variables into the equation

4:29 when programming gets simpler, it gets out of my way

4:29 mokuso: dysfun: here's something that will blow your mind

4:29 rhg135: Also, good night people

4:29 dysfun: mokuso: you may as well have just spoken chinese at me haha

4:29 g'night

4:30 the hardest part about trying to learn particle physics is realising what all the prerequisite knowledge is

4:30 and for all of those, there are wikipedia pages full of arcane symbols that i swear are not intended for human consumption

4:31 mokuso: sorry about that

4:32 my point was that you'll be needing to study a bit fourier analysis and linear algebra

4:32 to feel ok with quantum stuff

4:32 dysfun: that's handy, i've been learning machine learning stuff, which is all linear algebra

4:33 mokuso: cool

4:33 :>

4:33 dysfun: i'm also acutely aware that graphics cards are well suited to a lot of linear algebra maths

4:33 and so with the release of vulkan, i've got my eyes on that space

4:34 in truth i'm also astounded that people would have bothered to do all of this stuff by hand

4:35 if i'd been around before computers were widely available, i think i'd have hated physics

4:35 mokuso: heh

4:36 in the old days most physicists left the calculations to the mathematicians or to human calculators :P

4:36 at least in the WWII there was such a job, as a human calculator

4:36 mostly done by women

4:37 you might like this link: http://www.bristol.ac.uk/physics/research/quantum/engagement/qcloud/

4:38 I found it sometime ago when I was writing a pop article on quantum computing

4:40 dysfun: i quite liked feynman's "los alamos from below" lecture

4:41 he talked about how they were going to get IBM "computers" (adding machines etc.) and how they filled in using humans for each task instead in the meantime and managed to achieve the same performance that the IBMs were going to give them

4:42 and then when they had the computers and they were loading the appropriate cards by hand, they started doing concurrent work!

4:42 mokuso: heh

4:43 dysfun: security regulations meant they couldn't tell the computer operators what these numbers were for etc.

4:43 so feynman got them to tell them and suddenly they came up with better ways of squeezing performance out of the machines

4:43 they started running parallel tasks and performing fast error correction

4:43 a lot of stuff we're struggling with today

4:44 mokuso: it always helps to know the full problem, along with it's real world details so you can put some extra restrictions that will speed things up

4:45 dysfun: yeah, writing extremely general libraries is hard

4:46 i noticed it a few years ago. i got a bug report against one of my deprecated modules

4:46 and i found it amazing that this code that i'd written off as a really bad idea was powering some high frequency trading stuff

4:47 mokuso: heh

4:47 dysfun: it's sort of like tunnel vision - it's very hard to imagine all the scenarios in which people will find something useful

4:48 it's the reason i like clojure - it just has a few very general abstractions so it's very easy to interoperate

4:48 and things like list functions come in useful in ridiculously more scenarios than you expect when you start

5:02 Kah0ona: Question: soon i need to strip text out of resumes, and distill relevant tags/keywords from it. Are there clojure libraries that help in that, ie. contain algorithms that use some heuristics to find relevant information in large text files?

5:29 prohobo: nice

5:31 dysfun: Kah0ona: there are a bunch of libraries that can do that listed on http://clojure-toolbox.com/ if memory serves

7:03 kungi: I am currently starting to dispair about cljs-time. Even the most bacsic examples seem to not work? https://gist.github.com/Kungi/606959e6fd2d00ada1cd does anyone have an idea what is wrong here?

7:15 Henkraks: kungi: try defining the formatter separate

7:16 kungi: (date-format/unparse formatter (date/today-at 12 00))

7:16 ridcully_: also if this is using goog.string.format under the hood, you might have to require it

9:06 kungi: Henkraks: defining the formatter has no other effect

9:06 Henkraks: I tried: (def f (date-format/formatters :basic-date-time)) (date-format/unparse f (date/today-at 12 00)) but I still get the same error

10:34 AndreasO: Seesaw Image-shape, can't get it right. Given the right path it says "don't know how to make image from... "

10:39 sdegutis: Hi.

10:40 AndreasO: Seesaw Image-shape, can't get it right. Given the right path it says "don't know how to make image from... "

10:40 justin_smith: AndreasO: it wants something that to-image can use https://crossclj.info/ns/seesaw/latest/seesaw.graphics.html#_to-image

10:41 sdegutis: I dunno why, but I just have a hard time trusting DSLs like Seesaw.

10:41 justin_smith: so you need to give it a java.awt.Image or javax.swing.ImageIcon (though I guess it accepts nil too)

10:41 sdegutis: Maybe it's cuz I've had so many bad experiences with similar wrapper APIs in the past, and have just gone to the underlying API and had an easier time.

10:42 TimMc: AndreasO: Please don't re-post questions so rapidly.

10:42 AndreasO: Sorry

10:43 justin_smith: and what's that?

10:43 justin_smith: AndreasO: you would need to look up the constructors for java.awt.Image - it's in the core javadoc as it's part of java

10:45 AndreasO: Ok

10:45 justin_smith: https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html likely you would want the BufferedImage implementation https://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html

10:46 digiorgi: how can i change a JAVA object state safely from different threads?? in clojure

10:47 dysfun: you can't. you need to use a mutex

10:47 justin_smith: digiorgi: same way you would in java - IOW very carefully and it tends to be error prone, and you probably want to use a lock

10:47 (doc locking)

10:48 clojurebot: "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."

10:48 Glenjamin: you could hide it behind channels, go-style

10:49 justin_smith: Glenjamin: that's true, but then only one thread will ever be touching it (the one doing the channel read)

10:49 dysfun: ooh that's shiny

10:49 digiorgi: justin_smith, thanks (:

10:49 justin_smith: and if you have more than one thread doing a channel read, you're back to needing locking :)

10:49 Glenjamin: the channel effectively acts as a lock, yeah

10:50 dysfun: noooo, the word is a perfect immutable HAMT!

10:50 world*

10:50 justin_smith: haha

10:50 Glenjamin: it's just potentially safer than handing out references and relying on callers to lock

10:50 i think

10:50 low level concurrency isn't my strong suit, as i intentionally tend to avoid doing any

10:52 dysfun: i'm not sure it's anyone's strong suit tbh

10:52 we've made lots of progress but i still feel like we're scratching the surface

10:53 justin_smith: java concurrency in practice is pretty great, but the big takeaway is "unless you have really pressing performance needs that demand otherwise, use queues"

10:53 renl: if i wanna learn clojure web development should my first step be looking at clojure ring?

10:54 justin_smith: http://jcip.net/

10:54 renl: ring is pretty ubiquitous, there's a new edition of "web development in clojure" coming out right now, fresh and up to date

10:54 some friends are doing the book and all the exercises as a group, they say it's good

10:55 AndreasO: justin_smith: well, on thing works. Now I need to get the image into the buffer. No sleeping today!

10:55 Glenjamin: justin_smith: queues the datastructure, or queues like RabbitMQ?

10:55 renl: ah ok, and the book covers ring? or some other higher level framework?

10:56 justin_smith: Glenjamin: like java.util.concurrent.ArrayBlockingQueue - pretty much what channels are

10:56 renl: it covers ring plus some higher level stuff that uses ring

10:56 renl: most web stuff in clojure will be using ring, it's pretty basic and there's few reasons not to use it as part of the stack

10:57 it's not a framework, it's an abstraction that makes it easy to switch webserver implementations while not changing your code

10:57 renl: thanks i'll check it out, too bad its not in my local physical book library :D

10:57 justin_smith: heh, it's a bit too new for that

10:58 renl: it's in beta now https://pragprog.com/book/dswdcloj2/web-development-with-clojure-second-edition

10:58 renl: would that book cover frontend stuff as well? or that would fall under clojurescript books?

10:58 justin_smith: renl: yes, it covers frontend cljs and even css wrappers

11:02 TimMc: justin_smith: Weirdly enough, it wasn't until just this month that I seriously used a queue for asynchrony.

11:03 (And an executor!)

11:03 justin_smith: TimMc: it's remarkably similar to core.async (though not as pretty)

11:03 TimMc: I guess I just don't do much async that isn't already wrapped up in some other API like rxjava or something.

11:04 renl: justin_smith: sorry silly question, if the book is in beta, as and when there are content changes would i get to download it as well? or will i need to re-buy an updated copy?

11:04 justin_smith: renl: I think the usual idea is that if you buy in beta you will get free updates until the final version is done, but the publisher should have the full info

11:05 I mean you are doing them a favor by paying for it while it's still not done

11:07 wink: renl: for Manning's MEAP they actually regularly email you when you can download a new version, but no clue for others

11:08 renl: thanks :D

11:08 wink: now if only it would've been a text diff and not only PDFs... :)

11:08 ridcully_: renl: with pragprog you will get update notifications via email and can download the book then

11:09 renl: you (or your reader) might have to deal with the fact, that there are gaps in the book to revisit later. maybe not a problem with a second edition then

11:09 TimMc: Seriously, what I really want is access to the git repo so I can see the diffs. :-P

11:10 renl: nod :)

11:38 cortexman: any idea what this arises from? (blah and blerg have a type mismatch merging profiles.)

11:38 when running lein

11:39 justin_smith: first thing I'd check is if one is a map value, and the other is a vector of maps

11:39 profiles get merged when you run lein - first step might be figuring out which profiles are being used in the task

12:33 cortexman: thanks

13:16 amoe_: how can I insert into a field of type BYTEA using clojure.java.jdbc? seems that neither a string, a byte array, or a vector of bytes work

13:29 justin_smith: amoe_: if it's any help, in this code the :value field in the table is a bytea, and it looks like he's giving it the value of nippy/freeze, which iirc is a byte-array

13:29 oh, almost forgot the link https://github.com/yogthos/jdbc-ring-session/blob/master/src/jdbc_ring_session/core.clj#L38

13:42 WorldsEndless: I've made web apps using Luminus. Now I just need to make some micro services, not full-out content services. Any suggestions on where to start?

13:43 Luminus is overkill for something that just needs to respond with JSON.

13:49 justin_smith: I'd pick a nice routing lib (many people like compojure but there are nice alternatives too), plus ring.

13:49 that's all you really need for that.

13:52 MJB47: bidibidibidi

13:54 justin_smith: yeah, bidi is great

13:54 amoe_: justin_smith: thanks -- I just found the same thing, forgot to check

13:55 justin_smith: turns out I need the result of (bytes expr) [rather than (byte-array expr)]

13:57 justin_smith: aha

14:23 nehal: I'm losing my mind a little bit with an instaparse grammar thing, is anybody awake to point out where I've gone wrong?

14:31 sdegutis: I don't know why I opened IRC.

14:32 I left the room, went into the other room, sat down for a minute and talked with my wife, then came back in here, and IRC was opened. Nobody else was in the room since I left it, and it wasn't opened when I left it. So it must have been me. But I don't recall opening IRC.

14:33 nehal: quantum IRC

14:33 you were always in IRC, it's only when you came back that reality coalesced into you being here

14:35 justin_smith: you have both joined and parted the channel until you sit down at your desk

14:36 sdegutis: I have a standing desk tho.

14:36 Built it about a year ago I think.

14:36 nehal: ok some people are kind of here? is there something I'm missing with instaparse regarding handling 'empty' lines?

14:37 ridcully_: nehal: you will only find out, if you put your code on some paste site and share the url with the channel

14:37 amalloy: nehal: ask a real, specific question

14:37 sdegutis: Actually all I did was screw four 4x4s onto a butcher block with U-brackets and call it a day. My dad helped build a middle shelf with his tools, that the Mac Pro sits on.

14:37 ridcully_: ~ask

14:37 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

14:38 sdegutis: nehal: I tried out instaparse and it was neat, but it didn't quite serve my needs (an INI-like text file format) so I went with writing my own immutable parser in Clojure using mostly just reduce and a bunch of conds.

14:39 clojurebot: /how dare you/

14:39 clojurebot: No entiendo

14:40 sdegutis: clojurebot: I never!

14:40 clojurebot: Cool story bro.

14:40 sdegutis: clojurebot: who do you think you are???

14:40 clojurebot: I don't understand.

14:40 sdegutis: clojurebot: What gives you the right...

14:40 clojurebot: Excuse me?

14:42 sdegutis: I ran out of those kind of phrases, and they're ungoogleable.

14:43 justin_smith: clojurebot: I demand satisfaction, EMP guns at dawn.

14:43 clojurebot: excusez-moi

14:43 nehal: http://pastebin.com/HbsCLt8S

14:43 so I'm *pretty darn fresh* around most of this, so I'm sure it's something obvious

14:44 but what I run into is that the blank divider line keeps getting error'd out

14:44 justin_smith: nehal: that's too many args to def

14:44 wait, neverm ind

14:44 nehal: like the parser fails on the first character of that second line

14:44 and I'm trying to understand *why*

14:45 sdegutis: justin_smith: good one

14:45 Today my job is to learn how to use semantic HTML5 tags.

14:47 nehal: I've tried pulling the newline out of the main entry rule, doesn't work, tried doubling up on newlines in the num rule, no dice

14:47 even tried to keep in mind that the file I'm parsing has CRLF's - no dice :)

14:58 ridcully_: nehal: trying your code in `lein try instaparse` works out fine for me

14:59 nehal: didn't even realize lein had a instaparse tester, let me run that really quick and see if I've somehow avoided the actual trouble :v

15:00 ridcully_: hm no, that just is a plugin to start a repl with some deps loaded

15:00 (lein-try is the plugin)

15:01 nehal: got it

15:01 that'll speed up a bit

15:01 ridcully_: if you are dealing with dos files, then you need \\r\\n for your `nl`

15:02 nehal: see I've tried that and it still blows up, for some reason :)

15:02 and yeah, dealing with Windows terminated CRLF newlines

15:02 but oddly it'll get *to* the empty line fine

15:02 it's just it never wants to progress past it

15:04 ridcully_: i have copynpasted your sample entry, saved it starting from the `***...` and set ff=dos on it. then i just (slurp)ed it into the repl and tried from there

15:05 maybe you can provide the exact failing case?

15:11 nehal: the error when reading your data should somewho indicate what's the problem (expected X). if you file there has mixed line breaks, maybe you need `nl = '\\r'? '\\n'"` ?

15:12 nehal: @ridcully - working something out here, slowly, I'm suuuuuuuuuper new to Clojure and it's a bit of a cliff :) i've goofed with trying that, but it seems to blow up some other stuff equally

15:49 sdegutis: Hmm. I had IRC minimized, and didn't realize I was even logged into IRC.

15:49 Yet, here we are.

15:56 And again!

15:56 My goodness, this day is full of surprises.

15:57 spieden: sdegutis: i just went past this tmux pane and had the same experience =)

15:57 sdegutis: One minute I forget IRC exists, the next minute I realize I have a minimized live IRC window.

15:57 spieden: :)

15:58 spieden: i was trying the slack channels for a bit but petered out

15:59 not as easy to check in on i find, plus some sense of backlog obligation

16:01 sdegutis: Slack was an interesting fad.

16:01 I honestly thought it was going to catch on for a minute there.

16:01 But now it's all over the news that Slack sucks and people are going back to using emails once again.

16:02 I wonder how many times people will try this before they give up and just accept that they'll always either use IRC or email.

16:05 justin_smith: amalloy: does useful already have this? (defn run-indexed! [f coll] (reduce (fn [i x] (f i x) (inc i)) 0 coll))

16:06 fairly obvious extension of run! I think

16:17 sdegutis: justin_smith: why not something more like this? (defn run-indexed! [f coll] (run! f (map list coll (range))))

16:17 That's my go-to when I need indices with my content, which is like never.

16:17 justin_smith: sdegutis: the point of run! is to not build collections you don't need

16:17 sdegutis: justin_smith: meh, it's a lazy sequence

16:18 justin_smith: sdegutis: by that logic run! wouldn't exist and you would just call (dorun (map ...))

16:18 sdegutis: justin_smith: run! already explicitly uses reduce anyway

16:18 justin_smith: sdegutis: if run! should exist, run-indexed! shouldn't create lazy-seqs

16:18 sdegutis: and the reason it uses reduce is in order to not create a lazy-seq it doesn't need

16:18 sdegutis: justin_smith: oh, I see what you mean now; it's needlessly building a collection that it will probably never return, and if it does, it won't need (since it returns nil)

16:19 Why doesn't it just use recir?

16:19 justin_smith: recur? because reduce is simpler and has the same performance when you plan on running for each item in a seqable

16:20 also thanks to the various implementations of the coll-reduce protocol it can perform better (by not needing seq in those cases even)

16:21 sdegutis: (defn run! [f coll] (if-let [x (first coll)] (do (f x) (recur f (rest coll)))))

16:21 Interesting.

16:22 justin_smith: sdegutis: but that needs rest / first, which means you are getting the seq, with the other implementations of the reduce interface/protocol/whatever-it-is you can do better than that

16:23 sdegutis: most of this is pointless for most of our code of course, this is silly levels of micro-optimization, but hey, it first the micro-optimized spirit of run! itself and there's entertainment value to trying to get it right

16:23 *it fits etc.

16:24 amalloy: well, justin_smith's implementation has the benefit of being correct

16:24 sdegutis: Right.

16:24 amalloy: sdegutis's version fails for collections that contain nil or false

16:24 sdegutis: Yeah I always get rest/next confused.

16:24 justin_smith: sdegutis: that's not the issue

16:24 sdegutis: I never explicitly use them, either. Any time I need that behavior, I just use destructuring.

16:33 WorldsEndless: I'm looking for something to get me from "lein new" to a working restful microservice. Any pointers?

16:34 justin_smith: WorldsEndless: well, I'd start with something like "lein new bidi"

16:35 WorldsEndless: I was hoping bidi had a template, but it doesn't seem to

16:35 I went so far as to search clojars...

16:35 I could probably use some understanding on how it works with ring (or just how ring works)

16:38 Okay... reading through Clojure Web Development. It has a chapter on ring...

16:42 tabakhase: hm, i need help in adapting stuff in a ring context... -- "where" is my request object (i want to parse the requestersIP from it in line 10) http://paste.debian.net/416419/

16:42 ive edited the usual [] or req ... variants, but have no idea where its gone with {{}} magics :P

16:42 sdegutis: I very much would like to log off of IRC now.

16:43 rhg135: sdegutis: we'll only use irc till jim exists

16:43 well even then

16:43 maybe bridge it

16:45 amalloy: tabakhase: the request object is what's being destructured on line 9

16:46 you can simply add another key to that destructuring, or add :as request if you want to keep the whole request around, or whatever

16:47 tabakhase: so just add 'remote-addr :remote-addr' inside the {} block and it will find its way? -- is that the first ot second block then? amalloy

16:48 amalloy: tabakhase: {{foo :foo} :body} extracts the :body of the request, and then further destructures that by taking its :foo out

16:48 you don't want to look into the body, so it shouldn't be in the inner map, which is for destructuring the body

16:50 tabakhase: so that last step is "technically" (:body request) ? so my change would be {{...} :body remote-addr :remote-addr}

16:51 WorldsEndless: Okay, so let me get this straight: I need ring to interact with Java services, like Jetty or Immutant, right?

16:52 sdegutis: I suppose now is as good a time as any to exi

16:52 tabakhase: can i also somehow get the full object? (i want to throw it into a func that then also checks the x-forwarded headers and such for example)

16:53 amalloy: tabakhase: try re-reading the first two messages i sent, and see if that answers your question

16:54 tabakhase: ((if also have a wrap-local handler that i generally use where i have the full object -- so maybe that leads me into bad thinkering..

16:55 i think i dont get the "(GET "/stats" []" VS "(GET "/demos" req" VS (POST "/watch" {{}}}" magics...

17:02 justin_smith: WorldsEndless: ring adapts over various ways of running a web server, which can include an embedded web server inside your app, or a container that embeds your app

17:02 WorldsEndless: the nice thing is it makes it so you can use either of those options, with various embedded or embedding implementations, without changing your actual code

17:04 WorldsEndless: what you as a dev end up caring about is defining a handler, which is a function that ring will call for each request (regardless of how the request gets there). The handler will get a hash-map. All the things you need to be able to serve the request are in that map. You return another map, and ring will turn that map into a response.

17:05 typically the handler starts with a router, then functions called based on the route, etc. Clojure routing libs expect to do routing on an incoming ring formatted request.

17:05 it's actually all very simple once you get used to it

17:06 cat-o-the-thrill: justin_smith do you know of a good document that explains all this in detail... or should I just read the source code

17:06 I've read through https://github.com/ring-clojure/ring/wiki

17:07 justin_smith: cat-o-the-thrill: the ring api docs are decent, and that web development in clojure book we were talking about is good (or so I hear). I figured it out by using the stuff and reading the docs mostly, with a bit of code reading.

17:08 cat-o-the-thrill: justin_smith yeah that's what I figured... now if only I could find the time to read the code.

17:09 Probably way better time spent then reading a book

17:09 justin_smith: heh - the important thing to remember is it's all about the protocols (since ring is about adapting various kinds of data coming from the server implementations, and the various valid replies from your handlers)

17:12 sdegutis: I'm severely liking the idea of building my web app using Components for all the "features" which have routes, which would conform to some kind of WebFeature protocol which only specified a (routes [this]) method.

17:13 What is your opinion?

17:14 justin_smith: sdegutis: I really like the idea of having a query api - in other words instead of having an endpoint that returns a specific peice of data gathered in a specific way, you do it as if you are a db, and let the client make db style queries (while of course not just connecting randos on the web to your real db layer)

17:14 sdegutis: You have 30 seconds to respond. Best regards.

17:14 * justin_smith wins.

17:14 sdegutis: justin_smith: Hmm. I'm struggling to imagine even the slightest concreteness in your concept.

17:15 justin_smith: sdegutis: think facebook graph api

17:15 sdegutis: What's that?

17:15 justin_smith: sdegutis: https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html

17:15 rullie: sdegutis: "all girls within 50 miles radius from where i live"

17:16 sdegutis: Hmm. This API seems horrifying. I would prefer to not read any further about it ever.

17:16 rullie: lol

17:17 justin_smith: sdegutis: the idea is that instead of deciding on one end what data you need, and then on the other end writing code that returns exactly that data, you implement a function that parses a simple data structure describing the data you need.

17:18 om next gets into this territory too

17:18 sdegutis: justin_smith: So, instead of providing a fixed list of 'routes', like "/cart", all requests would .. um.. be a "query"?

17:18 rullie: justin_smith: but the "function" you just casually referred to here is an entire field of study in AI.

17:18 sdegutis: justin_smith: Om was an interesting experimental prototype of Reagent.

17:18 Are people still downloading and using Om? That's odd.

17:18 justin_smith: rullie: well, you get to define the rules for a valid query, and you can start with a known quantity like datascript you don't have to do it from scratch.

17:19 rullie: so you basically want sql over http

17:19 justin_smith: rullie: no, datascript

17:19 rullie: sure, same difference

17:19 justin_smith: datastructures, not strings, and no mutability

17:19 rullie: http get is never mutable.

17:20 justin_smith: sdegutis: if you look at that graphql link, it's meant to go with react - it's a way to simplify providing the data the frontend needs.

17:20 rullie: tell that to my coworkers who connect a get request to a db update.

17:20 sdegutis: justin_smith: Hmm, I've heard of React on HN a few tims.

17:24 justin_smith: anyway, I haven't tried doing an api this way, but I can see the appeal - why do an ad-hoc query / response combo that tightens the coupling between frontend and backend code when you can use an established query language, with easy to manipulate data structures on the input and output sides.

17:24 the hard part is isolation I guess, but it's not like this is solved by regular apis perfectly anyway

17:25 sdegutis: justin_smith: because it requires inventing some kind of query language on top of HTTP requests.

17:26 And transforming HTTP requests to this language.

17:26 Which I'm not opposed to in principle, but I'm not gonna be the one to invent it.

17:27 justin_smith: sdegutis: well datascript is already out there, it's not like you need to implement that - more the step of binding that to your own datomic or whatever on the backend

17:30 rullie: justin_smith: why use typed language that tightens the couping between your datastore and your actual data when you can just have maps of randoms? :)

17:31 justin_smith: as a user of an untyped data oriented language in an irc channel devoted to said language, why indeed?

17:32 sdegutis: justin_smith: Hmm. Interesting.

17:32 justin_smith: I like your (routes [this]) idea a lot.

17:33 justin_smith: I assure you I'm just sharing relevant ideas that I picked up here an there, I invented none of it.

17:33 sdegutis: justin_smith: the routes idea is great.

17:34 I really want to use Component, but it's just so complex. The readme's length really gives away how much needs to be memorized about how to use it.

17:35 In itself, the component/Lifecycle protocol is very simple and understandable. But the Systems section (https://github.com/stuartsierra/component#systems) is where it starts getting very confusing very quickly.

17:39 Huh! I like this idea more and more.

17:40 There'd be no need to store any of the dependency components on the request via middleware. You'd just get them from the Component's initialized fields.

17:45 https://gist.github.com/sdegutis/442d9ed9a6cf861ce7f7

17:45 justin_smith: right, interesting

17:45 sdegutis: Hmm, I forgot to use "db" anywhere.

17:46 But the point is that it could.

17:46 And records (all objects) automatically conform to component/Lifecycle, so they could be given to component/system-map.

17:47 Something like (conn db) would be called and the result passed to cart/add-product and whatever else.

17:51 Fwiw I like the aspect of Compojure that it uses Clout for.

17:51 And I have no problem creating the router functions manually and giving them to Compojure rather than using its DSL.

17:52 But man, Component is confusing.

18:10 Hmm. All my components have no-op start/stop methods, except one, the email service, which queues emails up every 2 seconds and then sends them.

18:10 I wonder if I can fix that one to not need start/stop. Then I'd be in business!!!

18:10 Actually, wait! I can!!

18:10 Wait, no.

18:11 Then I literally wouldn't even need Component! I'd just create a map of things, and give some of those things to the other things!!

18:11 Oh wait, the HTTP router.

18:11 DANGIT.

18:11 Oh wait! I still don't need Component for that. The router can BE the fricken system!

18:11 amirite? eh? ehh??

18:15 Hi.

18:17 ben_vulpes: hi sdegutis

18:17 sdegutis: how r u

18:17 ben_vulpes: well

18:17 yourself?

18:30 sdegutis: Great thanks.

18:34 Is this valid Clojure code, and will it resolve the .stop method properly at compile-time? (.stop ^Server (:server component))

18:38 Malnormalulo: Do you need the type hint? I've never seen one inside an s-expression like that -- usually they're in function signatures

18:39 amalloy: sdegutis: yes

18:39 sdegutis: Great, thanks amalloy.

18:40 amalloy: you can set *warn-on-reflection* to true to confirm

18:40 sdegutis: Malnormalulo: I have no idea if it's needed.

18:41 Is there a good reason not to put :global-vars {*warn-on-reflection* true} inside project.clj?

18:45 What simple self-sufficient Clojure expression is guaranteed to trigger a warning when warn-on-reflection is true?

18:46 Huh. Weird.

18:47 ,(binding [*warn-on-reflection* true] (eval '(.toString 23)))

18:47 clojurebot: #error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb...

18:48 sdegutis: Haha stupid thing.

18:51 Hmm. Okay, I see what happens now.

18:51 Thanks amalloy.

19:45 kenrestivo: is riemann still actively in use?

19:46 or are there newer ways to do this kind of thing with, say, onyx, core.async and transformers, etc?

19:48 tolstoy: Seems to have recent commits.

19:51 amalloy: aphyr probably still actively uses it

20:26 TimMc: ,((resolve (symbol "eval")) '(+ 1 2 3))

20:26 clojurebot: 6

20:27 TimMc: ,(binding [*warn-on-reflection* true] ((resolve 'eval) '(.toString 23)))

20:27 clojurebot: #error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb...

20:28 TimMc: I wish I could see what exactly was being denied...

20:28 Oh right, it's try/catch that clojurebot doesn't like, not eval.

20:36 tolstoy: On data.json :value-fn, how come (case (type v) java.util.UUID (str v) ...) doesn't work? Odd.

20:36 (cond (instance? java.util.UUID v) (str v) ...) does.

20:38 hiredman: ,(type 'java.util.UUID)

20:38 clojurebot: clojure.lang.Symbol

20:38 hiredman: ,(doc case)

20:38 clojurebot: "([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need not be quoted. If the expression is equal to a test-constant, the corresponding result-expr is returned. A single default expression can foll...

20:38 tolstoy: Oh, hm.

20:40 ,(= (type (java.util.Date.)) java.util.Date)

20:40 clojurebot: true

20:41 tolstoy: ,(case (type (java.util.Date.)) java.util.Date :foo :bar)

20:41 clojurebot: :bar

20:41 tolstoy: ,(condp = (type (java.util.Date.)) java.util.Date :foo :bar)

20:41 clojurebot: :foo

20:41 hiredman: "... They must be compile-time literals ..."

20:42 ,(type 'java.util.Date)

20:42 clojurebot: clojure.lang.Symbol

20:42 hiredman: ,(type (resolve 'java.util.Date))

20:42 clojurebot: java.lang.Class

20:43 tolstoy: I guess I'm a little confused about "literal" and class names, but I think I see it.

20:45 hiredman: ,(type (read-string "String"))

20:45 clojurebot: clojure.lang.Symbol

20:46 hiredman: ,(type (eval (read-string "String")))

20:46 clojurebot: java.lang.Class

20:46 hiredman: not a literal

20:46 tolstoy: ,(str (class (java.util.Date.))

20:46 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

20:46 tolstoy: ,(str (class (java.util.Date.)))

20:46 clojurebot: "class java.util.Date"

20:46 tolstoy: Oh, well. condp solves it for me. ;)

21:15 srruby: Does anybody have a source code formatter that follows bbatsov's guidelines? https://github.com/bbatsov/clojure-style-guide#source-code-layout--organization

21:16 tolstoy: https://github.com/weavejester/cljfmt maybe?

21:18 sfz-: and https://github.com/venantius/vim-cljfmt which uses it as a vim plugin

21:18 srruby: tolstoy: Thanks!

21:50 sdegutis: Which (ns) form is more correct when I just want to use Server as a class name? (:import org.eclipse.jetty.server.Server) or (:import [org.eclipse.jetty.server Server])

21:57 How do you do that thing like this? (.. ^Server server (stop) (join)) ?

21:58 Oh right, (. ^Server server (stop) (join))

21:58 Yay! Thanks amalloy.

22:21 Oh man justin_smith this is a great idea.

22:21 Your routes thing is working amazingly.

22:30 ajb: If I have a vector containing maps that all share a common key of `:tags` and that has another vector containing shared tags, how would I filter that based on one of the tags in the vector?

22:36 TEttinger: ajb: something like [{:tags [1 2]} {:tags [2 3]} {:tags [100 200 300]}] for the first thing you mentioned?

22:36 assuming strings instead of ints

22:36 ajb: yeah

22:37 TEttinger: so in that case, if you wanted to look for the tags [1 100], that would return the maps that have (I didn't have any other data, so just the taglist) [1 2] and [100 200 300], but not the other one?

22:39 ajb: correct

22:40 TEttinger: ,(for [data [{:tags #{1 2}} {:tags #{2 3}} {:tags #{100 200 300}}] wanted [1 100] :when ((:tags data) wanted)] data)

22:40 clojurebot: ({:tags #{1 2}} {:tags #{300 100 200}})

22:40 TEttinger: that uses sets not vectors, but I assume you don't want duplicate tags

22:41 it shouldn't be too hard to convert to use vectors, I just don't remember the fn off the top of my head

22:41 ajb: (vec)?

22:44 TEttinger: no no, I mean searching a set is just what the set does, I don't remember which searches a vec for an item

22:46 ,(for [data [{:tags [1 2]} {:tags [2 3]} {:tags [100 200 300]}] wanted [1 100] :when (some #{wanted} (:tags data))] data)

22:46 clojurebot: ({:tags [1 2]} {:tags [100 200 300]})

22:47 TEttinger: ,(for [data [{:name "TEttinger" :tags [1 2]} {:name "ajb" :tags [2 3]} {:name "rhickey" :tags [100 200 300]}] wanted [3] :when (some #{wanted} (:tags data))] (:name data))

22:47 clojurebot: ("ajb")

22:47 ajb: :D

22:47 TEttinger: that look like what you wanted?

22:47 for is a great piece of code

22:49 ajb: exactly what I wanted, thank you so much!

22:49 I tried to do that weeks ago and just ended up switching to datascript because of the cardinality it offers

22:49 I can finally use just plain clojure, woo

22:53 TEttinger: I am almost certain there's a more efficient way to do it; for goes through all combinations as part of something like...

22:54 ,(for [x [1 2 3] y [10 20]] [x y])

22:54 clojurebot: ([1 10] [1 20] [2 10] [2 20] [3 10] ...)

22:54 TEttinger: so if testing for many tags or many items, it tests more than maybe it needs to

22:54 then again, that might be appropriate here

22:55 since each tag is actually independent of the data, it could appear in all items or not at all

23:21 sdegutis: Hey.

23:21 Is it possible to-- oh wait!

23:36 Woo!

23:41 ajb: sdegutis: care to share?

23:41 sdegutis: C-x cider-refresh

23:41 Or C-c C-x for short

23:41 So far it mostly works, but it's not entirely working.

23:43 /cc ajb

23:43 ajb: awesome!

23:44 when are we going to get an all clojure window manager? :p

23:45 /cc sdegutis

23:45 sdegutis: ajb: haha, I already made ClojureScript bindings for my HTTP-based one a few years ago

23:45 I forgot what I called that one.

23:45 It was before Phoenix or Hydra though.

23:45 Man was it silly.

23:46 ajb: hah, sounds like a fun project

23:46 sdegutis: Huh, now I wonder what that was called.

23:46 Oh! Zephyros!

23:46 Man I was so crazy.

23:47 ajb: Aren't you in progress of making a new one?

23:47 that's paid/closed source

23:47 sdegutis: Oh boy, not even in the slightest.

23:47 I gave up on that years ago.

23:47 Nobody uses window managers, and the few people who do, aren't willing to pay, because there are many free ones.

23:47 And there are many paid ones too.

23:47 ajb: have you seen kwm?

23:48 sdegutis: Probably.

23:48 ajb: https://github.com/koekeishiya/kwm

23:48 it actually takes the windows and tiles them sort of like amethyst

23:48 sdegutis: Neat.

23:48 ajb: sort of like an OS X version of i3

23:48 sdegutis: Oh yeah I saw that one.

23:49 I just use AppGrid these days.

23:49 ajb: I just sort of gave up on the osx wm front and just switched over to fedora/i3 a while ago

23:49 sdegutis: https://github.com/sdegutis/appgrid

23:49 ajb: oh, nice!

23:49 sdegutis: Cool. I'd love to switch over to Linux, if it would just add all the features I need.

23:49 ajb: like what?

23:50 sdegutis: Well the main one is being able to support my Apple hardware as well as OS X does.

23:50 ajb: yeah, that's a bit lacking :/

23:50 sdegutis: That's actually pretty much it.

23:50 If they could get that working, I'd be sold.

23:51 ajb: but in my (albeit limited) experience with it, there aren't that many problems with hardware compatiblity on linux with the macbooks

23:51 sdegutis: 100% of the apps I use on OS X are Chrome and Emacs anyway.

23:51 What about retina MBP?

23:51 ajb: I have to say though, the one thing that I missed for the first few weeks was alfred

23:51 sdegutis: https://wiki.archlinux.org/index.php/MacBook#MacBook_Pro_with_Retina_display

23:52 Ah yeah, I know some people who use Alfred. I don't.

23:52 But, that reminds me, I do use Dash.

23:52 Does Linux have Dash?

23:52 ajb: Not sure, I am typing this on an 11" MBA right now

23:52 I think so

23:52 or something like it

23:52 https://zealdocs.org/

23:52 sdegutis: I use it for Java 8, jQuery, and Clojure. If they got that, then great.

23:53 Wow, such 1990s UI.

23:53 Hmm. I may experiment with trying Linux out on my stupid little 2013 rMBP.

23:53 ajb: you should try it!

23:54 sdegutis: Hmm. Then again...

23:54 I'd rather use that time making cool things in Clojure instead.

23:54 cuz that makes me money.

23:54 And OS X only super-annoys me like no more than 5% of the time.

23:54 Plus it lets me sync my stupid iPhone ever few months.

23:54 Then again I don't really need to do that anymore I guess.

23:55 The main thing though is figuring out why 9alter-var-root #handler (rebuild-handler)) is not seeming to do the thing I want it to.

23:55 ajb: huh? what's that?

23:55 sdegutis: s/9a/\(a/

23:55 Something I'm working on in Clojure for work.

23:57 Huh. It seems that (run-jetty #'handler ...) is completely ignoring changes to handler's root.

23:57 I.. I thought that was the whole point??

23:57 srruby: I'm on MBP/Linux

23:58 sdegutis: srruby: is it terrible on your battery & wifi?

23:58 I just imagine it must be.

23:59 ajb: once you get tlp setup the batterylife is pretty much the same

23:59 srruby: sdegutis: I'm really enjoying it. Battery life and wifi seems good.

23:59 sdegutis: Hmm.

23:59 ajb: maybe even a little longer in my case

23:59 sdegutis: I dunno.

Logging service provided by n01se.net