#clojure log - Mar 05 2014

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

0:06 SegFaultAX: Since we were talking about clojars earlier, RubyGems' AWS bill: https://www.dropbox.com/s/3v13d2g8klwer3d/AWS%20-%20RubyCentral%20-%20Feb2014.pdf

0:07 dissipate: SegFaultAX, wow, guess clojure isn't nearly as popular as ruby

0:08 SegFaultAX, oh and look, they are using a CDN. fancy that.

0:08 SegFaultAX: dissipate: No reason to be a dick about it.

0:11 dissipate: SegFaultAX, i offered to donate. was turned down. how is that being a dick?

0:13 SegFaultAX: dissipate: That's not the part people took issue with. It's the perceived tone of what you're saying. It /feels/ like you're being hostile because that's the tone that comes across from the text.

0:14 dissipate: SegFaultAX, sorry about that. i really do want to donate.

0:15 _ato2: wow 6126 GB out, $735 / month.

0:15 SegFaultAX: dissipate: No apology necessary.

0:21 xeqi: SegFaultAX: theres a Q/A going on about it at https://news.ycombinator.com/item?id=7345279

0:22 SegFaultAX: xeqi: Yea the maintainer has some good insights.

0:48 Null_A: Man, the team that i'm only is vouching to rewrite the whole codebase because as far as I'm concerned it's negativity towards clojure

0:49 makes me sad

0:50 dissipate: Null_A, any more details on the situation? how large is the code base?

0:50 Null_A: I can't really say too much

0:51 it's on the order of a tens thousands of lines

0:52 the cite reasons like not enough tooling, like intellij not working with clojure

0:53 dissipate: Null_A, damn, that's a lot of LOC for a clojure app

0:53 Null_A: yup

0:54 they want to rewrite in C++, so good luck with that

0:54 dissipate: Null_A, so a big app was written and they just now started complaining? are these the managers?

0:54 Null_A: they might be digging their grave

0:54 dissipate: Null_A, bwahahaha

0:54 Null_A: it's a long story

0:54 dissipate: cee plus plus

0:54 Null_A: management is certainly playing a role

0:54 dissipate: OMG, i can't imagine a 10,000 line clojure app in C++

0:55 Null_A: because they say it's hard to hire clojure programmers

0:55 but also other engineers on the team just aren't accepting clojure in general, some more than others

0:55 dissipate: Null_A, it probably is if their projects are boring

0:55 Null_A: I think it comes down to them not taking the time to actually learn it..

0:55 they keep saying it's not intuitive

0:55 these are not functional programmers by school

0:56 dissipate: Null_A, they will indeed dig their own grave

0:56 it is probably going to be an absolute nightmare porting that code to C++

0:57 dsrx: how did 10k LOClj get written without anyone learning clojure?

0:57 Null_A: they're definitely going to try and chop away certain aspects of the system if they port it

0:57 ddellacosta: seriously, sounds like one or a few engineers railroaded the rest into using Clojure.

0:57 Null_A: tehre's no way the could do a verbatim port in C++, i doubt that project would ever see the light of day

0:58 they're making different tradeoffs in the new system, e.g. consuming way more RAM

0:58 dissipate: ddellacosta, yeah, sounds like it to me.

0:59 Null_A: dsrx: it was me and a couple other people

1:00 dsrx: but they all left except for me, and we hired new people

1:04 dissipate: Null_A, these new people were hired without finding out of they wanted to do Clojure development?

1:10 Null_A: dissipate: yup

1:10 dissipate: Null_A, well, damn. i wish i was one of them.

1:11 ddellacosta: Null_A: are you in the U.S.? What city (if you can say)?

1:11 Null_A: i'm in U.S. yah

1:11 ddellacosta: why do you ask?

1:12 Raynes: Null_A: That van that has been sitting outside your place...

1:12 Null_A: dissipate: send me your resume :)

