#clojure log - Jun 07 2014

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

13:53 arrdem: Bronsa: config-map branch is up.

13:55 bobbrahms: 1

13:57 Bronsa: arrdem: looks fine, thanks for the docstrings :3

14:00 arrdem: Bronsa: there's more where that came from :P

14:01 * arrdem resists the urge to do a massive formatting branch

14:21 Frozenlock: Is there a :subdomain field in compojure?

14:21 ...or do I need to parse it myself from the host?

14:31 augustl: is it ok for my "app instance" (stuart sierra style) to have atoms, or should I go all in and have my business logic return a new version of the app instance, or something like that?

14:32 given that my app instance will be called from multiple threads (a servlet) managing that return value seems nasty..

14:39 justin_smith: augustl: with concurrency, the only way to have the app instance return a new version of itself is by allowing some coordination of threads, and that is what atoms and refs are for

14:41 augustl: is there a way to atomically get the value of an atom _and_ set it to a new value?

14:41 in this case it's for my app shutdown function, where I want to do stuff with an atom but ensure that no new items are added while I'm shutting down

14:41 justin_smith: (doc swap!)

14:41 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

14:42 augustl: I don't want the value that was swapped in, I want the value that was there before the swap :)

14:42 justin_smith: augustl: your shutdown function is the arg to swap!

14:42 augustl: reset! also returns the new, not the old value

14:42 justin_smith: ah, of course :)

14:43 swap! won't guarantee that my function is the last one to run, though..

14:44 justin_smith: you want something else for proper locking, atoms imply that retries are OK

14:44 they are not a locking construct

14:44 (doc lock)

14:44 clojurebot: Gabh mo leithscéal?

14:44 augustl: justin_smith: yeah sounds like I want something else :)

14:44 justin_smith: (doc locking)

14:44 clojurebot: "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."

14:44 justin_smith: (locking your-atom ...) may be what you want

14:45 but then it is up to you to ensure there are no deadlocks, livelocks, etc.

14:45 it is very low level stuff

14:45 augustl: what I _really_ want is for my system to not modify my app state while it's shuttting down

14:45 say shutdown is called while a thread processes a request, for example

14:45 justin_smith: also it only really works if everything that uses that atom in a way you care about uses the locking statement

14:45 it is brittle

14:45 Bronsa: augustl: I mean, you could be a really awful person and do something like user=> (def a (atom 0))

14:46 user=> (let [p (atom ∅)] (swap! a (ƒ [old p] (reset! p old) (inc old)) p) @p)

14:47 justin_smith: augustl: then maybe what you really want is for shutdown to stop all the threads first

14:47 augustl: I guess ideally I would like to control the executor that invokes my app, so I can poll it until there are no active threads and then shut down

14:47 justin_smith: (all the other threads that is)

14:47 augustl: justin_smith: yeah :)

14:47 not sure how to best handle that since this is typically done automatically by jetty/servlets

14:47 justin_smith: maybe (shutdown-agents) does the trick? it should not shut down until they are all done

14:48 augustl: perhaps I should have an additional executor for my own app

14:48 sounds like a lot of extra threads though

14:48 justin_smith: looking it up!

14:48 justin_smith: you can use jvisualvm to look at the threads that exist in your app at runtime, and to see if shutdown-agents really stops all the ones you care about

14:49 augustl: there are some operations in my system that I want to make completely serial anyway.. So perhaps taking control of the thread pools makes sense in my case

14:49 justin_smith: no if ring / jetty is using it's own threadpool that shutdown-agents doesn't know about, then your back in low level land again I think

14:49 *now

14:49 augustl: having my app support getting invoked by anyone at any time from any thread sounds like a world of coordination hurt

14:50 justin_smith: augustl: maybe you want a serialization mechanism, I like java.util.concurrent.SynchronizedQueue

14:50 augustl: yeah that sounds nice

14:50 justin_smith: so instead of invoking things directly other code puts events on your queue

14:50 augustl: I wonder how large a servlet/jetty thread pool typically is

14:51 50 or so extra threads won't hurt that much I suppose ;)

14:51 justin_smith: then the thread pool you control decides how to handle events, and when to stop handling them, etc.

14:51 very narrow and easy to control surface of interaction

14:51 augustl: yeah this sounds very pleasant :)

14:51 except from the extra threads of course, but then again that's just a gut feeling, no idea if it's a real problem

14:52 justin_smith: maybe you can be more lenient and use a queue with a length other than 0 - synchronizedqueue is very strict - it blocks until the previous contents leave

14:52 well you decide how many threads are dispatched from the requests in the queue

14:53 and you can use for example agents or futures that share clojure's nicely handled thread pool and you can bind the ones you are using and manually control those

14:53 will still using the shared pool

14:53 *while

14:55 augustl: making it a TODO for now, looking forward to implementing this

