#clojure log - Jan 27 2014

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

0:19 devn: yay for JoC 2ED

0:19 I've been enjoying the read. Fantastic teaching moment with reducible/reducers

0:19 rgrinberg: is there a clojurescript instarepl in lighttable?

0:20 kinda like the scratch buffer in emacs

0:27 tutysara: ddellacosta: how does the changes look, are they fine?

0:28 ddellacosta: tutysara: sorry, I haven't had time to take a look. As I said, I'll take a look ASAP.

0:29 tutysara: ddellacosta: sure :)

0:37 ddellacosta: tutysara: please be aware, it may take more time than I have in the next few days. I have to try setting up a few things and see what structure makes more sense in terms of multi-config in one workflow vs. multi-workflows. So please be patient and bear with me as I have a lot of priorities ahead of updating friend-oauth2, unfortunately.

0:40 tutysara: ddellacosta: okie, np, keep me updated, I am available for discussions around this time daily if we have to discuss something

0:40 ddellacosta: tutysara: thanks--good to know.

0:42 dissipate: ddellacosta, are you guys discussing contract work?

0:43 quizdr: I like to provide to everyone best wishes for the remainig days of the Snake. May your start of the year of the Horse be a good one, filled with many fine sexprs.

0:43 ddellacosta: dissipate: no, tutysara has been contributing a bunch to friend-oauth2, and we were just talking about the most recent changes (and my unfortunate lack of time to review them this week)

0:45 dissipate: ddellacosta, i see. i'm going to be looking for clojure projects to contribute to over the next couple of months. any good ones you recommend?

0:45 ddellacosta: dissipate: depends, anything you're interested in in particular?

0:47 dissipate: ddellacosta, i'm interested in rule engines with business applications. for instance, a business that runs promotions might have all kinds of rules. ideally, they would be able to select these easily from a UI.

0:49 ddellacosta: dissipate: not super familiar with what is available in Clojure for those kinds of systems, but have you checked out Clara? https://github.com/rbrush/clara-rules

0:49 dissipate: seems like there are a number of open issues

0:50 dissipate: based on your interest, perhaps a UI front-end for Clara would be an interesting project as well?

0:50 dissipate: ddellacosta, i have. seems interesting.

0:50 ddellacosta: dissipate: ah, sorry I don't have knowledge of other related projects out there...

0:52 dissipate: my knowledge of Clojure tends to be in the web domain, and I know there are a ton of projects all over the place that could be improved. But I find that it is best to try building something yourself and then figure out the parts you want improved based on your own usage. Or rather, that works best for me.

0:53 dissipate: ddellacosta, no worries. seems like Clara is enough for me to get going. i'm not a UI guy really, but i did help build a rather complex UI about a year ago for a web-based electrical engineering tool.

0:53 ddellacosta: dissipate: yeah, I was just throwing that out there...but I bet there's a ton of different directions you could go with it.

0:55 dissipate: ddellacosta, indeed. i'm actually new to Clojure. been interested in it for quite awhile, but haven't had time to really sit down and learn it. :P

0:56 ddellacosta: dissipate: there's no time like the present. :-)

0:56 dissipate: seriously though, I think it will be worth your while if you are interested in functional languages. Clojure has a lot of nice qualities.

0:59 dissipate: ddellacosta, all the videos i've watched about Clojure by Hickey etc. have me convinced Clojure is definitely in the right direction from where software development is now with the imperative languages.

0:59 ddellacosta: dissipate: I definitely feel similarly, and think that is what draws a lot of folks to Clojure.

1:00 dissipate: the community is pretty nice too. Lots of friendly and smart folks.

1:01 dissipate: ddellacosta, indeed. now how do i get the company i'm working for to switch to a Clojure based stack? :P

1:02 ddellacosta: dissipate: ha, I dunno...I solved that by trying to find a company that used Clojure. ;-)

1:03 dissipate: only works if you are ready to look for a new position, as I was at the time.

1:06 dissipate: ddellacosta, i am very interested in working for Cognitect actually

1:07 ddellacosta, i'm kind of confused as to what the relationship between relevance and cognitect though.

1:07 er, what the relationship is

1:07 ddellacosta: dissipate: well, seems like they may be looking. :-) http://www.cognitect.com/jobs

1:07 dissipate: relevance merged with the datomic/clojure core team to become cognitect, as I understand it.

1:08 dissipate: ah, they explain better here: http://cognitect.com/hello

1:10 dissipate: ddellacosta, do you work for congitect?

1:10 er, cognitect

1:10 ddellacosta: dissipate: nope, I work for a Canadian startup

1:10 dissipate: but I work remotely.

1:12 dissipate: ddellacosta, i'm jut wondering what it takes to get a contract type job at a clojure shop. how long had you been doing clojure before you got hired there?

1:14 ddellacosta: dissipate: well, these guys needed a web developer and posted something on the Clojure mailing list. I had been doing web dev for a while (Rails and etc.) and had been using Clojure on the side as a hobby for about ~3 months. We did a test project to see if there was a fit and it worked out.

1:16 logic_prog: in clojure, is there any good "sliding list", i.e. I want "cons" to create lists that have at most 100 elements

1:16 dissipate: ddellacosta, do you have any idea what kinds of projects cognitect does?

1:16 logic_prog: i.e. it bumps/drops eisting items

1:17 ddellacosta: dissipate: I don't, I'm sorry

1:17 dissipate: logic_prog, are you talking about a ring buffer?

1:21 logic_prog, this looks like what you are looking for: https://github.com/amalloy/ring-buffer

1:24 logic_prog: (inc dissipate)

1:24 lazybot: ⇒ 1

1:26 dissipate: ddellacosta, are you doing full-stack web dev or do you specialize in front-end or back-end?

1:27 ddellacosta: dissipate: full-stack web dev, but lately doing a lot of front-end work as we've moved from more back-end rendering heavy to front-end rendering

1:28 dissipate: ddellacosta, i see. i'm much more interested in back-end development myself.

1:29 logic_prog, thanks for the inc. :D

1:30 ddellacosta, i'm very keen on uncle bob's Clean Architecture.

1:30 ddellacosta: dissipate: http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html ?

1:31 dissipate: ddellacosta, i'm curious as to how far you can push this idea of completely abstracting the persistence layer though.

1:31 ddellacosta: dissipate: I definitely agree with it in theory, but I've had trouble reconciling the database parts of it with my own experience lately

1:31 dissipate: I think it works rather poorly actually (abstracting the persistence layer)

1:31 dissipate: whatever you end up with seems like a terribly leaky abstraction.

1:32 dissipate: ddellacosta, i've seen that and i've watched UB's talks and kept an eye on the 'clean code' discussion board

1:32 ddellacosta: dissipate: and I think he's glossing over a lot when he equates something like mongo with oracle, in terms of swapping things out

1:33 dissipate: ddellacosta, but it's strange. UB hasn't pointed to a significant implementation of Clean Architecture. only thing he has pointed to of substance is 'Obvious Architecture', which is just an clean architecture based Ruby framework.

1:34 ddellacosta: dissipate: yeah...I think it's a pretty challenging thing to put into practice.

1:34 dissipate: and i haven't seen any significant 'Obvious Architecture' implementations. it all seems too good to be true for non-trivial implementations.

1:34 ddellacosta: dissipate: it may just be. ;-)

1:34 dissipate: ddellacosta, so is 'clean architecture' just a marketing scheme? :O

1:35 ddellacosta: dissipate: no, I suspect it is a glorious platonic ideal of the sort that software developers love, no?

1:35 dissipate: I suppose it's marketing in some sense, for Uncle Bob

1:36 dissipate: don't get me wrong, I always like thinking about what Uncle Bob has to say, he is provocative. But there are many cases where I don't agree (and many I do)

1:37 quizdr: ddellacosta you guys are moving to front-end processing to save on server resources and demand?

1:38 ddellacosta: quizdr: no, I think that it's much more about providing a high quality user experience.

1:38 dissipate: ddellacosta, he says that web frameworks, calls to external services, persistence are all just 'details' and should be rapidly interchangeable. and yet, i see little of this going on in real applications. indeed it seems platonic.

1:38 ddellacosta: dissipate: yeah. :-(

1:39 quizdr: ddellacosta if a lot of your proprietary logic is in clojurescript, which is seen in the browser as javascript, then I'd think it would technically be visible to all visitors, right? hard to keep source proprietary when a lot depends on front-end processing?

1:40 dissipate: quizdr, it is probably obfuscated

1:40 ddellacosta: quizdr: I suppose so...what's your point? (yes, we compiled to advanced mode, it's not exactly easy to read, dunno about de-compiling it though...)

1:42 cark: i would hate being the on decompiling a google closure compiler output

1:42 the one*

1:43 dsrx: my thing.... it's half working http://www.youtube.com/watch?v=fLmq_S5cWsg

1:45 quizdr: ddellacosta i'm just curious how companies handle keeping their stuff closed when it's all running in a browser

1:45 akhudek: quizdr: we have our critical services behind the server

1:46 quizdr: plus, the ui code is pretty useless without the backend services and data

1:47 ddellacosta: quizdr: (I work for akhudek) ;-)

1:48 quizdr: got it, i've never looked at clojurescript at all but am quite curious about it.

1:48 dissipate: ddellacosta, are you guys doing dating apps?

1:49 ddellacosta: dissipate: no. I think seancorfield is working for a company that does that kind of stuff though.

1:50 dissipate: ddellacosta, i'm really getting the itch to do some stuff with docker. not sure what though.

2:46 logic_prog: what does #inst mean ?

2:46 in the context of (pr-str ... )

2:50 cark: i think it's a reader macro for inlining an instant in time as a string