1:12 Raynes: (that's him)

1:12 ddellacosta: Null_A: just curious. I see a lot of folks on the Clojure mailing list interested in jobs, when jobs pop-up. Most of the jobs are in the U.S. as far as I can tell. I'm wondering why whoever did the hiring there didn't post the position(s) on the Clojure mailing list.

1:12 Raynes: sssh!!

1:12 no one is supposed to know

1:12 dissipate: Null_A, do you guys allow working remote?

1:13 Null_A: dissipate: outside of US? not likely

1:13 dissipate: Null_A, i'm in the U.S. San Diego to be more precise.

1:14 Null_A: dissipate: are you open to moving?

1:15 koreth_: I recently convinced a friend of mine who runs a startup in China and is having trouble finding good developers that he should try migrating his app over to Clojure and advertising for Clojure programmers instead of Java ones, on the theory that they are small in number but high in quality and eager to find jobs. So if any of you guys want to learn Chinese...

1:15 dissipate: Null_A, unfortunately, no. i'm too tied down to San Diego with family and other stuff.

1:15 Null_A: hm, I don't think it would work :(

1:16 dissipate: Null_A, :(

1:16 koreth_, doesn't it take years to really learn Chinese?

1:18 koreth_, a startup on Java? that doesn't sound good

1:18 koreth_: dissipate: Yes and no. You can be functional enough to get by in a matter of months if you're dedicated and you're immersed 24x7. But reading takes a long time to learn which is a big hindrance to learning quickly.

1:19 dissipate: koreth_, yeah, i can see how learning 30,000 characters would be a speed bump

1:19 koreth_: dissipate: My friend isn't a technical person (it's a startup in the medical field and he's an MD) and the architect he hired initially had him on .NET. So Java is a step up.

1:20 dissipate: 3500-5000 is more typical for a college-educated person. Only a small handful of academics actually know 30,000 characters, though that many do indeed exist.

1:21 But that's still a lot.

1:21 dissipate: koreth_, does this 'architect' actually write code?

1:22 koreth_: No, the guy was a complete bozo who talked a good talk. He's long gone. But the Chinese educational system is churning out Java programmers like crazy right now and that's pretty much what you get unless you're looking for something else in particular.

1:23 dissipate: koreth_, perhaps he should look for Scala developers

1:24 cespare|home: Is there a function that can apply f to coll and return the first result which is not nil?

1:24 koreth_: That'll be my second suggestion if Clojure doesn't work out. The reason I suggested Clojure in particular is because it seems more likely to select for way-above-average programmers than Scala will (just due to Scala being much more popular) and I think what he needs now is some higher-skill people to round out his team, which is basically all junior devs.

1:25 cespare|home: I can do (first (map ... I suppose.

1:25 dissipate: koreth_, if i were doing a startup, i would do Clojure and Python, perhaps with some C sprinkled in

1:26 koreth_: His people seem like they're not stupid, just really inexperienced, so I think they could come up to speed and be productive in Clojure.

1:26 Null_A: I think clojure might be weeding out bad programmers

1:26 if they can't compute all the higher level abstractions in their head

1:26 cespare|home: or maybe it just breeds elitist bullshit

1:27 Null_A: haha

1:27 or maybe both

1:27 koreth_: Definitely some of both.

1:27 Null_A: One of the quotes I heard from someone at the office "It's true that 1 line of clojure translates to 5 lines of C++, but at least with the C++ I know what's going on"

1:28 or that "succinct code" is actually used with negative connotation

1:28 koreth_: They obviously don't do C++ template programming.

1:28 segmond: n #elixir-lang

1:29 koreth_: If I were starting from scratch and wanted a C++-ish "kitchen sink" language I'd take a serious look at D instead. Haven't done anything real with it but it seems much more well-thought-out than C++.

1:29 dissipate: Null_A, are you kidding me? OOP is a tangled mess.

1:30 alew: cespare|home: ,(some identity [nil nil nil nil "yay"])

1:31 cespare|home: it will also ignore false though

1:35 Null_A: dissipate: i know i feel like they want to bring to team back to the dark ages

1:36 I know C++ very well, i written way more C++ than clojure, and there's a reason I haven't written any c++ in a few years

1:36 rich hickey speaks the same gospel

1:37 bellkev: ddellacosta: can I trouble you with a quick oauth2 question?

1:38 cespare|home: alew: thanks

1:50 dissipate: Null_A, did you know that not even Bjarne Stroustrup has memorized the entire syntax of C++

1:50 Null_A: lol

1:50 no

1:51 dissipate: Null_A, yep. i don't understand the desire for huge syntaxes.

1:51 Null_A: dissipate: me neither, i don't understand the desire for english looking syntaxes either (ruby)

1:52 it doesn't help me program

1:52 i'd rather learn simple rules

1:52 dissipate: Null_A, Perl

1:53 Null_A, is there any legitimate need for a language to have a huge syntax?

1:54 Null_A: dissipate: maybe it helps certain kinds of people think better dunno

1:54 there's more 'landmarks' for their brain to pick up on *shrug*

1:55 notostraca: heh, APL has a very straightforward syntax. it just goes left and right in very strange ways...

1:56 I don't think that simple syntax necessarily means easy to read

1:57 it does however allow you to use macros without making your hair ignite

1:57 dissipate: notostraca, yeah, but there are a ton of symbols. it's pretty much unreadable.

1:57 notostraca: dissipate, are you talking about clojure here?

1:57 because I have had that complaint ledged against clojure I've showed to people

1:58 dissipate: notostraca, no, APL

1:59 notostraca, clojure has a lot to learn in the core libs, but that's unavoidable.

2:00 notostraca: yeah that's kinda the point of APL, it was to use terminology from math (including many symbols) rather than the traditional short ASCII names of the time

2:01 I think when I program in clojure I do sometimes side with terseness over clarity...

2:01 dissipate: notostraca, well, that failed

2:01 notostraca, good luck reasoning about APL programs

2:02 notostraca: oh yeah, there's no way to do that

2:02 but my point is, the precedence rules are _barely_ more complicated than clojure's

2:03 like lisp, it's a "syntax? what syntax?" language

2:03 but it still manages to be very very hard to read

2:04 dissipate: notostraca, no, but all of the symbols in APL are part of the core of the language

2:04 notostraca, i consider those syntax.

2:05 notostraca, and the rules for those symbols are quite complex

2:06 notostraca, nonetheless, APL itself has pretty much died out. there is a more modern successor called J that is backed by a company.

2:06 notostraca: that's much like saying map is syntax (in fact, it's the double dot in APL)

2:06 I know

2:06 dissipate: http://www.jsoftware.com/

2:06 notostraca: J is GPL now actually, not sure if it's still heavily backed

2:07 dissipate: notostraca, there is actually a pretty cool 'kit' you can download for J that has tutorials and other goodies

2:07 seems quite interesting for doing 3D programming

2:07 notostraca: but I think you missed my point

2:07 dissipate: notostraca, which is?

2:09 notostraca: J and APL have (IIRC) the same rules for precedence, which is their only syntax. Lisp has prefix notation, J and APL have two kinds, one reads arguments from one side (monadic) and one from boths sides (dyadic)

2:09 seancorfield: I saw the J talk at Lambda Jam last year and found it a lot less readable than APL

2:09 * seancorfield wrote an APL interpreter for his final year graduation project back in ;83

2:09 notostraca: this can be described a lot more easily than C++ syntax of course, but it's still very very hard to follow the path a program takes

2:11 I think clojure's in the sweet spot of tersness and readability, but it took me a long time to get proficient enough to think that

2:13 dissipate: notostraca, but you have to take into account the complexity of the builtins. J's builtins are very complex.

2:16 muhoo: why does david use (fn [] foo) in om examples instead of (constantly foo) ?

2:18 apgwoz: hi all -- I'm having a problem with 1.5.1. I get an IllegalAccessError when trying to require clojure.string/replace

2:18 (require '[clojure.string :refer [replace]])

2:18 IllegalAccessError replace does not exist clojure.core/refer (core.clj:3849)

2:19 Yet, :refer [replace-first] works fine.

2:21 ambrosebs: apgwoz: hmm have you tried a `lein clean`?

2:21 apgwoz: i have not. i'll try now.

2:22 ha!

2:22 yes, that worked. thanks ambrosebs!

2:22 ambrosebs: apgwoz: :)

2:22 you just can't explain that

2:23 apgwoz: hehe. i guess not.

2:24 sort of like old macs, in which the solution was always to repair permissions.

2:29 jjro: Is it possible to write macro so that (= [ (my-macro :a) ] [ [:a] [:a] ])

2:32 the problem I'm trying to solve is following: [:body

2:32 (current-user user)

2:32 (logo)

2:32 (topmenu)

2:33 I would like to combine current-user, logo and topmenu as a list elements after :body

2:43 mr-foobar: Can I use lein to point to a folder as a dependency ?

2:57 ddellacosta: mr-foobar: you probably want one of two things--checkouts (https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies) or to just use lein install in a different project directory.

2:57 mr-foobar: not sure how else you'd use lein to pull in third-party code, but perhaps there's a way.

2:58 bellkev: sorry I was in a meeting. :-(

3:00 mr-foobar: ddellacosta: checkouts solves it. thx !

3:00 ddellacosta: mr-foobar: great!

3:01 ambrosebs: ,`[:body ~@(concat [1 2] [3 4])]

3:01 clojurebot: [:body 1 2 3 4]

3:01 ambrosebs: jjro_: ^^ does that help?

3:22 mheld: hey y'all

3:22 we're hiring clojure guys and data scientists at my company -> http://weft.io

3:22 anybody in BOS or SFO looking for gigs?

3:24 Kneiva: Brotherhood of Steel

3:26 koreth_: Any Laser experts in the house? I am getting a NullPointerException from what I think is a super-simple usage of the API. Clearly I am doing it wrong but I'm too dumb to see where the mistake is. Stripped-down example at http://pastebin.com/bamMDWXB

3:27 ddellaco_: mheld: what does "Clojure guy" mean (in terms of what you expect people to know)?

3:27 mheld: not that I'm looking right now, just curious

3:29 ohcibi: hi.. i have a simple question about -> which I want to google for... how to google for ->? 8-))

3:29 mheld: ddellaco_: honestly, as long as you can manage yourself (aligned with the interests of the company), we don't particularly care

3:29 ohcibi: i.e. what is the name of this operator, i know it has a special name but I forgot it

3:29 ambrosebs: ohcibi: thrush iirc

3:29 mheld: ddellaco_: we're a clojure shop, so, of course we'd like it if you knew at least a little clojure

3:29 clgv: ohcibi: just ask here ;)

3:29 mheld: ddellaco_: but it's all learnable

3:30 clgv: mheld: where are you located?

3:30 mheld: BOS + SFO

3:30 minikomi: hi

3:30 clgv: ah ok

3:30 ohcibi: clgv: usually i'd like to google before asking here 8-)) but the question is simple: how to pass any further arguments to one method in the chain?

3:30 clgv: ohcibi: for example like ##(->> (range 7) (map inc) (filter even?))

3:30 lazybot: ⇒ (2 4 6)

3:31 ohcibi: clgv: exactly.. so I actually was loooking for ->>?

3:31 clgv: ohcibi: in words just write the function call without the first argument for -> and without the last argument for ->>

3:32 ohcibi: I dont know. the choice of -> vs ->> is only about where the threaded data is inserted in the subsequent calls

3:32 maxthoursie: ohcibi: it's called the threading macro

3:32 clgv: #(-> 20 (- 5) (* 2))

3:33 ,(-> 20 (- 5) (* 2))

3:33 clojurebot: 30

3:34 koreth_: ,(->> 20 (- 5) (* 2))

3:34 clojurebot: -30

3:34 ohcibi: ah, now I understand.. so in order to apply any additional arguments I just write a normal function call instead of just the function symbol

3:35 e.g. (-> some-initial-return-value (another-method-with params))

3:35 clgv: ohcibi: yes.

3:35 koreth_: ohcibi: exactly like that

3:35 ohcibi: okay.. thank you

3:36 clgv: in fact the no-args scenario without the list is a comfortable special case

3:37 ohcibi: the example I had at hand were about JFrame pack! and show! interop with seesaw. neither pack! nor show! needed any additional arguments and without the name I felt unable to google further 8-)

3:38 so knowledge now

3:38 clgv: ohcibi: that's one of the cases where clojuredocs.org could have helped you. just for future reference^^

3:39 e.g. http://clojuredocs.org/clojure_core/clojure.core/-%3E

3:39 ohcibi: clgv: still.. what should I have entered into the searchbox?

3:39 oh

3:39 k

3:39 didnt tried it like that..

3:39 koreth_: Speaking of clojuredocs.org, anyone know what's up with it? It's still stuck on 1.3.

3:39 ohcibi: lucky guy

3:39 google sends you rightaway to 1.2.0

3:39 (in most of the cases)

3:40 clgv: koreth_: there were rewrite intentions but seems as if the participating guys didnt mange to get it done yet

3:40 maybe they are to ambitious

3:41 *too

3:45 koreth_: https://github.com/zk/clojuredocs

3:46 koreth_: or maybe that one https://github.com/dlokesh/clojuredocs-docset

3:47 koreth_: I heard they were rewriting it but I can't find any indication of what the holdup is. Just lack of time to put into it, or are there specific things that contributors could help out with?

3:48 The open issues on Github don't seem to answer the question.

3:49 chare: what does -> mean in (->Book "title" "author")

3:49 clgv: well that's the problem. they do not seem to communicate the problems.

3:49 chare: it is a constructor function for the deftype/defrecord called Book

3:50 chare: I think it means as much as convert args to object

3:51 koreth_: https://groups.google.com/forum/#!searchin/clojure/%22clojuredocs.org%22|sort:date/clojure/eryt7REIp6o/E-IMIGv3rPYJ

4:04 Pate_: I'm busy doing 4clojure.com problem #100 to calculate the Least Common Multiple of a variable number of positive integers *or ratios*. How does LCM apply to ratios, when the definition of an LCM is "the smallest positive integer that is divisible by both a and b"?

4:04 e.g. one of the unit tests is: (== (__ 3/4 1/6) 3/2)

4:04 where is the function we are solving for.

4:05 *__

4:05 4clojure link: http://www.4clojure.com/problem/100

4:10 minikomi: @Pate_ if it helps, ,(mod 1/3 1/6)

4:11 dpathakj: Pate_: consider what a sensible definition of 'least common multiple' for fractions expressed in common terms might be. write the two fractions in common terms. you have 9/12 and 2/12. now what would a least common multiple mean?

4:11 ohcibi: Pate_: if you have two numbers and b, you are searching for the smalles n in a*n = x && b*n = x, only n has to be an integer

4:11 Pate_: right, but 3/2 is not an integer?

4:12 ohcibi: Pate_: 3/2 is a or b, not n

4:12 Pate_: (== (__ 3/4 1/6) 3/2)

4:12 ohcibi: 3/2 is a, 1/6 is b.. now I almost said too much 8-)

4:13 Pate_: No, 3/4 is a and 1/6 is b.

4:13 compare to the other answers:

4:13 ohcibi: Pate_: sorry, right 3/4

4:13 Pate_: (== (__ 2 3) 6)

4:13 (== (__ 5 3 7) 105)

4:15 ohcibi: Pate_: forget what I said..

4:18 Pate_: http://www.edugain.com/blog/2011/06/26/lcm-of-fractions/ first result on google

4:18 searching lcm fractions

4:18 Pate_: I found that, but I'm confused by the definition link (to wikipedia), which states that the LCM is "the smallest positive integer that is divisible by both a and b".

4:20 ohcibi: Pate_: right, but the sentence you are refering to starts with "lcm of two integers a and b"

4:20 so again, wikipedia is incomplete

4:20 dpathakj: Pate_: the wikipedia article is not general enough then. what you need to do is think of an alternate definition

4:21 I think it is going to be worth your while to write them both with a common denominator, then imagine what the world would be like if it were 'scaled up' so that common denominator were 1

4:22 ohcibi: the pasted article has exactly this in its last line

4:47 AmnesiousFunes: Is just about any graphic unicode character legal in Clojure symbols?

4:56 Pate_: how do I instantiate a new Ratio without using (/ a b) ?

5:04 dpathakj: Pate_: why do you need to do that? you don't for the 4clojure problem you are on.

5:05 Pate_: yeah, I don't. But I was thinking about this: (map denominator [(/ 3 2) (/ 5 4) (/ 10 1)]

5:05 which would break because of the (/ 10 1)

5:05 ...but on second thought, (denominator (/ 3.2 5)) also doesn't work

5:15 pyrtsa: Which one is more idiomatic, (apply concat colls) or (mapcat identity colls)?

5:17 jballanc: pyrtsa: why not benchmark them?

5:18 pyrtsa: Hmm, looks like mapcat is implemented like (apply concat (apply map f colls)), so I guess it's better to just (apply concat ...).

5:20 jballanc: :)

5:21 ,(source mapcat)

5:21 clojurebot: Source not found\n

5:21 jballanc: d'oh

5:21 ,(source clojure.core/mapcat)

5:21 clojurebot: Source not found\n

5:21 jballanc: hrmph

5:22 wonder if lazybot is a better behaved bot

5:23 &(source mapcat)

5:23 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

5:23 pyrtsa: &(clojure.repl/source mapcat)

5:23 lazybot: ⇒ Source not found nil

5:24 jballanc: pfft...useless bots

5:25 pyrtsa: Hmm, a non-variadic (defn cat [colls] (apply concat colls)) would be a nice addition to clojure.core.

5:35 dsrx: why, when you can (apply concat [...])?

5:49 ddellaco_: jballanc: if the bots returned the source IRC would be a completely unreadable mess.

5:50 jballanc: very true :)

5:50 but they could at least gist it for you

5:50 ddellaco_: jballanc: that would be pretty nice.

5:50 jballanc: ...oooh...brb, patching clojurebot

5:50 :P

5:50 ddellaco_: heh

5:50 pyrtsa: dsrx: I think a flatten-once (which cat is!) is a common enough function to be one of its own. Forgive the contrived example but for instance, it's clumsy to (map (partial apply concat) xs).

5:50 jballanc: (eh, who am I kidding...I *really* don't have the time :-/)

7:01 honza: is there some kind of limit on the number of keys a map can have? i'm trying to create one with about a million keys and it kills the program

7:02 (without any exceptions, just an exit code of 1)

7:03 Anderkent: ,(count (reduce #(assoc %1 %2 %2) {} (range 1000000)))

7:03 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

7:03 Anderkent: oh :P

7:05 ,(count (into {} (map vector (range 1000000) (range 1000000))))

7:06 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

7:06 Anderkent: bah

7:09 honza: bahaha

7:09 jballanc: honza: you probably really don't want to do that

7:10 you have to remember that a map is going to try and keep its load-factor around 0.5-0.7

7:16 clgv: Anderkent: works like a chram overhere, just a matter of how much memory you give your jvm

7:16 *charm

7:38 mping_: hi

8:12 joegallo: findfn

8:12 hmmm...

8:13 AeroNotix: clgv: http://www.urbandictionary.com/define.php?term=chrum

8:17 clgv: AeroNotix: luckily I had an "a" in that word^^

8:27 AeroNotix: clgv: :)

8:28 joegallo: $findfn 1 2

8:28 lazybot: [clojure.core/unchecked-inc-int clojure.core/unchecked-inc clojure.core/inc clojure.core/inc']

8:28 joegallo: $findfn 1 [2 3] 4 (1 2 3 4)

8:28 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

8:28 joegallo: $findfn 1 [2 3] 4 '(1 2 3 4)

8:29 Anderkent: ,(doc inc')

8:29 clojurebot: "([x]); Returns a number one greater than num. Supports arbitrary precision. See also: inc"

8:29 lazybot: []

8:29 Anderkent: ha. Didn't even know about it

8:29 joegallo: don't worry, Anderkent, i wasn't looking for inc, i was making sure i knew how findfn worked ;)

8:29 $findfn 1 [2 3] '(1 2 3)

8:29 fredyr: $findfn [2 3 5 7 11]

8:30 lazybot: [clojure.core/list* clojure.core/cons]

8:30 []

8:31 joegallo: $findfn [2 3] 4 '(2 3 4)

8:32 lazybot: [clojure.core/conj clojure.core/merge]

8:32 joegallo: ,(merge [2 3] 4)

8:32 clojurebot: [2 3 4]

8:33 joegallo: yikes

8:34 opqdonut: that's so cool

8:36 oh, right, you can conj maps into maps and merge is basically just into

8:36 lvh: Hi!

8:36 How do I test ^:private fns?

8:36 I suppose, perhaps a better question: how do I import them?

8:36 opqdonut: ,(into {:a 1 :b 1} [{:a 2 :c 3} {:d 4}])

8:36 clojurebot: {:a 2, :b 1, :c 3, :d 4}

8:36 opqdonut: lvh: you can refer to them with #'name.space/function

8:36 lvh: our codebase has a (with-stolen [fun-name] ...) macro that does that for you

8:37 but I'm not aware of a library that has something like that

8:37 lvh: opqdonut: Ah. That's a reader macro, right? So I don't need to require the namespace or anything?

8:38 opqdonut: that's a reader macro, yes. you will obviously need to use/require the namespace to make sure it is loaded

8:44 shep-werk: lvh: to be /that guy/, why test private functions?

8:44 lvh: shep-werk: I want to check if they work

8:44 shep-werk: Test the public interfaces, or move the private function somewhere public

8:44 lvh: I just don't want to expose them as api

8:44 shep-werk: [this is something I've spent time arguing in Ruby-land :-)]

8:44 opqdonut: unit tests for implementation are valuable

8:45 shep-werk: move them from myproject.core to myproject.impl

8:45 core is your api

8:45 lvh: maybe I'm amking things private that shouldn't really be, idk

8:45 opqdonut: sure that's the workaround

8:45 shep-werk: impl isnt publically consumable

8:45 opqdonut: my argument is that it's not a workaround

8:45 opqdonut: the thing I hate about .impling is that it makes reading the code nonlocal

8:46 shep-werk: in OOP land, my first reaction is to move private methods into a new object that is public

8:46 there, the important thing is that the state held by the original object is still private

8:46 but the implementation (the new object) can be public

8:46 opqdonut: well the thing I hate about reading java code is that it is so nonlocal :)

8:46 shep-werk: My FP experience is far less extensive though

8:46 tbaldridge: +1 for using two namespaces

8:47 opqdonut: the .impl solution fits some namespaces, but private functions definitely have their place IMO

8:47 shep-werk: and honestly, I would stay away from "impl" namespace; I bet there's a better, semantic, useful name

8:47 tbaldridge: almost every time I create a private defn I want a time machine later....so I can go back and time and kick myself for doing that again.

8:47 *in time

8:48 opqdonut: why?

8:48 clojurebot: why not?

8:48 tbaldridge: +1 clojurebot

8:48 shep-werk: I agree that private fns are useful, but if they are, you should be able to test them completely through whatever public interface uses them

8:48 tbaldridge: opqdonut: I try to trust my users. If they want to muck around with a private function, they should be free to do so. If it's really not part of the public api it should be in a different ns

8:49 but still open for a user to muck around with.

8:50 To me, making something private is like telling a user "I know more than you....you don't want this".

8:50 opqdonut: for a utility-like library private things might not make less sense, but for a product yes

8:51 errr

8:51 s/less//

8:51 shep-werk: tbaldridge: agree; that's something I hit as a developer-user - "I want to take what you did and stick it back together in some different way"

8:51 noidi: I agree in principle, but I don't mind ^:private, as it's so easy to bypass

8:52 tbaldridge: agreed, and I absolutely hate it when that developer-user is me, and I'm limited by someone else's close-minded view of how their code should be used. Especially when that person is also me :-)

8:52 noidi: just call #'some.ns/some-private

8:53 I think Clojure's access protection mechanism is the best of both worlds. it prevents you from depending on implementation details *accidentally*, but makes it easy to do so if you really want to.

8:53 ior3k: tbaldridge: are you talking in general, or when developing libraries?

8:53 tbaldridge: ior3k: both.

8:54 I literally have never used ^:private and later gone back and said "I'm glad I did that".

8:54 opqdonut: I have

8:54 when somebody else has used less time wrapping their head around the api because it's smaller

8:54 tbaldridge: opqdonut: can/should be done by using a impl ns

8:54 opqdonut: but I am working in a single large code base, we can always just make things public if we need them

8:55 .impl works sometimes, but sometimes it just breaks up the flow of the code

8:55 have to continuously jump back and forth between two nss when reading

8:55 chouser: when I can change the api of a fn without worrying about users, because it's marked ^:private.

8:55 tbaldridge: also, done via a impl ns.

8:56 core.async does this, anything in clojure.core.async is more or less fixed. Everything else is subject to change without notice.

8:56 chouser: so we're not arguing about private fns, but over the mechanism?

8:56 lvh: tbaldridge: oh, hi; I just wanted to say that you are an inspiration to a newbie clojurist, please keep up the good work

8:57 tbaldridge: chouser: what I don't want is the language saying "no you can't do that". Or making it harder in some way. with a impl ns all I really need to do is :require the impl ns

8:57 chouser: #'shrug

8:57 ToBeReplaced: tbaldridge: interesting perspective; in python, the accessibility of private-by-convention made it so that libraries in the stdlib couldn't change private functions because (dumb) third party libs would break

8:57 tbaldridge: with ^:private I have to use the #' hack (and then remember to deref values) or go back and change the code.

8:57 ior3k: I think private fns are great to limit the size of each module's public api *in application code*, where things can be easily changed

8:58 tbaldridge: ToBeReplaced: but did Python actually put those private fns somewhere else?

8:58 opqdonut: ior3k: that's what I've been trying to say

8:58 ToBeReplaced: tbaldridge: so similar to an impl namespace, and it caused a lot of problems in the evolution of the lang

8:58 ior3k: the act of switching an fn from private to public says something to readers

8:58 (during code review)

8:58 ToBeReplaced: tbaldridge: no, but does that matter? impl.foo or _foo seem similar... i guess easier to see "you're doing something dangerous!" with impl

8:59 lvh: tbaldridge: nah; they're usually on the same object.

8:59 ddellacosta: the only use I've found for private functions is as small helpers for my larger kind-of-imperative-wraps-a-complex-process function, which I usually test itself so I'm not testing the private functions. As others have observed usually if I find that I can't test a private function without...testing a private function, it should be public.

8:59 tbaldridge: ToBeReplaced: right, I understand now, the _thing. So yeah, in that case I would say, change it and let the broken libs fix themselves. This is pretty much the way Clojure has done it all along. Use a private API be prepared to be less portable.

9:01 ToBeReplaced: tbaldridge: right, so that was the idea with python... except that decision was unrolled and it was decided that private functions could not change in the stdlib because even though everyone was warned, removing them still caused problems

9:01 tbaldridge: maybe there's a distinction there between "core" and "everything else" though

9:01 ior3k: ddellacosta: I don't know... I think the larger the public api is, the more chance there is for increased coupling. I think making fns public so they can be tested is *complecting* (heh) 2 different things

9:02 opqdonut: agreed

9:02 ior3k: 1. that there is value in testing a given fn and 2. that there is value in making an fn public

9:02 ddellacosta: ior3k: let me rephrase--if I find that I'm trying very hard to test the behavior of a private function, and I can't get at it for some reason, it shows me my design is wrong. I suppose it's not necessarily case that it means that those functions should be public--but it does mean probably *something* should that isn't.

9:03 *should be

9:03 opqdonut: how is accessing private fns hard in tests? just #'

9:03 or were you talking about some other language perhaps

9:03 ior3k: ddellacosta: to me that's usually an indication that the fn is doing too much

9:03 ddellacosta: opqdonut: the point is that you if you are testing private functions you are testing the wrong thing. I agree with shep-werk.

9:03 ior3k: yep, definitely.

9:05 shep-werk: ToBeReplaced: the python thing is interesting, but I can see the same thing happening in Clojure

9:05 at least, it's technically possible, and it's not hard to access ^private functions, right

9:06 in Java, you have to use reflection to get at them, and IMO it's too painful, so it's less likely there

9:08 ToBeReplaced: shep-werk: i think the access is easy enough that anyone who wants it can get it... i think with clojure as small as it is, few will depend on it. i think if clojure gained much wider adoption, we'd see lots of it, mirroring the python history

9:09 shep-werk: ToBeReplaced: perhaps, but I have a feeling that clojure might get away with it too - you can just move the old/broken fns to a new lib & namespace and folk can use them

9:09 unlike in OOP where they would be more tied to the class

9:10 maybe :-)

9:10 ToBeReplaced: and the packaging is a much better story, so you might be right

9:11 ddellacosta: ToBeReplaced: Clojure's packaging > Python's? I hear people complaining about Python a lot but

9:11 ...don't know much about it's packaging options

9:11 *its

9:16 ToBeReplaced: ddellacosta: not necessarily "worse"... just that it makes things like "need two different versions of library x" impossible

9:17 ddellacosta: ToBeReplaced: ah, okay. Not that I find that particularly simple in Clojure, but I guess it's possible.

9:17 ToBeReplaced: ddellacosta: it used to be a really bad story, then virtualenv became popular maybe 6 or 7 years ago and it got very reasonable

9:17 ddellacosta: ToBeReplaced: ah, okay. I'll have to read up on that...heard of it but don't know much about it.

9:18 ToBeReplaced: ddellacosta: yeah i've never done it in java / never had to, but it oddly came up often for me in python

9:21 ddellacosta: unrelated to public/private, but having the jvm is big edge for distribution on internal infrastructure as well... in python we're only recently getting "wheels" (full support wasn't there last year)... before that you had to roll your own for precompiled libs on your platform

9:26 shep-werk: ToBeReplaced: you mean two versions at the same time used by the same app? or just two versions installed on the system somewhere?

9:29 ToBeReplaced: by same app is nigh-impossible in python... i think you could hack the classloader?... it's hard in java but i thought possible?

9:30 on the system it is impossible in python (no more than one version per python version), but virtualenvs help salvage that when writing applications... when writing libraries, it's a blocker

9:30 shep-werk: that is also my understanding; but was willing to be surprised by python :-)

9:31 honza: jballanc: load factor?

9:32 clgv: Anderkent: I don't get out of memory errors at all - it just dies; this is with 6GB of xmx

9:39 clgv: honza: but you should get those. maybe there is a very general try-catch somewhere that suppresses them

9:40 honza: clgv: no try catch, it's right in the core's main - but i'll keep looking

9:40 clgv: honza: as I said, 1 million keys is no problem here

9:40 honza: 10 million works as well

9:41 honza: clgv: what's your -Xmx?

9:41 (or other JVM args)

9:41 clgv: honza: (count (into {} (map vector (range 10000000) (range 10000000)))) though there is some garbage collection going on

9:41 plain "lein repl" without any project

9:41 honza: ok

9:42 clgv: I have a 16GB RAM here though

9:42 opqdonut: jvm uses 1/4 ram as the default heap size IIRC

9:42 (maximum heap size, that is)

9:42 rurumate: how to convert IPersistentList to a java collection?

9:43 opqdonut: it already implements the java List interface

9:43 honza: 8gb ram here, plain lein repl dies with 10M

9:43 clgv: rurumate: sth like that (doseq [x pst-lst] (.add java-coll x))

9:43 honza: with OOM?

9:43 honza: clgv: yes, sorry

9:43 clgv: honza: thats expected then ;)

9:45 honza: 1M works on 8gb Xmx, weird

9:45 your (count ... example works, not my original code

9:45 essentially, i'm loading a big ass json file, which is about 500MB

9:46 but it's becoming clear that i'll have think of a different solution

9:48 shep-werk: honza: http://stackoverflow.com/questions/444380/is-there-a-streaming-api-for-json ?

9:48 stream it instead of loading all at once, maybe?

9:48 honza: shep-werk: tried that, no luck :(

9:49 shep-werk: sad times

9:49 honza: it's a deeply nested map, so it just hates me

9:49 shep-werk: Is it a single 500MB key? :-D

9:49 honza: LOL

10:10 jballanc: honza: if you have a map with 3mil entries, it will allocate space for no fewer than 4mil entries

10:10 honza: jballanc: oh i see

10:11 jballanc: honza: that's the hashmap's load-factor...the fuller a map gets, the more likely collisions become, the less like O(1) lookups are

10:11 so hashmaps tend to keep lots of extra space around

10:11 honza: right, right

10:11 jballanc: if you have a set of fixed size, a hashmap is actually a really inefficient data structure

10:21 CookedGryphon: hey, is it possible to do cider-jack-in with a profile, without just running lein repl :headless separately?

10:44 fowlslegs: ,(def mi (atom "mi"))

10:44 clojurebot: #'sandbox/mi

10:44 fowlslegs: ,(swap! @mi str/replace #"(\w+)" "$1u")

10:44 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: str, compiling:(NO_SOURCE_PATH:0:0)>

10:44 fowlslegs: ,(swap! @mi clojure.string/replace #"(\w+)" "$1u")

10:44 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Atom>

10:45 fowlslegs: How do I order this correctly if I want "mi"->"miu"

10:45 Nvm

10:46 I just needed to get the @ out of there.

10:54 gfredericks: has anybody used incanter on 64-bit ubuntu?

10:54 clgv: gfredericks: yes but only older versions

10:55 I still have it as dependency for legcy code but dont use it that often... currently I depend on 1.5.2

10:58 boothead: Hi folks, is it acceptable to ask about recruiting clojurians here? (I'm not a recruiter by the way)

11:00 llasram: boothead: I'm not sure I've seen it done, but you won't get kicked for it (modulo being disruptively obnoxious)

11:00 boothead: You might have better luck sending a message to the Clojure users mailing list. It's relatively common there

11:01 boothead: llasram, I shall do my best not to be obnoxious :-) I'm trying to get the lay of the land really - being quite new to clojure and not really part of the community in London

11:04 llasram, my general question is about the state of the client side clojure(script) eco system. I have a backend implemented in Haskell and I'd like to realise some of the FP benefits with the front end as we have with the back

11:04 gfredericks: clgv: okay interesting; I imagine you never saw any errors about needing lib3fortran3?

11:05 llasram: boothead: Interesting. There are some Clojurescript people here, although I'm not one of them. I believe there's also a #clojurescript

11:05 gfredericks: I have this problem on a fresh project with ubuntu 12.04, and it seems odd to me that other folks aren't having the problem

11:05 boothead: oooh shiney! thanks for the steer - I didn't realise there was another channel!

11:08 clgv: gfredericks: no. but I have never used any matrix capabilities of incanter

11:23 gfredericks: hmm

11:24 clgv: I get the problem for (stats/linear-model [1 2 3] [4 5 6])

11:25 clgv: gfredericks: did you see https://groups.google.com/forum/#!msg/incanter/wzjQ0qZNuT0/oESo3vDyACUJ ?

11:28 gfredericks: clgv: looks relevant

11:28 thanks

11:28 I'm in the category of having successfully installed libgfortran3 but still having the issue

11:29 clgv: humm maybe some path issue?

11:31 gfredericks: weird. the linear-model example from the group post just works here

11:32 gfredericks: Linux Mint 16 which is based on Ubuntu 13.10

11:33 gfredericks: libgfortran is installed in /usr/lib/gcc/x86_64-linux-gnu/4.8/ and /usr/lib/x86_64-linux-gnu/

11:33 fowlslegs: How do I use the back reference \n to change the nth match for a capturing block, e.g., "miiiuiiii"->"miiiuiu", where I'm changing the third "iii" string to "u"? Can someone show me with str/replace? Thanks.

11:43 supersym: I can do first, second on a hash-map but what's the idiomatic way to get nth?

11:43 rasmusto: ,(nth 2 {:a 1 :b 2 :c 3})

11:43 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Number>

11:43 technomancy: supersym: nth on a hash-map doesn't make sense

11:43 rasmusto: ,(nth {:a 1 :b 2 :c 3} 2)

11:43 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap>

11:43 technomancy: they're not ordered

11:44 rasmusto: ,(nth (seq {:a 1 :b 2 :c 3}) 2)

11:44 clojurebot: [:b 2]

11:44 supersym: ok so first and second don't either then?

11:44 rasmusto: but yeah, doesn't make sense

11:44 technomancy: supersym: they don't make sense, but they're supported more or less on accident

11:44 bbloom: eh, first makes a little sense

11:44 it's essentially "sample one"

11:44 supersym: ah alright then... thanks

11:44 bbloom: w/o randomness of any kind

11:45 supersym: bbloom: true

11:46 gfredericks: clgv: I only see fortran in the latter of those two paths

11:53 myguidingstar: hi all, I'm new to core.logic. What is 'unique' optional argument to 'lvar' for?

11:54 gfredericks: Raynes: fs requires java 7?

11:57 hiredman_: myguidingstar: use fresh

11:58 muhoo: i upgraded to om 0.5.1 and my advanced compilation is giving errors: "Use of undeclared Var om.core/IAtom"

11:58 myguidingstar: hiredman_, I'm seeing this http://jonase.github.io/kibit-demo/#32

11:58 muhoo: also, the advanced compiled app crashes with the dreaded "Uncaught TypeError: Cannot read property 'object' of undefined "

11:59 myguidingstar: and trying to comprehend the lvar there

11:59 muhoo: in core.cljs type->str

11:59 clues?

11:59 dnolen_: ^

12:00 this was from om 0.5.0 -> 0.5.1 works perfectly on 0.5.0

12:00 dnolen_: muhoo: you need to use CLJS 2173

12:00 muhoo: and you also need to clean out your stale build

12:01 muhoo: i did lein cljsbuild clean will upgrade to 2173, thanks!

12:02 myguidingstar: hiredman_, anw, I know fresh already but sometimes we need more control, right?

12:06 hiredman_: myguidingstar: if kibit proceeds via unification, then it must be the same as (lvar)

12:07 myguidingstar: hiredman_, Ok, but can you answer my very first question?

12:08 mikerod: bbloom: seq on a hash-map is consistent though right?

12:08 dnolen_: myguidingstar: it's so that var equality isn't tied to reference equality, useful when building Datalog style syntax

12:08 bbloom: mikerod: only in that it's deterministic and hash-map is immutable

12:09 mikerod: if you add or remove items to it, there's no promises about the order remaining consistent in any useful way

12:09 dnolen_: '(?x ?x), using (lvar '?x false) means that both occurrences of ?x are considered the same

12:09 mikerod: bbloom: that makes sense

12:10 myguidingstar: dnolen_, I'm afraid I don't get it. I haven't touched Datalog, either

12:10 mikerod: bbloom: I remember reading a heated discussion over if: (= m (zipmap (keys m) (vals m))) ; was always true

12:11 hiredman_: dnolen_: but if kibit is doing the pattern thing via unification, any not ground lvar will unify with anything else, so why do that?

12:11 mikerod: I think this would rely on seq to be consistent

12:11 myguidingstar: is there any other use case?

12:11 dnolen_: myguidingstar: there's not much more to explain, I'm also not understanding why you need to know this implementation detail?

12:11 bbloom: mikerod: i'd imagine that the implementation achieves that invariant and it's unlikely to break

12:11 rasmusto: mikerod: I remember that too, I was told yesterday that keys/vals is dependable

12:12 mikerod: http://dev.clojure.org/jira/browse/CLJ-1302

12:12 I followed this one day

12:12 dnolen_: hiredman_: if you don't do it then the unification map is going to be ugly

12:12 fowlslegs: ,(clojure.string/replace "miiiuiiii" #"(iii){1}" "u")

12:12 clojurebot: "muuui"

12:12 rasmusto: fowlslegs: hah, that's a good chapter

12:12 mikerod: Then Rich said "keys order == vals order == seq order"

12:13 fowlslegs: I'm trying to get "miiiuui" can someone help me w/regex?

12:13 bbloom: mikerod: and this patch was apparently applied: http://dev.clojure.org/jira/secure/attachment/12760/clj-1302-2.patch

12:13 mikerod: yeah, I noticed the " in the same order as (seq map)" part

12:14 hiredman_: mikerod: has been saying that for years

12:14 myguidingstar: dnolen_, cos I don't get that part of kibit demo. Well, I should come back to this later

12:14 mikerod: and I started thinking, can (seq map) change from call to call; that doesn't seem to make sense

12:15 fowlslegs: rasmusto: I'm trying to evolve an algorithm that will solve it.

12:16 rasmusto: fowlslegs: I'm not sure if regex is the best option here. can you treat it like a seq of symbols and partition it to find all of the possible substitutions?

12:16 dnolen_: myguidingstar: that's probably for the best :)

12:17 rasmusto: ,(partition 3 1 '[m i i i u i i i i])

12:17 clojurebot: ((m i i) (i i i) (i i u) (i u i) (u i i) ...)

12:17 fowlslegs: rasmusto: This must work for any arbitrary string.

12:17 szymanowski: hi, how can i see all the protocols that a Record satisfies?

12:18 fowlslegs: I need to figure out how to replace the nth instance of a matched block.

12:18 ,(clojure.string/replace "miiiuiiii" #"(iii)" "u")

12:18 clojurebot: "muuui"

12:18 rasmusto: fowlslegs: well yeah. You can treat the string as a seq then. ##(partition 3 1 "miiiuiiii")

12:18 lazybot: ⇒ ((\m \i \i) (\i \i \i) (\i \i \u) (\i \u \i) (\u \i \i) (\i \i \i) (\i \i \i))

12:18 rasmusto: I'm saying that regex might be hard because it's greedy

12:18 hiredman_: myguidingstar: imagine it as a really annoying way to write (let [v (lvar)] (rule [`(+ ~v 1) `(inc ~v)]))

12:20 which, ugh, they have the let and still do it for no reason in the second example, :/

12:20 jonasen: hiredman_: as in the example below

12:21 hiredman_: jonasen: right, but in the example below there is no reason for the arguments pass to lvar

12:21 mikerod: I guess where I was going with that is, is Clojure `seq` consistent when called with the same obj, unchanged

12:21 jonasen: hiredman_: you mean the false in (lvar 'x false)?

12:22 hiredman_: jonasen: I mean all of the arguments

12:22 dnolen_: hiredman_: sorry I'm not actually really looking at the kibit, just explaining why the feature exists at all :)

12:22 hiredman_: dnolen_: sure

12:24 myguidingstar: hiredman_, that makes sense

12:24 jonasen: hiredman_: you mean that it's possible to use unification directly, and skip the 'rule' function entirely? as in this "quiz": https://github.com/jonase/kibit-demo/blob/master/src/kibit_demo/quiz.clj

12:25 hiredman_: jonasen: no, it looks like it is required due to the way prepare works, it just isn't required in the example on that slide

12:26 supersym: \q

12:26 hiredman_: basically, it seems like implementation details are leaking backwards from the implementation into what are supposed to be simplified examples

12:27 Raynes: technomancy: http://rain.ifmo.ru/~olegfink/ocaml.html

12:28 jonasen: hiredman_: those slides describe the implementation.

12:29 hiredman_: jonasen: I imagine the stuff after Rule v.2 (slide 42) does, but does the stuff on slide 33?

12:31 jonasen: hiredman_: slide 33 describes a first (flawed) implementation attempt. It's an attempt to explain what ?x (and 'prepare') is

12:33 hiredman_: myguidingstar: right, so you should skip over the flawed implementation slides :)

12:34 myguidingstar: :> anw I learnt something new

12:34 thanks jonasen for the demo

12:39 edw: Anyone seeing freezes with the latest Emacs 24.4 + CIDER?

12:39 jonasen: hiredman_: myguidingstar: At the meetup I was going to buy a beer to the first person who solved the question at: https://github.com/jonase/kibit-demo/blob/master/src/kibit_demo/quiz.clj but I didn't have time to show it... It's not difficult at all but it took me a while to figure out.

13:06 johnjelinek: hihi all :)

13:06 got a core.async question: https://www.refheap.com/52528

13:06 why does my channel reader only get the first response?

13:06 rasmusto: fun fact: hihi means goodbye

13:07 johnjelinek: rasmusto: in what language?

13:07 rasmusto: danish

13:07 johnjelinek: rasmusto: learned something new today :) thanks

13:08 rasmusto: technically its hejhej :p, and its conversational

13:08 johnjelinek: ahh, that's not quite the same thing

13:08 maybe you can help me with my core.async question?

13:08 rasmusto: I'm reading the code, don't know how helpful I can be

13:09 johnjelinek: perhaps I need a while true in there

13:09 or some way to loop

13:10 rasmusto: johnjelinek: yeah, I believe that's true

13:10 johnjelinek: rasmusto: ahh, got it

13:10 rasmusto: do you mean to call data-request in data-caller?

13:10 johnjelinek: data-request makes an HTTP request

13:10 data-caller initiates the request and listens on the channel

13:10 rasmusto: oh, I just didn't see a quote-request called

13:11 er, defined

13:11 johnjelinek: I got it to work with (doseq [_ (range 2)] ...)

13:12 example call: (quote-caller {:my-options})

13:12 so, let's say I didn't know how many responses to expect, what would I need to do in that scenario?

13:13 rasmusto: doens't a channel emit nil when things are done writing to it?

13:13 (I've done a few async tutorials, that's the extent of my knowledge)

13:13 johnjelinek: gotcha

13:13 dunno ... I think nil's are not allowed on channels

13:14 edw: Looks like the cider-eldoc integration in the latest cider is freezing emacs.

13:19 terpa: ola

13:20 ola pessoal

13:20 johnjelinek: question: when is (do necessary?

13:20 terpa: are you fron

13:20 johnjelinek: it seems sometimes I can stack expressions and it executes everything

13:20 other times I need a do

13:20 rasmusto: johnjelinek: when you need to do multiple things. fn has an implicit one

13:20 as does let

13:20 terpa: i from brazil

13:21 johnjelinek: ahh, I see

13:21 thanks

13:21 terpa: ?

13:21 dkinzer: johnjelinek: like for instance when you want the consequent or alternative in an if expression to d more than just one thing.

13:22 johnjelinek: dkinzer, rasmusto: so I can remove the do at line 7 here? https://www.refheap.com/52528#L-7

13:23 rasmusto: ,(macroexpand `(doseq [a [1 2]] (prn a) (prn "blah")))

13:23 clojurebot: (loop* [seq_27 (clojure.core/seq [1 2]) chunk_28 nil count_29 ...] (if (clojure.core/< i_30 count_29) (clojure.core/let [sandbox/a (.nth chunk_28 i_30)] (do (clojure.core/prn sandbox/a) (clojure.core/prn "blah")) (recur seq_27 chunk_28 count_29 (clojure.core/unchecked-inc i_30))) (clojure.core/when-let [seq_27 (clojure.core/seq seq_27)] (if (clojure.core/chunked-seq? seq_27) (clojure.core/let [c__...

13:23 rasmusto: johnjelinek: ^ there's a do in there somewhere

13:24 johnjelinek: I see

13:25 amalloy: rasmusto: amusingly, the 'do in the macroexpansion is unnecessary too

13:25 since it's (let [x y] (do ...))

13:25 rasmusto: amalloy: hah, good point!

13:27 amalloy: but it's there for a good reason, i suspect: `(do ~@xs) is an easier base case for the recursion than trying to avoid the do

13:29 dkinzer: do's are also kind of unnessary since one can do the same thing using an anonymous function. But then maybe that doesn't get evaluated in order and that's the point of dos. Not sure.

13:30 rasmusto: ,(macroexpand `(fn [] (prn "foo") (prn "bar")))

13:30 clojurebot: (fn* ([] (clojure.core/prn "foo") (clojure.core/prn "bar")))

13:30 rasmusto: ,(macroexpand `(fn* ([] (prn "foo") (prn "bar"))))

13:30 clojurebot: (fn* ([] (clojure.core/prn "foo") (clojure.core/prn "bar")))

13:33 dkinzer: ,(fn [] (prn "foo") (prn "bar"))

13:33 clojurebot: #<sandbox$eval101$fn__102 sandbox$eval101$fn__102@1f6d265>

13:37 bbloom: naming things is *hard*

13:37 dkinzer: ,((fn [] (prn "foo") (prn "bar")))

13:37 clojurebot: "foo"\n"bar"\n

13:37 rasmusto: bbloom: what are you naming?

13:37 johnjelinek: bbloom: it's one of the two difficult computer science challenges

13:37 dkinzer: what's the other hard part?

13:37 bbloom: I've got "Handlers", but a subset of the things that it manipulates might be called "Handles"

13:38 johnjelinek: dkinzer: cache invalidation

13:38 bbloom: a service which handles messages, vs an opaque reference indirection thinggie

13:38 Handler and Handle are clearly the best words separately, but together, it's confusing as hell

13:38 edw: bbloom: You're giving me classic Mac programming flashbacks. Pascal!

13:39 rasmusto: bbloom: Handlee?

13:39 AimHere: For added value, call the thing being handled the Handlee

13:39 dkinzer: :) funny I had a cache issue today. Something was sticking around longer than needed.

13:39 AimHere: Damn

13:39 Beaten

13:39 johnjelinek: dkinzer: :)

13:39 bbloom: heh. "Message" works just fine there :-P

13:40 maybe i should rename "Handle" to some synonym and just do the comp sci world a favor by helping disambiguate

13:40 We've got Pointers, References, and Handles... let's add "Grips" or "Hilts"

13:40 AimHere: Knob

13:41 bbloom: haft, shank, stock, shaft, grip, handgrip, hilt, helve, butt; knob

13:41 hyPiRion: bbloom: yeah, rename it to butt. No ambiguity there

13:41 or shaft, for that matter.

13:41 bbloom: pointers, references, and butts

13:41 clearly the correct answer.

13:41 AimHere: There needs to be more butts, knobs and shafts in computer jargon

13:43 edw: bloom: Sling? What attaches to a handle? A baggage tag?

13:44 noprompt: heh, just tabbed over and saw this discussion.

13:44 i'm all for butt.

13:45 johnjelinek: https://www.refheap.com/52538

13:45 bbloom: stupid english and your words.

13:45 johnjelinek: how should I make aggregate so that it becomes a collection of responses from the channel?

13:51 no thoughts?

13:51 #(println %) prints each message from the channel, but I want to build up a list

13:57 sdegutis: I've never gotten around to learning core.async because either I never had a need for it, or I don't understand what it is sufficiently enough to realize I do have a need for it.

14:00 systemfault: Hmm, core.async is what made me want to learn clojure :P

14:01 The videos by Tomothy Baldridge and the one by Rich Hickey on youtube were awesome.

14:01 johnjelinek: systemfault: wanna help me with my question? https://www.refheap.com/52538

14:02 I use take! to pass the channel to a function and I want that function to be able to build an aggregate

14:02 a list or vec

14:03 ptcek: I am trying to put regex as a key into a map, seems it is not possible. So just put there the pattern and get back regex with re-pattern? Any better way to do it?

14:04 systemfault: johnjelinek: I'm still learning, I don't think I'm at a point where I could help you

14:04 Pate_: where should I ask about the average costs of hosting Datomic on AWS' DynamoDB?

14:04 johnjelinek: systemfault: ok, thanks

14:06 huzzah! I got it with an atom

14:07 justin_smith: johnjelinek: if you want the aggregate to be accessible as it is being built you probably want to pass the reading loop a ref or atom that it will put things onto

14:07 if you are OK with it just returning it when done, you can have it construct a lazy seq that it eventually returns

14:08 johnjelinek: how would I have it construct the lazy seq? I've got the scenario using an atom working

14:08 zanes: I'm trying to use Slamhound through slamhound.el / nREPL. It appears to launch its own Java process, which is weird because the README seems to indicate that it should be using the nREPL session instead. Anyone have insight into this?

14:11 justin_smith: something like (loop [result ()] (if-let [new (<! channel)] (recur (cons new result)) result)) ... that's just a sketch mind you

14:11 there is probably some more appropriate looping function I am forgetting that you could use for that

14:12 chouser: Is that similar to (repeatedly #(<! channel)) ?

14:12 justin_smith: difference being you know when you are done

14:13 rather than it being always implicitly infinite

14:13 (take-while identity (repeatedly #(<! channel))) maybe?

14:13 that is cleaner

14:16 yong1: Hey guys I have a design question I was hoping someone can help me with.

14:16 Basically I have an online algorithm that takes in its previous internal state, a new piece of data, and outputs a new internal state and the result. The problem is that these online algorithms can depend on child online algorithms, which might be repeatedly used. So managing the state of your children manually becomes a chore, and will cause repeated computations of the child algorithms.

14:17 Some sort of memorization will solve this problem, but it seems too "magical", not to mention potential problems with GC. Is there a well known Clojure pattern for dealing with this scenario?

14:18 justin_smith: well, there is the memoize function

14:18 there is also core.cache with it's protocol if you want to be fancier about what cached values to keep vs. drop and when

14:19 https://github.com/clojure/core.cache

14:19 yong1: Yeah I looked into that

14:19 Hmm, I don't like that it's hiding the state in some hidden hash table

14:19 justin_smith: I tried to use core.cache and either a) I am not skilled enough to use it properly b) it is overengineered or c) all of the above

14:20 yong1: with unpredictable behavior

14:20 justin_smith: which one is unpredictable?

14:20 memoize is predictable - same args give you the same result

14:20 yong1: unpredictable with regards to memory usage

14:20 part of the reason I want an online algorithm is to save memory in the first place

14:20 justin_smith: it's predictable if you know how often your args will be unique

14:21 yong1: Weak refs might work

14:21 justin_smith: but not very nuanced in terms of how to keep its usage small

14:21 sounds like a least-used or ttl based cache may be useful for that?

14:22 yong1: Yeah I can certainly make memoization work. I just wonder if there is a better way or if there is a more specific name other than memoization.

14:24 justin_smith: https://github.com/clojure/core.cache this either has what you want, or has the tools to build what you want

14:25 I think, as I mentioned I tried to use it at one point and gave up on it (likely because I did not sufficiently understand what I was trying to do)

14:25 dbasch: sdegutis: this is how I ended up solving my authorization / redirect problem: https://www.refheap.com/52547

14:26 yong1: well, thanks. I'll probably go with memoization of some sort

14:26 joegallo: ptcek: no, there isn't, sadly.

14:27 java.util.regex.Pattern uses the default hashCode/equals from object, so you can't use instances of them like values

14:27 ,(= #"foobar" #"foobar")

14:27 clojurebot: false

14:27 joegallo: ,(.pattern #"foobar")

14:27 clojurebot: "foobar"

14:27 joegallo: will give you a string, though, which you could use

14:28 and then you can re-pattern it back to a regex later, as you've figured out

14:28 https://bugs.openjdk.java.net/browse/JDK-7163589

14:30 pjstadig: yeah, but should #"foo" be equal to #"[f][o][o]"?

14:30 in general you can't compare the equality of programs, and regexen are programs

14:31 joegallo: perhaps i'm naive, but i think it would be fairly reasonable to have the hashCode and equals be based on the text of the thing

14:31 but you're right -- that wouldn't be an indication of whether the patterns were truly and deeply equal in the sense of "doing the same thing"

14:33 pjstadig: well even comparing strings wouldn't work

14:33 joegallo: enlighten me

14:34 pjstadig: because the same pattern string with different flags can do different things

14:34 it may seem wrong, but it's The Right Thing for regexen to have identity equality semantics

14:35 johnjelinek: what's a good way to time (without blocking) the time it takes for a future to complete?

14:35 joegallo: pjstadig: i accept your rebuttal

14:36 pjstadig: joegallo: look. i'm not saying i like it :)

14:36 joegallo: :)

14:41 steckerhalter: am I doing something wrong here? (.connect (java.net.Socket.) (java.net.InetSocketAddress. (java.net.InetAddress/getByName "google.com") 80) 500)

14:41 sdegutis: dbasch: looks good

14:42 justin_smith: you probably want to hold onto that socket

14:42 but I assume you were already doing so

14:43 steckerhalter: ah... I see what you mean

14:43 thanks

14:43 justin_smith: it's an oo / mutation thing, not a functional thing. You need that mutated object before you do anything else :)

14:44 mklappstuhl: how do I update dependencies in a leiningen project?

14:44 johnjelinek: how would I catch exceptions in core.async?

14:44 mklappstuhl: found lein-search but thats 3 years old

14:44 justin_smith: change the numbers in project.clj and run lein clean

14:44 johnjelinek: I'm issuing 26 HTTP requests, and my channel is only sending back 21-23 responses

14:44 mklappstuhl: justin_smith: is there no automatic way of detecting outdated deps?

14:44 justin_smith: or do you mean automatically find the latest deps?

14:44 mklappstuhl: justin_smith, yes

14:45 justin_smith: https://github.com/xsc/lein-ancient

14:45 but you still need to edit the deps in project.clj manually

14:45 oh wait, it even has :interactive

14:45 weird

14:47 mklappstuhl: justin_smith, nice that was exactly what i was looking for

14:51 Fluffums: I'm a complete beginner, but I'm looking to learn Clojure by setting up a basic web application on a Koding.com VM. Would someone mind pointing me toward a resource that might help me figure out how to get my ring server configured to serve up pages? I've run "lein new compojure myblog" successfully, and "lein ring server-headless" seems to be working, but if it's working, I can't figure out the URL for the starter page (such as ht

14:52 matthavener: Fluffums: i think the default is http://localhost:3000/

14:53 oh, koding.com VM, it would be your http://&lt;yourvmiporhostname>:3000/

14:53 Fluffums: matthavener: Since this is a headless cloud-based VM...

14:53 Right.

14:53 But http://daneweber.kd.io:3000 is no good. :-(

14:53 matthavener: i think server-headless spits out the port its listening on, if its not 3000

14:53 run "hostname" on your VM and see what it gives you

14:54 justin_smith: also, 3000 is likely not open by default

14:54 Fluffums: vm-0.daneweber.koding.kd.io

14:55 And when I start the ring server, it says it's listening on port 3000.

14:55 justin_smith: best practice is to run something like nginx, listening on 3000 and serving on 80 - it has security features that ring lacks

14:55 but for the meantime, check that port 3000 is open

14:56 try wget localhost:3000 from the vm shell

14:56 matthavener: yeah it looks like some koding.com thing is intercepting everything

14:56 justin_smith: if that works, then it's a port issue

14:57 another trick is to use the -L argument to ssh in order to forward the remote port to a local port

14:57 much more secure than letting randoms access ring directly

14:58 Fluffums: Ahh. Looks like Koding is the problem here. "wget localhost:3000" gets me the hello world index.html file.

14:58 justin_smith: right

14:59 so you need to put up something like nginx, or open up the port

14:59 the former is preferable

14:59 short term, ssh -L will totally work

14:59 Fluffums: Why nginx? (I'm looking at the site now...)

15:00 justin_smith: it has security features that ring's various backends lack

15:00 Fluffums: Apache is probably just as good for my beginner purposes though, right?

15:00 justin_smith: personally I would put nginx in front of apache, but sure

15:00 though I don't know that apache has some advantage over nginx (unless you already know the config syntax or something)

15:01 Fluffums: (already installed and working fine with PHP/Ruby/Python)

15:01 justin_smith: sure, then no harm in using apache

15:06 gfredericks: is anybody familiar with the details of how clutch compiles CLJS views?

15:07 ptcek: joegallo: thanks for confirming the fact :)

15:08 If I use some lib from clojars, can I redefine it's method from within my program while running?

15:09 noprompt: dnolen_: IDisplayName just needs to return a string right?

15:10 ptcek: %s/method/function

15:10 dnolen_: noprompt: yep

15:11 noprompt: dnolen_: hmm, ok we're still seeing <Unknown> :(

15:11 dnolen_: noprompt: you need to use React Dev Tools from master

15:12 noprompt: dnolen_: ah, gotcha.

15:12 thanks!

15:12 justin_smith: ptcek: check out robert-hooke for doing such things cleanly

15:12 https://github.com/technomancy/robert-hooke/

15:13 nodename: What is this :scope "provided" in some of Om's :dependencies?

15:13 noprompt: nodename: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

15:16 nodename: thanks

15:16 ptcek: justin_smith: nice tip, thanks

15:17 noonian: dnolen_: awesome work with the :instrument option!

15:18 noprompt: dnolen_: it's kind of bittersweet. because updating to 0.5.1 means we have to update cljs which means austin doesn't work.

15:19 firefaux: is there a way in seesaw to set a fixed height for a widget, but allow the layout manager to set the width?

15:19 I know I could do :size [x :by y], but I want a variable width

15:21 dnolen_: noonian: pretty useful.

15:22 firefaux: I guess I could use :minimum-size and :maximum-size, and just use the same height for both, but that's pretty hacky

15:22 dnolen_: noprompt: right you're just waiting on the next CLJS release to fix Austin.

15:23 noprompt: dnolen_: yep. :(

15:24 dnolen_: noprompt: i mean if you want to keep developing you can just run ./script/build on ClojureScript and work off master

15:24 noprompt: sync'ing the next ClojureScript release with Clojure 1.6 seems like a good idea

15:24 gfredericks: hooray prismatic/plumbing is going to get update

15:25 noprompt: dnolen_: when is that scheduled to land?

15:25 dnolen_: i mean it's not a big deal, we can just used livereload or something. it's a team thing so i can't expect everyone to work off master.

15:25 dnolen_: noprompt: soonish, 1.6-RC1 is probably going to happen this or next week and I suspect 1.6 shortly thereafter

15:25 noprompt: otherwise that'd be fine.

15:26 muhoo: what's the difference between a channel and a port?

15:26 noprompt: dnolen_: this is fine though, most of the people on the team are still new to working w/ a repl anyway.

15:27 dnolen_: muhoo: I think the idea is that a port would have more specific constraints, read/write only

15:29 muhoo: the async docs were confusing me. it talks about ports in positions i've always sen channels used (and referred to as channels)

15:29 dnolen_: muhoo: that's exactly right though

15:31 bbloom: ports are not reified in core.async

15:31 would be nice if they were

15:32 muhoo: http://golang.org/ref/spec#Channel_types is a good resource

15:32 aka: so as a newer clojure dev I setup the workflow mentioned here http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

15:32 bbloom: Go reifies "ports" in their type system

15:32 aka: it seems odd that I can't have a sing (def) in any of the project's namespaces for it to work

15:33 is that right or am I missing something?

15:33 bbloom: muhoo: essentially, a port is either the read or write end of a channel, which Go accomplishes not by using a different object at runtime, but by type constraints

15:33 muhoo: oh, i think lamina does that. there's a concept of a channel pair, which is a read and a write

15:33 bbloom: yeah, so in a dynamic language, you don't have the type system to help you

15:34 so there are two ways to reify the concept: 1) you can wrap a bidirectional channel in one of two wrapper objects that only implement the read or write half of hte channel protocols

15:34 or 2) you can create a composite bidirectional channel out of two halfs

15:34 muhoo: that makes a lot more sense, thanks

15:34 bbloom: i wish core.async did either, b/c then you'd get a runtime error if you try to read or write to the wrong type of port

15:36 as it is now, you can get undefined behavior if you violate the read/write contract of a function

15:36 i'd rather define the behavior to be an exception :-)

15:38 bob2_: aka, not really clear what you're trying to do

15:38 novochar: How should I go about writing e2e tests for my Om app?

15:42 muhoo: live that there are mix, mute, and solo functions in async. can tell rich was an audio engineer at one time.

15:43 bbloom: muhoo: i'd guess that he literally added those functions so that he could mix, mute, and solo audio in harmonakit

15:43 muhoo: then again, working with immutability in clj, datomic, etc, is a lot like using protools. all the takes are there, structural sharing

15:48 noonian: dnolen_: yeah, i was already trying to build something like that on top of om and this should make what i'm trying to do much easier

15:55 aka: bob2_: I followed Stuart's guide for (reset) in the repl but as far as I can tell it requires me to not use `def` at all more

15:55 I ust wanted to confirm that was correct but I think I found a blog post explaing it all

15:57 dissipate: i figured out how to fix 'shuffle'. i think i'm going to do implement this.

15:57 stuartsierra: aka: Using `def` itself is not the problem. The problem is having application state in mutable global Vars, like `(def … (atom …))`

15:57 dnolen_: noonian: yeah it seems like several people were so happy that my idea was a common case

16:01 dissipate: i think 'shuffle' should be implemented as an infinite sequence that uses core.async to block on lack of entropy available in the system. each time enough entropy becomes available to fill in the next spot in the collection, the shuffled collection gets 1 more value added to it, until it fills up.

16:02 from the infinite sequence you can 'take' as many shuffled collections as you want. any input on this idea?

16:02 Pate_: is anyone running Datomic in a Docker container for dev?

16:03 aka: stuartsierra: I believe I understand the reasons behind but I'd like to confirm that would mean I wont be using the def aside from in my user.clj and in the repl

16:03 dissipate: Pate_: which part of Datomic?

16:03 Pate_: the transactor + H2

16:03 stuartsierra: aka: It really depends on what your app is doing with the def.

16:03 Pate_: well, I'm still new to Datomic so I may misspeak on the different parts, but I understand the hosted part is storage + transactor.

16:04 llasram: dissipate: I have a hard time imagining when I'd want that vs just sampling with replacement

16:04 Or just (mapcat shuffle ...)

16:04 stuartsierra: When you change a file and call `reset`, tools.namespace will 1) find all files/namespaces that have changed; 2) find all their dependencies; 3) delete all those namespaces; 4) reload all those source files.

16:04 dissipate: llasram: what do you mean by 'sampling with replacement'?

16:04 llasram: dissipate: http://en.wikipedia.org/wiki/Sampling_with_replacement

16:05 noonian: if you resample you are sampling from the same set, not the set minus the item you just sampled

16:06 dissipate: llasram: so you are saying you wouldn't want to use 'shuffle' at all, or that you wouldn't use my version of 'shuffle'?

16:07 llasram: dissipate: If understood your proposal correctly, it would yield essentially the same result as `(mapcat shuffle (repeat coll))`

16:07 dissipate: I have a hard time imagining when I'd want that result, and wouldn't just be satisfied with the entropy quality of the verbatim code example

16:08 aka: stuartsierra: I was storing default values to be used in functions in the current namespace. I cleared all that out and it's working now and cleaner. Thanks for the explination I get it now.

16:08 dissipate: llasram: no it would not. the current version of 'shuffle' in the core is broken. it uses Java's 'shuffle', which does not generate all potential permutations of a collection.

16:08 llasram: Ah, I missed that

16:08 Well, or more specifically, wasn't aware of that issue with `shuffle`

16:09 (The Java stdlib shuffle.) Do you have a reference with details?

16:09 dissipate: llasram: to put it bluntly, the current implementation of 'shuffle' shoves under the rug underlying issues regarding entropy pools on common systems

16:09 turbofail: i can see returning a lazy sequence, maybe, but an infinite lazy sequence of shuffle elements doesn't seem to make sense

16:10 dissipate: llasram: http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#shuffle(java.util.List)

16:10 llasram: dissipate: Ok.... What are you doing where this is a problem?

16:10 OOC

16:10 turbofail: but if you want a truly evenly random permutation you're just going to have to wait for enough entropy to get the whole thing anyway

16:11 so the lazy sequence aspect of it is kind of pointless

16:11 dissipate: llasram: the documentation is vague, but the bottom line is, if your collection is too large, the underlying pseudorandom number generator will wrap back around before it can generate all possible permutations

16:11 johnjelinek: dakrone: hey :) are you around?

16:12 dakrone: johnjelinek: for a little bit, yes

16:12 llasram: dissipate: Sure -- I was just curious if you have a specific application where this is problematic

16:12 dissipate: llasram: it's a major problem for scientific and statistical calculations and especially for applications like online casinos where uniform distribution of permutations must be generated

16:12 johnjelinek: dakrone: I get "Connection reset" exceptions often with clj-http, even with {:throw-exceptions false}

16:13 is this exception not meant to be included in the {:throw-exceptions false} flag?

16:13 llasram: dissipate: Fair enough, although inability to control the source of randomness or random seed makes it pretty useless for those applications anyway

16:13 dissipate: llasram: for instance, in your population example, suppose i want to shuffle 7 billion elements representing humans on earth

16:13 dakrone: johnjelinek: that's Apache throwing the exception, so you'll need to handle catching that yourself, :throw-exceptions is meant to have clj-http not throw an exception on an HTTP error code

16:14 dissipate: llasram: this version of 'shuffle' would tap directly into the truly random entropy pool on the system and use core.async to block until the pool had enough entropy to generate a random value for the next value in the sequence

16:15 johnjelinek: dakrone: I notice there is a message in the exception that says it will retry the request, do you know how many times this retry will happen?

16:16 dissipate: llasram: i realize that if the entropy pool is not generating enough entropy, it could block for significant amounts of time, but that would expose the problem at the OS and hardware layer where it should be exposed.

16:16 dakrone: johnjelinek: search for ":retry-handler" on https://github.com/dakrone/clj-http/ and there's an example, that might work for you

16:18 johnjelinek: dakrone: nice -- do you know what the default retry count is though?

16:18 dissipate: llasram: what is your honest feedback on this approach?

16:19 dakrone: johnjelinek: I am going to hazard a guess and say 3, but I don't know off the top of my head

16:20 johnjelinek: dakrone: ok, thanks :)

16:23 dakrone: copied the retry example and got: "Got:Got:Got: Got: Got:Got: Got: #<#<UnknownHostExceptionUnknownHostException#< UnknownHostExceptionjava.net.UnknownHostException: api.tradestation.com> #<"

16:23 pretty strange

16:24 dakrone: johnjelinek: you can use the :ignore-unknown-host? option also

16:45 myguidingstar: Hi all, I'm an emacs novice and learning core.logic. I want some functions ending with "o" (like membero) in current buffer to have that 'o' in subscript form

16:45 how can I do that?

16:45 dsrx: yay, font locking

16:45 I don't think emacs can render subscript text, though I might be wrong

16:46 oops, I am wrong

16:47 myguidingstar: ok, we may use some unicode char instead

16:47 but how can I do that? Please help with some elisp

16:47 danielszmulewicz: myguidingstar: You could do what we do with lambdas: http://www.emacswiki.org/emacs/pretty-lambdada.el

16:47 myguidingstar: Your elisp has been served :-)

