#clojure log - Nov 20 2014

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

0:05 technomancy: TimMc: whoa

0:15 FriedBob: Woo hoo! Figured out how to get the edn-config stuff and not have to use profiles. Now I can move on to the meat of the project and see how much of what I have read has stuck.

0:26 kenrestivo: is there a way in schema to say, i want a map here, but its structure is opaque and i don't have time to specify the whole deep thing?

0:27 i.e. {:foo s/SomeRandomMapIDontControl}

0:34 rritoch: kenrestivo: XML Schema?

0:34 kenrestivo: prismatic schema

0:34 https://github.com/Prismatic/schema

0:37 rritoch: kenrestivo: Hmm, sorry can't help you there... is XSD it's <xs:any namespace="##any" processContents="skip"/>, no idea what prismatic would use since I've never used it.

0:40 kenrestivo: Looking at the source though it looks like there is an Any, I'm just not sure what syntax you'd use

0:40 https://github.com/Prismatic/schema/blob/master/src/cljx/schema/core.cljx#L242-L244

0:40 kenrestivo: Maybe s/Any

0:40 kenrestivo: yeah i saw that. also an empty map seems to work {}

0:40 i want to specify that it's a map, just not what's in the map

0:41 {s/Any s/Any} might work too

0:47 ambrosebs: kenrestivo: perhaps (s/pred map? 'map?)

0:47 just going off the readme

0:48 kenrestivo: it seems like there are several ways. so far {} works, {s/Any s/Any} works, {s/Keyword s/Any} works. pred probably can too.

1:02 rritoch: Where is the clojurescript syntax #+clj documented? It looks like a reader macro but I can't find documentation for it

1:03 justin_smith: rritoch: that's cljx notation

1:03 it means code that is only used in clojure (jvm) and not in clojurescript

1:06 rritoch: justin_smith: Thanks, that helps, checkout out the cljx now. I'm easing into clojurescript since the web platform is nearly fully functional. I added a http-mapper to the kernel, and an implementation to the core which should now make it possible to serve static files

1:07 justin_smith: While doing that I realized that I can make a servlet specific for serving resolved ".clj" resources so that will probably be my next step which will invalidate the need for template engines since the role of delivering extension based content types would be taken over by servlets

1:08 justin_smith: And this may also mean that within a month I should finally be out of the systems level code and actually into web application development

1:21 Is it possible to "include" one lein plugin in another? Looking at the cljx features it looks like cljx would be very useful when generating OSGi bundles but I have a lein plugin which generates the OSGi bundles so I'm not sure how I could refrence cljx code from another leiningen plugin, I've never tried anything like that before.

1:23 If I load cljx as a dependency instead of as a plugin would that make the cljx code available to my leiningen plugin?

1:24 justin_smith: rritoch: it should, yes

1:25 rritoch: justin_smith: Cool :) That's been one of the big complications I've been trying to resolve, how to compile clojurescript into web applications prior to deployment, and cljx seems to solve much of that problem, and provides the benefit of code-reuse between the server side (clj) and the client side (cljs).

1:26 justin_smith: Sneaking into Web 5.0 land :)

1:28 clojer: Anyone deploying on Openshift? I'm missing something getting a default app to start. Probably something really obvious :(

1:28 rritoch: Someone in here was also working on making browser plugins using clojurescript which is another important leap I'll need to make to enter Web 5.0 land. Being able to offload processes to the client for offline processing is key to Web 5.0.

1:31 justin_smith: clojer: I don't know anything about openshift, but I know that it is easy to deploy an uberwar webapp to aws elastic beanstalk, and pretty straightforward to deploy a self-hosting webapp (ie. http-kit) on aws ec2 or heroku

1:31 clojer: in fact, technomancy works at heroku and often helps people here to get their apps set up to run there

1:33 clojer: justin_smith: I have the community cartridge and app setup but it doesn't appear to be started. I ssh'ed into the account and ran lein run but an error was returned: Could not transfer artifact lein-ring:lein-ring:pom:0.7.5 from/to clojars (https://clojars.org/repo/): Specified destination directory cannot be created: /var/lib/openshift/546d7bd35973ca795600002c/.m2/repository/lein-ring/lein-ring/0.7.5

1:34 justin_smith: clojer: OK, what's your $HOME set to?

1:34 clojer: also, it's actually better not to use lein in production at all

1:34 build an uberjar, and then use java to run it on the server

1:35 clojer: justin_smith: I thought of trying EC2 but they take card details, if I remember, so you have to watch your usage.

1:35 justin_smith: clojer: ahh, so openshift has a straightforward free teir? interesting

1:35 clojer: justin_smith: Lein was a last resort.

1:35 justin_smith: clojer: did you try creating an uberjar and running it?

1:36 clojer: justin_smith: Yes. No card and no 1-year expiry .... as far as I'm aware :)

1:37 justin_smith: I'm not sure their setup allows this as I didn't setup an app server. You can go with Wildfly 8 but that's a different route.

1:37 justin_smith: what wouldn't their setup allow?

1:37 if lein will run, java will run

1:38 clojer: use an embedded server, I like http-kit

1:38 java -jar my.uberjar.jar

1:38 that's it

1:38 clojer: justin_smith: OK, I'll give it a try. I'm new to deployment as all my Clojure so far has been running locally.

1:38 justin_smith: (well lein uberjar to create the jar...)

1:38 clojer: OK. Uberjars make it amazingly simple.

1:38 it's a single file, you tell java to run it. That's it

1:39 clojer: justin_smith: How do I tell Java to run it? Sorry :)

1:39 justin_smith: I already said above "java -jar <name of uberjar>"

1:40 clojer: if your app will run via "lein run", it will usually run from an uberjar with no issues

1:40 clojer: Ah, thought that was creation. Great.

1:40 justin_smith: "lein uberjar" is creation

1:40 also pretty simple

1:40 the tricky part is it means your main needs to be aot compiled

1:41 but, alternatively you can run it via "java -cp <name of uberjar> -m clojure.main your.core

1:41 "

1:41 clojer: justin_smith: Does that mean I have to create teh uberjar locally and git-push?

1:42 justin_smith: clojer: you should be able to scp it

1:42 clojer: justin_smith: If so there's a JVM mismatch :(

1:42 justin_smith: I don't even like to have git installed on my server

1:42 clojer: jvm mismatch...

1:42 I've never seen that

1:43 clojer: were there any more details?

1:43 clojer: justin_smith: When I ran the app locally there was an error which seemed to refer to something deprecated in JDK 8

1:44 justin_smith: so you created the uberjar, and tried to run it?

1:44 clojer: WARNING: :warn-on-reflection is deprecated in project.clj; use :global-vars.

1:44 Reflection warning, /private/var/folders/5h/4fvvcx856_lgdmyz0rxgtwgh0000gp/T/form-init3201957262574781917.clj:1:906 - call to invokeStaticMethod can't be resolved.

1:45 justin_smith: clojer: that's just reflection warnings

1:45 clojer: justin_smith: No, this was with `lein run`

1:45 justin_smith: clojer: those are not errors

1:45 OK

1:45 those warnings just mean that :warn-on-reflection is on, and you are getting reflection warnings

1:45 it's an optional feature that helps you get your code to run faster

1:45 if you use typehints and eliminate the warnings

1:46 but it doesn't mean your code won't run

1:46 clojer: justin_smith: It hung at that point, though.

1:46 justin_smith: OK

1:46 clojer: do you launch a server in your -main ?

1:47 I am assuming this is a ring app btw, is it?

1:47 clojer: justin_smith: Great discovery! It didn't hang. Just no feedback that it was running :)

1:47 justin_smith: oh, nice

1:47 clojer: justin_smith: Locally, that is.

1:49 justin_smith: I'll have another go getting it pushed and running. Thanks.

1:49 justin_smith: np

1:50 like I said, if lein run works, then running the uberjar should (which you can also verify locally)

1:51 clojer: justin_smith: Just one more thing.

1:51 justin_smith: OK

1:51 clojer: justin_smith: the default came with Clojure 1.5.1 so if I revert to the uberjar method do I assume I can upgrade everything to a higher version?

1:51 clojurebot: Titim gan éirí ort.

1:52 justin_smith: clojer: the uberjar will use whichever version of clojure your project.clj specifies

1:52 clojure is just another java library as far as the uberjar is concerned

1:52 clojer: justin_smith: Yes, thought so.

1:52 justin_smith: uberjars work fine with 1.5.1 in my experience

1:54 clojer: the reason I recommend uberjars and not using lein or git on the production machine is because it reduces the number of things that can be misconfigured (or differently configured) between your dev machine and prod

1:55 clojer: you have a guarantee that what runs on prod is the exact set of versions that worked locally, because uberjar grabs the same artifacts and packages them

1:55 clojer: justin_smith: Will use uberjar. I'd heard of it before but hadn't tried as I was doing everything locally. Cheers.

1:55 justin_smith: clojer: also, using a jar directly has faster startup time and lower memory usage than with lein, and that can matter a lot on production

1:56 clojer: I hope I didn't leave anything out... it's pretty simple though

1:56 clojer: justin_smith: I'm glad you mentioned that as I was originally going with Go for memory efficiency and because I wasn't aware that Clojure was an option at Openshift.

1:58 justin_smith: clojer: generally, if java will run, and you have sufficient RAM to spare, clojure will run

1:58 even android (though the startup time there is painful and the jvm is very nonstandard)

1:59 clojer: justin_smith: Openshift comes with 3 gears, each of which has 512Mb RAM but you can select a "scaling" option which appears to pool the combined resources.

1:59 justin_smith: interesting

2:00 clojer: justin_smith: More precisely it seems to add a Haproxy into the mix.

2:00 justin_smith: yeah, 512 is a limit you can hit fast in clojure, but with some care you should be able to make it work

2:00 clojer: that's a setup that isn't as good for clojure

2:01 clojer: for php or ruby, being able to route to different instances is a great way to scale, but clojure has a high baseline mem usage (thanks to the size of the lang, and the use of immutible data structures everywhere) but it scales very well in one instance

2:02 clojer: justin_smith: Yes, I'm hoping this "scaling" option creates a combined 1.5GB RAM but I have my doubts.

2:02 justin_smith: :)

2:03 clojer: justin_smith: I think the scaling is specific to web requests.

2:03 justin_smith: yeah, that just isn't what you do in clojure

2:03 clojer: justin_smith: You never know, though.

2:03 justin_smith: clojer: so for php you have one process per request

2:03 clojer: clojure handles threads, and long living processes very nicely

2:04 clojer: justin_smith: Some warning with uberjar: Warning: specified :main without including it in :aot.

2:04 justin_smith: clojer: I've done pretty big corparate sites, and I have used a lot of ram, but never more than one machine / vm instance

2:04 clojer: If you only need AOT for your uberjar, consider adding :aot :all into your

2:04 :uberjar profile instead.

2:04 justin_smith: clojer: that means you should use the java -cp option I mentioned

2:04 clojer: Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method.

2:05 justin_smith: clojer: how do you usually run the app?

2:05 clojer: justin_smith: `lein run`

2:05 justin_smith: My first use of `lein uberjar`

2:06 justin_smith: Maybe I need to study :uberjar options a bit first

2:06 justin_smith: OK, you can ignore the warnings and use "java -cp <your jar> -m clojure.main your.ns"

2:06 wait, let me double check that syntax

2:11 amalloy: justin_smith: java -cp my.jar clojure.main -m my.ns

2:12 justin_smith: amalloy: thanks! I was afraid of that.

2:12 amalloy: or uh, maybe it's not -m to clojure.main?

2:13 &(doc clojure.main/main)

2:13 lazybot: java.lang.SecurityException: You tripped the alarm! clojure.main is bad!

2:13 justin_smith: I run clean pretty often, so I will verify as soon as I have an uberjar to test it on

2:13 amalloy: well, anyway, it says use -m

2:15 justin_smith: I am totally gonna make a pr to leiningen where it immediately says "use LEIN_SNAPSHOTS_IN_RELEASE to override" instead of getting to the very end of the jar building process, and then bailing

2:15 clojer: justin_smith: It sounds like a bit of high magic is required to get this uberjar working :(

2:15 justin_smith: hmm - it's typically been reliable for me - though I usually have a script running things, so I only set it up once for each project

2:15 not magic at all, I promise

2:16 clojer: the whole "not needing to aot compile -main" is new for me, and I have not utilized it in production yet

2:17 but it is a good thing that I do intend to take advantage of

2:17 clojer: justin_smith: I'll look into it later. Have to dash now. thanks for all the help.

2:19 justin_smith: $mail clojer if you are using the built in ring server and don't have a standalone server configured in -main, you may want to use "lein ring uberwar" to create the standalone

2:19 lazybot: Message saved.

2:35 dysfun: justin_smith: is that preferred over generating an uberjar and providing a server in main?

2:36 justin_smith: dysfun: not really

2:36 dysfun: but easier to try out

2:36 dysfun: that's what i thought

2:36 justin_smith: (if you are using lein ring)

2:38 I just noticed that "teach yourself progoramming in ten years" mentions clojure http://norvig.com/21-days.htm

2:47 rritoch: Is there a good way to change the "source" folder in clojure at runtime? For example, if I have a clojure servlet running on a tomcat server, via whatever means, but I want to pull the sources from a different folder, similar to how yii is deployed where sources are in a non-web accessible location... Would that be possible and if so how?

2:48 justin_smith: rritoch: I think that would be a question of adjusting the classpath

2:48 rritoch: I am not sure of the details here though

2:52 rritoch: justin_smith: So I should be able to use clojure.core/add-classpath for this?

2:53 justin_smith: My concern is that function is deprecated

2:53 justin_smith: I'm not sure, but that sounds right. When you use require, it looks for files on the classpath.

2:54 rritoch: Any idea why they deprecated add-classpath?

2:54 justin_smith: relevant thread on the group https://groups.google.com/forum/#!topic/clojure/eAf3PT5vjsI

3:01 rritoch: justin_smith: Ok, I think I understand the problem at least. Currentlyl I'm deploying apps with lein grid push, which just compiles and copies code to the web root, but I want to be able to edit code in real time, maybe I can achieve this by just pushing the maven dependencies to the classpath, and a configuration file to direct the servlet to add the source folder to the classpath

3:01 err, push maven dependencies to the lib path ...

3:02 Either way, it looks like I need to make my own add-classpath function since this one is going away, which is really too bad because there are a lot of uses for it.

3:02 justin_smith: rritoch: you could check out what pomegranate does

3:03 it adds maven deps to the classpath at runtime

3:03 or maybe you can just use pomegranate

3:04 rritoch: Cool, that should work

3:04 The less I need to maintain the better :)

3:08 I also need to figure out what I need to do to ring to get it to work, I'm using hostmonster for my site right now which doesn't provide tomcat, but I'm thinking I can make a ruby app to deploy ring, assuming I can stop ring from blocking tomcat dependencies.

3:08 err, hostgator

3:08 justin_smith: rritoch: any reason you can't use an in-app web server like http-kit?

3:10 rritoch: Not particularly, I simply wasn't aware of it, Ring is the only stand alone clojure web server that I'm aware of.

3:10 justin_smith: rritoch: ring is not a server

3:10 it is an adapter layer

3:10 http-kit is ring compatible

3:10 ring can also be adapted for containers like tomcat or jetty

3:11 in fact, as far as I know ring is the way you are expected to use http-kit

3:12 http://www.http-kit.org/

3:13 rritoch: Hmm, well that sounds about right. Its usage looks very similar to ring, so as long as it doesn't block my tomcat dependencies that should work

3:14 With ring or http-kit though it looks like I'm still not going to be able to stream content, (such as mmpeg) but it is a step in the right direction

3:14 justin_smith: rritoch: ring is an adaptor that lets you use the same code for an embedded server (like http-kit) or a container (like tomcat) - but you would only be using one of those at a time

3:14 rritoch: http-kit explicitly supports websockets and streaming / async connections

3:15 rritoch: oh?

3:15 Ok, that is what I need then, I just need to figure out how it works and get it integrated. Tomcat is fine for development purposes, but isn't going to be good for end-users

3:15 justin_smith: that link I pasted above, their example code uses a websocket

3:16 another option that supports streaming (also ring compatible) is aleph https://github.com/ztellman/aleph

3:17 it is also standalone like http-kit is

3:17 rritoch: CPanel's tomcat plugin (experimental) is horrible, and virtually useless, so my choices are to tie into ruby with a standalone implementation, like http-kit, or rewrite the CPanel plugin and hope CPanel accepts it. http-kit seems an easier route.

3:19 (inc justin_smith)

3:19 lazybot: ⇒ 137

3:19 rritoch: I've owed you that for awhile, lol

3:19 I just didn't know how to use it until recently

3:21 Anyhow, thanks again. I think http-kit + pomegranate solve my remaining deployment issues

3:26 I'm also toying with the idea of trying to solve the C10K problem with clojure, but that may be pushing the technology far past it's capabilities.

3:26 If I were to solve C10K with it though, that would be very helpful for marketing purposes

3:28 I've already added a lot of optimizations, but I haven't yet run any significant benchmarks on it

3:33 szymanowski: hi, is there something other than performance that yields to prefer protocols over multimethods?

3:36 wei: datomic question: how do you use the pull api to get all entities with a specific attribute?

3:38 justin_smith: szymanowski: a protocol describes a group of methods a type implements, while a multimethod is a single method. You can easily create a single method protocol of course, but it means that a protocol can tend to be more like an interface (in fact it compiles to one) while a multimethod is just a single generic function

3:44 szymanowski: yes I know, but they target at the same purpose: polymorphism, and can be used for the same thing no?

3:46 it is just that everybody seems to automatically use protocols over multimethods and would like to know if it is JUST for performance or other aditional benefits

3:46 just*

3:46 justin_smith: szymanowski: they are simpler, they more directly use the built in facilities of the vm

3:47 szymanowski: does multimethods are really much more slow than protocols?

3:47 justin_smith: szymanowski: also, consider that if I write a library, and want users to be able to provide an implementation of some part of the logic - it often makes more sense to say "implement this protocol" rather than "implement these multimethods"

3:47 szymanowski: yes

3:47 szymanowski: yes I see

3:48 thank you

3:48 justin_smith: one advantage for multimethods is in the repl, reloading the codebase

3:48 protocols are much clumsier for redefining without a restart

3:49 szymanowski: I really love multimethods, so flexible

3:49 justin_smith: multimethods also support derive based heirarchies, and arbitrary dispatch functions, but in practice I don't see those features used very much

3:49 szymanowski: yes

3:49 justin_smith: usually it's either a keyword lookup, or the type of the thing that are dispatched on

