#clojure log - Dec 07 2013

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

0:00 bbloom_: seangrove: code academy is awesome too. our big differentiator is simply that we use blockly, so there is no typing required

0:00 also, we have angry birds. c'mon now, everybody loves angry birds

0:01 seangrove: bbloom_: Sure sure, just trying to categorize it so I know when it's appropriate to recommend

0:01 bbloom_: if you go to hourofcode.com/co you'll be able to categorize it rapidly

0:01 that dumps you right in to the tutorial

0:03 seangrove: bbloom_: Wow, very polished looking. Is there a legitimate curve to programming more abstract/low level??

0:03 lazybot: seangrove: What are you, crazy? Of course not!

0:03 seangrove: woops, just one ?

0:05 bbloom_: seangrove: the "hour of code" tutorial covers basic while loops and if/else conditionals. the extended "20 hour" curriculum we offer has for loops, subroutines & parameters, etc

0:07 isn't it funny how lazybot can condition us not to use too many question marks??

0:07 lazybot: bbloom_: Definitely not.

0:07 seangrove: bbloom_: This is pretty awesome, very impressive. The coolest hello world I've ever seen.

0:08 bbloom_: seangrove: thanks! i'll pass "coolest hello world" on to the rest of the team, they'll like that :-)

0:08 seangrove: Heh, Zuckerberg looks a bit uncomfortable a few times through the video

0:09 bbloom_: seangrove: frankly, i'm impressed by the delta in his perceived comfort level over the years

0:09 seangrove: bbloom_: I remember seeing this block-like system awhile ago, is it out of MIT?

0:10 bbloom_: seangrove: MIT is best known for Scratch. the 2.0 version up at http://scratch.mit.edu is all flash & is pretty cool stuff. great free-form thing. highly recommended that students try it out after our stuff, which is linear

0:10 seangrove: however, our tutorials are build w/ google blockly: https://code.google.com/p/blockly/

0:10 seangrove: which is html/svg/closure (note: no j, sadly)

0:10 seangrove: bbloom_: Ah, ok. Kind of feel like this would be pretty awesome on the ipad as well. May just be the angry birds talking though.

0:11 bbloom_: seangrove: i'm a little out of the loop on our devices support story, but iirc we're totally ipad compatible

0:14 sorry for the advertising, i'm just excited/proud :-)

0:14 seangrove: bbloom_: Not sure this is a bug or not, I could just be thick https://www.dropbox.com/s/4wqsyr38j9zuh7q/hourofcodebug.mov

0:14 bbloom_: Definitely something you could be proud of. I like this kind of civic project.

0:14 bbloom_: seangrove: that's not a bug, but it is a known usability shortcoming

0:15 seangrove: some levels have fixed/required blocks

0:15 they just aren't visually differentiated :-/

0:15 seangrove: bbloom_: Ok, that's fine. Thought it was either that or a bug.

0:15 clojurebot: I don't understand.

0:15 bbloom_: clojurebot: you wouldn't

0:15 clojurebot: Excuse me?

0:18 maravillas: bbloom_: this is great, thanks for sharing

0:19 bbloom_: maravillas: thanks, my pleasure :-)

0:20 maravillas: i've been doing some scratch with my son, but i think i dove in a little too fast...some of these look like better starting points

0:21 bbloom_: maravillas: yeah, i was volunteering teaching scratch to some middle school kids here in NYC & it was just too much stuff. it's overloading. i love scatch, but about half way through the course i had some kids beta testing our tutorials & holy crap, it's like having a team of spare teachers plus a room full of baby sitters at the same time :-)

0:25 maravillas: yeah, it seems like having directed goals plus the components already in place would help a lot, and let you get to the meat without having to fiddle around with the incidental sprite stuff first

0:26 bbloom_: maravillas: yup. scratch needs like a complexity slider :-)

0:27 maravillas: it's like in games when you get a new weapon or there is a new enemy type. they introcuce them one at a time, and there is some dialog, and you get presented with an immediate use case for your new capability

0:27 works great

0:27 but when it's time to fight the boss, you gotta figure that shit out w/ the tools in your toolbox!

0:27 maravillas: yeah, good analogy

0:44 technomancy: bbloom_: good luck with the launch!

0:45 the limited toolbox aspect actually reminded me of The Incredible Machine

0:45 and it makes me really disappointed that there's no OSS remake of it; come on guys

0:49 musicalchair: bbloom_: this angry birds tutorial is good stuff!

1:06 jph-: musicalchair: link?

1:07 musicalchair: jph-: http://code.org/ click start

1:07 scroll up for more discussion ^^ =)

1:08 jph-: musicalchair: is it cloj?

1:08 musicalchair: jph-: no

1:08 jph-: oh this is what happened with this stuff

1:08 cool

1:12 seangrove: Oh, damnit, I did something interesting in emacs, hit c-g, tried to look up the binding I hit, and it was something else

1:12 technomancy: How can I find out what binding/command I invoked?

1:13 * seangrove invokes the technomancy

1:13 andyf: C-h l for history of keystrokes?

1:13 lemonodor: C-h l

1:13 seangrove: andyf lemonodor: thank you, found it!

1:18 nonuby: could this http://stackoverflow.com/questions/20437767/what-happens-to-second-println-statement-clojure-repl/20438112?noredirect=1#comment30532129_20438112 be down to optimizations on server vm / 64 bit?

1:35 bellkev: does anybody know of anything like a generic leiningen "watch" plugin?

1:35 It seems like cljsbuild has most of the makings of such a thing with its "crossover" utilities... it seems like it could be handy to turn it into a separate file-watching plugin...

1:41 seangrove: bellkev: I thought someone just announced that...

1:42 bellkev: are you thinking of lein sync? because that looks like it's something else at first glance...

1:43 john2x: um, can I use .clj library in a cljs project? Or I'd have to make a port of the clj library?

1:43 seangrove: bellkev: Oh, no, I'm looking through the ml now

1:43 bellkev: https://groups.google.com/forum/#!topic/clojure/iXA49B-n1oA ?

1:45 bellkev: oh, cool

1:46 thanks, seangrove, I'll give it a look

1:46 seangrove: bellkev: Hope it works out!

1:46 bellkev: also, while I appreciate the creative names in the clojure community, I would have found this right away if it was called lein-watch and on the plugin list :P

1:47 But it looks like it's too new to even be on the list yet

1:47 but anyway, thanks again seangrove!

1:47 seangrove: well, technomancy immediately asked the author to put it on the list, heh

2:22 jph-: any incanter wizards? im trying to view a time series chart, but one axis data is in range of 0.000x (so it isnt visible)

2:22 is there a scale or range option for charting?

2:34 john2x: what does this error mean in cljs "Uncaught Error: Undefined nameToPath for my_other_namespace.core"

2:36 oops, typo (ns ...) in my_other_namespace

2:46 bitemyapp: seangrove: ML modules are nice.

2:49 I actually imitate them with protocols sometimes. So does Sierra.

3:19 jarodzz: hi, guys

3:19 any one using pedestal?

3:30 bitemyapp: jarodzz: not many, but some have good use cases for it. What's yours?

3:49 jarodzz: :bitemyapp i'm still trying to understand the concept

3:50 :bitemyapp not yet put it into a real case

3:50 but glad to know there's some one using it

4:03 john2x: do I need to sign the CA to request changes on a github wiki entry?

4:05 apparently the `format` fn doesn't exist in cljs.. I think it deserves a mention in this page https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure

5:37 bitemyapp: jarodzz: you probably want luminus if you just want to make web apps in Clojure.

5:38 jarodzz: :bitemyapp thanks for the suggestion, man. i want to create some thing with clojure as a learning process

5:39 bitemyapp: i'm still trying to figure out concepts like atoms, refs

5:39 bitemyapp: thanks for the suggestion man

5:42 cYmen: Sometimes I feel like the entire variable amount of arguments thing is crap.

6:31 wei__: how do I cast a Clojure biginteger to java.math.BigDecimal? any dangers in doing so? (this is for Postgres compatibility, in case that matters)

6:35 TEttinger: ,(doc bigdec)

6:35 clojurebot: "([x]); Coerce to BigDecimal"

6:35 TEttinger: ,(bigdec 11111111111111111111111111111111111111N)

6:35 clojurebot: 11111111111111111111111111111111111111M

6:35 TEttinger: wei__: ^

6:36 wei__: oh, very good. thanks TEttinger

6:36 TEttinger: no prob

8:25 echo-area: Is khinsen on github the same people on http://dirac.cnrs-orleans.fr/plone/Members/hinsen?