16:48 myguidingstar: thanks a lot danielszmulewicz

16:48 btw, I remember something like some elisp code at the end of a Clojure source file

16:49 (emacs will ask when open that kind of file)

16:49 what is it?

16:50 TimMc: myguidingstar: File-local variables?

16:51 That's the closest I can think of, but I'm no emacs expert.

16:51 bob2_: that'd be it

16:52 myguidingstar: that's it, thanks TimMc

17:23 justin_smith: buffer-local? or is there really such a thing as file-local?

17:23 oh, yeah, never mind, yeah file local it is

17:40 mikerod: How do I connect Visual VM to a leiningen REPL?

17:44 rasmusto: mikerod: just launch it. It'll show you one for leiningen's jvm and one for your app (iirc)

17:45 mikerod: rasmusto: hmm it doesn't look like I'm not seeing the app process. I'll keep digging.

17:50 abaranosky: anyone know about Clojure :line metadata?

17:50 is there anywhere to go read up on it, especially on which forms get the metadata added?

17:54 bbloom: abaranosky: LispReader.java (and Compiler.java) is pretty all you'll find

17:54 abaranosky: and i guess you need to check core.clj too, since various macros have to shepard that data around to vars

17:55 abaranosky: bbloom: cool, reading now :)

18:11 gfredericks: does anybody think it would be cools if data.csv took higher-level args?

