#clojure log - Jul 22 2014

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

1:25 andyf: bbloom: I gave you the wrong impression of my true thoughts on Clojure JIRA tickets earlier today, when you mentioned that there were a dozen you may have filed. Closer would be: You miss 100% of the shots you don't take.

1:36 69% of all 1264 tickets for Clojure are closed, either completed (50.4%), declined (14.8%), or as a duplicate of another ticket (3.6%)

1:37 (end of public service announcement :-)

1:37 SagiCZ: good morning

1:43 bbloom: andyf: it's not about hitting shots, it's about activation energy

1:43 andyf: writing a good ticket takes a non-trivial amount of time and involves reasonable friction

1:45 andyf: just searching to see if i'm creating a duplicate is exceptionally frustraiting

1:45 the back button doesn't work

1:45 and if jira bombs out on me even once, i just don't feel like dealing with it

1:46 the entire thing is optimized for batch operations on behalf of maintainers, which is head and shoulders above github, that's for sure, but it just doesn't justify me spending 10s of minutes for something that ought to be 10s of seconds

1:47 especially when the issues are small and classified as "enhancements"

1:47 which are all but entirely ignored

1:47 andyf: I'm not lying about the 50% closed and completed, although I'll be the first to agree that it is anything but convenient.

1:48 bbloom: andyf: the thing is that i run in to issues CONSTANTLY

1:48 i splunk around pretty deep in the clojure codebase

1:48 more than half the stuff i find has already been found

1:48 is already reported

1:48 usually i mention it here, and somebody else says "we know"

1:48 and half the time there is an open ticket w/ patch

1:48 if i spent 10s of minutes every time i said "wtf?" i'd never get anything done

1:49 andyf: do you add your vote to them? That is dead quick.

1:49 bbloom: i don't b/c apparently i'm only allowed 5 useful votes or something like that

1:49 andyf: No, you can vote as often as you like

1:49 bbloom: and almost none of them block me

1:49 http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html

1:50 apparently each vote lowers the weight i give to prior votes

1:50 and i have voted on issues that i really would like to see fixed, but havent been

1:50 andyf: Alex Miller and others also look at unweighted vote counts, too, I've seen him mention.

1:51 bbloom: ok, well i'll vote more in the future then

1:51 thanks

1:51 ambrosebs: any stats on how effective votes are to getting a ticket closed?

1:51 bbloom: argh. like now i'm going to see if there's any top issues i'd like to add votes to

1:51 i can't figure out how to do that

1:52 andyf: no problem. I understand being frustrated with the pace. Just wanted to put some more positive comments in that quite often tickets do get fixed. Sometimes it helps if you only look once per release :)

1:52 bbloom: i'm not frustrated with the pace really

1:52 i experience PHYSICAL DISCOMFORT when i use JIRA

1:53 andyf: I've heard similar comments before. I can't recall it ever bothering me all that much, but tastes differ.

1:53 bbloom: i have like microsoft flashbacks

1:54 andyf: ambrosebs: I've not seen any such stats. I do know Alex Miller looks at the top voted tickets and takes some action to move them along when he can.

1:54 bbloom: product studio *cringe*

1:54 ambrosebs: andyf: might be a more interesting stat to encourage votes

1:55 bbloom: how do i see top voted issues?

1:55 andyf: There are links to top voted tickets here with links to JIRA where, if you are logged in (top right link), you can click the 'Vote' link: http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html

1:55 You can get to that page a couple of clicks away from clojure.org/cheatsheet, strangely enough, since I maintain both.

1:55 bbloom: jira has like 7395789353 reporting tools, right? why can't i get to that from jira?

1:56 i don't bookmark anything, ever. how do i find this again?

1:56 andyf: You can get to top unweighted votes in a JIRA report. It doesn't do weighted vote calculation that I am aware of -- that was custom.

1:56 clojure.org/cheatsheet

1:57 Click "Download other versions with tooltips". Look down that page for links to reports on JIRA tickets.

1:57 bbloom: lol, not gonna remember that :-P

1:57 andyf: Google is your bookmark list?

1:57 bbloom: yup

1:58 i declared bookmark bankruptcy years ago

1:58 andyf: clojure top voted tickets

1:59 bbloom: ok, thanks

2:00 andyf: ambrosebs: Sorry, just noticing your latest comment -- you mean publishing stats on average time from a ticket reaching X votes until Rich makes a decision whether it moves forward or not?

2:00 SagiCZ: would you recommend clojure for building automated fund

2:00 trading system

2:00 is it mature enough?

2:00 bbloom: yes

2:00 SagiCZ: i dont want to run into hidden language issues

2:00 i mean java has been around many years and i expect it to be quite reliable..

2:01 bbloom: SagiCZ: clojure is quite reliable. and when it isn't you can use java seamlessly from clojure

2:01 ambrosebs: andyf: something like that.

2:01 SagiCZ: bbloom: i know.. that sounds good

2:02 andyf: ambrosebs: I'll keep that in mind, for a rainy day of hacking, perhaps. But it doesn't rain very often where I live :)

2:03 ambrosebs: andyf: :)

2:04 andyf: ambrosebs: Bronsa asked earlier if you knew what arrdem was planning to do with your latest core.typed release. I am curious, too.

2:05 ambrosebs: andyf: arrdem wanted a quick way to collect all annotations from core.typed

2:05 I assume there's going to be some amazing hyperlinked thing in grimoire

2:05 andyf: ambrosebs: For additional documentation of functions, I'd guess. Sounds good.

2:05 ambrosebs: yes

2:06 andyf: Bronsa: ^^^

2:06 bbloom: andyf: how big is the impact of having a patch or not?

2:06 andyf: ie are patchless tickets more or less completely invisible?

2:07 andyf: The exact criteria isn't revealed to me, but from my observations over time it appears that Rich's Vetted/Declined decision depends more upon the description of the problem, impact, and how the behavior should be changed, than whether there is a patch.

2:08 Presence of a patch is obviously critical for getting a patch screened by a screener, and then later approved by Rich, but nothing gets screened unless Rich has Vetted the ticket first (well, almost nothing)

2:09 I've seen plenty of patchless tickets be Vetted.

2:10 bbloom: ok

2:10 andyf: I suppose that can be a good thing to know when creating a ticket, if you are trying to save time.

2:14 * bbloom votes on any ticket that increases variadicity of functions :-)

2:16 andyf: Rock the Clojure vote :)

2:38 SagiCZ: anybody uses Cursive editor for typing Clojure programs?

2:38 its a plugin for IntelliJ IDEA

2:45 ivan: SagiCZ: many

4:08 tuft: SagiCZ: i do

4:17 zanes: When the core.async docs say, “Use transformer instead” what, exactly, are they suggesting? Rolling my own with map or a go loop?

6:28 swi: Hello. If i run lein jar i get jar file, but java -jar on this file gives me Could not find or load main class one.core. With uberjar and lein run all is working. Did i miss some idea ? :)

6:32 augustl: swi: "lein jar" doesn't bundle dependencies, so it can't find one.core because it's not there :)

6:33 swi: augustl: em. one.core is my project file, so it' in jar afaiu. May be it' something with classpath ?

6:34 augustl: swi: I guess one.core requires stuff that isn't on the classpath

6:34 ?

6:38 swi: augustl: actualy it's file right after lein new app one :) http://paste.debian.net/110950/

6:41 augustl: swi: never really used "lein jar". Perhaps it can't find clojure itself or something ominous like that

6:41 not sure if lein jar bundles clojure

6:43 technomancy: yeah augustl is right; you shouldn't expect that to work with java -jar

6:43 swi: so the 'hello classpath-hell' ? :)

6:43 technomancy: no

6:43 just use an uberjar

6:44 swi: and if i dont want to pack all in one file (i.e. distribute to server side) ?

6:46 hyPiRion: Isn't that the exact reason why you'd want to pack all in one file? To ensure the servers run same code?

6:47 technomancy: I guess if you want to make things more complicated, it's still possible to self-inflict classpath hell on yoruself.

6:47 swi: :)

6:49 technomancy: remind me my story with 'all-in-one-exe-file written with pygtk :)

6:50 augustl: swi: you can do that, as long as all the deps are available in the classpath when it is loaded

6:51 swi: augustl: i see. i think i'll stick with uber- for now :)

6:51 or even with nrepl actualy

7:14 sm0ke: hello

7:15 how are you people profiling your code for performance hotspots?

7:16 i have a function call which i want to bring down from 800 microsec to 100 mircosecs. Where do i start?

7:16 vijaykiran: sm0ke: pasting your code - if you don't mind - helps

7:16 SagiCZ: you could use some hotspot tools

7:16 jvm console

7:17 hyPiRion: vijaykiran: I think sm0ke meant how you actually go forward and find the bottlenecks

7:17 sm0ke: yea the function is imaginary here

7:17 SagiCZ: or VisualVM

7:17 sm0ke: SagiCZ: i tried that

7:17 but nothing was there relevant to my code

7:17 SagiCZ: sm0ke really.. well thats a bummer

7:18 sm0ke: only clojure .invoke calls iirc

7:18 SagiCZ: isnt there some profiling library for clojure?

7:18 hyPiRion: SagiCZ: there's criterium, but that's for benchmarking only

7:18 vijaykiran: there's criterium or something

7:18 hyPiRion: ... I think

7:18 sm0ke: hyPiRion: I am using it for profiling

7:19 i wont tell you what code in the expression is taking so long

7:19 it*

7:19 SagiCZ: clojure is slow

7:19 sm0ke: just a fancy timer i would say

7:19 SagiCZ: no it is not

7:20 clojure is fast enough imo

7:20 SagiCZ: sm0ke: i have seen some benchmarks.. slower than java

7:20 sm0ke: yea ok

7:20 SagiCZ: sm0ke: but i am not sure about the methodology of the statistic

7:20 sm0ke: lets talk about my incompetence to write faster code not clojure's

7:20 SagiCZ: yeah sorry

7:21 so it is not a concrete function you are talking about? you mean profiling in general?

7:21 sm0ke: consider that clojure is assembly

7:21 yes

7:22 SagiCZ: it sucks it's not possible to use JVM analysis tools, because that would leave you with tons of options

7:22 hyPiRion: sm0ke: From what I know, people tend to use YourKit, JProfiler, or VisualVM. But I also think it's possible to use Timbre

7:22 $google clojure timbre

7:22 lazybot: [ptaoussanis/timbre · GitHub] https://github.com/ptaoussanis/timbre

7:23 engblom: Idiomatic Clojure will be slower in many cases than Java. With Java you use global variables inside of the classes to store your data. Using methods not passing this data around will result in faster code, but bigger chance for bugs. Clojure has atoms and refs which could do the same, but then we begin to miss out the real benefit of functional programming

7:23 sm0ke: argh i understand that clojure is slower than java!

7:23 i am talking about which is slowest part of my code among all

7:24 hyPiRion: that would be a hell lot of manual process

7:24 putting profiling code everywhere

7:24 isnt there something like eclipse MAT or whatever its called

7:25 oh MAT is for heap

7:25 vijaykiran: MAT is for leaks and heap analysis

7:26 justin_smith: sm0ke: regular java profilers will tell you where hotspots are, you just need to round that up to your user level clojure calls

7:26 sm0ke: justin_smith: sounds hard

7:26 really

7:27 how much can you shave off by avoiding reflection?

7:27 justin_smith: visualvm and yourkit were mentioned above. they will give a profile of your code without needing to do manual instrumentation

7:27 sm0ke: a lot

7:28 sm0ke: hurm

7:28 is yourkit free?

7:28 i see it being publicize a lot

7:29 technomancy: it's not

7:30 sm0ke: well

7:30 justin_smith: it's free as in beer for open source project usage

7:31 technomancy: they make you publicize it in order to use it, which might explain that

7:31 sm0ke: yep, i see it a lot of github landing pages of repos

7:32 SagiCZ: sorry to jump in but what IDE do you guys use<

7:32 ?

7:32 vijaykiran: SagiCZ: Ah, the age-old question - I use Emacs (for clojure), IntelliJ for Java/Scala

7:33 sm0ke: i use vim for both, working with Java feels like walking on a rope blindfolded though

7:33 SagiCZ: vijaykiran: Is there any non-emacs editor that would let me recompile selected functions on the fly? I dig that functionality but I can't survive emacs

7:33 sm0ke: vim, eclipse, nightcode, lighttable..

7:34 idea

7:34 SagiCZ: i use idea (cursive)

7:34 sm0ke: it doesnt allow that?

7:34 SagiCZ: but don't know how to compile on the fly

7:34 not sure..

7:35 sm0ke: search for it, its the most basic thing in clojure imo..must be there

7:36 SagiCZ: alright will dig into it

7:36 sm0ke: ok i think i would start with refelection then

7:36 cfleming: SagiCZ: you're trying to re-evaluate a function in the REPL?

7:41 SagiCZ: cfleming: not REPL.. in clojure file

7:42 cfleming: SagiCZ: right, but you're trying to send a function from the editor to the REPL?

7:42 SagiCZ: cfleming: no

7:42 interactive evaluation is only in repl<

7:42 ?

7:43 cfleming: Yeah, interactive evaluation is always using a REPL.

7:43 That's true of Emacs et al too

7:43 SagiCZ: ooooh.. alright, i think that might work.. i will look into that, thank you

7:43 cfleming: The only one that's different is LightTable, and it just hides the REPL really - it's still using one behind the scenes

7:44 SagiCZ: LightTable is IDE?

7:44 cfleming: Yes

7:44 SagiCZ: alright

7:44 i will try to stick with IntelliJ since I use it for java and all

7:45 cfleming: So in Cursive, you'd start a REPL, then you can send forms to it using Tools->Run form before cursor in REPL or Tools->Run top form in REPL

7:45 Good choice :-)

7:45 (I develop Cursive BTW)

7:46 SagiCZ: Wow amazing! I used that menu to share namespace and forgot about the other options..