14:56 onwards to the actual business code for now though ;) will use an atom, and solve shutdown by taking control of threads executing my code later

15:01 justin_smith: augustl: also, core.async is another paradigm for addressing these same concerns / coordination issues

15:01 augustl: justin_smith: is core.async good for doing RPC? Or is it more of a queue system?

15:01 as in, get a request, return a response

15:02 justin_smith: augustl: well, queues are one way to coordinate RPC (among other things they can do)

15:02 it is about handling and sending messages

15:02 augustl: haven't done that before.. But I guess all you need is some kind of request ID

15:03 justin_smith: right, you would have an intake worker, and then assorted handlers, and the request would have to include the info needed to respond

15:03 instead of a request ID you can pass the open socket to the client

15:03 *the open socket the client is connected to* I mean

15:04 augustl: ah, that makes sense yeah

15:04 no need to create an id when one already exists :)

15:04 justin_smith: going with that whole functional passing state to functions idea

15:04 right

15:11 tolstoy: Does om/transact! and om/update! really take a tag, and do they really show up in the tx-listen callback? I'm not seeing them.

15:29 Ah. transact! expects a "korks" argument, even if the path is the root. An arity issue, I suspect.

15:37 borkdude: does anyone happen to know what merge-by is in scala?

15:39 pdk: hey, when you're writing the LICENSE file for a new project

15:39 is it ok to abbreviate your name in the copyright notice

15:43 Glenjamin: i'd err on the side of caution, but you're better off asking a lawyer if its important

15:43 pdk: like just f.m. last vs. first middle last

15:43 clojurebot: Pardon?

15:49 pdk: http://www.copyright.gov/title17/92chap4.html

15:49 looks like a recognizable abbreviation is okj

16:01 Frozenlock: Copyright Frozenlock 2014

16:05 Btw, how does one proves his identity when using 'official' names in a copyright? It's not like there's only one John Smith in the world.

16:05 *prove

16:06 We need namespaces for names :-p

16:18 arrdem: Frozenlock: you can provide a contact method and/or handle to add more bits of information to an otherwise useless name :P

16:18 Frozenlock: most of my stuff is (c) Reid "arrdem" McKenzie

16:18 where "arrdem" is unique to me AFAIK

16:19 Frozenlock: Which one is the useless one? Reid Mckenzie, or arrdem? :-p

16:20 arrdem: Frozenlock: your "John Smith" is pretty useless :P

16:20 roppongininja: light table v sublime text + sublimerepl?

16:21 or any other better alternatives (no time to fvck around with emacs)

16:22 Frozenlock: better alternatives? Emacs... No time to fuck around emacs? Well... use Emacs and don't fuck around!

16:22 I'm so funny today...

16:22 arrdem: then apparently you have no time to get used to the current top rated Clojure repl...

16:22 Light Table's repl is famous for being a "maybe works" still in development afair.

16:22 Bronsa: roppongininja: leaving emacs aside, I've heard cursiveclojure is pretty good

16:23 and should Just Work™

16:23 * yeoj___ is fucking around with emacs at the moment...

16:23 yeoj___: but hey it's saturday. thats what saturday is for.

16:23 * arrdem should publish the results of his many fuckings around with emacs

16:24 yeoj___: actually for me cider just started deciding it didn't understand any of the classpath business going on so i'm trying to figure out what went wonky

16:24 then i'll get back to work

16:33 for somereason cider connects to the repl, but gevise me "class not found exceptions" everywhere... i didn't have this problem yesternight. i'm also getting "Cannot decode message" in emacs, something about the nrepl middleware

16:33 i made something borken.

16:41 s_kilk: Hi all, is anyone here using Clojure web servers with a SQL backend in production? I have a few questions related to handling SQL migrations.

16:45 dbushenko: s_kilk, try http://flywaydb.org/

16:50 s_kilk: @dbushenko, thanks, I'll look into that. do you use it?