18:11 dnolen_: huh running React on the JVM via JDK Nashorn seems promising

18:11 gfredericks: (or is there another CSV lib that does this?)

18:13 dnolen_: seangrove: ^

18:13 seangrove: dnolen_: Very interesting

18:13 Slightly bonkers, but pragmatic if it works

18:14 dnolen_: seangrove: seems fast enough to actually work in production, way faster than Rhino

18:15 seangrove: dnolen_: Better than Nodyn as well, then?

18:15 dnolen_: seangrove: Nodyn was a joke

18:16 seangrove: this invoke dynamic thing is pretty crazy

18:16 seangrove: dnolen_: I read good things about Nashhord when searching for a way to run React on the JVM

18:17 dnolen_: seangrove: once JVM is warm only seem 2X-4X slower than React under JavaScriptCore

18:17 which is

18:17 INSANE

18:17 and V8 too

18:21 seangrove: dnolen_: Heh, makes me feel sad for Meteor et al. Love the idea of not needing phantom for SEO.

18:22 aka: wow that's exciting to think of

18:23 Om serverside

18:23 seangrove: Hrm, I suppose it also means we could run most of our smoke tests server side too

18:24 qbg: hmm... Om + CSS generation = true separation of presentation and content?

18:25 muhoo: i'd be interested to see what happens when someone applies the om/react model to... android. or objc