3:50 szymanowski: yes in this situation I prefer protocols

3:50 justin_smith: also, because protocols only do type based dispatch, you end up needing to use defrecord or deftype or adding a :type metadata to your code

3:50 ,(type (with-meta {} {:type 'foo}))

3:51 szymanowski: protocols doesn't dispatch on type but on class no?

3:51 clojurebot: foo

3:51 szymanowski: yes I'm often doing this trick

3:51 justin_smith: szymanowski: good point, I think it is actually class they dispatch on, yeah

3:51 szymanowski: that a bit sad I think

3:51 justin_smith: it's the sacrifice needed so that the performance is at least available

3:52 szymanowski: but this is maybe that that allow speed

3:52 justin_smith: szymanowski: yeah, a protocol directly creates a jvm interface, and interfaces only support class dispatch

3:52 szymanowski: I find that using protocol yields to write more complex code

3:52 justin_smith: yeah, it can

3:52 I use them sparingly

3:53 szymanowski: I like the old school way of doing all with native types plus type metadata

3:54 thank you, i'm going back to work, have a nice day

3:54 justin_smith: if possible I avoid type dispatch altogether, and simply write code that uses native types

3:54 you too

3:55 (I guess I am implicitly using the built in type / protocol dispatch when I use the core functions of course)

4:43 schrotti: hm the nrepl used by lein is a 2-3 times slower than the one that comes with clojure.jar

4:43 how come?

4:53 morfeen: Anybody here have used Clojurescript to build something on the server side?

4:53 with Node, that is

4:58 dysfun: why would you do that voluntarily when you have clojure available?

5:00 morfeen: dysfun: npm?

5:00 npm libraries

5:00 dysfun: clojars?

5:00 there's almost nothing i want for in clojure

5:01 and the only thing i want for involves poking around JNI, so i'm just using something else

5:02 TEttinger: morfeen, I think people do that, sometimes, but it isn't common

5:02 morfeen: dysfun: cool, do you use Clojure in production?

5:03 dysfun: product is in development, but we will be doing soon

5:04 using clojure makes me feel a lot more confident that the concurrency stuff won't become a problem

5:04 morfeen: Clojars seem cool

5:04 dysfun: there are a lot of useful libraries

5:05 if you're struggling to find a particular library, http://clojure-toolbox.com/ is a good resource

5:05 or asking in here. but bear in mind there's a choice and people have different tastes

5:06 but we've largely built around what luminus provides. except we've cut a few things out and swapped in some other things

5:06 it'll be open source when we've tidied it all up, so you'll be able to see

5:07 rritoch: Is there any way to check if a resource (URL) is a file or a directory?

5:07 morfeen: dysfun: I thought the Clojure community was against the idea of using monolith frameworks

5:07 Luminus seems to be one, if I am not mistaken

5:07 dysfun: morfeen: it isn't a monolith framework. it's some glue code around a reasonably well chosen selection of libraries

5:07 in fact, i'm not sure it even exists outside of a leiningen template

5:08 morfeen: right, so is Luminus the way to go with web dev? Like express for node?

5:08 dysfun: again, people have their preferences. i like it

5:08 we are, like any other programming language, not short for web frameworks

5:09 morfeen: Cool.

5:09 dysfun: notably we don't use korma per their recommendations because we're using redis to handle our data

5:09 clgv: morfeen: not necessarily. you can just have a look which libraries luminus uses and the you can setup your own project with only a subset of them without using luminus

5:10 dysfun: i'd recommend generating an app with the leiningen template and stripping out anything you don't want. i've done that a few times recently

5:10 rritoch: I didn't realize that getResource requests on OSGi bundles for directories would return a non-null response, so it is screwing up the following code https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/servlet/standard_servlet.clj#L91-L95

5:10 schmir: plain old clojure.jdbc instead of korma is also an option

5:11 dysfun: schmir: if you hate yourself

5:11 morfeen: clgv: cool

5:11 schmir: dysfun: why?

5:12 morfeen: dysfun: What are you guys building? If you don't mind me asking

5:12 dysfun: schmir: because it's painful in the extreme. if i had to use it every day i'd quit my job

5:12 morfeen: an open-source e-commerce platform ("online shop platform")

5:13 clgv: morfeen: optimization algorithms for logistics (but I am the odd one around here ;) )

5:13 morfeen: interesting stuff!

5:13 TEttinger: games.

5:14 morfeen: TEttinger: that's cool! Clojure or Clojurescirpt?

5:14 dysfun: i wanted to do some games using actual clojure and web canvas, but JavaFX is crap :/

5:14 the only way to make it work would be to mix clojurescript and clojure and that started to seem a bit daft

5:15 SagiCZ1: morfeen: i am using clojure to build stock trading platform and automatic trading robots

5:15 TEttinger: morfeen, I have one bad little demo in clojure, but I've been working on making the art assets to do something better.

5:15 dysfun: SagiCZ1: interesting. some people came to me with a similar problem the other day and i said "i'd use clojure". not alone :)

5:16 sveri: Hi there, timbre or something else for logging? Voting is opened now

5:16 dysfun: timbre is very lovely

5:16 TEttinger: the final game project may be in clojure or clojurescript, I'm just not an expert with web stuff

5:16 SagiCZ1: dysfun: the only thing i am concerned about, is that the platform has to be incredibly stable since outages could cost real $$.. i am not sure if clojure is mature enough to run for days without crash.. then again the bugs would be probably introduced by me anyways

5:17 dysfun: SagiCZ1: there are ways around that involving load balancers

5:17 schmir: +1 for timbre

5:18 SagiCZ1: TEttinger: are you using a 3d engine? i would love it if someone could wrap jMonkeyEngine in clojure.. it is very powerful but the API is a mess

5:18 schmir: dysfun: I don't think korma takes much pain away from sql...

5:19 TEttinger: SagiCZ1: erlang and its VM are possibly more reliable than the JVM, but clojure is certainly pretty reliable. My lightly-used IRC bot has had long periods of uptime, only broken when my household internet fails

5:19 schmir: but then I also haven't used it...

5:19 dysfun: schmir: i think it eliminates one category of pain entirely, but does nothing for the fact you still have to think in SQL

5:19 SagiCZ1: TEttinger: thanks for sharing the experience, that's reassuring..

5:21 dysfun: and there's an awful lot of clojure being used in banks. i think we'd have heard something if there was a major problem with stability

5:21 TEttinger: it's running on windows server 2008 R2 (on a laptop; I needed to fresh install and I had a copy of the OS from school for free). that OS has also been surprisingly reliable

5:21 SagiCZ1: dysfun: in banks? never heard of that

5:21 * schmir is thankful for being able to connect with jdbc to a 15 year old InformixSE database

5:21 SagiCZ1: TEttinger: i was thinking whether i really need to run this on linux since i am a windows guy.. maybe windows server would be an option

5:22 TEttinger: linux is cheaper if you aren't a student :)

5:22 BSD is also legendary for its reliability

5:22 SagiCZ1: TEttinger: i actually do have dreamspark licence so its free anyways

5:22 TEttinger: heh, good then!

5:24 clgv: SagiCZ1: Clojure has been major enough to run for days for a while

5:24 SagiCZ1: I have run experiments spanning at least 3-7 days using all cores on the machines running on 6 machines

5:25 SagiCZ1: clgv: yeah.. i guess the risk of my own bugs would be magnitudes higher than some inherited instability

5:25 clgv: SagiCZ1: yes, that is the challenge ;)

5:26 SagiCZ1: cglv: i actually chose clojure also because it is so easy to test pure functions, compared to traditional junit tests in mutable java which gave me many headaches in my day job

5:26 clgv: SagiCZ1: I had a number of try-catches which ensured that single failing runs do not take down the whole system

5:26 dysfun: SagiCZ1: well we know datomic is being used in lots of banks, and it's written in clojure...

5:26 SagiCZ1: clgv: yeah i am planning on including some sort of recovery system

5:26 dysfun: super cool!

5:27 dysfun: well, 'lots of' may be overstating it, but certainly a handful

5:27 SagiCZ1: dysfun: one would be enough to convince me, banks are serious business

5:29 dysfun: SagiCZ1: you might not say that if you'd worked in one. but those stories aren't for this channel :)

5:29 SagiCZ1: dysfun: hah i see your poitn

5:29 *point

5:30 dysfun: i am constantly amazed the banking system works at all

5:30 SagiCZ1: dysfun: you could be amazed equally about any compex burreocracy system.. (i cant spell)

5:31 dysfun: SagiCZ1: quite. i've had my fill of beaurocracies for a while

5:31 clgv: "office jackstraw games"? the first one to move in office losses? ;)

5:32 dysfun: if you find yourself in the office at 1 in the morning, ever, you should seriously take a look at your life and how it got this way

5:34 clgv: oh yeah that's bad.

5:34 my personal record is around 11pm - shortly before submission deadline ended

5:34 Glenjamin: i know a few places that still do really-late-night rollouts

5:35 dysfun: hah, i pulled an all nighter once

5:35 morfeen: Could you recommend a Clojure book for me? I am a node developer, so I am used to some of the ideas of functional programming, like higher order functions. I am currently reading Clojure in action.

5:35 dysfun: Glenjamin: if your system isn't set up to facilitate remotely flicking a switch to roll backwards and forwards, make it so

5:35 schmir: morfeen: joy of clojure.

5:35 morfeen: but finish clojure in action first

5:35 dysfun: morfeen: The joy of clojure is quite good if you like the functional bits. and it does a good job of explaining why if you understand some already

5:36 morfeen: schmir: is Joy of Clojure a reference book?

5:36 dysfun: no, it's a guided tour through the language

5:36 Glenjamin: mm, very much so

5:36 dysfun: there's enough material to make it a useful reference, i suppose

5:37 schmir: morfeen: no, but it's probably not the best book if you know nothing about clojure

5:37 morfeen: so, Joy of Clojure is mostly about the philosophy?

5:37 dysfun: schmir: on the other hand i find clojure in action to be a terrible book

5:37 morfeen: dysfun: why is that?

5:38 dysfun: mostly because we have much better libraries these days and it's getting old

5:38 schmir: dysfun: I read it a few years ago...and I think it was ok.

5:38 dysfun: but because the libraries were crap back then, it's a very hard progression

5:39 schmir: speaking about libraries...the clojure cookbook is nice

5:39 dysfun: and by introducing things like redis pretty early on, the author overloads you with information too quickly

5:39 it's more like "how to solve the specific problem i solved with clojure, and a bad tutorial to step you into it"

5:40 if you have the same problem, and you come at it with with existing knowledge of the other tools he uses, i can see it might be useful

5:41 Glenjamin: i found the most helpful thing when learning clojure was to have a problem to solve

5:41 dysfun: or a project :)

5:41 Glenjamin: tutorials/4clojure/koans to get started, then dive into a problem/project and keep looking things up

5:59 SagiCZ1: morfeen: i would strongly suggest to avoid Joy of Clojure.. i personally regret the time spending reading through this book, which is very long for what it has to offer.. i followed it with Clojure Programming and felt that it was much better read with more value to it.. try it.. also braveclojure is not that bad, koans and 4clojure is also enjoyable

6:14 m1dnight_: If i have (assoc {} \x 10), how do I get the value for \x?

6:14 I figured (\x <map) but that doesn't work

6:14 Bronsa: (get {\x 10} \x)

6:14 ,(get {\x 10} \x)

6:14 clojurebot: 10

6:14 m1dnight_: oh

6:14 Bronsa: ,({\x 10} \x)

6:14 clojurebot: 10

6:15 m1dnight_: oooh

6:15 but..

6:15 ,(:key {:key value})

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

6:15 m1dnight_: okay i must have been mistaken

6:15 thnx

6:15 SagiCZ1: ,(:key {:key 'value})

6:15 clojurebot: value

6:15 Bronsa: ,(:foo {:foo 1})

6:15 clojurebot: 1

6:15 Bronsa: m1dnight_: in clojure, keywords are functions

6:15 m1dnight_: maps vectors and sets are also functions

6:15 m1dnight_: char literals are not

6:16 SagiCZ1: and although maps are also functions, its recommended to use keywords as function, if you want to switch to records later

6:20 dysfun: why? don't records also act as functions like maps?

6:20 Bronsa: no

6:20 SagiCZ1: dysfun: they don't

6:20 dysfun: hrm

6:20 that seems an omission

6:20 Bronsa: you might want to implement a different IFn behaviour

6:20 dysfun: oh i see what you mean

6:21 it seems like a sensible default though

6:25 morfeen: SagiCZ1: thanks, will checkout Clojure Programming.

6:26 SagiCZ1: morfeen: the authors are Emerick, Carper, Grand

6:27 morfeen: SagiCZI: I'm currently reading Clojure in Action, have you read that book?

6:27 SagiCZ1: nope, is it good?

6:28 morfeen: It's alright, but some people in this channel do not recommend it

6:28 dysfun: i think it was just me, actually

6:28 SagiCZ1: i see..

6:28 opinions may differ i guess

6:28 morfeen: dysfun: some people, was you :D

6:28 clgv: morfeen: "Programming Clojure" (now in 2nd edition) was really good to get going rapidly

6:28 morfeen: clgv: great!

6:29 clgv: morfeen: pay attention to the order of the two words..

6:29 two pretty different books

6:29 morfeen: clgv: order of what 2 words?

6:29 SagiCZ1: there is also a very interesting chapter explaining how to develop really abstract code in a way i wouldnt imagine before

6:29 morfeen: Ah alright

6:30 dysfun: clgv: my flatmate is learning clojure. he programs mostly scala. would you recommend it to him as an intro?

6:30 SagiCZ1: oh its a different book

6:30 nevermind

6:31 clgv: dysfun: I'd make the choice between "Programming Clojure" and "Clojure Programming" depending on which writing style you like better

6:31 dysfun: I think that both have sample chapters

6:31 Glenjamin: as in your preferred noun-verb order?

6:31 SagiCZ1: Glenjamin: :D

6:31 dysfun: (inc Glenjamin)

6:31 lazybot: ⇒ 9

6:32 morfeen: SagiCZ1, clgv: You are both talking about different books right?

6:32 SagiCZ1: morfeen: yes

6:32 morfeen: So of the 2, which one should I read, if I want to get up to speed real quick?

6:32 clgv: morfeen: see my comment above ,)

6:33 SagiCZ1: morfeen: i cant compare, sorry

6:33 morfeen: I mean, I do have some exposure of FP with Javascript.

6:34 clgv: morfeen: from my point of view "Programming Clojure" since it has pretty technical writing opposed to the more narrative style of "Clojure Programming"

6:34 SagiCZ1: i started from scratch and Clojure Programming was easy to grasp so it might be to slow for you

6:34 *too slow

6:34 clgv: morfeen: but have a look at their sample chapters

6:34 morfeen: Cool.

6:35 clgv: replace "has pretty technical writing" by "is written in a more technical style"

6:35 ;)

6:38 kyrre: morfeen, i'd get programming clojure and then after a while follow it up with "the joy of clojure"

7:00 morfeen: kyrre: Cool. Programming Clojure it is then.

7:01 clgv: morfeen: make sure you get the 2nd edition

7:05 boyscared: it's clojure conj day!!@#!

7:05 there aint no party like a clojure conj party

7:05 cuz a clojure conj party infinitely recurses

7:06 clgv: ah really?

7:06 * clgv checksout the program

7:10 clgv: "tex in clojure" sounds interesting

7:19 luxbock: how long did it take the last time for the talks to be uploaded online?

7:23 clgv: 1-2 months it seems

7:23 judging from youtube info "posted on" and the conference date

7:42 jmnoz: beginner question: where can I find information about how to modify/troubleshoot project dependencies?

7:43 mavbozo: assuming you use leiningen: lein deps :tree

7:44 jmnoz: but if I want to modify the code in one of my dependencies?

7:47 mavbozo: jmnoz: I misunderstood you, what kind of problem that makes you think that you have to change the code in you dependencies?

7:47 *your dependencies*?

7:48 jmnoz: I am trying the lein-plugin figwheel on a windows machine and there seems to be some error with path names in that code.

7:49 I would like to troubleshoot figwheel, should I clone the git repository and somehow point leiningen at my local files?

7:52 mavbozo: jmnoz: yeah, I met that kind of path problem too. I did clone the lib repo and install it locally and modify it to find the problem.

7:52 jmnoz: ha! :)

7:54 rritoch: jmnoz: Yes, clone the repository locally and make your changes, you can then use "lein install" to install them to your localrepo, you may also want to change the version number to an unreleased version so there's little risk of changes made by the maintainer overwriting your local deployment.

7:54 jmnoz: excellent, thanks

7:55 mavbozo: jmnoz: there's a instruction to install lein plugin here https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

7:55 jmnoz: basically you just run lein install in your plugin project

7:55 jmnoz: alright great, thanks folks.

7:56 mavbozo: jmnoz: and creating .lein-classpath in your own project directory that contains path to the src directory of the above plugin

7:56 dysfun: justin_smith: i'm wanting to integrate some full packet logging into groundhog, wondering if you had any thoughts

7:57 well, some content and timings anyway

7:59 clgv: woah, building "pixie" requires quite some time.

7:59 dysfun: llvm :)

7:59 clgv: no pypy

8:00 dysfun: oh right. i was confusing it with the other one

8:00 but pypy is llvm, no?

8:01 clgv: not that I know

8:02 dysfun: ah, it's RPython

8:02 which transpiles to c

8:19 tbaldridge: Yeah, the RPython translation process is one of the most advanced partial evaluators I've ever seen. That's why it takes so much time.

8:20 I've tried compiling a RPython program before that contained a lisp program as a string, it did so much partial evaluation, it didn't even build the compiler, it just read/compiled/ran the lisp program and emitted the output as a constant.

8:21 Bronsa: sounds impressive

8:22 clrnd: tbaldridge, wait, what?

8:24 tbaldridge: clrnd: if the input to your reader/interpreter is a constant inside the interpreter, then that string's compiled output is a constant.

8:24 clrnd: so running something like this in RPython (defn -main [] (eval (read-string "42"))) gets compiled as int main () {return 42;}

8:25 clrnd: I'm not sure what RPython is, but why does it know Lisp?

8:33 jmglov: I'm seeing the classic "Exception in thread "main" java.lang.NoClassDefFoundError: clojure/tools/logging/impl/LoggerFactory" error when aot compiling a project that depends on clojure.tools.logging.

8:33 I figured I'd stop by and see if anyone has some insights to get me unstuck.

8:34 I did some research, and found others having the issue, but I couldn't find any solutions out there.