4:19 dsrx: ,(pr-str #inst)

4:19 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

4:19 dsrx: ,(pr-str #inst "foo")

4:19 clojurebot: #<RuntimeException java.lang.RuntimeException: Unrecognized date/time syntax: foo>

4:20 clgv: didn't zach tellman announce a library implementing a map-like data structure which is more space efficient than clojure's maps but has no structural sharing?

4:28 AeroNotix: clgv: was it still persistent?

4:29 clgv: AeroNotix: afair yes, copy-on-modification

4:29 but maybe it was'nt maps but his tuple-library

4:33 AeroNotix: oh there was a tuple library recently

4:35 clgv: I currently represent datasets for analysis as normal maps. but that way they consume unnecessary memory since I hardly manipulate them

4:36 AeroNotix: You're just making a time/efficiency tradeoff, your time is worth more than your programs {in}efficiency, it seems.

4:43 sobel: processing only needs to run as fast as i/o

4:43 unless you just like wait states

4:43 (i'm a huge fan!)

5:17 noncom: hi, what is the recommended way to approach parsing an xml stream incoming through udp/tcp ?

5:18 my initial guess would be aleph + lamina + clojure.xml , is it a fine approach?

5:20 clgv: AeroNotix: no, it's a fits in my RAM or not tradeoff ;)

5:21 sobel: clgv: working with a SQL store?

5:21 clgv: sobel: no. no time yet. I tried datomic a while ago, but I shouldnt have

5:22 AeroNotix: Not tried datomic yet

5:23 sobel: heh. i was more responding to your data not fitting in RAM. postgresql (and probably oracle and sql server) has a pretty mature i/o system. i do any big analysis in sql because it would take me years to ever write code that could do better

5:27 datomic looks complex. what is that thing?

5:29 sm0ke: datalog

5:29 sobel: so far i'm getting a strong whiff of jboss-style enterprise transactions

5:29 sm0ke: i guess

5:29 not for the ^

5:29 sobel: datalog is not datomic

5:29 that i can tell

5:30 sm0ke: yes its not datalog, its a immutable fact based datastore

5:30 sobel: so i read

5:30 sm0ke: but the query language is based on datalog

5:30 tim_: hi, very new to clojure. From what i can tell the 'let' keyword defines a local variable why not use a 'def' statement?

5:30 AeroNotix: tim_: because that'd be global, mmmkay

5:31 tim_: try it

5:31 sobel: tim_: you need to learn the difference between binding and defining. let binds, def defines.

5:31 tim_: all variables defined using 'def' are global and accessible to all functions?

5:31 AeroNotix: tim_: try it

5:32 sobel: tim_: i recommend looking at the doc on 'let' at http://clojure.org/special_forms

5:32 AeroNotix: tim_: https://gist.github.com/AeroNotix/532e67f7175bbe3e466c

5:32 sobel: tim_: the special forms are fairly critical to learning clojure. i'm starting there, also new to clojure as of this weekend

5:35 tim_: Thanks, just tried it in my noddy web app. I see what you mean.

5:40 sobel: so... do clojurists use jackson to render json for the web? does it correctly render sexps?

5:41 that's a bit ahead of where i am now but i don't really do html delivery from the server anymore.

5:41 (yeah, i thought client-server should have beaten the web but i was shouted down by the whole internet)

5:42 SoA is a dish best served cold

5:48 noncom: sobel: i use the cheshire library.. i think it can be based on jackson yeah..

5:55 Ember-: cheshire is based on jackson

6:08 andrevdm: Perhaps I misunderstaning terminoligy but the docs for case say "The test-constants are not evaluated. They must be compile-time literals" and yet this "(let [a :x] (case a :z 1 :x 2))" evals to 2

6:08 i.e. a in my example is evaluated to :x

6:08 This is exactly what I want to happen, I'm just not sure if I can rely on it given the docs

6:08 any ideas?

6:10 clgv: sobel: yeah, that was my short way to say that I wasted my time for that scenario differently, otherwise I'd have some SQL DB running therefore

6:10 opqdonut: andrevdm: the doc means that the _tests_ (i.e. :z and :x) have to be literals

6:11 the value you test can obviously be a nonliteral, otherwise case would be pretty useless

6:11 ,(let [a :x] (case :x :z 1 a 2))

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

6:11 opqdonut: oops

6:11 ,(let [a :x] (case :x :z 1 a 2))

6:11 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: :x>

6:12 clgv: opqdonut: ,(let [a :x] (case a :z 1 :x 2))

6:12 opqdonut: ##(let [a :x] (case a :z 1 :x 2))

6:12 lazybot: ⇒ 2

6:13 clgv: the matching values need to be literals

6:13 ,(let [a :x] (case :x :z 1 a 2 :default))

6:13 clojurebot: :default

6:13 andrevdm: oh right, thanks. yip I was being daft. Thanks!

6:13 I dont need to run for pattern matching just yet, then

6:14 clgv: ,(let [a :x] (case a :z 1 (:y :x) 2 :default))

6:14 clojurebot: 2

6:16 andrevdm: Right but if I want the matching val to be evaluated first then case wont work...

6:16 So then is the next best option pattern matching?

6:18 effy: what is the correct way to use memoize with a recursive function? i've tried this http://pastebin.com/xpgsAKfi but it only cache the top level call not the recursives calls

6:27 andrevdm: fwiw using a cond rather than a case works for my case

6:27 noncom: i know that ccw does not use leiningen's project file to run a clojure application. someone please tell me, how do i make all the definitions of the project file be effective for the launched app?

6:30 clgv: ping

6:46 clgv: noncom: I think newest CCW uses a tight leiningen integration but I have not checked the details yet

6:46 noncom: since 0.22.0

6:52 logic_prog: why does clojure prfer foo-bar to FooBar ?

6:52 Ember-: lisp way of naming things

6:52 logic_prog: I'm looking at "placed-nodes", and I think "PlacedNodes" makes more sense

6:52 since I want to say "there is many of "placed-node""

6:53 fredyr_: effy: the memoization is only local to one computation of fibo

6:54 effy: so all the recursions are being memoized, but if you run a new call to fibo-m its going to start over

6:55 effy: fredyr_: yeah i get that, that's why i'd like to know what would be a correct way to make the inner call to fibo to point to the "global" outter memoized one

6:56 fredyr_: effy: alright, don't really know, i guess the point of memoize is to keep the caching local

6:56 effy: you can have a look at how its implemented, to get some ideas perhaps

6:56 ,(source memoize)

6:56 clojurebot: Source not found\n

7:07 edbond: effy, you should call memozied fibo-m inside fibo

7:08 effy: edbond: isn't that create a new cache at each recursion ?

7:08 edbond: effy, no, memoized returns new function with cache - see https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L5723

7:10 opqdonut: andrevdm: I find myself using condp = more often than case

7:10 effy: edbond: unless i'm missing something here, it doesnt work, placing the memoize inside the body of the function just made it 3 time slower

7:11 edbond: effy, try http://pastebin.com/dmwgRT6T

7:13 effy, better another way - http://pastebin.com/VKWMJzRn

7:14 effy, the idea is to call memoized version

7:16 effy: edbond: oh sweet, the declare thing do the tricks, i didn't know you could pre-declare things like that, that's kind of neat ! :)

7:17 edbond: effy, I would better change fibo to return memoized version without declare trick. That looks hacky to me.

7:19 effy: hey at least i learned a new concept, doesn't matter if it's hacky, it's not like if i cared about fibonacci anyway :)

7:31 squidz: Does anybody know how to use a clojurescript multimethod from javascript? My multimethod dispatch-fn is just a key to a map which is passed (defmulti mymulti :akey) (defmethod mymethod :akeyval ...

7:39 so if I have a clojurescript function a can easily access it in javascript via app.myfn(), but if myfn is a multimethod this doesn't return a javascript function. Is there a way to call a multimethod from clojurescript?

7:42 clgv: squidz: you can have a look in the not-optimized javascript where you compiled a multimethod call to see how clojurescript does it

7:43 squidz: clgv: alright, i'll just look there. Thanks

7:57 noncom: clgv: oh ok, but otherwise, there was no way to specify the same things for a ccw project as for the lein project, right? for example, aot targets...

7:59 oh i guess i just have to read ccw manual more

8:00 clgv: noncom: no. there were no settings dialogs in eclipse

8:01 noncom: clgv: then how do i specify aots?

8:03 clgv: noncom: I am not sure whether the leiningen setting for :aot worked before. but it might now.

8:06 noncom: hm ok. :repl-options is not supported yet

8:07 noncom: so maybe just running launchers is enabled...

8:22 noncom: clgv: i see.... well, aot works in leiningen and i really need it to work for me, so seems ccw is of no help here..

8:22 however, ccw is said to use leiningen internally..

8:22 so i am lost..

8:23 well.. maybe i can still use leiningen for building the app, not ccw

8:23 clgv: noncom: file an issue on the googlecode page. laurent uses this to organize his work

8:23 noncom: okay, thanks, i'll ask laurent about this one!

8:30 deadghost: https://www.refheap.com/28385

8:30 enlive is making some funky html for me

8:32 I don't know what to pin it on

8:32 I've stripped it pretty bare

8:41 edbond: deadghost, did you try html/content instead of html/prepend?

8:42 deadghost: edbond, just tried it

8:42 still wonky

9:00 ok going to bed

9:00 http://stackoverflow.com/questions/21382703/enlive-snippet-giving-me-odd-html

9:00 if anyone wants to take a shot at it

9:09 ro_st: howdy dnolen

9:10 dnolen: ro_st: hello

9:28 noncom: what is the best option to parse xml in clojure?

9:29 ro_st: https://github.com/clojure/data.xml

9:31 noncom: thanks!

9:39 mikerod: If I'm looking at a decompiled .class generated by the Clojure compiler, and I see something like: somefn_const.invoke(local_variable_name_1 = null, local_variable_name_2 = null)

9:39 Well: to make this more readable:

9:39 somefn_const.invoke(local_variable_name_1 = null, local_variable_name_2 = null)

9:39 is this being decompiled wrong, or does that actually work?

9:40 I am fairly sure this has to do with "locals clearing" (which I cannot actually find any real explanation on, but I think I get it).

9:40 However, I'd think this would just invoke the function with null's

9:40 Since, I'd think the assignment would be done first. Maybe I am misinterpreting the semantics of how this works though...

9:48 tbaldridge: mikerod: the decompiler may be messing something up. Yes it is loccals clearing, but the assignment doesn't happen until after the value is pushed on onto the stack

9:49 stuartsierra: It might be pushing the values of those locals on to the stack before clearing them.

9:49 clgv: mikerod: yes definitely wrong decompilation. I have seen that often as well

9:50 mikerod: Oh, ok. Thanks for the feedback on that. It was bothering me since I couldn't see how that would possibly work.

9:51 I guess the lesson is to just read the bytecode. :P

10:25 clgv: mikerod: not necessarily, most output of the decompilers is readable

10:26 depends on which on you use though

10:27 mikerod: clgv: I haven't really decided on the best one to use. I should look into it some more.

10:27 clgv: mikerod: I default to procyon currently. I am using it with the luyten gui

10:28 mikerod: but I have jd-gui installed as well

10:28 mikerod: clgv: Cool, I'll look at these options. Thanks for recommendations.

10:29 clgv: mikerod: what did you use?

10:30 mikerod: I was using the built in decompiler of jarzilla when I was observing this locals clearing issue I mentioned. I'm not sure what decompiler it uses.

10:30 clgv: ah ok thanks

10:30 mikerod: (I was looking in a jar archive too, but I could just extract)

10:58 gfredericks: with cider does anybody get "Variable binding depth exceeds max-specpdl-size" when trying to eval a form in a large file with lotso forms?

11:00 seems like a weird thing to be sensitive to

11:02 technomancy: gfredericks: that's elisp for "stack overflow"

11:03 I would expect to see it from clojure-mode; pretty weird for cider to be susceptible to it

11:06 tim_: does clojure have a 'not' function to invert a boolean input? Just want to test for a input that is not nill '(=(nil? a) false)'

11:06 technomancy: ~tias

11:06 clojurebot: tias is try it and see

11:07 RickInAtlanta: ,(nil? nil)

11:07 clojurebot: true

11:11 ianbishop: happy to announce another clojure shop has been acq'd :) - http://techcrunch.com/2014/01/27/liveops-raises-another-30m-acquires-userevents-to-expand-its-cloud-contact-center-platform-with-routing/

11:12 tim_: ,(=(nil? nil) false)

11:12 clojurebot: false

11:13 tim_: just wondered if there was a shortened version.

11:13 RickInAtlanta: ,(not (nil? nil))

11:13 clojurebot: false

11:14 tim_: ok, thanks. i couldn't see the not function on clojure docs

11:15 ToBeReplaced: anyone ever used clojure to create circuit diagrams? i'm looking for a way to go from an edn representation of a simple circuit to visual output

11:21 RickInAtlanta: technomancy: I am sure you get this a lot. but from time to time I just need to comment on how awesome lein is.

11:21 Wild_Cat`: so very true.

11:22 gfredericks: technomancy: I don't know for sure it's not clojure mode?

11:23 ,((complement nil?) nil)

11:23 clojurebot: false

11:23 gfredericks: ToBeReplaced: this is probably not exactly what you're thinking of? http://gfredericks.com/gfrlog/98/sha1.svg

11:26 ToBeReplaced: gfredericks: no -- i might not even be using the best language -- i'm looking for the ability to draw http://commons.wikimedia.org/wiki/File:Transistor_Simple_Circuit_Diagram_with_NPN_Labels.svg

11:27 i get that graph drawing is not a solved problem, but figured there might be attempts for the common case -- think like ztellman's rhizome for xcircuit/tinycad/whatever

11:28 doesn't have to be clojure either really -- just anything that doesn't make me click on a screen and assign the layout myself because I really have no idea what i'm doing with that

11:53 Janiczek: Hi guys, core.logic.fd question... I have a vector [[0 1] [2 3]] and I want to get a value from it with get-in. I've got lvars x,y - (fd/in x y (fd/interval 0 1)). How do I do get the integer values from the lvars? (get-in myvec [y x] -1) gives -1 everytime. Do I have to use project or something like that?

11:54 tim_: i'm stuck on a problem with my code. '(> a 0)', i'm getting 'clojure.lang.Keyword cannot be cast to java.lang.Number'. i'm confused and can't replicate it in the repl, but it occurs in my web app.

11:57 S11001001: ,(> :hi 0)

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

11:57 S11001001: ^^ tim_

11:57 dsrx: ,(let [a :hi] (> a 0))

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

11:58 gfredericks: ,(type (hash-map)) ;; wat

11:58 clojurebot: clojure.lang.PersistentArrayMap

11:58 hyPiRion: gfredericks: welcome to Clojure

11:58 gfredericks: :D

11:58 ,(type (array-map))

11:58 clojurebot: clojure.lang.PersistentArrayMap

11:59 gfredericks: phew

11:59 rasmusto: ,(map type {} {1 2})

11:59 clojurebot: ()

11:59 rasmusto: o woops

11:59 ,(map type [{} {1 2}])

11:59 clojurebot: (clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap)

12:00 dsrx: ,(type (into (hash-map) (for [n (range 50)] [n n])))

12:00 clojurebot: clojure.lang.PersistentHashMap

12:00 hyPiRion: gfredericks: Aha

12:00 for no args, it's just ([] {})

12:00 gfredericks: yeah I figured it prollably was that

12:00 ,(type (dissoc (hash-map 1 2) 1))

12:00 clojurebot: clojure.lang.PersistentHashMap

12:00 gfredericks: ^ empty hash map

12:01 ,(type (apply array-map (range 10000)))

12:01 clojurebot: clojure.lang.PersistentArrayMap

12:01 hyPiRion: ,clojure.lang.PersistentHashMap/EMPTY

12:01 clojurebot: {}

12:02 dsrx: ,(type clojure.lang.PersistentHashMap/EMPTY)

12:02 clojurebot: clojure.lang.PersistentHashMap

12:05 tim_: thanks!

12:10 Wild_Cat`: so what's the deal with PersistentArrayMap? Are those faster/easier on the RAM for small sizes?

12:10 hyPiRion: faster for small sizes

12:11 Wild_Cat`: actually, is there a paper somewhere that describes how Clojure maps are implemented?

12:12 (kind of like http://hypirion.com/musings/understanding-persistent-vector-pt-1 -- which is awesome, thanks hyPiRion)

12:13 katox: woohoo, I just found out that Om discarded om/read, cool

12:14 dsrx: what was om/read?

12:15 katox: dsrx: it was a way how to prevent unsynced access to application state

12:16 dsrx: now cursors should behave similar to atoms if I understand it correctly

12:16 gfredericks: Wild_Cat`: I always imagined it was a pretty obvious hash tree thing but I'm probably wrong

12:16 * katox started refactoring chaos

12:17 Wild_Cat`: gfredericks: well since it looks like Clojure has at least 3 map types, only one of which is explicitly sorted, maybe not ;)

12:19 hyPiRion: Wild_Cat`: http://lampwww.epfl.ch/papers/idealhashtrees.pdf is probably the closest one. Describes a mutable version very similar to the hash map

12:20 Wild_Cat`: I figure I'll have to read the source if I want to find out how the immutable updates/merges work, then...

12:20 (I'm assuming there's a clever mechanism to avoid duplication like there is for vector)

12:22 hyPiRion: Wild_Cat`: It's the same idea, mostly. Path copying down to the node, then update/replace the lowest level

12:22 At least from what I've gathered

12:23 gfredericks: Wild_Cat`: well a hashmap wouldn't be sorted

12:23 Wild_Cat`: hyPiRion: and I imagine there's some promotion magic to determine what type will end up being used for the final map

12:24 hyPiRion: Wild_Cat`: hah, yeah. Probably

12:25 That's the magic I guess. I have no clue how that actually works

12:28 TimMc: Wild_Cat`: This has some info: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html

12:29 I think PHM has changed since then, though.

12:29 Wild_Cat`: TimMc: thanks, I'll check it out

13:17 gfredericks: Is it a problem that :post precludes recur?

13:18 mdrogalis: gfredericks: IMO yes, but there's not really a good solution.

13:18 bbloom: i mean, if you have a post condition, then that's the new tail position

13:19 if you want the post condition checked every go around, then you can't sue recur.. .makes sense to me. just insert a new loop or anonymous function & recur on that

13:19 dnolen: mdrogalis: seems doable w/ a little of analysis actually

13:19 little bit

13:19 sdegutis: head position is the new tail position

13:19 mdrogalis: dnolen: I suppose so.

13:19 gfredericks: bbloom: that could be done in the fn macro, right?

13:20 maybe a bit sticky; too sticky?

13:20 dnolen: mdrogalis: we actually already do loop/recur return type analysis ClojureScript, it's pretty trivial actually.

13:20 bbloom: gfredericks: which would it do? check post conditions on every recur or only at the top level?

13:20 gfredericks: dnolen: would that mean it's easier to do in the compiler than the fn macro?

13:20 mdrogalis: dnolen: Huh - did not know. Pretty cool.

13:20 gfredericks: bbloom: only at the top level

13:21 bbloom: gfredericks: i guess that's a somewhat reasonable thing to do

13:21 dnolen: gfredericks: the macro could call the analyzer and do the write thing in the actual tail positions that are not recur expresions

13:21 bbloom: alternatively, it could add a precondition to non-top-level calls

13:21 dnolen: s/write/right

13:21 teslanick: I'm working through the om tutorial in the project wiki, why is this the case? : "First we set the initial state by implementing om/IInitState.We just allocate a core.async channel. It's extremely important we don't do this in a let binding around reify. This is a common mistake. Remember the contacts-view function will potentially be invoked many, many times."

13:21 Does let do something under the hood that breaks reify/async channels?

13:22 bbloom: teslanick: no, thinking about the "many, many times" bit

13:22 dnolen: teslanick: because your component fn will be invoked multiple times, allocating a resource in a let binding outside reify is a leak

13:22 teslanick: Ah, so let [ my-chan (chan) ] would be no bueno?

13:23 dnolen: teslanick: any resource

13:23 teslanick: That makes sense, thanks!

13:53 Another question about the tutorial: "Evaluate the new code and try it out. As you'll see, clicking on the delete button won't do anything. In fact if you look at the JavaScript console you'll see an error about trying to manipulate a cursor outside of the render phase. What went wrong?"

13:53 I did not get this error, the contacts in the list appear to delete.

13:57 Adding the proposed fix throws the following error: "No protocol method IDeref.-deref defined for type om.core/MapCursor: [object Object]"

14:00 socksy: what's the best practice regarding large data structures within a reference type (say an atom)? Can't intuitively think how to alter some submap

14:00 technomancy: socksy: swap! + update-in

14:01 socksy: ah cheers

14:05 dnolen: teslanick: look at the list of closed issues, this has been reported many times now

14:07 teslanick: Sorry, and thanks again

14:08 devn: A lisp in Julia would be interesting...

14:08 in the style of clojure

14:10 bbloom: julia already has a lisp on the inside :-)

14:10 devn: julia> :(5 + 10 * 2 * 3) evals to :(+(5,*(10,2,3)))

14:11 cark: dnolen: i've been bugging the clojure-mode people to add indentation and coloring for specify. But they ask me now if specify! and specify* should also be added. I know these two were discussed, but are they part of the "public" api ?

14:12 dnolen: cark: specify* and specify! don't exist

14:12 cark: dnolen: ah that settles it, thanks

14:28 sdegutis: devn: was thinking of the very same thing the other day.

14:29 a VM hosted on Julia could be almost as fast as one written in C if done right without sacrificing much expressivityness

14:34 xuser: sdegutis: why would I C implementation of Clojure sacrifice expressiveness?

14:35 s/I/a/

14:36 sdegutis: xuser: C just makes it hard to separate the abstraction from the implementation

14:41 devn: sdegutis: we should do it, man

14:42 sdegutis: devn: lol, I'm not smart enough for that kind of thing

14:42 not yet at least.. in a few years maybe

14:42 devn: writing a lisp?

14:42 sdegutis: devn: writing a VM with a GV and bytecode compiler

14:42 devn: oh, that. :)

14:42 sdegutis: I tried my hand at a VM and bytecode compiler over the holidays and failed miserably

14:42 havent even attempted the GC of course

14:43 ive written a dead-simple AST-walking Lisp interpreter a few years ago that did no GC, it just leaked like crazy

14:44 devn: i dont know julia all that well yet, but i was imagining something more like just doing something stupid, like having an env with k/v, where the k is the fn name, and the v is the operation performed in julia

14:45 then just parse some ()s and eval those expressions

14:47 sdegutis: devn: so a simple lisp interpreter? yeah sure im up for that

14:47 would be a fun way to learn julia

14:47 devn: yeah, that's kind of what i was thinking

14:47 sdegutis: (more than just readin the docs)

14:48 devn: it'd also be fun to see if we could get to macros by way of julia's macro system

14:48 i mean, i know we could, just curious what it'd look like

14:48 sdegutis: hmm yeah

14:48 setup a github repo and invite me if you want

14:49 devn: needs a nem.

14:49 name*

14:49 sdegutis: im terrible at naming things.

14:49 also we could use the github issues to discuss design questions

14:49 technomancy: I was just wondering this morning if there were any projects named "alcibiades"

14:49 sdegutis: how about Clojure? i.e. closures in Julia

14:49 devn: "Ascanius"

14:50 Julia is "of the gens Julia, a descendant of Julus"

14:50 sdegutis: (the J in Clojure is for Julia)

14:51 devn: and Ascanius was also called Iulus or Julus

14:51 Iulus is kind of a cool name

14:52 DerGuteMoritz: dangerously close to lulz though

14:52 devn: haha

14:53 julisp sounds borderline inflammatory

14:54 sdegutis: I was reading Romana Familia the other day and Iulius kept popping up, which you just reminded me of.

14:54 er i mean Familia Romana, it teaches latin using natural method

14:55 RickInAtlanta: how about julep, after the drink?

14:56 devn: sdegutis: is this you?

14:56 RickInAtlanta: i like that name. maybe we'll change it, but i just went ahead and called it lispia

14:56 sdegutis: devn: huh?

14:56 devn: sdegutis: err this github username (sdegutis)

14:56 sdegutis: ys

14:56 devn: k, added

14:56 DerGuteMoritz: how about romeo? ;-)

14:57 RickInAtlanta: nice!

14:57 DerGuteMoritz: oh wait it's juliet in english, isn't it

14:57 devn: i like it either way

14:57 gfredericks: does anybody try to log in a compojure app which route is being matched? I feel like it is difficult/impossible to log that ideally early

14:57 devn: https://github.com/devn/romeo

14:57 DerGuteMoritz: you could even have an alpha romeo release

14:57 devn: romeo wins

14:57 gfredericks: and difficult to log at all in any case, without redefining the compojure macros

14:57 DerGuteMoritz: heh, cool,

14:58 * DerGuteMoritz checks off the "naming a programming language" task on his life time to-do list

14:58 gfredericks: i.e., I'd prefer to be able to log in some of the earliest middleware which route is being requested, but of course at that point the matching hasn't occurred yet

14:59 hiredman: gfredericks: time to start looking for an alternative

14:59 gfredericks: hiredman: that thought has occurred to me many times

14:59 hiredman: I don't imagine you know of one?

15:00 hiredman: compojure routes are composed ring handlers, ring handlers are just functions, function composition is not sufficiently rich

15:00 nope

15:00 sdegutis: devn: pretty sure we can rename the github repo at any time any number of times with no problems btw

15:00 hiredman: maybe pedestal has one?

15:00 sdegutis: woo downloading windows 8.1

15:00 * sdegutis is excited

15:00 gfredericks: hiredman: well it's not inconceivable to define routes as data, then have a function that does just the matching and a later handler that calls the matched function

15:01 I've 1/7 of a mind to write this myself

15:01 scape_: anyone use korma?

15:01 sdegutis: scape_: i was considering it before i eventually settled on datomic

15:01 hiredman: sure, not at all, you just need extra information above and beyond the ability to invoke a function

15:01 scape_: sdegutis: dataomic nice? I bet it is

15:02 sdegutis: scape_: much better than the alternatives for my use-case

15:02 which is just a plain old web app: www.cleancoders.com

15:03 got much faster the day i deployed the datomic branch and killed the mongodb branch

15:03 scape_: nteresting

15:03 nice site :)

15:04 mongo is tricky sometimes, seems better as a place to put things, then to retrieve

15:05 DerGuteMoritz: scape_: https://twitter.com/BigDataBorat/status/352043285549813760

15:06 scape_: hah

15:07 katox: huh, that was quite a bit unexpected, destructured #uuid from a cursor is a cursor a and must be derefed first

15:08 dnolen: do you think Om will support #uuids as react :key-s? or is it unreasonable and additional guid should be used instead?

15:09 scape_: in korma when updating a table in mysql, it returns nil when typically you'd get the number of affected rows. when running a raw query in korma it does return that, strange that the update function/macro does not return anything

15:10 dnolen: katox: deref in render phase will not be allowed in the future, that bug is becauase UUID is ICloneable in CLJS, probably a mistake on my part, should have restricted that to collections only.

15:12 sdegutis: devn: oh, your name is devin? i thought your nick was just a play on "developer" and "defn"

15:12 this actually makes it cooler

15:14 katox: dnolen: ah, ok. will that uuid fix also resolve its usage as a react :key? (having a unique identity)

15:15 dnolen: katox: the key should be a string or something that has a short sensible toString result

15:15 katox: I wouldn't use uuid

15:17 katox: dnolen: hmm, yes I use an additional id right now, so I'll probably leave it at that. I guess the duplication will be lesser evil than slower react node comparisons. thanks

15:21 piranha: dnolen: right now it's not possible to have computed cursor in om, right?

15:21 dnolen: piranha: what is that exactly?

15:21 piranha: hmm... well I have data incoming to a component which is two parts, some list with data and some hash-map with metadata

15:22 and when I render one component I need to pass metadata there as well

15:22 and can't really understand what's the proper way to do that...

15:22 I mean I want to render a list of components from that list of data, and each such component should get corresponding meta-data

15:26 dnolen: ^

15:28 dnolen: piranha: there are couple of ways to do this

15:28 cursors can be modified like normal collections

15:28 you can join in some new data from elsewhere in your render implementation with om.core/join

15:29 piranha: so I can preprocess it with :fn, I figured out this one but I'm not sure how to turn back my LazySeq from for to a cursor

15:29 hmmm ok I didn't really understand how to use join, I need to look at examples some more

15:29 dnolen: it's not fully baked yet, because we need some extra dependency tracking for it to work

15:29 but it's on my list of things to do "right now"

15:29 piranha: preprocess with :fn could also work

15:30 depending

15:30 but honestly a proper om.core/join sounds closest to what you and other people want for this use case

15:30 piranha: ok, I'll try with join first

15:31 right

15:31 dnolen: I'm still unsure how to use it...

15:31 ah

15:31 dnolen: piranha: expect suprises, om.core/join doesn't do dependency tracking, so if you join with something and that thing changes, you won't get re-renders

15:31 piranha: ah I think I got it

15:31 ohhhh

15:31 dnolen: this is what needs to be fixed

15:31 piranha: that's exactly what I want... well I think in my case it still could work

15:32 let me try :)

15:36 argh, it just breaks :\

15:36 dnolen: when I use om/join, it says 'cannot build Om component from a non-cursor'

15:37 I do something like (for [item items] (om/build single-item-view (om/join item [:points (:text item)])), does that look right?

15:38 dnolen: piranha: that's not how om.core/join works (apologies, it's experimental)

15:38 piranha: oh, how does it work?

15:38 dnolen: it just returns a cursor for a some other value from the root of the app state

15:38 piranha: hmmm

15:38 not sure I understand

15:38 dnolen: you typically call it from inside your component's render implementation

15:38 not at build

15:38 piranha: ah

15:38 AH!

15:38 :))

15:38 dnolen: piranha: look at the last section of the Om tutorial, it will clarify things

15:39 piranha: it's very short

15:39 piranha: well I looked at that point exactly but somehow it didn't get to me :)

15:40 dnolen: piranha: once fully baked, it will be the way to construct components that use different bits from the application state.

15:40 piranha: sure, that's what I actually need :)

15:41 dnolen: people are doing all sorts of crazy things at the moment and I can't blame them as I haven't really explained nor finished om.core/join

15:41 piranha: :)

15:42 dnolen: probably today or tomorrow I'll get it done and cut a new release. I already have the implementation worked out.

15:42 piranha: dnolen: yeah it really does not update :(

15:42 dnolen: yep

15:42 piranha: cool! :)

15:43 escherize: hello?

15:43 clojurebot: BUENOS DING DONG DIDDLY DIOS, fRaUline escherize

15:45 escherize: ,(+)

15:46 clojurebot: 0

15:46 escherize: ((fn [x] (eval (conj (range 1 (inc x)) *)) 5))

15:46 ,((fn [x] (eval (conj (range 1 (inc x)) *)) 5))

15:46 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: sandbox/eval49/fn--50>

15:47 dnolen: piranha: I take in React land people just pass more information via props in this case no?

15:47 piranha: dnolen: yeah, and then you just take what you need and pass further in props

16:01 ior3k`: anyone know what's relevance's % of clojure projects as opposed to say, rails projects, etc

16:01 I had a "heated" argument about the viability of clojure

16:01 I work at a dev shop and I'm trying to introduce clojure there

16:02 bbloom: ior3k`: i doubt they will share that number, but anybody who things clojure isn't viable isn't worth arguing with. 60 seconds of research can show dozens of companies that do clojure work

16:02 s/things/thinks

16:03 stuartsierra: I can say that a significant proportion of our consulting work is in Clojure(Script) these days.

16:04 ior3k`: yeah, the main argument thrown at me is that it's a relatively unknown technology, clients won't handle it after the handoff, etc

16:04 seems like a chicken and egg problem

16:04 bbloom: ior3k`: those are two different statements

16:04 stuartsierra: ior3k`: They can always hire us. :)

16:05 ior3k`: ha, that doesn't help me

16:05 bbloom: ior3k`: relatively unknown == obviously bullshit. but not great for handoff is quite possibly true

16:05 ior3k`: bbloom: unknown relative to say, rails (our main technology)

16:05 I argued rails was once relatively unknown as well

16:06 but that didn't seem to work so well

16:06 bbloom: ior3k`: the better argument to make is to say that some tech is unknown and stays unknown and some tech grows

16:06 ior3k`: clojure is clearly growing, so it's a good bet b/c you'll be experts sooner rather than later

16:06 however, it's worth noting that clojure is unlikely to grow to rails scale

16:07 ior3k`: bbloom: that's ok as long as *I* can work using it :)

16:07 although I really think it's a better way to develop software

16:07 which would clearly benefit us and our clients

16:07 bbloom: ior3k`: sure, but developing software is only part of your job

16:07 ior3k`: solving your clients problems is a bigger part of it

16:07 RickInAtlanta: ior3k thoughtworks has clojure as "adopt" on their technology radar http://www.thoughtworks.com/radar

16:08 ior3k`: bbloom: sure, but what if clojure helps me solve them better?

16:08 definitely not trying to push it just for the sake of it

16:08 bbloom: ior3k`: that's all well and good, unless your clients need to be able to maintain the software and wish to retain access to a larger pool of existing experts

16:08 ior3k`: bbloom: of course, I agree

16:08 bbloom: ior3k`: as with anything in life, it's a tradeoff

16:09 ior3k`: the question you need to ask/answer is whether the benefit in development speed/cost/quality is worth the risk of reduced ecosystem size

16:09 ior3k`: it's going to vary for different clients and consultancies

16:09 andrei: Is fmap from clojure.contrib.generic.functor supposed to return a list in reverse?

16:10 This breaks the definition of a Functor

16:10 bmath: The Python Paradox: http://paulgraham.com/pypar.html.

16:10 tldr; Using non-mainstream languages paradoxically attracts better developers.

16:10 (applies more to in-house hires than consulting)

16:10 ior3k`: bbloom: definitely

16:10 bbloom: but it still seems a chicken and egg problem

16:12 dnolen: ior3k`: any Rails shop making that argument against Clojure can hardly be taken seriously given history

16:12 andrei: more importantly clojure.contrib is dead

16:12 ior3k`: dnolen: exactly

16:13 andrei: dnolen: Oh. Where does one get fmap that is in clojure.contrib.generic.functor ?

16:13 dnolen: andrei: don't know but there are several monad / functor libs for Clojure floating around

16:14 andrei: dnolen: Ah, algo.generic

16:15 dnolen: Great! Seems like this was a bug and was fixed at some point after the migration. Thanks!

16:19 stuartsierra: clojurebot: contrib?

16:19 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

16:19 hhenkel: Hi all, got a small question regarding nested doseq and let constructs. What is the best way to return multiple values from such a beast?

16:19 rasmusto: hhenkel: return a map or a vector?

16:19 OneFourSeven: hhenkel, isn't for what you're looking for?

16:20 joegallo: put a vector on it

16:20 (http://www.youtube.com/watch?v=0XM3vWJmpfo)

16:20 rasmusto: I think I know what that is already

16:21 hhenkel: rasmusto: so, I create a temp variable within the doseq and at that to a map or vector then...once I'm finished I return it, right?

16:21 OneFourSeven: Nope, I think doseq does what I need it to do so far...

16:21 rasmusto: hhenkel: use 'for' instead of doseq if you're returning something.

16:22 hhenkel: rasmusto: okay, I'll check.

16:22 joegallo: ,(for [i (range 5) :let [j (inc i)]] [i j])

16:22 clojurebot: ([0 1] [1 2] [2 3] [3 4] [4 5])

16:24 hhenkel: joegallo: rasmusto: Is there a better way to do the same thing in a "more" clojure compatible way (my code looks a bit iterative) or is this a good way to do?

16:24 joegallo: reduce is also a thing

16:25 for is for list comprehensions

16:25 rasmusto: hhenkel: "for" is a good way to do it, it's not iterative, though it shares a name with other languages

16:25 joegallo: doseq is iterative, but doesn't return anything (nor should you want it to)

16:25 how about you pastebin some of your code for us to see, rather than describing it?

16:26 AeroNotix: if you could go ahead and *do that*, that'd be greeeeeaaat.

16:26 OneFourSeven: Anybody making web apps?

16:27 hhenkel: joegallo: rasmusto: okay, thanks so far, I'll give it a try and have a look how far I get...I guess I'll stop by later and paste my code when I'm facing probs.

16:27 rasmusto: hhenkel: ok, feel free to paste at any time, no use getting stuck

16:27 OneFourSeven: If you guys want to look at some code, I've got something

16:34 Okay

16:34 Who knows about authentication and sessions for ring apps

16:41 dnolen: OneFourSeven: if you have a question just ask a question

16:41 OneFourSeven: dnolen, sorry, was prepping something

16:43 Two things, first, I was building an authentication library for Ring because I thought friend was a little too complicated. Secondly, my weekend project was a code annotator/review site.

16:44 I was wondering if somebody could take a gander at the library I built

16:44 See if there are any possible security concerns

16:44 Here: http://kurikku.com/s/52e6c870e4b0909ac906fc5a

16:48 elarson: is there a good reason to use a record over a struct?

16:49 dnolen: elarson: structs are deprecated

16:49 elarson: I'm just starting out with clojure and noticed in the docs it mentioned most structs could just use records

16:49 OneFourSeven: I believe that structs aren't used much anymore

16:49 elarson: ok, cool

16:49 xexonixxexillion: I'm fairly new to clojure, so this is probably a stupid question, but does clojure have an equivalent of common lisp's set-dispatch-macro-character (I'm currently getting the feeling it doesn't)

16:50 technomancy: xexonixxexillion: it's intentionally omitted for composability reasons

16:51 dnolen: xexonixxexillion: you have a more restricted version of it - reader literals

16:52 clojure has I mean

16:52 TimMc: xexonixxexillion: Effectively, no.

16:58 elarson: if I have a record Foo, how can I do (let [a-foo (->Foo "hello")] ...)

16:59 jeremyheiler: elarson: Why can't you do that?

17:00 elarson: jeremyheiler: probably b/c something was wrong with another item in my let statment :/

17:00 jeremyheiler: heh

17:11 akurilin: When I'm validating outside input in my Ring app, does it make sense to separate validation into a "is the type correct" pass and then into a "can I parse this input to the intended type" pass?

17:11 As in, say you're getting a date as input, you want to make sure it's a string and hen that the string actually parses to a date

17:12 I'm thinking I might as well combine the two into one single check.

17:12 And just return the same error for both cases "Could not parse foo to date"

17:12 akhudek: akurilin: don't parameters always come as strings?

17:13 akurilin: akhudek: this is post JSON deserialization in cheshire

17:14 akhudek: akurilin: ah. well, separating it into a type check then a parse check could make sense if you have a generic way of doing type checks (maybe like schema?)

17:15 akurilin: For some reason this originally sounded like a great idea, but in reprospect it felt overly complicated for the purpose of telling the caller tha ttheir input is invalid.

17:15 Still can't quite fully remember why I thought that was going to be a superior approach

17:17 devn: Does anyone know of any good information on reduce-kv? I don't think any book to date has written anything about it.

17:19 doppioslash: Does caribou actually deploy to Heroku?

17:19 devn: doppioslash: no :)

17:19 doppioslash: well, they claimed that in their docs, but I found it borderline impossible

17:19 i dont think they've tested it

17:19 but this was a month or two ago, so maybe the story is better now

17:20 doppioslash: I'm trying now with a lein new caribou project and after changing the Procfile, adding in the postgres data in production.clj

17:20 I'm having trouble actually making the migration run

17:20 devn: doppioslash: you're going to need changes to the postgres config

17:20 let me see if i can find my old stuff

17:20 doppioslash: thanks :)

17:21 devn: doppioslash: i ended up running the migrations from my local machine

17:22 doppioslash: if I do it complains about no pg_hba.conf entry

17:23 devn: doppioslash: https://gist.github.com/devn/8658515

17:24 this was my local.clj.

17:24 which i did not commit

17:24 i dropped it into resources/config/

17:24 and then i was able to migrate to the heroku DB from my local machine

17:24 there were still issues after i got past this though, FWIW

17:24 doppioslash: thanks :)

17:24 what issues?

17:24 devn: also, you will have another issue

17:25 so, when you go to deploy, it's going to try and generate the js

17:25 and that directory is not there, so you'll need to commit a .gitkeep inside of.. (let me look)

17:27 cmatheson: i'm getting an "No matching method found: getPath" error when running the following code: (.getPath (FileSystems/getDefault) ""), but the FileSystem class *does* have a getPath method. what am i doing wrong?

17:27 devn: doppioslash: resources/public/js/app/.gitkeep, $PROJECT_ROOT/app/.gitkeep

17:28 doppioslash: thanks :)

17:28 devn: doppioslash: there may be another you need to handle, but im pretty sure you'll run into heroku complaining about directories not existing when it goes to compile JS and what not

17:28 doppioslash: the migration command

17:28 was it lein caribou migrate rsources/config/local.clj?

17:29 devn: also, doppioslash -- remove the jvm-opts line from project.clj

17:29 doppioslash: maybe, it's been awhile

17:29 doppioslash: additional stuff you might want to kill: project.clj :cljsbuild {:repl-listen-port 44994

17:30 you may also need to change :ring in project.clj to be :port (or (Integer/parseInt (System/getenv "PORT")) 33333)

17:30 or something like that

17:30 doppioslash: now you can see why i gave up :)

17:30 cmatheson: n/m, i can't read javadocs apparently

17:31 doppioslash: for the port changing the Procfile to web: lein with-profile production trampoline run -m myapp.core $PORT seems to have worked

17:31 devn: gotcha

17:31 doppioslash: at least it stopped complaining of being unable to get port 60

17:31 devn: doppioslash: i remember seeing something where it was spawning a repl server no matter what

17:31 that's going to tie up resources, so watch for that

17:32 doppioslash: yeah I think I saw it in the logs

17:32 haven't chased it yet

17:32 devn: doppioslash: you may also time out on deploy because heroku has a limit of 60sec or so

17:32 doppioslash: even after removing it from the proct.clj?

17:32 devn: you can do an uberwar deployment

17:32 doppioslash: project.clj*

17:32 devn: doppioslash: hmm, i think they recognized what i was seeing as a bug

17:33 so if you're on a newer caribou maybe they fixed it

17:33 doppioslash: boot.clj is the other place to look

17:33 :brepl and :nrepl are in there

17:33 doppioslash: there are indeed still in boot.clj

17:34 :brepl

17:34 devn: doppioslash: either way, if you get something working i'd love to see it. a write up would be much appreciated.

17:34 alew: devn: I'm deploying caribou to heroku

17:34 devn: It requires a bit of modification

17:34 doppioslash: I shall if I manage to make it work :)

17:34 thanks a lot

17:35 devn: alew: is that stuff documented now?

17:35 alew: devn: I was going to handle but I haven't gotten around to it yet

17:36 devn: fair enough. but alew, it would be nice to change the docs to reflect the reality of heroku deployment. the docs paint a picture that is far from accurate

17:36 alew: devn: I don't control the docs :P but yes, agreed

17:37 devn: i dont mind if it says: Heroku: "WIP. YMMV. You might have trouble. It's not easy. It can be done, though."

17:37 alew: doppioslash: There is a #caribou channel that you might want to check out to talk directly to those people

17:39 devn: alew: did you wind up doing the migration from your local machine, or did you set something up to run them on deploy?

17:39 alew: also, did you figure out how to turn off the repl server starting automatically?

17:40 alew: devn: It wouldn't make sense to do migration on deploy imo because that's a pretty sensitive operation

17:40 devn: And no, I haven't tried that yet.

17:40 devn: meh, i do it with rails

17:40 i feel like we've talked about this before

17:44 Morgawr: Raynes: opinions on a refheap plugin for LightTable? Do you know if somebody is working on it or if it's planned or... ?

17:44 (I could hack a plugin for that in case nobody is doing that)

17:45 Raynes: Morgawr: I don't know if anyone is working on it and I'm unlikely to get to it soon if you want to tackle it. I've written just under 7 billion clients across numerous languages, so there is plenty of code to look at. Also the API documentation on the refheap wiki.

17:45 Morgawr: yeah I saw the API docs, it shouldn't be hard to write, I might get to it in these couple of days ;)

17:45 just wanted to know so it's not duplicated/wasted effort

17:46 doppioslash: devn: inserting your local.clj :database in development.clj and running lein caribou migrate resources/config/development.clj made the migration work

17:46 devn: badda bing :)

17:49 arrdem: ibdknox: is the source for chromashift anywhere? I'm playing with my own CES architecture and curious what your update semantics are like.

17:50 patchwork: devn, alew: Yeah, I have been meaning to update the heroku docs for clojure for awhile now

17:51 I don't use it, so I haven't gotten around to it

17:51 *caribou

17:51 arrdem: yes.. the source is on github! google first.....

17:58 devn: wow. the JoC 2nd edition is /fantastic/.

17:59 scape_: I am using assoc-in on an atom {} to update a particular key's key, but I want to swap in more than 1 value to update a particular key's keys; like update key2 and key3 {:thing1 {:key1 :value1,:key2 :value2, :key3 :value3}}

18:00 AeroNotix: scape_: merge?

18:00 devn: really?

18:00 scape_: i'll try that thanks

18:01 AeroNotix: scape_: but you have to ask yourself why you're updating multiple keys?

18:01 perhaps you'd be better served with a map of refs

18:01 and then use dosync to take care of updates

18:02 rhg135: cljs

18:02 no stm yet

18:02 AeroNotix: oh

18:02 rhg135: just pointing out a reason :P

18:02 scape_: that's an idea

18:02 rhg135: idk why

18:02 AeroNotix: I didn't see any mention of CLJS

18:02 scape_: it's not

18:03 rhg135: ik

18:03 it's a valid reason it should be though

18:03 scape_: not using refs because I don't necessarily need it to be synchronously done, I just wanted to know if there was a way to update 2 keys at a time

18:03 Morgawr: if a function with only a when statement is evaluated and the when is not hit, it returns nil, right?

18:03 scape_: thx

18:04 rhg135: ya

18:04 Morgawr: my whole life was a lie :<

18:04 rhg135: ...

18:04 Morgawr: I've always written single when function with a stray "nil" at the end

18:04 always looked so ugly

18:04 AeroNotix: yeah it's not like there was a quick and easy way to check it

18:04 rhg135: mocker, thats funny and sad

18:05 oops

18:05 Morgawr,

18:05 AeroNotix: if only they made a program which could interactively read input, evaluate it and then print the results

18:05 a REPL, if you will

18:05 rhg135: my tabbing :c

18:05 AeroNotix: ohhh well, perhaps one day

18:05 rhg135: not node

18:05 well

18:05 repl yes

18:06 live no

18:06 AeroNotix: rhg135: I think you missed my sarcasm

18:06 rhg135: nope

18:06 i love it

18:06 the sad part is it doesnt always exist

18:07 Morgawr: AeroNotix: haha, I know right, I just never thought about it

18:07 AeroNotix: most not-shit languages have repls. There are even basic repls for C++

18:07 rhg135: ooh

18:07 doppioslash: devn: it's working :)

18:07 Morgawr: then I was wondering "wait, what if I just don't put it in?" and thought that sensibly it would return nil, I tested it and it did.. just asked in here cause I wanted to make sure there were no pesky corner cases

18:07 rhg135: a c++ one

18:09 i'd be sad without the repl

18:09 so useful

18:09 ,(doc when)

18:09 clojurebot: "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."

18:10 rhg135: hmm

18:10 i swear it was in the docs

18:10 ,(doc if)

18:10 clojurebot: It's greek to me.

18:10 rhg135: wut

18:10 michaniskin: ,(source when)

18:10 clojurebot: Source not found\n

18:11 rhg135: is it broken?

18:11 AeroNotix: no it just doesn't have the source on-file

18:12 afk

18:12 rhg135: i meant the doc thing

18:17 oich: way off topic,but I thought someone here would know. DITA-OT is software that uses ant for scripting that includes a plugin architecture. It's not an API. It doesn't have an API, exactly. Framework doesn't seem to fit. Is it a programming platform?

18:18 rhg135: oich, seems like a program

18:19 similar to eclipse sans ide

18:19 oich: ok. that makes sense.

18:20 rhg135: oich, js is a nice scripting lang

18:20 then clj was invented

18:20 oich: that is a very odd choice of events to describe history

18:21 rhg135: i mean before clojure you embeded rhino for scripting

18:22 now you write it in clojure and expose that

18:22 oich: ok. yeah I thought of comparing dita-ot to xulrunner or some such thing,but that's a bit of a stretch.

18:23 rhg135: im not familiar with either lol

18:23 oich: xulrunner is lower level than the mozilla... program. but it certainly has an API.

18:24 rhg135: ya... but it's for ___________ in ____?

18:25 oich: writing applications using the facilities shared by firefox, thunderbird and other stuff

18:25 rhg135: ah

18:25 technomancy: xulrunner: their heart's in the right place

18:26 rhg135: hmm

18:26 ohya i remember

18:26 * rhg135 shudders

18:26 elarson: if I change my code in clojure-mode and use C-c C-c in a function to compile it, does that also update the cider repl's version of that function?

18:26 rhg135: tried fixing a bug once

18:27 technomancy: rhg135: at least it's worlds better than Chrome's stance on extensibility: "Oh, you want to change a key binding? Cool; hope you've got three spare hours to recompile this huge chunk of C++"

18:27 rhg135: technomancy, touche

18:28 scape_: elarson: it should, though I use Cc Ce

18:28 technomancy: http://p.hagelb.org/punch.png

18:28 rhg135: i actually program on android

18:28 elarson: scape_: ah ok, I'll give that a try

18:28 rhg135: all that c++ and java

18:29 im referring to the core

18:32 technomancy, it was mainly cuz i had no c(++) experience and it was the first OSS project i worked on

18:36 Morgawr: mmm

18:37 I need some data transformation wizard.. I have some map inside a map inside a map (can be infinitely deep) and I need a non-destructive merge function to achieve something like this https://www.refheap.com/09051374e527ad08845dd85db

18:37 I tried using merge but it just overrides the old value and removes the inner maps, I tried using merge-with but then I'd have to recurse for as many inner maps I find

18:37 is there a function that does it already or do I need to make my own?

18:37 scape_: deep-merge?

18:37 Morgawr: is that a function in the stdlib?

18:37 (core, whatever)

18:38 scape_: http://clojuredocs.org/clojure_contrib/clojure.contrib.map-utils/deep-merge-with

18:38 Morgawr: scape_: nice, thanks!

18:39 scape_: :)

18:44 elarson: what is setq in clojure? I'm sure I could do a let but that seems like it is overkill... I'm probably missing something here

18:46 dnolen: elarson: setq doesn't exist, the closesting thing set! isn't really used the way it traditionally is in Lisp

18:47 elarson: you probably want a atom if you want something mutable that you can change

18:50 Morgawr: can I recursively apply destructuring of parameters?

18:50 like I have a map {:a 1 :b { :c 3}} and I want to get a and c out of it using :keys

18:50 scape_: dnolen: as in david nolen? i liked your talk on core.async! :D

18:50 technomancy: ~tias

18:50 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

18:51 devn_: nick devn

18:51 dnolen: scape_: thanks

18:51 Morgawr: technomancy: was that related to my question? I was asking if there's a simple way to do it like {:keys [something {:keys [something else]}]} or if I need to make my own

18:52 rhg135: 0.0

18:52 Morgawr: looks like freenode dun goof'd

18:52 technomancy: Morgawr: oh; I see. iiuc you can do it with exact destructuring but not with :keys

18:52 rhg135: again?

18:52 justin_smith: yeah, a map inside :keys doesn't really work

18:53 Morgawr: the problem is that I might have a lot of complex maps to pass around and I am only interested in a few parameters inside them, not the whole map

18:53 justin_smith: there is also get-in

18:53 or multi-stage destructuring

18:53 Morgawr: multi-stage?

18:53 justin_smith: (in a let block)

18:53 Morgawr: ah

18:53 oh well, that could work

18:54 (fn [{:keys [a b]}] (let [{:keys c} b] ...))

18:54 justin_smith: (let [{:keys [a b]} params {:keys [c d]} a] ...)

18:54 or that

18:54 but if you need a let already, it can be more clear to put it all in a let

18:54 Morgawr: yeah, probably

18:54 thanks

18:54 that makes sense

19:01 akurilin: Has anybody here tried to build sets of where clauses with Korma procedurally? E.g like what I'm doing here: https://www.refheap.com/28559

19:01 Obviously that won't work since it will actually evaluate the conditions before they're processed within Korma

19:02 And I can't get the quoting of it quite right in case that's how you'resupposed to roll

19:03 scape_: akurilin: maybe ['(< :id 100) '(= :id 50)] ?

19:03 cark: akurilin: i don't know much about korma but... there is no evaluation in conditions

19:03 oh sorry there are the < functions

19:04 akurilin: scape_: that won't work, Korma ends up generating something like WHERE ((?, answers.id, ?) AND (?, answers.id, ?))

19:04 scape_: i noticed it does that with as-sql for me too, not sure it is related to your issue

19:05 cark: i think you're supposed to compose the whole thing like the first example on the korma page

19:06 the end result is what you need

19:07 akurilin: cark: none of their examples use procedurally generated lists of clauses

19:07 cark: the first example composes two where

19:07 same thing, only done differently

19:13 akurilin: So apparently you need to quote the predicates if you want Korma to get them right

19:13 https://www.refheap.com/28559

19:13 They're evaluated somewhere within it too soon if you just leave them in the vec

19:13 scape_: interesting

19:14 cark: beats storing sql query text in a file =)

19:14 akurilin: Considering apply or / apply and aren't even documented, this is probably not the most trivial scenario.

19:15 Morgawr: Raynes: https://groups.google.com/forum/#!topic/light-table-discussion/ZZ9pcnUsKTQ looks like somebody is implementing a refheap plugin already, neat

19:16 scape_: I was trying to figure out earlier why I kept receiving ?'s in the query, figured I was doing it wrong. https://www.refheap.com/28566

19:17 I ended up just building a raw query

19:27 dsrx: raw query: "the electronica fans, tired of guitar riffs, considered themselves raw query"

19:30 akurilin: How do I evaluate something and then quote the return value?

19:30 As opposed to quoting the whole thing.

19:31 cark: it oesn't make sense

19:31 doesn't

19:32 quote is a special form

19:32 you can't apply it

19:32 also if something, say a function, returns a list. It's already "quoted"

19:33 the first element in that list isn't used as a functiona pplied to the rest

19:35 akurilin: I'm referencing the Korma quirk above. If I have something like [(give-me-function) "foo"], I'd like to get to ['> "foo"]

19:35 because returning just the fn at the beginning of that vec won't work

19:36 so I need to quote it

19:36 cark: again i'm not sure about korma, the macro could interpret the first element any way it wants. but my guess is that the first element should be a symbol instead of the function >

19:36 so just return the symbol >

19:36 (defn give-me-func [] '>)

19:39 akurilin: cark: that's fair, seems to do the trick

19:40 I don't get to work much explicitly with (symbol), not sure that's good or bad :)

19:40 cark: you might want to review your understanding of symbols and quoting

19:40 =)

19:40 ,(symbol? '>)

19:40 clojurebot: true

19:41 cark: ,(symbol? >)

19:41 clojurebot: false

19:42 akurilin: Is the idea that symbol just gives you the actual name of something as opposed to whatever the name evaluates to / is bound to?

19:42 The docs are pretty terse on this.

19:42 cark: right, the reader sees ">" ... he checks if it's a var and returns that

19:42 you can tell the reader to leave it alone by quoting it

19:43 akurilin: So when working with macros, you work on a symbolic level for the most part anyway, right?

19:43 cark: yes it's often the case

19:44 akurilin: If any of this breaks I'll never be able to debug it :D

19:44 cark: haha good luck =)

19:44 akurilin: Actually it's probably in my interest to get exposed to this stuff more.

19:45 cark: i'm not sure, i rarely if ever use symbols or even write macros anymore

19:45 most of the time, a mix of higher order functions will do the trick just as good

19:46 akurilin: I'm with you, which is why most of this is pretty foreign to me.

19:47 Difficult to get xp in macros when the n.1 rule is to never write them if you don't have to.

19:47 cark: i think you're supposed to thread your query through your functions and do you composition that way with korma

19:47 which might make it all easier

19:49 have a function check-credentials, for-customer-id, for-customer-name ...then (-> base-query check-credentials for-customer-id for-customer-name)

19:49 tho the example is kinda bad =P

19:50 akurilin: well I'm essentially implementing a generic JSON where blob to SQL translation where the caller gets to pick columns, predicates etc.

19:50 Basically what you'd get from using parse.com

19:50 So the whole thing is completely procedural.

19:51 cark: i think you may still do it this way only the functions a generated

19:51 akurilin: So I basically translate whatever's in that where map that I get from the caller into a sequence of where clauses that Korma can understand and then (apply and) them.

19:51 teslanick: I'm just barely looking at core.async; it seems like (go (while true … is a really weird pattern; is this actually common, or is it a hoist for tutorial purposes?

19:52 cark: teslanick: common pattern

19:53 akurilin: then once you have generated your functions you "thrush" these

19:53 (reduce #(%2 %1) base-qry functions)

19:55 this parse.com has a nice looking page =)

19:56 akurilin: cark: o is that the word for doing that kind of reduce?

19:57 cark: akurilin: i think so, that's the one i use anyways =)

19:57 akurilin: I never knew that.

19:57 devn: are you talking about thrush?

19:57 scape_: would it be possible to use filter with a vector as the predicate?

20:00 devn: scape_: you mean like this?

20:00 ,(filter [1 2 3] [0 1 2])

20:00 clojurebot: (0 1 2)

20:01 cark: keep only the indexes that map to a value

20:01 mhh

20:01 not very usefull =)

20:01 devn: yeah

20:01 scape_: hmm

20:01 devn: ,(filter [0 0 0] [0 1 2])

20:01 clojurebot: (0 1 2)

20:01 cark: ,(filter [0 0 0] [4 0 1 2])

20:01 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

20:02 cark: not even that

20:02 devn: cark: this is why we have set

20:02 ,(filter #{0 1 2} [4 0 1 2])

20:02 clojurebot: (0 1 2)

20:02 scape_: i'm doing this: (filter #(= (:uuid (val %)) uuid) @clients) but want to basically filter multiple uuid's and get a seq back, I guess I could use a for statement outside of this

20:03 cark: nto the same thing

20:03 scape_: so instead of filtering the 1 uuid, a vector of many uuids to filter out

20:12 devn: ,(filter #(some #{:A :B :C} [%]) [:a :B :C :D])

20:12 clojurebot: (:B :C)

20:13 devn: that's kind of a weird way to do it though

20:13 my brain is melting at the moment

20:13 scape_: yes, but that is a start for me

20:13 thx

20:13 the val % i have is complicating matters :-\ hah

20:15 delihiros: ,(clojure.set/intersection #{0 1 2} #{2 3})

20:15 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

20:15 devn: ,(require '[clojure.set :as set])

20:15 clojurebot: nil

20:15 devn: ,(set/intersection #{0 1 2} #{2 3})

20:15 clojurebot: #{2}

20:19 delihiros: devn: oops, thanks

20:19 devn: scape_: you could use reduce-kv as well

20:20 benmoss: should a .clj file in my cljsbuild source-path "just work"?

20:21 devn: to build up a sequence of uuids, filtering inside the reduce function

20:21 benmoss: in order to get it turned into JS that is

20:21 or do i have to use this "crossovers" feature

20:24 devn: ,(clojure.set/difference (into #{} (map (comp :uuid val) {:user1 {:uuid "user1"} :user2 {:uuid "user"}})) #{"user1"})

20:24 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

20:24 devn: ,(require 'clojure.set)

20:24 clojurebot: nil

20:24 devn: ,(clojure.set/difference (into #{} (map (comp :uuid val) {:user1 {:uuid "user1"} :user2 {:uuid "user"}})) #{"user1"})

20:24 clojurebot: #{"user"}

20:25 devn: scape_: does that do what you're looking for?

20:26 ,(clojure.set/difference (set (map #(get-in % [1 :uuid]) {:user1 {:uuid "user1"} :user2 {:uuid "user"}})) #{"user1"})

20:26 clojurebot: #{"user"}

20:26 devn: or that or something

20:28 elarson: dnolen: thanks. I'd like to use it in the repl so I can play around with a record

20:28 devn: ,(reduce-kv (fn [init k v] (conj init (:uuid v))) [] {:user1 {:uuid "user1"} :user2 {:uuid "user"}})

20:28 clojurebot: ["user1" "user"]

20:28 devn: etc. etc. etc. etc. etc.

20:31 okay okay, one more 'cause i'm a bit bored

20:31 ,(persistent! (reduce-kv (fn [init k {uuid :uuid}] (conj! init uuid)) (transient []) {:user1 {:uuid "user1"} :user2 {:uuid "user"}}))

20:31 clojurebot: ["user1" "user"]

20:32 * elarson tries var-set

20:32 devn: noooooooo!

20:32 elarson: devn: no to var-set?

20:32 technomancy: ~guards

20:32 clojurebot: SEIZE HIM!

20:32 devn: haha, i was mostly kidding

20:33 elarson: that didn't work anyway ;)

20:33 rhg135: mostly...

20:33 elarson: what is a good way to play with a variable you create in the repl then?

20:33 devn: what do you mean?

20:33 rhg135: hmm

20:33 devn: just rebind it to a new value

20:34 ,(def x 1)

20:34 clojurebot: #'sandbox/x

20:34 devn: ,x

20:34 clojurebot: 1

20:34 devn: ,(def x 2)

20:34 clojurebot: #'sandbox/x

20:34 devn: ,x

20:34 clojurebot: 2

20:34 elarson: well, in elisp I might do something like (setq some-url "http://foo.com") and then I can use some-url where I want

20:35 I'm just wanting to do something similar in the repl where I'm instantiating (if that is the right word) a record

20:35 rhg135: def...

20:35 cark: (def some-url "sdfsdf")

20:36 elarson: geez... I feel really dumb now

20:36 devn: elarson: s'cool man

20:36 rhg135: lol

20:36 devn: happy def'ing

20:36 elarson: thanks for pointing out the obvious :)

20:36 devn: elarson: if you think that's cool, wait until you see defn! ;)

20:37 rhg135: or defmacro

20:37 devn: rhg135: i have something for you!

20:37 err sorry

20:37 elarson: i have something for you!

20:37 rhg135: phew

20:37 elarson: devn: man seriously. I thought I was liv'n large with a defrecord and my defns

20:37 devn: elarson: http://hyperpolyglot.org/lisp

20:37 that might help you out if you're familiar with another lisp

20:37 technomancy: devn: no don't do that

20:38 devn: technomancy: haha, oh come on

20:38 technomancy: hyperpolyglot is rubbish

20:38 no seriously

20:38 it exhibits a very superficial understanding of everything but the CL/Scheme differences

20:38 devn: technomancy: i take your point, but it still can be useful if you're totally trying to hack something together

20:39 technomancy: it's very misleading

20:39 devn: like in this case he could have searched the page for setq, and then could see def in the same column

20:39 granted it's under "last butlast", but still

20:39 elarson: technomancy: my only real lisp experience is elisp and little cl by way of stumpwm (so very little)

20:39 technomancy: setq is totally different from def though

20:39 case in point

20:39 devn: technomancy: okay okay ill give you that

20:39 elarson: technomancy: it didn't load for me anyway ;)

20:40 devn: technomancy: i've used it when i knew absolutely nothing about a language and needed to just make someone's janky script work. it's done its job in that respect.

20:41 technomancy: ok, the arithmetic/logic stuff is decent

20:41 devn: doing the /right/ thing in that script? the idiomatic thing? maybe not.

20:41 technomancy: but as soon as you venture into stuff that just doesn't exist in CL, it tries to find something that looks vaguely similar in clojure and shoehorns it into there

20:42 devn: it uses (seq (.split "foo bar baz" "[ \t\n]+")) for split

20:42 :\

20:42 technomancy: hm; actually this has changed since I read it

20:42 it's a lot longer, and it used to not cover racket

20:42 devn: well, it's still not perfect

20:43 technomancy: maybe they've gotten rid of the really egregious stuff

20:43 devn: I see (String/format) in the clojure column

20:43 they include next in the cdr column

20:43 rhg135: awesome site btw xD

20:43 technomancy: yeah, this is not knee-jerk cringeworthy bad like it used to be

20:44 * devn wipes sweat

20:44 hiredman: http://hyperpolyglot.org/computer-algebra is kind of funny "select About Mathematica in Mathematica menu"

20:44 technomancy: actually looks kinda decent

20:44 devn: sql/awk/pig is kind of neat

20:47 hiredman: well, the real problem is, how does this matrix show you that clojure makes a large distinction between the local environment and the global environment, where other lisps don't make as large a distinction

21:04 technomancy: hiredman: right, it's like Google Translate; it'll sort of get the point across in an awkward way, but it'll never sound like a native speaker

21:08 hiredman: the news here in seattle is showing you things you might want to do if you fly to newyork for the super bowl in new jersey

21:10 quizdr: Seattle! nice.

21:10 hiredman: haha, whoops, wrong channel

21:10 quizdr: hiredman no worries

21:28 Kuollutrunkkau5: hiredman, do you still love me?

21:29 Bronsa: soo. I just loaded with success tools.reader with tools.analyzer.jvm :)

21:30 bbloom: Bronsa: before i get excited, let me see if i parsed that correctly

21:30 Bronsa: bbloom: I compiled tools.reader with tools.analyzer.jvm

21:30 s/analyzer/emitter

21:30 derp.

21:31 bbloom: Bronsa: haha yeah i was gonna ask if you meant emitter :-)

21:31 Bronsa: pretty freaking awesome

21:32 Bronsa: i'm wondering what your jvm assembler toolchain looks like....

21:32 * bbloom peeks at code

21:33 Bronsa: bbloom: yeah. also pretty fast compared to what I were expecting. Only ~6x slower than Compiler.java

21:33 bbloom: Bronsa: why did you expect it to be so slow?

21:34 oh you're still using objectweb.asm directly

21:34 cool, so it's more or less a direct port from compiler.java?

21:34 dnolen: Bronsa: that's pretty cool :)

21:35 Bronsa: bbloom: the bytecode emitted is really similar, yes

21:36 bbloom: Bronsa: why do still need all the interpreter goo?

21:36 Bronsa: bbloom: what do you mean?

21:37 bbloom: Bronsa: all the -exec methods are interpreting the ast, right?

21:37 Bronsa: oh no. they are interpreting the data rapresentation of the bytecode built.

21:37 See https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/emit.clj

21:38 bbloom: oh, ok, i see the distinction....

21:38 but why do you need *that* :-)

21:38 is it actually doing the work?

21:38 or just recording it to the output?

21:39 Bronsa: by "*that*" do you mean -emit or -exec?

21:39 bbloom: the -exec

21:40 it's not actually executing right, it's just writing to the output buffer?

21:40 Bronsa: yes

21:40 bbloom: ok, that makes more sense. name confused me a bit, but makes perfect sense now

21:40 Bronsa: -emit builds the bytecode, -exec emits it

21:40 bbloom: and now that you wrote that ^^ you see my confusion :-)

21:41 Bronsa: ... yeah. It's probably better to s/emit/build/ I guess

21:42 bbloom: naming things is hard generally, it's extra hard in compilers/runtimes when everthing has a generic name and has two different names depending on which layer you're operating at lol

21:42 in theory, you are in fact executing a DSL that is a byte code emission DSL

21:42 :-P

21:43 Bronsa: I'll think about renaming those.

21:43 bbloom: looks like some good stuff though man

21:43 great work!

21:43 Bronsa: Anyway, I really need to sleep now. almost 4am again.

21:44 bbloom: also, looking at it more, i now see exactly why you expected it to be slow: lots and lots of intermediate data structures :-P

21:44 Bronsa: yeah

21:44 but it's too easy to generate the bytecode like that to do it in another way

21:45 bbloom: Bronsa: surely you should use Factjor

21:46 [:dup-x2] [:jump-insn :IF_ACMPEQ ~fault-label] [:pop] would become dup-x2 IF_ACMPEQ fault-label jump-insn pop

21:46 much less garbage :-P

21:46 also, don't actually use Factjor

21:46 :-)

21:46 rhg135: my eyes "P

21:46 :P*

21:46 grr

21:48 bbloom: Bronsa: one thing that is interesting though is how much it uses syntax-quote

21:48 the syntax-quote implementation produces really naive concats

21:48 Bronsa: bbloom: I actually like writing [[:foo ..] ..]. might be stockholm syndrome

21:49 bbloom: that's why I'd expected it to be *much* slower with all those apply/concat

21:49 bbloom: Bronsa: you should experiment with a (doseq [... (flatten ...

21:49 Bronsa: just say that seqs (not vectors) get spliced in and then flatten at the top level

21:49 might speed it up quite a bit & clean up the syntax too

21:51 Bronsa: there's definitely a lot to do perf wise in both t.a and t.e. Right now I'm just trying to make everything work as easly as possible

21:51 btw, I really need to sleep now. bye!

21:52 bbloom: Bronsa: do you actually need any quoted symbols ever? or do you always unquote?

21:52 Bronsa: gnight

21:52 but if you always unquote, definitely try eliminating the syntax quoting :-)

21:52 Bronsa: bbloom: no quoting actually needed. it's all vectors/keywords/strings/classes

21:53 bbloom: Bronsa: yeah, then you can probably mechanically eliminate `, ~, and ~@, then just add a flatten to the top level

21:53 would be a huge perf & readability improvement

21:54 Bronsa: I'll try that in the next days, thanks for the feedback.

21:54 bbloom: cool. good stuff man

21:54 get some sleep :-)

21:54 Bronsa: thanks, bye

22:13 akhudek: for libraries, is the right thing to leave clojure out of the dependencies?

22:23 elarson: would someone mind clarifying why this happens? https://gist.github.com/ionrock/8661766

22:23 akhudek: elarson: map is lazy

22:23 elarson: effectively I'm doing (map println '(1 2 3 4)) and rather than seeing 1\n2\n3\n4\n I see what is in the paste