7:47 btw if you are a developer i have one question, why is synchronizing by leiningen so slow? and why is the call to (use '(...)) so slow? it takes around 6 seconds on my machine.. it might be clojure problem, not cursive

7:48 cfleming

7:48 cfleming: Lein sync is often slow the first time, since it downloads all the dependencies you need.

7:48 Once they're in your Maven cache it should be basically instantaneous.

7:48 SagiCZ: so rebuilding my project on every run while developing is not a good idea right?

7:49 well thats what i thought.. in java they download first and then its fast..

7:49 cfleming: The (use '(…)) being slow is just Clojure, Cursive doesn't affect that.

7:49 SagiCZ: alright.. i think it was the "use" slowing me and not leiningen

7:49 cfleming: One thing to check - do you have Settings->Leiningen->Automatically download sources/javadocs selected?

7:50 That can make things very very slow - I recommend turning them off.

7:50 SagiCZ: what if i like javadocs? :D

7:50 cfleming: Hehe

7:50 This is tricky with Clojure

7:51 sm0ke: so the warn-on-reflection falg just warns the first time?

7:51 cfleming: The problem is that most Clojure libs are distributed as source, so they don't have a source artifact.

7:51 So every time you sync, Cursive has to go out to see if all your libs have source artifacts, since there's no way to tell if they do or not.

7:52 sm0ke: i mean why doesnt it warn on a function call eveytime? just one the use and require's

7:52 SagiCZ: oh i see

7:52 so how do we go around that in clojure? ("use" being slow)

7:52 cfleming: The problem is that there's no way to know if a library is a Java dependency (where you want them) or a Clojure one (where you don't).

7:52 If you navigate to a Java class from a library, it'll prompt you to download the sources, and then you'll have sources + javadocs for that library

7:53 SagiCZ: so the comments in clojure functions are not called javadocs? i want those..

7:53 cfleming: Unfortunately Clojure is just slow loading large namespaces.

7:53 SagiCZ: yeah (use '(incanter core)) takes 6 seconds :(

7:54 cfleming: No - you'll get those automatically, since libraries are all distributed as source and Cursive gets the doc from those sources.

7:54 SagiCZ: oh alright.. well i can disable that option then..

7:54 sm0ke: hmm that migh be overkill but useful imo

7:54 expez: Is there some library that lets you squirrel away the results of calling some functions? I have some services that my app relies on, but I don't want to be calling those services in my tests. So I would like to turn on 'squirrel mode', run my tests, and save the (args, result) pairs for these functions so I can replace them with mock services in my tests. When the services are altered I could just rerun

7:54 the tests with 'squirrel mode' to update the dummy data.

7:54 cfleming: Yeah, sadly there's nothing to be done about that. There's a bunch of projects going on right now to make that faster, they might make it into Clojure 1.7

7:55 SagiCZ: cfleming: cool

7:55 cfleming: SagiCZ: But Clojure startup is very slow right now, which is why it's not great on Android, sadly.

7:56 SagiCZ: cfleming: luckily i dont care about that.. i am actually planning to develop large scale desktop application which will run 24/7 so start time doesnt affect me..

7:56 it sucks during development, but now i know how to evaluate functions in repl so it should be ok

7:57 cfleming: Great. The nice thing about the REPL is that you only wait once when you start the REPL up too, not when you run every test.

7:58 SagiCZ: 2cfleming: yep i like that too.. actually i chose lisp dialect because of the posibility to fix bugs while running.. it could be potentially really expensive to shut down the whole thing down too often

7:59 sm0ke: how do i put type hint for `f` in this expr ? ## (set *warn-on-reflection* true) (-> ^Integer 1 inc) ;?

7:59 lazybot: clojure.lang.ArityException: Wrong number of args (2) passed to: core$set

7:59 sm0ke: how do i put type hint for `f` in this expr ? ## (set! *warn-on-reflection* true) (-> ^Integer 1 inc) ;?

7:59 lazybot: java.lang.SecurityException: You tripped the alarm! set! is bad!

7:59 sm0ke: how do i put type hint for `f` in this expr ? ## (-> ^Integer 1 inc) ;?

7:59 SagiCZ: set!

7:59 sm0ke: obviously this wont work!

8:00 macro doesnt recognizes type hints right?

8:00 xsyn: anybody here used neocons?

8:00 sm0ke: hmm oh it does! but still i get warning

8:00 xsyn: can you define the id of a node with a batch-insert?

8:01 create-batch even

8:03 sm0ke: ok this, (defn foo [s] (-> ^String s .length .longValue))

8:04 how do i put type hint for Integer?

8:04 Bronsa: sm0ke: ^Integer (do 1)

8:05 justin_smith: sm0ke: http://clojure.org/java_interop#Java%20Interop-Type%20Hints

8:06 sm0ke: specifically the definition of hinted

8:06 sm0ke: justin_smith: sorry i dont understand which part of that is relevant here?

8:06 justin_smith: (defn hinted (^String []) (^Integer [a]) (^java.util.List [a & args]))

8:06 each arg arity is type hinted

8:07 sm0ke: justin_smith: umm i have already put type hint for first argument

8:07 justin_smith: just not in the conventional place though

8:07 justin_smith: sm0ke: that is not hinting args

8:08 that is hinting return types

8:08 sm0ke: also, when we were finding performance issues with an app I worked on, the biggest win was eliminating usage of eval

8:08 sm0ke: justin_smith: i am asking about the type-hint for Integer coming from .length

8:08 Bronsa: sm0ke: you shouldn't need any hinting there, clojure has local type inference

8:08 sm0ke: Bronsa: i warns me

8:08 it*

8:08 i am on 1.4

8:09 Bronsa: sm0ke: .length returns an int not an Integer

8:09 sm0ke: Bronsa: ok my mistake but i still get, reference to field longValue can't be resolved.

8:09 oh ok

8:10 justin_smith: then you need to hint the thing longValue is called on

8:10 sm0ke: let me see

8:10 Bronsa: sm0ke: this should be enough (defn foo ^long [s] (-> ^String s .length))

8:10 sm0ke: ok just a sec i couldnt make up a sensible example

8:12 (defn foo [m] (-> m :str .length))

8:12 how do you handle this without removing the threading macro

8:12 (-> ^String (:str m) .length) is not allowed either

8:13 Bronsa: I'm actually a bit surprised that clojure doesn't box the int to an Integer there

8:13 sm0ke: my point being it could be (-> a :b :c :d :e)

8:13 Bronsa: sm0ke: (-> m ^String (:str) .length)

8:14 sm0ke: what!!

8:14 haha

8:14 Bronsa: sm0ke: (-> foo bar) == (-> foo (bar))

8:14 sm0ke: yep

8:15 i was trying (-> m ^String :str .length)

8:15 i am not sure why that isnt valid?

8:15 Bronsa: sm0ke: keywords can't take metadata

8:16 swi: I just end up reading http://www.braveclojure.com/, was very fun but not everything i understand clear. What nextbook or resource can you recommend to read ?

8:16 sm0ke: ok make sense i guess

8:17 SagiCZ: joy of clojure?

8:17 sm0ke: Bronsa: thanks

8:21 engblom: I found Brave Clojure to be very easy to understand, but then on the other hand I had some Haskell background so functional programming was not completely new for me. I looked at several online Clojure books, and I found Brave Clojure to be the easiest to follow because it was fun at the same time.

8:23 swi: engblom: same here, but i have a little background in FP (touch a haskell a little with lyhgg), but clojure looks more elegant to me.

8:25 tvanhens: is there a core function to generate a map (graph) of your namespeaces and their dependencies?

8:26 I want to make a graph chart of our namespaces and their requires for documentation purposes

8:26 xsyn: that doesn't sound like something that there would be a core function for

8:27 nkozo: tvanhens, I think there was some project in github for doing that, don't remember it

8:28 tvanhens: It doesn't need to be core, I should of said is there a set of core functions I could use or is there a readily available library

8:28 I've tried noodling around with the ns functions but it was turning into a mess and though that this must have been done before

8:29 mpenet: you could try to look how codox does the ns walking part

8:30 sm0ke: ok another weird one, (defn foo [s] (.getBytes ^String (cond true s)))

8:31 Bronsa: sm0ke: .. yeah about that

8:31 turns out macros lose metadata on &form

8:31 so there's really no good way to type hint those forms

8:31 you have to wrap it in a do

8:32 ^String (do (cond ..))

8:32 sm0ke: hey but the macro expansion is (if true s nil)

8:32 Bronsa: http://dev.clojure.org/jira/browse/CLJ-865

8:32 sm0ke: vote or/and comment in this ticket if you care

8:33 sm0ke: it's macroexpansion that discards meta

8:34 sm0ke: i think i would vote that up

8:34 will*

8:43 ambrosebs: Bronsa: do you think preserving the metadata is a good idea?

8:45 Bronsa: ambrosebs: yes

8:46 ambrosebs: Bronsa: sounds a bit odd to me.

8:46 but I'm sure I'd get used to it.

8:46 I'm eager to see what crazy code it breaks :)

8:49 Bronsa: ambrosebs: well since nobody has come screaming at you for breaking their code yet, I guess it really doesn't break any

8:49 ambrosebs: t.a.j preserves metadata :P

8:49 ambrosebs: orly

8:49 well I'm convinced now then :P

9:08 bacon1989: so I was wondering, I have a string, that I want to pass to a function as a reader. Is there a way to convert a string to a reader?

9:09 Bronsa: StringReader

9:11 bacon1989: ah

9:11 i've tried StringReader, but it's not doing what I suspect

9:12 i'm trying to get the namespace from my file, along with all of it's dependencies. the file is in the form of a string though

9:12 so i'm using read-ns-decl from http://clojure.github.io/tools.namespace/

9:12 it keeps returning nil, even though my string content clearly has a (ns declaration at the top

9:15 stuartsierra: bacon1989: read-ns-decl returns nil on error, so that may be the reason

9:16 (clojure.tools.namespace.parse/read-ns-decl (java.io.PushbackReader. (java.io.StringReader. "(ns foo (:require bar))")))

9:17 bacon1989: what is the point of the pushback reader?

9:18 stuartsierra: Clojure's `read` requires a PushbackReader, so `read-ns-decl` does too. It's what allows the parser to read one character ahead without consuming it from the stream.

9:19 bacon1989: ah ok

9:19 I thought reseting the stringreader would have worked

9:19 using the pushbackreader seems to have done the trick

9:19 thank you

9:20 xsyn: ,(keyword 123)

9:20 clojurebot: nil

9:20 xsyn: ??

9:20 lazybot: xsyn: Definitely not.

9:20 clojurebot: ? is suddenly

9:21 xsyn: why can't I make a number a keyword?

9:22 hyPiRion: you can, just do ##(keyword (str 123))

9:22 lazybot: ⇒ :123

9:23 xsyn: yeah, just done that

9:23 ta

9:29 pro_1: This channel has many users.

9:29 xsyn: (statement? (last pro_1))

9:29 => true

9:30 pro_1: Programmers moatly?

9:31 Mostly*

9:32 I read somewhere that this channel is a welcoming one.

9:32 Get me beer, guys.

9:37 swi: Can someone explain me syntax for doseq ? Am i understand right, that if a have a list of promises and whant to print the results i need (doseq [i mylist] (println @i)) ?

9:40 ambrosebs: swi: that's right

9:45 swi: ambrosebs: and if want pass two seq's ? i.e. [1 2 3] and ("A" "B" "C") ?

9:45 raj91: i'm looking for a generalization of nth that lets me choose a seq of indices

9:45 e.g. (nth* [10 11 12 13 14 15] [1 3]) ; [11 13]

9:46 does this exist in core?

9:46 opqdonut: ,(map [10 11 12 13 14 15] [1 3])

9:46 clojurebot: (11 13)

9:46 opqdonut: ;)

9:46 raj91: opqdonut: haha, thanks

9:46 michaelr525: hey

9:47 Bronsa: mapv if you want to get a vector back

9:47 raj91: opqdonut, Bronsa : yeah, but I suspect neither is meant to be fast like subvec or nth, right?

9:47 justin_smith: raj91: mind you that will only work with a vector

9:48 raj91: if the numbers are in some other sequential type, you will need to turn them into a vector first

9:48 raj91: justin_smith: thanks

9:48 justin_smith: raj91: nth is slow

9:48 using [] as an fn uses get, which is faster

9:48 ambrosebs: swi: depends what output you want?

9:49 justin_smith: but you have to do the work of making the vector first, so really it depends, in the big picture

9:49 swi: ambrosebs: something like parentesis 1 - A, 2 - B etc

9:49 Bronsa: justin_smith: wut

9:49 justin_smith: how is nth slow

9:50 ambrosebs: swi: (doseq [a [1 2 3] b ["a" "b" "c]] (println a b))

9:50 vijaykiran: swi: liek this ##(doseq [x [1 2 3] y [ "A" "B" "C"] ] (println x y)) ?

9:50 lazybot: ⇒ 1 A 1 B 1 C 2 A 2 B 2 C 3 A 3 B 3 C nil

9:50 justin_smith: Bronsa: compared to get on a vector

9:50 Bronsa: justin_smith: get on vectors is implemented in terms of nth

9:50 raj91: justin_smith: ok, this helped clarify

9:51 swi: ambrosebs: vijaykiran no, like this i get 1abc 2abc etc but i need output only three line - 1a 2b 3c

9:51 justin_smith: Bronsa: OK sorry, I was thinking of the worst case performance of nth (if input was a seq), and for some reason it worked that way with other datatypes

9:51 Bronsa: perhaps I was thinking of "last"

9:51 Bronsa: ,(doseq [x (mapv list [1 2 3] ["a" "b" "c"])] (println x)

9:51 )

9:51 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

9:51 Bronsa: :(

9:51 SagiCZ: why does (use 'mynamespace) work fine but (ns thisspace (:require 'mynamespace)) throw noclassfound exception?

9:52 Bronsa: ,(doseq [x (mapv list [1 2 3] ["a" "b" "c"])] (println x))

9:52 clojurebot: (1 a)\n(2 b)\n(3 c)\n

9:52 michaelr525: hi

9:52 justin_smith: SagiCZ: that ' is being read as part of the namespace

9:52 Bronsa: justin_smith: yeah definitely last

9:52 swi: Bronsa: haha :) seems like i dont' describe clearly

9:53 SagiCZ: 2justin_smith: Thanks, that was it.. :)

9:53 michaelr525: I need to develop some CRUD administrative interface, thought maybe I could use the oportunity to try Om

9:53 Has anyone gone that path before?

9:53 swi: i mean i need output like this http://paste.debian.net/110988/ :)

9:54 vijaykiran: ##(doseq [[x y] (zipmap [1 2 3] ["A" "B" "C"])] (println x "-" y))

9:54 lazybot: ⇒ 3 - C 2 - B 1 - A nil

9:54 swi: AAhh.. zipmap!

9:54 Bronsa: vijaykiran: better to use map list than zipmap

9:55 SagiCZ: ,(println "hello")

9:55 clojurebot: hello\n

9:55 Bronsa: ,(zipmap [1 1 2 3] '[a b c d])

9:55 clojurebot: {3 d, 2 c, 1 b}

9:55 Bronsa: vijaykiran: using zipmap you're potentially removing some values

9:55 SagiCZ: ,(interpose \, (zipmap [1 1 2 3] '[a b c d]))

9:55 clojurebot: ([3 d] \, [2 c] \, [1 b])

9:56 vijaykiran: Bronsa: yup - but in my defense - it satisfies the pasted result :)

9:56 swi: ^ so - make sure you use map list than zipmap as Bronsa says

9:57 swi: will try

9:57 vijaykiran: michaelr525: yeah - I'm on a similar path using Om for a Crud App

9:57 michaelr525: vijaykiran: wooohoo !! :)

9:58 vijaykiran: how is it there?

9:58 vijaykiran: michaelr525: not too bad - still using 'callback' communication between the components not core.async

9:59 michaelr525: also, no backend ... yet.

9:59 swi: Bronsa: vijaykiran YES! (doseq [[x y] (map list A B)] (println ...)) do right what i need! Thanks a lot, i'm a little confused with all these 'similar' do-something functions :)

9:59 michaelr525: vijaykiran: hum hum.. I have fears of "developing generic ui components" here, instead of stitching the damn admin interface, if you know what I mean..

10:00 yunfan: michaelr525: what do you meant by `generic ui components` ?

10:00 vijaykiran: michaelr525: yeah -- there have been moments of .. wait I should make this "re-usable"

10:00 Glenjamin: there's react-bootstrap, which you should be able to use from om

10:01 michaelr525: yunfan: what vijaykiran said, i meant reusable components

10:02 yunfan: michaelr525: but arent you talking about clojure? or you're actually talk about clojurescript?

10:02 michaelr525: vijaykiran: clojurescript + om

10:02 yunfan: i think ui isnt the server side stuff

10:02 michaelr525: yunfan: ^^

10:02 heh

10:02 yunfan: unless you dont like data backend the concept

10:03 michaelr525: vijaykiran: do you get up to speed after the initial learning curve?

10:04 vijaykiran: michaelr525: yeah - e.g. I think after 2 days of why the hell "delete" isn't working on table row, suddenly things are clearer again

10:04 michaelr525: yunfan: hmm, not sure what you mean. I have to write a web application to edit some values in a database..

10:04 vijaykiran: michaelr525: but I'm keeping an eye on reagent too

10:05 yunfan: michaelr525: i meant you dont need worry about ui stuff, since there're so many generic ui components, just pick anyone

10:06 focus on the data backend, make your backend api security and fast, also restful

10:06 michaelr525: vijaykiran: so why delete isn't working on table row? ;)

10:07 silasdavis: how can I set the print-length and print-level for lein test

10:08 michaelr525: yunfan: oh, well the abundance of UI components is part of the problem here.. I thought to use Om this time for the UI and I haven't seen many Om components out there

10:08 vijaykiran: michaelr525: :) not realizing that each component gets cursor instead of the data directly

10:09 silasdavis: also how do you go about debugging clojure.test tests

10:09 vijaykiran: michaelr525: I'm not using bootstrap-components - but http://www.getuikit.com

10:09 michaelr525: vijaykiran: oh, so how had you solved it?

10:09 silasdavis: they don't return values, and print statements aren't echoed as far as I can see

10:10 michaelr525: vijaykiran: ohh nice

10:10 yunfan: michaelr525: i understand your problem now, you might like those tranditional tech , which would even generate the FORM ui in your backend code, like xajax to php

10:10 vijaykiran: michaelr525: BTW, gettin more familiar with React.js

10:10 yunfan: i dont like this style, but its your project. :]

10:17 sm0ke: whats the type hint for array types?

10:17 e.g. a bytes array?

10:17 justin_smith: sm0ke: bytes

10:18 or doubles, ints, shorts, longs, etc.

10:19 sm0ke: justin_smith: got it thanks

10:19 Bronsa: beware that

10:19 ,(defn ^bytes x [])

10:19 clojurebot: #'sandbox/x

10:20 justin_smith: http://stackoverflow.com/questions/3720196/how-can-i-type-hint-an-array

10:20 Bronsa: ,(-> #'x meta :tag)

10:20 clojurebot: #<core$bytes clojure.core$bytes@1432e1a>

10:20 Bronsa: you want to put the bytes tag on the argvector not on the def sym or it will resolve to the `bytes` function and be ignored

10:20 swi: btw, what is prefered way to play with Datetimes in clojure ?

10:20 vijaykiran: swi: clj-time

10:21 swi: which is wrapper for joda-time

10:21 sm0ke: oh ok

10:21 thats again a bug?

10:21 swi: vijaykiran: aha... seems like a perfect to me :)

10:21 sm0ke: and whats up with #^bytes vs ^bytes?

10:21 Bronsa: sm0ke: #^ is old syntax for ^

10:22 sm0ke: not a bug, def evaluates its metadata, it's documented

10:22 sm0ke: the bug there is probably that clojure silently ignores wrong tag metadata rather than throwing an error

10:23 sm0ke: umm does that means every type hint on def symbols is ignored?

10:23 not just bytes?

10:23 i mean most of them are functions right?

10:23 int float double etc..

10:24 of course custom classes are fine

10:24 Bronsa: sm0ke: right

10:25 sm0ke: (defn ^'bytes x []) works though

10:25 manually quoting the tag, I mean

10:25 sm0ke: ok, wow seems like you know type hinting to the every last detail

10:26 type hint much? :D

10:26 Bronsa: well I wrote a clojure compiler so.. :)

10:27 sm0ke: oh cinc

10:27 bbloom: (inc Bronsa)

10:27 lazybot: ⇒ 32

10:27 clojurebot: Gabh mo leithscéal?

10:28 sm0ke: (inc Bronsa)

10:28 lazybot: ⇒ 33

10:28 sm0ke: whats the rationale behind writing a clojure compiler in clojure?

10:28 how does it helps?

10:29 Bronsa: sm0ke: in the short-term the most important thing has been the analyzer, it's being used by a number of big libraries like core.typed and core.async

10:30 mikerod: tools.analyzer++

10:31 Bronsa: sm0ke: in the long-term, maybe one day we could get clojure to be self-hosting, having the compiler&analyzer written in clojure is a big win for extensibility, fast prototyping etc

10:31 IMHO at least

10:31 swi: vijaykiran: is there way to specify what tz i want to use by default in clj-time ?

10:31 Bronsa: also it's fun.

10:33 mikerod: Bronsa: I like the idea of that. Having the AST-as-data can be a very useful thing.

10:33 It really opens the door for some better analysis tools I'd imagine.

10:33 tbaldridge: at some point I want to extend tools.analyzer to provide something like macros 2.0. Macros, but you get access to the AST of the form (or program?).

10:33 mikerod: I thought I heard a talk mention that the emitter is not intended to replace the real clj bytecode emitter though?

10:33 sm0ke: hmm sounds nice, i am still too thick too see where and how it is used though

10:34 tbaldridge: would be useful for non-trivial macros.

10:34 vijaykiran: swi: not sure which func in clj-time - but joda has setDefaultTimeZone

10:34 mikerod: tbaldridge: Yes, I think it has a lot of benefits in that area.

10:34 boxed: tbaldridge: looked into seqex.syntax?

10:34 vijaykiran: swi: http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTimeZone.html#setDefault(org.joda.time.DateTimeZone)

10:35 Bronsa: tbaldridge: might be tricky, at macroexpansion time there's not yet a complete AST

10:35 arrdem: tbaldridge: yeah I'm not sure that's meaningful generally.

10:35 Bronsa: tbaldridge: what cljs does is a good compromise & can already be done -- manually using the analyzer on macro args

10:36 swi: vijaykiran: aha, thanks a lot :)

10:36 sm0ke: btw, wrapping this in (do..) didnt help either..(defn foo [s] (.getBytes ^String (do (cond true s))))

10:37 mikerod: To move the the clj analyzer over the current clj compiler, I'd imagine you'd have to out-perform or be relatively similar to have a shot.

10:37 Bronsa: sm0ke: blah, use identity rather then do then

10:37 tbaldridge: mikerod: or provide better features

10:38 CLJ 1.7 is getting compiler switches, add a few more of those in (for invokedynamic, etc. ) and you're going to start getting a nice hairy mess in the current compiler.

10:38 bbloom: Bronsa: where are you at on perf?

10:38 mdrogalis: Is anyone at LambdaJam now?

10:38 Bronsa: bbloom: still too slow unfortunately, 10/15x

10:38 tbaldridge: that's where tools.analyzer is better in my mind, I can add layers without intertwining them with existing layers.

10:38 mikerod: tbaldridge: true. I'd still imagine that perf has to be a goal at some point. clj is often compiled on the fly. I don't think a significant slow down there would be a very welcome thing.

10:39 bbloom: Bronsa: have you profiled it? what's the low hanging fruit? / what is gonna be hard to fix?

10:39 sm0ke: Bronsa: Thanks :)

10:41 Glenjamin: i think self-hosting is more compelling on the cljs side, generally

10:41 but probably further away?

10:41 arrdem: Glenjamin: several steps away.

10:41 Glenjamin: anything i can chip in on?

10:42 arrdem: and probably not a goal... google closure does stuff that tools.emitter.* probably never will.

10:42 Glenjamin: oh right, forgot about that bit

10:42 arrdem: I mean not that I don't want to see optimizing compilers for clojure in clojure..

10:42 boxed: Automatically run the code in your README.md: https://github.com/boxed/midje-readme

10:42 Bronsa: bbloom: haven't profiled in a while, I'll get on perf work once tools.analyzer.js is good enough, which isn't really going to take much longer

10:43 bbloom: the emitter can be heavily optimized and we know how but unfortunately that only accounts for a small amount of the overhead

10:43 Glenjamin: being able to compile cljs macros in the browser would be ace

10:44 Bronsa: given that t.a.js is ~3x slower than cljs.analyer that indicates that the AST walking multi-pass approach has some intrinsic overhead that might be difficult to reduce

10:45 Glenjamin: is there any parallelism in the compiler?

10:45 Bronsa: no

10:45 Glenjamin: i was thinking the other day that non-dependant namespaces could be compiled in parallel

10:45 tbaldridge: Duh man....everyone knows parallelism makes stuff faster

10:46 what's wrong with programmers these days?

10:46 :-P

10:46 bbloom: hehe well, it's true tho

10:46 arrdem: Glenjamin: unfortunately due to Clojure's load semantics that's not really possible.

10:46 bbloom: the Roslyn compilers are like 20% slower than the previous compilers when single threaded

10:46 but when compiling independent .cs files, it's almost a linear speed up

10:46 Glenjamin: arrdem: which part? i'd have though the lack of foward declarations and global namespaces would help

10:47 Bronsa: Glenjamin: it's non trivial to determine what namespaces a ns depends on

10:47 ghadishayban: Bronsa: is multimethod dispatch part of the problem?

10:47 bbloom: Bronsa: well, at least the ns form is quasi declarative