8:35 This guy is using clojure.tools.logging and logback together, which is exactly my configuration: https://groups.google.com/forum/#!msg/datomic/6xWGFB-Dx68/_Hr2I4lv39gJ

8:46 mnngfltg: jmglov, does it work in a simple project (after `lein new`)? Maybe there's some interference with another package you're including.

8:47 jmglov: mnngfltg: It looks like this bug: http://dev.clojure.org/jira/browse/CLJ-1544

8:47 There's a minimal repro in this repo: https://github.com/arohner/clj-aot-repro

8:47 sdegutis: Most of the return values from my API (see https://github.com/sdegutis/clover) are in vectors because they act like tuples, but some of them are single values (like :404), so should those be in vectors for consistency, or just bare for simplicity and/or efficiency?

8:47 mnngfltg: jmglov, can you disable AOT?

8:48 jmglov: mnngfltg: Nope, because this library is being used by a Ring app that is deployed with "ring uberwar", which does some AOT compilation.

8:48 I definitely stay away from AOT if I can. :)

8:49 tbaldridge: sdegutis: I'd convert everything into maps. Vectors/tuples imply meaning in the ordering. This makes programatic use of your api harder as you have to somehow express to the program(er) what each slot means.

8:49 mnngfltg: jmglov, too bad. Sorry I don't know nothing about the issue

8:49 tbaldridge: sdegutis: better explicit than implicit.

8:50 jmglov: mnngfltg: No worries. Do you know anything about how AOT works?

8:50 mnngfltg: know :(

8:51 no :(

8:51 sdegutis: tbaldridge: One of the goals of my API is simplicity, so we return [:redirect "/"] because it's shorter and easier to type and remember than {:operation :redirect, :location "/"} or something similar.

8:51 jmglov: I'm seeing if I can hack around this by AOT compiling c.t.l, then rsyncing its target/ into my project's target.

8:51 tbaldridge: sdegutis: but it's not simple, what does slot 1 and slot 2 mean?

8:51 sdegutis: if you pass me a map I know it instantly, I don't have to ask you

8:51 sdegutis: tbaldridge: The ideal is that valid return value patterns would be easy enough for the programmer to remember, and in the cases where memory fails, there'll be a lookup table in the docs.

8:52 tbaldridge: sdegutis: the ideal is data that is self-expressing.

8:52 sdegutis: tbaldridge: That's true, until you forget what the keys are (I've forgotten Ring's keywords many times).

8:52 tbaldridge: sdegutis: if I forget a english keyword name, how on earth am I going to remember what slot 1 is vs slot 2?

8:53 words are quite a bit easier to understand vs raw numbers

8:53 sdegutis: tbaldridge: They should be obvious by reflecting the order of a function call, like [:redirect "/"] or [:404].

8:53 So I'm wondering, should I indicate 404 by returning [:404] or just :404 ?

8:53 Everything else in my API uses [...] so far, so I'm leaning towards [:404] for consistency.

8:54 tbaldridge: sdegutis: well you often want a message with the error, bare error codes rarely are sufficient

8:54 especially for 400 errors

8:54 sdegutis: Wait, 404 error codes come with a message?

8:55 tbaldridge: Do you mean the HTML of the page that a 404 error can return?

8:55 sveri: Hi, what is the fastest way to integrate a simple storage engine with restart persistence for some key / values only, at best case it can be redistributed with the application and requires no extra setup on running the application

8:55 tbaldridge: 400 = bad data, so when you send that error, it's often nice to say "400 - you didn't give a valid email address"

8:56 sdegutis: Ah! Well then, that's a fine reason to use [:404] :)

8:56 Thanks tbaldridge :)

8:56 tbaldridge: sdegutis: have fun with vectors once you start including extra headers, encoding options, etc, then the vector approach is going to fall apart.

8:57 sdegutis: tbaldridge: Good point. I'll probably also allow maps as a fallback for more complex return values, but the goal is to avoid having more complex return values in the first place, or at least that they be very rare.

8:58 tbaldridge: 99% of my web app's return values are simple and can be expressed either like [:404] or [:redirect "/cart"] or [:render {:user-name username}] or similar.

9:00 jmglov: Ugh, that worked.

9:01 Bronsa: sdegutis: kind of funny that the other day you were complaining about clojure libs being written by the authors ad-hoc to solve their problems and now you're desigining a lib based on your web app's needs

9:02 sdegutis: Bronsa: I wasn't complaining, I was stating the facts :)

9:02 jmglov: I cloned git@github.com:clojure/tools.logging.git, added ":aot :all" to the project.clj, did a "lein compile", then copied tools.logging/target to my project dir. Then a "lein compile" of my project worked.

9:02 tbaldridge: sdegutis: that's kindof my point though, you can express that as {:status :redirect :url "/cart"} and then you won't have to make your framework accept vectors or maps. Having conditional logic like that is kindof a code-smell

9:02 Bronsa: your opinions, not facts

9:02 sdegutis: Bronsa: Okay :)

9:02 tbaldridge: and when you're starting your framework design with code-smells, that's also a code-smell.

9:02 jmglov: I'll drop that into the bug report, just to help out poor souls like me.

9:02 tbaldridge: that's what I'm reacting against here.

9:02 jmglov: But I don't like it, no sir!

9:03 sdegutis: tbaldridge: I would have (strongly) agreed with you a year or two ago on that.

9:04 tbaldridge: But I am beginning to disagree with the principles that I held strongly as I came into the Clojure community (which also holds them strongly).

9:04 Bronsa: jmglov: don't open a ticket on tools.logging's jira, your bug doesn't seem like a bug there at all

9:05 sdegutis: tbaldridge: Now it seems very reasonable to me to provide shortcuts where they make good sense. However, I do think that determining if it makes good sense requires a bit of time working *without* said shortcuts to get to know the problem domain very intimately first.

9:06 jmglov: Bronsa: Sorry, I was talking about the Clojure bug I linked previously: http://dev.clojure.org/jira/browse/CLJ-1544

9:06 Bronsa: jmglov: ah ok, sorry

9:06 jmglov: You are certainly right that the bug has nothing to do with tools.logging.

9:06 It's just a crazy compile-order issue with AOT in the Clojure compiler, best I can tell.

9:07 But hey! I learned something new in the last 3 hours of troubleshooting this. :)

9:08 Bronsa: unfortunately there are quite a bunch of bugs related to aot compilation

9:09 most of them are related to what I believe is a wrong classloader setup by the compiler but I never investigated this

9:09 jmglov: Interesting.

9:10 I'm certainly going to read the commit that fixes the bug.

9:10 sdegutis: Speaking of which, every time I add :main to "project.clj", I get some weird error when doing `lein ubarjar` talking about AOT or whatever. When will that go away? I'm using the latest lein (2.5.0).

9:10 * jmglov is a hopeless optimist.

9:10 jmglov: sdegutis: You actually need to add an :aot directive for that namespace.

9:10 Lemme find an example...

9:10 Bronsa: jmglov: best of luck waiting for that commit

9:11 sdegutis: Oh.

9:11 Is using :main & :aot the recommended way to give a `lein uberjar` file a 'main' function to run?

9:12 jmglov: Ah yes: (defproject "foo" "0.1", :main foo.core, :aot [foo.core]}

9:12 sdegutis: Yes, AFAIK.

9:13 At least, that's what my Googling seemed to indicate a few months back when I was trying to figure out how to get rid of that warning. :)

9:13 sdegutis: :)

9:19 clgv: tbaldridge: so it did finish meanwhile. note to myself recompile during meetings ;)

9:20 tbaldridge: does pixie have exploratory functions to find out what functions/macros are defined=

9:26 sdegutis: Anyone interested in working with me to port http://slim-lang.com/ to Clojure?

9:26 I found a good name for it: https://github.com/sdegutis/slim-cljm

9:32 mearnsh: half the work done then

9:40 egli: sdegutis: I don't see what slim could give you over hiccup

9:41 sdegutis: egli: inline Markdown

9:41 egli: hiccup has actual data structs

9:41 slim has indenting and weird conventions

9:42 can't you have inline md in hiccup?

9:42 in the sense of [:h1 (markdown "**foo**)]

9:42 sdegutis: egli: Sure, if you want to put the entire thing inside a giant string. Not very pretty when it's multi-line.

9:43 egli: Our website's "/legal" page is mostly Markdown, and it's incredibly awkward to have expressed it in Hiccup.

9:43 egli: aren't there md->html->hiccup converters?

9:44 sdegutis: Uhh...

9:44 What would that look like?

9:45 Frozenlock: this? https://github.com/chameco/Hitman

9:45 egli: sdegutis: feed in md out comes html pipe it through another converter and you get hiccup

9:45 Frozenlock: Or even this https://github.com/theJohnnyBrown/endophile

9:46 sdegutis: Instaparse is awesome.

9:47 Frozenlock: I should start a project to play with it.

9:47 I heard all kind of praises for instaparse.

9:49 sdegutis: Anyway that still doesn't address the problem I want to solve, which is to write inline Markdown.

9:49 luxbock: there's now Instaparse for ClojureScript as well

9:49 Frozenlock: o_O

9:49 luxbock: https://github.com/lbradstreet/instaparse-cljs

9:51 Frozenlock: sdegutis: you want to write markdown into a clj file? (as opposed to slurp it)

9:51 sdegutis: No, I want to write it into my Slim file.

9:51 It gets tedious after a while to write all sorts of double-quotes everywhere just because you want to write raw (or interpreted) content.

9:52 That's why http://slim-lang.com/ is so appealing to me.

9:54 TEttinger: huh, I hadn't seen https://codeclimate.com/ before

10:05 sveri: what happened to lighttable, no more menus in 0.7.1?

10:11 tbaldridge: that's one reason I moved away from LT, each version seemed to remove more of the GUI.

10:11 sdegutis: It's the evolution of Emacs, so its destiny is to have no GUI.

10:11 Frozenlock: sdegutis: really? Emacs seems to be its ultimate form. :-p

10:12 teslanick: LightTable: This Isn't Even My Final Form

10:12 Frozenlock: teslanick: that's what emacs tell me each time I open my .emacs file.

10:12 *tells

10:13 daniel_: nick

10:13 mavbozo: tbaldridge: what do you use as LT replacement?

10:14 tbaldridge: I've tried LT a few times, used to use emacs, now I use Cursive 100% of the time

10:14 sdegutis: Is there a lazier way to specify (-> 3 foo bar quux)?

10:15 Er sorry, #(-> % foo bar quux), in other words, a function.

10:15 Bronsa: what do you mean by lazier

10:15 sdegutis: (= (-> 3 inc inc) ((comp inc inc) 3))

10:15 ,(= (-> 3 inc inc) ((comp inc inc) 3))

10:15 clojurebot: true

10:15 sdegutis: Ah, comp is like -> then?

10:15 Bronsa: no

10:16 ,((comp inc -) 2)

10:16 clojurebot: -1

10:16 Bronsa: ,(-> 2 inc -)

10:16 clojurebot: -3

10:16 sdegutis: ,(= (-> 3 inc -) ((comp - inc) 3))

10:16 clojurebot: true

10:16 sdegutis: Ah, they're backwards.

10:16 Good!

10:17 Bronsa: reverse order, also comp is a function that returns a function, -> is a macro that does lexical transformation

10:18 so (comp foo bar) ~= #(-> % bar foo)

10:18 it's actually #(->> %& (apply bar) foo)

10:19 sdegutis: Oh, also -> calls the function immediately with args, comp does't.

10:19 So (-> 3 (foo)) turns into ((comp #(foo %)) 3)

10:19 Yikes.

10:19 Bronsa: ,(macroexpand-1 '(-> 3 (foo)))

10:19 clojurebot: (foo 3)

10:20 sdegutis: Right.

10:20 Frozenlock: lol

10:20 clojurebot: Excuse me?

10:20 mavbozo`: ,%&

10:20 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %& in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:20 Bronsa: mavbozo`: it's #() syntax

10:20 ,(#(vec %&) 1 2 3 4)

10:20 clojurebot: [1 2 3 4]

10:21 Bronsa: ,(#(vec % %&) 1 2 3 4)

10:21 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/vec>

10:21 Bronsa: ,(#(vector % %&) 1 2 3 4)

10:21 clojurebot: [1 (2 3 4)]

10:21 Bronsa: ,(#(vector %1 %2 %&) 1 2 3 4)

10:21 clojurebot: [1 2 (3 4)]

10:21 Bronsa: mavbozo`: %& is & foo for the #() fn literal

10:22 mavbozo`: (inc Bronsa )

10:22 lazybot: ⇒ 2

10:23 Bronsa: mavbozo`: no space before the paren ;)

10:23 sdegutis: I'm trying to turn a bunch of (-> routes (wrap-reload) (wrap-cookies) ...) into a function that can take a routes later.

10:23 The only solution I came up with was to put # around it and replace routes with %

10:23 Bronsa: sdegutis: what's wrong with that?

10:23 sdegutis: It's just not as pretty I guess.

10:24 sveri: I use cursive myself, but I like the instant of LT and therefor use it for this from time to time

10:24 mavbozo`: (inc Bronsa)

10:24 lazybot: ⇒ 73

10:25 Bronsa: sdegutis: I dislike #() and % myself, but they are handy. I worked around this by prettifying them via font-lock

10:25 sdegutis: I meant pretty in a different way.

10:26 agarman: ƒ(... ) is nice looking

10:26 luxbock: Bronsa: what do you use for that? pretty-mode?

10:26 Bronsa: i.e. this is how I see #(-> foo % bar) http://i.imgur.com/mk3nv65.png

10:27 luxbock: no https://github.com/Bronsa/.emacs.d/blob/master/config/hooks.el#L11-L31

10:27 andrewhr: the sad thing about Cursive it’s the buggy experience of IntelliJ’s Ideavim

10:29 luxbock: Bronsa: thanks, I'll these out

10:32 otfrom: anyone here at the conj?

10:33 hyPiRion: yess

10:33 clgv: hyPiRion: did the talks start, yet?

10:33 hyPiRion: where is the live stream? ;)

10:33 tbaldridge: clgv: no live stream, but they said they're doing "same day upload"

10:34 hyPiRion: idk if there's a live stream, but yes, we've been through two

10:35 andrewhr: tbaldridge: nice to know! :)

10:35 tbaldridge: https://twitter.com/clojure_conj/status/535087288725012480

10:36 That's the official tweet, and a link to the YT account

10:36 Frozenlock: Same day upload? That's amazing!

10:37 * Frozenlock remembers when he had to wait 6 months for the conj videos

10:37 tbaldridge: they pulled it off at Clojure/West, I think my talk was online 4 hours after I gave it

10:37 Frozenlock: most of that was due to InfoQ from what I understand, they delay things like crazy

10:38 Frozenlock: Ah, that would explain a lot...

10:38 tbaldridge: I think their goal was a steady stream of talks year round, and they didn't want some sort of "here's 20 Clojure talks" thing either. So they'd interleave conference videos and then only release 2-3 videos a week.

10:39 I understand why they did that, but it's still a bad idea IMO.

10:39 clgv: tbaldridge: oh that'd be great

10:40 I am interest in th Tex+Clojure combination - I couldnt find its repository so far

10:43 sdegutis: ,(:path (meta (defn ^{:method :get, :path "/foo/:bar"} get-foo-bar [] 3)))

10:43 clojurebot: "/foo/:bar"

10:43 gfredericks: does anybody know if I can get emails for all activity on a project on jira?

10:44 Bronsa: gfredericks: you have to ping puredanger for that

10:44 gfredericks: oh

10:44 Bronsa: gfredericks: I think ATM only project leads get emails on activity

10:45 gfredericks: maybe andyf can do that too, not really sure

10:45 clgv: gfredericks: test.check?

10:47 gfredericks: yeah

10:47 dogonthehorizon: Greetings all, I'm attempting to call java.nio.file.Paths/get in my code with a string argument but the REPL is using the URI variant of the function instead... any idea on how I can force it to use the string variant instead?

10:48 clgv: gfredericks: oh, it has a new release :)

10:48 gfredericks: oh cool

10:50 clgv: shrinking shuffle :)

10:50 luxbock: Bronsa: now my clj files do indeed look a lot prettier

10:51 I added a font-lock-builtin-face for the lambda character as well

10:52 Bronsa: luxbock: nice

10:53 justin_smith: dysfun: cool

10:54 Bronsa: ... hudson won't cut releases again

10:54 this is so annoying

10:57 justin_smith: dysfun: care to elaborate? the reference to packets seems abit odd since it is inside ring and all...

10:57 boyscared: good conj so far

10:59 andyf: gfredericks: I don?t know how to set it up for you to get all updates for a whole project

10:59 project leads do, but not sure if that is possible, or how, for others.

11:00 daniel_: is there a live feed of the conj?

11:00 boyscared: no

11:00 Bronsa: I'm so done with hudson

11:00 boyscared: the vids should be on clojuretv shortly after concluding though

11:01 daniel_: cool

11:03 simpleirc1: hi why people choose clojure over cl?

11:03 clgv: simpleirc1: jvm nad its million libraries

11:03 gfredericks: andyf: computers are hard

11:03 clgv: *and

11:04 mavbozo``: simpleirc1: awesome community

11:04 daniel_: simpleirc1: its not so fringe

11:04 tbaldridge: simpleirc1: also, the JVM GC and JIT are top notch, really hard to beat for the "normal" use cases of Clojure.

11:05 clgv: mavbozo``: sell the "someone else has done the basic tasks for a lot of domains already" first ;)

11:05 andyf: simpleirc1: Some people have found that they really like data that is immutable by default, with explicit places you can say 'this is mutable'.

11:05 CL tends to be mutable by default

11:05 Bronsa: I guess I won't cut a t.a release today

11:05 SagiCZ1: tbaldridge: its actually super easy to write a code that holds on references thus causing memory leaks in clojure..

11:06 dysfun: justin_smith: packets wasn't what i actually meant. i meant to record the timings of data coming in and out to provide an idea of how long bits of response take to happen and can be analysed later in aggregate

11:06 tbaldridge: SagiCZ1: that's easy in any language with lazy constructs

11:06 Ever since I started using transducers problems like that completely disappeared for me.

11:06 SagiCZ1: i gues.. it usually didnt happen to me in java

11:06 tbaldridge: SagiCZ1: how often did you use lazy seqs i Java? ;-)

11:06 Bronsa: SagiCZ1: java doesn't have lazy-seqs

11:07 SagiCZ1: i know i know... i was trying to say i didnt use any languages with lazy constructs before

11:07 tbaldridge: Fun fact, Rich used to write Common Lisp: http://foil.sourceforge.net/

11:07 mavbozo: http://cdn.cognitect.com/stateofclojure/2014/clj-general.txt

11:07 from the latest clojure survey

11:08 clgv: SagiCZ1: holding on to the wrong reference is pretty usual in java before someone takes the time and hunts those down ;)

11:08 justin_smith: dysfun: aha, I have something like that as its own middleware, one moment

11:08 andyf: simpleirc1: Search for "Clojure for Lisp programmers" on YouTube for a talk by Rich on some of the design goals of Clojure that were different from CL, by choice.

11:08 tbaldridge: but from what I've heard, Haskell has the same problems. The entire language is lazy, so sometimes you "blow the heap"

11:09 justin_smith: $google clojure for lisp programmers youtube hickey

11:09 lazybot: [Clojure for Lisp Programmers Part 1 - Rich Hickey - YouTube] http://www.youtube.com/watch?v=cPNkH-7PRTk

11:09 justin_smith: it was worth a shot :)

11:09 Bronsa: tbaldridge: does pixie have "proper" lazy-seqs or only sequence+transduce style lazy-seqs?

11:11 clgv: technomancy: currently the fibonacci on pixie doesnt seem to beat a non-optimized clojure one, though I couldn't really time it, since I have no idea how to get timestamps in pixie ;)

11:12 TEttinger: clgv: did you mean that for tbaldridge?

11:12 daniel_: whats pixie

11:12 Glenjamin: $google pixie lisp

11:12 lazybot: [pixie-lang/pixie · GitHub] https://github.com/pixie-lang/pixie

11:12 TEttinger: daniel_: clojure-inspired lisp running on the same kind of VM as PyPy

11:12 clgv: TEttinger: no technomancy was asking the hard question how the performance of the fibonacci function is on pixie ;)