8:26 (The people who write clojure.algo.monads)

8:26 *writes

10:59 S3thc0n: Hello #clojure! I found a new love to spend Christmas with :D

10:59 llasram: Is it Clojure?

10:59 S3thc0n: Yes! It is amazing!

11:00 andyf: Have you treated yourself to a Clojure book as an early Christmas present yet? I recommend getting one.

11:01 S3thc0n: Not yet, but I've played with the thought. Anyone you would recommend for someone new to FP, btu still wanting a quite extensive one?

11:02 I have an OO background (first language was C++), and Clojure has this inherent beauty I've always been missing. It's more than a tool.

11:02 andyf: Check out Clojure Programming by Emerick, Carper, and Grand on Amazon, or O'Reilly's web site. Should be able to peruse the table of contents, at least, if not a sample chapter.

11:03 S3thc0n: Thanks!

11:03 andyf: e.g. here is O'Reilly's listing, with the ability to browse contents: http://shop.oreilly.com/product/0636920013754.do

11:04 pdk: it's not lisp related but if you want to learn fp in general there are free books on haskell and erlang too

11:05 S3thc0n: I think I'll stay at Clojure first except for concepts (where it doesn't matter what language is behind it); else it could get a bit confusing.

11:07 pdk: yea

11:07 clojure is also a bit of a far cry from "traditional" lisp in a few respects

11:07 so if you took both concurrently i imagine there'd be some wires getting crossed

11:07 S3thc0n: Yeah, that is what I am concerned with.

11:08 I've watched an explanation by Brian beckman on Monads today, and wanted to know if I have understood it properly: In it's essence it just prepares data for another function? And what does that have to do with side effects?

11:09 pdk: oreilly also has a book available

11:09 functional patterns in scala and clojure i think

11:09 scala is the "other" big functional language on the jvm right now

11:10 S3thc0n: Yeah, I noticed it first as it attracts a bit more attention, but decided that Clojure seems to fit better to my way, so I'll learn that first.

11:10 andyf: S3thc0n: I don't understand monads well enough to risk trying to teach someone else about them, but I will mention that although some Clojure programmers understand and use them, you can get work done without monads, and most Clojure code I've seen doesn't use them.

11:10 S3thc0n: Oh, well then I don't have to force my head around them for now. Thanks for the clarification :)

11:12 andyf: S3thc0n: I'd like to grok them some day more fully, but it isn't high on my priority list of things to do at the moment. Clojure programmers tend to write lots of pure functions, but then call them from functions that do modify state explicitly.

11:12 Ideally with the state modification code fairly well contained in a relatively small fraction of the code.

11:14 S3thc0n: AM I right when I think that you face the very same problems you have avoided internally by not having mutable state as soon as you start interacting with something like a database which uses locks?

11:19 justin_smith: S3thc0n: a lock is how something mutable can pretend it has some consistency

11:20 if anything the part where it has locks is helpful

11:21 and since immutibility makes async easier, you can use async to make the locks invisible (except so far as they affect timing / performance - but those should not be first class things you have to deal with in your code, just side effects of a design)

11:31 S3thc0n: Ok, I have one more question. Does a clojure have any purpose apart from saving you from needing to keep the arguments for a function that would do the same somewhere?

11:31 Closure I meant. oop.s

11:36 andyf: S3thc0n: I am not sure if this is an example of what you are asking about, or a different reason to use closures, but they are very convenient when locally defining a function to be passed to another function like map, mapcat, filter, etc., and you want that function you write to refer to values in the environment where the map/filter/etc. call is.

11:37 An example would clarify that statement, I think.

11:37 WWWest1: S3thc0n: that's the main point, it makes it easier to create functions on the fly for your program while keeping a consistent state

11:37 S3thc0n: I get it like that, thanks!

11:39 So I said 'any purpose apart from ', but actually it solves my main concern with functional languages yet, namely being forced to pass around every little thing as argument.

11:48 justin_smith: S3thc0n: a full object system (inheritance, multimethods, etc. etc.) can be constructed out of closures - they are extremely powerful

11:48 of course given that our base language is the jvm we don't have to do that

11:49 S3thc0n: Wouldn't that kind of defeat he point of immutability?

11:52 newblue: S3thc0n: a closure can be a nice place to quarantine state. Unfortunately (or fortunately) we can't *always* be stateless

11:53 justin_smith: S3thc0n: you can replace an object instead of mutating, also

11:53 S3thc0n: justin_smith. That is what I thought it is commonly done like.

11:53 andyf: S3thc0n: When people are taught the Scheme programming language, closures are often used to show how to create private mutable state, similar to objects in many other languages. It isn't often used in Clojure, because the JVM has mutable objects already.

11:54 S3thc0n: So using JVMs built in objects is preferable to using clojures for 'emulating' objects?

11:55 justin_smith: mostly

11:55 maybe I did to much scheme programming, but sometimes it is a natural fit

11:55 newblue: andyf: you got me! that's where I learned about closures and how I approach them - never gave much thought to using interop instead

11:56 andyf: newblue: There is nothing wrong with using that technique in Clojure -- I just haven't seen it very often used. That particular sharp-edged tool is there in the toolbox, though.

11:59 justin_smith: it is the yin to the yang of writing procedural code where you repeatedly rebind the same symbol in a let binding block

11:59 ,(let [a 0 a (inc a) a (* a a)] a)

11:59 clojurebot: 1

11:59 justin_smith: bad example

11:59 ,(let [a 1 a (inc a) a (* a a)] a)

11:59 clojurebot: 4

11:59 newblue: andyf: I just don't know Java that well so I avoid interop when I can since debugging it is really scary

12:00 justin_smith: interop is easier to debug eventually - because stack traces and errors are presented in terms of the jvm version of reality, rather than the clojure version

12:00 but you need to grok the jvm's concept of things a little before that works

12:01 what trips me up is the interaction of laziness and stack traces - your code order in the stack does not really reflect the order in the file sometimes...

12:04 newblue: justin_smith: having the stack traces make more sense is an enticing benefit...

