#clojure log - Feb 19 2015

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

0:00 justin_smith: without the eval it looks OK

0:00 AHA

0:00 ,((fn [fname & args] (eval (conj () (conj args 'list) (read-string fname) 'apply))) "inc" 2)

0:00 clojurebot: 3

0:00 justin_smith: super-weird

0:00 haha

0:01 TEttinger: a ha!

0:01 justin_smith: TEttinger: it was because you were creating '(2) and passing it to eval

0:01 TEttinger: ahhhhhh

0:01 ,((fn [fname & args] (eval (conj () (vec args ) (read-string fname) 'apply))) "inc" 2)

0:01 clojurebot: 3

0:02 sm0ke: ,((fn [fname & args] (apply (eval (read-string fname)) args) "inc" 2)

0:02 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

0:02 justin_smith: the moral is: eval + conj on lists gets confusing when you have had enough vodka

0:02 TEttinger: ,((fn [fname & args] (eval (conj () (vec args ) (read-string fname) 'apply))) "+" 2 3 4)

0:02 clojurebot: 9

0:02 sm0ke: ,((fn [fname & args] (apply (eval (read-string fname)) args)) "inc" 2)

0:02 clojurebot: 3

0:02 TEttinger: ah, clever sm0ke

0:02 (inc sm0ke)

0:02 lazybot: ⇒ 8

0:02 sm0ke: :)

0:02 TEttinger: ,((fn [fname & args] (apply (eval (read-string fname)) args)) "+" 2 3 4)

0:02 clojurebot: 9

0:02 sm0ke: (inc justin_smith TEttinger )

0:03 lazybot: ⇒ 1

0:03 TEttinger: inc is still unary

0:03 sm0ke: hurmm who is getting all those karma points

0:03 justin_smith: ((fn [fname & args] (apply (resolve (symbol fname)) args)) "inc" 2)

0:03 (karma justin_smith TEttinger )

0:03 sm0ke: (inc justin_smith )

0:03 lazybot: ⇒ 6

0:03 TEttinger: (identity justin_smith TEttinger )

0:03 lazybot: justin_smith TEttinger has karma 1.

0:03 sm0ke: (inc TEttinger )

0:03 lazybot: ⇒ 3

0:03 justin_smith: TEttinger: it takes arbitrary strings

0:03 sm0ke: there you go

0:03 TEttinger: spaces

0:03 (identity TEttinger)

0:03 lazybot: TEttinger has karma 42.

0:04 justin_smith: notice that "justin_smith " has 1/20th my karma or so

0:04 (identity justin_smith)

0:04 lazybot: justin_smith has karma 189.

0:04 TEttinger: so you're at 195 abouts?

0:04 we're going to need a 200 karma party

0:04 (identity technomancy)

0:04 lazybot: technomancy has karma 162.

0:04 justin_smith: ,(/ 189.0 6.0)

0:04 clojurebot: 31.5

0:04 TEttinger: (identity Raynes)

0:04 lazybot: Raynes has karma 55.

0:05 TEttinger: (identity rhickey)

0:05 lazybot: rhickey has karma 9003.

0:05 TEttinger: hahaha

0:05 justin_smith: oh, only 1/30th!

0:05 TEttinger: of course it would have to be over 9000 on this channel

0:05 sm0ke: (dec sm0ke)

0:05 lazybot: You can't adjust your own karma.

0:06 sm0ke: (+ 1000 justin_smith )

0:06 :P i tried

0:06 TEttinger: you know, I've been making gfredericks memes, but any meme I made of myself would involve invisible BOMs so it would probably just be... well just as incomprehensible to outsiders

0:07 justin_smith: TEttinger: haha

0:07 sm0ke: gfredericks once pm'd me asking not to use offensive language in channel, and all is said was ~sex

0:07 lazybot: sex?

0:07 justin_smith: TEttinger: panorama picture of a cat so it looks like his head comes out of his tail "invisible BOM"

0:07 TEttinger: hahaha

0:08 ~sex

0:08 clojurebot: sex is off-topic and not appropriate for the channel

0:08 sm0ke: see

0:08 clojurebot: sex |is| never offtopic

0:08 clojurebot: Ok.

0:08 sm0ke: clojurebot: ~sex

0:08 clojurebot: Excuse me?

0:08 TEttinger: hha

0:09 no need to clojurebot:

0:09 sm0ke: ~sex

0:09 clojurebot: sex is never offtopic

0:09 sm0ke: quick learner is clojurebot

0:09 clojurebot: c'est bon!

0:09 sm0ke: ~clojurebot

0:09 TEttinger: clojurebot: sex |is| frequently offtopic

0:09 clojurebot: Ack. Ack.

0:09 clojurebot has a poetic soul

0:13 justin_smith: TEttinger: http://i.imgur.com/E5j8fwX.jpg?1

0:14 sm0ke: what is BOM?

0:14 justin_smith: ~BOM

0:14 clojurebot: Cool story bro.

0:14 TEttinger: \ufeff

0:14 byte order marker

0:14 an invisible character that's legal in clojure and java identifiers

0:17 sm0ke: BUT then i ask how do you copy and type something which is invisible!!!

0:17 :D

0:17 justin_smith: that's exactly the problem

0:19 TEttinger: ,(let [bindings "should have an even number of forms" bindings "BETTER HAVE AN EVEN NUMBER OF FORMS" bindings] bindings)

0:19 clojurebot: "should have an even number of forms"

0:20 TEttinger: I made that with

0:20 ,(println ",(let [bindings \"should have an even number of forms\"\ufeff bindings \ufeff\"BETTER HAVE AN EVEN NUMBER OF FORMS\"\ufeff bindings] bindings)")

0:20 clojurebot: ,(let [bindings "should have an even number of forms" bindings "BETTER HAVE AN EVEN NUMBER OF FORMS" bindings] bindings)\n

0:20 sm0ke: ,(def a b 1)

0:20 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

0:21 TEttinger: ,(def ab 1)

0:21 clojurebot: #'sandbox/ab

0:21 TEttinger: ,ab

0:21 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ab in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:22 TEttinger: ,ab

0:22 clojurebot: 1

0:22 TEttinger: it's tricky business

0:23 sm0ke: i was trying to put a ufefs in between :P

0:23 TEttinger: and I did

0:23 sm0ke: NO!!

0:23 ,ab

0:23 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ab in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:23 TEttinger: ,(map char ",(def ab 1)")

0:23 clojurebot: (\, \( \d \e \f ...)

0:23 sm0ke: ,ab

0:23 clojurebot: 1

0:24 sm0ke: nice one!

0:24 TEttinger: ,(map char "ab")

0:24 clojurebot: (\a \ \b)

0:24 TEttinger: it doesn't even print the visible character

0:24 ,(map int "ab")

0:24 clojurebot: (97 65279 98)

0:25 TEttinger: it gets crazier once you start needing to enter un-enterable, un-copyable characters

0:25 I believe some of the early, before space ascii characters have that property

0:26 sm0ke: imagine someone quietly sneaking these is clojure source code

0:26 TEttinger: clojurebot: BOM |is| http://i.imgur.com/E5j8fwX.jpg?1

0:26 clojurebot: Ack. Ack.

0:26 TEttinger: ~BOM

0:26 clojurebot: BOM is http://i.imgur.com/E5j8fwX.jpg?1

0:26 sm0ke: like in clojure.\ufeffcore

0:26 TEttinger: oh man

0:26 in C# it's even worse

0:26 you can overload the empty string

0:27 sm0ke: does github shows a diff for bom?

0:29 TEttinger: it must, it's different text

0:29 it would be +1 char

0:29 sm0ke: hmm lets hope so

0:31 TEttinger: ah,

0:31 typeof(string).GetField("Empty").SetValue(null, " ");

0:31 makes the empty string equal to " "

0:31 sm0ke: ,(= "ab" "ab")

0:32 clojurebot: false

0:32 TEttinger: and worse, that C# code can be stuck in a static constructor, making it run whenever that class is imported

0:33 sm0ke: i dont know much C# what are you trying to do there?

0:33 TEttinger: it's from an article on "Code Bombs"

0:33 things disgruntled employees could stealthily leave behind in code

0:33 and horribly break a running program

0:34 http://thedailywtf.com/articles/comments/The-Disgruntled-Bomb in comments

0:34 justin_smith: oh, the fucked up shit an angry clojurist could do...

0:34 sm0ke: ah i see!

0:34 justin_smith: i guess this can be sneaked everywhere

0:35 TEttinger: there's a good reason for it too

0:35 I actually added a bomb in some code I sent to a previous employer (in a different country), but I told them I had inserted the bomb, and would forward the source, without bomb, once payment cleared. This could be re-purposed.

0:35 justin_smith: sm0ke: in clojure there is very little you couldn't redefine out from under a running process, as a side effect of just loading your ns

0:35 prateekp: lein deps failed

0:35 cannot find project.cljs

0:35 TEttinger: prateekp: lein deps :tree

0:35 oh

0:36 well that would be a problem then

0:36 justin_smith: project.cljs?

0:36 is that even a thing?

0:36 TEttinger: where are you putting your deps?

0:36 prateekp: the project.cljs is not in the root

0:36 TEttinger: it should be project.clj I would imagine

0:36 justin_smith: wait, lein can even use "project.cljs" I have never even heard of that

0:36 TEttinger: but I guess it can huh

0:36 justin_smith: and also why would you not put it in the root

0:36 prateekp: clj*

0:36 TEttinger: it needs to be in root

0:37 or wherever you're executing lein from

0:37 prateekp: its in the root of the client folder ... but travis cant access it as .travis.yml is in the root of the repo

0:38 TEttinger: is this on github or something where we can see it?

0:38 (the code I mean, prateekp)

0:39 prateekp: i am very sorry, the code is private actually

0:39 but i can tell you

0:39 the situation

0:39 justin_smith: prateekp: if the project.clj can't be in the root, can you tell travis to run lein from a subdirectory containing the lein project?

0:40 prateekp: ohh yeah but while i am doing cd folder/ && lein cljsbuild once in the .travis.yml

0:40 its giving same error

0:41 sm0ke: TEttinger: and how do you know they wont be able to find it?

0:41 prateekp: justin_smith: is there other way to do it

0:41 sm0ke: TEttinger: you must have put it differently ? sounds very unprofessional

0:41 TEttinger: sm0ke, it's a quote from that article

0:41 err, comments

0:42 sm0ke: eh ok lol

0:43 TEttinger: sm0ke, he talks about how it slowly, over the course of 15-30 minutes, got slower and slower to the point of unusability. it let them verify the trial version, but not ship until payment cleared

0:43 justin_smith: prateekp: if you are having travis switch to the directory containing the project.clj, and lein doesn't find the project.clj, there is clearly something wrong that you haven't described yet

0:43 sm0ke: TEttinger: DRM is hight controvertial

0:43 highly*

0:44 TEttinger: yeah, but most people want to get paid, and some unscrupulous buyers won't pay if they think they can get away with cheating a foreigner

0:44 sm0ke: i would just prefer to deal with customers who can be trusted

0:44 justin_smith: prateekp: I assume the cd / lein commands are in one shell invocation? because usually each command is totally isolated

0:46 prateekp: i did like this

0:46 language: clojure

0:46 script: cd client && lein cljsbuild once && cd assets && compass compile

0:46 these are two commands i am using

0:47 in .travis.yml

0:48 justin_smith: and lein complains that it can't find project.clj?

0:49 prateekp: justin_simth: ^^

0:49 yes

0:50 justin_smith: prateekp: the line "language: clojure" tells travis to run lein test

0:50 you should take that out, it is causing your error

0:50 because of course lein test from the top level will fail

0:51 prateekp: ahh

0:51 so i should keep only the script command

0:51 justin_smith: right, "language: clojure" is just a shortcut for some default things to do with clojure code

0:51 you may want to add what it would have done to your script

0:52 prateekp: ahh thanks

0:56 TEttinger: (inc justin_smith)

0:56 lazybot: ⇒ 190

0:58 prateekp: while i am trying to run a project locally, i am getting an error - Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath

0:58 justin_smith: when using lein?

1:00 prateekp: yeah when building locally

1:00 justin_smith: sounds like a messed up config - can you run "lein help" outside your project dir?

1:01 prateekp: outside in the home folder, it gives out a list of commands

1:02 justin_smith: prateekp: yeah, probably something misconfigured in your project.clj

1:02 prateekp: and a error

1:02 Problem loading: java.io.FileNotFoundException: Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath: (localrepo.clj:1)

1:02 justin_smith: OK, then disable lein localrepo

1:02 prateekp: it gives the same error outside

1:02 justin_smith: lein localrepo is nearly useless nowadays anyway

1:02 prateekp: how should i do that

1:02 is there a coomad

1:03 justin_smith: it's a plugin, likely in your ~/.lein/profiles.clj

1:04 it's probably not compatible with newer lein versions - and AFAIK it isn't needed

1:05 prateekp: there is no profiles.clg

1:06 though there was a plugin localpro tar which i deleted

1:06 but still the same error persists

1:07 justin_smith: OK, something somewhere is telling lein to use localrepo

1:07 usually it would be ~/.lein/profiles.clj that set that up

1:07 what's your $LEIN_HOME setting in your shell?

1:08 prateekp: ahh i did echo $LEIN_HOME

1:08 it says nothing

1:09 justin_smith: OK, that's normal, but that means I have no idea what would be trying to load localrepo

1:10 and that error clearly indicates localrepo

1:10 prateekp: hmm

1:11 justin_smith : regarding the previous problem, it failed again saying lein not found

1:11 should i write lein: lein in .travis.yml

1:12 justin_smith: prateekp: you should try to find out what "lang: clojure" does in travis.yml, and recreate that without the part where project.clj has to be at the top level

1:17 prateekp: justin_smith : now the error looks different - Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath:

1:18 its not related to localpro

1:18 its subproject.clj:1

1:19 justin_smith: OK why do you keep getting errors with lein plugins when you claim that you don't have any profiles.clj?

1:19 subproject.clj is from lein-sub

1:20 what's your lein version?

1:20 prateekp: 1.7.1

1:20 justin_smith: OK, do you have any reason to be using a version that old?

1:21 prateekp: just did sudo apt-get

1:21 justin_smith: don't use the apt-get version of lein, install lein 2.x and let it auto-update. Best place to install it is to ~/bin

1:21 1.x is bad

1:22 prateekp: ok

1:22 justin_smith: lein is one of the few programs that manages it's own updates better than apt

1:22 because it is very self contained, and good at handling updates / rollbacks

1:23 as long as you install it locally / per -user

1:24 prateekp: what path should i choose to install lein

1:24 any path is ok_?

1:24 ?

1:24 justin_smith: your home bin/ dir is best I think ~/bin

1:24 but as long as it's in your PATH it will work

1:24 prateekp: is /bin ok

1:25 justin_smith: no, it should be owned by your user

1:27 prateekp: justin_simth

1:27 how to run it

1:28 i have saved and chmod 755 the lein file

1:28 in the ~/bin floder

1:28 justin_smith: you need to add ~/bin to your PATH

1:28 some shells do this automatically when you log in if the directory exists

1:28 which file to edit depends on your current setup / shell

1:29 likely .login / .profile / .bashrc

1:29 one of those

1:30 prateekp: i have added path

1:30 now how do i run it

1:31 justin_smith: lein

1:31 prateekp: ahh

1:31 justin_smith: if it's in your path, it's just lein

1:31 prateekp: hmm ]

1:31 its running

1:31 and thats it

1:31 justin_smith: yeah, probably doing a big self-install for its first run

1:32 prateekp: do i need any other thing now

1:32 justin_smith: you should be able to run your lein commands now

1:32 prateekp: hmm i have started the build

1:33 lets see if it passes this time

1:34 hmm its working

2:16 i am sorry ... i am, asking the same problem which i asked before ...

2:17 actually i am trying to run travis for clojure project

2:18 for travis to run, we have to keep the .travis.yml file at the root but the project.clj file in in another folder

2:19 so when i try to do script : cd folder/ && lein cljsbuild test

2:19 the travis tells cannot find the file named project.clj

2:19 luxbock: thoughts on using the discard macro (#_) for documentation?

2:20 prateekp: is the command in travis.yml -- language: clojure is running something that calls project.clj

2:20 how can i know what does this command do

2:21 luxbock: one could use it a bit like /* ... */ is used in Java, but without having to add *'s for each line

2:31 Kneiva: Java does not require * for each line

2:32 TEttinger: luxbock: since it's very similar to ; just for forms instead of until-end-of-line, I like #_ in general

2:32 and since ; is used for comments, I see no reason discard couldn't be adapted to comments

3:26 lxsameer_: what testing framework is more popular in clojure community ?

3:27 slipset: lxsameer_: midje?

3:27 lxsameer_: or even test.check which is property based

3:27 I kinda like midje with its auto-test stuff

3:27 whenever you save your file, midje runs all your tests

3:28 Empperi: midje is nice but plain ol' clojure.test isn't that bad either

3:28 midje has this problem about crapping the line numbers when your code throws an exception

3:28 when it breaks on assertion then it's great

3:32 lxsameer_: Empperi: slipset thanks guys

3:38 domokato: What is a possible reason for a NullPointerException on a java method call during compile time?

3:38 it's on the top-level of a namespace; is that okay?

3:40 TEttinger: domokato, one of the arguments or the object that you're calling it ob must be null somewhere

3:40 *on must

3:41 stick a println before it, see what the values are

3:41 domokato: but this is during compile time

3:45 oh, it actually runs the code during compile time...crazy

3:45 there's my problem

3:45 thx

3:45 TEttinger: cool!

4:04 mnngfltg: Has anyone tried persisting Clojure's persistent data structures on disk?

4:09 Basically I'd like to keep a PersistentHashMap in an atom and, on swap!, commit changes to the map to disk

4:09 slipset: wouldn't that just be to prn it to a file?

4:10 if you add a watcher to the atom?

4:10 but, you will probably have some problems going that way because you can have several swaps before you finish writing to disk

4:11 sounds like you want a databse

4:12 mnngfltg: slipset, yes, I bsically want to implement my own embedded database

4:12 hyPiRion: mnngfltg: This sounds like a subset of Datomic

4:12 slipset: mnngfltg: now why would you want to do that?

4:12 hyPiRion: oh, embedded

4:13 mnngfltg: hyPiRion, I haven't loooked into datomic yet

4:13 but yes, the idea would be to keep things as simple as possible

4:13 sort of like sqlite or h2 but with the ability to persisten clojures's maps, vectors and sets

4:13 slipset, I think it fills an interesting niche

4:13 hyPiRion: mnngfltg: I'd love to have something like an embedded datomic. I've looked at it and haven't found anything though

4:14 after it*

4:14 mnngfltg: slipset, basically you could use it to power a simple multithreaded web server with a very flexible data model

4:15 the whole dataset (app state) is in memory, in an atom, and each to you (swap!) the updates are committed to disk

4:15 presumably using some kind of commit log, so if you restart the app can re-build its state

4:17 hyPiRion, I've found http://www.mapdb.org/, which might be a nice base for a clojure-centric embedded db

4:55 dysfun: mnngfltg: i've got something going along those lines myself

4:56 not using mapdb, doing basically what you described

4:58 piranha: what's the benefit of using ref instead of atom? I have a bit of code which uses ref, and I mostly used atoms (most of my clojure code was clojurescript), so I'm wondering what's the point

4:59 kungi: piranha: refs are coordinated atoms are not

5:00 piranha: kungi: and 'coordinated' means that I can change two refs at the same time in 'dosync', right?

5:00 that's the point of using a ref?

5:00 and if I only have a single ref, it could as well be an atom?

5:01 kungi: piranha: as far as i see. yes and yes

5:01 piranha: kungi: cool, thanks!

5:01 clgv: piranha: yeah consistence of modifications of multiple refs

5:01 kungi: piranha: when I think about refs I always think about bank accounts. Transfer money from account a to b

5:02 piranha: ok :)

5:03 ianhedoesit: the clojure.org pages on them (http://clojure.org/atoms and http://clojure.org/refs) give pretty good descriptions, I think.

5:03 clgv: ianhedoesit: the books do a better job ;)

5:03 ianhedoesit: I'd hope so, since the page on atoms is only three short paragraphs!

5:04 piranha: that's mainly why I asked :)

5:04 ianhedoesit: but for a quick "spot the difference" it's pretty useful, I think.

5:05 kungi: Until now I never had to use a ref ...

5:05 piranha: oh, I just found out why the code uses refs and it makes sense

5:06 it needs to 'return and remove first element of contents', atomically

5:06 clgv: ianhedoesit: I'd say that one serves better for that purpose http://clojure-doc.org/articles/language/concurrency_and_parallelism.html#clojure-reference-types

5:06 piranha: and with ref it's wrapped in dosync, which makes it work

5:07 ianhedoesit: clgv: that is pretty nice! definitely more detailed.

5:07 (well, with a quick glance)

5:08 clgv: they gathered a decent amount of clojure knowledge overthere

5:08 dysfun: piranha: return and remove is an atomic operation

5:09 piranha: dysfun: (let [x (first @pool)] (swap! pool rest) x) is not exactly atomic, is it?

5:09 clgv: dysfun: not really with Clojure atoms, as swap! returns what is written into the atom

5:09 piranha: dysfun: it makes it possible that two threads will get same item from pool simultaneously

5:10 dysfun: i didn't say it was the best option, merely that it's atomic

5:10 ianhedoesit: piranha: I don't think that's possible?

5:10 dysfun: and the swap! can be wrapped

5:10 but yes, using refs here is a better option

5:10 piranha: ianhedoesit: why not?

5:12 ianhedoesit: I don't know. give me a minute to be silent until someone else says I'm wrong

5:19 julianleviston: If I want to access a piece of data in a map from multiple keys, is a good way to do that just to assoc the data in (inside a map which includes all the keys) multlpe times, once against each of the keys?

5:19 clgv: dysfun: you'd need a modified swap! implementation that lets you choose which value to return on successfull modification of the atom

5:20 julianleviston: clgv: it’s not being stored in an atom

5:21 clgv: julianleviston: I didn't answer you ;)

5:21 julianleviston: clgv: oh haha soz :)

5:22 clgv: julianleviston: you need to provide some kind of example to explain what you want to do

5:22 julianleviston: clgv: ok. I’ll build one.

5:22 wagjo: clgv: dysfun: something like https://github.com/flatland/useful/blob/develop/src/flatland/useful/state.clj#L43

5:22 TEttinger: a multimap?

5:24 clgv: wagjo: not really, but could serve as a blueprint how to achieve the desired result

5:24 dysfun: clgv: actually you need a second atom or a promise :)

5:24 clgv: wagjo: though it is actually cheating ;)

5:24 dysfun: clgv: as i said, ref is a better option in this case

5:25 clgv: dysfun: I guess you cant make a general function for it - it would need to be a macro to be able to select an arbitrary return value and not to do computations twice

5:29 julianleviston: clgv: here’s my pastie illustrating what I’m after… it feels a bit messy because I’m duplicating data. On the other hand, in the context I’m using it in, I don’t have to update the data, so perhaps that’s not important: https://www.refheap.com/97520

5:29 clgv: also, will there be any problems if the value at :data is a core async channel, do you think?

5:30 TEttinger: oh, were you talking to me?

5:30 TEttinger: yes, sorry

5:30 dysfun: clgv: i don't think it would need to be. but since refs are a better option in this case, i have no real desire to see if it can be done :)

5:31 julianleviston: TEttinger: ah… A multimap is multiple values, isn’t it? I want multiple keys...

5:31 TEttinger: as in… two paths into the values…

5:33 TEttinger: I mean, my proof-of-concept code there would work, it just feels ugly.

5:33 wagjo: you can have multiple keys pointing into the same data in classic hash-map

5:34 julianleviston: wagjo: I don’t follow, sorry… what’s classic hash-map ?

5:34 ianhedoesit: ,{:a 5 :b 5}

5:34 clojurebot: {:b 5, :a 5}

5:34 julianleviston: ah so just how i’m doing it?

5:34 wagjo: ,(let [data :foo] {:a data :b data})

5:34 clojurebot: {:a :foo, :b :foo}

5:35 julianleviston: wagjo: https://www.refheap.com/97520 <— just what I’ve done, then… but would that work with (chan)s, too?

5:35 TEttinger: yeah, objects are references anyway

5:35 julianleviston: TEttinger: ah ok… I wasn’t 100% sure about that,… now I know that, that completely answers my question… :)

5:35 (inc TEttinger)

5:35 lazybot: ⇒ 43

5:35 julianleviston: (inc wagjo)

5:35 lazybot: ⇒ 2

5:35 TEttinger: (inc wagjo)

5:35 lazybot: ⇒ 3

5:36 wagjo: thanks, but I'm a bit lost what's the problem you are trying to solve

5:36 mnngfltg: dysfun, sounds great

5:37 dysfun, anything public already?

5:37 dysfun: mnngfltg: nothing yet, sadly. i've been debating how to handle it. i want any number of interesting properties

5:38 and then i got bogged down with the layer i'm going to sit on top

5:38 julianleviston: wagjo: In a go-loop, I’m accumulating a map of debounce chans that pass messages off to a worker chan, and they also have an expiration timestamp on them… so I’d like to be able to look them up via timestamp, or via “id” (internal representation)… in the accumulation/message passing part, it needs to look it up via ID, and in the expiry phase it needs to filter by timestamp and then dissoc them. :)

5:38 mnngfltg: dysfun, I've been having this conversation with myself as well

5:38 dysfun: mnngfltg: we should collaborate

5:38 mnngfltg: totally

5:39 dysfun: i'll query you in a few once i've done the next item on my todo list

5:39 mnngfltg: cool

5:39 julianleviston: wagjo: if I needed to update the value of these keys, this solution wouldn’t work very well, but luckily I don’t, so it should be ok. Messy as it is.

5:40 TEttinger: ,(let [atm (atom 100) colll {:a atm b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) (:b coll)))

5:40 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0:0)>

5:40 TEttinger: ,(let [atm (atom 100) colll {:a atm :b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll)))

5:40 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: coll in this context, compiling:(NO_SOURCE_PATH:0:0)>

5:40 TEttinger: ,(let [atm (atom 100) coll {:a atm :b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll)))

5:40 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.concurrent.Future>

5:40 TEttinger: wat

5:40 ,(let [atm (atom 100) coll {:a atm :b atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll)))

5:40 clojurebot: 5

5:40 julianleviston: :atm

5:40 yeah :)

5:40 TEttinger: there you go

5:40 I'm getting sleepy

5:40 you see it's the same atom, referenced by a and b

5:41 CookedGryphon: Hey, I'm trying to redef async/timeout to a mock timeout provider that I have control of in my tests

5:41 julianleviston: TEttinger: if you’re talking to me, yeah, I get it. I just think it’s a messy way to do it.

5:41 CookedGryphon: but my redeffed function isn't getting used

5:41 julianleviston: TEttinger: it’s fine for what I want to do tho...

5:41 TEttinger: oh sorry yes, julianleviston. I'm getting quite sleepy and I hope that helped

5:42 julianleviston: TEttinger: thanks! :)

5:42 TEttinger: time for another attempt to get more than 3 hours sleep

5:43 CookedGryphon: does with-redefs work with async/timeout, or not because of something with the go macro?

5:46 wagjo: julianleviston: how do you plan to lookup data by the timestamp anyway

5:48 julianleviston: model your incoming messages as {:id "1d43e98a", :expiration 14563213, :payload {...}}

5:48 julianleviston: wagjo: yeah, that was my plan.

5:48 wagjo: julianleviston: that way you can easily filter by timestamp any message you've selected in the previous step...

5:49 julianleviston: wagjo: that’s what I’m doing.

5:55 wagjo: the main thing I was wondering was whether there was a data structure I wasn’t aware of in some library such as contrib because my googling turned up nothing other than multimaps… but it seems not… all good :)