22:24 akhudek: I'm not sure why that would inject those nil's then. do you mind explaining?

22:25 akhudek: https://www.refheap.com/28630

22:25 when the reader tries to print the output if forces it to be computed at that time

22:25 elarson: ah ok

22:25 that is mixing the output with the newly created sequence

22:25 akhudek: thanks!

22:26 akhudek: you're welcome

22:48 eraserhd: I feel like I'm missing something about deftype.. If I use (ns foo) (deftype Foo ...), then I should later be able to do ^foo/Foo x, right?

22:49 Does this require AOT compiling?

22:49 noonian: i think you might have to use import to bring it in, not sure

22:49 hiredman: eraserhd: don't use deftype

22:50 use a map

22:50 eraserhd: I'm pretty sure that's not a good idea for what I'm doing. (I'm implementing a binary tree variant.)

22:52 hiredman: eraserhd: {:left … :right … :value …} once you have done it that way, if you profile it and it isn't as fast as you want, or if it uses more memory than you want, start using defrecord, and then if after profiling defrecord it isn't fast enough, then deftype

22:57 gfredericks: haha hyperpolyglot does not think that clojure has not=

22:58 tbaldridge: eraserhd: yes, you have to import the deftype, and you don't need AOT

23:01 hiredman: tbaldridge: did you read his question?