12:05 wei__: trying to use tools.namespace: (use '[clojure.tools.namespace.repl :only (refresh)]) and getting FileNotFoundException: Could not locate clojure/tools/namespace/repl__init.class

12:06 justin_smith: newblue: it is also partially a fluency thing - you read them more, they make more sense

12:06 I remember when I would see one and my eyes would glaze over - I would get no information out of the huge mass of spew

12:07 wei__: how are you declaring the tools.namespace dependency?

12:08 wei__: justin_smith: :profiles { :dev {:source-paths ["dev"] :dependencies [[org.clojure/tools.namespace "0.2.4"]]}

12:08 in project.clj

12:08 justin_smith: if you run lein classpath, do you see clojure.tools.namespace in the output?

12:10 wei__: interesting, yes but it's pointing to 0.1.3. is the dependency version getting overwritten somewhere?

12:10 justin_smith: lein deps :tree

12:10 see what is pulling it in

12:10 add an :exclusions clause

12:11 wei__: hmm, lein deps :tree gives me: Consider using these exclusions: java.lang.NullPointerException

12:11 justin_smith: lol, it would be good to exclude that, huh

12:11 there is also mvn deps:tree

12:12 wei__: no reference to tools.namespace though

12:13 justin_smith: mvn deps:tree also errors with "No plugin found for prefix 'deps' in the current project"

12:13 justin_smith: sorry, wrong command

12:13 mvn dependency:tree

12:13 that one works (just verified)

12:15 wei__: looks like ring is the culprit? https://gist.github.com/yayitswei/7845544

12:15 justin_smith: so you can do [ring "1.2.0" :exclusions [org.clojure/tools.namespace]]

12:16 or something similar to that syntax

12:16 yeah, that's the syntax

12:16 or maybe use a newer ring, while you are at it

12:20 wei__: ah, thanks

12:20 btw I found the source of the NPE, lein deps :tree seems to break when there are duplicates in dependency vector

12:21 justin_smith: interesting

13:51 wei__: I'm suddenly getting this exception when calling "lein run": Exception in thread "main" javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial.

13:52 anyone seen something similar before?

14:23 sveri: hi, i set up a cljs project with leiningen, now when i run lein cljsbuild auto it retrieves a lot of jars, but then hangs on: Retrieving clj-stacktrace/clj-stacktrace/0.2.5/clj-stacktrace-0.2.5.jar is there anything wrong with this? i tried this already some hours ago from another internet provider and it hang at the same place, i never seen this happen

14:33 lvh: Hello! I've got a tiny little project I'd like to try to get my feet wet with in Clojure. I've got an SVG Christmas card envelope, and a bunch of addresses in CSV. I guess what I want after that is obvious :) Should I create a lein project for this?

14:33 It seems that's what everything starts with

14:33 seangrove: lvh: Definitely

14:34 lein new my-project, find a library to handle svg and add it to your project.clj under :dependencies, start up `lein repl` and you're off!

14:34 thieman: lvh: There are also some specific lein templates that you might want to use, for example if you want to start a project using Compojure you could `lein new compojure my-project` to start a project with the right dependencies

14:35 lvh: Ah, okay.

14:35 For SVG I was just thinking of using an svg parser.

14:36 Essentially I just need to change the text of "#address tspan" (to use CSS selectors)

14:36 I'm guessing there's no particular kind of lein template for this?

14:37 arcatan: sveri: cljsbuild auto does not say anything when it's waiting for the source to change, so if that's the last message, then it might be just waiting for you to do some changes in your cljs

14:37 thieman: Probably not, but you might look into the library enlive for modifying the SVG. Lets you transform parts of the document based on CSS-like selectors, at least for HTML. Not positive it works for SVG.

14:37 sveri: arcatan: that makes sense

14:37 emaphis``: sveri: try [clj-stacktrace "0.2.7"], I just downloaded it to a dummy project and it worked.

14:37 sveri: i got it working now

14:37 i cleaned the .m2 folder

14:48 justin_smith: lvh: http://liebke.github.io/analemma/ analemma is good for making svg out of clojure data structures

14:48 you can use clojure.data.xml to do the converse

14:48 lvh: justin_smith: Yeah, I was gonna do that. I already have an SVG.

14:48 I basically just want to fill it with data from a CSV file.

14:48 justin_smith: it may be easier to use a templating library in that case

14:48 lvh: the SVG already has proper tag ids, so I just have to grep for #address tspan, #name tspan, etc

14:49 justin_smith: analemma is good for if you want to use a data structure to generate the svg from scratch

14:49 well if you use clojure.data.xml you don't need to grep, you can look up the tags in the data structure, do the modification, then turn it into xml again

14:49 svg is just a kind of xml

14:50 amacdougall: Curious about testing. I've got a Clojure/ClojureScript app. I want to run functional tests on the CLJS side. Since I want it to have a fixed set of test data, it seems like I should strike at the very root, and replace the server-side "db" namespace with something that returns stuff from files instead of the database.

14:50 Basically I want to run the server-side app in a different mode which has a different code path. I'm just not sure of the most straightforward way to do that.

14:51 justin_smith: amacdougall: one option is to refactor so your "interface" (the part that interacts with the data source) is as thin and trivial as possible, and the rest is all simple pure functions

14:52 then you can test those functions with the inputs you know they will get

14:52 and have a couple of simple tests for the data gathering stage

14:53 amacdougall: I'm not so concerned with testing the db access functions themselves -- I'm looking for a dead-simple way to enforce a static data set for the client-side tests.

14:53 cprice404: hey, anyone know whether there are restrictions on what characters can be used in function / method names when using `proxy`?

14:54 amacdougall: justin_smith: The client side just makes API requests. /api/v1/users/1 and so on. Obviously I could mock things at the client side instead, but changing the functionality of the server-side db functions seems even simpler.

14:54 justin_smith: amacdougall: so make the functions so they don't rely on the db, and call them with data structured in the way you expect

14:54 cprice404: i have a protocol that has a function name with a dash in it, and it seems like it might not be possible to define that function inside of a `proxy` call

14:55 justin_smith: unless your db layer is untrustworthy, why test db access? just call your code with the data the db will return

14:55 amacdougall: justin_smith: I think I get you. Maybe what I'm really asking is how to run my app in a test mode which has the different behavior.

14:56 Step One: Understand Thy Own Question.

14:56 justin_smith: amacdougall: my way of doing it is not to run the app, but to run the individual fucntions and verify their output

14:57 amacdougall: if you design in an fp style this is easy, and if it is hard to do that, it is a sign you could make your codebase more functional

14:57 but that's just how I prefer to do it, there are probably other good ways to do this, like with-redefs or making something that implements the right protocol (test stub) but I think that stuff gets weird and more complicated than it needs to be

15:01 amacdougall: justin_smith: The ultimate goal is that on the client side, I test things by simulating user actions. I'm using a JS library called FuncUnit that makes this easy. It loads the entire site, does stuff, asserts a DOM state, closes the site; repeat. I just want to load the site with a static dataset. It's not the data I'm testing -- it's the UI functionality and application flow.

15:02 justin_smith: I might have been phrasing things wrong, or I might currently be misunderstanding your advice.

15:04 I can think of plenty of ways of doing this by changing the main application code -- like checking some test-only constant to decide whether to serve test data, or something. But that seems totally wrong. I might just be stuck in an OO mindset where my first thought is dependency injection.

15:04 "Just replace the db object!" except obviously it's not an object.

15:04 justin_smith: there may be a reasonable way to do that. I avoid full-app mockup testing myself so I wouldn't be able to give good leads about it.

15:04 seangrove: The only place you should be injecting dependencies is behind the dumpster in an alleyway

15:04 coventry: I think justin_smith's suggestion is that you factor out your cljs so that you can simulate the client-side/database events just by passing them in as function arguments.

15:05 amacdougall: seangrove: It's safe as long as I don't share IDEs.

15:05 seangrove: I don't actually believe that, but it sounded vaguely plausible.

15:05 justin_smith: coventry: exactly

15:05 seangrove: amacdougall: Good man.

15:06 amacdougall: Ah, okay, I did misunderstand, then. So basically, put the test-specific functionality at the CLJS level in the first place. That makes sense, since it's the CLJS that I'm testing anyway.

15:06 justin_smith: coventry: amacdougall clearly not the only way to do it, but the only reliable and simple way I have found

15:10 solidus_: can someone recommend some open source projects written in clojure? I want to get a feel to how clojure is used in medium/big projects

15:11 noncom: hi, is there any simple way to make timbre log 2 different sets of information to 2 different files?

15:12 thieman: solidus: Not a great answer for you, but GitHub will point you to some neat projects for a given language. https://github.com/trending?l=clojure

15:12 dsrx: Storm is a pretty massive project

15:13 albeit, mostly written in java i guess

15:15 dnolen: dsrx: a lot of that Java is/was generated according to Nathan Marz

15:15 coventry: solidus: I've gotten a lot out of reading ztellman's code. I wouldn't read those projects to get a sense for how it's used, as their intended usage is a bit out there. But one of his popular ones might be good.

15:16 justin_smith: noncom: https://github.com/ptaoussanis/timbre/blob/master/src/taoensso/timbre.clj#L174 global atom, you could do it but it would be a pain in the ass :(

15:16 coventry: solidus: Maybe aleph or lamina?

15:16 justin_smith: noncom: you could lock the atom, reset! it, log, then restore and release the lock for each call, but that would be a pain

15:17 solidus_: the default caribou template installs a cms capable of building a whole site, so it could arguably be considered a large open source clojure app

15:18 though it is meant to be extended with one's own pages and controllers etc.

15:19 seconding ztellman's projects as good for reading, stuart sierra is another good one for that

15:19 coventry: "those projects" meaning the ones I read, riddley and sleight.

15:22 noncom: yah, looks like no simple way...

15:23 justin_smith: we need a pure functional logger!

15:23 or at least one with lexical bindings for config

15:23 noncom: :)

15:23 andyf_: justin_smith: It has one. identity :-)

15:24 noncom: but maybe i could use a dynamic var to designate the path for the file and create two helper functions with (binding ...) ?

15:24 coventry: "What do you mean it has no side-effects? *I* know it ran."

15:24 noncom: do string values get passed by pointer or value?

15:24 pointer i gueess

15:25 andyf_: noncom: In Java, they are passed by reference (i.e. pointer), but they are immutable, so I'm not sure when it would make a difference between by reference and by value.

15:25 justin_smith: noncom: may be simpler / more powerful to simply replace the global atom with a dynamic var / binding forms

15:26 stack usage?

15:26 devn: good afternoon all

15:26 justin_smith: I don't think passing by value even happens in the jvm world, except maybe for unboxed primitives

15:26 noncom: uhh.. i jut did not want to make any invasive surgery :)

15:26 andyf_: justin_smith: Yes, it would make a difference in time and/or memory usage, but for other kinds of observable behavior, I can't think of a difference.