5:56 sveri: Hi, I remember there was a caching / memoization library that emptied the cache after a given time. But I don't recall the name, anyone knows what I mean?

5:56 julianleviston: sveri: core.cached

5:56 CookedGryphon: Could someone take a look at my attempt to mock core async timeouts for testing and let me know what's going wrong: https://gist.github.com/AdamClements/33ef8d6ac9a65e9361ae

5:57 julianleviston: sveri: sorry cache… not cached. https://github.com/clojure/core.cache

5:58 CookedGryphon: core.cache is caching primitives, core.memoize uses core.cache to memoize functions

5:58 sveri: julianleviston: Hm, I think it was a different one

5:59 ah, it was core.memoize with the ttl function

5:59 CookedGryphon: julianleviston thank you both

6:07 mnngfltg: This puts the `:end` at the beginning rather than the end: (conj (take 5 (range 10)) :end) -- what's the idiomatic way to fix this?

6:07 There doesn't seem to be a `takev`...

6:08 hyPiRion: mnngfltg: if you can afford to retain some semantic garbage, then (conj (subvec (vec (range 10)) 0 5) :end)

6:08 which should be equal to this

6:08 ,(-> (range 10) vec (subvec 0 5) (conj :end))

6:08 clojurebot: [0 1 2 3 4 ...]