16:52 Frozenlock: Eh... I wanted to activate a SSL certificate today... but Namecheap email servers are down. :-(

16:53 (and they send to SSL stuff to the domain email)

16:53 *the

16:56 dbushenko: s_kilk, yes

16:59 s_kilk: dbushenko, thanks!

17:06 _pr0t0type_: Hey Guys, so I know I can use reify to implement an interface. however, how do implement other methods within that reify call? When I try to, I get a "java.lang.IllegalArgumentException: Can't define method not in interfaces"

17:07 Glenjamin: _pr0t0type_: you can implement multiple interfaces

17:09 _pr0t0type_: Glenjamin: I see, so there is no way to inline a definition right in reify without another interface

17:09 Glenjamin: not as far as i know

17:10 _pr0t0type_: Glenjamin: thanks

17:40 JokerDoomWork: Any recommendations for excellent Lispy/Clojurey books?

17:41 bbloom: ~book

17:41 clojurebot: book is http://www.pragprog.com/titles/shcloj/programming-clojure

17:41 bbloom: ~books

17:41 clojurebot: books is programming clojure

17:41 bbloom: ~onlisp

17:41 clojurebot: excusez-moi

17:41 bbloom: clojurebot: onlisp is http://www.paulgraham.com/onlisp.html

17:41 clojurebot: Ack. Ack.

17:42 JokerDoomWork: wth just happened

17:42 bbloom: clojurebot: schemer is http://scottn.us/downloads/The_Little_Schemer.pdf

17:42 clojurebot: Alles klar

17:42 bbloom: JokerDoomWork: i'm telling clojurebot some stuff to help answer book related questions here in irc

17:43 Jaood: bbloom: isn't that warez?

17:43 the little schemer pdf

17:43 bbloom: Jaood: is it?

17:43 it was 2nd link on google

17:43 *shrug*

17:43 JokerDoomWork: Eh, I'm ok on the Paul Graham, I try to steer clear of demagogues

17:44 I'm jk, I'll check it out

17:44 Jaood: bbloom: as far as I know there's no official pdf for that book but I may be wrong

17:44 bbloom: JokerDoomWork: all of pg's other dealings aside, On Lisp is pretty much the definitive Common Lisp book

17:46 JokerDoomWork: bbloom, I actually am a fan of his writings, at least his style, but I've always assumed learning lisp from him would turn me into him on lisp, which I don't want...

17:46 Glenjamin: "with bottom-up programming as the unifying theme"

17:46 this intrigues me

17:46 as i'm generally of the opinion that top-down gives better results

17:47 i may have to buy this

17:47 or just download it for free, apparently

17:47 Hodapp: It's not that top-down gives better results, it's that a lot of languages don't provide for the sort of composition of structures that makes bottom-up even possible.

17:56 bbloom: Glenjamin: Hodapp: is is the case with *any* dichotomy/duality .... the answer lies in the middle

17:56 there's no correct answer, you need to do a little bit of both

17:57 the reason for trumpeting the bottom up approach is b/c it is/was was common/supported/encouraged

18:02 Hodapp: As is the case with any dichotomy/duality, the answer may or may not lie in the middle.

18:03 Claiming that it is a dichotomy and therefore that the right answer must lie in the middle

18:03 ...can tend to lend some equivalence to a side that may not be appropriate.

18:04 Glenjamin: which side is that? ;)

18:05 Hodapp: Either one.

18:07 Both could be wrong. One could be wrong. It's not an automatic "both are correct".

18:08 justin_smith: a claims that PI is 3.14... b claims it is 3, Some things are not subjective and not helped by compromise

18:11 Glenjamin: on a continuum from bottom-up to top-down, i'm not sure there's a third way

18:11 justin_smith: middle out?

18:13 even Paul Graham talks about the need to alternate between Top Down and Bottom Up in On Lisp IIRC - the significant thing is that in most languages Bottom Up isn't even feasible

18:13 JokerDoomWork: I'm so entrenched in Top down decomposition I have trouble even imagining what bottom up even means

18:14 justin_smith: JokerDoomWork: imagine that you have all your infrastrcuture, all your libraries and data structures implemented. Now write the code that would use that infrastructure.

18:14 next, start implementing the stuff that makes that code valid.

18:15 this especially makes sense in a syntax-creation-happy lang like common lisp

18:16 JokerDoomWork: but didn't I have to implement all those things first, that seems like I'm starting from the top

18:18 justin_smith: no, you write the code, then the syntax and libraries that makes it compile

18:18 JokerDoomWork: Oh I see

18:18 justin_smith: tdd can get into that kind of thing

18:18 JokerDoomWork: I do that quite a bit actually, Hrmmm, I just never thought of it as bottom up, I just consider it, pretending that I have done the hard parts haha

18:18 tdd?

18:18 oh test driven development

18:31 Glenjamin: Interesting, I think I'll have to read this now

18:32 "no, you write the code, then the syntax and libraries that makes it compile" <- i would describe this as top-down

18:33 justin_smith: Glenjamin: really? so what would you call bottom up?

18:33 Glenjamin: writing the syntax and libraries first

18:34 justin_smith: I think of it is the structure of the implementation vs. what usage looks like - bottom up starts with usage, top down starts with structure

18:34 Glenjamin: oh, i would have used the terms in the opposite way :D

18:34 justin_smith: http://www.paulgraham.com/progbot.html <- here is where graham describes bottom up

18:35 "Experienced Lisp programmers divide up their programs differently. As well as top-down design, they follow a principle which could be called bottom-up design-- changing the language to suit the problem."

18:36 Glenjamin: i guess that's a meet-in-the-middle sort of thing