15:26 justin_smith: right

15:27 noncom: i mean when i designate the file path by a dynamic variable, it will be the pointer, not the value of it, so i can later bind the dynamic var to diferent strings... i guess.... or i'll have to dig inside timbre and redefine some stuff

15:28 justin_smith: yeah, I was trying to suggest forking timbre and changing the definition of config would be simpler than dynamic binding of config vars with the existing timbre

15:28 but that could be wrong

15:29 noncom: oh forking, right

15:33 akurilin: bitemyapp: just fyi I started using xmonad earlier yesterday, pretty cool so far, very spartan. On a side note, Haskell syntax looks super alien right now. I wonder if everybody feels that way at first :)

15:33 seangrove: akurilin: The endless complaints about clojure syntax hints that everyone does...

15:34 akurilin: seangrove: hah yes I know what you're talking about. Every Clojure-related HN post ever has at least a couple of replies saying "now if only the syntax didn't have so many parentheses"

15:35 coventry: They care more about their power-to-weight ratio than their appearance. :-) http://book.realworldhaskell.org/

15:35 noncom: btw, how do you usually format (let) ? do you start the bindings [] on the next line or on the same line?

15:37 akurilin: coventry: is that a good starting point?

15:37 andyf_: noncom: same line always for me, and most code I've read

15:38 noncom: damn...

15:38 justin_smith: noncom: not universally agreed with, but a good starting point https://github.com/bbatsov/clojure-style-guide

15:39 akurilin: oh man, I remember using bbatsov's guide back in my ruby days

15:39 andyf_: noncom: About the only time I've ever seen it on a separate line is when I pprint forms that have been read in, but that is machine-generated.

15:40 noncom: heh :)

15:40 akurilin: it'd be cool if there was one guy out there who was the arbiter of good taste for many key languages

15:41 andyf_: akurilin: There is. It is just so many people disagree with him and don't follow his good taste :-)

15:41 justin_smith: akurilin: this was traditionally the role of the Queen of England, but she has been slacking

15:41 akurilin: andyf_: I haven't followed any conversation regarding his guides, but I imagine anybody in that position would receive a lot of criticism.

15:41 coventry: akurilin: I can recommend the first few chapters, but that's all I've read. That much suffices for casual reading of haskell in CS papers.

15:41 akurilin: justin_smith: :D

15:42 coventry: fair enough. Should suffice if I just want to be able to read it.

15:43 Has haskell syntax changed much over the years or has it been stable for a while?

15:43 coventry: I'm sure you would benefit much more by reading the whole thing.

15:45 I only brought it up because of the bug-ugly bug with the high power-to-weight ratio on the cover. :-)

15:46 justin_smith: the syntax is pretty stable, it is basically a super sugarry ml

15:48 seangrove: coventry: Ah, clever.

15:59 akurilin: coventry: that was deep

16:01 amacdougall: Okay, I've been thinking "what's the simplest thing that could possibly work", and here's what I came up with: the test runner loads the full site with ?test-data=true in the querystring. Initial site bootstrap code detects this and sets a Var in the core namespace. Whenever I call data/GET (a simple AJAX wrapper), the function delegates to test-data/GET if necessary. Finally, test-data/GET compares the URL to a mapping of URL patterns to EDN files i

16:01 This still seems a lot more complicated than necessary.

16:02 Call it "the simplest thing I could think of that could possibly work."

16:02 And it involves adding test-specific code to the main app, which seems like it should be avoidable.

16:03 seangrove: amacdougall: You could probably just make some helpers in your test code runner and clojurescript.test

16:03 (deftest ... (with-mocked-ajax ... (... webdriver-code )))

16:05 (with-mocked-ajax ...) relying on (with-redefs ...) under the hood.

16:05 Hrm, now I'm wondering if with-redefs exists in cljs. Maybe not.

16:07 Ah, the older days, before bbloom_ refused to use confluence and dnolen pretended to read the design docs https://groups.google.com/forum/#!topic/clojure/6cmnkHmHBNw

16:07 amacdougall: clojurescript.test seemed really hard to use for UI testing. Which makes sense. And if it's black-box functional testing, there's no reason not to just use a JS library.

16:10 At work, we're using the same library, but in a Rails environment. Thanks to the efforts of our test engineer, we're able to use Capybara to set up some fixtures, open the test runner HTML using Selenium, wait for results, close it all back down.

16:10 I just don't have the determination or the need to set up something that complex and automated.

16:12 noncom: how do i make concat here work at compile time? (this version does not work):

16:12 (defmacro z [f & args] `(println (apply ~f ~(concat [1] args))))

16:19 coventry: noncom: What's wrong with a simple (defmacro z [f & args] `(println (~f 1 ~@args)))?

16:20 noncom: i think i just complicated it :)

16:22 amalloy: what's wrong with (defn z [f & args] (println (apply f 1 args)))?

16:25 coventry: amalloy: It doesn't teach you anything about how to use syntax quote.

16:26 noncom: i just want to make it execute at compile-time, not everytime during runtime. am i correct that this macro will help with this or not?

16:27 llasram: Nope. Totally wrong.

16:27 dsrx: .wea

16:27 oops wrong window

16:28 bbloom_: seangrove: heh

16:28 noncom: so apply is a function which means it has a runtime overhead?

16:29 doesn't apply have a runtime overhead?

16:29 not the whole function at compile time i mean, but just the application to the passed args

16:30 bbloom_: seangrove: i now have a much much much better understanding of dynamic variables & bindings. i don't think that clojure can possibly get the "right" binding conveyance semantics w/o some way to take a "slice" of bindings up to a marked point in the stack (ie. effect handlers :-P)

16:31 raek: noncom: yes, but you can't use the macro in all circumstances where you could use the function (eg. you can't apply it or use it as a value)

16:32 macros make code less composable

16:32 justin_smith: http://www.chrisstucchio.com/blog/2013/write_some_fucking_code.html an adolescent and foul-mouthed intro to monads

16:33 seangrove: justin_smith: There's also crockford's google talk, where he does it in javascript and makes a lot of strange references to male anatomy

16:34 justin_smith: "Monads are like a dildo factory, staffed by midgets"

16:35 raek: noncom: also, I reckon this particular extra step of indirection won't be the performance bottleneck of your application

16:35 seangrove: justin_smith: I guess that one does win on the strange-meter

16:45 devn: Is there a better way to write this? https://gist.github.com/devn/befc73863d0f6c4a6144

16:51 kilex: I've given myself a toy problem to solve with core.logic: http://bit.ly/19q9V3Y. Any suggestions for improvement?

17:02 also: are there any good examples of the idiomatic use of ex-info?

17:04 noncom: devn: maybe something like (apply merge (mapv (fn [v ks] (reduce (fn [acc k] (assoc acc k v)) {} ks)) {your-map-here})) ?

17:05 also: I have some code that throws IllegalArgumentException, but I'd like it to work in ClojureScript

17:05 justin_smith: also: we have used something similar (but with the slingshot lib) in order to recover elegantly from template rendering errors with an informative message

17:06 noncom: at least something like that would definitely be better than using update-in in such a cae

17:06 s/cae/case

17:07 devn: oh, looks like i have incorrectly read your example.

17:07 so that's not a solution to your qustion

17:09 gdev: updating by hand a project that still uses a ton of contrib libraries is a pain

17:09 I feel like my computer is going to laugh at me tonight because I'm did all of its work

17:10 %s/I'm/I

17:10 devn: justin_smith: that guy is insane

17:11 coventry: justin_smith: LMAO

17:17 gdev: kilex, if it works, ship it

17:23 kilex, actually I'm confused why B1 and B2 have no relation or is it okay for them to come in any order?

17:27 kilex: gdev: that's the point, there's no constraint on their order. It works, but is awfully slow. There must be a better way (with core.logic that is).

17:28 Also, am interested to learn an idiomatic way to express (distinct) in core.logic

17:30 technomancy: also: use ex-info over IllegalArgumentException

17:31 also: yeah, that was the direction i was heading. i was just wondering if there was a usual way of doing that

17:32 llasram: also: The only potentially-non-obvious suggestion I'd have is not to stuff the info map with the kitchen sink. Printing the exception prints the map non-pretty-printed, which can be annoying to sift through if it contains too much

17:34 cYmen: I am trying to figure out 4clojure 121. My first two solutions have been branded evil because the used eval and ns-map. Do I have to create my own map from '+ to clojure.core/+ or is there some other way?