6:09 hyPiRion: ,(-> (range 10) vec (subvec 0 4) (conj :end))

6:09 clojurebot: [0 1 2 3 :end]

6:09 mnngfltg: ah so a solution would be replacing take w/ subvec (and use mapv before instead of map I guess)

6:11 hyPiRion, it is a significant amount of semantic garbage though

6:15 CookedGryphon: no core.async experts around today?

6:17 AeroNotix: give CookedGryphon ask

6:17 ,ask

6:17 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ask in this context, compiling:(NO_SOURCE_PATH:0:0)>

6:17 AeroNotix: ~ask

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

6:17 AeroNotix: CookedGryphon: ^^

6:17 CookedGryphon: AeroNotix: I already asked, see a few lines back

6:18 Could someone take a look at my attempt to mock core async timeouts for testing and let me know what's going wrong:

6:18 https://gist.github.com/AdamClements/33ef8d6ac9a65e9361ae

6:42 ah, I think I know what's going wrong. With-redefs is putting the var back before it's even been called because the go loop returns immediately and we fall out of the end of the redef scope

6:44 lvh: Just reading your blog post on the fn type of timeout, I'm curious, did you finish your clock implementation? It sounds like you were trying to do exactly what I'm trying to do now

6:45 kaplan_: Hi, can anyone explain Refs to me?

