#clojure log - Sep 15 2014

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

1:06 danielcompton: Our long national nightmare is finally over https://github.com/technomancy/leiningen/issues/1629

1:30 jarodzz: hi, guys

1:30 anyone has experience to add clojure into exisitng java project?

1:48 seancorfield: jarodzz we run Clojure embedded inside a Java runtime, an app running on Tomcat... what's your question?

2:12 kenrestivo: i just realized my (--> love for the threading operator) is a legacy | of | being |a | unix | shell | guy

2:43 augustl: kenrestivo: i/o for the win

2:46 kenrestivo: has anyone tried to create a standalone windows/mac executable from a clojure program? i looked at the .iss file of leiningen-win-installer for ideas, and it looks intimidating.

2:46 also, just dealing with the oracle dependency as a separate install step might stop users from bothering.

2:47 like, zoinks scoob: https://bitbucket.org/djpowell/leiningen-win-installer/src/9c971dd33439/leiningen-installer.iss?at=bitbucket-master

2:49 amalloy: kenrestivo: the oracle dependency? you're worried about users who don't have java installed?

2:49 kenrestivo: yes.

2:50 amalloy: well, good luck. no clever ideas from me

2:52 kenrestivo: haha, no prob. this may be an app i have to write in C and wxwindows or similar. but it'd sure be nicer to write in clojure/seesaw instead.

3:00 papachan: hi there

3:01 seancorfield: evenin' papachan

3:01 augustl: kenrestivo: you can redistribute openjdk afaik

3:01 not sure how well that works in practice

3:01 papachan: i am trying to make an assoc inside a function but i still cannot find a way out

3:02 kenrestivo: augustl: oh cool, thanks. should work fine actually. but there would still need to be all that hairy .iss checking to see if there's a working vm there already first.

3:03 augustl: you can of course also ignore that and always use your bundled openjdk runtime :)

3:03 papachan: https://code.stypi.com/papachan/test.clj

3:03 augustl: papachan: what's the code?

3:03 papachan: augustl, i just paste it

3:04 augustl: papachan: there's no call to "assoc" there

3:04 papachan: auguts no, because nothing works were working

3:04 so i print the same local hasmap

3:04 seancorfield: that code prints results - it doesn't return anything

3:05 augustl: papachan: what do you want/expect that code to do that it doesn't do now?

3:05 papachan: yeah

3:05 this code print the two lines there is in comment

3:06 for example it iterate over a hashmap

3:06 and put it in another hashmap structure

3:06 i need to merge each result into a new hashmap

3:06 seancorfield: papachan I think you're looking for the merge function?

3:06 papachan: i have tried womething

3:09 as i understand clojure way, it always return the merge result of each row, not the sum of all

3:10 m is a local hashmap so its stay immutable, my merge work for one row, but do not merge all the resulds

3:10 seancorfield: ah, so you want reduce

3:10 reduce is the clojure way of looping of things to make a new thing

3:12 the local m map would be the initial map you start with, and params would be the collection you reduce

3:13 and then you'd define a function to merge in each part of the collection to that initial map

3:13 papachan: i have tried something like this

3:15 (reduce (fn [m [k v]] (assoc m k v)) y x)

3:21 seancorfield yes i understand that way, but i cannot change the map structure with reduce and assoc, i havent find the way

3:21 i have tried with (reduce #(assoc % (keyword (str %2)) %2) y x)

3:23 seancorfield: papachan https://www.refheap.com/90268

3:23 ollivera: Given the Authentication example below, how can I assign "conn" to a global var. I tried def, but (mg/authenticate db u p) returns a boolean.

3:23 http://clojuremongodb.info/articles/connecting.html

3:24 podviaznikov: Hi, I'm trying to scrape cyrillic web page with enlive. Parsing seems to work but I can't see readable text in the console(both lighttable and REPL). Does anyone know if it's some issue with console or I need to specify encoding before enlive html parsing?

3:27 papachan: seancorfield it works. really cool.

3:29 zot: does clj have a way to print out structures in a way that they can be pasted back into the repl (a la python's %r format)?

3:30 amalloy: zot: that's the default print format. just put a ' in before you paste, to quote the data structure

3:33 zot: ok, then what i'm printing must not be pure map/vector/string :/

3:34 amalloy: tnx :)

4:06 kenrestivo: so if i wanted to, say, emit liquidsoap from clojure, is this still the best general approach to take? http://clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure.html

4:07 (liquidsoap is itself a dsl, kind of ruby-like syntax, which was written in ocaml)

4:08 clgv: kenrestivo: you want general advice on best practices to create a DSL with clojure?

4:08 kenrestivo: that'd be a good start, yes

4:08 i've seen lots of stuff in the past, i just don't know what's the current best thinking on the topic

4:09 clgv: well, usually you start writing functions that do what you want. when you encounter cases in your DSL where you need specifiy evaluation semantics you introduce a macro for that

4:09 specification can be done in pure clojure data (maps, vectors, sets)

4:10 kenrestivo: ok, that's generally what i've seen. i didn't know if there was any spiffy new way to do it nowadays, like "you'd use tools.analyze.foo" or similar

4:10 doing it with simple functions and macros is just fine with me, if that's still the recommended way

4:11 clgv: no, the tools.analyzer stuff is mainly for wrinting clojure(script) compilers - though it can be used in tangantial topics as code analysis etc

4:11 *writing

4:14 kenrestivo: usually it hurts to do too much special. for example I used a special registry for a DSL just too switch back to clojure namespaces some months later

4:15 kenrestivo: ok, thanks

5:12 zot: ok, just found out the hard way that creating a java buf'd file writer in a let does *not* get it nicely flushed/closed. is there a graceful to handle this? the let stmt handles input from both stdin or from the command line, and uses bind, which makes with-open impractical. ideas? (code snippet coming...)

5:14 https://gist.github.com/anonymous/e381f4df594421cbbf75 — without the .flush call, my result doesn't make it out :/

5:15 Bronsa: zot: use with-open to automatically close the buffer

5:15 amalloy: zot: what makes you think with-open is impractical? it is easy to apply here

5:15 zot: naivety, clearly :)

5:16 amalloy: (with-open [out (...)] (binding [*out* out] ...))

5:16 zot: but then it will close my stdout after the stmt, correct?

5:17 amalloy: no?

5:17 clojurebot: no is tufflax: there was a question somewhere in there, the answer

5:17 zot: in my head the jvm would have done a nice garbage collection-y thing on the object at the end, which would include flushing the buffers.

5:18 amalloy: the descr from with-open suggests otherwise — "and a finally clause that calls (.close name) on each name in reverse order"

5:18 amalloy: zot: a correctly-written program can never depend on garbage collection for its correctness

5:18 zot: perhaps i misread it?

5:18 amalloy: indeed, it will close out, the temporary thing you created

5:18 but not the stdout for your process

5:20 zot: if stdout is specified as the output, then it would also get closed; it probably doesn't matter here, but i dislike closing stdout, since i will almost certainly later put print stmts, etc., there, and forget that it's dead :/

5:21 amalloy: huh? you are totally focused on imaginary side effects of a thing that is not happening

5:23 zot: https://gist.github.com/anonymous/346827c515696975e94a - for me, only "line 1" is printed, presumably due to stdout now being closed

5:24 amalloy: yes, good lord, don't write that

5:24 nobody said to write that

5:24 zot: but that's my "imaginary" case

5:24 in the let stmt of my code, out can be *out* as well.

5:25 hence my side effect

5:25 amalloy: i see. that was an easy-to-miss subtlety

5:26 then you will need to flush, or use println, which flushes

5:26 zot: now that we've got that out of the way … any great ideas? :)

5:27 yeah, i figured out what the problem was when i used println, but prefer to be explicit with flush since it's required.

5:27 but technically the file still isn't closed, so the argument about relying on GC side effects still carries some philosophical weight

5:29 amalloy: yeah, if you want to have different behavior for the stdout vs file cases, you will have to do more than just bind *out*

6:35 lazylambda: guys, I have a question

6:36 let forms in clojure aren't lambdas like scheme and common lisp, right?