11:13 Glenjamin: which reminds me, i should take another crack at getting pixie to build

11:13 clgv: that got me curious as well. but I guess there are no optimizations for that yet ;)

11:14 Glenjamin: current master built just fine some hours ago - you need libuv-dev and libffi-dev though

11:14 Glenjamin: yeah, pkgconfig on os x is annoying

11:14 combined with me not really knowing how it works

11:15 clgv: Glenjamin: on debian-based OS it is just an "apt-get install" away ;)

11:15 Glenjamin: i think i have ffi and uv installed now, just need the makefile to find them

11:15 clgv: you can take a coffee or two during build :D

11:16 Glenjamin: seems to be going using the notes on https://github.com/pixie-lang/pixie/issues/49

11:17 warnings are ruining the nice picture

11:17 tbaldridge: Glenjamin: yeah, the warnings are being fixed.

11:17 clgv: hehe. it's a pixie, I guess? the warnings ruined it here as well

11:18 tbaldridge: And I'd be more than happy to help people build and install pixie, but sadly I'm working today. Will be on 20% time tomorrow, so I'll hang out here as well as in #pixie-lang

11:18 Glenjamin: output like this sounds like made-up tech they use on movies:

11:18 clgv: tbaldridge: did someone spend hours on the ascii image progressbar or is that generated from an image?

11:18 Glenjamin: [jitcodewriter:info] there are 988 JitCode instances.

11:18 tbaldridge: clgv: it's a mandelbrot fractal

11:19 clgv: tbaldridge: oh interesting. do I find its parameters in the pixie repository?

11:19 SagiCZ1: does average clojure newbie need to learn about transducers or is it some super hard core niche thing i would use once in ten projects?

11:19 tbaldridge: clgv: actually that's part of the RPython compiler framework, it does it on its own.

11:19 clgv: SagiCZ1: I'd say, not immediately

11:19 Frozenlock: I never looked at transducers. Shameful, I know...

11:19 clgv: tbaldridge: ah ok

11:19 sdegutis: ,(namespace *ns*)

11:19 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Named>

11:20 Bronsa: ,(ns-name *ns*)

11:20 clojurebot: sandbox

11:20 clgv: SagiCZ1: actually as newbie hold on to stable clojure which does not contain transducers ;)

11:20 tbaldridge: SagiCZ1: IDK, I mean we got along for years without them, but these days I think transducers should be taught before lazy seqs.

11:20 SagiCZ1: what is stable clojure? or why is clojure with transducers unstable?

11:20 tbaldridge: once they're stable, there's still a few bugs in transducers.

11:20 hiredman: tbaldridge: a feature which isn't in a released version yet?

11:20 Glenjamin: do you think they should be taught under the "transducers" banner, or just as "here's how to combine a bunch of operations" ?

11:20 TEttinger: 1.7.0 is the transducer release

11:21 it's in alpha

11:21 SagiCZ1: oh i see

11:21 clgv: tbaldridge: really, we didn't really explain that those sequence functions are lazy at all in the first lectures to not confuse the students which knew only Java

11:22 tbaldridge: I guess my point is, why would I ever want lazy-seq map, when I have transducer's map? Transducers give you most of the power of lazy seqs without some of the drawbacks.

11:23 sdegutis: tbaldridge: Which drawbacks?

11:23 tbaldridge: There's no reason to teach features in the order they were released.

11:23 Frozenlock: tbaldridge: do you have a link to a further explanation for this?

11:25 luxbock: tbaldridge: are you working on any videos about transducers? I subscribed to your pivotshare site

11:25 for the core.async videos, but now I'm kind of wondering how much of that stuff is going to be outdated with the addition of transducers

11:26 Glenjamin: oo, RPython now appears to be generating C code

11:27 clgv: tbaldridge: true, but if you introduce students to a completely different paradigm of programming. most try to not to overwhelm then

11:27 tbaldridge: luxbock: yes there are 3 transducer videos, more to come later this week

11:27 clgv: tbaldridge: e.g hey that's a function that applies a given function to all elements of the given list

11:27 Glenjamin: you could teach ##((map inc) [ 1 2 3 ]) instead of the seq version

11:27 lazybot: ⇒ #<core$map$fn__4338$fn__4339 clojure.core$map$fn__4338$fn__4339@45acd1f6>

11:28 Glenjamin: &*clojure-version*

11:28 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

11:28 tbaldridge: clgv: and then you spend the rest of the day explaining how bindings don't work right, how you can't read from a file with them, etc.

11:28 Bronsa: Glenjamin: that's not how transducers work

11:28 Glenjamin: :s

11:28 justin_smith: Glenjamin: I assume you want to call sequence?

11:28 Glenjamin: oh right

11:28 duh

11:28 clgv: tbaldridge: not really. reading files is for later anyway

11:29 luxbock: tbaldridge: ah nice, I hadn't realized they were out already. I sent a request to pivotshare to add RSS feeds as a feature but so far they haven't added it

11:29 Glenjamin: &(sequence (map inc) [ 1 2 3 ])

11:29 lazybot: ⇒ (2 3 4)

11:30 mavbozo: isn't How to Design Programs book a good and tested method on teaching students without overwhelming them?

11:30 clgv: mavbozo: havent heard of it thus far

11:31 tbaldridge: Glenjamin: clgv: the way walked through it in my videos is to start with eager map and filter. Then extract the conj, then integrate it with a loop, now name that loop reduce, etc. One step at a time.

11:31 Teach the rationale, not the public APIs, at least that's how I like to go about it.

11:31 mavbozo: clgv: some consider it a improvement over SICP

11:31 clgv: tbaldridge: sounds good. I did not refer to your videos since I don't know them ;)

11:32 zakwilson: Is there a clojure library with a macro providing functionality similar to and and or, but catching exceptions and treating them as false?

11:33 sdegutis: zakwilson: Not that I know of, I'm not sure I see the benefit to that.

11:33 clgv: zakwilson: easy write-up - you can just modify the source of `and` and `or`

11:34 zakwilson: Yeah, I have no doubt I could write it. I was more wondering how popular the idea was.

11:34 clgv: zakwilson: wrap "(try ~x (catch Exception e false))" around "~x"

11:35 ah probably "nil" is better as return

11:35 justin_smith: I could see that leading to really weird bugs if you did not specify which exceptions you catch

11:36 I can't tell you how many times I have gone down a rabbit hole debugging because some lib was doing a try/catch/nil that one wouldn't expect...

11:36 zakwilson: It can't really do anything that you couldn't do with try/catch, but it seems like it might be clearer in some situations.

11:36 justin_smith: zakwilson: point being it makes the bad behavior easier

11:36 catching all exceptions and returning nil is already a problem

11:37 this is a functional language, your try/catch can easily be wrapping *my* code

11:37 gfredericks: does anybody regularly make use of a "sample" function that returns a random sample of a sequence w/o holding the head?

11:37 clgv: justin_smith: yeah that's the huge disadvantage

11:38 Glenjamin: datapoint: "something_flaky rescue nil" is relatively common in short ruby scripts

11:38 dunno if that's for or against

11:38 zakwilson: justin_smith: yeah, I can see that, though I was just recently dealing with a library in Python that was too far the other way. It returns an object that may or may not have a certain attribute, which should contain a dictionary that may or may not have a certain key.

11:41 It ends up being that it needs to be wrapped in a try/catch or a bunch of really ugly calls to getattr. It would be less problematic in idiomatic Clojure.

11:41 justin_smith: zakwilson: we already have error-free nil returning property lookup (via get or some->)

11:42 tslocke: Is there a core function equivalent to (fn [col] [(map first col) (map second col)]) ?

11:42 justin_smith: ,(some-> [1] .length)

11:43 clojurebot: 1

11:43 justin_smith: ,(some-> nil .length)

11:43 clojurebot: nil

11:43 tbaldridge: tslocke: try juxt !!!

11:43 clgv: zakwilson: isn't duck typing common in python?

11:43 Bronsa: tslocke: (juxt keys vals)?

11:43 justin_smith: tslocke: (map (juxt first second) coll)

11:43 Glenjamin: ~juxt

11:43 clojurebot: juxt is a little hard to grok but it's the best thing ever

11:43 tbaldridge: , ((juxt first second) [[1 2] [3 4]])

11:43 tslocke: ty all

11:43 clojurebot: [[1 2] [3 4]]

11:44 justin_smith: tbaldridge: you may want a map in there :)

11:44 tbaldridge: um, no, bad example

11:44 lol yeah

11:44 Bronsa: justin_smith: that doesn't work the way he asked

11:44 justin_smith: no?

11:44 clojurebot: no is tufflax: there was a question somewhere in there, the answer

11:44 tbaldridge: tslocke: congrats, you just found a use case for everyone's favorite function

11:45 justin_smith: Bronsa: oh, right

11:45 Bronsa: ((juxt keys vals) {1 2 3 4}) vs (map (juxt key val) {1 2 3 4})

11:45 justin_smith: tslocke: Bronsa's right, that's not the answer

11:46 tslocke: ,(map (juxt first second) ‘[[a 1] [b 2] [c 3]])

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

11:46 tslocke: lol

11:46 Bronsa: wut

11:46 justin_smith: tslocke: yeah, that acts as identity

11:46 Bronsa: smartquote