6:54 mnngfltg: What do you think of this general `constrain` function usable for, say, adding ellipses to a truncated seq? https://gist.github.com/pesterhazy/af12a5f85355f5c80358

7:00 wagjo: mnngfltg: straightforward but not very efficient

8:15 sameerynho: what is the pattern in libraries for getting global values for example api key

8:17 mnngfltg: wagjo, consise but truthful

8:27 Glenjamin: sameerynho: generally they should be passed as the first argument to api calls

8:28 sameerynho: Glenjamin: thanks

8:28 Glenjamin: (let [config {:api-key "ASDASDASD"}] (api/call config and other arguments))

8:30 ordnungswidrig: glenjamin: if you want to enable threading then you might want the config on second position.

8:31 sameerynho: I think another typical case is to bind a dynamic variable and to provide a `with-foo` macro.

8:31 Glenjamin: i'd say if you want to do a dynamic var, have that as an api which wraps a first-arg internal version

8:31 sameerynho: thanks

8:32 Glenjamin: i know the clojurewerkz projects are going down the first-arg route: http://clojureelasticsearch.info/articles/getting_started.html#querying

8:33 ordnungswidrig: Glenjamin: it depend on whether you'll need to pass the argument around a lot.

8:33 Glenjamin: but on the library-level I'd go with explicity args

8:33 Glenjamin: yeah, can always wrap that in other API styles

9:02 pandeiro: anyone using httpkit w/ websockets noticed that the on-close handler isn't called when a browser window refreshes (expected behavior would be to close socket connection and then re-establish)?

9:05 ordnungswidrig: every browser?

9:08 pandeiro: ordnungswidrig: no, just chrome yeah

9:08 found this: http://code.google.com/p/chromium/issues/detail?id=51687&q=websocket&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary

9:08 ordnungswidrig: pandeiro: I wonder whether this could be a feature. Is the websocket kept alive?

9:08 pandeiro: so it's chromium

9:09 ordnungswidrig: yes it appears to be

9:09 from that bug report seems only firefox implements the expected behavior

9:09 ordnungswidrig: pandeiro: which is unfortunate in the case of browser shutdown. you will either lower some timeout or fight the idling sockets on the server.

9:10 pandeiro: ordnungswidrig: yeah it means i have to do more bookkeeping

9:10 ordnungswidrig: even browser refresh presents a problem, i have duplicate entries for the same client id

9:11 ordnungswidrig: pandeiro: can you drop the old one? Except when you want to support mutliple windows from one browser, then this will fail

9:11 pandeiro: ...and using core.async channels to broadcast events i get errors about exceeding the number of put!s b/c of these 'ghost' connections

9:12 ordnungswidrig: yeah it's just a question of looking for the client-id each time a connection is established

9:12 and probably implementing some sort of a timeout

9:12 which i don't want to do (maybe the browser is just idle)

9:13 ordnungswidrig: pandeiro: that opens a can of worms, you'd need to make the browser send keep alive requests etc.

9:14 justin_smith: this stuff will all change with http/2 right?

9:15 pandeiro: justin_smith: no idea, will it?

9:16 i wonder if sente has any logic to clear this up...

9:16 ordnungswidrig: not sure, http/2 changes are mostly on the "transbport" layer. instead of opening multiple tpc connections it will multiplex over a single connection.

9:16 which allows the server to send out-out-band responses to prefetch resources.

9:17 I guess websockets will be multiplexed over that connection too and should behave like now

9:23 julianleviston: Hooray! My debouncing core async chan is working really nicely! :)

9:37 AeroNotix: ordnungswidrig: problem with "just drop the old one" is multiple services

9:38 we are solving a similar problem in Erlang, and erlang has built in tools for stuff like this. I wonder what Clojure has.

9:39 The safest bet is to use Zookeeper or something to manage the connection registration

9:42 ordnungswidrig: areonotix: not sure but zookeeper might be to slow.

9:42 AeroNotix: I said "safest" not fastest

9:42 It really depends what you're after