18:36 from wikipedia, on top-down: "In a top-down approach an overview of the system is formulated, specifying but not detailing any first-level subsystems. Each subsystem is then refined in yet greater detail, sometimes in many additional subsystem levels, until the entire specification is reduced to base elements."

18:37 i would do that, but replace "specify" with "implement"

18:38 justin_smith: "implementing but not detailing"?

18:38 kenrestivo: bbloom: all generalizations destroy themselves. including that one.

18:39 :-P

18:41 Glenjamin: justin_smith: doesn't fit that sentence very well, but sort-of, You call code you wish you had

18:42 justin_smith: Glenjamin: I also sometimes do refactoring this way (though it is easier in a stricter language) - I make the change I want in a few pivotal places, and then just follow the hyperlinks emacs offers to compilation errors until it all makes sense again

18:43 platz: My idea of bottom-up is rather than building the control flow first and then implementing the details, you construct primitives that compose in the way that will be able to solve your problem.

18:43 and then having all your building blocks putting them in the final flow is the last step

18:44 which speaks to the "utilities you wrote for the first program will also be useful in the succeeding ones" idea in the article

18:44 justin_smith: platz: well, that is kind of what I meant by writing the code in the way you think it should look before implementing the details - though that is a much better way of putting it because it is more explicit about the extending the language part

18:44 Glenjamin: That fits my perception. I prefer to build downwards to discover what building blocks I need

18:44 platz: justin_smith: I don't think that's the same, that seems more like tdd

18:46 justin_smith: platz: your right, I was thinking sloppily, in my head the thing I was doing that was not yet implemented was language building blocks, but I in no way indicated such a thing

18:46 *thing I was using

19:36 JokerDoomWork: so reflection in Clojure, do I need to use the normal java facilities?

19:36 Or is there better support in clojure for reflection as a languauge feature?

19:46 AWizzArd: Any AI devs around?

19:52 justin_smith: JokerDoomWork: there is clojure.reflect

19:52 and there are some other, easier to use libs too

19:52 sometimes it suffices to just use bean to find what I want

19:52 ,(bean java.io.File)