11:46 tslocke: ,(map (juxt first second) `[[a 1] [b 2] [c 3]])

11:46 clojurebot: ([sandbox/a 1] [sandbox/b 2] [sandbox/c 3])

11:47 Bronsa: ,(= \‘ \')

11:47 clojurebot: false

11:47 zakwilson: clgv: yes, but it doesn't help here. If you have an object that supports the expected properties and methods, you can use it in place of another, but my problem involved an object that may or may not have the right properties, despite being the same type.

11:47 Glenjamin: you want the opposite of zip i guess

11:47 EvanR: how do i implement a protocol for the data structure "map"

11:47 Bronsa: fucking unicode

11:47 Glenjamin: EvanR: IAssociative perhaps

11:47 Bronsa: EvanR: extend the protocol to IPersistentMap

11:47 Glenjamin: there's no IAssociative, there's a c.l.Associative

11:48 Glenjamin: bah, i'm rubbish at remembering the interface names

11:48 EvanR: i dont think you can implement protocols for interfaces?

11:48 Bronsa: EvanR: yeah you can

11:48 justin_smith: EvanR: why wouldn't you?

11:48 EvanR: is that new?

11:48 Bronsa: EvanR: nope, always been teh case

11:48 justin_smith: EvanR: that's the point of protocols isn't it

11:48 Glenjamin: i was under the impression you only implement for interfaces

11:48 zakwilson: justin_smith: property lookups of various types are probably the most common use case for error-free-or, and since those are typically error-free anyway....

11:48 Bronsa: btw this is one of my main issues with protocols. in cljs those interfaces are protocols

11:49 Glenjamin: defprotocol generates an interface

11:49 Bronsa: and you can't extend protocols to protocols

11:49 so doing that in clojurescript means extending a protocol to all the concrete types

11:49 which.. should be implementation details

11:49 I would love if clojure had the concept of a "supertype"

11:49 EvanR: ill try

11:50 Bronsa: i.e. PAM, PHM & co would be PersistentMaps & extending a protocol to persistentmap would extend that for every type registered as a PersistentMap

11:54 EvanR: so i can implement a protocol for java classes, java interfaces, types

11:54 but i cant implement java interfaces for any of these right

11:55 Bronsa: you can implement java interfaces for deftypes, you just can't extend an existing class to a java interface

11:55 EvanR: how does that look

11:55 Bronsa: (deftype foo [] Interface (method [arg

11:55 ] body))

11:56 EvanR: ok

11:56 tslocke: fwiw

11:56 ,(reduce #(map conj %1 %2) [[] []] [[:a 1] [:b 2]])

11:56 clojurebot: ([:a :b] [1 2])

11:57 tslocke: Kinda ugly though

11:57 I think transducers would be the way to go but not got them at my fingertips yet

11:57 justin_smith: tslocke: not ugly to me, but maybe I have reduce-stockholm-syndrome

11:57 EvanR: cant resolve IPersistentMap

11:57 Bronsa: EvanR: clojure.lang.IPersistentMap

11:57 justin_smith: EvanR: clojure.lang.

11:58 EvanR: whats the interface for "set"

11:58 Bronsa: IPersistentSet

11:58 justin_smith: ,(clojure.string/join \space (supers (class #{})))

11:58 clojurebot: "interface clojure.lang.IEditableCollection interface java.lang.Runnable interface clojure.lang.IFn class clojure.lang.APersistentSet interface java.io.Serializable interface clojure.lang.IHashEq interface java.util.Collection interface clojure.lang.IObj interface clojure.lang.IMeta interface clojure.lang.IPersistentCollection class java.lang.Object interface java.util.concurrent.Callable interfac...

11:59 justin_smith: for some reason IPersistentSet is near the bottom there...

12:00 $(clojure.string/join \space (supers (class #{})))

12:00 &(clojure.string/join \space (supers (class #{})))

12:00 lazybot: ⇒ "interface clojure.lang.IHashEq interface java.io.Serializable interface clojure.lang.IEditableCollection interface java.util.Set interface java.lang.Runnable class clojure.lang.APersistentSet interface java.util.concurrent.Callable interface java.lang.Iterable inter... https://www.refheap.com/93685

12:03 KnightsWhoSayNi: :q

12:03 blergh

12:04 clgv: Ni! Ni! Ni!

12:05 EvanR: ,((symbol ":a") {:a 2})

12:05 clojurebot: nil

12:05 EvanR: ,((symbol "a") {:a 2})

12:05 clojurebot: nil

12:05 EvanR: whats the big idear

12:06 Bronsa: :a is not a symbol

12:06 it's a keyword

12:06 EvanR: oh

12:07 bcm: Hmm, why test.check?

12:09 gfredericks: bcm: you're asking why it exists?

12:10 justin_smith: ,((keyword "a") {:a 2}) ; EvanR

12:10 clojurebot: 2

12:11 EvanR: yes, and i finally got it to work after saving my file and reloading my source files several times

12:11 clgv: EvanR: you can explore types via ##(type :a)

12:11 lazybot: ⇒ clojure.lang.Keyword

12:11 EvanR: ##?

12:12 justin_smith: EvanR: inline syntax for lazybot

12:12 EvanR: yes i got type

12:13 kenrestivo: ,phm is persistent hash maps

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

12:13 kenrestivo: ~phm is persistent hash maps

12:13 clojurebot: Alles klar

12:15 clgv: phm?

12:15 clojurebot: phm is persistent hash maps

12:15 clgv: clojurebot: botsnack

12:15 clojurebot: thanks; that was delicious. (nom nom nom)

12:15 clgv: you have to reinforce it ;)

12:27 marchdown: Hello there. I’ve a couple of questions about lazy sequences. First, how do I take a difference of two lazy sequences, second, where do I chant appropriate incantations to get bignums in the following example: https://gist.github.com/marchdown/d89c273506f120c9f7ba

12:29 I mean, is there a canonical difference function, or do I have to inspect two lazy sequences element-by-element and discard some by hand?

12:29 dnolen_: marchdown: use +' for auto promotion, no canonical difference function, you probably need to do something by hand

12:29 marchdown: Thanks.

12:30 Yep, that works.

12:30 dnolen_: marchdown: you do have clojure.data/diff, never tried it w/ lazy seqs

12:31 marchdown: What should I read up on once I begin to care about performance? As in timing and profiling tools?

12:32 Bronsa: marchdown: https://github.com/hugoduncan/criterium

12:32 justin_smith: standard java profilers work

12:32 or criterium for microbenchmarks, yeah

12:32 marchdown: Thanks.

12:33 tbaldridge: marchdown: the two rules are a) only benchmark after the code is warm (see criterium for help) b) don't profile inside lein, it does crazy stuff to the JVM to help with development.

12:33 sometimes at the cost of runtime performance.

12:34 clgv: it should be safe to profile within "lein" when your profile.clj replaces the default jvm args lein sets

12:34 btw. recent versions of criterium warn when that is not the case

12:34 tbaldridge: probably, but I don't like to risk it. I just compile via uberjar and then do java -jar.

12:35 technomancy: lein with-profile production run ...

12:35 marchdown: regarding lein, how do I grow past single core.clj source file? Simply adding (ns foo.core (:require foo.bar)) is not enough to call quux defined in bar.clj

12:36 technomancy: marchdown: (:require [foo.bar :as bar])

12:36 bar/quux

12:36 marchdown: Thanks!

12:37 noonian: or (:require [foo.bar :refer [quux]])

12:37 tbaldridge: technomancy: but what are the settings of with-profile production? That's the problem if I'm citing benchmark results it's easier to just use a jar and remove all doubt.

12:38 TimMc: marchdown: Or your original :require, but then use foo.bar/quux

12:38 technomancy: tbaldridge: production is an empty profile

12:38 tbaldridge: technomancy: that goes for any dev tool btw, not just lein

12:39 technomancy: but yeah, the closer to production the better

12:40 don't profile on a mac if you're deploying on linux

12:40 gfredericks: hey I just succeeded in getting the phrase "test.chuck" onto a slide at clojure conj

12:44 clgv: gfredericks: you did a talk about test.check?

12:44 and snuck in the lovely chuck? ;)

12:45 gfredericks: no I'm not even there

12:45 somebody mentioned test.chuck

12:45 clgv: ah kk

13:21 sdegutis: So far this API isn't looking different enough to be worthwhile: https://github.com/sdegutis/clover

13:25 expez: Given a jar, how would I go about getting a list of all exported symbols?

13:26 justin_smith: expez: you can open the jar as a zip file and look at the namespaces

13:26 there is no specific "list of vars created in a jar"

13:26 expez: or do you mean classes/

13:27 expez: justin_smith: Vars, initially, but would like to do classes too. Visual inspection is not an option. I was thinking maybe I could ingest everything with tools.analyzer and query the ASTs or something

13:27 justin_smith: expez: the problem is there is no manifest that lists all namespaces contained

13:28 expez: just consume all .clj files?

13:28 justin_smith: not to meantion dirty tricks that create a var without using top level def / defn

13:28 expez: I guess you could hack that up with t.a.jvm yeah

13:29 expez: I was thinking an 'import symbol at point' operation would be nice for clj-refactor. it would then build a cache of symbols on the classpath and just import it if it's one or prompt you if several.

13:29 justin_smith: expez: you keep saying symbol when you mean var

13:29 expez: Building ASTs are expensive, but you could cache that stuff

13:30 my bad, is java.util.Date. considered a var?

13:30 justin_smith: maybe you are looking for some sort of compile time abstraction

13:30 but it isn't a symbol, or a var

13:31 it's a reader macro that resolves to (new java.util.Date)

13:31 expez: the thing at point might not even resolve to a var, right?

13:31 justin_smith: right

13:31 Bronsa: well it *is* a symbol justin_smith

13:31 justin_smith: Bronsa: OK

13:32 Bronsa: also it's not a reader macro

13:32 justin_smith: just not one that can be read as such

13:32 Bronsa: ,(read-string "foo.")

13:32 clojurebot: foo.

13:32 expez: clojure.tools.analyzer.ast.query this looks like it might have some stuff, where you can build a db from ASTs and query it.

13:32 Bronsa: justin_smith: it can be read, the transformation happens at macroexpansion time not at read-time

13:32 justin_smith: Bronsa: oh, thanks for clearing that up

13:33 Bronsa: I have no idea what I'd call that though

13:33 a macroexpansion-time transformation

13:33 expez: yeah, you need to depend on Datomic to use that though

13:34 justin_smith: expez: I imagine namespaces like this could easily trip you up https://github.com/Prismatic/hiphip/blob/master/src/hiphip/double.clj

13:35 expez: Does this seme doable, Bronsa? Just ingest every .clj file found on classpath with tools.analyzer to get a list of symbols to possibly import?

13:36 technomancy: expez: are you familiar with slamhound?

13:36 expez: justin_smith: it's just a helper function, if it works 90% of the time that's still cool.

13:36 Bronsa: expez: I wasn't following the conversation, what are you trying to do?

13:36 expez: technomancy: I know what it is. Does it contain code I should pilfer?

13:37 technomancy: expez: well, it does the same thing, basically, but with a dramatically simpler approach

13:37 expez: Bronsa: user hits 'import symbol at point' and clj-refactor imports the symbol below the cursor, possibly with a prompt if it's ambiguous

13:37 technomancy: (all-ns) + (ns-publics n)

13:37 after loading all namespaces on the classpath

13:37 you don't need the analyzer for that

13:37 provided you're OK with compiling everything you find

13:38 Bronsa: you'd need to do that with t.a anyway

13:39 expez: man, didn't even know about all-ns. The docstring is a bit sparse, but the seq is of every ns on the classpath?

13:39 justin_smith: expez: no, all the ones loaded already

13:40 and also, namespaces made by shady methods where the ns does not reflect an artifact in the classpath as well

13:40 Shayanjm: someone should make a cool clj dsl for working with these sets: http://opendata.cern.ch/

13:40 :)

14:00 kenrestivo: using the clojure.tools.namespace.repl/refresh thing... it tries to compile test/ files and chokes on them. anyone else seeing that?

14:01 specifically, it compiles test/foo/core_test.clj which has in it a (:require [foo.core :refer :all]), and can't find that namespace at wherever it is in the compilation at that point

14:08 mi6x3m: hey bbloom, did you by any chance find the reason for the issue yesterday?

14:08 I thought I'd search for it this evening

14:14 emacsnub: does annotating your code w/ core.typed act as type inference?

14:14 act as type hinting

14:15 clrnd: emacsnub, I'm sure core.typed use type inference, otherwise you'd need to type every sub-expression

14:18 amalloy: emacsnub: i would be quite surprised if it acted as typehinting

14:18 emacsnub: amalloy: clrnd: thanks!

14:19 :amalloy so it probably won't improve runtime performance, right

14:19 amalloy: kenrestivo: test/ is on the classpath during dev, so if you attempt to reload everything on the classpath then test/ will be included

14:20 but it should work fine, i would think, as long as the dependencies are declared properly and you don't do anything grossly side-effectful at the top level of your tests

14:20 clrnd: core.typed doesn't touch the runtime at all, afaik

14:21 amalloy: emacsnub: no, core.typed only acts at compile time; as far as i know, the bytecode generated for a function that's typed with core.typed will be identical if you remove the annotations

14:21 emacsnub: oh ok

14:22 thanks again

14:41 gfredericks: so I think something about autocompleting is causing my emacs to be really laggy while typing clojure code

14:41 sound familiar to anybody?

14:42 even worse if I type a prefix of something quickly and then try to autocomplete it, it will likely autocomplete from a prefix of the prefix

14:42 tbaldridge: reason #42 why I stopped using emacs

14:42 gfredericks: what nobody STOPS using emacs

14:42 jaaqo: My lagginess was about cider, cider-nrepl and company version mismatches

14:43 Bronsa: I have never had lag with ac-slime

14:43 technomancy: gfredericks: autocomplete.el?

14:43 joshuafcole: gfredericks: oh?

14:44 :P

14:44 technomancy: gfredericks: it's a pretty crap implementation from what I understand; the alternatives are a lot more stable.

14:44 gfredericks: technomancy: I see "AC" in my modeline; what does that suggest?

14:44 technomancy: gfredericks: yeah, you probably want to ditch that

14:45 jcsims: gfredericks: I switched from auto-complete to company awhile back, and it's treated me well

14:45 technomancy: I just use the built-in completion because I'm a luddite

14:47 amalloy: i use AC but not ac-slime. i heard bad things about ac-slime years ago

14:47 Bronsa: amalloy: ?

14:47 gfredericks: is there a good lein plugin for generating a Main class so you can have an arg-free executable jar but otherwise avoid AOT?

14:48 * TimMc perks up

14:48 TimMc: gfredericks: There's a bad lein plugin.

14:48 amalloy: as i recall, the same thing gfredericks is saying. long pauses while typing because autocomplete is trying to find all possible completions

14:49 gfredericks: TimMc: what's the bad one?

14:49 TEttinger: https://github.com/llasram/lein-otf

14:50 Bronsa: dunno, I never noticed any lag & type pretty fast

14:50 TimMc: https://github.com/timmc/lein-otf is broken with lein 2.4.3 or 2.5.0 (I forget which I've tried), but it's really really easy to replicate in your own code.

14:51 amalloy: TimMc: why do this with a java loader class that reads the manifest, rather than injecting a clojure file like: (ns my.loader (:gen-class)) (defn -main [& args] (require 'real.main) (apply (ns-resolve 'real.main '-main) args))?

14:52 i don't know how to do that in a lein plugin, but that's how i've produced non-aot runnable uberjars by hand

14:52 gfredericks: speaking of which what's the right way to "inject" some clojure code as above which is intended to work when packaged up as well?

14:52 EvanR: why is the datomic pull api only getting some of the things nested past depth 3 (i know this is technically the wrong channel but if you know the answer to this ill be happy to hear the answer in #datomic)

14:52 gfredericks: we were talking about util libs a while ago and the problem applies there too

14:53 TimMc: amalloy: I think I did, but it was pulled in from the dependency.

14:53 I don't recall the tradeoffs of various injection strategies.

14:53 amalloy: TimMc: pulled in from the dependency?

14:54 TimMc: As in, a clojure file was injected, but it still read from the manifest.

14:54 I had to much with stuff in or near the manifest anyhow, IIRC.

14:55 Anyway, I should just replace the readme with "Just make another nsthat requires your real ns and calls -main, okay?"

14:56 gfredericks: you could call the namespace itself -main

14:56 TimMc: I.. could.

14:56 gfredericks: don't judge me.

14:56 amalloy: gfredericks: if i made suggestions as outrageous as yours i'd live in constant fear of the inquisition arriving on my doorstep

14:57 gfredericks: hey great I love questions

14:57 amalloy: gfredericks: is your answer to this question a lie?

14:58 dbasch: amalloy: perhaps

14:58 TimMc: where's technomancy

14:58 technomancy: you'll never catch me

14:58 * technomancy flees

14:59 gfredericks: amalloy_: I’m really happy for you, Imma let you finish but Beyonce had one of the best videos of all time

14:59 TimMc: Get back here! I need that "mu" character!

15:00 technomancy: (defun mu () (interactive) (insert "無"))

15:00 TimMc: gfredericks: "What is 2 + 2? (This is strictly a 3-or-5 question.)"

15:01 dbasch: TimMc: pancakes

15:01 gfredericks: ,(bit-or 3 5)

15:01 clojurebot: 7

15:01 TimMc: haha

15:02 dbasch: (inc gfredericks)

15:02 lazybot: ⇒ 108

15:02 TEttinger: clojurebot: mu |is| 無

15:02 clojurebot: In Ordnung

15:02 TEttinger: ~mu

15:02 clojurebot: mu is 無

15:03 TimMc: ~無

15:03 clojurebot: excusez-moi

15:03 TEttinger: better, TimMc?

15:03 TimMc: *nod*

15:04 TEttinger: $google 無

15:04 lazybot: [無 - Wiktionary] http://en.wiktionary.org/wiki/%E7%84%A1

15:05 TEttinger: neither yes nor no, interesting

15:18 bbloom: mi6x3m: iirc you were doing (foo a b c :x 1 :y 2 :z 3) positional arguments like that

15:18 that's not a map, and so won't be formatted as a map

15:18 there's no general way to tell keyword args from positional args

15:19 so there's no general way to print them where key/value pairs stay on a line

15:19 at best, you could use a heuristic

15:19 danielcompton: ~karma amalloy

15:19 clojurebot: excusez-moi

15:21 bbloom: clrnd: i tink emacsnub's intended question was: does using core.typed preclude the need to write clojure's type hints to the compiler for avoiding reflection and boxed math

15:21 danielcompton: karma amalloy

15:21 ,karma amalloy

15:21 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: karma in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:21 gfredericks: is bbloom time-traveling again?

15:21 justin_smith: danielcompton: $karma amalloy

15:21 TimMc: gfredericks: I COME... FROM THE PAST!

15:21 danielcompton: $karma amalloy

15:21 lazybot: amalloy has karma 197.

15:21 justin_smith: (identity amalloy)

15:21 lazybot: amalloy has karma 197.

15:21 justin_smith: or that :)

15:22 danielcompton: whew, I didn't miss the big 200

15:22 gfredericks: bbloom: how many fingers am I holding up?

15:22 clrnd: bbloom, ooohhhhh, yeah probably

15:22 bbloom: amalloy: i'm not sure, but there may be variants of defn that accept annotations and do hinting, but i dunno

15:23 shafire: hello smart people

15:27 bbloom: gfredericks: can you hear me now?

15:27 gfredericks: bbloom: ACK

15:27 bbloom: gfredericks: i have no idea wtf is wrong

15:28 maybe i was rate limited or something? .... i've set my irc client to join far fewer channels

15:28 justin_smith: bbloom: I've had that delay thing before. IRC is weird.

15:28 bbloom: *shrug*

15:28 clrnd: lol

15:28 gfredericks: bbloom: does it apply across all freenode or just to #clojure?

15:29 bbloom: gfredericks: doesn't seem to affect private messages

15:29 not sure about other channels

15:29 gfredericks: aw snap

15:29 bbloom: it's kinda hard to find out b/c people may just ignore you heh

15:29 i feel like i'm manually implementing TCP :-P

15:29 gfredericks: yeah and it's hard to guess on this end because you might just be having an unsurprisingly laggy IRC conversation

15:30 I didn't guess it till I saw two late replies back to back

15:30 bbloom: that's why i was testing with the ghost_of_bbloom via a web irc client

15:30 TEttinger: you could be missing out on show gratis spam! solo hoy!

15:30 bbloom: no, i'm not missing out on that at all lol

15:32 justin_smith: TEttinger: we should totally have a bot that a) changes nicks periodically b) spouts a small bit of markov generated clojure related gibberish periodically c) kickbans anyone that sends it a pm which matches our profile

15:33 gfredericks: d) kickbans random people periodically

15:33 justin_smith: sure, why not

15:34 gfredericks: but our spammer is predictable enough that false positives would be pretty easy to prevent - ie. repeatedly using the same text

15:34 TimMc: This would require getting additional ops.

15:34 TEttinger: yes.

15:35 Montanan: I'm staring at the core.async example, line 91 of https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj and wondering how we get out of the (while true ...) loop

15:35 justin_smith: Montanan: replace true with a different condition?

15:35 TimMc: I think if we should have two bots. One periodically says ~guards and the other inc's the first. If both get the same message from the same sender within 30 minutes of each other one kickbans the sender.

15:36 They'll blend right in.

15:36 justin_smith: haha

15:36 Montanan: my question is, why does it leave the (while true ...) loop

15:36 aperiodic: Montanan: you don't. that's the magic of go blocks; when it's waiting for a new value from the channel, it stops executing that go block's state machine and frees the thread up to go do something else.

15:36 justin_smith: Montanan: does it ever leave?

15:36 aperiodic: that example is a thread, not a go block

15:37 Montanan: whoah, that's a trip. Thank you aperiodic

15:38 aperiodic: Montanan: and the thread keeps going because the `go` macro is asynchronous (the body gets executed in a different thread, I think) http://clojure.github.io/core.async/#clojure.core.async/go

15:38 justin_smith: what? there's a go call right on that line.

15:38 tbaldridge: first conj vid: https://www.youtube.com/watch?v=BNkYYYyfF48&feature=youtu.be

15:40 nullptr: tbaldridge: awesome, didn't realize these were posted so quickly -- thanks

15:40 justin_smith: aperiodic: what line?

15:40 aperiodic: justin_smith: line 91, as Montanan said https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj#L91

15:40 justin_smith: aperiodic: oh, I did not see the line part, sorry

15:49 Montanan: aperiodic: when the let block ends, is the thread or go block cleaned up?

15:54 aperiodic: Montanan: I'm not sure. I'm not that familiar with core.async. My guess would be no, since the thread actually executing the go block still has a reference to the channel and it's still open. I would think that the channel needs to be explicitly closed first, then the thread where the go block is executing will notice and release references to the channel & go block, and then after the channel is released on the calling/consuming side everything can be

15:55 Montanan: but like I said, I don't know much about core.async, so you should verify that somehow.

15:55 justin_smith: Montanan: what do you mean by "when the let blcok ends"

15:55 when all code inside it has stopped running?

15:57 objects that don't have references outside a specific thread will be reclaimed sometime after that thread is reclaimed

15:57 Montanan: Thank you aperiodic. Yes justin_smith, when the main thread of execution leaves the let block

15:57 justin_smith: Montanan: main thread?

15:59 I mean if I use my definition of main thread, nothing inside a thread or go block is run in the main thread

16:01 Montanan: I'm following, justin_smith, once outside the let block, there is no reference to the thread, and thereby it should be reclaimed later

16:02 I should be able to verify that in a debugger

16:03 justin_smith: Montanan: right, jvisualvm will show you all the threads that exist

16:03 it's much trickier in core.async

16:03 tbaldridge: Montanan: os the gist is, the that everything gets reclaimed after the last reference to it is gone. For go blocks, when they pause they are attached to channels.

16:03 justin_smith: since they use a thread pool, and have some implementation dependent definition of a go block that may be hard to recognize in a profiler or debugger

16:03 tbaldridge: So they live as long as the channels they are attached to.

16:04 with (thread...) blocks there is an actual OS thread running that block, and the OS keeps a pointer to that thread, so it never gets reclaimed.

16:04 until it exits that is.

16:05 justin_smith: tbaldridge: so the actual answer to Montanan 's earlier question was that he could stop the go block by closing the channels

16:05 tbaldridge: justin_smith: well closing them will cause them to start returning nulls, which will cause that go block to loop forever.

16:06 if you just drop the reference to the channel, the go block will attach to it, then the channel will get reclaimed, and with it the go.

16:06 justin_smith: tbaldridge: oh, ok

16:06 tbaldridge: the interaction between gc and clojure constructs still confuses me sometimes, thanks for clearing that up

16:11 Montanan: Thank you tbaldridge, justin_smith.

16:12 justin_smith: Montanan: tbaldridge has some video tutorials for core.async

16:13 Montanan: Looks like he gets some of my loot

16:22 SagiCZ1: do you have any idea what could be causing this?

16:22 NumberFormatException For input string: "198717588"

16:22 I mean, it looks pretty parsable to me..

16:22 ,(Integer/parseInt "198717588")

16:22 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588">

16:22 justin_smith: &Integer/MAX_VALUE

16:22 lazybot: ⇒ 2147483647

16:23 SagiCZ1: ,(< 2147483647 198717588)

16:23 clojurebot: false

16:23 justin_smith: &(> Long/MAX_VALUE 198717588 Integer/MAX_VALUE)

16:23 lazybot: ⇒ false

16:23 justin_smith: hrm

16:24 tbaldridge: ,(< 2147483647 198717588N)

16:24 clojurebot: false

16:24 justin_smith: (Integer/parseInt "198717588")

16:24 tbaldridge: hrm...

16:24 justin_smith: &(Integer/parseInt "198717588")

16:24 lazybot: ⇒ 198717588

16:24 SagiCZ1: ,(Integer/parseInt "198717588")

16:24 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588">

16:24 justin_smith: ,(map int "198717588")

16:24 clojurebot: (65279 49 57 56 55 ...)

16:24 SagiCZ1: what is this sorcerry

16:24 justin_smith: there's your problem

16:24 unicode!

16:24 amalloy: (inc justin_smith)

16:24 lazybot: ⇒ 138

16:24 tbaldridge: rofl

16:24 SagiCZ1: sorry im slow, could you elaborate?

16:24 tbaldridge: that's awesome

16:25 justin_smith: ,(char 65279)

16:25 clojurebot: \

16:25 amalloy: SagiCZ1: that's not a 1, it's a different unicode character that renders the same as a 1

16:25 or similarly, at least

16:25 justin_smith: ,(char 49)

16:25 clojurebot: \1

16:25 dbasch: on my screen it renders like _1

16:25 SagiCZ1: isnt that nice

16:25 justin_smith: I think that may be a BOM hidden in the screen

16:25 clojurebot: Pardon?

16:25 kenrestivo: that charactter renders as a \

16:25 justin_smith: ,(str (char 65279))

16:25 clojurebot: ""

16:25 Bronsa: I see an small underscore

16:25 dbasch: same as Bronsa

16:26 Bronsa: shade

16:26 amalloy: &(printf "%x" 65279)

16:26 lazybot: ⇒ feffnil

16:26 amalloy: yeah, that's a BOM

16:26 Bronsa: http://i.imgur.com/xjjHK5V.png

16:26 amalloy: FEFF

16:26 justin_smith: ZERO WIDTH NO-BREAK SPACE

16:26 old-name: BYTE ORDER MARK

16:26 SagiCZ1: ,(Integer/parseInt "198717588")

16:26 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "198717588">

16:27 justin_smith: SagiCZ1: it has hidden whitespace, so it isn't parsable

16:27 SagiCZ1: i am not sure what i can do about it.. its a string from a text file, can i trim it or something?

16:27 justin_smith: ,(Integer/parseInt (sube "198717588" 1))

16:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sube in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:27 justin_smith: ,(Integer/parseInt (subs "198717588" 1))

16:27 clojurebot: 198717588

16:27 amalloy: SagiCZ1: probably, read the text file better so that it doesn't include the BOM

16:27 justin_smith: a regex that trims should handle it

16:28 TimMc: SagiCZ1: Stop using notepad?

16:28 amalloy: it's probably the first two bytes in the file, and when you specify the proper character encoding you should be able to read it just fine

16:28 kenrestivo: right, we've been around this block before here.

16:28 SagiCZ1: TimMc: its notepad++

16:29 amalloy: i was joining these files earlier, so im afraid the bom is actually in the middle of the new file

16:29 kenrestivo: the dreaded feff

16:29 justin_smith: ,(Integer/parseInt (second (first (re-seq #"([0-9]+)" "198717588")))) ; SagiCZ1

16:29 clojurebot: 198717588

16:29 dbasch: SagiCZ1: where do the files come from?

16:30 TimMc: BOM: Because no one would ever cat files together, ever.

16:30 csd_: I'm looking for code similar to Rich Hickey's ants.clj. Any suggestions?

16:30 justin_smith: ,(Integer/parseInt (ffirst (re-seq #"([0-9]+)" "198717588"))) ; actually this is better

16:31 clojurebot: 198717588

16:31 SagiCZ1: justin_smith: thank you very much.. but i still wonder how to fix the actual file.. notepad++ doesnt show any weird unprintable characters

16:31 TimMc: SagiCZ1: Notepad++ is probably adding it.

16:31 SagiCZ1: TimMc: i am not saving it though

16:31 justin_smith: SagiCZ1: you could slurp the file, and filter all characters that equal (char 0xfeff)

16:31 SagiCZ1: justin_smith: i could do that

16:31 justin_smith: err, I mean remove of course

16:31 SagiCZ1: yeah sure

16:32 justin_smith: and then spit it back out again, of course

16:32 TimMc: .replaceAll

16:32 justin_smith: even better

16:32 SagiCZ1: these files used to be in a really obscure encoding.. i think it was utf16 little endian.. i had a lot of trouble even decoding it.. but after that i spit it back with the default spit encoding so i dont know what went wrong

16:33 TimMc: &(first "198717588")

16:33 lazybot: ⇒ \

16:33 TimMc: &(first (.replaceAll "198717588" "\ufeff" ""))

16:33 lazybot: ⇒ \1

16:33 SagiCZ1: TimMc: this just baffles me honestly

16:34 TimMc: BOM is pretty baffling. :-(

16:34 justin_smith: BOM is also the name of a character in one of Samuel Beckett's weirdest plays

16:34 SagiCZ1: justin_smith: what a coincidence

16:34 justin_smith: heh

16:35 yeah, the play is pretty baffling too

16:35 SagiCZ1: zero width no break space.. who thought that would be a nice character to have?

16:35 justin_smith: http://en.wikipedia.org/wiki/What_Where

16:36 SagiCZ1: it's used as a marker. It should be metadata, but it is in the file.

16:36 SagiCZ1: i see

16:36 justin_smith: "The byte order mark (BOM) is a Unicode character used to signal the endianness (byte order) of a text file or stream."

16:36 http://en.wikipedia.org/wiki/Byte_order_mark

16:37 SagiCZ1: so feff is bom?

16:37 justin_smith: yes

16:37 SagiCZ1: but what is it doing in the middle of the file?

16:37 justin_smith: feff is bom, and should only be at the beginning of a file

16:37 because someone fucked up, clearly

16:37 SagiCZ1: justin_smith: i did

16:37 justin_smith: well, whatever tool was combining the files should not have left a bom in the middle

16:37 csd_: SagiCZ1: is this a Clojure exercise? why not just use a hex editor to remove it

16:38 SagiCZ1: when i was reading and writing the new tweaked files i used write and getBytes.. actually its a little snippet you wrote for me.. i think it wrote the bom too

16:38 csd_: its not an exercice and i would totally do it manually if there wasnt 100GB of those files

16:38 justin_smith: yeah, getBytes and write would let you do something like that :)

16:38 csd_: oh its more than one?

16:39 SagiCZ1: justin_smith: at least i know how it happened..

16:39 Guest70412: Does anyone know if it is possible to call a function in a namespace in a lein project.clj? I'm trying to call a function to return a generated version number to use in the defproject.

16:40 TimMc: justin_smith: It's not exactly SagiCZ1's fault.

16:40 Guest70412: I can write simple functions at the top of the project.clj but was unable to call into another namespace or add the ns macro to the top of the project.clj

16:40 justin_smith: TimMc: well, he used byte oriented methods for textual data. I put it a bit harshly, and for that I apologize.

16:41 sorry SagiCZ1

16:41 hyPiRion: Guest70412: You can do (require '[my-namespace :as my-ns]) then (my-ns/my-function ...) if the namespace is on the classpath

16:41 Guest70412: I guess there is a bootstrap problem

16:41 TimMc: justin_smith: I feel like a lot of text-oriented tools screw this up too.

16:41 It's just a bad situation.

16:41 justin_smith: yeah

16:41 SagiCZ1: justin_smith: no problem, i didnt see the harsh tone, language barrier i guess :)

16:41 Guest70412: thanks @hyPiRion

16:42 hyPiRion: Guest70412: But it sounds like a bad idea to use functions outside of core clojure, at least that's my gut feeling

16:43 justin_smith: Guest70412: maybe what you really want is to write your own lein plugin and run it?

16:43 Guest70412: hyPiRion: I have some code that gets version numbers from the build server and I was wondering if I could share the code between clojure projects.

16:43 justin_smith: didn't actually consider that

16:44 justin_smith: could be a good shout if it's possible to set the version of the current project

16:44 justin_smith: Guest70412: or you could make your version-fetching code into a standalone lib, install it locally, and add it to deps in your profiles.clj

16:44 SagiCZ1: TimMc: i was vaguely aware that i should use text oriented functions/methods when i work with text files, but then i needed this line by line zipping writer and write/getBytes was a way i figured out with the help of this channel.. i guess i will just go through the file and remove all invisible characters besides newlines

16:45 justin_smith: SagiCZ1: ahh, in that case it was me, I remember that now

16:45 haha

16:45 (dec justin_smith)

16:45 lazybot: You can't adjust your own karma.

16:45 SagiCZ1: justin_smith: yeah, it was actually a problem with heap space, beacuse i was keeping the whole file in memory

16:45 justin_smith: right, and I suggested a solution using getBytes and write

16:45 amalloy: SagiCZ1: BOMs in the middle of the files might not be the only problem, if you copied a bunch of bytes around without caring about their encoding

16:45 SagiCZ1: yea

16:45 dbasch: justin_smith: you can inc everyone else, which produces the same effect :P

16:46 justin_smith: dbash

16:46 (map inc #clojure)

16:46 SagiCZ1: amalloy: i am afraid of that.. they still seem to be readable though

16:46 amalloy: eg, any characters that take more than like 7 bits may be mis-encoded

16:47 SagiCZ1: amalloy: the files contained jsut numbers, letters and ",:."

16:47 Guest70412: thanks justin_smith and hyPiRion, I'll see what works

16:47 justin_smith: SagiCZ1: plus newlines, one assumes

16:47 SagiCZ1: justin_smith: yeah

16:48 amalloy: when you say "letters", are you sure that there's nothing like ä?

16:48 SagiCZ1: amalloy: yes, i think it could be encoded in plain ANSI

16:48 amalloy: then you are probably okay to just throw away and FEFFs you see

16:49 SagiCZ1: is it possible to modify the file in place by the way? i always create a new one

16:49 dbasch: SagiCZ1: yes if you seek and replace bytes

16:49 of course you can’t shrink it

16:49 SagiCZ1: dbasch: ok thats horrible, scratch that thought

16:50 dbasch: well you can shrink it but that would be blasphemy

16:51 “now I’m going to move 1GB one byte up”

16:51 justin_smith: dbasch: finger tree of inodes? lol

16:52 SagiCZ1: i guess there is no easy way to wrap the .getBytes so that it wouldnt write the bom character huh?

16:52 https://www.refheap.com/93692

16:53 kenrestivo: i'm sorry if i'm being dense, but what is required to turn a manifold stream into a core.async channel? i only see docs to to the inverse.

16:53 amalloy: SagiCZ1: the question is where this "lines" thing has come from

16:53 the BOM have been skipped while reading in the first place, if you were reading lines correctly

16:54 hyPiRion: Guest70412: You can use the update-in leiningen task to inject the version number – I just verified it

16:54 SagiCZ1: amalloy: they come from (line-seq (io/file "filepath))

16:55 technomancy: the version is available at runtime now on the classpath

16:55 check the faq for the 2.5.0 release

16:55 justin_smith: SagiCZ1: amalloy: wouldn't that be a bug in line-seq if that's the case?

16:56 amalloy: justin_smith: not necessarily. i don't know what line-seq's API is for setting the character encoding

16:56 it can't necessarily just guess character encodings by magic; if your file is encoded in some surprising way, you'll have to say so or else get out garbage

16:57 justin_smith: amalloy: hmm, looking at the soure it just wraps BufferedReader / .readLine

16:57 one would think that would be well behaved

16:57 amalloy: justin_smith: obviously it's not a problem with line-seq. the question is io/reader

16:57 SagiCZ1: by line-seq i am reading from a ZipEntry - InputStream .. i guess that reads boms as well

16:57 hyPiRion: technomancy: could you use that to change the version in the first place? Like replace something like `lein update-in : assoc :version '"my-version"' -- my-task`

16:57 I must've missed that

16:58 technomancy: I think so

16:58 TimMc: amalloy: I don't know that io/reader properly removes the BOM.

16:58 All my experiences with BOM disposal have been manual.

16:58 amalloy: TimMc: you have to set the character encoding

16:58 SagiCZ1: and what is InputStream? isnt it just input of bytes?

16:58 amalloy: if your file is encoded as utf-16, you have to say so when making the reader

16:58 "remove the BOM" is the wrong level to be thinking about this problem at

16:59 SagiCZ1: amalloy: but ui/reader has some default encdoing doesnt it? if you dont specify it

16:59 TimMc: You'd think.

16:59 amalloy: sure, it's utf-8, of course

16:59 SagiCZ1: and if it reads the file so i can see the text.. thats not a guarantee it is the correct encoding?

16:59 justin_smith: right, because bom is likely invisible

17:00 and utf8 uses a different bom (or does not use it at all)

17:00 SagiCZ1: but i can't be certain about the encoding can i? unless i would specifically ask the creator of the file..

17:00 TimMc: amalloy: The last place I worked involved text analytics and we just had a special reader that would strip the BOM when reading a file.

17:01 justin_smith: SagiCZ1: well, that's part of what bom does, is help you figure out the encoding

17:01 amalloy: TimMc: that is so wrong

17:01 TimMc: We were setting the encoding properly but still ahd to do that.

17:02 SagiCZ1: justin_smith: i see.. notepad says its ANSI as UTF-8 .. but i guess i added some UTF-16 in the mix.. what a mess.. i guess i should have just paid for high quality data

17:02 nickik: Does anybody know how one could get the full url out of a pedestal request

17:03 TimMc: amalloy: You're saying that if I slurp a BOM-laden text file it should strip that initial U+FEFF?

17:03 because that's not what I see.

17:04 SagiCZ1: TimMc: even if you slurp it with the correct encoding specified?

17:04 amalloy: TimMc: that was what i thought; i could believe i'm wrong, but when you said "we *just* [strip the BOM when reading a file]" it sounded like that's all you're doing

17:04 TimMc: SagiCZ1: Yes.

17:05 SagiCZ1: TimMc: that's a shame then.. i would think i get just the text with no nonsense

17:05 TimMc: Besides, slurp should default to UTF-8 if Alan is right (and I think he is).

17:05 SagiCZ1: who is Alan again?

17:05 TimMc: amalloy

17:05 SagiCZ1: oh.. duh

17:05 TimMc: I don't know why I use his wallet name sometimes.

17:05 amalloy: TimMc: so, i just created a file and saved "abcd" to it, encoded as "UTF-16" by my text editor

17:06 TimMc: I make no bets on UTF-16.

17:06 amalloy: and (seq (.getBytes (slurp "/home/akm/utf.txt" :encoding "UTF-16"))) produces (97 98 99 100 10)

17:06 TimMc: huh?

17:06 utf-16 is the only encoding that needs a BOM at all

17:07 TimMc: And yet UTF-8 has an optional "BOM".

17:07 And some programs add it, just to make our lives miserable.

17:08 Mmmm, 

17:09 (or Ýsfs if you're using UTF-EBCDIC)

17:09 justin_smith: if we all just stopped using things that default to utf-16 this wouldn't be a problem... oh, wait

17:10 SagiCZ1: what defaults to UTF-16?

17:10 justin_smith: java, windows

17:10 SagiCZ1: i see

17:10 justin_smith: internal string rep in the jvm is utf-16

17:11 that was my joke :)

17:11 amalloy: justin_smith: ucs-2, really, right?

17:11 SagiCZ1: i always thought it was utf-8

17:11 amalloy: SagiCZ1: that's the format it assumes when reading from disk, if given no other instructions, not what it uses for strings in memory

17:11 TimMc: I think JS uses UCS-2.

17:12 SagiCZ1: isnt that just peachy

17:12 dbasch: amalloy: well, it defaults to whatever the system default is

17:12 justin_smith: "Java originally used UCS-2, and added UTF-16 supplementary character support in J2SE 5.0."

17:12 SagiCZ1: i wish endoing would just go away and never come back

17:12 amalloy: SagiCZ1: save your wrath for measuring time. it's just as bad as character encodings

17:12 TimMc: [[all data suddenly disappears from all the computers of the world]]

17:12 dbasch: the famous “default platform encoding”

17:12 justin_smith: SagiCZ1: yeah, screw all those foreigners and their squiggly gibberish, let 'em all use american letters like god intended

17:13 SagiCZ1: yeah my alphabet doesnt fit into ascii

17:13 i have these ěščřžýáíé

17:13 not sure how they show up in your clients

17:13 TimMc: E̲̥͙͇̲ͭͣn̵̮͕͓͉̫̦ͪc̙̩̹o̡͚̠̔͗d̹̮̖͙̠͎̏̈͋ͩͭ̏ͩ̀i̶͉̩̙̬̘͎͑̂ͥ̓̋n͎ͧ̇̿̒̒̐g͑͆͊ͩ͛҉͖̮ ̛̙̰̓ͬ̇ḭ͕̞̜̳̔̽͂ͬs͍͓͉̰̣͕ͮͪͣ ͮͥͩ̽ͦͩ҉̮͍̺̦̝f͑͞u͖̱͕͔̯̭ͣͤn̵̉̾̏̎ͣ͒͗!̿ͨ҉͍̺̹̣̻

17:13 justin_smith: SagiCZ1: it would all be much easier if we used something extensible from the beginning

17:14 amalloy: if everyone just used ucs-4, we could forget about it forever. but nobody is willing to quadruple the space used by all text documents, even though storage space quadruples like every day according to moore's law

17:14 SagiCZ1: justin_smith: yeah, people are bad at making reasonable standards

17:14 dbasch: justin_smith: well, the 0-1 alphabet was pretty extensible

17:14 amalloy: (because surely, nobody could ever need more than 4 bytes...right?)

17:14 dbasch: you mean the next beginning :)

17:14 justin_smith: dbasch: well yeah, we got that one right, but good luck getting users (or even me) to read it without a translation and encoding layer

17:14 SagiCZ1: how much space would i save if i saved the UTF-8 files in ASCII? .. i mean they are like 100 GB so it could have benefits

17:15 dbasch: amalloy: wait until we get invaded by Andromedans with their alphabet of 2^33 characters

17:15 justin_smith: SagiCZ1: the point of utf8 is that it uses no more space than ascii if your file is free of higher bits / extended characters

17:15 SagiCZ1: justin_smith: cool.. so i dont need that

17:16 dbasch: justin_smith: utf8 is discriminatory. It’s designed to make foreigners spend more money on storage and bandwidth.

17:16 justin_smith: dbasch: it's an NSA plot

17:18 kenrestivo: they droppin BOMs

17:21 dbasch: someone set up us the BOM

17:21 justin_smith: I suspect #cats

17:28 TimMc: I feel like https://en.wikipedia.org/wiki/Byte_order_mark deserves a "Criticism" or "Controversy" section.

17:28 TEttinger: "Seething Hatred" section

17:29 SagiCZ1: i promise i will add it if i dont sort these files out..

17:29 technomancy: http://p.hagelb.org/antipathy.jpg

17:29 brehaut: “The byte order mark (BOM) is a Unicode character used to cause inexplicable errors in old but pervasively deployed software, and to find problems in languages string handling code”

17:29 technomancy: submitted for your consideration

17:30 SagiCZ1: technomancy: where is that from, thats hilarious

17:31 TEttinger: ,(def *clojure-version* {:major 1, :minor 0, :incremental 0, :qualifier nil})

17:31 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

17:31 technomancy: SagiCZ1: no idea, sorry

17:32 TEttinger: ,(def what "huh")

17:32 clojurebot: #'sandbox/what

17:32 SagiCZ1: ,what

17:32 clojurebot: "huh"

17:32 TEttinger: ,(def whaaaat "huh")

17:32 clojurebot: #'sandbox/whaaaat

17:33 TEttinger: ,whaaaat

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

17:33 TEttinger: ,whaaaat

17:33 clojurebot: "huh"

17:34 justin_smith: from the talk page on the BOM wikipedia page: "Should I interpret the article as if Windows Notepad is the only widely spread software which actually creates UTF-8 BOMs? It would make sense"

17:36 SagiCZ1: oh, it turns out there is a linux program called bomstrip

17:37 TimMc: It must be tiny.

17:41 amalloy: TimMc: tail -c-2 $1

17:42 justin_smith: amalloy: TimMc: I juste downloaed, it comes with java, haskell, brainfuck, perl, sed, ocaml, php, ruby, awk, c++ ... etc. implementations

17:43 amalloy: TimMc: it's not just removing from the beginning, but also eliminating any that accidentally end up in the middle of the file, it seems

17:45 strike that

17:45 so it won't do the cleanup that SagiCZ1 wants

17:46 Guest6: In clojurescript, can I use the full name (namespace and all) of a function and not require it?

17:47 amalloy: no

17:49 brehaut: Guest6: passive (global) dependancies is a bad thing anyway. you shouldnt want to do that

17:50 amalloy: require is for loading code; if you don't require it, it won't exist. you can refer to required vars by their full, qualified name; the function that gives you shorter, convenient names for loaded things is refer; *that* is the step you can skip

17:52 Guest6: brehaut: I normally wouldn't but it's for a routes file, and I didn't want to require each file before using it.

17:52 amalloy: thanks

18:08 {blake}: Trying to debug a ring/compojure app. I've been using "lein ring server" but I'd like to look at the running code. I've been using Cursive, but I have CCW, LightTable...I have Emacs but I don't think it's in a usable state...

18:09 justin_smith: {blake}: two options are to not use the lein ring plugin, and launch your server from the repl; or use clojure.tools.nrepl.server to create a repl you can connect to from inside your server

18:10 {blake}: justin_smith: I've been trying to figure out how to do the former.

18:10 noonian: its really easy to just start the server from your code instead of using the plugin

18:10 {blake}: I'm using the java servlet stuff.

18:10 noonian: ah, i don't have any experience with servlet stuff from clojure unfortunately

18:11 i might check out the source for the lein ring plugin and look at what its doing

18:11 {blake}: noonian: Thanks anyway!

18:11 justin_smith: {blake}: you can start the embedded jetty server (which is what ring uses) from inside -main

18:11 {blake}: noonian: Yeah, I've been digging around there.

18:11 justin_smith: or from a repl, passing it your handler

18:12 {blake}: justin_smith: So, would I just include the jetty code for debug purposes?

18:12 justin_smith: {blake}: well, it's an alternate means of running your server

18:12 if you deploy a war, your -main is not called

18:12 if you are running locally, you can call it manually

18:13 (require '[ring.adaptor.jetty :as jetty]) (jetty/run-jetty #'handler {:port xxxx})

18:13 I guess you can just do that in a repl (maybe put it in a future) and not even have it in a main

18:14 {blake}: justin_smith: That's what I was trying and getting back an error...

18:14 justin_smith: also you can use http-kit instead of jetty, for example

18:14 what was the error?

18:14 {blake}: "FileNotFoundException Could not locate ring/adaptor/jetty__init.class or ring/adaptor/jetty.clj on classpath"

18:14 So I have to put that in my project.clj, right?

18:15 justin_smith: {blake}: then you need to add the dep to your deps list (lein ring adds it implicitly)

18:15 https://clojars.org/ring/ring-jetty-adapter

18:15 of course you probably only want to add it to the :dev profile

18:15 {blake}: justin_smith: That's kind of interesting. So lein ring does it, but only when you run...lein ring?

18:16 justin_smith: {blake}: well lein ring can't do anything if you don't run it

18:16 {blake}: justin_smith: Sure, but I would've guessed it was tucking the dependency away somewhere.

18:16 dbasch: it’s adapter, not adaptor

18:17 justin_smith: (inc dbasch)

18:17 lazybot: ⇒ 21

18:17 justin_smith: I didn't catch that :)

18:18 dbasch: (dec homophones)

18:18 lazybot: ⇒ -1

18:19 {blake}: Interestingly, I have ring-mock and java-servlet in my dev dependencies, and nothing in my regular dependencies. (I mean, I have compojure and hiccup but no ring stuff at all.)

18:19 justin_smith: {blake}: as dbasch points out, your code may just work if you spell adapter right

18:20 dbasch: not only homophones, they are two spellings with the same meaning

18:20 dbasch: justin_smith: they actually have slightly different meanings

18:20 catery: clojure is suppose to be a memory hog having to do with jvm limitations right??? does racket suffer the same memory problems, and if not then what does clojure offer in advantage?

18:20 {blake}: justin_smith: lol, no, I was getting the same error prior to this...

18:20 dbasch: they overlap though

18:21 catery: clojure is suppose to be a memory hog having to do with jvm limitations right??? does racket suffer the same memory problems, and if not then what does clojure offer in advantage?

18:21 justin_smith: catery: not just the jvm

18:21 catery: it's impossible to run clojure without the whole compiler in memory

18:21 catery: so wait

18:21 are you saying racket has the same problem?

18:22 justin_smith: catery: racket has a different design. It tends to use less RAM. But like clojure it is a lisp that usually has the whole compiler in core. But unlike clojure it is able to make a smaller executable excluding unused parts of the language.

18:22 {blake}: Is that seriously an issue for a non-trivial application?

18:22 justin_smith: catery: with some caveats here about clojurescript of course

18:23 {blake}: what issue?

18:23 technomancy: racket has racket/base, which avoids loading most of the language

18:23 kenrestivo: why are pub and sub not pub! and sub! ? i was surprised that they're side-effecting, mutating the channnel in place

18:23 {blake}: justin_smith: Compiler taking up RAM? Moreso than, say, immutable data structures?

18:23 catery: justin_smith so why can't these issues of clojure be fixed to make it comparable to racket

18:23 justin_smith: {blake}: the clojure compiler and internals are large, that's another part of it

18:24 catery: they can be. They haven't been.

18:24 technomancy: catery: the clojure compiler outputs jvm bytecode. the fact that the jvm trades space for speed can't be changed in a library.

18:24 and there's no way you can get out of the fact that the jvm uses utf-16 for string encoding

18:24 catery: isn't racket also on a vm

18:24 technomancy: racket is on their own VM

18:24 catery: you saying the racket vm is designed to not be a memory hog?

18:25 technomancy: they get to decide the tradeoffs

18:25 justin_smith: catery: different vm, different design, different issues

18:25 technomancy: racket doesn't have enough manpower to implement the space/speed tradeoffs that the jvm makes, whether they'd want to or not

18:25 kenrestivo: and one more dumb question: what's the idiomatic way to terminate a go loop asynchronously and restart it? or just use threads instead?

18:25 catery: so racket vm designed to not be a memory hog, what does racket vm give up to achieve that then?

18:25 justin_smith: But do note that a java program can be quite small. Not so for clojure on the jvm.

18:25 technomancy: catery: it's a lot slower

18:26 dbasch: {blake}: compojure doesn’t bring in the ring-jetty-adapter dependency, you have to add it to your project.clj

18:26 catery: technomancy is there like an article that explains how it ends up slower?

18:26 {blake}: justin_smith: I get a jar that's 1.7MB on my latest project. Not compact, but not exactly scary.

18:26 amalloy: catery: are you the same person as catern?

18:26 catery: technomancy: without having to be a compiler expert

18:26 technomancy: catery: maybe, but I doubt it

18:26 catery: who is catern

18:26 scottj: amalloy: no way, he's not talking about haskell.

18:26 {blake}: dbasch: So I must be running development versions then.

18:26 justin_smith: {blake}: the jar is small, the running executable not so much - but a running java executable, in heap usage, at run time, can be much smaller

18:27 technomancy: catery: the biggest difference is that one of them has had a bazillion dollars of optimizations applied that were financed by a company that sells server hardware.

18:27 {blake}: justin_smith: So it decompresses and fills up the RAM. (I suppose it would have to.)

18:27 technomancy: s/sells/sold/

18:27 justin_smith: {blake}: right, the clojure.core initialization and bootstrapping

18:28 catery: technomancy but why should optimizations equal more memory usage?? typical C++ compiler has a bunch of optimizations but c++ is not a memory hog by default

18:28 afhammad: kenrestivo: why would you want to terminate then restart it?

18:28 technomancy: catery: the JVM's optimizations are based on runtime analysis, so they can be a lot more relevant and effective

18:28 justin_smith: catery: c++ also doesn't have run time compilation, or reflection

18:29 kenrestivo: to start/stop them. for testing,, say at the repl?

18:29 justin_smith: catery: and just try using polymorphic runtime dispatch, and persistent data structures in c++, you will not see low memory usage

18:30 {blake}: That'd be fun: C++ compiler bundled in every executable.

18:30 justin_smith: right

18:30 kenrestivo: also, to stop them and modify them, again at the repl, say i've got a go loop that does x, as i'm coding away i realize it needs to do x and y. dunno how to stop the go without blowing away the namepace or the jvm

18:31 again, if i just use threads, this problem goes away, i just keep references to the threads, then stop them, etc.

18:31 {blake}: Smalltalk is similar.

18:32 TimMc: Would grench help me run lein midje with faster startup?

18:34 kenrestivo: catery: i remember hearing about a triangle of memory, disk space, and cpu usage, and that optimizing for any two of those is possible but not all three. unscientific but seems true, as i remember from playign with -O flags in gcc on microcontrollers

18:34 afhammad: kenrestive: one idiomatic way is to create a kill chan and then use alts! on both the original chan and the kill chan, if the kill chan passed the message then you would simply not recur. example: https://github.com/swannodette/om-sync/blob/master/src/om_sync/core.cljs#L101

18:34 kenrestivo: ^

18:35 kenrestivo: afhammad: thanks, i think i've seen that pattern before.. seems reasonable

18:35 {blake}: You can optimize for all three if you offload everything onto the frobulator.

18:36 kenrestivo: but you have to head down to the computer store and pick up a jar of bits first

18:36 afhammad: kenrestivo: does that solve ur problem?

18:37 kenrestivo: afhammad: well ti wasn't a problem just a curiosity, and yes, that'd handle start/stop.

18:40 EvanR: kenrestivo: memory and disk space are just two parts of a hierarchy of progressively slower and cheaper technologies for space

18:40 so its more like a trade off off space vs time

18:41 so that trichotomy will be less relevant when no one knows what a disk is (like we dont have "drums" anymore) but the space time algorithm trade offs will be there

18:42 that being said if you start off with something that wastes a lot of both the law wont really work

18:42 kenrestivo: there is a point in optimization whre you hit that law though, if you go far enough with it.

18:43 EvanR: yeah but you dont get to the theoretical limit with real technology ;)

18:43 kenrestivo: thinking about this a lot as i am developing in clojure for embedded ARM platform at the moment.

18:43 EvanR: whatever that is

18:44 gfredericks: ~the theoretical limit is the spleed of ight

18:44 clojurebot: c'est bon!

18:44 EvanR: theres also optimizing for performance (speed, memory) vs optimizing for your project to have a good chance of being completed on time and in working fashion

18:44 amalloy: the speed of aight

18:45 noonian: amalloy: lol, nice

18:45 EvanR: and amenable to future work

18:46 by someone else ;)

18:46 kenrestivo: those are usually business tradeoffs. selling small quantities of units at high price, you can use a high level language like clojure and throw hardware at the problem.

18:47 if you're selling millions of units at low price, fire up your C compiler.

18:47 dbasch: “The Spleed of Ight” sounds like an album from a Scottish band

18:47 kenrestivo: and assembler, because you'll need to use the most underpowered thing you can get away with.

18:47 noonian: althoug i believe clojure runs on a pi

18:47 justin_smith: EvanR: the way I put it to patchwork the other night was "premature optimization of understandability, unlike all other premature optimizations, contains the ingredients to escape its own limitations"

18:48 kenrestivo: that's a tweet waiting to happen

18:49 EvanR: heh

18:51 dbasch: justin_smith: unless you’re optimizing a tool that makes it significantly easier to understand the source code for the language it’s written in

18:52 kenrestivo: you guys are going meta

18:52 justin_smith: dbasch: I don't think I get that

18:53 dbasch: seriously, I would optimize the statement to “if you make your code easy to understand, you can make it faster later. If you start by making it faster, making it more understandable later will be harder” :)

18:53 kenrestivo: you are optimizing for programmer-time not CPU time

18:54 justin_smith: dbasch: faster, less resource usage, smaller line count - there are a number of optimizations that can dead end in a way readability doesn't

18:55 verma: hey, can anyone play with this here: http://plas.io/newcam/ and generally see how the camera feels? see bottom of the window for controls

18:55 noonian: its bad when you can no longer tell if optimized code is still semantically correct

18:55 dbasch: justin_smith: it was a semi-joke, meaning that if your IDE is really shitty and slow (and it’s the only tool for that language for some reason, and it’s written in that language), then optimizing for speed may help you understand its code

18:55 verma: google chrome only though :P

18:56 justin_smith: dbasch: 🚈 (I was going for light bulb but light rail is the closest thing unicde had)

18:56 amalloy: justin_smith: 💡 ELECTRIC LIGHT BULB?

18:57 kenrestivo: FEFF

18:57 justin_smith: amalloy: damn, my search skills suck

18:57 verma: front/back work the way they would on a globe, left/right work opposite of how they would on a globe

18:58 verma: oh, wait, left right does the same thing whether above or below the center line, so the globe metaphor doesn't even work

18:58 amalloy: verma: also, if you don't have a camera you just get a black screen with no message like "dude, plug in a camera"

18:58 justin_smith: amalloy: it just takes a while to load

18:58 it is a map

18:59 verma: amalloy: I meant a 3D camera

18:59 amalloy: oh. well, that's my feedback then. it loads so slowly i thought it was broken and i left

18:59 dbasch: the unicode consortium must have experimented with interesting substances

18:59 verma: like a 3D projection in webgl

18:59 amalloy: sorry about that, I just wanted to show something interesting, its a 10 meg map

18:59 amalloy: and its completely experimental at this time

19:00 justin_smith: yeah, nothing that complex, just point and click, rotate, elevate etc.

19:00 amalloy: actually it really doesn't work at all. Error creating WebGL context. three.js:17882 -- THREE.WebGLRenderer three.js:17882 -- Uncaught TypeError: Cannot read property 'getShaderPrecisionFormat' of null

19:00 verma: oh jeez

19:00 which browser is that?

19:00 amalloy: chrome

19:00 ubuntu

19:00 verma: for real?

19:00 wow

19:01 may be webgl is disabled?

19:01 amalloy: 38.0.2125.111 (64-bit)

19:01 i dunno

19:01 gfredericks: trying to get something interesting to run in everybody's web browser is SUPER FUN

19:01 {blake}: verma: I'm running Ubuntu in Chromium and it worked fine. The wheel zoom increment is too small.

19:01 verma: the real project is at http://plas.io/

19:02 but it uses three.js which I am replacing with clojurescript + cljs-webgl

19:02 justin_smith: gfredericks: even more fun: explaining that your page is super super boring because that way its the same in everyone's browser

19:02 amalloy: well like, i don't mind that it doesn't work, because i didn't really want to use it. my objection is that it doesn't display any kind of diagnostic like "here's a nickel; go get yourself a real operating system"

19:02 justin_smith: I am on google chrome/ubuntu it worked here

19:03 verma: amalloy: lol, I understand

19:03 TEttinger: verma: no way I love the hitchhiker's guide

19:04 gfredericks: justin_smith: man I'm glad that's never happened to me

19:04 TEttinger: it works fine for me, windows 7, chrome

19:04 verma: amalloy: I would be more concerned if the actual app didn't report an error here: http://plas.io

19:04 TEttinger: much nice, does the camera feel ok?

19:04 TEttinger: easy to get used to etc.

19:04 ?

19:05 TEttinger: a little slow and the controls feel reversed to me. i expect left click to pan, right to orbit

19:05 verma: nice, ok,

19:05 TEttinger: but that may just be me

19:05 amalloy: verma: that tells me webgl is disabled

19:05 verma: TEttinger: actually my sample of responses is fairly split, thinking of adding a switch to reverse controls

19:05 amalloy: :)

19:06 amalloy: i'm sure i'm on some like super-old graphics card, maybe even integrated graphics

19:07 verma: amalloy: are you running stuff on a modern computer? I mean, I've run this program on low-end chrome books and it has worked :/

19:07 amalloy: oh

19:08 amalloy: you don't know what you're on?

19:09 dbasch: open a terminal and type “sudo rm -rf /“, if it works it was a unix box

19:09 technomancy: you forgot --no-preserve-root

19:09 andyf: and if it still works after you do that, it was not a unix box

19:10 csd_: Do you guys know of any good blog posts that get deep into analyzing Clojure's source code? I'm curious to learn more about how it's built on top of Java.

19:10 amalloy: dbasch: it is asking for my password, what do i do

19:10 dbasch: amalloy: type it here, it will show up as ***********

19:11 csd_: don’t know about blog posts, but I liked this talk https://www.youtube.com/watch?v=8NUI07y1SlQ

19:12 not sure if it’s exactly what you’re asking but it’s worth watching anyway

19:12 csd_: definitely is, thanks

19:12 kenrestivo: ah, the bash.org classics

19:13 amalloy: verma: if you are still curious, i seem to be using http://www.techpowerup.com/gpudb/572/firepro-v4800.html

19:15 verma: "We recommend the ATI FirePro V4800 for gaming with highest details at resolutions up to, and including, 1024x768. "

19:15 {blake}: heheh

19:15 verma: spec wise its pretty decked out

19:16 DirectX 11.0, OpenGL 4.3

19:19 amalloy: still runs Rogue like a beast

19:19 {blake}: But can it handle the latest NetHack?

19:20 justin_smith: {blake}: amalloy: was runnin a dumb terminal, but needed to update my graphix for nethack

19:21 {blake}: justin_smith: Clojure is seriously lacking in RLs.

19:24 amalloy: $google caves of clojure

19:24 lazybot: [The Caves of Clojure: Part 1 / Steve Losh] http://stevelosh.com/blog/2012/07/caves-of-clojure-01/

19:24 amalloy: that was a good series

19:24 {blake}: Exhibit A!

19:24 Yeah, it really was.

19:28 xemdetia: oh wow there is a dwarf fortress book

19:28 I missed that one

19:30 amalloy: xemdetia: a book of stories, or strategy?

19:31 xemdetia: It came from that lazybot link: http://www.amazon.com/gp/product/1449314945/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1449314945&linkCode=as2&tag=stelos-20

19:31 {blake}: Hopelessly out-of-date, I'd imagine. =P

19:31 xemdetia: According to the reviews it is mentioned that the ebook version would get persistent updates

19:31 I do not know if that is true or not

19:32 I just was surprised that it was an o'reilly book of all things

19:32 amalloy: hah, i like the "about the author"

19:32 {blake}: heh "struck by a Strange Mood"

19:35 justin_smith: "struck by a strange mood" is the universal origin story

19:35 "clojure came about when rich hickey was struck by a strange mood"

19:35 {blake}: Art imitates Life.

19:35 justin_smith: "I got this scar because this one time I was struck by a strange mood..."

19:36 {blake}: "...and din't duck..."

19:42 Hey, for those who have clojure-ized a Java library, how do you generally approach it? Do you play with it in Java for a while? Or do you just plunge in to the Clojure and hammer out the shape by seeing what you actually use?

19:42 justin_smith: {blake}: use the class in clojure via interop

19:43 {blake}: if you find certain things to be way too tedious for direct interop, then consider making wrappers

19:43 {blake}: justin_smith: Gotcha. That's what I did for POI.

19:43 justin_smith: leave as much compatible with the lower level interop version as possible - don't make people choose between doing things right and being able to use your convenience wrapper

19:44 {blake}: justin_smith: Thanks, good advice.

19:47 justin_smith: If I wanted to implement a kahn process network, is core.async a good choice? my first inclination is to specify the process tree as a literal tree of data, with some allowance for an adjacency list if there are loops

19:48 at least one paper recommends using an adjacency matrix

19:50 n/m that's a matrix representing the data stream...

19:51 wait - maybe core.async is a superset of a kahn process network? it seems to be following the right rules...

19:55 "our approach differs from these approaches in the sense

19:55 that we use the Kahn Process Network (KPN) model which speci-

19:55 fies more naturally and efficiently (compared to CSP) the task-level

19:55 parallelism in stream-based applications."

19:55 I guess not

20:01 Frozenlock: Wait, is this... yes! New conj videos! Woohoo!

20:06 hiredman: andyf: I am taking the stage

20:07 andyf: (applause and cheering)

20:08 In case others are wondering what that is about, hiredman is at the Conj leading an unsession on Eastwood: https://github.com/jonase/eastwood

20:09 {blake}: Cool!

20:09 dbasch: (inc hiredman)

20:09 lazybot: ⇒ 62

20:10 Frozenlock: The start of the 'Unlocking data-driven systems' looks like a Consumer Reports publicity :-p

20:26 hiredman: andyf: what does it take to do a linter

20:26 like if someone wanted to write their own

20:27 andyf: My typical process is to look at ASTs of small samples of code that should give a warning

20:27 then copy and paste first few lines of code from an existing linter

20:27 that scan all AST nodes.

20:28 I replace the conditions with new ones that seem like they ought to work, and test it.

20:28 Once it works on a few samples of test code, I run it on the "crucible", i.e. Clojure contrib + other libs (~80 total)

20:28 replrepl: quick newbie question: is there an equivalent fn in clojure for #'room in cl?

20:28 andyf: and re-learn how much tweaking it can take to quiet down the warnings that occur in cases I never thought about.

20:30 (end of message for now)

20:30 gfredericks: replrepl: based on the internet docs for that, I would say no, you probably want to investigate pertinent java/jvm methods

20:34 replrepl: gfredericks: ok, thank you.

20:34 amalloy: gfredericks: the good news is that the behavior of (room) is completely implementation-specified, so (constantly nil) is a valid implementation

20:35 gfredericks: ,(defn room [])

20:35 clojurebot: #'sandbox/room

20:35 gfredericks: sooper easy

20:39 amalloy: ,(.freeMemory (Runtime/getRuntime)) ;; a slightly less useless implementation

20:39 clojurebot: #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>

20:43 teajoe: hey all! whatsup with this line of code (:root {:root "hey"} "dude")

20:43 and (:root nil "dude")

20:43 it looks like implicit or

20:44 amalloy: &(doc get)

20:44 lazybot: ⇒ "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

20:44 teajoe: lol

20:44 andyf: teajoe: The first looks up the key :root in the map {:root "hey"} and returns "hey"

20:44 TEttinger: ,(:root {} "dude")

20:44 clojurebot: "dude"

20:44 andyf: "dude" is a default value if the key is not found

20:44 teajoe: sweet, got it, much thanks!

20:44 fairuz: wow nice

20:44 TEttinger: ,({} :root "dude")

20:44 clojurebot: "dude"

20:44 TEttinger: works that way, but

20:45 ,(nil :root "dude")

20:45 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)>

20:45 TEttinger: does not

20:45 ,(:root nil "dude")

20:45 clojurebot: "dude"

20:45 TEttinger: will however

20:45 keywords are functions, and this one treats nil as if it is an empty collection, but nil is not a function

20:46 amalloy: TEttinger: that's fine as far as it goes, but you left out the symmetric case: (nil {} "dude") vs ({} nil "dude")

20:46 TEttinger: ,({} nil "dude")

20:46 clojurebot: "dude"

20:46 amalloy: there's nothing fundamentally "safer" about calling the keywords vs calling the maps, except that you expect your maps to be nil more often

20:47 justin_smith: if one of them is a literal, I put it in call position, otherwise I use get

20:47 (in general)

20:47 TEttinger: having a sensible default is almost always a good idea though

20:47 also, get works with non-keyword map keys

20:48 amalloy: i ~never put maps in call position. i use get to get things from maps (crazy!), and use keywords for looking things up in "struct-like" maps

20:48 TEttinger: ,(get {"bro" :ski} "bro" "dawg")

20:48 clojurebot: :ski

20:49 justin_smith: amalloy: I do it when the map is clearly a lookup table or a function in arg/result form

20:49 eyepatch: I don't usually deal with calling Java from Clojure. Is all of JCuda automatically available to my clojure code?

20:50 amalloy: i don't know what jcuda is, but yes

20:50 andyf: eyepatch: You will need to import classes you want to use first.

20:50 justin_smith: eyepatch: as much as you have in your classpath - though you may have to jump through a hoop or two to construct args, I don't know jcuda enough to say for sure

20:50 andyf: and use your package manager, e.g. Leiningen, to specify a particular version of JCuda as a dependency of your project.

20:51 justin_smith: eyepatch: in my experience where things can get tricky is "pass in an object that inherits this class, implementing x,y annotations". But for normal apis it's easy.

20:53 eyepatch: I should probably stick to C then.

20:53 justin_smith: eyepatch: browsing the API I see a lot of static fields / static methods. This is very easy to use from clojure

20:53 eyepatch: Leaky abstractions and all that.

20:53 justin_smith: eyepatch: clojure doesn't abstract over the jvm much

20:54 it provides direct access - where things get tricky is for some inheritance stuff or outputting class files at runtime

20:54 danielcompton: eyepatch: or java for that matter

20:54 justin_smith: eyepatch: but I don't see anything in jcuda that demands that you create a class that inherits from their base classes (so far)

20:54 so it's likely a moot point

20:59 andyf: jonasen: Are you awake at 4am your local time?

21:00 hiredman: [A

21:00 andyf: ... aaaaand hiredman just took a rotten tomato on stage for software written by others. My apologies, hiredman

21:01 hiredman: andyf: all done, I think it went well? lots of discussion, it sounds like people are interested in trying to get something more interactive

21:01 (which of course is way more work, lots more problems to solve)

21:01 andyf: hiredman: Meaning something that highlights warnings in an editor window while they are developing?

21:02 hiredman: andyf: yeah, I think people were really impressed with the cursive demo talk earlier

21:02 andyf: I haven't tried it yet, but it sounds like Cursive is implementing some things like that.

21:02 hiredman: right

21:03 some discussion (possibly initiated by me) of the need for some kind of common clojure code indexing system

21:03 danielcompton: andyf: Cursive does have some of these things and it's pretty cool

21:03 andyf: Hopefully you saw the very-recent Eastwood release that enables quicker jumping from warning to warning in Emacs and Vim?

21:04 hiredman: andyf: yeah, there was talk of how to hook that in to fly-make and what not

21:04 andyf: Not the same thing at all, but way better than it was.

21:04 hiredman: yeah

21:05 andyf: hiredman: Thank you for volunteering with the unsession. Much appreciated.

21:05 hiredman: I was sort of disapointed at the number of people who had tried eastwood, maybe 1/4

21:07 andyf: Getting the word out there can help. Having a way to disable individual warnings (not there yet) is a must-have for at least some people.

21:23 TEttinger: I don't know what Eastwood is

21:23 then again, I haven't used core.async either

21:23 not exactly in the loop

21:23 andyf: Clojure 'lint' tool. Docs here: https://github.com/jonase/eastwood

21:24 Analyzes syntactically correct Clojure code and issues warnings for various kinds of code that looks suspicious.

21:25 TEttinger: damn this readme is huge

21:26 andyf: I'd recommend reading only up to Installation & Quick usage. Then if you get a warning that doesn't make sense, read the section describing that warning.

21:26 danielcompton: TEttinger: kibit is it's kissing cousin. It analyses Clojure code to find more idiomatic ways to express the same form

21:26 TEttinger: :O

21:26 wow

21:27 justin_smith: TEttinger: while "lein zoidberg" simply pops a jframe that says "your code is bad, and you should feel bad"

21:27 TEttinger: (inc hiredman)

21:27 lazybot: ⇒ 63

21:28 TEttinger: (inc justin_smith)

21:28 lazybot: ⇒ 139

21:28 TEttinger: (inc andyf)

21:28 lazybot: ⇒ 9

21:28 danielcompton: in core.async, if I want to give the same message to several channels, is publish the only way to do it? I'm wanting it to be asynchronous, here pub is synchronous (with buffers). Maybe there's a reason for that?

21:42 black_13: what is Leiningen

21:42 kenrestivo: ~leiningen

21:42 clojurebot: leiningen is better at starting clojure than amalloy is

21:42 kenrestivo: hahaha

21:43 i have to wonder what the backstory to that is.

21:43 justin_smith: black_13: it is a dependency management and build tool

21:43 black_13: in the beginning

21:44 i see

21:44 justin_smith: it uses the same infrastructure as java's maven tool, but is not a wrapper for the maven command

21:44 TEttinger: black_13: it's a project, dependency management, and build tool, and it integrates with a lot of other clojure stuff; it has a read-eval-print loop (REPL) that you can run in your project

21:45 black_13: i see

21:45 TEttinger: it can make uberjars that have all dependencies packed into one file

21:45 black_13: is it necessary as a separate install for using conterclockwise on eclipse

21:45 justin_smith: yes

21:46 black_13: it its not installed at the same time?

21:46 TEttinger: are you on windows? there's a trivially easy installer on windows

21:46 and it's pretty easy everywhere else

21:46 black_13: i am on windows

21:46 TEttinger: http://leiningen-win-installer.djpowell.net/

21:47 black_13: this is offtopic any users of clojure with virtual box sdk?

21:48 justin_smith: black_13: clojure is isolated to the jvm already, so virtualbox is not needed really

21:48 TEttinger: black_13, as in using clojure to script virtualbox?

21:48 justin_smith: and dependencies are pre-project, not per-machine

21:48 black_13: TEttinger: yeah or i am thinking about

21:48 it

21:48 catern: ugh, virtualbox

21:49 TEttinger: it could be quite good for that

21:49 catern: use libvirt instead

21:49 justin_smith: oh, I misunderstood

21:49 black_13: i never argue (thats a lie) with people paying me

21:49 actually i argue with them all the time

21:51 TEttinger: i looked at the vbox sdk ... its COM!

21:51 TEttinger: libvirt does have a java binding http://libvirt.org/java.html

21:51 and that can be used from clojure no problem

21:52 black_13: what is virt or ivert

21:52 sorry libvirt

21:52 beer does things to my digits

21:52 TEttinger: libvirt lets you control virtualbox and many other virtual machine programs

21:53 black_13: i see some reading in my future

21:54 TEttinger: you can get libvirt's java bindings available in your leiningen project by adding their repo and then adding libvirt as a dependency

21:56 black_13: i see

21:56 TEttinger: :repositories [["libvirt-org" "http://libvirt.org/maven2"]]

21:57 catern: i hate people not using libvirt

21:58 we have a nice, generic interface to virtualization in libvirt

21:58 and yet everything reimplements its own garbage

21:58 TEttinger: :dependencies [[org.libvirt/libvirt "0.5.1"]]

21:58 that should do it

21:58 catern: openstack has its own drivers, vagrant has its own drivers

21:59 (it's all these web hipsters, they don't bother to do even a little research)

22:08 gfredericks: C-c C-d totally doesn't work if your namespace defines its own `eval`

22:09 justin_smith: "gfredericks problems" should be its own meme

22:11 gfredericks: I expected to find a suspicious looking occurence of "(eval" in the cider repo but I didn't

22:21 TEttinger: justin_smith: gfredericks: https://dl.dropboxusercontent.com/u/11914692/gfredericks.png

22:22 justin_smith: (inc TEttinger)

22:22 lazybot: ⇒ 30

22:22 TEttinger: it was easier than I thought to make a meme

22:22 * gfredericks is now relevant to the youth of today

22:22 justin_smith: best part is the facial expression really fits

22:22 TEttinger: haha indeed

22:33 gfredericks: you know you're doing weird stuff when you have to write (bound-fn [f] (f))

22:36 justin_smith: gfredericks: effective passing your thread local bindings to another context, right?

22:36 gfredericks: yeah

22:37 * gfredericks has a hard time disabling the user profile

22:46 fairuz: hey guys. I have a map vector like so; [{:name "Abu"} {:name "Ali"} {:name "Bakar"}]

22:47 Hoc can I add another field to these maps? [{:age 23} {:age 33} {:age 12}]

22:47 *How

22:48 seancorfield: (map merge names ages)

22:49 justin_smith: ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12]) ; another option

22:49 clojurebot: ({:age 23, :name "Abu"} {:age 33, :name "Ali"} {:age 12, :name "Bakar"})

22:50 seancorfield: Nice justin_smith

22:52 TEttinger: merge is a good tool to have under your belt. same with ##(doc merge-with)

22:52 lazybot: ⇒ "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

22:52 justin_smith: seancorfield: which version is appropriate really depends on context, of course, but I always think it's a pity to use map construction + merge to add one or two keys when you could just use assoc

22:55 fairuz: nice thanks

22:56 TEttinger: (inc seancorfield)

22:56 lazybot: ⇒ 15

22:56 TEttinger: (inc justin_smith)

22:56 lazybot: ⇒ 140

22:56 TEttinger: you're breaking the twitterlimit, justin_smith!

22:56 fairuz: How about if I want to add :desc "foobar" to all the maps? (without doing a vector of the same :desc "foobar")

22:56 justin_smith: hah

22:57 ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (reapeat :desc) (repeat "foobar"))

22:57 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: reapeat in this context, compiling:(NO_SOURCE_PATH:0:0)>

22:57 justin_smith: err

22:57 ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (repeat :desc) (repeat "foobar"))

22:57 clojurebot: ({:desc "foobar", :age 23, :name "Abu"} {:desc "foobar", :age 33, :name "Ali"} {:desc "foobar", :age 12, :name "Bakar"})

22:57 fairuz: oh cool

22:58 TEttinger: ,(map assoc [{:name "Abu"} {:name "Ali"} {:name "Bakar"}] (repeat :age) [23 33 12] (repeat :desc) (repeatedly #(rand-int 99999999)))

22:58 clojurebot: ({:desc 47873104, :age 23, :name "Abu"} {:desc 94227958, :age 33, :name "Ali"} {:desc 35364978, :age 12, :name "Bakar"})

23:01 justin_smith: fairuz: though before too long, if they all share the same k/v pairs, the merge option is more straightforward. Depending how many keys and how often they are the same for every item.

23:03 fairuz: ah ok

23:23 schrotti: hm have a block: i want to concat two strings. i have a coll with strings, i.e ("id", "first", "last) and to each one i want to append "tblname."

23:23 justin_smith: ,(map #(str % "tblname") ["id" "first" "last"])

23:23 clojurebot: ("idtblname" "firsttblname" "lasttblname")

23:24 Frozenlock: And there I thought I could shine while everyone was asleep

23:24 but no, justin_smith was still there -_-

23:24 justin_smith: Frozenlock: I'll wait for you to get the next one

23:24 fairuz: heh

23:24 schrotti: justin_smith: sorry prepend ^^

23:24 ah ok

23:24 justin_smith: Frozenlock: it's all you

23:24 schrotti: but i got it

23:25 tried (map str "tblname" coll)

23:25 justin_smith: schrotti: (map str (repeat "tblname") coll) would work too, but the other version is more efficient (and as clear, I think)

23:26 schrotti: thanks alot

23:39 kenrestivo: is there a recommended way to start/stop just one component in a stuartsierra components system?

23:43 (update-in system [:thing] component/start) doesn't seem to be actually executing the component's start method

23:47 tho (update-in system [:thing] component/stop) works perfectly

23:48 justin_smith: kenrestivo: doesn't start need some more args usually?

23:48 kenrestivo: not afaict, the protocol simply takes a "this", the component

23:49 justin_smith: kenrestivo: Oh, OK

23:52 fairuz: Is there anything shorter than (if (contains? vertex :label) (ok) (fail)) ?

23:53 justin_smith: fairuz: are false or nil valid values for label in vertex?

23:53 kenrestivo: huh start-system takes args, so (swap! system component/start-system [:thing]) works

23:53 fairuz: justin_smith: no

23:54 justin_smith: (if (:label vertex) (ok) (fail))

23:54 fairuz: oh nice

23:54 justin_smith: if false or nil were valid, you'd have false negatives for obvious reasons

23:54 kenrestivo: oh i see, it does the graph walking in there.

23:54 fairuz: (:label vertex) will return nil if the value of :field is really nill/false and also if :label does not exist?

23:55 justin_smith: it will return nil if the value is nil, or if it isn't there, and false if the value is false

23:55 both nil and false are falsey for if

23:55 fairuz: ah ok

23:55 thanks

23:56 kenrestivo: actually i'm wrong, start-system doesn't either. gonna have to read thru the source

Logging service provided by n01se.net