9:43 with our erlang solution we use pg2 (built in Erlang distributed process registry, it's AP)

9:43 ordnungswidrig: AP?

9:43 AeroNotix: as in CAP

9:44 favouring availability and partition tolerance

9:44 instead of consistency

9:44 with pg2 after a netsplit, for example, the registry on different nodes is different.

9:44 but it works for us, we have 7k registrations some times and the 95th percentile is 800ms on EC2 with 4 nodes.

9:45 a registration needs to do an erlang message to each node

9:45 ordnungswidrig: I'd love to see what there is in the Clojure space for this.

9:45 7k in the space of 1s I mean

9:46 Akka probably has something like this right?

9:46 I didn't look into it much

9:46 julianleviston: AeroNotix: wow

9:46 AeroNotix: julianleviston: yeah we handle a lot of websocket connections

9:46 we use Erlang though

9:47 it's great for this

9:47 julianleviston: AeroNotix: yeah, that’s it’s perfect use case

9:47 AeroNotix: indeed

9:47 I'd really love to use Clojure simply because I hate Erlang otherwise :)

9:47 julianleviston: AeroNotix: there’s not really a dist soln for clojure yet is there...

9:47 AeroNotix: yeah, it’s a bit GUHHHHHH to code in, isn’t it

9:47 AeroNotix: I don't know if there's something specifically for Clojure, but I'm sure you could use Akka

9:48 ordnungswidrig: AeroNotix: I think akka is what is used most likely. maybe hazelcast can be used

9:48 AeroNotix: ordnungswidrig: this could work

9:48 what are the failure semantics?

9:49 julianleviston: AeroNotix: http://joxa.org ?

9:49 hehe ;-)

9:49 AeroNotix: it doesn't mention on the front page whether it's CP or AP

9:49 julianleviston: it's fine, LFE is more popular. But none of them are anything like Clojure.

9:49 julianleviston: AeroNotix: yeah fair enough :)

9:50 mbac: zookeeper seems to have fared well in the call me maybe series

9:50 AeroNotix: mbac: indeed!

9:50 but it's throughput might be quite bad

9:50 I don't see you being able to add/remove keys to ZK in the way we want to for example

9:51 mbac: maybe if you could federate the zookeeper namespaces across sub-zookeepers? :)

9:51 AeroNotix: e.g. 7k add/removes a second

9:51 mbac: that's one scaling strategy...

9:51 AeroNotix: mbac: so you mean sharding an already distributed kv store :)

9:51 julianleviston: AeroNotix: Last I heard Rich was still saying distributed computing was “an area of interest” I wonder if he’s hammock’d up anything amazing yet? :)

9:51 AeroNotix: julianleviston: I would *love* to see what Rich comes up with

9:51 mbac: AeroNotix: i don't think i mean sharding

9:52 AeroNotix: mbac: you mean having different namespaces on different ZK clusters?

9:52 ordnungswidrig: Is zookeeper AP or CP?

9:52 julianleviston: AeroNotix: I really liked that pretty much the first thing you build in the book on erlang that joe armstrong wrote was a distributed bouncing ball… lol

9:52 ordnungswidrig: or can you configurE?

9:52 AeroNotix: ordnungswidrig: massively CP

9:52 mbac: i think i mean that you can decide some sections of the zookeeper namespace are delegated to other zookeepers

9:52 sort of like dns

9:52 that is, it would be nice if this existed

9:52 AeroNotix: julianleviston: ignore Joe Armstrong as much as possible

9:52 mbac: i have no idea if it does

9:53 AeroNotix: he's an out of touch fool that spouts cliches and memes over and over.

9:53 julianleviston: AeroNotix: really? haha what in preference? and why? :)

9:53 AeroNotix: ah… ok lol.

9:53 AeroNotix: I've spoken to him a few times, he really has no clue about modern Erlang development at all.

9:53 mbac: ordnungswidrig: according to this https://aphyr.com/posts/291-call-me-maybe-zookeeper it's CP

9:53 julianleviston: oh Akka has clojure bindings

9:54 AeroNotix: mbac: ordnungswidrig definitely CP.

9:54 ordnungswidrig: for websocket registration, could you use something like cassandra? would that make sense?

9:54 AeroNotix: ordnungswidrig: AP, massive row mutation, imagine the tombstones/compaction on that.

9:55 worth a try but the operational overhead might be massive

9:55 ordnungswidrig: hmm, maybe in a memory only mode :-)

9:55 AeroNotix: as a SPOF?

9:55 julianleviston: oh not really actually.

9:56 AeroNotix: ordnungswidrig: check out pg2 in erlang

9:56 this is a really good way of doing it

9:56 it's in-memory, pretty scalable

9:56 but it *is* AP. But it gives you tools to merge similar keys together.

9:57 cemerick: AeroNotix: cool story re: Joe Armstrong o.0

9:57 ordnungswidrig: good to know. I actually do not have any needs for such tool right now.

9:57 AeroNotix: cemerick: Did you ever use Rebar?

9:57 the Erlang build tool

9:57 * ordnungswidrig is still waiting for a decent implementation of RAFT in clojure to abuse it as a event store

9:58 cemerick: AeroNotix: I have.

9:58 julianleviston: have any of you used avout?

9:58 AeroNotix: cemerick: I spoke to him about repeatable builds and the like. He was aware of rebar and said it was fine and I quote "dependencies are easy"

9:59 julianleviston: I’m only curious.

9:59 AeroNotix: julianleviston: oh yeah I tried that

9:59 so cool

9:59 the idea is really neat

10:00 it Just Werkz

10:00 julianleviston: AeroNotix: reminds me of some kind of precursor to datomic a lot…

10:01 cemerick: AeroNotix: Okay. Going to have a hard time bootstrapping that into "Joe Armstrong is a clueless fool".

10:01 AeroNotix: cemerick: clueless about modern Erlang development. There's a lot more to it than that though.

10:02 gfredericks: what? dependencies are easy? hasn't he heard that they're hard?

10:02 AeroNotix: gfredericks: go use rebar in prod for a while. You'll see what I mean. It's horrifi

10:02 horrific

10:03 cemerick: so bizarre

10:03 AeroNotix: a lot of the people you see swooning over Erlang are just using it for trivial projects.

10:04 I've met most of those people who go to all the Erlang/Erlang solution gigs

10:04 literally all of them are just making shit up

10:04 it's full of posers et al.

10:04 cemerick: Bjarne Stroustrup is an idiot for not saving us from semicolons

10:04 AeroNotix: Excuse me though, I'm a little burned out on it.

10:04 julianleviston: LOL

10:04 cemerick: Guy Steele is dumb for having helped make Java

10:05 julianleviston: cemerick: multiple inheritance!

10:05 cemerick: dunno, I'll stop now :-P

10:05 julianleviston: cemerick: you protest too much ;-)

10:05 mavbozo: AeroNotix: let's hear more about it in #clojure-offtopic

10:05 AeroNotix: cemerick: Joe claims to have invented Erlang but he invented JAM which is not BEAM and was vastly different.

10:07 cemerick: AeroNotix: I don't really have anything to add. The whole thread is absurd.

10:07 Sorry for the noise, everyone :-)

10:07 AeroNotix: yeah^ sorry

10:08 mavbozo: we need a place to vent our frustation

10:12 ordnungswidrig: cemerick, AeroNotix: it's interestung noise

10:16 mavbozo: AeroNotix: thanks for sharing

10:16 (inc AeroNotix)

10:16 lazybot: ⇒ 8

10:59 daniel__: clojure.core seems to crash my browser: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj

10:59 or rather github

11:01 locks: I'm trying to do something like http://stackoverflow.com/questions/10634417/image-resize-to-fit-on-jpanel but I'm getting an empty pane, my code (I'm using seesaw):

11:01 https://www.irccloud.com/pastebin/z5hVQvO8

11:02 chrstphrhrt: anyone know which of the clojure repl options is most like bpython? don’t need fancy graphical notebook or editor integration, just a solid standalone repl

11:03 locks: the backtrace is so big LightTable isn't displaying all of it

11:17 mnngfltg: chrstphrhrt, bare `lein repl` should get you most of the way there; for colored output, https://github.com/venantius/ultra

11:18 what exactly are you looking for?

11:18 chrstphrhrt: mnngfltg: ooh purdy, thanks!

11:18 mnngfltg: looks like REPLy is nice too

11:19 mnngfltg: would like completion to help learning.. but prefer in terminal rather than editor

11:30 mmitchell: justin_smith: hey sorry to bother again. Re. cider and nrepl... I just can't seem to get "lein ring server" + repl options to work with cider-nrepl. No matter what I do, I get the "wrong version" warning in Emacs. The only way I can get it to work is through "lein repl". This seems to indicate the problem is in the "lein-ring" plugin?

11:30 which is all handled here - https://github.com/weavejester/lein-ring/blob/e0bee845db33e18c020a27fb069bf16a07dcf11c/src/leiningen/ring/server.clj#L54

11:31 justin_smith: mmitchell: that code makes me think that by adding cider-nrepl to the :nrepl-middleware key in your project you could fix that

11:32 mmitchell: oh snap, i didn't even see that

11:40 mnngfltg: chrstphrhrt, I agree, using the repl from the console is easier a lot of times than one integrated in the editor

11:40 chrstphrhrt, REPL-y is actually the repl you see when you run `lein repl`

11:41 chrstphrhrt: mnngfltg: oh ha didn’t realise that

11:44 __tim_: hi how do you detect a dependency issue with lein deps when using it with a CI server? The return code seems to be the same regardless or any dependency errors, or i'm using it wrong. I've enabled :pedantic true in my project. and running lein deps.

11:47 ordnungswidrig: __tim_: if the return code is the same then you might be able to grep for a keyword in the output

12:04 mmitchell: lein-ring :nrepl-middleware for cider support doesn't seem to help at all :(

12:10 oh wait, latest version of lein-ring doesn't support those options, they're only in master

12:58 clintm: Do any of you happen to know if we will eventually see support for read macros in clojure?

12:59 dnolen: clintm: it will not happen

13:00 clintm: Ok, thanks!

13:34 bja: having spent some time in a CL codebase recently, I'm glad I won't see full read macros in clojure anytime soon

14:11 moquist: dnolen: Wouldn't om/IRender be preferable for professor-view in https://github.com/omcljs/om/wiki/Basic-Tutorial, since professor-view has no state of its own?

14:13 dnolen: NM... somehow got the history of my own tutorial code confused. The tutorial doesn't use om/IRenderState like I firmly had in my head that it did.

14:14 dnolen: Figured it out. Same comment, but for registry-view. :) Isn't om/IRender more appropriate than om/IRenderState ?