19:52 clojurebot: {:enum false, :interfaces #<Class[] [Ljava.lang.Class;@cdd309>, :declaredConstructors #<Constructor[] [Ljava.lang.reflect.Constructor;@133fb54>, :simpleName "File", :package #<Package package java.io, Java Platform API Specification, version 1.6>, ...}

20:27 pandeiro: any thoughts on the easiest way to create a new lein project /within/ the pwd instead of creating a new directory?

20:34 justin_smith: pandeiro: why?

20:35 lein new whatever; mv whatever/* .; rmdir whatever

20:35 pandeiro: justin_smith: my workflow is: i create a project as a bare remote repo, clone it to a local dir, then do the scaffolding

20:36 sure i guess that is what i thought of wrapping in a script

20:36 then the complexity came in with not knowing which arg would be the project name

20:36 `lein new schwa` vs. `lein new ouija schwa`

20:38 amalloy: pandeiro: why clone the bare repo? create a bare repo, then create a project with lein new, then git init; git remote add the bare repo

20:38 justin_smith: pandeiro: "${@: -1}" in bash

20:38 and yeah, amalloy's suggestion is what I do

20:40 mwelt: hi there

20:40 AWizzArd: Moin mwelt.

20:40 mwelt: the leiningen chan seems dead so maybe here is some one who can help me :)

20:40 AWizzArd: Worth a try.

20:41 mwelt: got the latest leiningen version and made up simple dummy project with lein new app someappname

20:41 lein run needs 47s to print out hello world

20:41 AWizzArd: mwelt: even when you do this 2-3 times in a row?

20:42 justin_smith: yeah, that's mainly clojure's fault

20:42 tolstoy: Did Clojure 1.6 significantly increase boot time like that?

20:42 mwelt: its 1.5

20:43 1.5.1 to be correct

20:43 AWizzArd: Tho 47s is still a bit high, no?

20:43 tolstoy: Oh, hm.

20:43 mwelt: and leiningen version 2.3.4

20:44 AWizzArd: its the same time even 2-3 times in a row ...

20:44 this is a reald dealbreaker for me, but i hoped it did something wrong

20:44 its running on jdk 8_5

20:44 AWizzArd: mwelt: I am using Java 8 too. But why is that a dealbreaker?

20:45 mwelt: AWizzArd: i am not willing to wait nearly one minute to execute a bunch of simple code. I wanted to build up a project on clojure...love the language thou...but 1 minute to run a simple test? no way

20:46 Bronsa: 47s is insanely slow, lein run on a new project takes 3.5s here

20:46 mwelt: Bronsa: so maybe my setup ist corrupted

20:46 AWizzArd: mwelt: typically the idea is that in the morning you run „lein repl” and develop your program. There should be very few startups per day.

20:46 tolstoy: I just did a "lein new app someapp" and "time lein run" and got:

20:47 real 0m2.453s

20:47 user 0m3.579s

20:47 sys 0m0.241s

20:47 mwelt: tolstoy: this would be great :)

20:47 tolstoy: java version "1.8.0_05"

20:47 Nice fast iMac, though.

20:49 mwelt: Not sure if it'll be of any use, but "DEBUG=1 lein run".

20:49 mwelt: ill try

20:50 justin_smith: mwelt: also, you can do (clojure.test/run-tests) as many times as you like in a repl (after reloading changed namespaces of course)

20:50 tolstoy: If you have any deps defined, but they can't be pulled down for some network issue, I wonder if that would make a diff?

20:50 AWizzArd: While a startup time of one minute would be bothersome I still don’t see why it should be a tragic problem in practice in most cases.

20:51 justin_smith: it can also be caused by large numbers of deps

20:51 AWizzArd: justin_smith: how often do you call „lein run”?

20:52 justin_smith: less than once a week per project usually

20:52 with long lived repls, and reloading files as apropriate

20:52 AWizzArd: Compared to me you are a high-profile user of lein run then (:

20:52 justin_smith: heh

20:53 but mind you, I start my repl with lein run

20:53 tolstoy: When people are just learning, typing code then running "lean run" is the lowest barrier.

20:53 justin_smith: so that my repl is also the back door into a long running server process

20:53 AWizzArd: tolstoy: I accept this point.

20:53 tolstoy: Going "full repl" is a bit later in the game, no?

20:53 justin_smith: tolstoy: easier than lein repl really?

20:53 tolstoy: with my first lisp, the repl was a revelation and made everything in programming make so much more sense

20:54 I guess some others have different experiences

20:54 tolstoy: justin_smith: not ultimately, but when I first learned Common Lisp, repl + emacs + the language: I focussed on the language first.

20:54 justin_smith: hah, I started with the repl inside xterm

20:55 then later started entering stuff directly into files

20:55 tolstoy: Me, too, kind of. But there was no way to hook up files to the repl, until Emacs. But (for me) that was a WHOLE new thing.

20:55 mwelt: i also started with repl only

20:56 zaiste: is it possible to dynamically destruct a map ? i.e. https://gist.github.com/zaiste/19f9c4c0cb84bd9e8819

20:56 tolstoy: I had to learn the difference between the language errors, editor problems, etc, etc. ;)

20:56 mwelt: tried to fix some 4clojures

20:56 and this brought the language to me

20:56 but now i want to build up a litte project

20:56 AWizzArd: mwelt: when the repl is up you can start doing Clojure for several hours. The time spent with startups would even take with your 47s scenario just 3-4 minutes a day.

20:56 mwelt: what project you wanna build? (:

20:57 justin_smith: zaiste: looks like you want :keys

20:57 mwelt: how can i execute my written code with all dependency and stuff in REPL?

20:57 justin_smith: ,(let [{:keys [a b c d]} {:a 0 :b 2 :c 4 :d 8}] d)

20:57 clojurebot: 8

20:57 zaiste: justin_smith: yes, perfect, thank you

20:57 justin_smith: mwelt: (require '[your.ns :as alias] :reload)

20:58 mwelt: its something 4 my plessure language related data mining stuff on a huge amount of textdata

20:58 justin_smith: sometimes you may also want to do (in-ns 'your.ns)

20:58 AWizzArd: ,(let [{:keys [amount name x] :strs [foo] :or {x 33}} {:amount 14, "foo" 88, :name "Carlos"}] [amount name x foo])

20:58 clojurebot: [14 "Carlos" 33 88]

20:58 justin_smith: AWizzArd: nice

20:59 mwelt: there is also :reload-all to recursively reload the requires of an ns

21:00 mwelt: justin_smith: and this is always project related?

21:01 justin_smith: mwelt: well it uses your classpath, which lein sets up based on your project.clj

21:01 but you can hypothetically extend your classpath at runtime and fudge things, if that matters to you

21:02 with alembic you don't even need a restart to use new deps from clojars or maven central

21:02 mwelt: justin_smith: seems cool to me, but why does lein need 47s to startup this seems odd

21:03 justin_smith: mwelt: clojure does a lot of work at load time - it has no tree shaking and very little lazy loading (if any?) in core

21:03 this is not just a lein issue

21:03 zaiste: justin_smith: is it also possible to generate vec for :keys automatically, from symbols ? 3rd snippet: https://gist.github.com/zaiste/19f9c4c0cb84bd9e8819

21:03 arrdem: justin_smith: loading is lazy, but there is no tree shaking at all.

21:03 tolstoy: mwelt: Unless your computer is really underpowered, that IS odd.

21:04 * nDuff wonders what hardware mwelt is running

21:04 arrdem: for lazy defined at the level of namespaces

21:04 justin_smith: arrdem: oh, good to know, thanks

21:04 nDuff: mwelt, ...I'd expect that kind of timing if, say, lein were downloading a library that wasn't in your local Maven cache.

21:04 arrdem: nDuff: or if you're running on a free ec2 instance

21:05 mwelt: tolstoy: got i7 with 16GB ram and ssd

21:05 seems fine to me

21:05 tolstoy: Yep. Something's odd. ;)

21:05 justin_smith: zaiste: I am confused about the use case there - you wouldn't know until runtime what symbols are bound in the let, so you would not be able to effectively write code using those symbols

21:06 tolstoy: mwelt: Still 47secs when you "lein run" a brand new project with no deps you've added yourself?

21:06 mwelt: Surely "java -version" doesn't take a long time, right?

21:06 mwelt: tolstoy: mom

21:07 java -version :

21:07 real 0m0.067s

21:07 user 0m0.052s

21:07 sys 0m0.007s

21:08 tolstoy: mwelt: The folks on #leiningen woke up.

21:08 AWizzArd: mwelt: it might be worthwhile to start up a jvm with clojure.jar on the CP.

21:08 * nDuff is still curious about the empty-project lein run timing.

21:09 justin_smith: mwelt: what are the deps in the project that takes that long anyway?

21:09 mwelt: no

21:09 justin_smith: no deps just plain ne genrated projekt

21:10 time lein run

21:10 Hello, World!

21:10 real 0m24.313s

21:10 user 0m4.367s

21:10 sys 0m0.289s

21:10 AWizzArd: justin_smith: how are your timings for “java -server -version”?

21:11 zaiste: justin_smith: you're right, i've overcomplicated, thanks

21:11 justin_smith: 0.076

21:14 mwelt: time java -server -version

21:14 java version "1.8.0_05"

21:14 Java(TM) SE Runtime Environment (build 1.8.0_05-b13)

21:14 Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

21:14 real 0m0.064s

21:14 user 0m0.046s

21:14 sys 0m0.019s

21:14 AWizzArd: mwelt: but try this with java -server -cp clojure.jar

21:15 mwelt: k

21:16 where does leiningen store clojure.jar?

21:16 AWizzArd: java -server -cp clojure-1.6.0.jar clojure.main -e "(println 55)"

21:22 tolstoy: mwelt: ~/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar

21:22 arrdem: does lein's eval-in-project return the eval result as one would expect?

21:24 it doesn't appear to T_T

21:24 tolstoy: For me, AWizzArd's suggestion ran in .7s.

21:24 AWizzArd: tolstoy: that seems pretty okay

21:25 tolstoy: Yep.

21:27 AWizzArd: mwelt: another test for you and tolstoy could be: just type “lein help” and time that.

21:27 On my not-so-fast system it’s around 8s.

21:27 mwelt: 3 s

21:28 AWizzArd: lein help actually must load a jvm

21:28 tolstoy: I *thought* my system was fast, I get around 8s too.

21:28 mwelt: the plain java run without leinen is also under 3s

21:29 AWizzArd: So, it seems Leiningen can start up fast enough with its own code & Clojure.

21:29 tolstoy: I've got stuff in my .lein/profiles.clj, too.

21:30 Yeah, lein is fast enough for me with the empty project. I was just hoping to establish that mwelt is experiencing a fluke compared to the average.

21:30 lein deps :tree might be interesting.

21:31 (I have nrepl snapshot, for instance.)

21:31 faster: lein with-profile production deps :tree

21:33 amalloy: `lein help` is a bad thing to time, because it loads all plugins

21:33 mwelt: tolstoy: the problem was the fileshare

21:33 tolstoy: Woo hoo! ;)

21:33 mwelt: tolstoy: i ran the program in sshfs

21:33 tolstoy: without it its under 2s

21:33 tolstoy: Glad you found it. Phew!

21:33 mwelt: tolstoy: ^^

21:34 justin_smith: oh wow, yeah, I guess that would affect things

21:34 AWizzArd: those 47s were indeed a bit too suspicious, even for some slower system.

21:34 justin_smith: I guess I have used / developed to many bloated mega-apps for 47 seconds to seem that big a deal :(

21:34 tolstoy: Yeah. Now, add cljsbuild to your hooks, and we're back into the 1 minute start territory. ;)

21:35 mwelt: tolstoy: well ... no :) but thanks a lot for helping

21:35 tolstoy: Heh.

21:36 mwelt: and yea shame on me for not believing in slow network issues

21:37 what is cljsbuild?

21:38 tolstoy: It's a plugin for compiling (and cleaning) clojurescript clients.

21:38 When you add it to the hooks key in your project, it'll participate in the normal "run" "jar" and "clean" tasks.

21:39 justin_smith: yeah, clojurescript currently builds kind of slow

21:39 tolstoy: At least the incremental build it fast, but, yeah.

21:39 justin_smith: yeah, auto can be OK

21:50 amalloy: man, i remember when i tried to run lein over sshfs. what a terrible idea

21:50 arrdem: amalloy: I tried that once... the .class files made my wifi cry

21:53 mwelt: amalloy: it was not a good idea

21:55 arrdem: RFC on https://github.com/arrdem/radagast/blob/54844b2d3939d77dba3fd1c36c99829b803ad206/src/leiningen/radagast.clj, I kinda feel like failing test cases should also be a reason for a nonzero return code in addition to incomplete test coverage.

22:29 allenj12: hey, what is the most recommended full stack framework?

22:29 justin_smith: ,nil

22:29 clojurebot: nil

22:30 tolstoy: allenj12: Most Clojure devs and tinkerers compose small frameworks. Since Clojure is not OO, there's no ORM, for instance.

22:31 But I think there are fullstack things out there.

22:31 justin_smith: allenj12: I have worked on one that people who are familiar with django or rails may find familiar in its usage (caribou), but what tolstoy said

22:31 tolstoy: Yeah, caribou. I was trying to remember what that was. ;)

22:32 allenj12: hmm alright im new to web dev completely just not sure where to start :p

22:32 justin_smith: caribou tries to do mvc / orm with clojure maps, kind of. it is overengineered in places, and clunky in places, but has a lot of stuff out of the box

22:33 tolstoy: allenj12: I'd find an interesting Compojure tutorial somewhere.

22:33 allenj12: hmm alright sounds good

22:34 tolstoy: compojure is a routing lib, like sinatra in ruby, so you can get an app running and use CURL to try it out. Then use a JSON lib to convert clojure maps to json, try that out, etc.

22:35 Put your html, js and css in /resources/public, try that. Hook up mongo or sql or something....

22:36 At that point, you'll have something to swap out parts, or at least a general idea of what's good or bad. IMHO. ;)

22:36 allenj12: haha alright

22:37 tolstoy: Where I work (conservative Java shop), someone demo'd a compojure app that read in a SQL file from disk and executed the query, returning the results as json.

22:38 People were amazed at how little code made that work.

22:38 Oh, and you might look up the "lein ring" plugin.

22:40 allenj12: ring? got it. ill do that

22:42 tolstoy: This: https://github.com/weavejester/lein-ring

22:42 And this: https://github.com/weavejester/compojure/wiki/Getting-Started

22:46 dbasch: this is kinda nice http://jafingerhut.github.io/cheatsheet-clj-1.3/cheatsheet-tiptip-cdocs-summary.html

22:48 tolstoy: Nice. Hover gives the doc string.

22:49 allenj12: hmm ok so im looking more at this stuff. Just wanna make sure tho, is it worth building a website in clojure? i assumed it would be best because its pretty much all i have been programming in for a while, but is there something else i should be using?

22:50 benkay: for a 'web site' you might consider flat files on disk and a web server like nginx or apache over clojure

22:50 if it needs to be interactive, clojure webapps are pretty fun imho

22:50 dbasch: allenj12: if you mean a web application, yes

22:50 justin_smith: allenj12: for dynamic content, yeah, clojure is pretty kickass

22:50 allenj12: maybe i should be more specific

22:51 justin_smith: also if you need to integrate with other web APIs etc.

22:51 clojure makes that stuff very straightforward (thanks to the amount of similarity in edn and json in part)

22:51 tolstoy: Using clojure to generate a static site is fun, too.

22:52 justin_smith: tolstoy: but maybe not the most practical way to do it

22:52 allenj12: so i am making a gaming platform, i need a website that can make users where they can buy credit etc. i also need my platform to access that information (its going to be a downloadable client).

22:52 tolstoy: you mean maybe awk and sed are praps even better?

22:53 allenj12: does that change anything?

22:53 justin_smith: allenj12: you should definitely check out friend, and clojure.java.jdbc

22:53 that's totally doable in clojure

22:55 allenj12: hmm ok i am most comfortable in clojure so thats good. and its as practical as other options?

22:55 arrdem: for other options defined to be the usual suspects of PHP, nod_js# and dogescript, sure.

22:56 justin_smith: what was that doge json knockoff you linked?

22:56 http://dogeon.org/ gotcha

22:56 justin_smith: allenj12: practical can mean dev time or cpu time - it's better performing than most mainstream web dev options, and pretty close to the rest, and in terms of dev time it can be very straightforward

22:57 arrdem: speaking of practical, huh :)

22:57 allenj12: ok great thats what i wanted to hear :)

22:57 arrdem: justin_smith: sssssh nobody needs to know that my databases are really just flat dogeon files

22:57 allenj12: is there a specific host i should be looking at when i decide to look for one?

22:58 justin_smith: arrdem: wow, such table, much data, many plaintext passwords

22:58 arrdem: allenj12: anything that'll let you run a JVM with arbitrary jars...

22:58 allenj12: digitalocian and ec2 get some love around here.

22:58 dbasch: allenj12: I heard Heroku is putting effort into making clojure easy to deploy

22:58 justin_smith: allenj12: well the nice thing is that you can just use httpkit and make an uberjar, so any host that has java, which is pretty much any host worth using

22:58 arrdem: dbasch: yeah but heroku's prices are insane for a nonfree instance of both a database and a server...

22:59 dbasch: you pay a ton for their tooling

22:59 justin_smith: well really they should support nginx and varnish too, but that is also not hard to find

22:59 dbasch: arrdem: of course

22:59 allenj12: yea i heard both af digital ocean and heroku lately when asking around

22:59 benkay: does anyone know how to return a value from deftest? i'd like to compose the output of some kerodon testing from a threaded macro with another test.

22:59 allenj12: both seemed most recommended

22:59 benkay: if your budget's constrained, ipxcore's nice

23:00 dbasch: arrdem: I use ec2 directly, but also used Heroku quite a bit for one-off ruby/rack apps years ago

23:00 benkay: if not terribly performant on the vps side of things.

23:00 allenj12: heroku seems expensive for now tho... since i need to play around with things like that :)

23:00 benkay: if you have a budget, servers from aws is the way to go.

23:00 arrdem: dbasch: I did my first real clojure blog on heroku. their deployment system was nice, but then I realized what their pricing was like.

23:01 justin_smith: speaking of deployment, also one of the wins with clojure compared with other backend web server options is you can get more throughput while spending less on hardware

23:01 allenj12: hmm alright cool. btw is is there a lein template recommeded for this kinda stuff?

23:02 dbasch: allenj12: the default compojure template is an ok start

23:02 arrdem: allenj12: there is a lein template for a new ring app, but in general lein templates are few and far between.

23:02 justin_smith: the compojure one should be a nice start (though I recommend looking into one of the non-macro-based routers too, being able to make routes from data at runtime is nice)

23:03 arrdem: allenj12: if you see anything about noir, steer clear of it 'cause it's deprecated.

23:03 allenj12: hmm gotcha, o really? i atcually just did, thanks for the heads up

23:03 arrdem: allenj12: lib-noir is OK tho.

23:03 justin_smith: there is also (from the project I work on) lein new caribou, which is kind of everything you need and 5 times as many things you don't need, but hell it comes with a semi-usable web cms UI out of the box

23:04 and a db backend with "data models" all set up and ready to use from the cms

23:04 arrdem: allenj12: yeah ibdknox did a reasonable job of making all the ring stuff nice to use, but the result wasn't very flexible and he wound up abaindoning it. that happened about 3mo after I finished my noir backed blog :P

23:05 allenj12: lol :)

23:05 * arrdem now runs a jekyll based static HTML site via nginx

23:07 allenj12: o i guess i should also ask although it might sound really dumb. when does cljs come into the picture

23:07 ?

23:08 justin_smith: when you want to make client side js code in clojure

23:08 allenj12: gotcha

23:08 justin_smith: you compile the cljs to js, and send that in a page

23:08 useful for single page app kind of stuff

23:10 benkay: does anyone know how to return a value from deftest?

23:10 from a deftest macro

23:10 arrdem: why would you do such a thing?

23:11 benkay: composing a kerodon test, would like to preserve a session across composed tests.

23:11 unless...crazy/stupid.

23:11 in which case, what's a really awesome way to test a webapp's session functionality and then compose those tests?

23:12 arrdem: you can write tests that require other tests pass, I think the "right way" to do this is just to structure your test such that the test of the composition requires individual tests and then tests the compise.

23:12 *tests the compose of the individual elements.

23:12 justin_smith: you can use a fixture that runs once around all tests

23:12 that sets up your session

23:13 benkay: hm write the to-be-composed stuff in regular functions and then call them composedly from inside deftest macros?

23:13 justin_smith: also remember that you can call is in functions outside a deftest, and then call said functions in multiple deftests

23:13 right

23:13 benkay: man lisp is cool

23:14 justin_smith: indeed, I do love it as well

23:14 (inc clojure)

23:14 lazybot: ⇒ 16

23:14 justin_smith: haha

23:14 (inc juxt)

23:14 lazybot: ⇒ 10

23:14 benkay: anyways, thanks y'all.

23:14 allenj12: is envlive useful?

23:15 benkay: rather, allenj12

23:15 justin_smith: yeah, enlive is great for being able to treat html content in a functional way

23:17 allenj12: ok cool

Logging service provided by n01se.net