18:25 qbg: or swing :p

18:26 muhoo: or some replacement for swing, sure.

18:26 seangrove: qbg: What do you mean CSS generation? Something like SASS/Garden?

18:26 muhoo: i think this is a bomb in the world of UI that will explode everything

18:27 qbg: seangrove: Not precisely. Local css like you generate local markup using Om

18:27 seangrove: qbg: Shadow-dom like?

18:28 muhoo: some good old-fashioned shiva-like creative destruction.

18:28 qbg: seangrove: yes

18:29 seangrove: muhoo: Maybe. I think the breakthrough will be in the tooling that can be built on top of Om. You can have IB-like interactions for designers, and smalltalk-like development experience with devs, with composable, reusable components

18:29 aka: I can't wait to add 500 smooth animated clocks to every site and app I make

18:29 muhoo: seangrove: yep, i'm about to lift your draggable window out of omchaya :-)

18:30 seangrove: muhoo: It needs a lot of polish, but that's the idea ;)

18:30 If we had IB, you'd just add it to your library, drag it in, configure its options, and save your presentation layer

18:30 muhoo: ~ib

18:30 clojurebot: excusez-moi

18:31 seangrove: muhoo: Interface Builder

18:31 muhoo: ~ib is interface builder

18:31 clojurebot: Ack. Ack.