14:19 daniel``: looking for the clojure or java equivalent of random.SystemRandom().getrandbits(n)

14:19 in python

14:19 AeroNotix: daniel``: https://github.com/weavejester/crypto-random

14:20 relevant java classes are java.security.SecureRandom

14:21 daniel``: SecureRandom :)

14:21 i was looking at Random

14:22 is more or less the same, i need a way to convert a byte-array to a long

14:22 justin_smith: ,(let [rnd (java.util.SecureRandom.)] (.next rnd 8))

14:22 AeroNotix: doesn't it have .getLong ?

14:22 clojurebot: #<CompilerException java.lang.ClassNotFoundException: java.util.SecureRandom, compiling:(NO_SOURCE_PATH:0:0)>

14:23 justin_smith: ,(let [rnd (java.security.SecureRandom.)] (.next rnd 8))

14:23 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: next for class java.security.SecureRandom>

14:23 justin_smith: hrmph

14:23 daniel``: justin_smith: i think .next is protected and i can't call it

14:23 justin_smith: well that's dum

14:24 daniel``: AeroNotix: don't think so, it has nextLong but then i can't specify the byte length

14:24 justin_smith: daniel``: nextBytes

14:24 tell it how many bytes you want, turn them into whatever you need

14:25 you probably wanted a multiple of 8 anyway

14:25 AeroNotix: daniel``: what do you need the random for/

14:25 ?

14:25 daniel``: trying to implement an SRP login system

14:26 its for a salt

14:26 http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol im copying this python implementation

14:26 AeroNotix: I'm just using (random/bytes 20)

14:26 from crypto.random

14:27 the _first_ thing I linked you to

14:27 20 is the number of bytes, obv

14:28 justin_smith: AeroNotix: a whole lib seems a bit much for what could be two interop calls

14:28 AeroNotix: justin_smith: it's a whole lib which does the interop calls :)

14:29 justin_smith: AeroNotix: that fit in a clojurebot one-liner

14:29 AeroNotix: and I don't understand that argument either. We have great tooling for managing dependencies in Clojure, use them!

14:29 daniel``: AeroNotix: yep, thats similar to my implementation

14:29 trouble is the python version returns a long not a byte array

14:29 AeroNotix: justin_smith: right, but there's no reason (especially with crypto code?) to do it over and over again

14:29 justin_smith: AeroNotix: using the class directly is not reinventing the wheel in any sensible definition of the term

14:29 AeroNotix: daniel``: byte-array => ByteBuffer => getLong?

14:30 daniel``: and crypt-random is a good reference though

14:30 AeroNotix: thanks for the tip, ill try

14:30 amalloy: i think that either using this lib or doing interop directly are both perfectly reasonable approaches, i don't know why you guys are arguing about it

14:30 AeroNotix: amalloy: shrug

14:30 daniel``: amalloy: :)

14:30 dnolen: moquist: perhaps, the wiki is user modifiable, I'm always happy to see enhancements

14:31 AeroNotix: no arguments just different approaches and asserting they are the preferred way.

14:31 daniel``: its useful for me to see the interop because i have no java background

14:31 and like to know whats going on

14:32 moquist: dnolen: Cool. I'll do that.

14:33 AeroNotix: user> (.getLong (ByteBuffer/wrap (random/bytes 200)))

14:33 ;; => 7805789527915639494

14:33 daniel``: ^^

14:34 daniel``: yep, thanks AeroNotix, just got to the same

14:34 AeroNotix: obv you only need 8 bytes

14:34 daniel``: yeah

14:35 justin_smith: you can use bit-and to ensure you don't get more bits that wanted (if it wasn't a multiple of 8)

14:37 daniel``: it uses 1 or 0 for the remaining bits?

14:38 justin_smith: daniel``: it would be for ensuring bits you don't want are zeroed out (but keeping the sign bit intact)

14:38 if you want a value with a specific non-multiple-of-8 bits

14:39 daniel``: right

14:39 Error detected while processing function <SNR>64_printop..<SNR>64_opfunc: weird error i get trying to evaluate the long

14:39 its ok if i call it with (prn s)

14:40 think this is a fireplace thing

14:40 can't evaluate a value outside parens

14:40 AeroNotix: primitive ;)

14:46 daniel``: this is where i got to https://gist.github.com/danielstockton/40dd5a9c3bdde35244ea

14:47 can't parse the string digest in the one way hash function to an integer either

14:48 python has hexdigest that MessageDigest doesnt

14:51 socksy: is datomic the only existing database[-style-project] that supports the clojure philsophy of immutability/persistent data structures, or are there some others out there?

14:52 lvh: Hm. I have a data structure, only passed at runtime, that looks like [{:a :a} {:b :b} {:c :c}]. I want to transform that into (l/run* [q] (conde [(l/featurec req {:a :a})] [(l/featurec req {:b :b})] [(l/featurec req {:c :c})]). The obvious choice for that kind of rewriting seems to be macros, but I can't do that, because runtime (unless I'm supposed to call macroexpand or something).

14:53 Just apply won't work; l/run is itself a macro.

14:54 amalloy: i think you can easily enough write a version of conde that takes a list of goals

14:58 (defn conds [goals] (if (empty? goals) (fail nil) (conde [(first goals)] [(conds (rest goals))]))) or something like that

14:59 hiredman: isn't there already one?

15:00 amalloy: hiredman: probably

15:00 hiredman: everyo or something?

15:00 lvh: hiredman: Isn't everyo conjunction?

15:00 gfredericks: you can write a recursive function too I thinks

15:00 amalloy: gfredericks: that's what i did

15:00 gfredericks: that's what amalloy just did

15:01 lvh: conde is [[a AND b AND c] OR [d AND e AND f]]

15:01 amalloy: i mean, who knows if it works

15:03 AeroNotix: daniel``: do you have the python code you're emulating?

15:03 daniel``: yeah http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

15:03 made a tiny bit more progress on the gist

15:07 hmm it actually works, what i have in the gist

15:07 lvh: amalloy: Thanks!

15:07 daniel``: im having trouble with reevaluating my file due to my primitive setup

15:07 amalloy: lvh: does it actually work?

15:07 lvh: amalloy: I removed the inner []s since I still want to be able to specify the conjunctions

15:07 amalloy: Yeah, looks like it :)

15:08 amalloy: great

15:08 daniel``: hmm no, sometimes it gives a NumberFormatException Infinite or NaN

15:08 lvh: wait, maybe not

15:09 amalloy: What's (l/fail nil)? I thought you were just supposed to use l/fail to get a failing goal?

15:09 amalloy: lvh: yeah, it's a failing goal. if there are no goals left in the conds, you need to fail, right?

15:10 lvh: amalloy: OK, cool, as long as it's the same as l/fail I know what it means :)

15:10 amalloy: lvh: i don't really know; i just wanted a failure for my base case, and found l/fail. it probably does what i mean. haven't touched core.logic for at least a year

15:10 lvh: amalloy: Okay, cool :) Thanks!

15:15 amalloy: I can't get the version without []s to work, though: https://gist.github.com/lvh/353d5a5c057a758b7858