17:36 llasram: cYmen: I haven't looked at a problem, but building a map from keywords or symbols to functions for dispatch is a pretty pattern common

17:36 s,a problem,the problem,

17:36 Er, and "pattern common" / "common pattern"

17:38 cYmen: It is?

17:38 nkozo: there is a way to redirect all stdout to the nrepl repl buffer?

17:38 cYmen: Under what circumstances?

17:40 llasram: cYmen: Well, when you want to dispatch :-). I usually only see people fairly new to Clojure (and usually coming from Ruby) use `ns-map`, `resolve`, etc over manually constructing a map of specific allowed dispatch options

17:40 coventry: I hear it's better style to use multimethods than a dispatch map, but they're almost semantically equivalent in this case and you don't need to learn a new language feature at the same time you're doing this problem.

17:42 llasram: coventry: And I think it does depend on the problem. Definitely multimethods if the dispatch is open, or complex

17:44 cYmen: Hm...maybe I should jump at the chance to use multimethods...

17:44 coventry: I would do it with a dispatch map first and rewrite with multimethods once I had that down.

17:45 But multimethods aren't that much more to keep track of, I guess.

17:56 xpe: I'm looking for a way to run some code only when the :dev profile is active. My use case is enabling Enlive reloading.

17:58 I think I want :init or :init-ns

17:59 but those are only REPL options, best I can tell

18:00 coventry: xpe: I have {:user {:repl-options {:init (load-file "~/.lein/replrc.clj")}}} in my profiles.clj. You might try something like that, with s/:user/:dev/

18:00 xpe: it looks like I have to setup a different entry point, just like Pedestal does with `run-dev`

18:00 coventry: thanks for that idea

18:01 for my use-case, I'll add my function calls into `run-dev` I think

18:02 justin_smith: (when (= (System/getenv "environment") "development") ...) is another way to do it

18:03 but then you have to set the key via env vars

18:03 xpe: justin_smith: also a good idea

18:04 having `(net.cgrand.reload/auto-reload *ns*)` in my production code seems silly. I'll bet others are also thinking about ways of pulling out reloading in production environments

18:05 While we're talking environment variables, I could also set a global. :(

18:05 justin_smith: well, yeah, but it has to come in from somewhere

18:05 in caribou we grab the "environment" from the env, and put it in a dynamically scope config

18:06 so you can bind it in the repl to do things with the prod db or whatever

18:06 without having to run a repl in prod

18:07 we make sure the root binding is the default env config, so threads all see the right config etc. but any part of the code that needs to can override it in a scoped way

18:07 noncom: why in clojure there is no in-line comment like /* */ in c or java (except for the (comment) macro which is different) ?

18:08 xpe: noncom: you can use ;

18:09 noncom: just at the end of the line. it makes everything after it a comment

18:09 justin_smith: #_ comments a whole form

18:09 xpe: or #_(whatever)

18:09 noncom: i know that in other lisps there is no such thing too.. but..

18:09 #_ ??? wow!

18:10 justin_smith: #_ is very handy, it always comments out a balanced expression

18:10 xpe: noncom: I'm sure, I couldn't evaluate that. What did you saY?

18:10 justin_smith: lol

18:10 xpe: I mean "i'm sorry..." i blew that joke

18:10 noncom: :)

18:11 xpe: RuntimeException Invalid token: :

18:11 noncom: ; :)

18:11 xpe: RuntimeException Unmatched delimiter: )

18:11 justin_smith: the only problem with #_ is how many clojure programmers don't know what it does

18:11 and emacs doesn't even highlight the form it precedes as commented

18:11 which is sad

18:12 I guess I could see if I can figure out how to fix it.... I've hacked elisp in the past

18:12 noncom: i think that its usefullness is so great that we should start a world-wide campaign with banners, parades and such to announce that it exists..

18:13 xpe: justin_smith: emacs's parsing could be fixed, right?

18:13 noncom: emacs is lisp, so it never was broken

18:13 _Vi: How to write (doall (map ... shorter? Is there something like domap?

18:13 xpe: haha

18:14 noncom: _Vi: (mapv) ?

18:14 SegFaultAX: That gives different results.

18:14 noncom: it gives a vector

18:14 SegFaultAX: So it isn't the same.

18:14 noncom: (mapl) ?

18:15 SegFaultAX: _Vi: What's wrong with just calling doall? Are you sure you even need to do that?

18:15 _Vi: Unable to resolve symbol: mapl in this context

18:15 noncom: _Vi: sorry, that was a joke

18:15 _Vi: SegFaultAX, Typing more and closing more parentheses.

18:15 SegFaultAX: :/

18:15 _Vi: "mapv" suits well.

18:16 coventry: What is the purpose of #! vs ';'? Just some vestigial thing? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L108

18:17 justin_smith: coventry: the unix kernel interprets that magically

18:17 #!java -jar clojure.jar ...

18:17 coventry: Oh, so you can make clojure scripts. Cool.

18:19 andyf: _Vi: You are welcome to define a domap yourself, of course.

18:20 justin_smith: if you already want to greedily do the whole map, what is the advantage of not doing mapv?

18:20 noncom: and be sure to make a pull request. but that's another joke :)

18:20 justin_smith: it's not like the datatype has some advantage

18:21 noncom: unless you are really working with lists like building clojure forms, but that's sorta exotic for (map) i guess..

18:21 justin_smith: noncom: seq on a vector is cheap

18:21 andyf: noncom: Making pull requests against Clojure or contrib libraries is no laughing matter :-)

18:22 justin_smith: whereas arbitrary lookup on non-vector sequentials is expensive

18:22 SegFaultAX: andyf: I assume he meant against the github repo, in which case PRs are expressly declined.

18:22 llasram: Humor on the Internet: NP-hard

18:22 noncom: :D

18:22 andyf: uncomputable, I'd say

18:23 noncom: maybe core.logic can get it right, if given enough IRC logss

18:23 SegFaultAX: Hey girl, are you a travelling saleman because you make me NP-Hard.

18:24 * SegFaultAX shows himself out

18:24 noncom: haha

18:24 llasram: Yeah, the dec then inc karma cancel out

18:24 _Vi: Clojure's Github repository is arrogant one like linux.git and git.git and don't accept too-easy-to-do pull requests and issues?

18:25 SegFaultAX: I don't often write jokes on the spot, but when I do, I regret them immediately

18:25 CaptainLex: SegFaultAX: I liked it

18:25 noncom: yeah, joking is nice. i like feeling that someone was in a mood to joke, it makes me glad

18:25 coventry: L'esprit de let-me-show-you-the-way-out-thank-you-very-much

18:26 SegFaultAX: Ok, now I /have/ to tweet it.

18:27 CaptainLex: alt: you make me NP-complete

18:28 andyf: _VI: If you consider that to be arrogant, then yes, it is. I don't understand the value judgement you are making though.

18:29 SegFaultAX: _Vi: No, they don't accept PRs because all work is done via jira and you must have signed the CA.

18:31 _Vi: andyf, I've seen some recommendations to avoid using Github "pull request" feature regarding to Linux repository (along with some general criticism of the features). This gives feeling that "one cannot simply pull request to the Linux repo" and that Github pull requests are for lesser repositories.

18:31 SegFaultAX: irccloud sent me an invite.

18:31 1.5 years after I applied.

18:32 gdev: _Vi, in the case of Clojure core it's just a matter of using a different workflow

18:32 andyf: _Vi: If some software project has a different process for submitting change requests besides pull requests on Github, then I think that is their choice. If you create a software project, you get to decide how you will accept requests for changes. Seems simple to me.

18:32 SegFaultAX: andyf: Well said.

18:35 coventry: It would be cool if there was a clojure-unstable like debian-unstable, pulling in patches more liberally than the clojure core team does. But no one seems to be interested in curating such a thing.

18:37 andyf: coventry: I considered it for a while, but it would be a big time sink, and most likely things would get added that were never put into Clojure itself. Effectively what you would have is a very similar but somewhat different programming language, incompatible in perhaps well-documented ways.

18:37 cYmen: I find it irritating that this doesn't work: (letfn [r [] 3] r)

18:38 Could somebody offer some insight into what is going on?

18:38 coventry: andyf: Yeah, it would probably lead to some friction down the road.

18:39 justin_smith: ,(letfn [r ([] 3)] (r)) ; cYmen do you want this?

18:39 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

18:39 coventry: cYmen: Have you seen the example at http://clojuredocs.org/clojure_core/clojure.core/letfn

18:39 justin_smith: err

18:39 amalloy: ,(letfn [(r [] 3)] (r))

18:39 clojurebot: 3

18:40 arrdem: ,(doc letfn)

18:40 clojurebot: "([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."

18:41 cYmen: One beer... well thanks for your help in finding my missing brackets guys... ;)