18:32 seangrove: muhoo: They were ahead of their time, but this is *eactly* the kind of thing Om is well-suited for http://www.youtube.com/watch?v=ouzAPLaFO7I

18:32 bbloom: dnolen_: nice. the react-page project seems not to have gotten much love. would be awesome if the clj community can carry the ball forward there

18:32 aka: whoa omchaya is cool and a nice reference

18:33 seangrove: muhoo: If there's a protocol for components to expose their keys/types/etc., then this kind of tooling just falls out

18:33 muhoo: Also, all of the components in Omchaya should basically be spun out into om-components, like om-stack-panel

18:33 muhoo: i was thinking about that today, be nice if tehre were a clojars/maven repo for components

18:34 dnolen_: bbloom: yeah, agreed

18:34 seangrove: muhoo: They're just libraries like anything else

18:34 bbloom: Which React page is this?

18:34 patchwork: Hmm… I have a simple ring handler that is returning {:status 404 :body "<html><body><h1>404</h1></body></html>" :headers {"Content-Type" "text/html"}}, but in the browser it shows up blank

18:34 Anyone else seen that?

18:34 bbloom: seangrove: https://github.com/facebook/react-page

18:34 muhoo: on a more practical level, i was wondering how i'd put css into a component in a lein project so that others could use it transparently

18:34 patchwork: weird

18:34 seangrove: bbloom: Got it, thanks.

18:34 patchwork: Seems like it should be the simplest thing ever

18:35 muhoo: i could see building a component as just pure cljs, and om-sync is a great example of how easy it is to pull one in. but what about the css or other includes?

18:35 seangrove: patchwork: What happens when you cURL it?

18:35 muhoo: i'm not sure how that'd work with the lein/jar model of dependencies

18:35 seangrove: muhoo: Ah, yes. I think there will be some standardization around that eventually

18:36 muhoo: I think it does. Some function that spits out preprocessor-friendly css that can be mangled/compiled in with the user-provided css

18:36 patchwork: seangrove: Says 404 not found, content-length 0 … ?

18:36 ior3k: muhoo: I'm generating everything (HTML/CSS + the rest) in the client with Om + Garden. Not sure if that's what you're talking about but I love it

18:36 muhoo: ior3k: that'd work, thanks

18:36 i haven't messed with garden yet but it looks great.

18:36 seangrove: noprompt Sure seems to like it ;)

18:36 muhoo: it's his thing, no?

18:37 seangrove: Yeah, just teasing a bit

18:37 patchwork: seangrove: curl output here: https://www.refheap.com/52598

18:37 noprompt: seangrove: ?

18:37 muhoo: is there going to be a cljs meetup or bof at cljwest?

18:37 seangrove: bof?

18:37 muhoo: seems like there is so much exciting stuff in om specifically, a bof might be fun

18:37 ~bof is birds of a feather

18:37 clojurebot: Roger.

18:37 seangrove: muhoo: We moved the CLJS meetup from the Monday after to the day after so Clojure/west people could join in

18:38 muhoo: thurday night, augh, can't make that. oh well.

18:38 seangrove: patchwork: Not sure, sorry

18:38 muhoo: hmm, wait, cljwest is thursday/friday. so the meetup is saturday?

18:39 seangrove: muhoo: Meetup is 27th, Clojure/west ends 26th

18:40 muhoo: ah. got it. no thursday for me. i see cljswest is mon-wed.

18:42 seangrove: muhoo: Are you going to Clojure/West, and are you normally out here?

18:42 muhoo: If you're interested in an Om/Omchaya unsession, please mention it here https://github.com/cognitect/ClojureWest/wiki/Clojure-West-Unsessions

18:42 noprompt: objective j. eesh

18:42 muhoo: right, i guess BOF's are called "unsession" now

18:43 * muhoo is not up on those conference trends

18:43 seangrove: noprompt: Regardless, they were amazing for what they pulled off ;)

18:43 noprompt: seangrove: oh no kidding and it looks like they're still working on it.

18:43 seangrove: noprompt: It was too heavy, too early, etc. But the ideas were brilliant. We can bring in the best bits of those now.

18:43 noprompt: Nah, they were bought by Motorala, one of the cofounder is at Stripe now, the other two left a long time ago

18:44 muhoo: ~bof is "birds of a feather", an old-fart name for "unsession"

18:44 clojurebot: Ack. Ack.

18:45 bbloom: for some reason, both of those terms set off my marketing bullshit fuzzy hippy good times alarm

18:45 `cbp: $google unsession

18:45 lazybot: [Unsession - Minnesota.gov] https://mn.gov/governor/unsession

18:46 `cbp: Everything is so clear now

18:46 muhoo: bbloom: bof's date back to the IETF and IEEE conferences in the Ancient Times

18:46 rasmusto: unsession is a session??

18:46 lazybot: rasmusto: What are you, crazy? Of course not!

18:46 muhoo: ~botsnack

18:46 clojurebot: thanks; that was delicious. (nom nom nom)

18:46 muhoo: wrong bot :-/

18:46 bbloom: ~unbotsnack

18:46 clojurebot: I don't understand.

18:47 bbloom: you wouldn't.

18:47 muhoo: hahaha

18:47 bot of a snack

18:48 seangrove: bbloom: You could edit the unsession page with a title of "Synergistic free-love commune of ideating"

18:49 muhoo: basically a bunch of nerds sitting around drinking beer and talking shop.

18:50 like IRC, but in person

18:50 noprompt: haha

18:51 rasmusto: whos bringing clojurebot?

18:53 justin_smith: muhoo: it's more fun to kick someone in person

19:07 patchwork: So our project is pulling in [fs "1.1.2"], but doesn't show up anywhere in our > lein deps :tree (we are including [me.raynes/fs "1.4.5"] explicitly)

19:07 Probably AOT compiled somewhere?

19:08 How to I begin looking for such a thing?