10:47 unfortunately the way it's implemented isn't super helpful in that regard

10:47 Bronsa: bbloom: ns is not the only way to load a namespace

10:47 Glenjamin: i kinda imagined some sort sort of queue

10:48 bbloom: Bronsa: right, but it's the most common and readily parallelized

10:48 Glenjamin: load adds to a queue, if you hit another load then queue another and pause until it's fulfilled

10:48 tbaldridge: I've done tests on storing analysis data in a tuple store + a datalog to query. It completely changes the model, but it does allow you to touch leaf nodes without updating the path to that node.

10:48 ghadishayban: I've tackled static vars, protocol calls, and keyword invokes with invokedynamic, but I haven't started plotting what to do with MM dispatch

10:49 blunte: Hello all. I'm struggling a bit to understand how to iterate over a sequence of vectors properly. Can I show a line of code for suggestions?

10:49 ghadishayban: blunte: go for it

10:49 Bronsa: ghadishayban: I do think the heavy use of multimethods is part of the problem but, I have plans to try using records for the AST nodes & using protocols to see if that helps

10:49 tbaldridge: ghadishayban: you'll have tons of fun with that, since it's basically opaque to the compiler. You could dispatch on anything

10:49 ghadishayban: tbaldridge: my only idea is to intrinsify MMs

10:50 blunte: I'm processing CSV like data, and for testing purposes I would like to join the inner vectors with comma and the sequence elements (vectors) with newline)

10:50 arrdem: tbaldridge: build a partial application/evaluation engine and precompute dispatch where possible :D

10:50 tbaldridge: dang it! now I want go and run a profiler over t.a.j instead of working this morning

10:50 blunte: (doall (map clojure.string/join "," '(["one" "two" "three"] ["four" "five" "six"] ["seven" "eight" "nine"])))

10:50 it just returns the first vector, comma joined.

10:51 Glenjamin: blunte: you need to wrap the "join ," bit into a function

10:51 ,(map #(clojure.string/join "," %) '(["one" "two" "three"] ["four" "five" "six"] ["seven" "eight" "nine"]))

10:51 clojurebot: ("one,two,three" "four,five,six" "seven,eight,nine")

10:51 blunte: ooh

10:51 thanks. processing mentally

10:51 that's very nice, thanks!

10:52 and that returned sequence can be joined with newline to give me the result I want

11:10 lvh: Hi!

11:10 Are there bindings for nacl/libsodium anywhere?

11:10 (If not I guess I can use the Java stuff)

11:14 justin_smith: lvh: there is clojurescript for targetting js, but no nacl backend that I know of

11:14 lvh: ehh

11:14 ssideris: http://blog.cognitect.com/blog/2014/7/22/transit

11:14 lvh: justin_smith: sorry I should clarify, I mean nacl the crypto lib, not native client :)

11:14 ssideris: Mr Hickey strikes again

11:18 john2x: what's the opposite of assoc-in?

11:18 nkoza: john2x: get-in ?

11:18 mdrogalis: *Cough* http://dev.clojure.org/jira/browse/CLJ-1063

11:18 john2x: i mean the dissoc part

11:18 mdrogalis: john2x: ^

11:18 john2x: ooh.. thanks mdrogalis

11:19 mdrogalis: john2x: You can find an implementation of dissoc-in in most util libraries.

11:19 tbaldridge: john2x: normally, this

11:19 andyf: Bronsa: Expected change from t.a.j 0.2.2 to 0.3.0 that ignored/wrong primitive type hints cause exceptions to be thrown?

11:19 tbaldridge: , (update-in {:a {:b 42}} [:a] dissoc :b)

11:19 clojurebot: {:a {}}

11:19 arrdem: well at least it's not "patch declined" yet...

11:20 tbaldridge: john2x: mdrogalis: would a "true" dissoc-in remove the entire path? or just the leaf node,

11:20 Bronsa: andyf: got an example?

11:21 john2x: tbaldridge: for my needs just the leaf node (I guess it's analogous to get-in that way)

11:21 andyf: Bronsa: (defn #^bytes to-bytes ...) throws exception with 0.3.0 but not 0.2.2

11:21 Bronsa: andyf: oh yeah

11:21 tbaldridge: john2x: right, but I think that is one of the reasons dissoc-in was never added to core

11:22 Bronsa: andyf: intended

11:22 tbaldridge: ,(assoc-in {} [:a :b :c :foo :bar] :baz)

11:22 clojurebot: {:a {:b {:c {:foo {:bar :baz}}}}}

11:22 andyf: Bronsa: Wrong tag: clojure.core$bytes@6747009b in def: to-bytes

11:22 JohnTalent: how can you check your tried password attempts on freenode?

11:22 justin_smith: tbaldridge: if you want to remove the whole path, you only need to dissoc the prefix

11:22 andyf: Bronsa: Thought so, but wanted to verify that it didn't surprise you too much :)

11:22 tbaldridge: justin_smith: recursively, yes

11:22 Bronsa: andyf: https://github.com/clojure/tools.analyzer.jvm/commit/829c996198ecbc7023e8bd3f0757e830cd6b475e

11:24 andyf: Bronsa: I'll take a stab at documenting this change, since some Eastwood users will see it.

11:24 Glenjamin: is core incubator still a thing?

11:25 Bronsa: andyf: I'm going AFK for a couple of hours now, if you need me write to me in query and I'll reply when I get back

11:25 andyf: Glenjamin: I think it has been a year or three since any change has been made to it

11:25 Bronsa: got it

11:27 Glenjamin: Medley and Prismatic plumbing libraries are not official, but have similar kinds of things you may find useful https://github.com/weavejester/medley

11:27 Glenjamin: yeah, there's also useful too

11:28 as in, the library called useful

11:29 andyf: Glenjamin: understood. I can't speak to future plans of other people here, but it seems like a safe bet that core incubator will remain static.

11:30 Glenjamin: in the sense that it isn't really incubating things anymore :)

11:30 andyf: well, it is still incubating the same things -- they just won't hatch :)

11:31 Glenjamin: heh

11:32 arrdem: I mean... now that technomancy has obligingly solved the dependency management problem, there's kinda no good reason for core to bloat at all. In fact shrinking core has become possible...

11:33 not that I really consider stuff like dissoc-in "bloat", but we have the tools to implement our own convenience tools without having to enshrine them in the lang itself

11:34 andyf: Seems some people like enshrined things

11:34 Glenjamin: unless two libs depend on different versions of a util lib

11:34 andyf: I'm not arguing for or against enshrining here -- just observing.

11:36 I hope Transit gets an ANN in the Clojure group, too. I don't want to feel I have to follow all the blogs :)

11:37 arrdem: andyf: thoughts on transitioning Grimoire to a simple Ring app?

11:37 Glenjamin: where would you host it arrdem?

11:37 arrdem: Glenjamin: same place I already do... my underutilized digitalocean instance

11:38 Glenjamin: oh, i assumed it was github pages currently

11:38 andyf: arrdem: I have no advice there, unfortunately. I am a very rare bird these days -- a software developer who has never written a dynamic web site.

11:39 john2x: so is Transit "replacing" EDN?

11:41 ambrosebs: andyf: should we feel bad for that?

11:42 andyf: ambrosebs: I don't think so :) It can certainly change in the future, and probably will when I get off my a** and do it some day.

11:42 ambrosebs: yea that's what I tell myself

11:44 dnolen_: http://blog.cognitect.com/blog/2014/7/22/transit

11:44 Transit landed

11:44 probably time to EOL sending EDN or JSON between CLJ/CLJS :)

11:48 nullptr: dnolen_: given that both sides speak EDN natively, the primary motivator in that scenario would be -- wire perf?

11:53 justin_smith: nullptr: looking at the github repo examples, transit looks bulkier on the wire than edn would be

11:55 dnolen_: justin_smith: not true - caching

11:55 justin_smith: will be way smaller

11:55 nullptr: yes for Clojure data easily faster than JSON most of the time

11:55 because of caching and lot of optimizations

11:56 cognitect.github.io/transit-tour

11:56 look at the bottom

11:56 89K for raw JSON rep, 53k w/ caching

11:57 V8 based engines can parse that nearly 2X faster and the remaining time hydrate

11:57 also true for recent IEs

11:57 Safari & Firefox lag a bit, but still blows EDN away

11:57 20X faster to read

11:58 Glenjamin: caching seems be a bit of an overloaded term in this case

11:58 dnolen_: Glenjamin: in what sense?

11:58 Glenjamin: but i guess compression would suffer from the same overloaded meaning

11:59 well wire caching usually refers to intermediaries serving stale responses

11:59 dnolen_: Glenjamin: it's not just comprehension

11:59 we read values out of the cache

11:59 Glenjamin: and i know this isn't wire caching, but it's talking about caching for a wire format

11:59 dnolen_: if a keyword appears 1000s of times

11:59 ... same keyword

11:59 Glenjamin: oh right, i see

11:59 it's both wire compression and reader caching

12:00 averell: does that test include compressed transport?

12:00 dnolen_: averell: the last 2 lines do

12:13 basic transit clj/cljs example https://github.com/swannodette/transit-example

12:13 sm0ke: i have a definition (defn ^bytes tobytes....) ..but the compiler throws java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core$bytes@73fc62f

12:16 razum2um: how does transit compare to protobuf?

12:16 tbaldridge: razum2um: protobufs have a external format

12:16 sm0ke: Bronsa: mentioned that ^bytes on def is error prone, but seems like defn is also in the same boat

12:17 moreover ^'bytes also doesnt work

12:17 tbaldridge: razum2um: transit is ad-hoc in the sense that there is no formal schema you simply write/read values

12:17 sm0ke: what a joke

12:18 razum2um: tbaldridge: I feel like it's gonna be a lib further anyway like prismatic schema :)

12:18 tbaldridge: be a lib further?

12:19 razum2um: tbaldridge: I mean there will appear a lib to schemify transit :)

12:20 tbaldridge: razum2um: perhaps, but I doubt it will come from Cognitect (IMO my opinion is my own). Existing schemas will work with transit, and yet I've never used one in my professional work.

12:38 silasdavis: is the a clojure core function: (fn [v f] (f v))

12:38 ?

12:38 is there*

12:39 hoverbear: Are there any guides to deploying Clojure apps to Wildfly/Jboss?

12:43 DomKM: hoverbear: http://immutant.org/

12:48 hoverbear: DomKM: Ah yes, with it's lovely blank "Deploying with Wildfly" page. :(

12:48 DomKM: hoverbear: oh, sorry. Maybe hop over to #immutant and ask them.

12:48 hoverbear: DomKM: Yeah. :) already there.

12:49 johncash: Why use json and msgpack for transit rather than edn and fressian?

12:49 I don't see the point of using JSON if you need a separate library to parse it

12:50 tbaldridge: johncash: fast JSON parsers exist for almost every language.

12:50 The only way you're going to get decent performance in the browser for example, is by writing your data format on top of JSON

12:51 johncash: (inc tbaldridge)

12:51 lazybot: ⇒ 8

12:51 tbaldridge: fun fact, msgpack implementations for JS are actually slower than JSON JS implementations.

12:53 johncash: Is that because JSON parser is in C?

12:53 hoverbear: johncash: The JSON parser in browsers are generally native

12:53 C/C++/C# or whatever goofy stuff IE is written in

12:54 johncash: by "C" I mean low level language the browser is written in

12:54 tbaldridge: johncash: partly, and just that JSON in node.js/browsers has has been optimized by dozens of people over years and years of work. Beating that is going to be super hard.

12:55 johncash: So we are letting the nodejs and browser people dominate the clojure world? A sad day, but pragmatic I guess

12:56 * johncash realises that the entire point of transit is for non-clojure languages and goes back to his corner

12:57 bbloom: dnolen_: is the transit-tour up somewhere? or should i just run it local?

12:58 tbaldridge: From some of the small tests I see, transit also outperforms EDN, so I'd use it all most all my CLJ->CLJS apps. The only time I wouldn't use it is when Fressian would work (only on the JVM)

12:58 dnolen_: bbloom: http://cognitect.github.io/transit-tour/

12:58 bbloom: dnolen_: would you accept a PR for the readme? ;-)

12:58 dnolen_: johncash: even if you do Clojure <-> Clojure, Transit beats EDN

12:58 bbloom: can't

12:59 johncash: it's a win if you're entire stack is Clojure, esp. if ClojureScript is involved

13:00 johncash: I'm going to start calling this JSON 2.0

13:01 bbloom: dnolen_: your `new Date(0)` example is problematic b/c it "works" with normal objects too

13:02 ie it will return "Works!" but obviously that's broken in actuallity

13:02 calls toString on the date

13:03 dnolen_: bbloom: not seeing that here, got a specific snippet?

13:03 bbloom: var m = transit.map([new Date(0), "Works!"]); m.get(new Date(0)); // "Works!"

13:04 > var m = {}; m[new Date(0)] = "works?"; m[new Date(0)] // "works?"

13:04 dnolen_: i know what you're trying to say, but somebody might try that and be like "what is this dnolen guy smoking?

13:04 dnolen_: bbloom: I have no idea what you are talking about yet

13:04 show me something that shouldn't work

13:04 bbloom: on http://cognitect.github.io/transit-tour/

13:05 dnolen_: bbloom: you haven't shown me anything that should not work

13:05 the second thing you posted here doesn't even make sense in the context of transit

13:06 bbloom: dnolen_: you write "The above is impossible under the proposed ES6 Map specification." which is true, but anybody reading this might think the second thing i posted

13:06 dnolen_: what does that have to do w/ ES6 Maps

13:06 ?

13:07 bbloom: dnolen_: i'm saying that what you wrote may fail to convey what you're attempting to demonstrate

13:07 dnolen_: it won't work w/ ES6 Maps that's all that I'm saying

13:07 your point is completely orthogonal

13:08 bbloom: i'm not trying to make a counterpoint or anything

13:08 justin_smith: sm0ke: looking at your unable to resolve class name, for the ^bytes type hint, the class name it lists looks like the actual value of the bytes function

13:08 bbloom: what you've written is correct

13:08 dnolen_: bbloom: for people who can't imagine doing this w/ more types and w/ good perf ... we can't help those people

13:08 justin_smith: sm0ke: I would not be surprised if ^'bytes only works in newer versions of clojure - is there some reason you need to stay at 1.4?

13:09 bbloom: dnolen_: *shrug* ok

13:13 dnolen_: http://jsperf.com/json-vs-transit

13:14 bbloom: dnolen_: the mini benchmarks on the bottom of the tour don't run long enough to present useful results

13:14 about 1ms each on my machine

13:15 but other than that, just read it. super good stuff

13:15 go team

13:15 dnolen_: bbloom: thanks! :)

13:17 bbloom: dnolen_: the example json you linked to contains some... suggestive... keys ;-)

13:18 dnolen_: bbloom: no comment :)

13:20 CookedGr1phon: Is there anyone here familiar with JVM bytecode? I'm debugging an issue with monitorenter and monitorexit on the new android ART runtime

13:20 sm0ke: justin_smith: yep need to stick to 1.4

13:21 isnt there some workaround for 1.4?

13:21 bbloom: CookedGr1phon: i'm not a bytecode expert, but i do know that montior enter/exit are weird in that they have to be statically verified in pairs, or something like that

13:22 CookedGr1phon: ie you get some kind of verification failure if you have one without the other in the same lexical extent

13:22 CookedGr1phon: bbloom: yeah, and the art compiler is falling over claiming that the clojure generated bytecode doesn't pass this check

13:23 bbloom: CookedGr1phon: gist the clj & bytecode

13:23 CookedGr1phon: bbloom: okay, one sec

13:28 bbloom: sorry, taking more than a sec, having to rebuild the project to remove my attempted workaround (moving the monitor-enter out of the try in the locking macro - something I'm fairly sure should be the case anyway looking at the bytecode that a plain java synchronized generates)

13:29 gtrak: so... is transit related to EDN and fressian at all?

13:29 devth: gtrak: https://news.ycombinator.com/item?id=8069731

13:30 gtrak: perfect :-)

13:36 CookedGr1phon: bbloom: here you go https://gist.github.com/AdamClements/2ae6c4919964b71eb470

13:38 bbloom: I realise the two segments aren't exactly equivalent, but when I had the java one just return 2, it did a shortcut returning from within the monitorenter/exit and I thought that might be affecting things

13:39 bbloom: my observations so far: the try in the clojure version includes the monitorenter instruction, and in the java version doesn't

13:40 bbloom: CookedGr1phon: did your custom locking macro fix it?

13:40 my guess is that this is an ART bug, that only expects output from javac

13:40 but presumably if moving the monitor-enter fixes it, then it may be reasonable to make that change

13:41 CookedGr1phon: I'm not sure yet, just going to go back to that, I reverted it just after I'd made the change in order to show you the bytecode of the original master clojure version

13:42 I'm trying it again now, I'm also trying different versions of the java code to see if I can find one which art won't run

13:42 hiredman: it looks like the java code's exception handler is installed for the bytecode right after the monitorenter, the clojure code's exception handler is installed for the bytecode starting right before the monitorenter

13:43 bbloom: hiredman: yeah, that he was saying about the definition of locking