18:42 oh parens actually...whatever

18:46 coventry: Is there a way to identify what threads are running and kill one of them, either from the repl or some kind of emacs nrepl thing short of the ritz debugger?

18:49 justin_smith: jvisualvm

18:50 ,(Thread/getAllStackTraces)

18:50 clojurebot: #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getStackTrace)>

18:51 coventry: Thanks, Thread/getAllStackTraces looks like it would work.

18:51 justin_smith: it is a hash from thread handle to stacktrace

18:51 bitemyapp: akurilin: Haskell in general feels like alien technology at first.

18:51 justin_smith: so you could use that handle to kill it, if it has the stack trace that interests you, I think

18:52 coventry: justin_smith: Yeah, should be able to identify the thread from the stack trace.

18:58 justin_smith: also, depending on how the thread is started, you could store a reference to it for later

18:59 coventry: justin_smith: Yeah, this is more for development. My experimentation started a long-running thread which turned out to be a bit of a nuisance and I was wondering what tools there are for that kind of situation.

19:06 gdev: ugh i hate when i finally have the answer just to find out the person has left irc

19:08 justin_smith: which is why one should never leave irc

19:08 bitemyapp: gdev: I hate that too.

19:08 justin_smith: leavers are a weird breed.

19:08 hard to get much value from IRC unless you lurk.

19:08 maybe they pay for their internet by the minute?

19:09 gdev: hrm, or maybe they finally ran out of the 1000 free hours of AOL

19:09 well good, now I can go back to working on my problem ^_^

19:09 SegFaultAX: gdev: Heh, nice.

19:12 dsrx: what's a good way to test macros? test the output of macroexpand or macroexpand-1?

19:12 probably the latter if anything

19:13 amalloy: dsrx: just test that they do the right thing when you use them. you shouldn't need to test that they expand to exactly what you expect

19:13 dsrx: hmm

19:13 amalloy: if you do, you tie yourself to an implementation strategy for no reason

19:14 dsrx: i see that you answered almost this exact question on SO earlier this year. makes sense, thanks :

19:14 :)

19:14 amalloy: more than once a year, i'd wager

19:18 gdev: I'm working on an irc client that searches google and the channel history for the past three years before it shows a question in the channel. calling it bitemyChat

19:22 bitemyapp, that name isn't taken yet is it?

19:24 bitemyapp: gdev: not yet.

19:28 gdev: i think I'm abusing lein-ancient. instead of looking up the version of the libraries I want to use I just put "0.1.0" and then run lein-ancient

19:30 llasram: gdev: lein-ancient can lookup the most recent version of a lib you provide on the command-line

19:31 gdev: llasram, I know, but if i do lein ancient :interactive it will update the project file for me

19:31 llasram: Fair enough :-)

19:32 devn: `lein search conch` returns a version which is 0.6.0

19:32 `lein ancient` in a project including conch returns the latest is 0.5.1

19:33 Any idea why?

19:35 gdev: devn, did you try running ancient with :allow-all ?

19:35 devn: nosir

19:35 gdev: devn, what about with :aggressive ?

19:35 devn: same result with :allow-all

19:35 aggressive found it

19:36 gdev: neato

19:38 llasram, whoops I meant `lein ancient upgrade` updates it for you, interactive just prompts you before doing so

19:46 dsrx: `lein ancient aliens`

19:47 devn: haha

19:47 *sad face* OpenRefine won't load my dataset in the browser despite me upping the heap to 8GB

19:48 gdev: bitemyapp, now that c.j.j dropped the sql dsl, that's one less thing you have to test in blackwater =D

19:49 devn: methinks i need a 16GB machine if i want to run this on this dataset

20:06 zmansiv: hi, i wrote this code to construct a tree structure for a given directory http://pastebin.com/hT7pXnQm . since the jvm doesn't support tail call optimization, i get a StackOverflowError if i run this on a dir with lots of nested directories. how can i solve that problem?

20:07 i looked into loop/recur but couldn't come up with a way to use it here

20:07 amalloy: &(doc file-seq)

20:07 lazybot: ⇒ "([dir]); A tree seq on java.io.Files"

20:08 amalloy: or use tree-seq if you don't want actual File objects

20:08 the point is to do it lazily

20:09 bitemyapp: gdev: I'm grateful for that.

20:09 gdev: it makes the awkward relationship between c.j.j and Korma less awkward too.

20:09 zmansiv: amalloy doesn't file-seq return just a flat structure?

20:11 justin_smith: but you can use the paths to construct the tree

20:11 using assoc-in

20:12 or whatever tree constructor, if you don't want to use maps / records

20:13 amalloy: well, you're trying to build a tree of depth N, where each node is eagerly realized, all at once. that can't help but consume unlimited stack

20:17 zmansiv: right now my goal is to display a gui with a treeview that shows the directory and its contents

20:18 i was doing that by constructing the tree structure with the code i linked, and then recursively iterating over that and creating TreeItems

20:18 what would be a good way to achieve that?

20:22 deadghost: if I do a map in a map will the inner % have problems with the outer?

20:22 or can I give it a name or something

20:24 aspotashev: deadghost: AFAIK you cannot make nested anonymous functions with the #() syntax

20:25 but you still can make an anonymous function by writing it in a full form: (fn [a b c] something)

20:25 so yes -- you have to give the arguments some names

20:26 bbloom_: which is a good idea even if your #() isn't nested, but the % is visually far away

20:37 deadghost: http://pastebin.com/8rUCU952

20:37 not sure if I'm doing this right

20:39 _Vi: deadghost, % should be paired with #(

20:40 deadghost: it's a map inside a map

20:40 justin_smith: _Vi: also notice the unmatched paren, this is just an incomplete snippet

20:40 deadghost: it gets the individual values in the sequence %

20:40 aspotashev: #(map (fn [name] (insert-categories name business-id)) %)

20:40 justin_smith: use for instead of map inside map though

20:40 cljr: is there something similar to python's asyncore in clojure, or an easy way to do similar functionality?

20:41 _Vi: I think usually better to use #( ... % ...) for inner functions, and (fn[...]...) for outer ones.

20:42 justin_smith: ,(for [a (range 4) b (range a)] b)

20:42 clojurebot: (0 0 1 0 1 ...)

20:42 justin_smith: much easier than setting up nested maps

20:44 aspotashev: justin_smith: wow1

20:44 *!

20:45 justin_smith: cljr: you can attach a future or agent to an input source, or manually run Thread objects - or do you really want to do explicit polling and dispatching, because it is possible, I just don't see the point

20:46 core.async is pretty cool for taking asynchronous tasks and writing them out the way you would normal code

20:46 cljr: but it could be I don't understand what feature you actually want from asyncore

20:47 cljr: justin_smith: yeah, I'm not positive mnyself, I think I need to do some more research.....thanks

20:48 justin_smith: cljr: there are a lot of options for async and thread based stuff in clojure, it is one of the things that distinguishes the language

20:48 that is a big part of why so many things are immutible - it makes threaded stuff so much nicer / simpler

20:49 cljr: right

20:49 ive done enough clojure programming to know that, but this specific area is new to me

20:50 i was looking at how Bitcoin clients work and one in particular seemed to handle messages over a socket async, hence my reference to that library anove, but im just trying to wrap my head around that

20:51 justin_smith: http://docs.python.org/2/library/asyncore.html the example client here looks a lot like a state machine. core.async takes normal looking code and makes a state machine, so that may be somewhere to start

20:52 cljr: k, thanks again

21:01 justin_smith: cljr: clojure version of 17.6.1, the asyncore HTTP client example (future (println (slurp "http://clojure.org")))

21:02 musicalchair: some people here might like this. p2p webworkers: https://grimwire.net/ http://grimwire.com

21:03 cljr: justin_smith: https://github.com/jgarzik/pynode/blob/mini-node/node.py

21:03 justin_smith: not asking you to spend time looking at it, but it seems to create or connect to a socket, then just checks for reveieved messages on it and handles that asyncr

21:08 john2x: is there a fn that converts clojurescript datastructures into native javascript? e.g. PersistentVector -> JS Array

21:08 zmansiv: any way to get the value that would be set if you passed certain keys to assoc-in?

21:09 john2x: but handles other datastructures as well, automagically