19:08 Raynes: I'm not sure how it could possibly not show up in lein deps :tree if it is in your dependencies, particularly in the profile in which you're running `deps :tree`

19:08 xeqi: patchwork: any plugins?

19:08 Raynes: patchwork: Is this a Github project?

19:08 patchwork: Raynes: Yes

19:08 Raynes: May I see it pwetty pwease <3

19:09 patchwork: Raynes: Here you go https://github.com/caribou/caribou-development

19:09 xeqi: Yeah, three plugins

19:10 Apparently the bug only shows up when using lighttable (which includes its own version of fs which conflicts with ours)

19:10 dnolen_: it will be funny to have to wrap native Clojure data structures in ClojureScript protocols to get ClojureScript interop

19:10 Raynes: Oh, yeah.

19:10 Light table is all kinds of magics.

19:11 I wouldn't trust anything light table tells me about my dependency tree :P

19:11 patchwork: Well, it's just that it fails

19:11 I wouldn't care what it told me if it works : P

19:11 Raynes: What fails?

19:12 patchwork: Raynes: https://github.com/caribou/caribou-core/issues/21

19:12 xeqi: patchwork: https://github.com/emezeske/lein-cljsbuild/blob/master/plugin/project.clj#L10

19:12 patchwork: xeqi: You found it!

19:13 Raynes: Oh yes.

19:13 patchwork: (inc xeqi)

19:13 lazybot: ⇒ 11

19:13 patchwork: Thank you greatly

19:13 seangrove: dnolen_: (clj->cljs) ? :)

19:13 patchwork: I thought I had hunted through all the project.clj's of my dependencies, but apparently I forgot that one

19:13 Raynes: patchwork: Any version that doesn't have my name before it is too old to be used with the ones that do have my name behind it :p

19:14 (because of namespace changes, in particular)

19:14 patchwork: Raynes: You have become master of fs!

19:14 Thanks for the help

19:14 Raynes: xeqi did the hard part

19:15 patchwork: Now the only question is why lein-cljsbuild is using such an old fs

19:15 but at least I can exclude it

19:17 justin_smith: they should get a PR to update it

19:37 shoepie_: dnolen_: if i have a cursor to my app state, what's the best way to om/transact! on items in a vector in that cursor?

19:38 dnolen_: i see om.core/transact! takes korks but i'm manipulating a vector...

19:41 dsrx: 2korks?

19:46 qbg: ,(assoc [1 2 3 4] 1 7)

19:46 noonian: shoepie_: you can pass vector indices as part of the korks that om/transact! takes i believe

19:46 clojurebot: [1 7 3 4]

19:46 dsrx: what the heck are korks?

19:47 qbg: keyword or keywords

19:47 dsrx: ah, like a fn that [& {:keys [...]}] ?

19:47 noonian: if you pass in a vector for korks you can think of it as the path in the nested data structure that is your app state

19:47 shoepie_: noonian: what if i wanted to do all the elements?

19:47 rasmusto: ~korks

19:47 clojurebot: No entiendo

19:48 qbg: shoepie_: You could pass in the empty vector

19:48 dsrx: oh, it's an argument named that in omitself

19:48 noonian: if you app is an atom like this: (atom {:vec [1 2 3]}) you could do (om/transact! app [:vec] (fn [v] ["my" "new" "vec"]))

19:49 which is really the case that om/update! is intended for

19:49 (om/update! app :vec ["my" "new" "vec"])

19:49 shoepie_: noonian: huh, never would've guessed that

19:50 noonian: so if i wanted to update certain indices...

19:50 (om/transact! app [:vec [1 2 3] (fn ...

19:50 noonian: do that in the function you pass to om/transact! and give it the whole vector

19:51 (om/transact app :vec (fn [old-vec] (mapv (fn [e index] ...) old-vec (range))))

19:51 and do you index specific logic in the ...'s

19:52 danielszmulewicz: Speaking of Om, when I use sablono, React complains about missing "key" prop in the array, this happens only for dynamic children (build-all).

19:52 noonian: i've been getting that also, but it doesn't seem to affect anything

19:53 i don't think i use build-all anywhere though

19:53 shoepie_: noonian: that's basically what i'm doing now

19:53 noonian: my vector contains maps and in my transact i'm returning a new vector of the changed maps

19:54 noonian: shoepie_: if you only want to change the third element say, you could do (om/transact! app [:vec 2] (fn [ele] ...))

19:54 danielszmulewicz: noonian: yeah, but I'd like to get to the bottom of this. Why isn't this happening when using the original dom notation?

19:54 shoepie_: noonian: then i om complains: "No protocol method ITransact.-transact! defined for type cljs.core/PersistentArrayMap"

19:55 noonian: so it must not like that i'm replace those values with persistant maps (i assume they were originally cursors ?)

19:55 noonian: that means you are calling transact! on a raw map, when it needs a cursor

19:55 yeah

19:55 shoepie_: noonian: still a little fuzzy how and when cursors are cursors

19:56 noonian: anything om passes to the functions you pass to transact! or update! will be a cursor unless they are primitive js types like string or number

19:56 also, the first parameter to your component fns will be a cursor

19:56 shoepie_: here's my transact (still messy)

19:56 (om/transact! app-state :event-types (fn [event-types] (map (fn [et] (assoc et :editing true )) event-types))))

19:56 :event-types is the vector

19:57 danielszmulewicz: shoepie_: this might help clear things up regarding cursors: https://gist.github.com/asolove/8322218

19:57 qbg: Is app-state your atom?

19:57 shoepie_: just trying to set and editing flag

19:57 yeah

19:57 danielszmulewicz: shoepie_: Basically an atom with a couple of "methods"

19:58 shoepie_: danielszmulewicz: cool, thanks

19:58 echosa: I asked around about private functions (defn-) and testing because I've been making everything public (defn) so that I can write unit tests. However, I've been told that I can test private functions using #'. This certainly does work, but leads me to ask: what's the point of defn- if it can so easily be worked around with #'?

19:59 qbg: echosa: So you have to go out of your way?

19:59 technomancy: echosa: private is about communicating expectations of stability, not about literally hiding vars

20:00 hiredman: ~private

20:00 clojurebot: not even once

20:00 echosa: technomancy: Ah. See, since it uses the JVM, I thought it would act more Java-like in respecting privates.

20:00 seancorfield: Groovy ignores private too...

20:01 echosa: qbg: It's not that much otu of the way to change (my-func) to (#'name.space/my-func).

20:01 technomancy: echosa: but at least if you do that and it breaks, you understand it's your fault

20:01 not the fault of the author of the lib

20:03 echosa: Fair enough. So I should make my classes as they should be, with things that should be private declared with defn-, and use #' to test them as desired. However, production (non-test) code should respect the private-ness (basically, working on the honor system). Yeah?

20:03 technomancy: classes?

20:03 echosa: s/classes/clj files

20:03 technomancy: it's fine to work around private as long as you take responsibility for dealing with the consequences

20:04 not something I'd get in the habit of doing, but there are situations where it's justified

20:05 echosa: would you, personally, consider unit tests a justified situation?

20:05 technomancy: yeah

20:05 echosa: Ok good. I'm glad that's your answer. :-)

20:05 technomancy: private is about communicating from the author of a piece of code to the consumers

20:06 echosa: Because that's what I'm leaning towards, and at least I'm not alone.

20:06 technomancy: if you're the author, then you presumably don't need to communicate with yourself

20:06 echosa: private is more about the outward API, then

20:06 jimrthy2___: ?jimrthy

20:06 hiredman: private is gross, don't use it

20:07 echosa: hiredman: What's your reasoning?

20:07 technomancy: another strategy is to not care if other peoples code breaks

20:07 hiredman: http://clojure-log.n01se.net/date/2014-03-01.html#02:01b

20:07 technomancy: in that case, private isn't very useful

20:08 hiredman: echosa: if you read forward from there, I explain to the last guy to ask

20:09 basically http://clojure-log.n01se.net/date/2014-03-01.html#02:14b

20:13 echosa: Most useful thing I've read in that thread so far: "defn- only exists because it's hard to get rid of.. but there's no def- and clojure/core has repeatedly rejected calls for it"

20:15 technomancy: echosa: that's silly. encouraging people to be explicit about the difference between unstable implementation details and an API with a promise of stability is really important if you want to build up a functional ecosystem where things aren't constantly breaking

20:16 hiredman: technomancy: depedency management is important for that

20:16 echosa: technomancy: agreed... I find that quoted statement useful because it shows an interesting different in def/defn/defn-

20:16 At this point, I still think I'll mark functions that are only used in their host namespace as def-

20:17 I find it clearer to read as far as my own code goes, to know if it's an "external" or "internal" function, from the namespace's view

20:17 technomancy: hiredman: sometimes you are stuck pulling in new versions of things transitively even though you only want a new version of one lib

20:17 clojure isn't nix

20:17 echosa: that's not what it means

20:18 it's about an explicit guarantee of stability, not about whether it's used outside the host namespace

20:18 echosa: mind you, I'm not creating widely used libs here. I have a single project (my first) and everythign is internal to the project. Nothing will be pulled out into a separate, resuable lib. (At least, not anytime soon).

20:18 hiredman: technomancy: if you have to upgrade, you have to upgrade, the supposedly stable api is really just as likely to have changed

20:18 technomancy: hiredman: yeah, if you don't take stable apis seriously

20:18 we can do better than that

20:18 echosa: technomancy: I don't understand what you are talking about with "stability". Stability of what?

20:18 technomancy: echosa: you can have things that aren't used outside the host namespace that are still intended for end-user consumption

20:19 you can have things that are used outside the host ns that aren't intended for external consumption

20:19 clojure doesn't have a good way of signifying the latter, but I personally like adding :internal metadata

20:19 hiredman: technomancy: even if someone is using semenatic versioning to communicate breakage of "public apis" you could still be transitively forced in to ugrading

20:19 technomancy: hiredman: it's about managing expectations

20:20 you should be able to know what you're getting into

20:20 you can suck at communicating expectations, or you can make an effort at doing a good job

20:21 hiredman: what does - communicate?

20:21 quizdr: why do I get this error about contains? not working on list when I'm passing a vector to it? https://www.refheap.com/52622

20:21 technomancy: hiredman: if you're doing it right, it means "this could change at any time"

20:21 qbg: ,(doc contains?)

20:22 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

20:22 echosa: technomancy: that's not how I woudl read - at all, but I think I see what you're saying, from an API development standpoint.

20:22 rasmusto: ,(contains? [1 2 3] 0)

20:22 clojurebot: true

20:22 hiredman: because conj builds lists when starting with nil

20:22 quizdr: oh i see

20:23 seancorfield: quizdr: your `if` only has one arm - so the else is nil

20:23 echosa: If I were making a library for others to use, I would consider defn- as functions only I (the developer) should use (internal use only), and defn as functions anyone should (outward, external API)

20:23 seangrove: echosa: Even though you might think that, you should basically never use defn-

20:23 technomancy: seangrove: bullshit

20:24 seangrove: It's really rare that authors are right about that

20:24 quizdr: seancorfield good catch

20:24 cespare: I find myself using (fn [f x] (f x)) as the pred of a condp -- am I missing something obvious that's simpler?

20:24 seangrove: technomancy: It should definitely be used very, very sparingly

20:24 seancorfield: quizdr: this works: https://www.refheap.com/52627

20:24 technomancy: if you're writing a library and considering making a change, it's really valuable to be able to know whether the thing you want to change is used by downsteam codebases or just your own code

20:25 if you don't have this information, you're either going to be stuck with ugly backwards compatibility hacks that aren't necessary, or you're going to break everyone's code

20:25 seangrove: technomancy: It's pretty common to need to use the private functions underneath the public functions to get something I need done, but because the author thought I shouldn't be able to access it even though I know the risks, I have to fork the library

20:25 technomancy: please be responsible

20:25 seangrove: technomancy: Nah, docstrings. Put warnings, but let people handle it if they need to

20:25 technomancy: no one bothers with docstrings

20:25 seangrove: technomancy: Then you can't shed too many tears for them

20:25 technomancy: you don't need to fork a library to use private defns

20:25 that's silly

20:25 seancorfield: quizdr: actually no it doesn't... it doesn't error but it doesn't give the "right" answer...

20:25 seangrove: technomancy: How do you do it then?

20:26 technomancy: seangrove: seriously?

20:26 seancorfield: quizdr: contains? doesn't do what you think :)

20:26 seangrove: technomancy: Well, short of monkey patching?

20:26 technomancy: seangrove: #'lib/thingy

20:26 mischov: Same way you test private functions.

20:26 clojurebot: Gabh mo leithscéal?

20:26 echosa: I've written docstrings for every (I think) function in my app (except unit test functions, of course)

20:26 technomancy: works great, and visually signals that you're doing something that will probably break

20:27 it's not like private defns are actually inaccessible

20:27 echosa: Yeah, the #' thing is what people said I could use to call my functions from test namespaces.

20:27 seangrove: technomancy: I think I've tried to call them before and I get an error

20:27 technomancy: #' side-steps that?

20:28 technomancy: seangrove: yeah, easy

20:28 echosa: Sure does.

20:28 seangrove: technomancy: Well, I appreciate the lesson, even though the delivery method was pretty harsh

20:28 Still, good to learn

20:29 seancorfield: quizdr: try (contains? [1] 1) and you'll be surprised :)

20:29 echosa: hiredman quote form the link he posted: "private is from conceit of being a grand architect of software, instead of acknowledging the wrapper library you are releasing will save a some guy at a start up and afternoon, and then he'll have to rip it out in 2 months anyway, because the assumptions in it don't match his use"

20:30 technomancy: echosa: if it took more than two characters to sidestep private I'd be inclined to agree

20:30 which I guess is true in Java, but not here

20:30 echosa: API design is a whole field on it's own, but just because some people can't design a decent public API doesn't mean you should necessarily just Public All The Things!

20:30 noonian: doesn't it also work to just fully qualify the namespace of the private defn?

20:30 echosa: technomancy: technically, it takes two characters *and* the namespace... ;-)

20:31 noonian: I believe you need boht.

20:31 technomancy: echosa: eh, you're already doing that, right? no one uses :use anymore =)