6:37 clgv: no, they are not. are they in CL?

6:38 but maybe you interpret your question differently. can you be more specific?

6:38 lazylambda: yea, (let ((a 1) (b 2)) (+ a b)) is just syntactic sugar for ((lambda (a b) (+ a b)) 1 2)

6:38 in scheme and common lisp

6:39 in clojure, the semantics are different

6:40 clgv: no in clojure it would look like the following java snippet: final long a = 1; final long b = 2; return a + b;

6:40 lazylambda: exactly

6:40 I was just making sure

6:40 clgv: when you use a java decompiler you'll see that pattern

6:41 lazylambda: I was just going through SICP with clojure, and the clojure let was behaving differently than in scheme and CL

6:42 clgv: there is another distinction clojure's `let` is more like `let*` in CL

6:43 lazylambda: you are correct, that didn't hit me

6:45 Bronsa: lazylambda: I don't think any cl/scheme impl actually implements let in terms of lambda

6:46 bja: Bronsa, chicken scheme might, but how it implements it and what happens after compilation don't seem to bear any resemblance to each other

6:46 lazylambda: @Bronse it does, you'll find that explained in SICP and in Paul Graham's Ansi common lisp..it makes sense if you translate one into the other

6:47 @Bronsa it does, you'll find that explained in SICP and in Paul Graham's Ansi common lisp..it makes sense if you translate one into the other

6:48 Bronsa: I suppose implementations are free to do what they want though, but semantically they are both equivalent

6:48 Bronsa: lazylambda: no, all they say is that (let ((a 1)) a) is equivalent to ((lambda (a) a) 1), but in reality they are not implemented in terms of one another

6:50 clgv: Bronsa: that's what I suspected

6:59 lazylambda: Bronsa: I think you're right, I just looked it up

7:06 I am new to clojure, folks. What open source projects would you recommend for a new comer?

7:09 rweir: to learn idiomatic clojure form?

7:12 hyPiRion: I would say that playing around with whatever you're interested in is good

7:12 But 4clojure is generally nice to do to learn clojure

7:13 clgv: lazylambda: yeah try out 4clojrue

7:13 mskoud: Can i get a list of fields from a record? (like python's dir function)

7:14 lazylambda: thanks, I already started solving some problems on 4clojure.

7:14 I am also working on this bug in refheap

7:15 hyPiRion: lazylambda: ah, nice

7:15 lazylambda: I'd like to get into core.logic as well, but I want to finish reading the reasoned schemer first

7:16 rweir: mskoud, (keys)

7:16 lazylambda: Are there any open source AI projects done in clojure?

7:16 mskoud: ah : (map #(.getName %) (.getFields Site))

7:17 ok. keys is nice if i have an instance.

7:18 corecode_: lazylambda: i think the term AI is not used anymore

7:18 now it's machine learning, etc.

7:21 tachibana: it's beatiful ;]

7:22 lazylambda: corecode_: lame :P.. I am more interested in rule based systems, but yea, machine learning is the hot thing today

7:22 tachibana: r u the lamda that is truly lazy??

7:24 clgv: corecode_: it's just not "cool" anymore - but it is still used and distinct from machine learning ;)

7:25 tachibana: yeah you have to call him to get an answer ;)

7:25 lazylambda: I think symbolic AI is more interesting than the statistical stuff

7:26 hyPiRion: lazylambda: I think there's some work with core.logic out there

7:26 tachibana: stumped me with that one

7:27 who's core

7:27 different times call for different measures

7:30 lazylambda: hyPiRion: Nice, I'll look out for that. Thanks.

7:30 daniel___: anyone got a thinkpad E540 and can vouch for it?

7:32 clgv: daniel___: you need someone you can sue if it ends up being crap? :P

7:32 daniel___: yeah clgv

7:33 hyPiRion: lazylambda: I wanted to work on the core.logic version of https://github.com/webyrd/relational-parsing-with-derivatives – but I didn't get time. It's not AI, but it's certainly useful core.logic material

7:33 daniel___: pls provide your address and contact details

7:33 clgv: good look searching ;)

7:33 *luck

7:33 hyPiRion: I know there's other stuff out there, but unfortunately I'm not that into the core.logic work yet

7:33 daniel___: im not american, dont just sue people willy nilly

7:39 CookedGryphon: Which of the automatic test refreshing lein plugins actually works for normal clojure.test?

7:40 Midje doesn't show me the output of my non-midje tests, just says pass or fail, test-refresh fails, quickie always says everything passed, I've tried a few others too

7:42 clgv: CookedGryphon: isn't there "lein autotest"?

7:48 CookedGryphon: clgv: link? the lein-autotest I found on github looks old (last updated 4 years ago and still using lein 1)

7:48 lazylambda: hyPiRion: Nice, I'll check that out

7:48 CookedGryphon: clgv: and doesn't seem to run anything...

7:52 and cider-test-mode doesn't work, borks out with a syntax error...

7:52 clgv: CookedGryphon: damn ok, I just remembered that one

7:52 CookedGryphon: I think I'm stuck going back to the terminal manually

7:53 clgv: doesnt expectations have an autorunner?

7:53 CookedGryphon: well yeah, but I'm not using the expectations test framework

7:54 clgv: CookedGryphon: I thought it might integrate with deftest - but I am not sure, you'd have to check

7:55 CookedGryphon: It probably does, but it still feels like overkill to pull in an entirely different test framework...

7:55 surely there must be a plain clojure.test autorunner which works

7:55 clgv: CookedGryphon: otherwise you could steal from the other autorunners to write one for deftest

7:57 CookedGryphon: according to the readme lein midje should run clojure.test tests

7:59 CookedGryphon: yeah, it does

7:59 but it was losing the output of my test.check and just showing me pass/fail status

7:59 which isn't useful for actually fixing the test

7:59 clgv: hwat output? error messages on failure?

7:59 CookedGryphon: *but* I've just realised taht it was printing it, just elsewhere

8:00 yeah, the actual information about what failed and how