21:09 zmansiv: i.e. using the "users" vector defined in the example at http://clojuredocs.org/clojure_core/clojure.core/assoc-in

21:09 justin_smith: zmansiv: you can run assoc in, and if you don't like the result, don't use it - it doesn't mutate the input

21:09 zmansiv: how can i see what the keys [1 :age] yield in that data struct? (should be 43)

21:09 justin_smith: there is get-in

21:10 zmansiv: oh awesome, thank you

21:10 justin_smith: ,(get-in {:a {:b {:c 42}}} [:a :b :c])

21:10 clojurebot: 42

21:11 zmansiv: perfect

21:12 justin_smith: cljr: depending on the intent, in clojure you would do what that node.py is doing with ring (an async web service lib that lets you define functions that massage the incoming data and generate responses), or core.async (if you wanted to work on the level of the logic of various events that take a variable amount of time)

21:14 cljr: justin_smith: ring isn't limited to just http?

21:17 rads: john2x: (clj->js [1 2 3])

21:18 zmansiv: say i have this structure: { :value "1", :children ({ :value "2", :children () }) }

21:18 john2x: rads: thanks!

21:18 zmansiv: how could i get "2" ? i tried (get-in x [:children 0 :value]) but no dice

21:19 x being that structure above

21:20 it's the 0 that's not working, i guess that works on vectors but not lists. can i achieve that using a list or do i need to be using a vector?

21:20 dnolen: zmansiv: lists are not associative data structures that won't work

21:21 zmansiv: alrighty vector it is then

21:22 justin_smith: cljr: oh, it is limited to http I think, so it may not be as general as what you were thinking

21:30 cljr: random snippet from my own code that may be a bit closer to what you have in mind? https://www.refheap.com/21593 I define a thread that handles output from a shell process stdout, and returns functions to write to the process stdin or ask it to close

21:40 "symbols, whose values are looked up in the court of the LORD’s glory."

21:40 http://kingjamesprogramming.tumblr.com/ this site is funny

21:40 cljr: justin_smith: very cool, thanks

21:56 rads: "The global environment is chosen here, because this is the will of God."

21:56 justin_smith: AMEN

21:56 that whole blog is gold, he needs to update more

21:58 That quote places bitemyapp as the Satan, who tells you to forsake the global environment of our LORD in favor of explicit arguments and monads.

22:10 Raynes: bitemyapp is webscale.

22:11 seangrove: +1 explicite arguments with state monads

22:12 pragmatism: back

22:18 dnolen: comprehensive #js literal support in CLJS master, fixed behavior of #inst and #uuid to match Clojure's

22:24 mcblumperson: does the #js literal have the same effect as js->clj ?

22:25 bitemyapp: all of a sudden people like my milkshakes?

22:26 dsrx: here's a good project name, something that incorporates edn and garden, "eden"

22:27 seangrove: dsrx: Love it. A return to innocence and perfection.

22:27 But could imply ignorance as well

22:27 rads: I've heard people say "eden" out loud when referring to edn so that could get a little confusing

22:27 ivan: mcblumperson: isn't it more like clj->js?

22:29 mcblumperson: right

22:29 sorry, got my arrows crossed

22:41 egosum: Is there a good/easy/nice way to store arbitrary datastructures (e.g. a map with nested maps/lists within) in Datomic?

22:41 I'm reading "no" but I want to make sure…

22:43 nightfly: serialized to a string

22:45 cljr: im not familia enough with java libhraries, but from what I can te4ll BUfferedReader just let syou continue to read from a socket when yuou feel like it, but is there nothing that basically notifies you when there is a data on a socket to be read and uses your callback?

22:45 dnolen: mcblumperson: no it's just data literal syntax for JS objects / arrays

22:45 egosum: nightfly: Yeah :\ so, "no"

22:45 dnolen: mcblumperson: no conversions

22:45 gdev: egosum, yeah you could have db.type/string and then store values such as "[1 2 [4 5 6]]"

22:46 egosum: gdev: I suppose that is a reasonable way to do it, anyway. Could make a new type and apply a function to it in the transactor to read it, too, perhaps…?

22:46 Probably not necessary.

22:47 gdev: egosum, just curious what system you're building that would need to store nested collections

22:48 egosum: gdev: Storing representations of finite state machines

22:48 basically

22:49 justin_smith: egosum: there is always the conversion of an arbitrary graph to two key/value maps: one with the identities, and one describing connections between entities

22:49 you can even do arbitrary recursive relations you could not describe with nested structures

22:50 and for the non-recursive case it is straightforward to convert the two flat maps into a nested structure

22:52 igorw: I have a case of two sets that should be the same, yet my test suite says they're not

22:52 egosum: justin_smith: I'm not sure I entirely follow; could you say/point to more?