20:31 clojurebot: Excuse me?

20:31 echosa: *both

20:31 quizdr: seancorfield got it, thanks

20:32 echosa: I actually haven't used :use. I've used :refer and :import. (and only used :import for core.typed)

20:32 dsrx: :use is no longer really necessary

20:32 seancorfield: echosa: so you'll :refer :as x and then (#'x/foo ...)

20:32 er :require :as

20:32 dsrx: well maybe it is, but I think :refer :all should cover all its uses

20:32 technomancy: echosa: oh, :refer is basically :use

20:32 :refer :all is only for tests

20:33 noonian: :refer :all is just as bad as :use

20:33 seancorfield: agreed

20:33 dsrx: i agree with that

20:33 echosa: I actually don't use :as either, except I did for one third party lib (lanterna)

20:34 can someone explain :refer vs :use and why they're bad (or at least, why :refer :all is bad)? I have some preconceptions as to why, but I'd like other thoughts and explanations.

20:34 noonian: i tend to use both :refer and :as, names eventually conflict, and i like that from the leiningen repl if you've used :as x you can tab complete x/ to see all the fns in the ns

20:35 dsrx: :refer :all can be bad because you can't easily tell where a var comes from

20:35 and conflicts, etc

20:35 noonian: if someone else looks at your code and sees you calling functions that aren't defined in the ns or explicitly refered to from other namespaces there is no easy way to figure out where those functions are defined

20:36 echosa: :as just assigns a short name to a namespace, right? It's just there to reduce typing?

20:36 Wild_Cat: echosa: yes

20:37 echosa: I mean, even if you use :as, you could still call that function without the namespace/:as prefix, right? It doesn't force you to use whatever you supplied to :as?

20:38 noonian: yes, either by first using :refer or by fully namespace qualifying it

20:39 seancorfield: If you avoid :all, then all names in your code are either a) local to that namespace b) invoked via namespace-qualification (or alias-qualification) or c) explicitly listed in a :refer in your ns declaration.

20:39 (or they're from clojure.core)

20:40 echosa: I understand and agree with the benefit of only pulling in/referring/using/whatever the functions that are *actually* used in the source that follows.

20:41 and just to be clear and sort of come full circle, out of curiosity really, does :refer :all only pull in public functions?

20:41 noonian: the worst is when documentation for libraries uses :use in the examples

20:41 echosa: I know that's a dumb question, but I want to be clear.

20:42 noonian: *cough* lobos...

20:43 dsrx: a lot of older libraries do that I've noticed

20:43 e.g. https://github.com/dakrone/clojure-opennlp

20:43 echosa: still not fully getting :use vs :refer

20:44 dsrx: er well, that's using the use function, not :use in the ns macro I guess

20:45 seancorfield: echosa: :use == :require with :refer :all

20:46 echosa: Oh... so (:use name.space) == (:require [name.space :refer :all])?

20:47 seancorfield: noonian: I think a lot of libraries documented the usage in the REPL and most people do (or used to) simply (use 'the.library) and start playing...

20:47 echosa: yes

20:47 dsrx: i'm not sure what (:use (my.lib this that)) does -- does it use both my.lib.this and my.lib.that ?

20:47 seancorfield: hence :refer :all is just as "evil" as :use

20:47 noonian: dsrx: its equivalent to (:use my.lib.this my.lib.that)

20:48 dsrx: k

20:50 seancorfield: TIL: (require '[clojure [string :as s] [set :as t]]) works...

20:50 devn: :refer :all is not "evil"

20:50 seancorfield: devn: no more so than :use is what I meant

20:50 noonian: maybe "adversarial" is a better word

20:51 devn: seancorfield: even then though, i think there are damn good reasons to use :use

20:52 i tend to prefer :require :as, but there are cases where it makes sense to just use the darn thing.

20:52 i guess my most recent example is :refer :all with honeysql.helpers

20:53 as long as the ns you're doing it in serves a narrow purpose

20:53 noonian: yeah, i agree with that

20:54 but even if i'm referring to everything, i tend to just use gigantic refer vectors

20:54 devn: otherwise it looks like garbage to read

20:55 like (-> (h/select ...) (h/where ...) (h/from ...)) etc

20:55 it's the reason a lot of c programmers drop the * on the left

20:56 like const char* x, vs const char *x

20:56 muhoo: so, what's the trick to getting the react dev tools to work with om?

20:56 devn: actually i dont know if that's an argument in either direction, but in the case of the ns prefix, i feel like there's a consistent cognitive load of needing to parse every single x/foo

20:57 if there are a ton of them it gets annoying quickly

21:01 muhoo: speaking of sidestepping, i noticed rich alter-var-root-patched overtone in his harmonikit project.

21:04 ~korks

21:04 clojurebot: Excuse me?

21:04 muhoo: ~korks are keywords or a seq of keywords, like update or update-in, c.f. om docs

21:04 clojurebot: excusez-moi

21:05 * muhoo sings "you know where to put the kork"

21:05 muhoo: ~korks are keywords or a seq of keywords (like update or update-in) used in om i.e. transact! and update!

21:05 clojurebot: excusez-moi

21:06 muhoo: ~korks is keywords or a seq of keywords (like update or update-in) used in om i.e. transact! and update!

21:06 clojurebot: In Ordnung

21:06 ddellacosta: ~korks

21:06 muhoo: ~korks are keywords or a seq of keywords (like assoc or associn) used in om i.e. transact! and update!

21:06 clojurebot: Titim gan éirí ort.

21:06 oRaCuLaR13: ~korks

21:06 clojurebot: korks is keywords or a seq of keywords (like update or update-in) used in om i.e. transact! and update!

21:07 oRaCuLaR13: ~korks

21:07 ddellacosta: hmm

21:07 clojurebot: korks is keywords or a seq of keywords (like update or update-in) used in om i.e. transact! and update!

21:07 muhoo: fix it if it's wrong :)

21:07 oRaCuLaR13: ~juxt

21:07 clojurebot: juxt is a little hard to grok but it's the best thing ever

21:07 muhoo: ~java logging

21:07 clojurebot: java logging is clown shoes

21:07 muhoo: i love that one so much.

21:07 oRaCuLaR13: lol

21:07 ddellacosta: it's not, actually, the best thing ever

21:07 muhoo: timbre by the way, is awesome

21:07 ~timbre

21:07 clojurebot: Cool story bro.

21:08 muhoo: ~timbre is awesome if you are tired of java logging (c.f. java logging)

21:08 clojurebot: Ack. Ack.

21:08 seangrove: ddellacosta: Pretty close

21:08 ddellacosta: seangrove: I find I use it (juxt) surprisingly infrequently...maybe I'm doing it wrong. comp, on the other hand, is super cool.

21:09 and I love me some threading macros

21:10 oRaCuLaR13: can anyone comment on how they represent objects without resorting to java interop? do you find maps to be enough or do you frequently resort to defrecord?

21:11 seangrove: oRaCuLaR13: Definitely just maps

21:12 ddellacosta: comp, partial, and juxt are a wild threesome

21:14 ddellacosta: oRaCuLaR13: definitely what seangrove says, but depends on your use-case. What do you mean by "object?"

21:16 oRaCuLaR13: ddellacosta: I'm translating parts of an interpreter from Java to Clojure. In Java I've got a base object for the "Program" to interpret, but there's variations in forms that "Programs" can take. Thus an inheritance/polymorphism pattern.

21:16 ddellacosta: I'm having trouble expressing that in Clojure with just maps, short of putting a key/value to encode the type of program. but that seems poor taste.

21:17 seangrove: oRaCuLaR13: Probably just maps and multimethods then

21:18 oRaCuLaR13: You essentially just need to call different forms of the same function depending on the type/shape of your data, right?

21:21 oRaCuLaR13: seangrove: that's right. For instance, a ComponentProgram and a RecordProgram should get their bytecode from the database in the same way, but they should initialize themselves from the database in different ways. You're saying I should use a single function for something like initialize, and then use a multimethod with de-structuring to look into the map and choose which form is appropriate?

21:23 seangrove: oRaCuLaR13: That's certainly one way. You can also get polymorphism from protocols, but I'd start with the multimethod approach

21:23 oRaCuLaR13: You can see it used to good effect in the clojurescript compiler (written in clojure)

21:25 oRaCuLaR13: seangrove: alright thanks i'll take a look.

21:25 seangrove: oRaCuLaR13: No problem, sounds like a cool project

21:28 oRaCuLaR13: yeah i'm creating an open source alternative runtime engine for peoplesoft. Eventually i want to start a company that involves taking some of oracle's lunch money away, i think targeting peoplesoft could be one way to do it.

21:28 seancorfield: devn: another possible good use is monger.operators since you generally want all of them... although I might still :refer [..] there

21:39 chare: what is the difference between using Java through something like (. foo bar 7 4) vs (.bar foo 7 4)

21:39 muhoo: wow peoplesoft. haven't heard that name since 1999

21:40 when they were the Big Thing. shortly after netscape had imploded and lost its Big Thing status.

21:41 chouser: chare: no difference.

21:44 seancorfield: ugh! peoplesoft... adobe used a bunch of their stuff when i worked there :(

21:45 * seancorfield left adobe in 2007 and they were still using it!

21:53 oRaCuLaR13: yeah they're not the Big Thing anymore but peoplesoft isn't going anywhere. esp when IBM owes them a ton for convincing non-technical managers to buy AIX rather than something that doesn't blow, which is everything but AIX

22:04 seangrove: bbloom: Even if VirtStackPanel hasn't worked out yet, the scroll view is very nice!

22:11 brehaut: (source number?)

22:11 &(source number?)

22:11 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

22:11 oRaCuLaR13: (def source 1337)

22:12 brehaut: ,(number? nil)

22:12 clojurebot: false

23:08 firefaux: is there a function which, given another function f(x, y, z, ...), returns a function g(..., z, y, x) ?

23:08 i.e. it reverses the order of the arguments

23:09 brehaut: not in the standard library

23:09 firefaux: oh

23:09 actually

23:09 I guess I could do something like

23:09 amalloy: firefaux: remember that's not what functions look like in clojure :P

23:09 firefaux: (fn [f & args] (apply f (reverse args)))

23:09 segmond: how different is clojure 1.1.0 vs 1.6?

23:09 amalloy: but it's easily written: (fn reverse [f] (fn [& args] (apply f (reverse args))))

23:09 segmond: monumentally

23:10 segmond: ok, thanks. i'll try and get the latest then.

23:10 firefaux: amalloy: I know :P

23:10 my brain's still partly in math mode right now

23:10 amalloy: segmond: don't use your package manager

23:10 segmond: yeah, i did. i just downloaded lein

23:10 amalloy: download lein and let it get clojure for you

23:11 great

23:11 segmond: trying to figure out how to use it

23:11 how do i make it get clojure?

23:11 amalloy: well, it already has! just run `lein repl`

23:11 firefaux: oh

23:11 right

23:11 segmond: you are right, it has 1.5.1

23:11 is that good enough?

23:12 firefaux: I made a function that takes the arguments

23:12 not one that just takes the function

23:12 amalloy: 1.5.1 is latest stable

23:12 firefaux: and whoa, there was a huge delay in the chat for me for a second

23:12 amalloy: it's what most folks are using

23:12 firefaux: got like 8 messages in an instant

23:13 insamniac: blame the NSA

23:14 amalloy: oh haha, my version of reverse is broken because i wrote (fn reverse ...) instead of (fn anything-else ...)

23:16 firefaux: oh yeah

23:16 I just thought you were trying to use a named lambda

23:16 though I forget exactly how those are formatted

23:16 amalloy: well i was

23:17 but i accidentally named it reverse, and then tried to use the clojure.core/reverse

23:18 firefaux: I just wrote it in a way that works

23:18 here's what I wrote

23:18 wait a sec

23:18 if I paste a 3 line function, will it send 3 posts?

23:18 maybe I should use tinycode

23:18 I got yelled at once for pasting a somewhat large function

23:18 oh

23:18 I see

23:18 amalloy: ~refheap

23:18 clojurebot: https://www.refheap.com/

23:19 firefaux: yeah, I thought that was odd that you were naming it after reverse

23:19 though it didn't occur to me that it would shadow the actual reverse function

23:34 randall`: Hello, quick question. I'm using paredit with the cider repl in emacs. When I try to move to a new line within a form, which I would traditionally do by hitting return, paredit automatically completes the closing parens and then has the repl read it.

23:34 I'm sure there's an easy fix, but a 15-minute search effort has failed to produce it.

23:43 noprompt: randall`: i turn of paredit in the repl

23:43 *off

23:44 randall`: but remember you can always just write code in your buffer and evaluate it directly there.

23:44 randall`: ok! thanks

23:48 Denommus: I'm trying to use friend as authentication library on a luminus project

23:48 but I'm kinda confused on the concepts

23:49 amalloy: randall`: you can also use C-j instead of RET for editing

23:49 Denommus: should I do that in a middleware?

23:49 amalloy: i don't use paredit at the repl either, but i've gotten into the habit of using C-j pretty often anyway

23:53 randall`: :amalloy that's exactly what I was looking for! Thank you.

23:54 Denommus: in better wording: what should I know BEFORE trying to understanding Luminus' and friend's docs?

23:55 dissipate: is there a 'lint' utility for clojure that enforces good style practices?

23:55 seancorfield: dissipate: have you looked at Eastwood?

23:56 dissipate: seancorfield, cool, thanks.

23:57 ddellaco_: Denommus: I would recommend reading through ring and compojure's wikis, at least enough to get the basic concepts. https://github.com/ring-clojure/ring/wiki https://github.com/weavejester/compojure/wiki

23:58 dissipate: ddellaco_, what about pedastal?

23:59 Denommus: ddellaco_: thanks

23:59 ddellaco_: dissipate: uh...to understand Luminus? Definitely not. And definitely wouldn't suggest it as a developer's first attempt to build a web app with Clojure...but that's based on the last time I checked out the tutorial (v 2.x I think).

23:59 dissipate: ddellaco_, is the documentation bad?

Logging service provided by n01se.net