23:02 eraserhd: you don't type hint that way

23:03 gfredericks: you don't?

23:03 hiredman: eraserhd: foo/Foo is a clojure name, a namespace qualified symbol

23:03 gfredericks: oh hright

23:03 hiredman: eraserhd: typing hinting is about host types, in this case the jvm

23:03 the jvm classname is foo.Foo

23:04 eraserhd: as the only person who took the time to read through your question and see the real error, I suggest following my advice and sticking to maps, vectors, sets, seqs

23:06 tbaldridge: still suggesting someone not use deftype to implement a binary tree is a bit off IMO.

23:06 eraserhd: frustrating in fact.

23:06 hiredman: tbaldridge: deftype is just not something I would recommend to a novice clojure programmer in any case

23:07 eraserhd: maps seem like a better idea for prototyping, honestly, and so I'm switching on that account.

23:08 noonian: unless you just want to learn about how deftype works

23:09 eraserhd: but I still need to solve the original problem.

23:09 socksy: I have a list of maps from symbol to number ( [{symbol -> number}] ) — what's the most idiomatic way to get the symbol relating to the number found by (max (vals map))?

23:09 err, not max vals map, but the english equivalent

23:09 gfredericks: socksy: it's not clear what (max (vals map)) means since you have multiple maps

23:10 hiredman: noonian: deftype has so many rough edges around it and how it interacts with other features by the time you start fiddling with it, to deal with those issues when they arise in your projects you better already know clojure and have some experience working with it and the tools you use with it