22:52 igorw: actual: (not (= #{0.0 4.0} #{0.0 4.0}))

22:52 any ideas or suggestions for debugging?

22:54 xpe: # (= #{0.4 0.0} #{0.0 04})

22:54 I forget the bot's prefix

22:55 gdev: ,(= #{4. 0.0} #{0.0 4.0})

22:55 clojurebot: true

22:55 xpe: igorw: testing locally, I get (= #{0.4 0.0} #{0.0 0.4}) ; true

22:55 gdev: works on this box

22:55 xpe: igorw: can you reduce your test and try in the REPL

22:55 igorw: yes, same when copying to the repl :-/

22:56 xpe: machine type? java version? clojure version?

22:56 justin_smith: egosum: {:a 0 :b {:c 1}} -> {:entities {:a 0 :b {} :c 1} :edges {:b :c}}

22:56 igorw: but the value must be somehow different from what is dumped

22:56 justin_smith: all the information is present, it is in a flattened form

22:56 xpe: igorw: i'll bet it is a typo somewhere :)

22:56 justin_smith: also that can express recursive / circular nestings that cannot be expressed in a single literal

22:57 ie. if :c had :b in it

22:57 igorw: 64-bit jvm, java version 1.6.0_65, clojure 1.5.1

22:57 xpe: igorw: yeah, I'll bet you have a typo somewhere :)

22:57 egosum: justin_smith: Ah, yes. Makes sense, thank you

22:58 justin_smith: in practice you would not use the keywords from the original structure - I did that for clarity, you would map a unique id to [k v] as a pair

22:59 igorw: xpe: well the thing I pasted is copied directly from the tests output

22:59 egosum: justin_smith: What about a list representation, though?

22:59 justin_smith: Er, that's unclear. Say :b's value was a list.

22:59 justin_smith: right

22:59 xpe: igorw: please make a gist of the test

23:00 I'll wager that the problem isn't with Clojure's set equality

23:00 justin_smith: egosum: there may be a standard way to do that, but the easiest way is to treat a list as a hash of indexes to values with some key indicating it should be treated as sequential

23:02 ie. [:a :b :c] -> {:type :seq 0 :a 1 :b 3 :c}

23:02 egosum: Right, makes sense. Have you been using datomic in production, out of curiosity?

23:02 justin_smith: I have not used it, I just know it is a keystore and I think graphs are awesome and I know how they map to keystores

23:03 well it isn't a keystore

23:03 but I know it can be used in that way

23:03 egosum: justin_smith: Fair enough :) Thanks!

23:05 gdev: justin_smith, its a datom store ;)

23:06 justin_smith: gdev: OK, someday I will know what a datom is I guess

23:06 gdev: justin_smith, [E A V Tx]

23:08 the other day I gave a presentation on avoiding jargon during speeches, then the next day I gave a presentation on Datomic...was so hard to follow my own advice

23:08 justin_smith: so on further reading, the datomic model is basically a graph (nodes with key/val + edges as I showed above) with an explicit time component

23:08 I think

23:08 gdev: lol

23:08 xpe: justin_smith: in case you want to learn more about diatoms http://westerndiatoms.colorado.edu/about/what_are_diatoms

23:09 justin_smith: ROFL

23:09 that extra i makes a big difference

23:09 xpe: they have special forms and history too

23:09 justin_smith: but they are not immutible

23:09 in fact they evolve via mutation

23:10 xpe: haha, so true

23:10 holy cow: It is estimated that 40% of the earth’s oxygen (02) is produced through the photosynthetic activities of diatoms.

23:10 justin_smith: LOL someone needs to do a creationist programming project in clojure (since we don't do mutation)

23:10 gdev: diatoms are web scale

23:11 justin_smith, yeah we'll call it "in the garden of edn"

23:12 justin_smith: but they have global scope (found everywhere) plus mutation, so they are bad

23:12 lol

23:12 * xpe looks for a big hook

23:13 * justin_smith will show himself out.

23:14 igorw: xpe: one thing I noticed is that there is a negative zero involved in the calculation which might have some strange effects...

23:14 gdev: justin_smith, they're a legacy system so you just have to deal with it

23:14 xpe: gdev: going way back ^^^ it is only jargon if your audience doesn't understand it right?

23:14 john2x: how do I "explode" a vector to be passed as args in a fn? like foo(*args) in python.

23:14 igorw: trying to reduce the test case now

23:14 xpe: justin_smith (apply str [1 2 3])

23:14 gdev: xpe, I don't think they did =/

23:14 xpe: whoops that was for john2x

23:15 justin_smith: heh, np

23:15 arrdem: john2x: example input? but yes apply is probably the rigt fix

23:15 gdev: arrdem, don't you have a scala project to work on ;)

23:15 xpe: igorw: a negative zero? you've got problems then, haha

23:15 arrdem: gdev: it's done :D

23:16 oh right I was gonna post code...

23:16 john2x: I'm trying (subs some-str [start end]).. so the first arg needs to be provided.

23:16 gdev: arrdem, good job

23:16 igorw: xpe: oh? can you elaborate?

23:16 xpe: ,-0

23:16 clojurebot: 0

23:16 justin_smith: the other half of that: (fn [& [a b c :as args]]) in order to get all args as a list you can use further

23:16 igorw: ,-0.0

23:16 clojurebot: -0.0

23:16 arrdem: gdev: https://github.com/arrdem/fractals

23:16 igorw: it's a float ;-)

23:17 arrdem: no README yet, but you can sbt run it just fine :P

23:17 xpe: ,(type 0.0)

23:17 clojurebot: java.lang.Double

23:17 xpe: ,(type -0.0)

23:17 clojurebot: java.lang.Double

23:17 justin_smith: ,(= -0.0 +0.0)

23:17 clojurebot: true

23:18 gdev: arrdem, turles all the way down

23:18 *turles

23:18 arrdem: gdev: that was the design intent :D

23:19 gdev: arrdem, now you can rewrite it in clojure, just use a map ;D

23:19 justin_smith: ,(applyu subs "hello" [1 4]) ; john2x

23:19 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: applyu in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:19 justin_smith: ,(apply subs "hello" [1 4]) ; john2x

23:19 clojurebot: "ell"

23:19 arrdem: gdev: I benchmarked the L system expansion in Clojure vs in Scala and Clojure won by a factor of 4 :P

23:19 john2x: ooh nice. thanks

23:19 arrdem: gdev: no clojure port will be forthcomming tho.. too many other projects

23:20 gdev: arrdem, cool, anything fun?

23:21 arrdem: gdev: I got the go ahead to help finish clojure in clojure as my graduation project... I've got a stack of JVM books on the way for my Christmass relaxation reading as a result

23:21 never did finish cloutjure tho...

23:22 justin_smith: arrdem: that is awesome, great news

23:22 gdev: lol yeah we didn't get far enough to have anything to continue

23:22 arrdem, now I know what I'm getting you for christmas =D

23:22 * arrdem gets worried

23:24 arrdem: gdev: hehe I played for a couple days with neo4j and ultimately did get something reasonable working, I just realized that the graph construction issues were more complex than I could fathom without a partner :/

23:24 so the whole

23:24 "social graph" thing kinda killed it

23:27 gdev: arrdem, yeah I tried modeling it in Datomic, but I didn't have the data you had scraped so I wasn't sure what all we were capturing

23:29 arrdem: gdev: :/ yeah. sometime when you can get away we should get together and take a second stab at that... in fairness tho our toolset & codebase coordination was essentially no-existant :P

23:29 next year'll be better if clojurecup runs again

23:30 gdev: arrdem, yeah next year lets just do a windjammers clone in clojurescript

23:30 arrdem: gdev: hahaha that'd be awesome.

23:32 gdev: my latest project is doing 8bit clones with Quil and Overtone. but everyone is migrating to the browsers

23:32 justin_smith: I want to model something in blender this weekend that I can print with the 3d printer at work

23:33 bonus points for an idea that lets me use clojure to help generate the structure

23:34 arrdem: justin_smith: 3d serpinsky triangle

23:34 justin_smith: https://github.com/krumholt/penumbra-blender-exporter I found this

23:34 arrdem: justin_smith: trivial to compute, uses turtles in 3D!!!11!1

23:34 * arrdem loves his turtles

23:34 justin_smith: I can thus make a shape, export to edn, fuck with it, then export to blender

23:34 arrdem: awesome idea

23:36 gdev: justin_smith, lol 4 year repo, good luck with that

23:37 justin_smith: it's just a python script that turns blender format into edn

23:37 so it shouldn't be too bad? worth a try

23:37 arrdem: what could possibly go wrong...

23:37 gdev: oh, sorry I'm just burned because I've been trying to get penumbra up to date for a couple days now

23:39 justin_smith: oh, I am unaware of the larger project

23:39 arrdem: clojurebot: turtle |is| http://www.rockpapercynic.com/strips/2011-11-25.jpg

23:39 clojurebot: 'Sea, mhuise.

23:42 gdev: justin_smith, yeah, and its not under active development

23:43 arrdem: gdev: do you remember who got the domain name?

23:43 gdev: arrdem, no idea

23:44 arrdem: oh. it was James.

23:47 igorw: ,(= #{0.0 4.0} #{0.0 (Float/valueOf "4.000")})

23:48 clojurebot: false

23:48 igorw: ,(= #{4.0} #{(Float/valueOf "4.000")})

23:48 clojurebot: true

23:48 arrdem: gdev: I figured out what I've been doing wrong... I've been trying to munge multiple datasources into a single graph. Split it out into a single representation per service and suddenly everything falls into place.

23:48 * arrdem feels silly

23:48 igorw: anyone want to explain that one to me? :)

23:49 xpe: ^

23:49 arrdem: igorw: you're comparing the set #{0.0 4.0} with the set #{4.0}

23:49 igorw: that should fail

23:49 oh wait.

23:49 what?

23:49 clojurebot: what is http://gist.github.com/306174

23:49 arrdem: clojurebot: go away

23:49 clojurebot: Gabh mo leithscéal?

23:49 arrdem: ~botsmack

23:49 clojurebot: Owww!

23:51 igorw: so, is it a bug? I have no clue how to debug this

23:52 arrdem: igorw: not sure... whatever's going on here sure isn't obvious.

23:53 justin_smith: ,,(= #{0.0 4.0} #{0.0 (Double/valueOf "4.000")})

23:53 clojurebot: true

23:53 justin_smith: 0.0 as a literal is a double

23:53 now why it is not doing the implicit numberic equality in sets is another question

23:53 gdev: ,(class 0.0)

23:53 clojurebot: java.lang.Double

23:54 xpe: igorw: that's pretty cool

23:54 nicely done

23:55 igorw: justin_smith: ah nice, thanks!

23:55 justin_smith: much simpler:

23:55 ,(= #{4.0} #{4})

23:55 clojurebot: false

23:55 justin_smith: ,(= 4 4.0)

23:55 clojurebot: false

23:56 xpe: ,(hash 4.0)

23:56 clojurebot: 1074790400

23:56 xpe: ,(hash (Float/valueOf "4.0"))

23:56 clojurebot: 1082130432

23:56 xpe: right?

23:57 arrdem: xpe: Double/

23:57 oh.

23:57 (inc xpe)

23:57 lazybot: ⇒ 1

23:57 xpe: igorw ^

23:57 arrdem: igorw: this...

23:57 ,(= #{0.0 (Double/valueOf "4.0")} #{0.0 4.0})

23:57 clojurebot: true

23:57 justin_smith: ,(every? #(apply == %) (map list #{4} #{4.0}))

23:57 clojurebot: true

23:58 justin_smith: if you have nothing but numerics in your sets, that should suffice

23:58 arrdem: igorw: Double and Long are the standard numeric literal types in Clojure

23:58 justin_smith: ,(every? #(apply == %) (map list (sort #{3 4}) (sort #{3.0 4.0})))

23:58 clojurebot: true

23:59 igorw: confusing part is that the sets behave differently when they contain mixed types

23:59 justin_smith: igorw: notice my ammendment to call sort above

23:59 gdev: convert them all to string

23:59 justin_smith: because sets are not ordered

23:59 gdev: my above works if the sets are strictly numeric

23:59 gdev: justin_smith, converting them to string makes everything just work

Logging service provided by n01se.net