13:43 `(let [lockee# ~x] (try (monitor-enter lockee#) ~@body (finally (monitor-exit lockee#))))

13:43 CookedGr1phon: hiredman *is* a byte code expert, as far as i know :-P

13:43 hiredman: fuh

13:44 thrown under the bus, just like that

13:45 (I am not)

13:45 bbloom: more than me

13:46 CookedGr1phon: one thing I really don't get about this bytecode, is what aconst_null, pop can be doing

13:46 m_m_: Hi. I am searching simple clojure web framework with clojurescript support and good doc. Any suggestions?

13:47 boxed: m_m_: reagent on the client side and ring+compojure on the server side

13:48 m_m_: how about caribou framework?

13:49 hiredman: CookedGr1phon: locals clearing

13:49 CookedGr1phon: nulling out locals that aren't used anymore so as not to keep references longer than required

13:50 Bronsa: hiredman: no he's talking about https://gist.github.com/AdamClements/2ae6c4919964b71eb470#file-test_locks-class-L42-L43

13:51 hiredman: Oh, right, not a store

13:51 Bronsa is the guy writing a clojure compiler

13:51 boxed: m_m_: haven’t tried it… but from what I can see it doesn’t seem to have a react-based frontend system so that’s a bit of a bummer for me personally… the db stuff looks interesting though

13:52 Bronsa: CookedGr1phon: the null is there so that that's what's returned if the monitor-exit is in return position

13:53 CookedGr1phon: but since that's not the case there, it's popped

13:53 sm0ke: is there some way to associate type hint in with-open binding?

13:53 Bronsa: admittedly the compiler could be a little smarter there and could not emit the null at all but this works too

13:54 sm0ke: i tried (with-open [s (vary-meta x assoc :tag FooClass)]...) to no use

13:54 Bronsa: sm0ke: type hints must be visible at compile time to have any effect

13:54 hiredman: "Clojure: The compiler could be smarter"

13:54 sm0ke: oh right

13:55 Bronsa: sm0ke: also reading the backlog, ^'foo obviously doesn't work I meant it as a shortrand for ^{:tag 'foo}, sorry if it wasn't clear

13:56 sm0ke: ok got it

13:56 its a way to avois it resolving to function

13:56 i am not very familiar with meta yet

13:57 Bronsa: wait wtf

13:57 ,'^foo []

13:57 clojurebot: []

13:57 Bronsa: ,(meta '^foo [])

13:57 clojurebot: nil

13:57 Bronsa: oh I have a patched clojure.

13:57 CookedGr1phon: okay, looking at the *java* version bytecode, what's with the second exception handler, where it's handled with itself

13:58 does that just keep trying monitorexit until it succeeds?

13:59 sm0ke: ,(meta {:tag 'foo} [])

13:59 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/meta>

13:59 sm0ke: ,(meta ^String [])

13:59 clojurebot: {:tag java.lang.String}

13:59 CookedGr1phon: in the clojure version, neither of the monitor-exits are in the scope of an exception handler, but in the java version both of them are... that's weird

13:59 sm0ke: ,(meta {:tag 'String} [])

13:59 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/meta>

13:59 sm0ke: ,(meta ^{:tag 'String} [])

13:59 clojurebot: {:tag String}

13:59 sm0ke: ,(meta {:tag 'foo} [])

13:59 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/meta>

14:00 sm0ke: ,(meta ^{:tag 'foo} [])

14:00 clojurebot: {:tag foo}

14:00 hiredman: looks like some kind of encoding of finally semantics

14:00 Bronsa: sm0ke: please avoid spamming clojurebot in the channel

14:00 sm0ke: ok so :tag can be anything ? clojure doesnt check for a valid classs?

14:00 yep sorry

14:00 Bronsa: sm0ke: correct

14:01 hiredman: or maybe not, I dunno

14:01 sm0ke: so for the with-open thing is there a workaround or i would have to write my own (with-open*..)

14:02 Bronsa: sm0ke: can't you type-hint the with-open binding symbol?

14:02 (with-open [^foo x ..] ..)

14:02 sm0ke: you mean (with-open [x ^int 1] x) ?

14:02 oh shit

14:03 doesnt work either

14:04 more over i had (with-open [^foo x (bar)] ..) where bar already has type hint for return

14:04 does it works for you?

14:06 CookedGr1phon: Is there a way to express the same semantics in clojure at all?

14:06 a catch which catches exceptions and retries until it works

14:06 hiredman: CookedGr1phon: no

14:06 CookedGr1phon: or am I down to fiddling with ASM at this point

14:07 hiredman: it is very weird, because I am not sure that is what would happen

14:07 CookedGr1phon: hiredman: but you agree the bytecode looks like that's what's happening right?

14:08 Would it be possible to forego all this and make something which uses the ACC_SYNCHRONIZED tag on the method instead?

14:08 hiredman: CookedGr1phon: not without doing the bytecode generation yourself

14:09 btcNeverSleeps: Can you call APIs written in Java 8 in Clojure? Do you need a specific Clojure version for that?

14:09 hiredman: CookedGr1phon: yeah, I don't think that is even actually finally semantics, I wonder if that bytecode is actually just generated as part of compiling a sychronized block

14:10 that isn't a sensible way to compile a finally, but for a synchronized where you *really* want that monitorexit to run

14:12 justin_smith: btcNeverSleeps: you can use parts of java8 via interop, if you use the java8 runtime

14:12 btcNeverSleeps: clojuer version should not affect this at all

14:12 btcNeverSleeps: justin_smith: thanks, that is great

14:14 CookedGr1phon: hiredman: if that were the case, wouldn't you think there'd be something in ASM for that construct? Or is it reasonable for that to be at a higher level

14:15 hiredman: CookedGr1phon: I doubt there is a construct in asm for it, it would be an implementation detail of javac

14:16 (which art may depend on because they only ever delt with code generated by javac)

14:17 http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/#4 shows the same kind of region that handles itself for monitorexit

14:20 CookedGr1phon: hiredman: so, is this a clojure bug waiting to happen, or an acceptable alternative way of doing things do we think?

14:21 i.e. should I be looking at getting this changed in clojure, or bugging google to allow this bytecode in ART?

14:22 hiredman: I dunno

14:23 CookedGr1phon: could do with the equivalent of c's inline assembly block to try this out :P

14:23 hiredman: I suspect it is an art bug in the sense that the bytecode spec lets you do it, and the art compiler does not

14:24 CookedGr1phon: hiredman: but by the same token you can do all sorts of things in the wrong order, jump to invalid instructions etc., it might be that monitorenter and monitorexit are only meant to be used in fairly specific ways

14:24 SagiCZ: whats the idiomatic way to ask if seq is empty?

14:24 hiredman: CookedGr1phon: you can't though

14:24 SagiCZ: (= x [])

14:24 ?

14:24 technomancy: ,(doc empty?)

14:24 hiredman: CookedGr1phon: jvms verify bytecode on load and barf on that kind of stuff

14:24 justin_smith: ,(map empty? [[] {} '()])

14:24 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

14:24 (true true true)

14:25 SagiCZ: ,(empty? [])

14:25 clojurebot: true

14:25 SagiCZ: ty

14:25 CookedGr1phon: SagiCZ: calling (seq x) is the idiomatic + fast way, it will return either the sequence or nil which is falsey if there's nothing in it

14:25 hiredman: CookedGr1phon: so the code clojure emits passing the bytecode verifier but art is barfing on it

14:25 CookedGr1phon: hiredman: yeah, fair point

14:26 hiredman: it might even be both

14:27 SagiCZ: CookedGr1phon: I think that empty? is way clearer, its obvious what i was asking ..

14:27 CookedGr1phon: hiredman: I'm fairly sure having the monitor-enter inside the try is wrong

14:27 hiredman: e.g. that bytecode passes the verifiers so art should accept it, but clojure should generate safer code

14:28 CookedGr1phon: wrong in what sense?

14:28 CookedGr1phon: hiredman: if the monitor-enter fails, you don't want to run monitor-exit

14:28 which is what the current implementation does

14:29 SagiCZ: sorry, wasn't paying full attention, I meant to say seq is the idiomatic way to check if a collection has something in it, rather than (not (empty? x))

14:30 SagiCZ: as a potentially relevant aside

14:31 SagiCZ: CookedGr1phon: I see

14:31 hiredman: CookedGr1phon: I suspect monitorenter only ever fails when the object is nil

14:32 SagiCZ: I need to pass a string or 'symbol to a function according which the function chooses one of its subfunctions to execute, how can i pass that?

14:32 i am trying to acll it as (fun 'parameter) but it doesnt work

14:32 hiredman: CookedGr1phon: but you are right, that may be an implementation detail of all jvms to date

14:32 CookedGr1phon: hiredman: http://stackoverflow.com/questions/15121402/jvm-synchronized-finally-blocks has some relevant discussion

14:33 justifies it as "at least the deadlock will happen in the right place, rather than next time something tries to get the lock"

14:33 amalloy: hiredman: is it not possible to also fail if someone interrupts your thread while you're waiting to get the lock?

14:34 hiredman: amalloy: dunno, it would depend on how you interrupt, I sort of doubt and implementations of monitorenter poll the thread interrupted flag

14:35 http://docs.oracle.com/javase/specs/jvms/se5.0/html/Compiling.doc.html#6530 the bytecode here doesn't have the second handler

14:36 SagiCZ: (= 'parameter (symbol "parameter"))

14:36 ,(= 'parameter (symbol "parameter"))

14:36 clojurebot: true

14:37 CookedGr1phon: I'm wondering if it's the goto that's throwing ART's static analysis, none of the java examples I've seen jump over the exception handler like the clojure version

14:38 hiredman: CookedGr1phon: it maybe easier to get clojure to make a change than to get google to, but I am not sure

14:38 I am pretty sure https://gist.github.com/AdamClements/2ae6c4919964b71eb470#file-java_test-class-L22 is jumping over the handler?

14:38 CookedGr1phon: I mean if we *can* get it fixed in clojure, it's certainly no worse, and there's an argument for it being better, especially if it matches javac

14:39 hiredman: oh yeah, ignore that then!

14:40 hiredman: CookedGr1phon: well, I am pretty sure it would involve adding support for something like java's sychronized blocks to the compiler, I don't think you'll want to try and check try/finallys for synchronize like blocks and generate the same bytecode

14:41 which means adding a special form, and then what do we do with the existing monitor-enter and exit forms, I dunno, I doubt anyone uses them directly

14:41 CookedGr1phon: hiredman: the docstring explicitly says not to use them...

14:42 I was surprised how few things even used locking tbh

14:43 hiredman: it might be easier/better to make it possible to mark functions as synchronized

14:43 CookedGr1phon: and then just make locking generate a function internally?

14:43 hiredman: (^:synchronized fn [] ...) and generate synchronized methods

14:43 CookedGr1phon: or just ignore locking

14:44 CookedGr1phon: I'm thinking for making existing code compatible with ART

14:44 but yeah, you wouldn't need locking in that case

14:46 anyway, I have to head home now, not really sure what the next step is to fixing this

14:47 might be worth moving this conversation to the mailing list

14:47 SagiCZ: can anyone explain me difference between ` ' ~ ?

14:49 amalloy: whenever i type them in that order i always feel like i'm executing a hadouken in street fighter, SagiCZ

14:49 SagiCZ: amalloy: yeah i dont necessarily mean to use that in that particular order :)

14:49 amalloy: just looking at the directions they go in. it's so perfect

14:50 but, briefly, ' quotes a subform, and ` also quotes a subform but allows ~ to suspend quoting

14:50 justin_smith: ' is a shorthand for wrapping the next thing in (quote ...), ` is known as quasiquote and is like quote but it resolves symbols to their namespace and allows for ~ (unquote) / ~@ (unquote splicing) which selectively unquote inside the form

14:50 amalloy: if you had to ask the question, this brief answer was probably not very helpful

14:50 justin_smith: or what amalloy said

14:50 SagiCZ: amalloy: no, it actually sounds good

14:50 thank you guys

14:51 justin_smith: ,`(a b c ~+)

14:51 clojurebot: (sandbox/a sandbox/b sandbox/c #<core$_PLUS_ clojure.core$_PLUS_@8b0bea>)

14:51 SagiCZ: ,'~`~',

14:51 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

14:51 SagiCZ: i thought so

14:51 :D

14:51 DerGuteMoritz: ,(let [a 1] `(a ~a))

14:51 clojurebot: (sandbox/a 1)

14:51 DerGuteMoritz: better example I guess!

14:52 SagiCZ: not too shabby, thank you

14:52 DerGuteMoritz: what's the deal here though:

14:52 ,```()

14:52 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/list))))

14:52 stuartsierra: Anyone having problems with clojars.org?

14:52 DerGuteMoritz: ` in clojure isn't actually like traditional quasiquote

14:52 Bronsa: stuartsierra: it doesn't load for me

14:53 DerGuteMoritz: it also plays a role in its macro hygiene system by fully qualifying symbols

14:53 Bronsa: stuartsierra: now it does, but I see an empty page

14:53 DerGuteMoritz: which probably also explains that weird expansion for quasiquoted quasiquotes

14:54 compare with quoted quote:

14:54 ,'''()

14:54 clojurebot: (quote (quote ()))

14:55 SagiCZ: DerGuteMoritz you just hit me with this when i thought i was starting to get it

14:55 :)

14:55 amalloy: DerGuteMoritz: the hygienic nature of ` isn't really what leads to the runaway explosion in the expansion of ````

14:56 DerGuteMoritz: SagiCZ: heh, well, you can safely ignore that, it's rarely necessary to quasiquote quasiquote and probably better to express it differently anyway in case you think you need it :-)

14:56 amalloy: oh, i guess you didn't really claim it did

14:56 DerGuteMoritz: amalloy: indeed, just the implementation of ` leaking through I guess!

14:57 amalloy: ,````````````x

14:57 clojurebot: #<StackOverflowError java.lang.StackOverflowError>

14:57 DerGuteMoritz: heh

14:57 this is also interesting:

14:57 ,''a

14:57 clojurebot: (quote a)

14:57 DerGuteMoritz: ,'`a

14:57 clojurebot: (quote sandbox/a)

14:58 DerGuteMoritz: so symbol qualification happens even inside quote

14:58 probably at read time?