23:10 gfredericks: socksy: or does each map have one entry?

23:10 socksy: each map has one entry, but that's potentially easily changeable

23:10 using for to construct the list, not really sure the best way to go about doing this

23:10 hiredman: ,(doc max-key)

23:10 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

23:11 devn: (inc hiredman)

23:11 lazybot: ⇒ 34

23:11 eraserhd: So I'm just crazy that I can't (:import '[other.namespace DeftypeThingy])?

23:11 gfredericks: that's the quote-or-not ns vs function confusion

23:12 hiredman: eraserhd: there are a couple things, a. :import is just a keyword outside of the ns macro

23:12 noonian: you should be able to, but if thats in a ns form you don't have to quote the vector

23:12 hiredman: b. outside of the ns macro you just import

23:12 eraserhd: Right. I didn't quote it.

23:12 hiredman: c. inside the ns macro with :import you don't need to quote things

23:12 d. you need to load the namespace that defines the type first

23:14 eraserhd: Oh, crap. Because ns declarations are order sensitive.

23:15 Now I understand.

23:15 (I was importing before requiring)

23:16 hiredman: basically, don't use deftype, you're gonna have a bad time, at least use defrecord, and the factory functions and keyword accessors

23:17 tbaldridge: *grumbles about telling people to use the wrong tool for the job *

23:17 hiredman: tbaldridge: then make tools they won't stub their toes on

23:18 technomancy: anyone actually qualified to use deftype is smart enough to ignore advice telling them not to

23:18 hiredman: you want a production quality binary tree, sure, you'll want deftype, but if you are creating a binary tree as a my first clojure project, don't use deftype

23:19 devn: i want a production quality turing ball pit

23:20 hiredman: deftype is just not a good intro to the language

23:21 technomancy: speaking of the wrong tool for the job, someone should show tbaldridge how /me works =D

23:21 tbaldridge: yeah, sorry, I'm not very good with chat programs from the 90's

23:21 hiredman: ~gentlemen

23:21 tbaldridge: :-P

23:21 clojurebot: You can't fight in here. This is the war room.

23:24 eyepatch: Project Euler 3 spoilers: http://ideone.com/6vSlaN The code works for small numbers, but is *way* too slow to work for large numbers. I understand how exponentially this grows as the number grows.

23:25 But, I'm having difficulty coming up with an idiomatic alternative without turning imperative.

23:26 I understand that prime? only cares if there's a single result, but this will get all of them.

23:27 That should be a *huge* reason for the slowness.

23:28 ooh idea.

23:29 tutysara: starting a toy clojure web project, like to what what stack people use in their projects

23:29 eyepatch: feel free to spoil it for me.

23:30 deadghost: what what

23:31 tutysara, http://i.imgur.com/8Dv3vst.png

23:31 something I'm working on

23:31 compojure + enlive

23:32 and libnoir

23:32 tutysara: ohh cool

23:33 deadghost: hiccup or another html lib might be a better choice than enlive

23:33 tutysara: is it available for us to use

23:33 deadghost: enlive is a bit difficult to use

23:33 tutysara, not yet

23:33 technomancy: hiccup is great!

23:33 hiredman: eyepatch: generally for euler problems the trick is to apply more math reasoning upfront

23:33 deadghost: I'm learning clojure webstack so I'd want to clean it up a bit

23:34 tutysara, do you have a project in mind?

23:34 eyepatch: hiredman, there's quite a few of these that can be solved with a calculator. I'm using euler as a starting point to feel my way around clojure.

23:34 tutysara: I find enliven more easier than generating html using hiccup

23:34 eyepatch: I've already solved all of these in golang. I figure if I can write the code to solve it in golang I should be able to do so in clojure.

23:35 I'm not expecting to do it faster, only more readable, and within a minute.

23:36 tutysara: I mostly did backend work and I am more comfortable taking a html page from some boilerplate code and replace elements in it :)