8:00 clgv: probably the reporting part does not integrate well`

8:00 CookedGryphon: yeah, but i've just realised if I'm only dealing with one failing test at a time, the output is manageable

8:01 so I'm happy enough for now

8:01 clgv: but there is definitely room for improvement

8:14 agarman: https://github.com/CareLogistics/somni <- it's yet another Ring routing lib.

8:17 clgv: those grow like grass lately ;)

8:27 agarman: yeah

8:28 it's unfortunate. as hard as we tried, compojure, bidi, gudu, liberator all left us writing code we didnt' like

8:34 zot: is there a psuedo-standard place for test fixtures/inputs? foo/test/resources?

8:35 clgv: zot: "project-root/test" is the convention in lein, but you can change it in the project.clj

8:36 ah you meant input data

8:36 zot: my code is in there; but one of my tests is more end-to-end-ish and needs external inputs

8:36 beat me to it

8:36 hyPiRion: dev-resources

8:36 clgv: exactly ^^

8:37 I wouldnt mix code and resources in general

9:00 stompyj: bbloom: there?

9:42 CookedGryphon: you know how most things in clojure are easily printable? Why oh why do exceptions not list locals?! I have an exception here saying I passed the wrong thing, chances are if I saw what that one thing was I'd twig immediately what I've mixed up

9:42 but as it is I need to reconstruct the situation leading up to this call in the repl now

9:42 justin_smith: CookedGryphon: there are tools that let you investigate locals when stack traces happen

9:43 CookedGryphon: yeah, but I don't want to faff about with custom tooling

9:44 60% of the time, just having a few locals printed in the stack trace, limited to 20 chars or so, would be enough to tell me exactly what the issue is

9:44 justin_smith: How would it know which stack frame to show locals for?

9:45 CookedGryphon: the one that exploded, the top one

9:45 if you're writing semi-reasonable clojure code, everything you're interested in will be closed into that frame

9:45 justin_smith: then you'll get some locals inside clojure.core

9:45 (with most stack traces I see at least)

9:46 CookedGryphon: no you wouldn't

9:46 justin_smith: the top frame, when I see exceptions, is usually quite a few levels of indirection away from any code I wrote

9:47 CookedGryphon: yeah, but the value that caused it to explode is still there

9:48 justin_smith: and it is usually nil

9:48 CookedGryphon: for example if you passed 2 into something which tried to use it as a seq

9:48 that's different

9:48 nil is teh one case where it already gives you the value you passed in

9:48 and it's highly useful

9:48 imagine if instead of saying can't do anything with nil, it just said "There's a problem with the value you gave me"

9:48 because that's the situation we have with every value other than nil

9:49 bbloom: stompyj: what's up?

10:04 boodle: hi, I'm looking to change a vector as follows.. (looking for elegence): https://www.refheap.com/90271

10:10 cityspirit: boodle: try (mapcat identity coll)

10:13 sveri: Hi, I am using midje to count function calls with the provided function, now, I have a case where one function argument is a vector of elements and I want to make sure that function is called with the right number of elements in that factor like this: (provided (func-call arg1 [elem1 elem2]) => anything :times 1). Is it possible to apply some predicates or something like this? (provided (func-call arg1 [(> % 1)]) => anything :times 1)

10:14 boodle: cityspirit: brilliant! Thank you (off to study mapcat!)

10:14 tim_: sveri: if your functions are pure, then why do you need to count how many times they are invoked?

10:14 clgv: boodle: or easier (apply concat coll)

10:14 boodle: clgv: I figured there was an 'apply' way of doing it

10:15 clgv: boodle: mapcat does not makes sense since only the "cat" referring to "conact" is used ;)

10:15 *concat

10:15 tbaldridge: severi: the much better approach (IMO) is to mock out your side-effecting modules, then test the inputs and outputs to the system. Put an atom in the mocks if needed to validate that they are called with the correct data

10:15 sveri: tbaldridge: Basically I want to test if the right calls to the right functions are made, and sometimes not all functions are pure, I guess

10:16 TimMc: boodle: By any chance are you generating these vectors from a for macro?

10:16 tbaldridge: sveri: IMO the way midje encourages you to (provided...) calls is an abomination. That's not the way it should be done </rant>

10:16 boodle: TimMc: honeysql, so I believe yes.. for where stmts

10:17 tbaldridge: sveri: one way (the way I prefer) to look at testing is this: What happens inside my code is of no concern of the tests. As long as the right value is returned and the right side-effects happen, the code is correct.

10:18 TimMc: So, instead of (apply concat (for [v (thing)] ...)), what you can do is (for [v (thing), x ...] x)

10:18 boodle: TimMc: excellent, ty!

10:18 tbaldridge: so test the outputs and mock the side-effects, and you're set. Otherwise if you change the internals of your code, you'll have to update all the tests that make incorrect assumptions as to how the code under test is constructed.

10:18 TimMc: and check out the other bindings and control options in the for macro

10:20 boodle: TimMC, sure, I always think (unfortunately) in terms of 'map' first rather than things like 'for' for generating seqs/colls

10:21 sveri: tbaldridge: this sounds like a valid statement, however, I just have a method that has two side effects (first: write incoming data into database, second grab some changed database data and schedule some events. Then, what would the output of such a function be? How do I test that this function successfully calls the two sideeffecting functions with the correct arguemnts?

10:23 clgv: sveri: do you mock the database with an sqlite database or similar?

10:23 sveri: clgv: I use datomic and it's in memory database functionality

10:23 clgv: ah ok

10:23 tbaldridge: sveri: then you're set! just create the DB at the start of the test, run your code, then run a query against the DB.

10:24 justin_smith: sveri: when possible, it helps to separate logic from side effects - make stateless functions that do all the logic, and then make the part that does side effects a simple conjoining of the logic plus the side effecting code

10:26 sveri: tbaldridge: well, for the first case (writing data to database) that is ok and I have tests for this, but the seconde one is harder, hm, the longer I think about it, the original problem I had was indeed a type problem, I passed a string instead of a UUID, and that lead to the error that no runtime exception was thrown, but even, no data in database was found

10:27 Maybe it's better to do a type assertion on params in that case

10:27 justin_smith: sveri: I think prismatic/schema may help here too

10:28 sveri: justin_smith: Yea, I finally have a reason to look deeper at it

10:28 thanks everybody for taking time to listening :-)

10:28 tbaldridge: sveri: are you sure the Datomic error wasn't swallowed by something? I've had Datomic throw type errors many times.

10:29 sveri: tbaldridge: Well, not 100%, but I think so, I never saw any error, neither during manual tests nor during automated testsin this case

10:49 tbaldridge: sveri: btw, you have an even better way of testing if you're using Datomic. Have your function return pure data, don't call transact inside the function at all

10:54 jtackett: hey has anyone done any clojure work with voice to text

10:54 or speech recognition

10:54 zot: can you run lein on another directly (ie, from a make system, i can do "cd ../foo; lein run …" but wondered if i can do it without the cd indirection

10:55 mdrogalis: jtackett: Sounds like a good place to shell out to Java libs. But I haven't, no.

10:55 zot: s/another/another directory/

10:55 jtackett: mdrogalis: I think you’re probably right, just hoping there is a clojure library/wrapper for it

10:56 justin_smith: zot: if you have an uberjar, you can run java from anywhere and point the classpath to the uberjar

10:56 zot: justin_smith: that way i knew, but was curious about it from a 'live' dir, without having to gen

10:56 mdrogalis: jtackett: Definitely :)

11:17 Jaood_: b

11:18 jlongster: hey guys, transducers provide a way to to make a custom data type that is reducible and automatically get all the transforms. but I don't see a protocol for constructing my custom data type. does it need to implement `conj` somehow?

11:19 or are you supposed to just natively take an transducer and my data type runs it and returns a collection of the same type as itself?

11:22 lvh: jlongster: CollFold, CollReduce

11:22 jlongster: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj#L13

11:22 jlongster: lvh: `reduce` only implements how to take apart the data and iterate over it. it doesn't care about how you piece it back together into a specific type

11:22 lvh: you get Iterable for free though

11:23 jlongster: the function I pass to `reduce` will manually create something like a vector using `conj`

11:24 lvh: jlongster: ehh? that sounds different from what you were just saying about creating a custom reducible datatype

11:25 jlongster: lvh: I said I understand that part of it. I don't understand the other end. You can `into` to "run" a transducer and create a new type, but it uses `conj` so can only create native data types

11:25 if I create a new data type, what is the pattern for providing something like `into`?

11:30 lvh: jlongster: Okay, so, to be clear: you're not interested in getting your data structure to be foldable/reducable, you're interested in getting into to dump items into your data structure?

11:31 jlongster: lvh: yes! and full disclosure, I'm just studying and am not trying to do something specific.

11:32 dnolen_: jlongster: this is why transduce takes a transformer `xform` and `f`, `f` builds the next result

11:32 lvh: jlongster: So, "conjable" is IPersistentCollection

11:32 dnolen_: it's also why transduce really requires an initial value, `f` must produce it or you must give `init`

11:33 lvh: but dnolen_'s answer is the enlightening one here, I presume :)

11:33 jlongster: dnolen_: yeah, I didn't know if there was a way to have the simplicity of `into`. if I want to just `map` over my structure and not think about reduce

11:33 dnolen_: jlongster: transducers have nothing to do w/ conj, you can use map/filter now to build arrays if you like in CLJS

11:33 jlongster: lvh: what's `conjable`?

11:34 dnolen_: oh yeah, I realize that. I was just looking to see if there was a way to do something like `into` (which assumes how it's reduced and put back to together)

11:34 dnolen_: jlongster: into is just really just `f` = `conj` and `init` = empty data structure

11:34 transduce with those arguments supplied

11:35 not exactly much more verbose

11:35 especially if `f` can supply init

11:36 jlongster: dnolen_: well, (transduce (map inc) conj [] [1 2 3 4)) is more verbose than (map inc [1 2 3 4]). now assume I'm not working with a vector, but with a custom type

11:37 dnolen_: well first off (map inc [1 2 3 4]) doesn't even do what you want :)

11:37 (vec (map inc [1 2 3 4]))

11:37 or (into [] (map inc [1 2 3 4]))

11:38 that's what you're comparing transduce to

11:38 jlongster: dnolen_: still writing clojure abstractly (haven't written much real code), sorry :)

11:38 justin_smith: $source mapv

11:39 jlongster: dnolen_: I see. map returns a lazy-seq when the collection is there

11:39 dnolen_: jlongster: yep

11:39 jlongster: but, as you probably already know, into is now defined in terms of transduce now

11:40 jlongster: yeah! but I'd like that short form to also because to create custom data types somehow

11:40 so I'm working on transducers.js. It's pretty awesome. I get everything but this is the last piece

11:41 dnolen_: jlongster: there's not really any good way to magically do that at least in a dynamically typed context, not w/o a the collection supplying an answer to something like empty

11:41 note all of this is really orthogonal to transducers

11:41 SagiCZ1: ~?

11:41 dnolen_: since transducers are designed specifically to not have to deal w/ collections

11:41 clojurebot: excusez-moi

11:41 dnolen_: otherwise the core.async transducer stuff would not work

11:41 jlongster: dnolen_: yeah, this has nothing to do with transducers. I'm trying to figure out what convenience functions to provide for stitching values back together

11:41 that's all

11:43 you wouldn't normally use `transduce`, but rather `into` because it's shorter

11:43 dnolen_: jlongster: but you're not really asking about `into` right?

11:45 jlongster: dnolen_: I guess not exactly. I know how it works, but you can't use it if using custom data types. If I'm using immutable-js with transducers, I'd rather not always have to use `transduce`

11:45 but maybe I should try that first

11:45 dnolen_: jlongster: in ClojureScript this is non-problem because of protocols

11:45 jlongster: you can make a custom data type implement ICollection, IEmptyable - done

11:46 jlongster: oooooh there it is. That means you implement `conj` for your structure. yep

11:46 exactly what I was looking for

11:47 yeah protocols are awesome, I hate JS's lack of interfaces

11:48 dnolen_: btw my transducer.js already beats lodash is many benchmarks, haha

11:48 *in many

11:48 dnolen_: jlongster: nice not suprising. I expect transducer to crush anything that people have yet tried in JS

11:49 jlongster: dnolen_: it's absolutely ridiculous. great performance and one single API works with everything. you guys are smart.

11:50 tbaldridge: jlongster: Rich is the smart one, we are simply his oracles here on earth.

11:51 jlongster: tbaldridge: haha

11:51 mdrogalis: Big red, run. :|

11:56 stompyj: does @aphyr ever hang out here?

11:56 justin_smith: stompyj: he is very active on twitter

11:58 stompyj: justin_smith: thx, I’ll ping him on there

12:01 perplexa: hi, when i have a map like { :kw1 { :kw2 { :kw3 "somevar" } } }, what is the preferred way to access "somevar"? i think i've seen something more elegant than (:kw3 (:kw2 (:kw1 {...}))) but can't remember anymore

12:01 jbaiter: who would have thought that aphyr is into bondage...

12:02 mdrogalis: jbaiter: That awkward moment when an industry leading database thinker posts bdsm pictures to Twitter.

12:02 perplexa: get-in

12:02 perplexa: ah yeah thx!

12:03 mdrogalis: Np!

12:04 raspasov: perplexa: also (-> my-map :kw1 :kw2 :kw3)

12:04 aka thread-first macro

12:09 perplexa: raspasov: get-in is the preferred way, isn't it?

12:11 raspasov: it might be, someone with more experience might want to chime in - the thread-first macro basically does a macro re-write of pretty much exactly what you posted (:kw3 (:kw2 (:kw1 {...})))

12:12 perplexa: thanks :)

12:12 raspasov: np :)

12:12 noonian: get-in is nicer when you have a collection of nested maps like that since you can do (map (partial get-in [:k1 :k2 :k3]) my-maps)

12:13 raspasov: as long as your keys are keywords, I believe both offer safety guarantees in the sense it won't throw exception of a key is missing and return nil instead

12:13 if a key*

12:14 noonian: doh my example was wrong heh, can't use partial like that since it expects the map as the first arg :P

12:16 justin_smith: (map (comp :kw3 :kw2 :kw1) c)

12:19 raspasov: justin_smith: nice :)

12:27 justin_smith: ,(letfn [(rot [f & args] (apply f (last args) (butlast args)))] (map (partial rot get-in [:a :b :c]) [{:a {:b {:c 0}}} {:a {:b {:c 2}}}]))

12:27 clojurebot: (0 2)

12:27 TimMc: $seen aphyr

12:28 justin_smith: TimMc: lazybot is still out

12:28 TimMc: :-(

12:32 arrdem: cbp: o/

12:33 cbp: arrdem: sup

12:42 hoverbear: Anyone ever had this issue before with clj-http? Cannot cast DefaultHttpClient to CloseableHttpClient https://gist.githubusercontent.com/Hoverbear/f9715961a5cd8ea19cdb/raw/150944c1efeaee72231595fa353313cffd5d5800/gistfile1.clj

12:47 perplexa: raspasov: so, the thread first macro fails for (-> config :kw1 (keyword "kw2") :kw3), whereas get-in works :)

12:48 surprisingly works, though when i assign (keyword "kw2") to another variable first, though.

12:48 at least to me that's surprising :P

12:48 otherwise i get: ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.lang.String clojure.core/keyword (core.clj:575)

12:49 quile: well, isn’t the problem that (keyword "kw2") is being rewritten by the macro?

12:49 justin_smith: perplexa: ((keyword "kw2")) would also work

12:50 perplexa: indeed it does

12:50 justin_smith: perplexa: welcome to the weird side of macros

12:50 perplexa: haha

12:50 justin_smith: (it gets much weirder)

12:50 perplexa: yeah i've seem some of them ;x

12:51 clojure must be the most unintuitive thing to learn \o/

12:51 it's fun tho

12:51 justin_smith: perplexa: the number of rules and special cases to remember is actually fairly low, it's just not the same rules and special cases all the "normal" languages have is all

12:52 perplexa: sometimes i end up catching myself writing something like x * y and then wonder why it doesn't work :D

12:53 moments of epic facepalm

12:53 SagiCZ1: perplexa: happens to me all the time

12:53 arrdem: $google expresso

12:54 cbp: ~lazybot

12:54 clojurebot: lazybot is echo ~lazybot

12:54 justin_smith: $google where is ma lazybot, bring back ma lazybot dammit

12:54 arrdem: expresso's good for when you need infix math... but it's definitely not as nice as I'd like

12:54 SagiCZ1: perplexa: but what gets me everytime are the idiotic nonsensical exceptions.. for example Class not found when you pass int instead of double into some Math function.. i HATE that

12:54 arrdem: Raynes: UR BOT IZ TRASH AND U R 2

12:54 SagiCZ1: ,(Math/sqrt 5)

12:54 clojurebot: 2.23606797749979

12:54 Raynes: I don't think anyone ever just says "lazybot is down" anymore.

12:54 SagiCZ1: ,(Math/sqrt (int 5))

12:54 clojurebot: 2.23606797749979

12:54 SagiCZ1: damn it

12:55 perplexa: :D

12:55 arrdem: Raynes: but that's no fun...

12:55 SagiCZ1: perplexa: ok i guess it just doesnt work in my project xD

12:55 ,(Math/sqrt 5 5)

12:55 clojurebot: #<CompilerException java.lang.IllegalArgumentException: No matching method: sqrt, compiling:(NO_SOURCE_PATH:0:0)>

12:56 SagiCZ1: that kinda makes sense.. ok i will shut up now

12:56 perplexa: soooo, which do i want? (-> config :aggregations ((keyword aggregation)) :sink-schema) vs (get-in config [:aggregations (keyword aggregation) :sink-schema])

12:56 they're both kinda nice :P

12:57 cbp: i think the latter is easier to understand

12:57 perplexa: so i go with the former? :D

12:57 justin_smith: ((comp :sink-schema (keyword aggregation) :aggregations) config)

12:57 noonian: perplexa: i like the latter, agree with cbp

12:57 perplexa: me too, actually.

12:57 also need to look up what comp does :P

12:58 noonian: stands for compose

12:58 cbp: makes you an egghead

12:58 TimMc: Raynes: What, you don't have a paging alert on lazybot's status?

12:58 noonian: ((comp f g) 7) == f(g(7)) in math syntax

12:59 justin_smith: I like comp because it returns a function, so you can easily bind it to a more meaningful name and call that

12:59 noonian: yeah, i like using it like that, same with partial

12:59 justin_smith: (let [get-schema (comp :sink-schema (keyword aggregation) :aggregations)] (map get-schema configs))

12:59 noonian: and it makes your programs 'cuter'

13:00 justin_smith: noonian: yeah, gotta keep up with the kawaii metrics

13:01 TimMc: hiredman: Moving `lein compile` from encrypted disk fs to a ramfs took real/user timing from ~70/30 to ~15/30. So that seems confirmed.

13:01 noonian: justin_smith: always introducing me to new memes :P

13:02 perplexa: thx justin_smith / noonian

13:02 learned something new again today

13:02 comp is damn mind twisting, tho

13:03 arrdem: eh? the only remotely odd thing about comp is its argument order...

13:03 perplexa: well it's reversed ;p

13:03 arrdem: right that's what's confusing about it :P

13:05 justin_smith: noonian: thanks to this exchange, my usage of comp will now be accompanied by the mental image shrieking teenage japanese cartoons with heart bubbles and eyes larger than their cranial capacity

13:09 dmitrygusev: just knew there's Clojure Russia community on G+, please join: https://plus.google.com/u/0/communities/114227952963737516047

13:09 perplexa: thanks for all the advice, guys

13:51 Grazzy_: Hola!

13:53 shoepie: Grazzy_: sup

13:54 Grazzy_: shoepie: looking for new interesting chans

13:55 justin_smith: Grazzy_: if you want to learn more about the Clojure programming language, this is a very interesting chan

13:55 Grazzy_: I want to learn as much as possible

13:55 I was told to come here

13:55 Can you tell me a bit about it?

13:57 justin_smith: It's a langauge in the lisp-1 family that stresses immutibility and tractible concurrency

13:58 xemdetia: Grazzy_, have you seen all the Rich videos?

13:58 it answers a lot of the why

13:59 Grazzy_: nope

13:59 noonian: yeah, i would highly recommend the 2008 video introducing clojure from infoq

13:59 Grazzy_: http://www.infoq.com/presentations/hickey-clojure

14:00 and just be prepared for things to be very different from what you are used to at first if you have never seen a lisp before or done functional programming

14:00 Grazzy_: noonian: Thanks

14:00 noonian: np

14:00 xemdetia: If anything it should make you more intrigued :)

14:00 Grazzy_: Oh now i get it

14:01 I messed around with it a while back

14:01 Lisp is great

14:01 So hard though

14:01 Whats the application of this language in the bigger picture?

14:02 justin_smith: Grazzy_: easy to use concurrency

14:02 (with performance)

14:02 noonian: for me it has become my goto language for anything that doesn't need to startup fast or run on embedded devices

14:02 tbaldridge: Grazzy_: assuming you mean "what can Clojure be used for", pretty much anything. Perhaps except shell scripting.

14:02 Grazzy_: Nice

14:03 Ill look into it

14:03 This looks great

14:03 Bronsa: tools.analyzer now has a pass scheduler :) https://github.com/clojure/tools.analyzer.jvm/commit/4183ba79ef47ba57de3af46aac1d318fa1a0cd8a

14:03 xemdetia: Yeah the only thing I would mention that you may not have come across Grazzy_ is lein

14:04 Grazzy_: How big the community and support structure i.e stack over flow and fourm posts

14:05 tuft: Grazzy_: not too big and not too small in my experience

14:05 noonian: in my subjective opinion, there is a very active, helpful, and enthusiastic community

14:05 justin_smith: this channel and stackoverflow are pretty active

14:06 Grazzy_: Yuh yuh

14:06 im pumped

14:08 clear

14:08 Man this is great. Lisp that i dont understand mixed with something i know

14:08 :D

14:09 How many of these mixed breed languages are out there

14:09 tuft: Grazzy_: yes, it's an excellent gateway lisp =)

14:11 xemdetia: Grazzy_, I would look at some of the other languages that cropped up on the JVM

14:11 Grazzy_: Ok

14:11 Im so glad i started using IRC

14:12 xemdetia: It's mostly the fact that you can write in a new and interesting language and still have access to what you need from JVM which makes languages like clojure more practical then it otherwise would be

14:12 Grazzy_: I wish i was born 10 years earlyer and lived in the prime of the internet growth and culture

14:12 xemdetia: Grazzy_, IRC existed more than 10 years ago :)

14:12 Grazzy_: Yea

14:13 But 10 years is what i wanted

14:13 *want

14:13 tbaldridge: Grazzy_: but yes, there are other languages that mix a OOP platform with some other language. F# and Factor are two others that come to mind. But Clojure is probably the best :-P

14:13 Grazzy_: sweet

14:14 noonian: Clojure was the answer to my quest for a practical lisp

14:14 xemdetia: and Grazzy_ I wouldn't worry about when you got started- what's interesting now is interesting because it solves problems of the time

14:14 just make cool stuff

14:14 Grazzy_: For sure! i love the technology that am able to grow up on. There is so much interesting things to learn

14:15 There is so much i have no idea what my technological passion truly is

14:18 tuft: Grazzy_: the good pockets of irc are much the same as a decade ago =)

14:18 s/as a/as/

14:21 ToxicFrog: Re: practical lisp: similarly for me, Clojure is the only lisp I've actually gotten real-world work done in.

14:21 I liked Scheme but I never really did anything with it.

14:23 xemdetia: scheme is fun, and gambit is very slick but the fact that normally with a lisp or scheme you had to build your entire library base from scratch make them nonstarters

14:24 noonian: plus they all support different libs and module systems so it is hard to write portable code

14:31 yocapybara: hi guys, I'm in cider, and I find I'm looking for a command to evaluate everything in my buffer, but in the REPL buffer so I can then mess around with the code. Am I really looking for a wrong thing? I keep finding I have to copy or C-c M-p each form into the repl, so I wonder if I'm just plain doing things oddly

14:31 ToxicFrog: xemdetia, noonian: yeah, that was kind of my impression, and well if I want a lightweight language with no library support I already have Lua for that~

14:43 technomancy: ToxicFrog: Scheme is way older than Lua

14:43 noonian: i still use scheme when i want a repl that loads quickly for small computations

14:43 ToxicFrog: technomancy: yes, but I learned Lua first

14:44 xemdetia: embedding Lua is still much nicer then scheme

14:44 tinyscheme isn't awful

14:44 just Lua is easier

14:44 technomancy: ToxicFrog: oh, I read that as "we already have lua" like as a civilization or something

14:45 ToxicFrog: Yeah, no, it was that I personally knew Lua well before I looked at Scheme

14:56 snrmwg: hello, does anyone have good ideas for CRUD method names? i thought about something like api namesapces, each domain goes in a namespace, but function names like 'read', 'load' (and i think 'update' at clojure 1.7) are already defined in clojure.core. method names like 'my.api.domain/read-domain' look somehow redundant to me.

14:57 noonian: you can tell clojure to not refer to the core functions you want to define yourself if you want

14:58 in your ns form (:refer-clojure :exclude [read load])

14:58 i'm still experimenting myself with good api ns organization

14:59 snrmwg: cool. didn't know that feature, i will give it a try.

14:59 is it also possible to refer the core functions with an alias? just in case i would need one of them?

15:00 xemdetia: You should be able to import it directly again, right?

15:00 or the longname

15:01 (these are guesses)

15:01 snrmwg: ok, just never thought about importing something from core :) but why not, it's just a namespace as any other

15:02 yogsototh: Hi! I am trying to use friend interactive-form, while the demo works the same workflows doesn't set any cookie. How could I start to debug this?

15:03 sritchie: yogsototh: do you have session middleware in place?

15:03 yogsototh: it’s the session middleawre that sets the cookie, not friend

15:03 yogsototh: ok thanks!

15:06 sritchie: thanks! It works. I didn't know how I could discovered this myself.

15:07 sritchie: I think he mentions it on the README

15:07 it’s pretty buried though:

15:07 https://github.com/cemerick/friend#authentication

15:07 see “Note that Friend itself"...

16:20 kschrader: anybody know how to jump to test definitions in the new version of Cider? it used to be C-c C-t, but now that says "No test report buffer"

16:20 AeroNotix: kschrader: never update CIDER if you can help it

16:21 kschrader: yeah, too late for that...

16:21 AeroNotix: kschrader: if you just upgraded "just because" then I'd advise you to downgrade if you have real work to do

16:21 it's so broken on their latest release that it's horrible

16:21 your .emacs.d should be in VCS

16:21 if not, time to start :)

16:21 kschrader: yeah, it is, I was just hoping for an answer :)

16:22 justin_smith: kschrader: every command is available by name via M-x, and if it has a keyboard shortcut, emacs will show you the shortcut in the minibuffer after running the command

16:23 it should be called something like cider-jump-to-definition

16:24 I think the canonical keybinding has always been M-.

16:25 kschrader: yeah, that's not what I'm looking for

16:25 maravillas: kschrader: C-c C-j, I believe

16:25 if you're looking to jump from foo.clj to foo_test.clj, e.g.

16:25 justin_smith: kschrader: ahh, sorry, I missed the word "test" in your question, sorry

16:26 kschrader: maravillas: That's what I'm trying to find

16:26 but it doesn't seem to work anymore

16:26 stompyj: the first rule of CIDER club is never update CIDER

16:26 maravillas: M-x clj-jump-to-other-file ?

16:26 kenrestivo: first rule of cider club is use nrepl.el :-P

16:26 i've been avoiding cider for years, so far so good.

16:27 kschrader: ah, it's M-x clojure-jump-to-test now

16:27 stompyj: (inc kenrestivo)

16:27 lazybot: ⇒ 1

16:27 stompyj: I’m on the cursive clojure train

16:40 jlongster: how do I install Clojure 1.7 with lein?

16:43 technomancy: jlongster: just edit project.clj

16:44 jlongster: technomancy: I tried that, but got https://gist.github.com/jlongster/4524b4552a1f98aac516

16:44 technomancy: oh, sorry... you mean the snapshot?

16:45 jlongster: yeah

16:45 gphilippart: hi, how do I add a map to a vector ? For example I have {:a :b :c :c},, how do I get [{:a :b :c :d}] (conj and into won't) ?

16:46 technomancy: jlongster: it's in the sonatype snapshots repository

16:46 seancorfield: jlongster: "1.7.0-alpha2" or "1.7.0-master-SNAPSHOT" (for the latter you'll need to add the sonatype snapshots repo)

16:46 you can use the alpha from maven without adding extra repos tho'

16:46 jlongster: oh, thanks

16:46 seancorfield: we're running alpha2 in production...

16:47 snrmwg: gphilippart: (conj [] {:a :b :c :c})

16:49 gphilippart: hm, yeah right.

16:51 noonian: ,(into [] [{:a :b :c :c}])

16:51 clojurebot: [{:c :c, :a :b}]

16:52 noonian: ,(vector {:a :b :c :c})

16:52 clojurebot: [{:c :c, :a :b}]

16:53 justin_smith: ,,(assoc-in (vector {:a :b :c :c}) [0 :c] :d) ; pedantic

16:53 clojurebot: [{:c :d, :a :b}]

16:54 noonian: :D

16:54 gphilippart: the issue I'm facing is when using clj-http.client/get, sometime it returns a vector of maps, and sometimes it returns just a map. I'd like to add both these types of results into a vector and return it with one expr. Is it possible ?

16:55 justin_smith: wow, I didn't think client/get was so fucked up as to randomly return different datatypes

16:56 noonian: ,(let [get-result [{:status 200}]] (if (vector? get-result) get-result (vector get-result)))

16:56 clojurebot: [{:status 200}]

16:56 noonian: i just had this problem in python

16:56 dakrone: gphilippart: get should never return a vector of maps, it should always be just a map, do you have code that backs up what you're seeing?

16:56 gphilippart: it doesn't do that randomly, I'm calling github's various api. /users will yield a vector of maps. /users/rhickey will yield a single map.

16:56 dakrone: ahh yea, that's not clj-http, it's github's API

16:56 noonian: xmltodict uses lists if there are more than one child nodes and a single one otherwise, really annoying imo

16:57 justin_smith: gphilippart: so if you know what shape the data has by endpoint, why not have a different adaptor function as needed for each endpoint?

16:57 noonian: ^ this

16:58 justin_smith: phew, good to know client/get is vindicated, I did think it was better than that

16:59 gphilippart: I'd like a function that gets any resource. It recurses on the 'next' link in the header ( https://developer.github.com/guides/traversing-with-pagination/).

17:01 CisZZZa: Hello

17:03 danielcompton: gphilippart: not sure if you've seen https://github.com/Raynes/tentacles? I haven't checked to see if it keeps the shape the same or not

17:46 seangrove: $seen bbloom

17:46 lazybot: bbloom was last seen talking on #clojure 3 days ago.

17:52 justin_smith: seangrove: in this case it wouldbe more appropriate to ask bbloom how recently he saw lazybot - he was around earlier today

18:03 seangrove: justin_smith: I guess lazybot isn't quite as perceptive as one might hope...

18:11 amalloy: is there some issue with lazybot's $seen?

18:16 justin_smith: lazybot has not been online consistently

18:16 he had a bunch of downtime this weekend

18:19 amalloy: lazybot: you're fired

18:26 noonian: lazybot should pull and parse rayne's logs on startup and backfill his or her or it's $seen data

18:26 amalloy: noonian: lazybot produces Raynes's logs. unless you mean the ones on his pc?

18:26 noonian: oh lol

18:27 i didn't know that

18:27 amalloy: lazybot lives on the server Raynes and i run, and produces the logs at logs.lazybot.org

18:27 Raynes: I can assure you, the logs on my machine are far worse than lazybot's.

18:27 Especially given that I'm pretty sure I don't log.

18:27 :p

18:27 amalloy: yeah, i would have guessed that too

18:28 Raynes: But yeah, lazybot has been going down a ton in the last week or so.

18:28 tac_: ,conj

18:28 clojurebot: #<core$conj clojure.core$conj@15d87c>

18:28 noonian: naughty bot

18:28 tac_: Can you get a docstring from a function name?

18:29 noonian: tac_: you can get the meta data off the function's var

18:29 amalloy: from a function *name*? yes, just call doc. from the function itself, no

18:29 tac_: ,doc "conj"

18:29 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0:0)>

18:29 tac_: ,(doc "conj")

18:29 clojurebot: #<CompilerException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)>

18:29 noonian: ,(doc conj)

18:29 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

18:30 tac_: ,doc

18:30 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0:0)>

18:30 tac_: hmm

18:31 noonian: ,(-> 'clojure.core/conj find-var meta :doc)

18:31 clojurebot: "conj[oin]. Returns a new collection with the xs\n 'added'. (conj nil item) returns (item). The 'addition' may\n happen at different 'places' depending on the concrete type."

18:31 noonian: ,(doc doc)

18:31 clojurebot: "([name]); Prints documentation for a var or special form given its name"

18:31 noonian: ,(source doc)

18:31 clojurebot: Source not found\n

18:31 noonian: ,(macroexpand '(doc doc))

18:31 clojurebot: "([name]); Prints documentation for a var or special form given its name"

18:31 tac_: ,(source conj)

18:31 clojurebot: Source not found\n

18:32 noonian: ,(macroexpand-1 '(doc doc))

18:32 clojurebot: "([name]); Prints documentation for a var or special form given its name"

18:33 noonian: hmm, i wonder why clojurebot does that, I get this in the repl

18:33 ((var clojure.repl/print-doc) (clojure.core/meta (var doc)))

18:34 ,*clojure-version*

18:34 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

18:35 xemdetia: I'm just waiting for the day where I can do CI over IRC

18:35 noonian: i think that day has arrived

18:36 we do ci over hipchat, i'm sure you could hook it up to irc without much trouble

18:37 xemdetia: I was more talking about me personally

18:37 Bronsa: ,(class @@#'doc)

18:37 clojurebot: clojure.core$eval445$fn__446$my_doc__447

18:37 Bronsa: noncom: ^ that's why

18:38 clojuredoc redefines clojure.repl/doc

18:38 noonian: ah

18:38 Bronsa: ,@#'doc

18:38 clojurebot: #'clojure.core/my-doc

18:38 noonian: Bronsa: i'm sure noncom was interested also :P

18:39 Bronsa: this is probably better

18:39 noonian: ops

18:40 tac_: ,(doc reduce)

18:40 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...

18:45 shd: Does anyone know "gloss" library? https://github.com/ztellman/gloss Is it possible to read compiled frame size instead of entering it manually? Sorry for such a newbie question but i'm newbie indeed and i'm trying to learn by practice...

18:46 i would figure it out myself but it's very hard for me to read this code yet

18:56 noonian: shd: i'd look at the wiki: https://github.com/ztellman/gloss/wiki/Introduction

18:56 shd: noonian: of course read it, did you found answer to my question there? maybe i missed it..

18:56 noonian: imo manipulating raw bytes is not the easiest way to get a feel for a language unless its something a little closer to c :P

18:59 shd: noonian: you might be right, but i'd like to use clojure in my hobby project and since it doesn't interface with C ABI that well i need to rewrite some basic stuff in it

19:00 noonian: shd: i'm not sure, but i think you need to call compile-frame to create a codec, and then should be able to call decode with that codec and your raw frame and it should decode it

19:00 raw frame meaning a byte stream

19:01 shd: noonian: thanks, but i understand how to make a frames and decode them, it's just annoying to write [buf (byte-array 16) ...] manually, i don't really see this need

19:02 noonian: shd: i might be more help if i had a better understanding of what you are trying to do. Are you trying to serialize clojure data structures as bytes or read them back or both?

19:02 tac_: ,(doc ->>)

19:02 clojurebot: "([x & forms]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

19:03 tac_: does that just mean that (->> x f g) = (g (f x))?

19:04 noonian: tac_: yes, but it's a little more complicated when your fns take more than 1 arg

19:05 shd: noonian: i'm trying to read binary TO clojure - basically parse a file

19:05 noonian: (->> x (f 8) g) = (g (f 8 x))

19:06 shd: right, so i guess i don't understand why you are creating a byte-array manually then, since you already have binary data to read

19:06 shd: when i define a frame i'm declaring arguments with their length as well, it's annoying having to type them in (byte-array count) again, i believe there is easy workaround for that

19:07 noonian: that would be great to read directly from buffer - i were not able to do it yet :P

19:07 noonian: shd: i probably can't be much help since I have zero experience reading binary formats in clojure

19:07 shd: noonian: right, thanks for trying anyway

19:08 noonian: shd: np, don't give up on clojure even if you can't figure this thing out!

19:09 justin_smith: shd: looking at the docs, what about using "repeated"?

19:10 shd: justin_smith: frames vary between each other, as i understand repeated is for same types of data

19:12 i.e. byte + ushort = 3, then i read uint + uint = 8, every time i need to add this numbers in my head while i should be able to read them from frame definition i.e. sizeof()

19:13 justin_smith: shd: The author, ztellman, hangs out here, maybe he is around for answering questions

19:14 shd: justin_smith: thanks, if i wont find any solution i'll be definitely haunting him :P

19:16 amalloy: i don't understand why you're adding these numbers together in your head either. you shouldn't need to know them at all

19:17 tac_: noonian: right.

19:19 shd: amalloy: do you mean i shouldn't read through the byte-array or i should read them from their definitions?

19:19 not really logical what i said, but i hope you grasp the point

19:20 amalloy: you should define a single gloss frame that is capable of reading the entire thing from the buffer at once. don't make a million sub-frames and feed them sub-arrays or something weird like that

19:21 shd: amalloy: yes, i'm trying to reach that point, but it's easier to solve small problems than parse whole file at once

19:23 amalloy: major problem is: i don't couldn't find a way to define struct{ int type_id, union{ string a, byte b, int c } }... actually union isn't correct too, because this attributes might not exist at all

19:23 so i hoped to solve this problem in my own function

19:24 justin_smith: so there is no defined frame type, it's just free form tagged unions?

19:26 shd: justin_smith: everything mixed with each-other, but you're right - not everything is known at the time i declare frames

19:27 amalloy: justin_smith: the C tradition of the 70s: just write structs directly as binary

19:29 Guest47278: Perhaps a stupidly vague/broad question, guys. Does experience suggest that Clojure is a language that takes a *long* time to learn? Coming from, say, a Ruby background with rudimentary FP knowledge

19:29 I'm comparing primarily to Scala - which really seems to qualify, to me, as a language that takes a whole lotta time.

19:30 justin_smith: Guest47278: clojure is nowhere near the leage of scala or c++ in terms of complexity

19:34 seancorfield: Guest47278: The real learning curve is the Functional Programming paradigm, not the language itself.

19:34 Guest47278: seancorfield: I certainly recognize that - but I also recognize that Scala is a highly complex language

19:34 seancorfield: Clojure is a pretty simple language, with a relatively small core library (compared to many other languages' libraries).

19:35 Jaood_: yeah, the core only has like 600 functions :P

19:35 seancorfield: Yes, there's a lot of syntax and semantics to learn in Scala - but you can plough on writing OOP code in Scala if that's your background, you're not "forced" to learn FP.

19:38 Jaood_: you think 600 is a lot? have you looked at the number of methods in Ruby 2 for example? :)

19:38 numberten: is there a core function for changing the value of a key in a map?

19:38 justin_smith: numberten: there is update-in

19:38 amalloy: numberten: are you looking for assoc?

19:39 justin_smith: ,(update-in {:a 0 :b 1} [:a] inc)

19:39 clojurebot: {:b 1, :a 1}

19:39 seancorfield: Jaood_: I could about 1,700 functions here http://www.ruby-doc.org/core-2.1.2/

19:39 numberten: the value of a key

19:39 seancorfield: s/could/count/

19:39 akkad: are there any primers for CL -> clojure?

19:39 numberten: (foo {:a 10} [:a :b]) => {:b 10}

19:39 something more like that

19:40 specifically for nested keys, so like assoc-in

19:40 Guest47278: seancorfield: Ruby 2 doesn't have that many methods, does it..? It's my dayjob, I never knew :)

19:40 amalloy: numberten: clojure.set/rename-keys

19:41 Guest47278: in all the classes in all the standard lib? gotta be about a trillion

19:41 justin_smith: yeah, likely update-in plus rename-keys for the nested situation

19:41 Guest47278: amalloy: standard lib != core though

19:41 seancorfield: Guest47278: I just looked it up out of curiosity... I'd say most languages have a lot more than 600 methods/functions in their core (language plus auto-imported classes)...

19:41 numberten: alright

19:41 didn't think to use update-in alongside rename-keys, thanks

19:42 Guest47278: Ruby's methods do seem to have a knack for being extremely powerful, even more so when put together, though

19:42 Referencing docs for ruby methods never seems a prohibitive deal

19:42 seancorfield: Guest47278: indeed... and a lot of Ruby folks seem to love Clojure for its dynamic power too...

19:43 Guest47278: Partially due to its awesome docs, as well, I'm sure. It's amazing what the stylesheet on a language's docs do for the language.

19:43 seancorfield: Personally I don't like Ruby's syntax - but that sort of thing is very subjective.

19:43 I love being able to get docs on functions in the REPL (since it's just metadata on the fn itself)

19:43 justin_smith: I tend to find many of the things that are considered "friendly" or "usable" in ruby-land to be annoying

19:44 Guest47278: justin_smith: example? (for my understanding)

19:45 seancorfield: it's possible to do that with Ruby too (Pry) - but I'm not here to evangelize ruby :)

19:45 In fact, i'm actually here to discover my exit strategy

19:45 Jaood_: seancorfield: that's not fair, some methods are inherited showing them more than once on the list (for each class), ruby also likes to give the same method multiple names :/

19:45 justin_smith: Guest47278: ubiquitous usage of ansi colors (often ignoring what I am actually doing with the tool's output)

19:46 Guest47278: justin_smith: hey that's not rubylang!

19:46 justin_smith: OK - sure

19:48 Guest47278: do you guys find clojures lack of types to be prohibitive?

19:49 the inability to create abstraction in the same way

19:49 justin_smith: we have types, they are just late-bound

19:49 ,(1 1) ; type error

19:49 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

19:49 Guest47278: justin_smith: can you create your own

19:49 justin_smith: yeah, deftype or defrecord are the easiest ways

19:50 the main focus is developing against interfaces (for java interop) or protocols

19:51 Guest47278: justin_smith: is there a clear route on getting a firm grip on clojure in a short period of time?

19:51 justin_smith: i know in my lifetime, to learn what i've learned in the languages i know, they were extremely long and winding paths, stepping through many turds on the way

19:51 justin_smith: Guest47278: really depends on where the gaps in your experience are - do you have experience with coding with immutible data? lisp syntax?

19:51 Guest47278: I want something quick & direct now :)

19:52 Jaood_: Guest47278: get a book

19:52 Guest47278: justin_smith: immutable data, yes - lisp syntax, not a great deal. Although I've done Little Schemer, for instance.

19:52 (People definitely describe their degrees of experience with orders of magnitudes differences in optimism :)

19:53 seancorfield: Jaood_: my experience with Ruby is that it seems to like offering lots of different ways of doing the same thing - which expands the surface area of what you need to learn... but I think measuring the "size" of a language's function base is a bit pointless and misleading so I was merely reacting to the complaint that clojure.core is "big" (I don't consider it so).

19:53 Guest47278: Is there a "best" book on clojure?

19:53 justin_smith: ~book

19:53 seancorfield: Guest47278: you'll get different answers from different people

19:53 clojurebot: book is books

19:53 justin_smith: ~books

19:53 clojurebot: books is http://clojurebook.com/ http://joyofclojure.com/

19:54 Guest47278: The one thing I hate about whenever I revisit FP, is I find I'm reading the same crap about FP over and over again

19:54 seancorfield: Guest47278: my preference/recommendation is the o'reilly book first and joy of clojure second

19:54 so, yeah, same books justin_smith listed

19:54 Guest47278: awesome, thanks.

19:54 justin_smith: seancorfield: I credit whoever made the factoid

19:55 Jaood_: seancorfield: yeah, I was not being serious, you don't really need all that functions to start programming in clojure since most are just abstractions and can be easily be pick up with time

19:55 justin_smith: Guest47278: reading the same crap about FP because you forgot in the meantime, or because you can't find more advanced material?

19:56 Guest47278: justin_smith: more because I can't find the right stage. It either all seems too easy, or just way out of my league and mathematically crazy.

19:58 justin_smith: so maybe you are at the stage where what you want to learn is math?

20:00 Guest47278: justin_smith: well, I can't link any of this mathematical crap to practice, yet. So I wouldn't know where to start, or whether I'd want to

20:01 I think a gulf between basic FP and advanced FP concepts definitely exists and is wide

20:02 justin_smith: I think there is a big gap between knowing how closures and immutible data and tail recursion can be used to structure an app, and actually being able to build something in a mostly-functional programming style. And that is not a question of reading more about fp, or learning more math. It's a question of reading more real working code, and writing apps, and redesigning them. There is no substitute for practice.

20:03 Guest47278: justin_smith: I've totally found that to be the case. I've come to realise that I spent many years living a lie - learning a whole lot about theoreticals, when actually building stuff is king.

20:04 justin_smith: a bit of theory can save you from big mistakes (the kind of mistakes that waste cumulative years of your life) - but the answer to moving forward often isn't more theory

20:11 Guest47278: justin_smith: a lot of theory can also help tremendously with job interviews. I know of people that have talked their way into high positions - but become notorious for being actually incapable, besides good speech - once incumbent..

20:11 Too little, too late, of course!

20:11 raspasov: Guest47278: totally, building stuff == king for me as well; with just enough theory without getting bogged down by it

20:12 yea, practical knowledge != good interview skills :)

20:15 I would even argue that it's even more about how you structure your side-effects, I/O etc operations in your code that ultimately determines the amount of potential bugs your code has, and not strong/weak typing, etc; of course I have zero research to prove that :)

20:16 Guest47278: raspasov: I'd generally agree, although you could say that assertion is vague enough to be a truism

20:17 raspasov: I've seen functional people program in OO languages like Ruby, trying to do it in a functional way, ignoring OO principles. That ends up coming off worse though

20:17 even if, technically, you could say it has less side-effects etc.

20:17 raspasov: :)

20:18 yea, but does one good example make it a truism? aka basic unit tests, or type checking?

20:18 i.e. is the fact that object is of type X, actually make your program correct, is this a "good enough" check? I think it's "basic" check

20:19 basically, there's no substitute for thinking and reasoning about your program

20:19 Guest47278: I feel like there is a gap between static & dynamic analysis that needs bridging

20:19 raspasov: a perfect checker would be an AI :D

20:19 Guest47278: ^

20:19 raspasov: lol

20:20 Guest47278: A more feasible short-term bridge would be something that essentially animates a model of your code, based upon static analysis - allowing the human to dynamically analyse the code

20:20 papachan: seangrove thank you for your help last night, i have finally put in production my code

20:23 raspasov: there's also this testing tool for Clojure if you haven't seen it https://github.com/clojure/test.check; a good video intro to the concept https://www.youtube.com/watch?v=JMhNINPo__g

20:31 seangrove: papachan: Are you sure it was me?

20:32 papachan: seangrove oh sorry tab select you instead of seancorfield

20:33 seancorfield: Too many Seans :)

20:33 seangrove: No worries, wanted to make sure the right Sean got the thanks ;)

20:33 seancorfield: I used to have IRC highlight "sean" but seangrove gets a lot more responses that I do so I took that off :)

20:34 glad you got things working papachan - how much Clojure do you have in production now?

20:36 papachan: seancorfield not so much but my conversion from params to session cookie works finally

20:37 seancorfield: Cool...

20:37 Well, I'm out of here for the day. May pop in later, but I have to be up at 5am to catch my flight to The Strange Loop. Hope to see some of you there?

20:39 seangrove: seancorfield: That's a conference I need to make time to go see next year - hope you enjoy it!

20:40 seancorfield: This will be my third year - it was awesome in 2011 & 2013 (I was in England in 2012, unfortunately).

20:40 And I already have the dates in my calendar for 2015 :)

21:53 andyf: Is there 'standard' terminology to name the relationship between namespaces where one has a name that is an extension of another, e.g. namespace 'foo.bar.baz' is a ___ of namespace 'foo.bar'

21:54 And perhaps a related question, is there such a terminology for Java packages?

21:55 Grazy: Hello all!

21:57 amalloy: andyf: in java i'd call it a subpackage. i don't know what it is in clojure

22:02 justin_smith: and in both java and clojure that concatenative nesting means something to a human reader, but really doesn't affect how the language does things (there aren't different rules for using foo.bar.baz from foo.bar as opposed to using foo.baz)

22:36 TimMc: justin_smith: Java (and probably the JVM) has a notion of "sealed packages", which I assume refers to prefixes -- but I could easily be wrong on this, since I've never cared to look into it.

22:47 justin_smith: TimMc: that may be the case actually - it looks like subpackage inherit certain classloader settings of their parents too

22:47 but in practice, these things don't effect my code much

23:06 Jaood_: mutual recursion apart, are forward declarations used much in the wild?

23:09 justin_smith: Jaood_: I sometimes use them to make reading a namespace top to bottom make more sense

23:14 Jaood_: justin_smith: I see, haven't seen much code do that, I guess its a matter of taste then

23:14 justin_smith: the high-level functions are just mostly at the bottom

23:20 justin_smith: right, it was an aesthetic choice

23:34 Jaood_: b

Logging service provided by n01se.net