14:58 amalloy: DerGuteMoritz: ` happens at read time, so it has no idea it's inside of a quote

14:58 DerGuteMoritz: right

14:58 well, a slightly shady corner!

15:08 SagiCZ: ,(clojure.pprint/pprint "hello")

15:08 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>

15:08 SagiCZ: why cant it find pprint<

15:08 ?

15:09 Bronsa: ,(require 'clojure.pprint)

15:09 clojurebot: nil

15:09 Bronsa: ,(clojure.pprint/pprint "foo")

15:09 clojurebot: "foo"\n

15:09 SagiCZ: :> this channel is 100x quicker than google .. thanks

15:19 zanes: Anyone have any insight into why so many functions were deprecated from the core.async API at once?

15:19 Just curious what the thinking was there.

15:21 Ah, I see: https://github.com/clojure/core.async/commit/4b06327455d993930a121db7ecfadc6359a23e95

15:22 Guess they’re coming back at some point.

15:24 bbloom: zanes: problem is that rich is working on master rather than a feature branch :-P

15:24 the master branch updates the docs automatically

15:24 zanes: bbloom: Got it.

15:57 stuartsierra: Who's running clojars.org these days?

16:00 numberten: is there a good rule of thumb for when to use threading macros?

16:00 like how many nested sexprs you should have?

16:00 imperman: stuartsierra: is it working now? see white page only

16:03 justin_smith: numberten: I don't understand that question

16:04 imperman: numberten: more a personal favor, I think

16:04 stuartsierra: imperman: same here

16:05 gill_: can confirm, clojars is returning bum route

16:05 numberten: if I have (f (g (h x))) I can rewrite it (-> x h g f), which seems to be idiomatic afaik

16:05 but what if I have (f (h x))

16:05 is that worth theading?

16:06 certainly using -> as identity isn't the thing to do >.>, so I guess my question was when is it no longer worth threading

16:06 bbloom: numberten: do what feels right

16:06 there's no hard rule

16:06 numberten: alright thanks

16:06 i had a feeling that was the answer

16:06 technomancy: stuartsierra, imperman: can't repro clojars issues; can you provide details?

16:06 gill_: stuartsierra: maybe phil? https://groups.google.com/forum/#!topic/clojars-maintainers/d8HNd-R4uw8

16:06 numberten: just wanted to be sure there wasn't a standardized informal rule

16:06 thanks :)

16:07 technomancy: is it a specific page? a 500 error?

16:07 BobSchack: technomancy: It's a 500 error for me

16:07 gill_: technomancy: it's a blank page

16:07 stuartsierra: technomancy: Getting a blank page on clojars.org/

16:07 gill_: like an empty route

16:07 BobSchack: NM I'm getting it now

16:07 bbloom: numberten: one other thing to consider is that -> reads imperatively: "do this then this then this", which may or may not be sway you one way or another when you're on the fence

16:08 stuartsierra: technomancy: Odd, suddenly now it works

16:08 bbloom: ie you want to emphasize sequencing or results

16:08 imperman: technomancy: oh, i'ts ok now. blank white bage before, mabe browser bug\

16:09 stuartsierra: I'm pretty sure I couldn't fetch dependencies from Clojars a couple of hours ago.

16:09 technomancy: hm; seems unlikely to be a connectivity issue if you're able to get an HTTP response back

16:10 stuartsierra: Oh well, maybe a false alarm. Sorry for the interruption if that's the case.

16:10 technomancy: only a single 500 in the logs for today

16:10 on an index out of bounds exception, which is probably a legit bug but also probably not what you're seeing

16:11 if you have headers I'd be interested in seeing them

16:12 stuartsierra: technomancy: Don't have headers from a failing request, I'm afraid.

16:12 technomancy: oh, if it was affecting dependency downloads it was probably an ngnix problem

16:12 the clojars app shouldn't get hit for static files

16:13 also it gives you a stack trace on 500s, not a blank page

16:13 amalloy: numberten: http://stackoverflow.com/questions/12715577/when-should-i-use-the-clojure-arrow-macro/12716708#12716708 is my opinion on how to use ->

16:15 imperman: technomancy: I tried only from a firefox and had a result like that: https://github.com/ato/clojars-web/issues/231

16:16 technomancy: white blank page. at now i'ts all right. in any case - thx for support :)

16:19 bbloom: dnolen_: is there a way to force the decoder to always return longs? would be useful for testing purposes to ensure i don't do anything stupid like try to use + and get back a string, heh

16:21 dnolen_: bbloom: well you won't get back a string I think you'll likely get a corrupted number (which is worse)

16:21 bbloom: at one point this was overrideable but the spec has since changed

16:21 bbloom: transit.reader("json").read('"~i9007199254740994"') + 10

16:21 "900719925474099410"

16:22 dnolen_: bbloom: huh, ok I guess goog.math.Long must return the string rep then, I though it didn't do that.

16:22 bbloom: I can bring it up w/ the powers that be.

16:22 s/though/thought

16:22 bbloom: dnolen_: it seems highly likely that i may overflow an int and start crashing :-P

16:23 also .add doesn't seem to work

16:23 x.toString()

16:23 "9007199254740994"

16:23 x.add(5).toString()

16:23 "9007199254740994"

16:24 dnolen_: are you using this from CLJS or JS?

16:24 bbloom: dnolen_: right now just experimenting in the console onn the transit tour page

16:24 x.multiply(2).toString()

16:24 "0"

16:25 dnolen_: bbloom: oh yeah probably not going to work, that page uses the advanced build and we don't guarantee anything about the underlying rep

16:25 from CLJS it should work

16:26 we may expose more functionality to JS users if there's interest

16:26 bbloom: ohhh

16:26 x.add(x) seems to work

16:26 i guess goog.Long expects anothe rlolng

16:26 just silently passes on non-longs

16:26 dnolen_: oh k

16:26 bbloom: presumably b/c it expects you to be using their type system at compile time...

16:26 dnolen_: yeah

16:37 SagiCZ: anybody has pdf or mobi of this book? http://www.braveclojure.com/

16:38 amalloy: SagiCZ: if you want to read it, buy it. it's not like they've made that hard

16:39 SagiCZ: 25 bucks?

16:39 amalloy: #clojure is the wrong place to ask for unauthorized copies of books by people in the clojure community

16:39 SagiCZ: got it

16:40 amalloy: SagiCZ: if it's not worth $25 to you, don't buy it

16:40 SagiCZ: $25 is not the same amount depending on where you live.. some people work 25 hours to get that.. some 10 minutes

16:40 technomancy: that doesn't justify copyright infringement

16:41 amalloy: i didn't say "$25 is nothing, you should buy it"

16:41 i said, if you're not willing to pay the price the authors are asking, then they won't give you a copy, and stealing one isn't the right reaction

16:41 arrdem: seems like you have an opportunity to write a cheaper book on clojure then...

16:41 technomancy: especially not when it involves using freenode's services to rip someone else off

16:41 SagiCZ: ok i dont think we need to discuss it anymore.. i get yall's point

16:41 arrdem: unless you just want to complain about the price in a single vendor market

16:42 technomancy: amalloy: nitpick: stealing is not the correct term for this, and it bugs me when people conflate the two.

16:42 (simply because it makes accurate discussion of copyright infringement murkier)

16:43 amalloy: also, http://www.braveclojure.com looks like you can read the whole thing for free online?

16:43 SagiCZ: 2amalloy: I know, exactly. so why should I pay for a different format, I don't get it.

16:43 amalloy: because they chose to give you one format for free, and not the other

16:44 SagiCZ: if i write a script that crawls the html and builds a pdf for my purposes, is that copyright infrigment?

16:44 amalloy: don't repay their generosity by doing something that technomancy prefers not to call stealing

16:44 lysergide___: Hi

16:44 technomancy: amalloy: you can call it "being a dick" if you like

16:44 aperiodic: $google price discrimination

16:44 lazybot: [Price discrimination - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Price_discrimination

16:45 lysergide___: I’m a beginner at clojure. Let’s say I wanna repeat a function roulette 100000000 times and apply a if to what is returned.

16:45 To do this I write.

16:45 (dotimes [n 100000000] ( if ( > (roulette) 50) (println "Catastrophe")))

16:45 Is there a better way to do this?

16:46 SagiCZ: (dotime [_ 100] (fun))

16:46 amalloy: technomancy: i can't support your campaign for a word less murky than "stealing" if the only alternative you can offer is so generic it applies to anything at all

16:46 technomancy: amalloy: the technical term is copyright infringement

16:46 SagiCZ: 2amalloy: answer my question please.. i wonder what you think about it

16:46 technomancy: but I know it doesn't roll off the tongue quite as nicely

16:47 SagiCZ: 2lysergide: (dotimes [_ 100] (fun))

16:47 amalloy: SagiCZ: i'm not a lawyer. my answer would have no value

16:47 SagiCZ: amalloy: It has a value for me. I care.

16:47 amalloy: also of course "answer my question please" rather rudely implies that you're somehow entitled to my answers

16:47 lysergide___: SagiCZ: Okay thank you very much ! basically you use « _ » to say that we don’t care about the « variable » ?

16:48 SagiCZ: amalloy: I am not and if saying "please" makes the whole thing rude pardon me. I am not native English speaker.

16:48 lysergide___: exactly.. its still a valid symbol as far as I know but its the idiomatic way to say that you will not use it

16:48 justin_smith: ,(do (repeatedly 10 (print "."))) another option, the do can be left out, it just makes the bot output more clear

16:49 clojurebot: #<NullPointerException java.lang.NullPointerException>

16:49 justin_smith: err

16:49 amalloy: justin_smith: ??????

16:49 llasram: I think you mean `dorun`

16:49 lysergide___: SagiCZ: It seems like it does not work..

16:49 llasram: Well, and a function

16:49 lysergide___: Oh yes it works.

16:49 amalloy: anyway, i'm not going to answer that question, SagiCZ. giving legal advice is not a good business to be in, as a software developer

16:49 justin_smith: llasram: oh, I thought repeatedly took a number like repeat does, I guess not

16:50 SagiCZ: amalloy: fair enough.. it was a hypothetical question of course

16:50 amalloy: it does, justin_smith

16:50 justin_smith: ,(do (repeatedly 10 #(print ".")))

16:50 clojurebot: (..nil .nil .nil .nil .nil ....)

16:50 justin_smith: but I misused the do, Ok

16:50 amalloy: justin_smith: that's lazy

16:50 hyPiRion: ,(do (repeatedly 10 #(print ".")) nil)

16:50 clojurebot: nil

16:51 justin_smith: ,,(dorun (repeatedly 10 #(print ".")))

16:51 clojurebot: ..........

16:51 justin_smith: finally

16:51 SagiCZ: ,(dotimes [_ 10] (println "."))

16:51 clojurebot: .\n.\n.\n.\n.\n.\n.\n.\n.\n.\n

16:51 lysergide___: Lazy sequence is a better solution, that’s what I am using with filter.

16:51 I just wanted to know If I had it right with dotimes

16:52 Laziness is why I love clojure.

16:52 Haskell too but Haskell takes too much time to be learnt

16:52 imo

16:52 llasram: Oh, BTW, hi everyone! Not that anyone missed me, but I am starting to be back from being totally burned out

16:52 SagiCZ: llasram: what happened to you?

16:52 hyPiRion: lysergide___: how much time does it take to learn Haskell?

16:52 llasram: SagiCZ: Just working too hard

16:52 technomancy: too many amps passing through your body?

16:53 aperiodic: llasram: good to hear!

16:53 seangrove: lysergide___: I don't know if that's good reasoning...

16:53 SagiCZ: llasram: welcome back then :)

16:53 hyPiRion: llasram: welcome back =) I know that feeling too

16:53 Zekka: Speaking as a Haskell programmer, it doesn't take as long to learn as people say but it can still take a while

16:54 lysergide___: Zekka: Well for example I wanted to create a simple game.

16:54 Zekka: to varying degrees of grok it took either a month, six months, or a year for me to understand it as well as I do now, but I could have written useful programs after the first month

16:54 lysergide___: I had to learn about the State monad

16:54 stuff like that

16:54 Zekka: Well, right, there's a sharp learning curve initially

16:55 lysergide___: It is a an interesting language but not sure it is worth the time to learn it

16:55 seangrove: Right

16:55 Zekka: A Haskell dogmatist would probably reply that the alternative of not making people learn about things like that is much worse than losing people in making them do that

16:55 seangrove: If you're going to be programming for years, probably shouldn't spend much time picking up new concepts

16:55 llasram: Zekka: How much of the sharpness do you think is just learning new tokens for familiar things, and how much foreign concepts?

16:56 Zekka: llasram: Mu.

16:56 SagiCZ: what I don't understand is why people say that Clojure is easy because it has easy syntax... yeah you only need to know THIS http://clojuredocs.org/quickref/Clojure%20Core to effectively use it.. wtf

16:56 llasram: ha

16:56 Zekka: A lot of the unfamiiar parts of Haskell are actually familiar things reified in a way you wouldn't expect

16:56 But learning how Haskell treats them is really hard sometimes

16:56 i.e. instead of globals you have Reader

16:57 so you still have the familiar concept of globals, but you have to understand them in terms of strategies for function composition

16:57 lysergide___: After doing some haskell clojure looks super easy

16:57 Zekka: And that last thing is the unfamiliar part

16:57 lysergide___: Because you already learnt the concepts

16:57 Zekka: Clojure is much more like the languages you've probably already worked with than Haskell is

16:57 arrdem: SagiCZ: counterpoint because clojuredocs is comparatively out of date.. http://grimoire.arrdem.com/

16:57 lysergide___: I find it greate that I can use Java’s libraries

16:57 Zekka: I don't personally like it as much but it's more of a taste judgment IMHO

16:58 lysergide___: I hate java’s syntax but the libraries are so great

16:58 boxed: zekka: clojure is a lot easier to ease into. Haskell is a lot of “all these things or you can’t do shit”… or at least that’s my experience from trying Real World Haskell and some online tutorials

16:58 SagiCZ: but java's syntax has 5 times less keywords..

16:58 Zekka: boxed: That's pretty accurate

16:59 you really need to understand the idea of offloading things to your data types before you can write neat code in it

16:59 and if you don't understand that it just feels like ugly, inflexible Scheme

16:59 boxed: but clojure is annoying in that every function potentiallt has it’s own syntax

16:59 SagiCZ: boxed: +1

17:00 Zekka: You actually get most of the semantics you want pretty easily once you understand that

17:00 technomancy: every form you mean?

17:00 Zekka: although a lot of people justifiably argue that in large programs State becomes pretty ugly

17:00 lysergide___: It is the power of clojure to have a lot of keywords.

17:00 technomancy: certainly not every function

17:00 SagiCZ: Zekka: are you talking about haskell or clojure

17:00 Zekka: SagiCZ: Haskell

17:00 SagiCZ: ok

17:01 hyPiRion: llasram: I'm just in the middle of Haskell learning atm. The immutability is rather easy due to Clojure nature. Type system was easy to comprehend, monads took some time to grok (not yet finished with the different monad types).

17:01 Zekka: I used 'Scheme' because it's a mostly-pure language that doesn't do a lot of the things Haskell does AFAIK in terms of offloading work to i.e. composition strategies

17:01 boxed: technomancy: probably… but to me as a nood the difference between “form” and “function” sounds like academic wankery and not a useful difference :P

17:01 Zekka: (when I say 'composition strategy' substitute 'monad', 'category', 'applicative', or 'arrow' based on personal preference and/or degree of knowledge)

17:01 SagiCZ: lysergide___: well they are not effectively keywords or reserved words.. just core functions or macros really.. but there is just too many of them and nobody tells you which of them necessary

17:01 arrdem: boxed: wat

17:01 Jaood: hyPiRion: are you going to write a monad tutorial?

17:01 hyPiRion: Jaood: I've written 5 already

17:01 technomancy: boxed: well, forms that aren't functions are pretty rare in good code

17:01 boxed: technomancy: well, the binding stuff for functions makes every function it’s own syntax

17:01 Jaood: ;)

17:01 llasram: hyPiRion: Cool. I'm thinking of tackling a project where I don't need the JVM, and was considering using it as an excuse to actually learn Haskell. Or maybe OCaml

17:02 technomancy: that is, unfamiliar forms

17:02 Zekka: IMHO Haskell is totally worth learning and it's a really easy language to write good code in once you get used to it

17:02 lysergide___: SagiCZ: Well I agree with you, and you need to pick up many different books to get Clojure.

17:02 technomancy: llasram: doooo eeeet

17:02 llasram: he

17:02 heh even

17:02 lysergide___: Every tutotial is incomplete

17:02 Zekka: it kind of makes me sad that it doesn't have more useerbase

17:02 lysergide___: Ocaml syntax is the worst aha

17:02 benkay: does anyone else suffer from the JVM falling over during uberjar compilation on aws t1 micros?

17:03 technomancy: lysergide___: the precedence rules are a train wreck, but I found "just add parens till it compiles" helped with that

17:03 Zekka: Of course you have to get used to the fact that it will train you to casually say things that make no sense to all your friends who don't know it already

17:04 someone was quoting the old "monads are monoids in the domain of endofunctors joke" and I tried to explain what it actually meant, and may have accidentally fried his brain instead

17:04 hyPiRion: or that lenses are costate comonad coalgebras?

17:06 Zekka: hyPiRion: I don't think a lot of people on the outside know about lenses.

17:06 Hodapp: Zekka: Yeah, I tried to explain Haskell to a contractor once and ended up making him lose his job instead.

17:06 oh wel.

17:07 systemfault: hahaha

17:07 Hodapp: that's only partially a joke.

17:07 Zekka: What's the whole story?

17:08 Mine pretty much tells itself: I explained it in a straightforward fashion using lots of big words that he didn't know and things got worse every time I tried to define them

17:08 Hodapp: we also had some co-ops (20something college kids in the engineering & comp sci program) that I explained Haskell to, and they found it fascinating.

17:08 they were much more receptive to new ideas.

17:09 I use the term 'new' sometimes a bit jokingly, because sometimes the newest ideas to get through a person's head are some quite old ideas.

17:09 Zekka: I have a few friends who are writing haskell code at my recommendation but for some reason they're having trouble getting much expressivity out of it

17:10 they seem allergic to the idea of offloading design details to types

17:10 gfixler: Zekka: it's difficult - I'm struggling with kinds at the moment

17:10 Zekka: i.e. manual reinvention of State, but occasionally writing Reader instead just by accident, and having to wite tons of code to glue everything together

17:10 Hodapp: This fellow mostly just insisted that if it couldn't be expressed in C++ cleanly, you were doing it wrong.

17:10 gfixler: (thought I was in #haskell for a minute there)

17:11 Zekka: gfixler: Yeah, I remember you from earlier!

17:11 systemfault: Haskell is hard. Took me two weeks of reading to be able to do simple things :(

17:11 justin_smith: benkay: any reason you need to create the uberjar on the micro? why not a more powerful machine dedicated to doing the builds?

17:11 Zekka: Hodapp: Did you write everything in TMP instead then?

17:11 gfixler: I'm new to freenode - loving it (#git, #haskell, #vim, #clojure)

17:12 zanes: What’s the right way to terminate any running go routines when working in the REPL?

17:13 Hodapp: gfixler: you'll find some channels you don't like :P

17:13 Zekka: IIRC I had very bad experiences with #emacs at least

17:13 and #cobol is kind of dead

17:13 amalloy: #emacs is pretty cool. it's just mostly not about emacs

17:14 arrdem: #emacs is the best offtopic I know of

17:14 Zekka: amalloy: Really? They shouted me down three or four times for reasons of "Read the fucking source!" after I had already read the fucking source and found the apparent bug causing my woes

17:14 (my question was basically "is this a config issue or a bug?")

17:15 hiredman: amalloy: it's just that no one can be told what emacs is, you have to see it for yourself

17:15 lysergide___: Emacs sucks hard.

17:15 Hodapp: Try asking a conceptual question sometime in #java.

17:15 imperman: emacs editor at all is not about editor but about "have time with it" ;)

17:15 amalloy: hah. so when i think #emacs is off topic, it's really just evidence that i don't truly understand emacs

17:15 Hodapp: I've found that folks here and in #haskell, for instance, have no problem with conceptual questions.

17:15 in #java they flip their shit.

17:15 Zekka: Hodapp: Last time I did that they just redefined my problem domain until I quit

17:16 Hodapp: Zekka: I don't understand, could you give a test case?

17:16 imperman: lighttable is pretty cool nowadays

17:16 justin_smith: Hodapp: or ask a posix centric (or sometimes even a stack architecture centric) question in ##c

17:16 hiredman: it is an osmosis learning lab

17:16 Hodapp: justin_smith: or do anything else there o_O

17:16 justin_smith: heh

17:16 Hodapp: god, what a channel of assholes and drunken idiots

17:16 gfixler: Hodapp: no worries - there are something like 30 #haskell-* groups to try out :)

17:17 Zekka: Hodapp: Let's see: the gist was "I want to define a type which can always be constructed based on two numbers." (so I can parameterize another type over it and guarantee my code still works)

17:17 They responded with a bunch of flavors of "what if you want to construct it based on a *STRING*?!" though, and explained that I really wanted the factory pattern

17:17 mdrogalis: Oh man, I really want to hop in #java and ask a conceptual question now D:

17:18 amalloy: guys, complaining about or insulting other freenode channels is just not productive

17:18 Zekka: never mind that if I went with the factory pattern I would have exactly the same problem as if I were able to put the constructor in the interface!

17:18 amalloy: if you don't like ##java or whatever, don't go there

17:18 mdrogalis: amalloy: Yeeeeah but its fun D:

17:18 gfixler: #haskell is great for conceptual questions, but you must brace yourself for a torrent of responses

17:19 tbaldrid_: it all started when when somebody mentioned haskell, we should just ignore that it exists and then we won't have rant sessions in #clojure anymore

17:19 Hodapp: gfixler: oh, I got a torrent of responses in #java, but they were mostly "Test case, or GTFO."

17:19 Zekka: Sorry: hope I'm wrecking no one's day

17:19 (and that's not an attempt to be snide or flippant)

17:19 Hodapp: amalloy: Why is "don't go there" the only valid choice?

17:20 gfixler: Now I want to create a table of responses to various kinds of queries for each group

17:20 mdrogalis: Zekka: Entire day. Ruined. D:

17:20 gfixler: I love #clojure, but it's very tied to Java, and so are a huge portion of the people using it

17:20 Hodapp: amalloy: And actually, if I convince even one person to not go there and have their time wasted, it in fact _is_ productive.

17:21 gfixler: percentagewise, I think java programmers outnumber all other kinds

17:21 I've really never used Java, and I'm not a big fan of OO anymore (did my 10 years of fighting that monster)

17:21 Zekka: I'm working in Clojure specifically as a part of working in Java, so I'm one of those

17:21 gfixler: but when I come into #clojure often, it feels like there's a lot of java-y stuff being discussed (which makes sense)

17:21 amalloy: there are lots of valid choices, Hodapp. construct an altar in your closet to some dark gods and call down their wrath on ##java or whatever, for all i care. just don't clutter up #clojure with complaints - they don't make anyone happier

17:21 Zekka: our app is largely Java with significant Clojure parts, but if push came to shove we would generally use more Java over more Clojure

17:22 Hodapp: amalloy: If you don't care, then why are you cluttering up #clojure with complaints?

17:22 hyPiRion: Hodapp: He didn't say he didn't care though, he just said he didn't mind you setting up an altar

17:22 amalloy: i'm trying to keep #clojure on-topic, constructive, and friendly

17:23 Hodapp: gfixler: yeah, I am definitely over using OO as the default, go-to method for attacking problems.

17:23 gfixler: I see amalloy in here constantly, always helping out and furthering discussions (not that amalloy needs defending)

17:24 Zekka: Hodapp: Although I think the goals of OO are pretty cool

17:24 Hodapp: Zekka: the goals and the original work are quite interesting

17:24 imperman: amalloy: +1, I'ts better to create some #clojure-flame for other purposes

17:24 rurumate: I need a fn that takes as input two arbitrary functions f and g, and returns (fn [x y] (and (f x) (g y))

17:24 amalloy: is clojerks still around?

17:24 mdrogalis: amalloy: Ahaha, what's that?

17:24 Hodapp: Zekka: ever read some of Alan Kay's work, or the "Programming as experience" paper on the Self language?

17:25 amalloy: rurumate: you're almost there! just write one more right-paren, and you'll have written the function you wanted!

17:25 Zekka: Hodapp: I don't think so: I've read some of Kay's interviews but I don't think I've read any essays/books by him

17:25 rurumate: amalloy: yes, but it's not variadic yet, like and

17:25 Zekka: rurumate: Well, how do you want to make it variadic?

17:25 amalloy: huh? you said the number two, your example has exactly two things

17:26 rurumate: also, I need this operation for or. it's getting tedious, this seems to be a general thing to do

17:26 Zekka: Do you want to alternate applications of f and g to the list of args?

17:26 amalloy: what function are you actually trying to write, if two is not what you want

17:26 Zekka: Do you want to take a variable number of functions and result in a function that takes that many args?

17:27 rurumate: I want something for two at this moment, but when I start using it I'm gonna need 3-arg version too

17:27 gfixler: rurumate: we're all wondering where f and g are coming from

17:27 amalloy: but what does the three-argument version *do*? your example is too specific to exactly two args; it's not clear in what direction you hope for it to generalize

17:27 Zekka: He already said

17:28 (fn [f g] (fn [x y] (and (f x) (g y))))

17:28 amalloy: which is what Zekka is asking

17:28 Zekka: He wants to generalize this pattern

17:28 At least I think that's what he wants

17:28 rurumate: yes Zekka

17:28 hyPiRion: rurumate: If you decide f and x, then (fn [& fns] (fn [& args] (every? true? (map #(%1 %2) fns args)))) takes a list of functions and returns that function you wanted (sans checking correct amount of input vars)

17:28 Zekka: it seems to me like your answer lies in the domain of map and apply

17:29 amalloy: sure. but do you N functions and M args? N functions and two args? N functions and N args? two functions and N args?

17:29 rurumate: yes, soemthing like map

17:29 hyPiRion: f and g*

17:30 rurumate: yes, I want more arguments than just the two of f and g

17:31 gfixler: rurumate: do you want to pass pass in functions and get back a function that takes arguments, or vice versa, or pass in all the functions and arguments at once and get back a result?

17:32 rurumate: I just want and to "work as expected" on fns

17:32 justin_smith: amalloy: mdrogalis: if you mean clojerks as in the portland, or clojure meetup group, yeah, we still meet (though some think the name should change)

17:32 amalloy: justin_smith: really i couldn't remember what clojerks actually was, the name just sounded appropriate

17:33 justin_smith: heh

17:33 rurumate: something like creating new predicates from existing ones, by ANDing them

17:34 think of f and g as predicates or truth functions

17:35 that should be EASY, but it's a lot of work with standard clojure

17:35 Zekka: I think hyPiRion's looks pretty simple and correct

17:36 zoldar: Hi. Is anyone able to use om 0.6.4 (or any post 0.5.0 for that matter) along with austin repl? there seems to be conflict in requirements for a particular clojurescript version.

17:36 rurumate: it's not obviously correct. there should be something more accessible

17:36 Zekka: with the exception that I think you can use 'and' instead of 'every? true?''

17:36 Well, wait, I don't think you can use and without 'apply'

17:36 rurumate: I'm not sure how you would simplify it

17:37 rurumate: ok then

17:37 technomancy: amalloy: it's where you go to complain about jira to keep this channel positive

17:37 Zekka: I'm not a Clojure expert, of course

17:37 rurumate: but this is basic stuff, it should be in some standard library at least.. no fun writing it over and over everywhere

17:37 hyPiRion: rurumate: so you want something more evident, is that it?

17:37 rurumate: I just want that stuff to "already exist"

17:37 hyPiRion: ah

17:38 rurumate: it's kina low level

17:38 amalloy: rurumate: what you're asking for is clojure.core/every-pred, except that as i said it's not clear what the relation between x/y and f/g is once you go beyond two args each. if you want pairwise correspondence, then fine, that's what hyPiRion did

17:38 Zekka: I'm tempted to write out the Haskell definition here because in Haskell at least it's one of those functions that looks too small to factor out

17:38 rurumate: amalloy: cheers

17:38 Zekka: but this isn't really a Haskell channel

17:39 amalloy: Zekka: sure, it's even easier in haskell, of course

17:39 Zekka: amalloy: Although not very safe.

17:39 amalloy: and $ zipWith ($) fs xs -- right?

17:39 Zekka: it's as safe as the Clojure version but you would expect it to be safer

17:39 amalloy: Yeah, with optional point-free

17:40 amalloy: oh, sure

17:40 nice. so just: and . zipWith ($)

17:40 or...not quite. ugh. composing functions with more than one arg always trips me up

17:40 Zekka: I think it's actually nontrivial to get rid of the fs, let me check with lambdabot

17:40 I think it ma be (and .) . (zipWith ($)) but I'm not sure

17:41 Yeah, it is, although you probably s houldn't write it that way

17:41 just eta out the xs and leave the fs alone

17:43 amalloy: A lot of people take pointlessness far too far. It's a bad habit!

17:43 technomancy: just maximize your juxt usage and you should be good

17:44 Zekka: If you really like writing pointless code, switch to Java.

17:46 nullptr: If you really like pointless tools writing pointless code for you, switch to Java.

17:46 rurumate: amalloy: yes there was a mistake in my original expression, there should be no y but only x

17:47 amalloy: AUGH. and you couldn't say that after the many requests to clarify? the whole time the function you wanted was just every-pred

17:47 rurumate: sorry, I meant (fn [x] (and (f x) (g x)))

17:47 yes

17:48 hyPiRion: oh well, at least it's sorted out

17:48 cespare: How can I read a file to a byte[]?

17:48 amalloy: well, at least the question got answered. five points from rurumate for obstinacy and a few from hyPiRion and Zekka for answering an unclear question nistead of getting it clarified

17:48 hyPiRion: horray!

17:49 Zekka: Pretty sure the word was 'from'

17:49 so technically we should be upset

17:50 amalloy: Strangely enough, someone had a near-identical problem in #haskell earlier this morning, and once again they were asking for something other than what they wanted

17:50 rurumate: Zekka: b-but clojure was written in javaD

17:51 hyPiRion: Zekka: I consider that as a compliment from amalloy.

17:51 Zekka: (they actually wanted folds)

17:51 amalloy: Zekka: new game idea: ask a vague question in one irc channel. take the answer, and ask it as a new question in the irc channel for a different language

17:51 rurumate: should we not be thankful for the world class garbage collection that the jvm provides?

17:52 systemfault: Java is fine… haters gonna hate.

17:52 technomancy: amalloy: you're really taking this "freenode as a distributed multiplayer text adventure puzzle game" thing to its logical conclusion.

17:52 hyPiRion: rurumate: I'm actually not sure if you refer to the garbage collector or the collection of garbage that the jvm provides.

17:52 brehaut: z-machine as implemented by IRC users

17:53 ghadishayban: https://twitter.com/shipilev/status/491610175284183040

17:53 amalloy: (inc hyPiRion)

17:53 lazybot: ⇒ 39

17:53 rurumate: java is so cool. they have lucene. and storm

17:53 hiredman: ghadishayban: heh

17:54 technomancy: "I've seen things you people wouldn't believe ..."

17:54 hiredman: I use emacs on Compiler.java all the time

17:55 Zekka: cespare: Slurp gets you a string, I'm not sure how to get a byte[] right offhand, though

17:55 let me do a little googling

17:55 amalloy: ghadishayban: that tweet alerted me to the use of //*/ in Compiler.java, which i had never noticed before

17:55 cespare: Zekka: found a fairly crappy looking function on SO that nevertheless works, and I only need this for checking something in a repl real quick, so I'm good.

17:55 thanks

17:55 amalloy: what an interesting solution to the self-imposed problem of "i have no idea if my file contains comments"

17:56 Zekka: cespare: *Should* be dead easy -- I'm surprised if it's not

17:56 hiredman: what does //*/ do?

17:56 gtrak: whoa

17:57 amalloy: hiredman: it's a lexer trick: "if i'm inside a /* block already, then close it; otherwise, do nothing"

17:57 gtrak: it comments the comment

17:57 cespare: Zekka: writing using clojure.io.java/output-stream is certainly dead-easy. The inverse is harder because you have to bring your own buffer for the .read call, so I think a loop a required to do it properly.

17:57 hiredman: amalloy: pffft

17:57 jesus

17:58 ghadishayban: that's awesome

17:58 hiredman: man's machine mediated inhumanity to man

18:02 amalloy: hiredman: introduced via https://github.com/clojure/clojure/commit/2c57f4b5cbb5608905f45cccad3958de51c62590#diff-1, which is practically performance art

18:03 hyPiRion: I'm glad it's not normal to allow nested comments.

18:03 technomancy: if you're stuck writing java, the least you can do is make it an art form

18:04 (says the guy who has never written java)

18:04 amalloy: technomancy: that would explain the creative indentation in clojure/lang

18:04 hoverbear: technomancy: And good on you

18:05 technomancy: I have led a sheltered life.

18:05 Zekka: technomancy: Personal experience has been that it introduces a ton of "right way"/"sane way" tradeoffs

18:05 technomancy: probably couldn't hack it on the streets

18:05 Zekka: where conceptualizing a problem the Java way requires you to lose flexibility and neatness

18:06 so it's actually a really hard language to write well IMHO

18:06 gfixler: we used to call the /*/ stuff "tie-fighter comments"

18:06 hoverbear: gfixler: Insulting to tie-fighters

18:06 technomancy: Zekka: I've heard others say it's the opposite, because it forces you to give up on producing good code. You know from the outset that what you produce will be mediocre.

18:08 gfixler: hoverbear: well, such language was common in the Rebellion - it was a different time

18:08 I don't like java itself, but I like how much thinking has sprung up because of java

18:08 java seems really hard to write, so a lot of really strong tooling and thinking has come out of it

18:09 all of the TDD, refactoring, clean coding, design patterns stuff seems to swell from java springs

18:09 hyPiRion: gfixler: oh, that made me realise why Go has such good tooling

18:09 gfixler: haha

18:09 I grabbed a copy of Head First Design Patterns, and sighed when I realized it was all Java examples

18:10 and then learned that other languages don't need many/most of the design patterns

18:10 systemfault: Because Java is the “classic” OOP language.

18:10 gfixler: many of them mitigate all-oo, all-the-time issues

18:11 the examples had lines like WeatherStation weatherStation = new WeatherStation (weatherstation, alsoweatherstation)

18:11 and I was like "How does anyone do anything in this language?"

18:11 hoverbear: I've been growingly interested in Rust lately.

18:11 No OO junk

18:11 gfixler: I think it was Bob Martin who showed an example of some code he converted from Java to Ruby

18:11 it was 7x smaller

18:11 the difference between a screen of code and 7 screens of code is big

18:12 hoverbear: Huge

18:12 gfixler: not that tiny is always great

18:12 technomancy: a systems language written by someone who has actually researched the existing landscape before designing their own? how novel! =)

18:12 Zekka: Some of my pals who used to write tons of low-level code are huge Rust fans

18:12 systemfault: 10 times slower and 2 times less reliable :P

18:12 gfixler: I can't figure out what is going on with J examples posted to /r/dailyprogramming, e.g.

18:12 Zekka: so I'd say based on their appraisals that it's probably pretty cool

18:12 hoverbear: technomancy: Someones!

18:12 Zekka: gfixler: J's an APL relative, right?

18:12 gfixler: that's why I'm loving Clojure and Haskell - much more expressive

18:12 hyPiRion: Zekka: yes. It's like APL without the greek characters

18:12 gfixler: Zekka: I think so, but I'm not convinced it really exists, and that I'm not being trolled

18:12 hoverbear: gfixler: I like haskell but I find Cabal is huge let down

18:13 Zekka: One of my friends actually works in APL: he's a huge fan of it

18:13 gfixler: hoverbear: that's what I'm hearing; haven't experienced it yet personally

18:13 also, I have some first-hand experience now of what happens when you move away from OO

18:13 Zekka: I've gotten the rough impression that it's tied really closely to the problem domain ("manipulate matrices or go home") but I haven't worked in it

18:13 gfixler: 11 classes shrinking down to none, and then turning into some functions and a couple of maps

18:13 and seeing orders of magnitude more/less everything in positive ways

18:14 hoverbear: gfixler: Lein, comparatively, is frigging brilliant. ( technomancy )

18:14 gfixler: actually finishing tricky things, implementing 3 new tricky things in a few hours, unexpectedly

18:14 tons of reuse

18:14 actual reuse, it's amazing

18:15 hoverbear: I'm using Lein in very tiny ways; I need further investigation

18:15 does it download and install dependencies for you? (it seems so)

18:15 hoverbear: gfixler: Yeah, automatically. Plugins too.

18:16 gfixler: I just finished up about 2 years of deep-diving into dependencies and DAGs

18:16 they've been in my face for more than a decade in my job, and I've always fought them

18:16 hoverbear: I love not having to do some stupid stuff like `npm install` or `bundle install` (Heaven forbid I have to code in Ruby, frick)

18:16 gfixler: they're in everyone's face

18:16 many don't know it

18:16 now I have crazy ideas about how I wish it all worked

18:17 things like - nothing should be able to import from above itself

18:17 hoverbear: I'm really interested in seeing how Cargo (Rust's package manager) turns out... It's made by the folks who made bundler... So I'm not expecting much

18:17 gfixler: I don't like dependencies traveling upward

18:17 that means no PATH, which is completely nuts

18:17 the dependencies we never have problems with are the things directly in our project trees

18:18 technomancy: hoverbear: yeah that was pretty discouraging to hear

18:18 gfixler: the end game there is that everything becomes a member of a project

18:18 hoverbear: gfixler: We've got some Ruby code running on 1.9.3... It took one of our coders over 3 months to update to 1.9.3 from 1.9.2

18:18 gfixler: that's the logical extreme - no dependencies, everything local

18:18 hoverbear: technomancy: They should have got you :)

18:18 * technomancy literally spent two hours last night in an outage caused by bundler ignoring the version I had specified and using whatever was on disk instead

18:18 gfixler: of course, we don't want to copy everything from everywhere, so we use symlinks for files and directories

18:18 hoverbear: technomancy: If it's any consolation, Cargo doesn't support versions yet.

18:19 technomancy: hoverbear: yeah, that was a huge "doesn't understand the problem" red flag

18:19 "because things are changing quickly, there is no way to lock to a specific version"

18:19 Zekka: hoverbear: Developers wouldn't break compatibility!

18:19 gfixler: also, I don't really love tags and releases

18:19 Zekka: That'd be terribly impolite!

18:19 technomancy: um... hello? quick change is exactly when you need locking to specific versions the most.

18:19 hyPiRion: hoverbear: well, that sounds like the Golang way

18:19 hoverbear: technomancy: Well I understand the reasoning. Most Rust projects right now won't compile on a compiler from last week anyways.

18:19 gfixler: this is a murkier area, but if we had a gitOS, everything could be a unique thing in the universe

18:20 hoverbear: gfixler: nixOS

18:20 technomancy: hyPiRion: rust had such a great track record of avoiding the foolish design mistakes of google go up to that point

18:20 gfixler: if you needed a dependency, you'd pull the entire project

18:20 hoverbear: technomancy: Remember, Cargo isn't done, hell it's not even beta.

18:20 gfixler: there would be some place for all git(-like) repos

18:20 and everything would refer to things in submodule fashion

18:20 technomancy: hoverbear: you can't retroactively apply a DTRT mindset in things like that

18:21 hoverbear: technomancy: DTRT?

18:21 gfixler: but, the gitOS would check things out internally to a project

18:21 technomancy: people *still* put "version X or greater" in their gem declarations and it's been known for the better part of a decade how harmful that is

18:21 hoverbear: Do The Right Thing

18:21 gfixler: so /gitos/proj/<hash>/

18:21 and then your project would symlink that in

18:21 and another could symlink in /gitos/proj/<hash2>/

18:21 technomancy: if you can't bother to get it right at the start, there's not a lot of hope

18:21 hoverbear: technomancy: Yeah. The only reason they released Cargo when they did is because it became as capable as `Cargo-lite`

18:22 gfixler: if 3 prjects need to symlink the same thing, they symlink the same checkout

18:22 gitOS would handle this internally

18:22 hoverbear: technomancy: I have high hopes, but I suspect Cargo will languish.

18:22 hyPiRion: technomancy: I get this feeling that every single language must have at least one wart

18:22 gfixler: also, anything that's the same between two checkouts would be symlinked

18:22 or hard linked

18:22 hard links would allow reference counting

18:23 technomancy: hyPiRion: at least it helps me justify the fact that I'm not paying attention to rust when it seems promising in most other aspects

18:23 not having persistent data structures is a pretty big hindrance though

18:23 gfixler: there are some weird benefits - there could be hash trackers online that track hashes to projects

18:23 hoverbear: technomancy: What do you mean?

18:24 gfixler: so if you need a particular commit, it could figure out from a tracker which project that is and pull the whole thing into the gitOS, check out that one into that project, and symlink it in

18:25 I also want this at the langauge level, somehow

18:25 amalloy: gfixler: i honestly can't tell if you're describing a utopia or a dystopia

18:25 gfixler: amalloy: me either

18:25 amalloy: i'm pretty sure it's not in the middle, though

18:25 hoverbear: dystopia

18:26 amalloy: it sounds that way to me, hoverbear, but he sounds so enthusiastic

18:26 gfixler: amalloy: it's a thought exercise

18:26 hoverbear: I shudder in horror at the thought of Git integrated into my OS

18:26 gfixler: hoverbear: I don't literally mean git, but something with that beautiful data model

18:27 hoverbear: gfixler: Look at nixOS, seriously.

18:27 gfixler: hoverbear: I thought you made that up

18:27 hyPiRion: technomancy: yeah, that was the one big issue I have with it. I found it hard to implement them myself last time I tried too.

18:27 hoverbear: hyPiRion: In Rust?

18:28 hyPiRion: hoverbear: yup (persistent data structures)

18:28 hoverbear: hyPiRion: When abouts was this?

18:29 hyPiRion: hoverbear: this was a long time ago, last year sometime

18:30 hoverbear: hyPiRion: The language is very, very different now

18:30 technomancy: even though I know ocaml will probably not have as bright of a future as rust, at least it has persistent data structures

18:30 and way better type inference

18:30 hoverbear: technomancy: You realize they use the same algorithm yeah?

18:30 technomancy: hoverbear: from the examples I've seen, rust needs a lot more spoon-feeding

18:30 hoverbear: technomancy: It does. :)

18:31 technomancy: They've improving it quite a bit.

18:31 gfixler: hoverbear: nixOS looks pretty impressive

18:31 hoverbear: A patch that landed Sunday night removed like 60% of lifetime annotations

18:31 gfixler: Looks cool to me

18:32 technomancy: hoverbear: rust certainly has much more low-hanging fruit and easy fixes ahead of it =)

18:33 hoverbear: technomancy: I agree. I think it has some great potential, though.

18:33 I certainly like the ideas it's touting.

18:33 technomancy: hoverbear: I agree, and I'm glad if it takes off

18:33 especially if it means fewer people writing C and google go

18:34 hoverbear: Exactly

18:34 I'd rather see Rust then C.

18:34 technomancy: I've heard there's potential for it to be used in microcontrollers

18:34 brehaut: high bar

18:34 technomancy: which would make me pretty happy

18:35 hoverbear: technomancy: I was playing with that actually, really cool. I like how you can use it without the stdlib

18:35 technomancy: I'm interested in using it for init

18:36 technomancy: wait, have you got it running on a microcontroller? arm or what?

18:36 mirf: don't speak

18:36 I know

18:36 just wjut yur sayin

18:36 9don't (say it) cos it hurts)

18:36 hyPiRion: hoverbear: Looks like there's potential in the persistent data structure land. Not sure how transients work out, but I think it's possible with unsafe.

18:37 mirf: hi crank1988

18:37 hoverbear: technomancy: You can use it on an Arduino Due

18:37 I don't have a Due, though.

18:37 technomancy: hoverbear: that's arm?

18:37 hoverbear: technomancy: ATMega

18:37 technomancy: huh

18:37 hoverbear: it says here it's an atmel cortex m3

18:38 aperiodic: hoverbear, technomancy: no, the Due is an ARM board

18:38 technomancy: I've got a cortex m4 board in my closet

18:38 hoverbear: technomancy: Whoops, yeah, Due is ARM, sorry. I have an ATMega

18:38 * technomancy ponders rewriting his keyboard firmware

18:38 mirf: due or die

18:38 it's all the same

18:39 technomancy: hoverbear: is this still a "you need to be a rust expert to get it to compile" stage?

18:39 for a uc specificaly

18:40 hoverbear: technomancy: You'll want to be on the #rust irc channel, but you don't need ot be an expert

18:40 technomancy: super tempting!

18:40 hoverbear: technomancy: I'd be happy to work with you on it

18:41 (For those wondering what Rust looks like doing simple tasks: https://github.com/hoverbear/rust-rosetta )

18:41 justin_smith: technomancy: just think how much better your keyboard could be with a 64 core coprocessor attached http://www.parallella.org/board/

18:41 technomancy: justin_smith: I was toying with the idea of building one around a 100MHz sparc core board with an onboard GPS receiver that I kickstarted

18:41 hoverbear: technomancy: Type by moving the keyboard?

18:42 technomancy: hehe

18:42 https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver too bad the toolchain is a hopeless mess

18:43 hoverbear: technomancy: Rust has actually been splitting their stdlib into "std" and "core"... Core will run freestanding.

18:44 technomancy: "The current version supports only static memory allocation and no stack pointer safety checks." hmm... sounds pretty raw

18:45 OTOH keyboard firmware doesn't need malloc

18:45 hoverbear: technomancy: Just started happening like 1 or 2 weeks ago

18:48 technomancy: hm; the thing is if I switch to ARM I was going to pick back up on my forth implementation

18:48 since then I'd get a repl for free

18:56 justin_smith: I'm amazed there isn't a tiny forth for arm already

18:56 technomancy: justin_smith: there are a few for arm. there's only one for avr, and I can't really use it because of reasons.

18:56 hiredman: arm isn't low end enough to interest people who write forth

18:57 justin_smith: or ubiquitous enough (x86)

18:58 Frozenlock: "Ran 5 tests containing 3 assertions." Uh.... I should have many more assertions than this. Has anyone had experiences with tests ignoring assertions? What was causing it?

18:59 amalloy: Frozenlock: bet you a nickel you're doing something lazy, like (for [x xs] (is (zero? x)))

18:59 Frozenlock: No, unless the lazyness is hidden deep within my code.

19:03 amalloy: well, my attempt to telepathically hack into your mind and guess what your code is has failed, Frozenlock. so you'll need to ask something more specific than "tests don't run"

19:04 Frozenlock: I know. I'm staring at the screen trying to figure out what might be good info.

19:05 justin_smith: Frozenlock: first you could verify whether all the test namespaces are loaded

19:06 Frozenlock: justin_smith: I'm not testing all the namespaces, just one in the repl. Calling the test directly or using run-tests doesn't work.

19:06 https://www.refheap.com/88475

19:06 justin_smith: and you have loaded the latest version of the test ns?

19:06 Frozenlock: Yes. Closed the jvm, started it again...

19:07 Err the grammar fail in that paste.

19:07 justin_smith: and how are you requiring the test ns?

19:08 is there a chance the test ns has the same name as some other ns?

19:08 Frozenlock: ctrl-c alt-k

19:08 I doubt it, but I'll look.

19:09 Well, at least this fails (deftest dummy-test (is (= 1 0)))

19:09 technomancy: when in doubt, bisect

19:12 Frozenlock: Oh I think I found it. Wait for it....

19:12 justin_smith: waiting...

19:12 Frozenlock: Ah no, still nothing :-(

19:12 I should write tests for my tests.

19:14 justin_smith: take a point of failure out, what happens when you manually run lein test rather than relying on editor tooling?

19:23 bbloom: does anybody know if the extra colon in the protocols in the URIs for datomic's connect function are a "thing" or just something datomic made up? http://docs.datomic.com/clojure/index.html#datomic.api/connect

19:23 Frozenlock: Ok, it seems I have a NullPointerException somewhere. Good to know that an exception isn't enough to make a test fails.

19:23 bbloom: i've never seen "sub-protocols" in uris or whatever

19:23 amalloy: bbloom: jdbc uses subprotocols for its connections

19:23 Frozenlock: *make it fail even

19:23 amalloy: jdbc:postgres:whatever or something

19:24 bbloom: amalloy: crazy, since java.net.URI doesn't parse them...

19:24 treats them as "protocolSpecificPart"

19:24 amalloy: well, that's what they are

19:25 Jabberz: so organization of compojure routes -- do you group them all together in a single handler ns, or break them apart into separate ns's for collection of logical routes for different pages/capabilities

19:25 bbloom: i guess so, but there's no method to get parse out the sub protocol specifically or to get the full protocol w/ subprotocol

19:25 amalloy: java.net.URI doesn't know about the datomic: protocol, so all it can say is "it's a URI whose scheme is datomic, and then some more stuff i don't understand, maybe ask someone who knows about datomic"

19:25 bbloom: huh? just take out the protocol-specific part, which will be like "riak://whatever", and parse that as a uri

19:26 bbloom: amalloy: ah, i guess that makes sense

19:32 * Frozenlock realizes there's a try/catch in is db test environment.

19:32 * Frozenlock crawls in a hole, never to be seen again.

19:37 justin_smith: Jabberz: I have often used a pseudo mvc thing, where there is an ns for each "controller", and each route is an "action" defined by that controller

19:37 and a set of routes are handled by a given controller and its actions

19:38 (technically I wasn't using compojure for this, but the concept is general enough to apply across routing libraries here)

19:45 Jabberz: justin_smith: ah yeah, i think that's where the compojure-app template kinda leads you to too

19:52 so for webapp auth solutions -- is lib-noir or friend preferred these days? looks like friend is the most popular/maintained?

19:53 justin_smith: yeah, I think lib-noir is much less popular

20:08 amalloy: is lib-noir even an auth solution?

20:11 xcthulhu: No, it’s not

20:11 You are probably going to have to break your mind with friend

20:12 GL

20:12 friend != simple made easy

20:13 Jabberz: yeah i meant more in terms of gluing things together with lib-noir session handling, but don't really want to go down that road

20:13 is there another alternative?

20:13 xcthulhu: Well, this is the modern auth middleware https://github.com/cemerick/friend

20:13 Jaood: roll your own ;)

20:14 xcthulhu: (this is what I am complaining about)

20:14 Frozenlock: xcthulhu has a point, friend is a little cryptic.

20:14 xcthulhu: Yeah, but lib-noir is deprecated

20:14 Frozenlock: If it's for a toy-like application, just roll your own with lib-noir.

20:14 Jaood: the clojure community is not as webish as python/ruby/hs

20:14 js

20:14 xcthulhu: Compojure security is a sad place

20:15 kristof: Is it sad, or just insecure?

20:15 Frozenlock: xcthulhu: lib-noir isn't deprecated https://github.com/noir-clojure/lib-noir

20:16 xcthulhu: I suppose noir is deprecated, random parts of it live on

20:16 Frozenlock: Not 'random' parts. The best parts :-D

20:16 kristof: Jaood: That surprises me, because a lot of the Conj talks are web related and server/client side software seem to be the niche this community's going for

20:16 boxed: Jaood: ruby has historically been a security nightmare :P

20:17 but I guess that’s pretty webish.. ^_-

20:17 zanes: What determines when println sends to nrepl-server vs cider-repp?

20:21 justin_smith: zanes: the binding of *out* at the point where the printing happens

20:22 zanes: justin_smith: So, if I’m using http-kit with callbacks and printlns inside the callbacks are going to nrepl-server that means http-kit is somehow rebinding *out*?

20:25 amalloy: zanes: more like it's *not* rebinding out. nrepl works by rebinding *out* in some clever way or other while you're at the repl, but that binding does not carry over to the other threads running your callbacks, and so you just get the default printing behavior

20:26 zanes: amalloy: Super helpful! Thanks!

20:26 xcthulhu: amalloy: If you just do (bind [*out* -whatever-] …) it’s threadsafe

20:27 kristof: xcthulhu: How does it make it thread safe?

20:27 xcthulhu: I don’t know. But I ran into this today

20:27 kristof: xcthulhu: So binding should be thread-safe too, right?

20:27 xcthulhu: Should, yeah

20:27 kristof: I gotta look at the source for that, that's interesting

20:28 xcthulhu: If you don’t want it to be threadsafe, try (with-redefs [*out* -whatever-] …)

20:28 (which is what I ended up doing)

20:28 amalloy: what you guys are writing makes no sense. it is not related to zanes's situation at all aside from mentioning *out*

20:29 kristof: I was just asking a question about bind and binding.

20:29 xcthulhu: Yeah

20:30 I suppose I should be saying “thread-local”

20:30 Rather than thread-safe

20:31 amalloy: yes. thread-safe is not well-defined in this context. thread-local is true but, again, not related to the question i was answering

20:32 xcthulhu: I was really talking with kristof… I’m sorry if I offended you

20:32 kristof: Woah, now I'm confused.

20:33 What I meant was that if I establish a dynamic binding in a goroutine, and that goroutine gets parked, and ends up on say a *different* thread, that special variable will still have the same dynamic binding

20:33 THAT's what I meant by "thread-safe".

20:35 xcthulhu: I think if A passes a dynamic variable to B, and B rebinds it (using bind), A won’t notice

20:35 Not sure

20:35 amalloy: kristof: that's certainly not true for (binding [...] (go ...)), but it probably is true for (go ... (binding [...] ...))

20:36 xcthulhu: erm binding

20:39 kristof: amalloy: I don't think it's true for the latter, either. If there's a put or a take from a channel in the body of that binding in the second example, and that entire block is 1) parked 2) later rescheduled on a different machine thread, then the binding should be different

20:39 amalloy: Because if I understand correctly, dynamic bindings are stored on the TLS

20:40 amalloy: kristof: yes, but go does all kinds of form rewriting. it probably turns that binding into something else, which it re-establishes each time it un-parks

20:41 kristof: amalloy: I'll look for what it does when it parses the symbol 'binding, but I wouldn't bet that it does anything special

20:45 amalloy: i guess there wouldn't be much point, would there - what i'm proposing would just be the same as let

20:49 numberten: is there a clean way to take two strings x y and get [(head y)] ++ x ++ (tail y)?

20:49 the shortest solutions I could think of make lots of ugly lazy seqs which don't string well :(

20:50 amalloy: (str (subs y 0 1) x (subs y 1)) sounds right

20:50 ,((fn [x y] (str (subs y 0 1) x (subs y 1))) "hello" "world")

20:50 clojurebot: "whelloorld"

20:52 numberten: wasn't familiar with subs

20:52 that's nice

20:52 thanks :)

20:53 kristof: numberten: How do you normally get substrings?

20:53 numberten: should have thought to use more string specific functions

20:53 kristof: :P

20:53 nullptr: ,(clojure.string/replace "world" #"(\w)(\w*)" "$1hello$2")

20:53 numberten: **shame**

20:53 clojurebot: "whelloorld"

20:54 nullptr: "never do cleanly with functions that which may be grotesquely expressed with a regular expression"

20:54 brehaut: where is my table flipping emoticon

20:54 blur3d: Does anyone know of a clojure TCP library other then ztellman/aleph for low level stuff? I really dislike lamina. Otherwise it looks like I’ll write my own using java interop

20:55 technomancy: lmao if you don't have M-x tableflip configured in your irc client

20:55 justin_smith: blur3d: what about http-kit?

20:56 well never mind, that's http not tcp

20:56 obviously

20:56 blur3d: justin_smith: this is for the same project as yesterday… so I’m hoping to write simple adapters for tcp/udp/serial

20:56 amalloy: blur3d: probably just java.nio

20:57 blur3d: aleph supports tcp/udp (I have serial apready), but it doesn’t sit well with me

20:57 aleady’

20:59 hmm, I might give aleph a go, and then look at java.nio

20:59 TEttinger: ,((fn [x y] (clojure.string/replace y #"(\w)(\w*)" (str "$1" x "$2"))) "hello" "world")

20:59 clojurebot: "whelloorld"

20:59 amalloy: TEttinger: and if x is "$1"?

20:59 blur3d: perhaps a tcp/udp library that supports core.async would be nice to write

21:00 TEttinger: ,((fn [x y] (clojure.string/replace y #"(\w)(\w*)" (str "$1" x "$2"))) "$1" "world")

21:00 clojurebot: "wworld"

21:00 amalloy: (hint: you want java.util.regex.Matcher/quoteReplacement)

21:08 boxed: anyone want to read the readme for https://github.com/boxed/instar ? I just rewrote it but it’s 3AM here and I’m not totally sure I’m 100% coherent

21:09 plus… blind to flaws at home

21:10 * tuft reads.

21:10 boxed: thanks

21:12 tuft: looks good to me -- neat lib

21:13 boxed: tuft: cool. It’s born out of my pain :P

21:15 mthvedt: boxed: readme looks good

21:15 boxed: mthvedt: thanks

21:16 mthvedt: boxed: can you return the favor? i’m planning to ANN this tomorrow: https://github.com/mthvedt/qarth

21:16 amalloy: boxed: (update-in {:foo {:bar {:baz 1}}} [:foo :bar] #(dissoc % :baz)) should just be (update-in {:foo {:bar {:baz 1}}} [:foo :bar] dissoc :baz) - if you're planning to show that your function is better than the built-in, you should use the built-in well to be convincing

21:17 gfixler: boxed: looks nice; I made something along these lines for Python a couple of years ago

21:17 boxed: amalloy: ah, my bad, I’ll fix

21:18 gfixler: on

21:18 amalloy: also, this style makes it hard (impossible?) to store the function assoc itself in a map

21:18 mthvedt: or anyone else is welcome also :P

21:18 boxed: gfixler: on github or something?

21:18 amalloy: or any function, really, since you assume it's an update

21:18 gfixler: boxed: no, unfortunately it's company-internal

21:19 python's mutable, so it just modified in-place

21:19 but it used paths and wildcards

21:19 boxed: amalloy: not impossible, just ugly :P but yea, I made the decision that it’s probably worth it to do that tradeoff

21:20 gfixler: pity.. would have been nice to combine with something like pyrsistent

21:20 gfixler: you could Tree() or Tree({'a':{'b':{'c'}}})

21:20 and tree.grow('/a/b/c'), which would grow any parts that didn't exist as new dicts

21:20 boxed: amalloy: the update-in example is fixed now, thanks

21:20 amalloy: amusingly, you're also in a weird spot if i do something like (let [* unchecked-multiply] (transform m [:x *] * 10))

21:21 gfixler: tree.grow('/a/b/c', 42) to make the terminal an int

21:21 amalloy: er, #(* 10 %) in your style, i mean

21:21 gfixler: but also tree.search('/a/?/c'), or tree.search('/a/*/c') for recursive path part finding

21:22 it returned triples - (path, terminal key, value) - so you could do for path, key, val in tree.search(...):

21:22 boxed: amalloy: heh, yea well… also a tradeoff…

21:22 gfixler: had grafting, pruning, cloning, etc

21:22 kristof: boxed: ^ so you should change your wildcard to _

21:22 gfixler: fun stuff

21:23 boxed: kristof: well, then I’d have to change the name and also learn how to write macros I believe

21:24 amalloy: anyway, the wildcard stuff is cool. i don't love that you're comparing functions to each other; that's the cause of both problems i noted. but, sure, it probably makes things convenient. personally, i prefer the tradeoffs that update-in and friends use (like the ability to use varargs as i suggested you do in your update-in example), but i can see some people liking your way

21:24 gfixler: tree.search could also take a leaf parameter, which was a value predicate, which made it easy to grab all paths to particular values

21:25 boxed: amalloy: well I can probably do the varargs thing anyway, but I’d have to redo this as macros…

21:25 gfixler: something like tree.search('/a/*/c/?', leaf=lambda key, val: key.startswith('foo') and val > 42)

21:25 boxed: gfixler: neat… I’ve thought about doing predicates for instar but I didn’t have a usecase for it myself so I haven’t bothered yet

21:26 gfixler: I forget the method now - prune, maybe - worked just like search, but instead of triples, it returns a filtered version of the tere

21:27 tree*

21:27 so you could tree.prune('a/*/c').pretty() to see the reduced tree pretty printed out, e.g.

21:28 trees had a hidden __root__, too, for metadata about the tree - that was always fussy to keep working right, though

21:28 but if you did a tree('/path/to/JSON/file'), it would tuck the filename in the root, and then after modifications, you could tree.plant()

21:28 or at any point tree.plant('some/path')

21:29 tree.prune('/a/?/c/').plant('smallerTree.json')

21:29 it was all very convenient

21:30 boxed: cute with “plant”

21:30 gfixler: tree.prune('*', leaf=lambda k,v:type(v)=int).plant('justTheInts')

21:30 yeah, I called the whole thing ficus - the genus of the figs

21:31 tiny bonsais up to 100' tall trees, and they also like to strangle other things and destroy sidewalks, which seemed fair warning to anyone using it

21:32 boxed: gfixler: funny story… a phychologist friend of mine had a lecture once about a man who had ficus-fobia :P

21:33 gfixler: wow

21:33 it's an impressive spread of species - benjamin figs in everyone's offices, rubber tree plants, enormous banyan trees, all ficus

21:33 boxed: I think the point of the lecture was something like “you need to keep a straight face no matter what crazy shit you hear, it’s still a patient that needs help” :P

21:33 gfixler: :)

21:34 folks here are still using ficus, but I haven't in more than a year

21:34 I've moved on to immutability, and very flat dicts where possible

21:34 boxed: gfixler: have you seen this: https://github.com/tobgu/pyrsistent ? Made by a collegue of mine

21:35 gfixler: boxed: I appreciate the attempts to unify the formats and simplify expression

21:35 boxed: looks interesting

21:36 I'm stuck in Python for work - it's integrated into our main application - so any attempts to bring immutability to it are appreciated

21:36 boxed: gfixler: “I appreciate the attempts to unify the formats and simplify expression” <- in relation to instar? you switched context pretty fast

21:36 gfixler: sorry, yes

21:36 boxed: cool thanks :P

21:37 gfixler: I have a question for the room about refs, agents, vars, and atoms

21:37 I don't know enough about them yet to know if this is even a good question

21:37 but I've been wondering if underneath they're not all actually the same thing

21:38 and that it's really just some behavioral or implementation details that make them entirely separate constructs

21:38 would it be possible to unify any or all of them into a single concept?

21:39 justin_smith: gfixler: definitely not the same thing

21:40 gfixler: e.g. ref is for transactional changes (correct me where I'm wrong, please)

21:40 but couldn't that just be (transaction ref ref)?

21:41 i.e. transaction is some kind of wrapper you put around some code to make it all work or fail together

21:42 justin_smith: they have different update rules (sequencing/locking vs. check/retry vs. change and hope nothing broke)

21:43 agents don't retry, and do enter a failure state

21:43 atoms do retry, and have no concept of a failure state

21:43 there are many differences in behavior

21:43 gfixler: right, but that just sounds like functional programming to em

21:43 me*

21:44 justin_smith: gfixler: which one?

21:44 you get to choose one of the behavior sets

21:44 gfixler: things would be uncoordinated by default, unless you put them into a coordination context

21:44 it could even be a kind of binding in that case

21:45 (transact [a ref1 b ref2] (- 5 a) (+ 5 b))

21:45 so coordination wouldn't be a property of the thing, but a construct of the function applying the changes

21:45 that feels more FP to me

21:46 it's strange to me that coordination exists in the objects - that feels OO, and at the wrong level

21:47 justin_smith: gfixler: then you are back in the world of java, where it is up to each user of an object to respect the invariants (lock the right thing when accessing the shared value etc.). The point here is the right (semantically clean) thing is the easy default, but you have different reference types for when different conventions of update make sense.

21:48 gfixler: I see - I don't come from a Java world, and I've not had to think about coordination in my work, so it's a new area for me

21:48 justin_smith: is what you are doing pure and retryable? use an atom. Is it impure but commutative? you probably want an agent

21:48 I am vastly oversimplifying here though

21:48 gfixler: you're speaking in FP terms, though

21:48 "what you are doing" sounds like a function

21:49 maybe right now I want a transactional thing with two refs that must change atomically

21:49 but later I might not care

21:50 justin_smith: then don't focus on the container, focus on the values, and use the right reference type for the behaviors you want

21:50 nathan7: You're using a type to capture a property of a value.

21:50 justin_smith: put it in a ref now, an atom later, if the semantics need to change

21:50 gfixler: ok

21:50 nathan7: The container type signifies its properties.

21:50 gfixler: I was missing that bit

21:50 so you deref out of one and drop it into another?

21:51 justin_smith: if you really need to change up the behaviors - but I actually find that pretty rare in practice

21:51 nathan7: the semantics will likely change only your code changes

21:51 not at runtime

21:51 gfixler: sure, I'm realizing this is probably mostly theoretical talk

21:51 justin_smith: gfixler: in haskell, you don't conflate the mondads you use with the values that flow through them, I hope

21:52 gfixler: nathan7: I get that the container type signifies the properties, but that feels very OO

21:52 justin_smith: similarly, you shouldn't conflate the reference type which controls the update semantics with the value they store

21:52 gfixler: Rich talks about FP when he talks about these things

21:52 it just felt more FP to choose the behaviors at the function level

21:52 as needed

21:52 justin_smith: haven't made it to monads yet :(

21:53 I'm up to kinds, having just grokked functors

21:53 justin_smith: OK, I only brought it up because you mentioned haskell before

21:53 nathan7: gfixler: I'm quite familiar with Haskell's type system

21:53 gfixler: so to me this seems very much in the functional realm

21:54 gfixler: nathan7: I might be able to see that

21:54 if I think of the containers more like constructed types

21:54 nathan7: Yeah. That's the trick.

21:54 gfixler: the 4 types feel like vehicles, or payload systems

21:55 nathan7: They're boxes for state.

21:55 gfixler: load a value into them, and then fire them off into some function

21:55 justin_smith: gfixler: simpler analogy: you decide whether to put your string in a vector vs. lazy-seq vs. hash-map depending on how the values should flow through your code - this is all a separate thing from the fact that it is an immutible string, and you pick the container with the behavior characteristics you need

21:55 gfixler: justin_smith: that's a good comparison

21:55 justin_smith: gfixler: similarly, if you need an updatable reference type, you again choose the one with the properties and behaviors you need

21:56 gfixler: I think the thing that was bugging me was the idea of "forever"

21:56 like if I (def foo (atom 0)) then foo is *always* an atom

21:56 but you could just as easily slide the value out of there and into something else

21:56 justin_smith: right

21:57 gfixler: or even let it into something else

21:57 I get the practicality of the 4 types

21:57 and I even understand if it's an implementation thing - it's just hard to not do it as 4 types, e.g.

21:58 but it felt less pure than just (def foo 5)

21:58 a name pointing at a value

21:58 and then determining how that would work in tandem with other values on-the-fly

21:58 functionally

21:58 justin_smith: well, that is the least pure thing in clojure, since vars can be rebound (we just know they shouldn't be)

21:58 gfixler: sure

21:58 zanes: With core.async, if I have an asynchronous process that generates channels over time and I want to read from any of them as they’re available what’s the best way to do that? merge? mix?

21:58 boxed: it’s nice not being able to fuck up too.. and binding it strongly to atom/ref/whatever makes fuckups explode instead of subtly break

21:59 jack_rabbit: So, I've included [org.slf4j/slf4j-log4j12 "1.7.7"] and [org.clojure/tools.logging "0.2.6"] in my project.clj, but when I (log/*anything*) on the repl, nothing happens. I'm sure I'm doing something stupid.

21:59 boxed: sometimes complecting a little bit is a good thing :P

21:59 gfixler: zanes: one thing I haven't considered was not being inside the context

22:00 zanes: gfixler: Sorry, what?

22:00 gfixler: zanes: you bring up a good point about getting values over time

22:00 justin_smith: gfixler: he wasn't talking about your issue

22:00 gfixler: justin_smith: lol, it made sense in my head

22:00 justin_smith: :) but sure, core.async channels are another way of representing / coordinating values over time

22:01 gfixler: well, it made me think of 'over time' as a problem

22:01 justin_smith: gfixler: if you get abstract enough, everything is always relevant

22:01 gfixler: if I (def foo 5) and (def bar 7), then want to transactionally change them the way I was saying with (transact <changes to foo and bar>)

22:01 then I have to stay inside of that over time if I want to keep seeing what they're doing

22:01 justin_smith: touche

22:02 so that would be a problem with what I was proposing about purely functional properties

22:03 brehaut: gfixler: just to check: you know that putting refs into vars is not really best practise eh

22:03 gfixler: brehaut: I don't know all that much tbh :)

22:03 I'm speaking well about my station currently

22:03 s/about/above

22:03 * zanes laughs.

22:04 gfixler: I've only used atoms so far, but I've read up a bit on the other 3

22:04 I just wanted to ask about this, because it's been on my mind since earlier this year, when I was reading through JoC

22:04 justin_smith: gfixler: in some ways core.async channels can be considered a fourth :) though they are more conduits for values than containers of course

22:06 kristof: they are containing conduits that implement control

22:09 gfixler: I appreciate all the answers - I make tools and pipelines for artists (games), so I have no web/scalability/async experience

22:09 I just find it all very interesting

22:09 kristof: gfixler: You're right, sort of. The functions are responsible for the coordination, not the datatypes.

22:10 gfredericks: I want to go to bed has anybody asked about the ambiguity of transit supporting vanilla json?

22:10 kristof: gfixler: A ref does not do its coordination, a compare-and-swap function does, on arguments that happen to be within the same ref

22:10 gfixler: The thing is that when you establish data structures that need to be coordinated in some way, that coordination philosophy is intimately tied to the logic, and your logic is never going to change.

22:11 gfixler: kristof: that makes sense

22:12 The other thought I had was that 'coordinated', 'asynchronous', etc could just be metadata on regular variables

22:12 kristof: gfixler: Why would a collection of values that make a ref suddenly not need synchronized, coordinated update?

22:12 gfixler: You're missing "synchronous".

22:13 gfixler: "Coordinated" implies it's coordinated with another variable. You'd have to store all the variables it's coordinated with. And then... you just reinvented the ref data type.

22:14 zanes: Related: Not understanding the difference between >!! and put!.

22:14 gfixler: kristof: that could be something I've not understood properly

22:14 I've been thinking of these types the way I used atom, with a value inside

22:14 kristof: zanes: Who is?

22:14 zanes: kristof: I’m not!

22:14 gfixler: not as large collections of distinct things

22:15 kristof: zanes: A goroutine is a little (fn [] body) that gets passed around from thread to thread by a threadpool scheduler

22:15 zanes: Yeah, that much I understand.

22:16 amalloy: gfixler: also it's kinda impossible to do what you were suggesting, to start with atoms and then if you need coordination wrap them up in some coordinator context

22:16 the contract that atoms provide is not conducive to coordination - you can't coordinate them externally

22:16 kristof: zanes: Wait, are you talking about ">!!" and ">!"?

22:17 zanes: kristof: No, I’m talking about ">!!" and "put!”.

22:17 gfixler: amalloy: impossible with atoms as they exist, or even in concept?

22:17 kristof: zanes: put! is nonblocking

22:17 zanes: Ah! Okay.

22:17 So it’s more or less equivalent to using >! inside a go block?

22:17 kristof: zanes: Works exactly like >!

22:18 amalloy: gfixler: as in, if your primitives are "a mutable cell, deref, swap!, and reset!", you cannot write a function like dosync

22:18 gfixler: amalloy: my simple example is (def accountA 10) and (def accountB 10) and I want to transfer 5 from A to B

22:18 amalloy: that is, something that takes two atoms and performs a single coordinated transaction across them

22:18 gfixler: amalloy: I'm not sure that what you're saying isn't just implemenation specific, though

22:18 I agree atoms as they exist can't do this, or probably can't

22:19 amalloy: uhhhh, i'm not talking about an implementation, i'm talking about any implementation of the atom contract, which is deref, swap, reset

22:19 gfixler: that's a kind of implementation, though

22:19 amalloy: i don't see any way you could combine those primitives to build something that acts like the refs we have today

22:19 gfixler: that contract

22:20 amalloy: ...it's how atoms are defined. you could say "we could do X with atoms if only atoms were a different thing", but what's the point? you could use spaghetti noodles instead of atoms, if we gave them good enough coordination guarantees

22:20 gfixler: haha

22:20 justin_smith: gfixler: what is there to an atom aside from the behavioral guarantees described?

22:20 gfixler: I didn't mean to get you all worked up :)

22:21 justin_smith: nothing, but my point isn't these existing constructs

22:21 amalloy: getting worked up is a hobby

22:21 seangrove: Can't quite get clj-time to give me the right format - (.toString (clj-time.core/now)) => "2014-07-23T02:16:49.620Z", when I want "2014-07-23T02:16:49+07:00"

22:21 alandipert: amalloy, you can rewrite refs and dosync into an atom + swap with some rewriting; scope becomes a map in the atom. the difference is dynamism i think - refs can be added any time

22:21 gfixler: it was name=value and then coordinating changes in different ways on them, functionally

22:21 seangrove: (no milliseconds and the timezone)

22:21 gfixler: instead of as properties on the names that point to the values

22:21 that's all

22:22 amalloy: it's good to have a hobby

22:22 amalloy: alandipert: i don't think so. not without leaking your transactions into other threads who are reading while you're writing

22:22 Jaood: amalloy: he needs some concurrency 101

22:22 justin_smith: gfixler: I just don't understand what you would even mean by "atom" if you were not describing those behaviors. There are different reference types because they have different behaviors for access, update, and synchronization.

22:22 gfixler: justin_smith: I'm actually talking about throwing out the term atom (not really - just as a thought exercise)

22:22 amalloy: i'd be interested to be proven wrong

22:22 alandipert: amalloy, oh right, and throughput - all threads would need to go through the same atom

22:22 gfixler: you guys keep talking about behavior, but won't let me make that a functional thing

22:23 justin_smith: gfixler: in that case our conversation has no basis - I thought we were comparing the various clojure reference types

22:23 gfixler: you keep making properties of objects and containers

22:23 justin_smith: I'm using them as a starting point

22:23 for the behaviors they describe

22:24 I like the structural sharing thing

22:24 justin_smith: They *are* the behaviors they describe. There is nothing else there to talk about. The point is that they describe behaviors that are not unifiable into a single thing.

22:24 gfixler: and the necessary double-referencing required by that

22:24 amalloy: alandipert: i'm confused. are you saying that it's possible to write macros and/or functions named "ref", "dosync", and "alter" that give you ref-like behavior on top of atoms without making you change anything compared to using refs as they are now?

22:25 gfixler: my name actually points to a particular moment in time in the life of a value

22:25 amalloy: or that you can rewrite your whole app to use atoms instead of refs

22:25 alandipert: amalloy, i'm not fully convinced, but i went through some exercises to this end

22:25 amalloy, and i surprised myself with what new possibilities emerged when the environment is static

22:25 gfixler: but if I needed to change two values pointed to in an atomic way, I could imagine doing that functionally, maybe

22:26 I could be wrong, of course

22:26 Jaood: I really haven't seen refs used much in clojure, what libraries out there use them?

22:26 amalloy: Jaood: you'll never need a ref

22:26 alandipert: amalloy, to clarify, this isn't anything possible in clojure currently lol

22:26 amalloy, or at least, this would involve a whole-program macro :-)

22:27 amalloy: right. obviously you can do everything with atoms if you rewrite the whole program

22:27 Jaood: amalloy: why is that?

22:27 amalloy: why will you never need a ref?

22:27 Jaood: I know STM hasn't been much of a success

22:27 amalloy: yeah

22:28 blur3d: I’ve given up on using aleph (and never touching again)… onto java.nio

22:28 ztellman: blur3d any particular reason?

22:28 amalloy: alandipert: you can do everything with lambda calculus if you rewrite the whole program. but gfixler was talking about some sort of combinator that glues two atoms together and gets you something like a ref (or at least i thought so at the time; apparently he was just talking in general about mutation)

22:29 justin_smith: amalloy: do you have a link to a blog post that gets into the details of demonstrating that / why you never need a ref?

22:29 alandipert: justin_smith, datomic.com

22:29 :-)

22:29 amalloy, gotcha, sorry for traipsing in and blathering

22:30 justin_smith: alandipert: so you mean use datomic as a data store instead of using refs?

22:30 ztellman: blur3d: fwiw, I'm on the cusp of rewriting Aleph to use https://github.com/ztellman/manifold instead

22:30 kristof: zanes: I'm a dirty liar. put! is the exact same as >!! for two arguments.

22:30 blur3d: ztellman: everytime I touch it I seem to hit dead ends. I had trouble with UDP broadcasting working correctly the first time, and now I’m finding working with tcp more difficult then I’d like it

22:30 gfixler: amalloy: well, I was questioning whether or not it was possible to have one reference type, and then get the behaviors of the current 4 by functional application

22:30 so obviously I was throwing out the 4 existing types

22:30 alandipert: justin_smith, right, datomic is a competitor because it offers in-memory storage

22:31 gfixler: the point was basically "Couldn't we just achieve the same thing with functional wrappers?"

22:31 ztellman: blur3d: well, sorry to hear that

22:31 alandipert: justin_smith, the cost is ease of use - you lose the idea of a collection when you invest in datomic

22:31 justin_smith, the benefit is, with minor modification whatever you made can be durable

22:31 gfixler: i.e. you wouldn't decide on a type up front, but decide on coordination and such later, when you did something with them

22:31 hiredman: some guy published a thesis paper recently about building resuable composable concurrent stuff, which had some similar sorts of things like fusing atoms together

22:31 ztellman: not sure what the issue with UDP broadcasting would be, it's just a flag

22:31 gfixler: it may not make any sense logically, which is why I asked the room about it

22:31 alandipert: justin_smith, also it's proprietary and stuff which may or may not appeal to you

22:32 justin_smith: alandipert: yeah, I've considered datomic before and did run up against the licensing

22:32 blur3d: ztellman: I am also trying to do a few things that I wouldn’t expect it to support out of the box - like using 7 bit bytes - so it isn’t entirely the libraries fault

22:32 alandipert: justin_smith, the free version is quite capable as of recently-ish

22:33 ztellman: blur3d: ha, yeah, that'll cause a few impedance mismatches, but ideally Aleph should be a much thinner wrapper around the protocols than it currently is

22:33 justin_smith: blur3d: any good reason not to just use a jvm byte and truncate it to a positive value? there's your seven bits

22:33 blur3d: ztellman: UDP was likely related to https://github.com/ztellman/aleph/pull/96 - but I haven’t tested it since

22:33 hiredman: https://www.mpi-sws.org/~turon/turon-thesis.pdf

22:34 blur3d: justin_smith: I’m building on top of the Arduino Firmata library, so just going with what it uses

22:34 justin_smith: ahh

22:34 alandipert: hiredman, this looks like an incredible find

22:34 justin_smith: blur3d: yeah, you need it to actually be 7 bits on the wire or whatever then

22:34 hiredman: alandipert: just aesthetically it is a beautiful pdf

22:35 blur3d: justin_smith: yeah, the 8th bit is used for control chars

22:35 alandipert: hiredman, i was gonna say, it's a marvel of typesetting

22:35 blur3d: justin_smith: http://firmata.org/wiki/V2.3ProtocolDetails

22:35 justin_smith: blur3d: OK, use the absolute value, and multiply * -1 if you need the control bit to be set

22:35 hiredman: like, he must have figured out the concurrency stuff in a year and spent the rest of the time futzing with latex

22:36 justin_smith: blur3d: since everything is signed in the jvm integral types

22:36 amalloy: justin_smith: i got disconnected. i tried to say:

22:36 blur3d: justin_smith: I actually have all the data stuff working using https://github.com/peterschwarz/clj-firmata - but its the transfer that I’m working on atm

22:36 amalloy: justin_smith: i mean, refs are more powerful than atoms, so in theory you could be in a situation where one makes your life simpler; i can't prove you'll never need one

22:36 all i can say is "lots of people who've written a lot of clojure agree you never need a ref", which is only slightly more interesting than an argument from authority

22:37 and of course "never" is in quotes, because who knows, it could happen someday. but usually if it does it means you wrote the rest of your program poorly

22:37 justin_smith: blur3d: also, mind that there is extensive midi support in the jvm

22:37 amalloy: OK, I do trust your judgment on this, I was honestly interested in reading an in depth post or article on the subject though

22:37 blur3d: justin_smith: nice to know. Firmata uses a superset of the MIDI - but for my use I am more using the superset

22:37 justin_smith: amalloy: maybe it's a blog post you need to make

22:39 amalloy: i don't know of one; hiredman might? he's another member of the Campaign Against Ref [E-something - i couldn't come up with the rest of this acronym but it's a shame to waste]

22:40 Ennoblement seems too grandiose

22:40 gfixler: amalloy: so wait, I only need to learn 3 of these things now?

22:40 kristof: zanes: The difference is that for 3 arguments, or 4 with a 4th that isn't nil, you can call a function as well. That's really it.

22:40 justin_smith: blur3d: when I most recently played with low level data on the jvm (I made a simple real time audio maniuplation engine), I found java.nio.ByteBuffer really useful for getting bits out of and back into twiddly little formats

22:41 amalloy: gfixler: probably. but refs are a fun theoretical study anyway

22:41 gfixler: well, if there are only 3 now, I don't feel the need to turn them into functional wrappers ;)

22:41 amalloy: hah

22:41 gfixler: 4 was just too many

22:42 amalloy: vars are rarely used for mutable constructs anyway; they're mostly just for changing top-level defs at the repl

22:42 gfixler: did my point ever end up making any sense, btw?

22:42 hiredman: the one place we use a ref instead of atom it is because we have this side effect thing that we do in an agent, and transactions hold agent sends until they commit

22:43 amalloy: Campaign Against Ref Evangelism! how did i miss that?

22:43 justin_smith: blur3d: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html - lets you grab the next N bytes and treat them as whatever datatype you need, or insert whatever datatype as the next N bytes - but below 8 bits you need to do some masking / AND ing whathaveyou

22:44 hiredman: I suspect more people write data processing jobs than large multithreaded simulations

22:45 data processing tends to be sort of logically single threaded, with sort of parallel data processing combinators, like mapreduce, so some kind of coordinated transaction stuff doesn't really make sense

22:47 we can't all write systems that simulate national elections via sythesizing music

22:53 alandipert: hiredman, i've found transactionality very lucrative in the browser in cljs

22:54 via cells and the spreadsheet approach, it's a kind of reverse transaction i guess since it's all 'push', but you have the same consistency guarantees

22:55 bad for IO-bound stuff but fortunately that's not even possible in the browser

22:55 hiredman: alandipert: which is interesting, it may just be that the stm doesn't get used because people do more backend server work on the jvm than guis

22:56 alandipert: hiredman, yeah my feeling is like you say, people are doing processing or interacting with a DB

22:56 but yeah, transactions are killer for UI, because there's only ever data (not process) behind a UI, and it needs to be coordinated

22:56 hiredman: the cannonical stm example, the ants simulation, uses the stm to take consistent snapshots to render a gui "report" (if I recall correctly)

23:00 alandipert: hiredman, the situation we ran into taht motivate transactions was 'the pregnancy test' - present a form in which is was impossible to indicate you were both male and pregnant, under any circumstance

23:04 sitrus: I was wondering if anyone knew of a way for running all of the tests in a namespace multiple times. I have two *Contexts* that I want to run through but can't find a way to have tests repeat after running

23:04 hiredman: sitrus: using clojure.test?

23:05 justin_smith: sitrus: what I do is put multiple is calls in a defn, and call that function in different contexts (sometimes it makes sense to make the contaxt an arg to the function even)

23:05 hiredman: sitrus: (use-fixtures :once (fn [f] (f) (f))) should do it

23:05 justin_smith: if a deftest calls a function with calls to is, the tests are noted properly by the runner

23:05 hiredman: you can setup different things around each call to f

23:07 http://dev.clojure.org/jira/browse/CLJ-701?focusedCommentId=35148&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-35148 I am excited about this, I've wanted to be able to do hoisting kinds of things in the compiler for a long time

23:08 I want to turn letfns that aren't used in a higher order way in to methods too

23:08 sitrus: so hiredman I'm currently using (use-fixtures :once…) to set the context for that particular run of the file, would there be a way to have it run each of the deftests multiple times with different functions

23:09 hiredman: sitrus: a once fixture gets passed a function that when invoked runs the tests

23:09 if you invoke it multiple times, it will run multiple times

23:10 if you setup a different binding or with-redefs around each call to the function, each run of the tests will have different environment setup by the binding or with-redefs

23:11 sitrus: thank you! I'm going to take a stab at it now!

23:41 Jaood: is there a function that removes only the first occurrence of some item in a collection?

23:44 nkozo: Jaood: (rest [1 2 3]) => (2 3)

23:45 Jaood: nkozo: heh

23:46 Raynes: Jaood: Also ##(next [1 2 3])

23:46 lazybot: ⇒ (2 3)

23:46 nkozo: sorry, misread

23:46 sm0ke: is there some way to preserve collection type?

23:46 Raynes: 99% of the time you don't want to preserve collection type

23:47 1% of the time you have to use whatever functions are native to that collection.

23:47 Or functions like 'conj' that Do The Right Thing.

23:47 sm0ke: there should be a conj equvivalent for rest too then?

23:47 Jaood: I mean some like remove or filter but only for the first match

23:47 sm0ke: like conj is for cons

23:48 Jaood: ,(remove #('a %) '[b c a d a f])

23:48 clojurebot: (b c a d a ...)

23:48 sm0ke: ,(conj [1 2 3] 4)

23:48 clojurebot: [1 2 3 4]

23:48 sm0ke: ,(conj {:a 1} [:b 2])

23:48 clojurebot: {:b 2, :a 1}

23:49 Jaood: ,(remove #(= 'a %) '[b c a d a f g])

23:49 clojurebot: (b c d f g)

23:49 justin_smith: Jaood: remove expects a predicate, a symbol used as a function does get (just as a keyword would) so will not return true for the same symbol

23:49 Jaood: justin_smith: fixed ^^

23:49 nkozo: but that removes all occurrences

23:49 Jaood: Raynes: like that example but I only want to remove the first 'a for example

23:50 I can write this but clojure.core has so many fns and was wandering if there is already something for it

23:52 nkozo: ,(let [[a b] (split-with #(not= 3 %) [1 2 3 4 5 6])] (concat a (rest b)))

23:52 clojurebot: (1 2 4 5 6)

23:53 justin_smith: nkozo: nice

23:54 ,(let [[a [_ & b]] (split-with #(not= 3 %) [1 2 3 4 5 6])] (concat a b))

23:54 clojurebot: (1 2 4 5 6)

23:54 justin_smith: cleaned up a little :)

23:54 nkozo: :)

23:55 justin_smith: since you were destructuring already and all

Logging service provided by n01se.net