15:15 not the bestest error message :(

15:15 amalloy: that is not how brackets or core.logic work

15:16 in (conde [a b c]), the value [a b c] never exists at runtime: it's just a grouping mechanism for core.logic's macroexpander to use

15:16 creating your own vector and passing it in will never work; you need to use like (l/all a b c)

15:24 AeroNotix: When I am trying to generate a class is it not possible to keep re-evaluating the gen-class ns and have the changes reflected?

15:24 because it seems that this is the case.

15:25 i.e. I add / change the :constructors key, and the changes aren't reflected.

15:25 amalloy: dnolen: a lot of stuff in core.logic is macros that doesn't seem to need to be. like, why is l/all a macro? it expands into bind*, which expands into bind, which is just a function with no funny business

15:25 AeroNotix: amalloy: I've had similar thoughts when looking at core.logic

15:25 dnolen: amalloy: dunno, some things are vestiges of history or things brought over from miniKanren

15:25 amalloy: so it seems to me like bind* could be a function, which would make l/all a function, and then you could just write (apply l/all goals)

15:25 AeroNotix: there's a few places that could seemingly be replaced by functions

15:26 amalloy: dnolen: would you take a pull request that changed bind* and all to functions?

15:26 ul: hi! anybody encountered such error in repl?

15:26 clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: vfsm.core.Automaton cannot be cast to compile__stub.vfsm.core.Automaton

15:26 what is compile__stub?

15:26 amalloy: oh, core.logic is a contrib, so i guess it'd be a jira ticket

15:27 dnolen: amalloy: I don't like changing old stuff

15:27 amalloy: but I'm happy to see the desirable behavior provided by some other route

15:27 ul: it happens if i try to call function from vfsm.core namespace

15:28 amalloy: dnolen: you mean something like all* that's a function version of all?

15:28 AeroNotix: dnolen: would the observable behaviour change all that much?

15:28 dnolen: amalloy: yeah, that's preserved

15:28 amalloy: AeroNotix: well no, not at all, which is the point

15:28 dnolen: s/preserved/preferred

15:28 AeroNotix: amalloy: that's why I don't get the fuss about changing it.

15:28 dnolen: amalloy: I'm happy to assess the change if you do a bit more legwork wrt to verifying it doesn't actually change anything (perf etc.)

15:30 amalloy: AeroNotix: nobody wants to fiddle with the foundations of their work on a lark. even if it seems like it would obviously be an improvement, it's dangerous

15:31 AeroNotix: amalloy: isn't this why we have test suites and beta/rc releases?

15:32 do I really need to restart the vm when I change gen-class definitions?

15:32 amalloy: AeroNotix: when you have a project as large and widely used as core.logic, you can make a policy of accepting any pull request that doesn't break the tests. but since core.logic is dnolen's, i'm happy to live with his policies

15:32 AeroNotix: amalloy: ok

15:33 dnolen: AeroNotix: core.logic is just really old now, I'm not quite so cautious with other projects that I maintain

15:33 AeroNotix: dnolen: rog

15:33 amalloy: dnolen: i don't really want to do a ton of legwork, since i don't even use core.logic; i just noticed this issue while answering someone's question in here. but i can put together and*, a function version of all, and or*, a function version of conde. or do you prefer some other name?

15:34 vas: So I want to chain transformations together in enlive using ( enlive/do-> ) ... but i'm not sure how it works. do I need to supply the nodes it operates on to each transform, or are all transforms applied to the same node set?

15:35 dnolen: amalloy: we do have a simple convention around goal functions, just tack a g onto it. but that's kind of ugly. maybe a new goals namespace?

15:35 amalloy: "condeg"?

15:35 dnolen: amalloy: but also happy to take a patch, think on it, and refactor it if I get a better idea

15:35 ul: is it legitimate to e.g. extend-type clojure.lang.PersistentArraMap with own protocol?

15:35 AeroNotix: condegg

15:35 amalloy: okay

15:35 AeroNotix: hehe

15:35 dnolen: er apply it, and refactor it

15:35 amalloy: right

15:36 ul: figured out that mentioned above compiler exception happens after i did such extension

15:36 amalloy: ul: yes, if it's your own protocol or your own type it's fine

15:36 extending someone else's protocol to someone else's type is the dangerous thing

15:36 ul: it is my protocol, but clojure.lang... type

15:37 and it leads to compiler error =(

15:37 AeroNotix: ul: can you show some code friend?

15:37 what's triggering that?

15:37 ul: yes, wait a second

15:37 AeroNotix: just looks like you're passing something to some java joint that it doesn't like, though

15:38 do I really need to restart the vm when I change gen-class definitions?

15:38 justin_smith: ^?

15:38 ul: https://gist.github.com/ul/a8d61b4372a4e04484e4

15:38 this is vfsm.core

15:38 if i paste its content directly to repl

15:38 or require — it loads fine

15:39 amalloy: AeroNotix: probably yeah

15:39 AeroNotix: amalloy: sadness

15:39 amalloy: gen-class is heavy stuff

15:39 ul: but calling any function involving my protocols produces exception

15:39 AeroNotix: understandable though

15:55 amalloy: dnolen: https://www.refheap.com/0383ff71c2b0ad526bd7f9b66 is the outline. anything you want changed before i make a proper patch?

15:56 dnolen: amalloy: looks good, a few simple example tests would be nice

15:59 amalloy: dnolen: good idea. actually i'll just take a couple example tests from conde, and assert that or*/and* get identical results

15:59 dnolen: amalloy: nice

16:00 amalloy: you might want to try some of the trickier ones

16:00 TimMc: something something generative tests for equivalence

16:00 That would be a fun challenge.

16:00 amalloy: TimMc: well that's the joke, you can't actually do it

16:00 because the existing features are macros

16:00 you can't really generate calls to them without eval

16:00 TimMc: Nonsense, there's eval.

16:00 yeah

16:01 amalloy: and tbh the last thing i want to use eval on is randomly generated code

16:01 dnolen: ugh

16:01 TimMc: What's the point of this fancy-ass language if we don't ever use eval?

16:01 dnolen: GitHub syntax highlighting is so bad now

16:01 locks up in every browser

16:02 amalloy: anyways, the divergence tests would be interesting

16:02 AeroNotix: would be cool if they just had a profile option to turn it off

16:02 dnolen: amalloy: search for "divergence" in tests.clj

16:03 amalloy: dnolen: (def f1 (fresh [] f1))? you're a maniac

16:04 dnolen: amalloy: ha, that's Will's tests actually

16:05 locks: dnolen: that's quite the big file dnolen :P

16:05 dnolen: locks: for some definition of "big"

16:05 last time I checked the year it was 2015

16:07 amalloy: dnolen: hrm, conde does interleaving? my version probably doesn't

16:07 crack_user: someone knows what is wrong with this tiny code: https://gist.github.com/fariasvp/fae3d6ae4bf5ab083e15

16:07 amalloy: i wasn't sure if you'd made that the default

16:07 dnolen: amalloy: oh yeah, it is

16:07 amalloy: sorry for sending you down this direction, didn't realize you were still going off TRS ;)

16:09 crack_user: hello guys

16:10 some one can help with this error: https://gist.github.com/fariasvp/fae3d6ae4bf5ab083e15

16:10 amalloy: you can't name a function new

16:11 crack_user: thx

16:15 AeroNotix: it's weird that it *allows* you to make a function called new but then completely ignores you

16:15 {blake}: Is there any code lying around to turn a nested JSON into a flat-file or CSV?

16:16 TEttinger: {blake}, sounds like a recipe for disaster

16:16 {blake}: TEttinger: Heh. Why?

16:16 It could get very wide, I suppose. But...

16:17 TEttinger: I just think of CSV as having specific columns, and JSON could have any name for any field, so you would have many columns yeah

16:18 {blake}: Well, I guess no big deal to roll my own.

16:18 boblarrick: http://konklone.io/json/

16:19 also http://csvkit.readthedocs.org/en/latest/index.html

16:19 {blake}: ^

16:22 {blake}: boblarrick: Thanks. I guess I steal from here and convert to clojure. =P

16:23 boblarrick: if you really need to do in-process i guess, maybe just shell out?

16:25 {blake}: Honestly, I wouldn't want to deal with the bitching from devops. =P

16:32 nicferrier: how annoying that clojure is infected with java's private fallacy.

16:33 the-kenny: Only with interop. But it sucks, yeah :/

16:33 nicferrier: I am trying to find where http-kit/client converts { :a 1 :b 2 } to "B=2&A=1" (caps??) but it would be easier if I could get at the internals.

16:33 as it is, I'm having to read the code and try and guess :-(

16:36 the-kenny: nicferrier: that sounds very strange. Why would http-client do that?!

16:37 nicferrier: the-kenny: I presume defn- means "private" of some sort?

16:37 the-kenny: nicferrier: yes, but still accessible via fully-referenced var like #'my.ns/some-private-fn

16:38 nicferrier: hmmm. ok. can;t seem to reach it from the repl. must be my fault.

16:39 the-kenny: Accessing it via foo.bar/foo won't work, throwing something like var: foo.bar/foo is not public - accessing it via the var should work

16:39 nicferrier: via the var?

16:40 the-kenny: Via #'foo.bar/foo

16:40 it's a side channel here

16:40 nicferrier: ok. fair enough. thanks.

16:41 still a *bit* frustrating though. why do we need privates?

16:41 lmohseni: howdy

16:42 AeroNotix: nicferrier: otherwise you'd have silly naming conventions indicating what's private and what's note.

16:42 not*

16:42 nicferrier: with the way it is now, you can at least show the user of the code "hey this is not public"

16:42 but they can easily circumvent it

16:43 https://gist.github.com/AeroNotix/83a91d08b05ea694abbb

16:43 the-kenny: nicferrier: Distinction between public/private api for example. You don't want to make all utility-fns accessible in case you will remove that later. All such stuff

16:44 AeroNotix: It's *a* distinction that causes pause for thought when using it

16:44 amalloy: okay dnolen, you bastard, i replicated your interleaving for or* and now it behaves exactly like conde in the divergence test. do you need "simple" tests for it too, or is passing the divergence tests good enough?

16:44 nicferrier: the-kenny: yeah. but here you go, it's still accessible... so people could break it if they wanted.

16:44 the-kenny: That's their fault though. You marked it as non-public.

16:44 dnolen: amalloy: divergence tests are good

16:44 amalloy: (ps i guess that kinda sounds like i'm really mad, but i am just playing. the internet is hard sometimes)

16:44 AeroNotix: nicferrier: except someone clearly knows they shouldn't be doing that

16:44 the-kenny: Else you would get internal comments or silly naming conventions like AeroNotix said

16:45 (like in elisp :D)

16:45 dnolen: amalloy: haha, I read it as "I got nerd-sniped by dnolen"

16:45 AeroNotix: e.g. in Python or Emacs Lisp you have silly naming convenctions

16:45 {blake}: amalloy: I was waiting for you to say "DNOLEN YOU MAGNIFICENT BASTARD I READ YOUR BOOK!"

16:45 AeroNotix: dnolen: you have a book?

16:45 amalloy: does he have a book? i read TRS

16:45 {blake}: lol

16:45 xemdetia: "dnolen's fishing guide"

16:45 AeroNotix: oh that one

16:45 yeah that's a snoozefest

16:46 "Dnolen's guide to having rad hair" is much better

16:46 nicferrier: the-kenny: I just think it's silly. there was some xkcd a while ago about it I seem to recall. I think he was right.

16:46 AeroNotix: nicferrier: what's your alternative?

16:46 how do you convey "hey this is private, dragons"

16:46 TimMc: ^:dragons

16:47 AeroNotix: TimMc: perfect!

16:47 TimMc: Actually, I'm going to start using that, thanks.

16:47 the-kenny: I thought ^:private meant dragons

16:47 AeroNotix: except that's exactly what defn- does

16:47 defn- is ^:private

16:48 TimMc: I've seen ^:internal

16:48 {blake}: ^:infernal

16:48 AeroNotix: TimMc: does tooling/the language do anything with it though?

16:48 ^:private is clear, well understood, integrated into the language, and above-all -- Ignorable.

16:48 the-kenny: nicferrier: FWIW: I don't see the behavior in http-kit: @(org.httpkit.client/get "http://localhost:4035" {:query-params {:foo 233}}) works just like xpected

16:49 TimMc: AeroNotix: :private is annoying because it gets in the way of tests

16:49 AeroNotix: TimMc: explain

16:49 why are you testing private functions

16:49 TimMc: Because unit tests?

16:49 the-kenny: AeroNotix: I think that's fine. For granularity.

16:49 nicferrier: the-kenny: yeah. I just found the problem and it was me being stupid. and i wasted 10 minutes not finding my stupidity by having to arse around to prove that it wasn't http-kit.

16:49 the-kenny: TimMc: can't you just use the #'foo.bar/fun workaround?

16:49 AeroNotix: TimMc: you test private functions?

16:49 TimMc: Absolutely.

16:49 AeroNotix: Lol

16:50 test the interface

16:50 the-kenny: AeroNotix: I do that too from time to time.

16:50 xemdetia: if I am relying on it why wouldn't I test it

16:50 * crash_ep tests his code in production

16:50 the-kenny: If there's hairy logic or some widely-used utility-fn why not test its behavior?

16:50 TimMc: Just because they're not part of the interface doesn't mean you can't or shouldn't pin down behavior.

16:50 amalloy: dnolen: http://dev.clojure.org/jira/browse/LOGIC-167

16:50 dnolen: amalloy: thanks!

16:50 AeroNotix: you should be able to invoke this "hairy" code through regular testing of the interface

16:51 also, if your interface makes it hard to get good coverage, you dun f'd up.

16:51 nicferrier: in fact, that's the definition of a unit test. unit tests are supposed to test "business value" and not integration.

16:51 TimMc: AeroNotix: Sometimes I test things that the interface does not *currently* expose but could later if the code is modified.

16:51 AeroNotix: TimMc: I just delete things the interface doesn't expose.

16:51 TimMc: That's your call.

16:52 but sometimes that is not possible

16:52 AeroNotix: TimMc: vcs makes it possible to time travel

16:52 TimMc: The private fn may be highly general and the public one restrictive. You can't "delete" the generality.

16:53 Anyway, you haven't demonstrated that there is harm in testing private fns.

16:53 xemdetia: I like bridges I built to be tested even if we only care about the cars that drive over it :(

16:53 AeroNotix: there's no harm, obviously. I'm just saying that it's code that should be easily invoked through normal interface testing and it's code that could be ephemeral in the face of changing requirements

16:54 TimMc: I do it because it can add robustness against future code changes that I haven't even imagined yet.

16:55 AeroNotix: my goal is to usually check the coverage report and see whether these helper/private functions have been invoked and ensure that I write tests to invoke those paths

16:55 "branch testing"

16:55 TimMc: AeroNotix: OK, but many of my tests of non-interface fns are also there because I test as I write and it helps flush out bugs faster. You think I should delete them afterwards?

16:55 AeroNotix: TimMc: I use a repl for that

16:56 but yeah, when I develop I have snippets of code that work with the internal stuff in the file, when I am doing messing with it, I'll paste it into a test file. If eventually I don't need it and I can invoke that code from just the interface, I'll delete it.

16:57 TimMc: Whatever floats your boat.

16:57 AeroNotix: This is why people end up with test suites which take hours to run

16:57 because they're testing irrelevant things, or things multiple times.

16:57 TimMc: Never had that problem.

16:57 AeroNotix: perhaps not hours

16:58 TimMc: If and when I have that problem I'll consider changing things.

16:58 xemdetia: I mean this is why you make your test suite configurable so you only run what tests are required and still have them around for a full final build

16:58 AeroNotix: xemdetia: sure, but you still need to do the full final build for CI.

16:59 in fact, I just run tests in the repl too by evaluating the test.

16:59 nicferrier: personally I do change based testing.

17:00 xemdetia: I don't mind CI builds taking a while, the point of CI is that nobody is having to watch the stove

17:00 AeroNotix: xemdetia: it's fine when you've got the infr or the cash to spunk on redundant CI servers

17:00 it's actually _really_ fun when you've got N-million CI servers

17:02 TimMc: you mean customers?

17:02 xemdetia: well I don't know, when something is taking too long I do the sensible thing of take measurements, make changes, measure for improvements like everyone else, even if my CI server is just a vm on my laptop building linux iso's

17:02 AeroNotix: haha

17:02 xemdetia: if I have to make tests more efficient because it doesn't fit my needs that is just as well a documented problem as code optimization

17:02 that doesn't mean I should just purge it

17:02 at least to me

17:06 TEttinger: Open Build Service from OpenSUSE is pretty nice for linux builds

17:07 not CI I guess

17:07 AeroNotix: travis is sweet

17:12 justin_smith: TEttinger: does suse stop being super weird? because as a long time debian user I jumped into it recently and it was a major culture shock

17:12 TEttinger: justin_smith: I use windows, I stopped fiddling with linux a few years ago tbh

17:12 justin_smith: OK

17:13 TEttinger: I still have some VMs I occasionally use for FontForge

17:13 one is basically only used to build GNU Unifont

17:15 sveri: Hi, I have a string containing some html code. Using selmer I want to get the content from the string and just use that as plain html in the template. {{some.content|safe}} keeps the content from being escaped, but it still is inside a string. How can I do that?

17:15 TEttinger: http://www.unifoundry.com/unicode-utilities.html this stuff is highly linux-specific, but I used clojure to bit-twiddle each line of hex digits (after parsing) into different shapes to make 8x16 glyphs into 16x16 glyphs or 16x16 glyphs into garbage 8x16 ones

Logging service provided by n01se.net