23:37 deadghost: I know about luminous and recently came across gizmo

23:37 hiredman: eyepatch: you should be able to implement the same algorithm then, euler in clojure is kind of neat because you can have infinite lazy seqs, but it isn't like lazy seqs are super fast

23:38 eyepatch: hiredman, sure, I could write an imperative algorithm, but then I might as well work in an imperative language.

23:38 I'm looking for something a little more readable.

23:39 tutysara: deadghost: did you know about gizmo, they use enlive as well

23:39 eyepatch: and Clojure does not make mutability very readable.

23:39 deadghost: tutysara, nope looking it over right now

23:41 hiredman: eyepatch: the first thing you can do, is since you are looking for the largest, is generate factors in reverse, the next thing is there is a possible upper bound, both of which limit the search space

23:45 tutysara: deadghost: give me you thoughts after see it, they compose pages from widgets and generate widgets by associating html snippets and data

23:45 eyepatch: hiredman, worst case would be 38. Where the largest prime is 38 / 2 = 19. So I only need to look for primes up to half.

23:46 Since I'm processing the whole list, order doesn't really matter.

23:47 I'm trying to figure out a way to not process the whole list.

23:49 deadghost: hmm tutysara I haven't looked into either thoroughly

23:50 but luminius is written by the author of the clojure web dev book I'm reading

23:50 and seems very loosely coupled

23:50 and aims for getting boilerplate out of the way

23:51 tutysara: deadghost: yes, I too have a copy and have been reading it :)

23:51 deadghost: gizmo seems tighter coupled than I'd like, gizmos seem interesting but aren't they just enlive snippets?

23:52 err *widgets seem interesting

23:58 tutysara, I'd go with luminus if I had to choose a microframework

23:58 mostly because gizmo seems pretty opinionated

23:59 egghead: when did all these clj frameworks start appearing

23:59 deadghost: and I'd want to have enough experience to know whether I agree with these opinions before using it

Logging service provided by n01se.net