#clojure log - May 11 2014

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

2:49 servo: can you perform a function on destructuring? something akin to (let [[(keyword x) (keyword y)] ["foo" "bar"]])

4:16 sveri: Hi, I have trouble with js interop, I am trying to initialize a tokenfield for an input but dont succeed, I always get "object is not a function error" whenever I type in the input field (the autocomplete gets initialized, so the error must be somewhere inside the #js object I guess), this is the js code I want to convert to cljs code: http://pastebin.com/cxd1P8hc

4:19 hiredman: I don't think #js is recursive

4:20 sveri: hiredman: you mean I should try it like this: :autocomplete #js {:source...?

4:22 ah, this seems to be working, at least it tries to connect to the server

4:22 thank you very much

5:19 klokbaske: hi there! trying to build a project with a dependency on a jar. Normally I specify dependencies in my project.clj, but I'm not sure what to do with this one

5:19 How do I find out what to specify in the dependencies list?

5:56 ptcek: klokbaske: you mean you have a jar file that is not in a repository (such as clojars?) if this is the case, add it to your own local repo; this may help: https://github.com/kumarshantanu/lein-localrepo

6:00 martinklepsch: anyone experience with upserting documents into elasticsearch using elastisch by clojurewerkz? I'm uncertain if I should build a bulk upsert query on my own or use the native document/upsert function; more here: https://groups.google.com/forum/#!topic/clojure-elasticsearch/bZ7owwef1fo

6:03 klokbaske: ptcek: I think it's in a repo - at least I found a pom.xml referencing it:

6:03 http://jvstwrapper.cvs.sourceforge.net/jvstwrapper/jvst_examples/dist/pom.xml?view=markup

6:03 but i'll look into your link, thanks :-)

7:26 mi6x3m: Can a lazy seq be built with loop recur?

8:12 yotsov: http://arstechnica.com/science/2014/05/scientific-computings-future-can-any-coding-language-top-a-1950s-behemoth/ this article gives me the impression that a clojure that can interop with fortran (a clojure that compiles to fortran maybe) could have its users

8:13 it seems to be big selling point for julia in academia

8:27 mi6x3m: Hello, I wrote this function as a solution to problem #30 on 4clojure: http://pastebin.com/V4d8nHMT. Can someone provide me some hints if this is a good / idiomatic solution?

8:28 the task as to compress a sequence, i.e. remove consecutive duplicates

8:33 Glenjamin: mi6x3m: seems broadly sensible

8:34 i don' think remove-run needs to be extracted

8:35 mi6x3m: Glenjamin: yeah, I did it just for prototyping

8:35 Glenjamin: and you generally are supposed to use (seq) instead of empty?

8:35 mi6x3m: Glenjamin: ah, why is that?

8:35 Glenjamin: i have no idea tbh

8:35 its just something i see often

8:35 "seq is idiomatic"

8:36 i assume there's a reason

8:36 mi6x3m: yeah I heard it yesterday as well

8:36 but empty? is just "(not (seq coll))"

8:37 Glenjamin: you can collapse your if and let down into and if-let

8:37 ,(if-let [[h & t] (seq [])] :t :f)

8:37 clojurebot: :f

8:37 Glenjamin: ,(if-let [[h & t] (seq [1])] :t :f)

8:37 clojurebot: :t

8:37 mi6x3m: ah, yes, thanks, if-let yeah of course

8:39 wow, Glenjamin, thanks so much

8:39 Glenjamin: ,((fn compress [coll] (if-let [[h & t] (seq coll)] (cons h (lazy-seq (compress (drop-while #(= h %) t)))))) [1 1 2 2 3])

8:39 clojurebot: (1 2 3)

9:29 agarman: anyone use timbre logging library?

9:36 gyim: i do

9:38 agarman: gyim how's it working out? to me, it looks like it involves a lot of logging code added to all the functions

9:39 gyim: what do you mean?

9:39 in our app we have a few custom appenders, but only a few lines long

9:40 agarman: yeah I started writing a kafka appender

9:40 gyim: oh i see... i am simply logging to file / console

9:40 Glenjamin: agarman: are you concerned about littering all your functions with logging code?

9:41 agarman: I kinda want to be able to add profiling to namespaces, without messing with the fns in the namespace, AFAIK timbre requires you to wrap fns with pspy to profile

9:42 Glenjamin: you can do defnp

9:42 agarman: Glenjamin exactly...most of the application is pure, occasionally I want to profile...tools.trace is good in a repl

9:42 Glenjamin: something like this perhaps? https://github.com/MichaelDrogalis/dire#pre-hooks

9:42 agarman: but I want something that works well with logging to a db

9:43 I'd looked at that last week. And surprisingly forgot about it, because Michael & I were talking about a lot of stuff

9:45 agarman_: network fun

9:45 thanks for the reminder of dire...

9:49 shiranaihito: IntelliJ IDEA forgot what Java looks like again.. does anyone remember how to fix this? -i've tried "invalidating caches", and even deleted Library/Caches/<etc> .. but no luck

9:50 justin_smith: forgot what java looks like?

9:50 some kind of cursive bug?

9:51 shiranaihito: it's a bug in IDEA, pops up every now and then.. now i'm switching from Java 7 to 8, and it went wonky again

9:51 now it says "java.lang.String" is an unrecognized symbol or something, paints all std java classes in red.. :P

9:51 justin_smith: woah

9:52 shiranaihito: yeah :P

9:52 this is really annoying

9:52 justin_smith: btw the new syntaxes for first class methods in 8 are cool

9:52 shiranaihito: completely prevents you from doing anything, but pops up so rarely that you don't remember how to fix it :P

9:52 justin_smith: System.out::println

9:52 shiranaihito: yeah, Java 8 is pretty sweet

9:52 justin_smith: first class

9:53 shiranaihito: oh? i didn't remember about that

9:53 the new lambdas are great too

9:53 justin_smith: Sysem.out::println = (s) -> System.out.println(s)

9:54 makes sense, really

9:56 shiranaihito: :P

9:59 justin_smith: shiranaihito: http://stackoverflow.com/a/5905931/2258453 see comment from pastafarian

9:59 shiranaihito: i had overlooked one "project language level" -setting btw .. now it's back to normal :p

9:59 justin_smith: oh, OK

10:00 shiranaihito: thanks for the tip anyway! :)

10:00 justin_smith: I am a total luddite using emacs (learning java 8 as my first java, as a resume / portfolio building thing)

10:01 shiranaihito: :P

10:01 justin_smith: I am excited to try things like Stream.reduce()

10:01 shiranaihito: well, i couldn't live without JetBrain's IDEs myself

10:01 the best tool for the job and all.. :P

10:02 mmm

10:02 justin_smith: right - I just don't think about using another env

10:02 shiranaihito: well, at least Java jobs are plentiful

10:02 and Java 8 is a really great update.. makes the language much more palatable for snobs too :P

10:02 justin_smith: right, that's the idea - my clojure job layed me off and hired a java guy :/

10:03 shiranaihito: wow :/ .. how did that happen?

10:03 did they decide to ditch clojure?

10:03 justin_smith: we moved up to bigger clients, and with that success they get more clients that dictate backend

10:03 or have existing codebases

10:03 etc.

10:03 shiranaihito: ah

10:03 yeah, well.. even Python jobs are really rare

10:04 justin_smith: and everyone's like "your setup looks nice, but I wouldn't be able to find clojure devs ten years from now"

10:04 shiranaihito: i've got a Java background, actually, but learned to be comfortable with Python too.. now i'm getting used to Clojure

10:04 Clojure might be everywhere in ten years though :P

10:05 justin_smith: as a self-educated coder, I am coming into this all backward, scheme/ocaml/lisp to clojure to java...

10:05 shiranaihito: :P

10:05 justin_smith: shiranaihito: well, if it was me talking to the clients I would try to tell them that

10:05 shiranaihito: that's certainly an unusual progression :P

10:05 well, it's understandable they feel that way _now_.. but they sure as hell don't know anything about what the world will be like in 10 years

10:06 (no one does)

10:06 but yeah.. it's just business

10:06 nothing personal

10:06 justin_smith: shiranaihito: that they will find java devs in 10 years, given the pace of acedemia and the current cs curriculum, is a safe bet

10:06 shiranaihito: the people giving up their money for a company's services kind of dictate what the company does :p

10:07 justin_smith: shiranaihito: right, it was a layoff, not a firing, I'm collecting unemployment for a minute and building my resume

10:07 shiranaihito: yeah

10:07 justin_smith: exactly

10:07 shiranaihito: start your own business btw, it's the best thing you can do for your financial independence/well-being

10:07 justin_smith: I'll consider it

10:07 teslanick: and for some people, the worst thing you can do for your sanity. :)

10:07 shiranaihito: it's really difficult, of course, but everything worth doing is.. :P

10:08 teslanick: :P

10:08 freelancing/contracting is a step in the right direction

10:08 justin_smith: shiranaihito: you use the :P emoticon so much, I am picturing you as a pug that learned to type

10:08 Glenjamin: most decent jobs i see these days are "perm only"

10:08 shiranaihito: do pugs tend to be particularly smiley? :P

10:09 teslanick: Or: http://imgur.com/BCxVZ2p

10:09 Glenjamin: no-one around here wants to hire contractors for interesting stuff

10:09 justin_smith: shiranaihito: their tongues are always hanging out

10:09 shiranaihito: Glenjamin: yeah, lots of companies want "commitment".. but you may be able to negotiate a contract position anyway - you can agree to a long contract too, etc

10:10 Glenjamin: yeah, its odd that "salaray" is equated with "commitment"

10:10 shiranaihito: Glenjamin: well, they're just thinking about an employee as a "long-term investmen" kind of deal

10:10 Glenjamin: right, they think the relationship is asymmetrical

10:11 they believe that I owe them something beyond the work i produce for the salary i'd get

10:11 shiranaihito: an employee willl take some time to become productive, to get used to how the business operates, to become knowledgeable in their systems and products etc

10:11 Glenjamin: whereas in practice i find that we're at least even

10:11 shiranaihito: from a business perspective, it's a "loss" to have to start over with a new guy

10:11 mmm

10:11 Glenjamin: unless that guy is sufficiently experienced to hit the ground running, and improve their systems for the better

10:12 shiranaihito: i don't think they feel "entitled" to anything from you outside of your work arrangement

10:12 Glenjamin: every job i've left, i left them in better shape than when i started

10:12 shiranaihito: .. if they do, they've got issues

10:12 Glenjamin: not purely through my own work, but i certainly contributed

10:12 shiranaihito: but what i just explained is certainly a factor

10:13 Glenjamin: that "long term investment" thinking is an entitlement though

10:13 shiranaihito: it's just a business consideration - switching employees incurs costs to them

10:13 Glenjamin: yes, but when you hire a permanent employee, you give them ~3 months notice

10:13 you don't own them forever

10:13 shiranaihito: nope, it's just a business consideration :P .. we might not like it, but it's just them pursuing their personal gain, just like we all pursue ours

10:13 Glenjamin: oh, certainly

10:14 shiranaihito: "own them forever"?

10:15 Glenjamin: basically, there's no rule that says contractors switch more

10:15 shiranaihito: ofc not, but they feel like a salaried employee is a "safer bet"

10:15 and/or they just don't think things through, etc

10:15 Glenjamin: yeah - thats the bit i'm disappointed in

10:15 shiranaihito: yep, but that's something you can work around by negotiating etc

10:15 teslanick: Well, most employees aren't maintaining a client list or a pipeline.

10:16 Glenjamin: most decent employees could find another tech job in < 1 month in the current climate

10:16 shiranaihito: yeah

10:16 Glenjamin: especially if they're willing to move

10:16 shiranaihito: you in the US?

10:16 teslanick: It's true

10:16 Glenjamin: i'm in the UK

10:16 shiranaihito: ok, Finland here

10:17 teslanick: (US here)

10:17 shiranaihito: k

10:17 we're kind of fortunate to be developers anyway

10:18 but people don't exactly appreciate things they take for granted :P

10:18 (myself included!)

10:18 anyway, freelancing --> business is the way to go :P

10:19 or just straight to starting a business :P

10:19 freelancing/contracting gives you a pretty sweet pay raise too

10:20 Glenjamin: if i had an idea, i'd be all over a business

10:20 teslanick: In the US, most of that raise gets plowed into buying health insurance.

10:20 shiranaihito: in finland, contracting gets you roughly double what you'd get as your gross salary

10:21 Glenjamin: same here.. :P i'm back to square one, and somewhat paralyzed by the fear of implementing "a solution in search of a problem"

10:21 teslanick: yeah, obamacare is immensely destructive

10:22 teslanick: That's not really fair: health insurance is expensive in the U.S., especially if you want it to actually cover anything.

10:22 shiranaihito: teslanick: what kind of "insurance" is something that you're basically forced to buy? :P

10:22 teslanick: The ACA just makes it mandatory to buy that expensive insurance. (lame)

10:22 shiranaihito: what do you think it does to prices when you're forced to buy something?

10:23 yep

10:23 "mandatory" being the operative word there

10:23 teslanick: At this point, nobody knows what's going to happen. The market here is so dysfunctional

10:23 shiranaihito: imagine the government forcing you to buy McDonald's burgers :P

10:23 seem familiar somehow? :P

10:24 yep

10:25 teslanick: Everyone can have an opinion about it and they're all equally valid, because the legislation is thousands of pages long and nobody knows which parts are actually practical or not.

10:25 shiranaihito: what would happen to the price of a Big Mac if everyone was forced to buy them?

10:26 yeah well, the legislation is an incomprehensible mess, but that's not exactly an accident

10:26 Glenjamin: my understanding was that it's more akin to forcing everyone to buy a burger

10:26 but the individual is free to choose which one

10:26 shiranaihito: :P

10:27 Glenjamin: anyway, we have nationalised healthcare here paid for by taxes, a system i much prefer

10:27 shiranaihito: ok, imagine there are five massive burger chains, and everyone is forced to keep buying burgers from one of them.. what happens to the prices?

10:27 (the forced "customers" are spread roughly evenly among the five chains ofc)

10:28 Glenjamin: if "one of them" means "any one of them", prices would go down

10:28 shiranaihito: Glenjamin: yeah, and there you're forced to "buy" NHS' services :p

10:29 Glenjamin: both the price and service levels are regulated, meaning: if i get hit by a bus, they'll fix me up

10:29 anyway, this is very OT for a clojure room :)

10:29 nathan7: go compute why the world sucks, y'all

10:31 shiranaihito: well, the point was that if you're forced to pay for something, you're not a customer in any real sense of the word -- being a customer implies choosing something and voluntarily paying for it

10:31 and if you're forced to buy X, then its producer has no incentive to maintain/improve quality, or to lower costs

10:32 (and this applies to all public services btw :p)

10:34 teslanick: Although evidence suggests that "open" markets for purchasing health care and insurance raises real costs faster than government-provided health care.

10:35 Glenjamin: also, if you have no money, you die - which is what public services guard against

10:35 teslanick: The United States spends 17% of GDP on health care, vs. 10% in Canada and the UK. Both countries have better health care outcomes in the general case.

10:46 shiranaihito: McDonald's forcing you to buy its burgers would be outrageous and clearly immoral, but the government forcing you to pay for health care, insurance, or aircraft carriers and military bases all over the world is.. perfectly fine? :p

10:52 teslanick: Depends on your moral priors, like anything.

10:53 justin_smith: shiranaihito: not to mention police, and roads, and the internet

10:54 shiranaihito: well, coercion is immoral regardless of what supposedly good "outcome" someone thinks he'll achieve by doing it.. for example, i'm not allowed to force you to eat carrots even if they're good for you

10:56 justin_smith: allowed by whom? we coerce for the public good all the time, and every human society in the history of ever has as well

10:57 for example we coerce people not to claim goods that are already previously claimed, AKA property law

10:58 shiranaihito: that's true, but we all know that coercion is immoral on an individual level

10:58 well, you can't defend your property before someone tries to take it :)

12:00 whilo: is it necessary that one cannot use <! in for-comprehensions (inside a go-block)?

12:06 Glenjamin: whilo: i suspect it's because for is lazy

12:06 try doseq instead

12:06 whilo: Glenjamin: yes, well i need all results. i also tried to put it into doall

12:07 Glenjamin: ,(doc doseq)

12:07 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

12:08 whilo: yes, but i need the return value, i have used doseq before

12:08 it just turned out i need some boilerplate wrapping, first returning channels in the for-comprehension and then using async/merge, async/into etc

12:09 Glenjamin: oh, sorry - for some reason i thought doseq returned the result

12:10 whilo: since the for comprehension is actually compiled by the go-macro (contrary to closures), i thought it could be transformed into synchronous code

12:10 was just wondering, if it was possible

12:11 Glenjamin: i would have assumed that was possible

12:11 coventry: whilo: Can you give an example of a for comprehension which doesn't work, or a citation for it? Hadn't heard of that limitation.

12:14 whilo: coventry: (go (println (for [i [1 2 3]] (<! (go i)))))

12:17 ,(go (println (for [i [1 2 3]] (<! (go i)))))

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

12:18 coventry: whilo: Interesting. Thanks.

12:32 (def d (go (for [i [1 2 3]] (println (<! c))))) ; <- Fails with "<! used not in (go ...) block" if you (take! d println)

12:35 It looks like the go macro doesn't walk into for loops. I wonder why.

12:35 seangrove: Laziness/

12:35 ?

12:41 coventry: Maybe because for wraps its body in a fn.

12:41 Anderkent: hm, is anyone else having issues with loading core.async using lein try?

12:42 coventry: whilo, seangrove: Yeah, I think that's why. (def d (go (for [i [1 2 3]] (go (println (<! c)))))) kind of works.

12:46 Bronsa: coventry: I think it's becasue the body is wrapped in a fn, yes

12:46 whilo: seangrove: right, but i was wondering whether the laziness could be transparent in this case, so the go macro can transform its body into a state-machine (which is lazy)

12:46 ok, makes sense

12:47 seangrove: whilo: Yeah, part of the drawback to having it as a library and not a core language (or runtime?) feature, I think

12:49 whilo: yes. wrapping in async/boilerplate is verbose, yet still readable with the threading macros. i was just wondering whether in this case it could resolve the for-comprehension, because it knows all the code (while closures in general can be compiled outside of the go macro)

12:49 Anderkent: with core.async, is there a way of synchronously getting a value from a channel if available, or returning nil immediately if not?

12:51 hm nevermind maybe i don't need that after all

12:54 coventry: Is there anything in the for macro which stops it from being expressed as a set of loop/recurs?

12:56 Oh, maybe the lazy-seq? In which case maybe laziness is the blocker, in a way.

13:00 whilo: To make that work, the go macro would have to be able to tell when a for loop is being passed out as a value, and somehow re-institute standard laziness in that case.

13:00 whilo: yes, i picture it is not trivial

13:00 probably a for< or sth. would make sense

13:01 in the core.async api

13:02 or just for, because you wouldn't pass in a channel per se

13:26 seangrove: bbloom: How would you express the requirements for 2 and 3 here? https://dl.dropboxusercontent.com/u/412963/screenshots/layout_strategies.jpg

13:26 I'm wondering if I need to introduce ideas like {:strategy :expand :width 230 :height :remaining}, etc.

13:27 Or {:strategy :fixed :width 230 :height (fn [state] (- (:window-height state) 50)) }

13:32 Anderkent: ugh, core.async channels aren't IObjs? :/

13:37 amalloy: Anderkent: i'm not sure how you would make use of IObj. if you (with-meta some-channel m), does the resulting channel read-through or write-through from the original channel? neither? both? do they somehow share messages, or does the new one steal all the messages?

13:37 Anderkent: well, is that any different than just having two references to the same channel?

13:38 amalloy: well yeah. two references to the same channel are identical?

13:39 Anderkent: hm, why is that important?

13:40 I don't see the difference bwteen two reads from 'identical?' chans, and two reads from '=' chans

13:42 oh, I see your point, I was thinking in terms of the interface, you were talking about the implementation

13:47 mi6x3m: Is there a function to remove a prefix from a sequence

13:47 if I know some sequence is a prefix of another?

13:48 opqdonut: well you can always do (take (count prefix) the-sequence)

13:48 err sorry

13:48 mi6x3m: drop

13:48 yes

13:48 opqdonut: s/take/drop/

13:48 but I haven't really seen anything that would remove a prefix using equality checking

13:49 (of course it's pretty straightforward to implement)

13:51 amalloy: mi6x3m: i think https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L244 is that function

13:52 mi6x3m: amalloy: right, this one yes :)

14:12 whilo: seangrove: is this an application you build?

14:14 seangrove: whilo: ?

14:14 whilo: seangrove: the screenshot you linked

14:15 seangrove: whilo: Oh, sorry. It's kandan/Omchaya/my goto app to rebuild when testing out ideas

14:24 visof: ,(str "http:\/\/hello.com")

14:24 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \/>

14:25 visof: if i have string like this, how can i remove \ from it?

14:28 mi6x3m: clojure how do you get an empty sequence?

14:28 technomancy: ,(doc empty)

14:28 clojurebot: "([coll]); Returns an empty collection of the same category as coll, or nil"

14:29 mi6x3m: visof: with filter?

14:29 amalloy: mi6x3m: () is empty. do you want something else?

14:29 dnolen_: ,(.replace "http:\/\/hello.com" "\" "")

14:29 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \/>

14:30 mi6x3m: amalloy: well, yeah, I was just confused with myself

14:30 Glenjamin: ,(.replace "http:\\/\\/hello.com" "\\" "")

14:30 clojurebot: "http://hello.com"

14:30 dnolen_: visof: ^

14:31 Glenjamin: is there a heredoc/raw-string type thing in clojure?

14:31 dnolen_: Glenjamin: there is not

14:31 amalloy: guys, "http:\/\/hello.com" is not even a legal string. shouldn't we figure out what his actual input is before trying to turn it into his desired output?

14:31 visof: ,(.replace "http:\/\/hello.com" "\\" "")

14:31 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \/>

14:32 Glenjamin: visof: where are you getting the string from?

14:32 mi6x3m: amalloy: so if I want to make a function which returns an empty sequence for an incoming nil argument I can just return '() ?

14:32 and this would be idiomatic

14:33 for you see, I want to always return a sequence, but it will sometimes be empty

14:33 amalloy: mi6x3m: i wouldn't worry about it. returning nil would be fine in almost all circumstances, or if you're returning a lazy seq it will naturally be empty

14:34 mi6x3m: amalloy: let me show you what I work on

14:34 and explain the scenario

14:38 whilo: seangrove: do you rebuild it in clojurescript? for fun? i happen to build a prototype messaging app as well in cljs

14:38 mi6x3m: amalloy: so I wrote this http://pastebin.com/BcKqfQGm as a solution to https://www.4clojure.com/problem/32

14:38 seangrove: whilo: Yeah, I've rebuilt it a few times in cljs now :)

14:38 mi6x3m: i wanted an efficient solution so I use lazy sequences

14:38 whilo: seangrove: is it mobile-friendly? could you use it for messaging on a phone?

14:38 mi6x3m: I used your suggestion and wrapped everything in lazy-seq

14:39 seangrove: whilo: Yeah, it's mobile-responsive

14:39 whilo: ok

14:39 seangrove: There's no backend for it right now, it's just a frontend

14:39 whilo: is your version open-source?

14:39 oh, ok. yes i build it for my backend

14:39 or better we build it for it

14:39 Glenjamin: seangrove: personally, i prefered the keyword version

14:39 felt a bit more declarative

14:39 whilo: ranek: as well

14:40 seangrove: Glenjamin: keyword version?

14:40 Glenjamin: :remaining vs (fn)

14:41 seangrove: Glenjamin: Ah, ok. It's tricky, I don't want to accidentally walk into making a half-baked syntax

14:42 Glenjamin: hrm, i see what you mean - i guess functions to begin with and common patterns could always become keywords later

14:43 seangrove: Glenjamin: That's what I'm thinking as well

14:44 whilo: seangrove: got it: https://github.com/sgrove/omchaya

14:45 ImperialCity_G: is there a irc channel for seesaw library?

14:51 whilo: seangrove: looks cool, will have a look at it. is it very coupled to the original rails backend?

14:54 seangrove: whilo: Yeah, it has no concept of the rails part other than the single API namespace

14:54 whilo: ok, good

14:54 phuu: hey #clojure. i want to represent a tree where every node has a value. i'm using lists at the moment, where the first element is the value — '(0 (1) (2 (3 (4)))) — but navigating with zippers seems weird because you have to skip the first child every time. what am I missing? is there an idiomatic way?

14:57 seangrove: phuu: Use hashmaps to represent the tree?

14:57 {:value X :children [{:value Y :children []}]}

14:58 phuu: https://www.youtube.com/watch?v=YgvJqWiyMRY Dendrology

14:58 dbasch: phuu: and look at tree-seq

14:58 ,(doc tree-seq)

14:58 clojurebot: "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."

14:59 phuu: seangrove: will check out that talk, thanks. i believe I need to use zipper because i'm need to keep a reference into the tree, and to make changes to it – is there another way where I could use a map?

15:07 seangrove: phuu: Sorry, I haven't used Zippers in awhile, I know that the api isn't immediately straightforward though, so I feel for you

15:08 amalloy: i think you can use maps with value/children nodes as seangrove suggests, and build a zipper that knows about that structure

15:09 mi6x3m: what the hell is going on here:

15:09 ,(= ((fn [coll n] (apply interleave (take n (repeat coll)))) [4 5 6] 1) '(4 5 6))

15:09 clojurebot: true

15:09 phuu: seangrove amalloy: ah, ok. i'm really just interested in if there's a canonical way to store & manipulate a tree where every node has a value. i'm considering adding metadata to the node to store the value and using seq-zip

15:09 mi6x3m: this doesn't work on 1.4

15:09 amalloy: phuu: that sounds like the grossest thing imaginable. use maps

15:10 seangrove: phuu: Metadata is pretty cool, but you'll have less pain in the long-run if you use maps

15:10 phuu: amalloy is specifically concerned about people getting killed over the metadata on any given node, hence his aversion.

15:11 amalloy: is metadata like blood diamonds? i'm not sure i understand the concern you're alleging i have

15:12 seangrove: amalloy: Well, we kill people over metadata.

15:12 phuu: hah, ok! i can imagine grosser things ;) but yeah, ok. i'll try building a {:value x :left y :right z} zipper

15:12 amalloy: phuu: it'll be easier to support a list of children rather than just left/right

15:12 but if you want to limit to exactly two it's not completely wrong to use left/right

15:12 phuu: amalloy: yeah, i thought so, but I want to enforce 2

15:12 yeah exactly

15:14 (-> tree :left :right :left}

15:17 coventry: I need a clojure.walk/prewalk which won't blow the stack on very deep trees. Is there such a thing already?

15:28 visof: ,(.replace "http:\\/\\/hello.com" "\\" "")

15:28 clojurebot: "http://hello.com"

15:31 phuu: seangrove: thanks for pointing me to this talk, it's brilliant

15:32 seangrove: phuu: I agree it's good - it's bbloom's talk

15:32 Jaood: link?

15:33 oh sqw it

15:33 saw

15:34 lxsameer: hey guys, how can i install clojure using lein

15:45 rpaulo: lxsameer: lein includes clojure already. you can start the clojure repl with lein repl. is this what you wanted?

15:45 dissipate: is core.contracts abandonware? hasn't been updated in 10 months: https://github.com/clojure/core.contracts

15:46 ImperialCity_G: lxsameer: with lein just create a project with 'lein new' ... when you are ready to run the project type 'lein run' and the first time it will download clojure before running it

15:47 lxsameer: ImperialCity_G: rpaulo thanks, I'm a totally newbie

15:47 dissipate: ImperialCity_G, but in order to do 'lein run' your project has to have a '-main', no?

15:48 ImperialCity_G: dissipate: doesnt lein new do that for you already

15:48 it gives you core.clj with a -main in it

15:48 dissipate: ImperialCity_G, i don't think it did for my project. maybe i'm mistaken.

15:48 rpaulo: lein new might not create a main

15:48 ImperialCity_G: dissipate: maybe it was a recent addition

15:50 i just typed 'lein new app test', 'cd test', 'lein run' and i got a hello world

15:50 im using lein version 2.1.3

15:58 Glenjamin: is there a (not) version of == ?

15:58 i've got (if-not (and (== a b) (== c d)) and it seems a bit convoluted

15:58 coventry: (doc not=)

15:58 clojurebot: "([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"

15:59 coventry: Oh, ==. Sorry, don't know.

16:00 Glenjamin: on an unscientific test, that doesn't appear to be any slower

16:00 so not= it is, cheers

16:01 i wonder why it wasn't called !=

16:08 ,(persistent! {})

16:08 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.ITransientCollection>

16:08 Glenjamin: hrm, i get a missing stack trace doing that in my repl :s

16:09 coventry: ,(persistent! (transient {}))

16:09 clojurebot: {}

16:09 Glenjamin: oh, i know it's wrong

16:10 but it took me ages to find the bug because the stack trace was missing

16:10 expez: https://www.refheap.com/85346 <- most of this code is lifted from http://swannodette.github.io/2013/11/07/clojurescript-101/, what's wrong here?

16:10 amalloy: Glenjamin: it's pretty unusual to have a use case for == where = isn't just as good

16:11 Glenjamin: the fact that == was just for numerics led me to an incorrect assumption about perf

16:11 clearly i need to measure more :)

16:11 seangrove: ,(source =)

16:11 clojurebot: Source not found\n

16:12 amalloy: expez: you're calling (<! x), where x is not a channel but a lazy sequence

16:12 in this case, it's clear that that's on line 16

16:13 expez: amalloy: thanks, that makes sense

16:15 coventry: expez: You might want to use (alts!)

16:24 seangrove: Datascript is *slow*. Wonderful to play with, but GC activity goes through the roof querying against ~1000 facts

16:28 Glenjamin: do you think that's a fundamental property of it, or just because it's new and hasn't been heavily optimised yet?

20:34 seangrove: Glenjamin: Bit of both. Reducers are going to be critical for it

22:47 lordB8r: on http://clojure.org/, url for the clr is out of date. Anyway to update it for https://github.com/clojure/clojure-clr?

22:48 or is intentionally pointing to that git?

Logging service provided by n01se.net