2014-06-07
| 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:21 | Frozenlock | Is there a :subdomain field in compojure? |
| 14:21 | Frozenlock | ...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 | augustl | 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 | augustl | 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 | augustl | justin_smith: ah, of course :) |
| 14:43 | augustl | 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 | justin_smith | they are not a locking construct |
| 14:44 | justin_smith | (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 | justin_smith | but then it is up to you to ensure there are no deadlocks, livelocks, etc. |
| 14:45 | justin_smith | 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 | augustl | 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 | justin_smith | 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 | Bronsa | 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 | augustl | 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 | augustl | sounds like a lot of extra threads though |
| 14:48 | augustl | 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 | justin_smith | *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 | augustl | 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 | justin_smith | very narrow and easy to control surface of interaction |
| 14:51 | augustl | yeah this sounds very pleasant :) |
| 14:51 | augustl | 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 | justin_smith | well you decide how many threads are dispatched from the requests in the queue |
| 14:53 | justin_smith | 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 | justin_smith | will still using the shared pool |
| 14:53 | justin_smith | *while |
| 14:55 | augustl | making it a TODO for now, looking forward to implementing this |
| 14:56 | augustl | 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 | augustl | 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 | justin_smith | 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 | justin_smith | instead of a request ID you can pass the open socket to the client |
| 15:03 | justin_smith | *the open socket the client is connected to* I mean |
| 15:04 | augustl | ah, that makes sense yeah |
| 15:04 | augustl | 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 | justin_smith | 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 | tolstoy | 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 | pdk | 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 | pdk | looks like a recognizable abbreviation is okj |
| 16:01 | Frozenlock | Copyright Frozenlock 2014 |
| 16:05 | Frozenlock | 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 | Frozenlock | *prove |
| 16:06 | Frozenlock | 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 | arrdem | Frozenlock: most of my stuff is (c) Reid "arrdem" McKenzie |
| 16:18 | arrdem | 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 | roppongininja | 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 | Frozenlock | 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 | arrdem | 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 | Bronsa | and should Just Work™ |
| 16:23 | yeoj___ | but hey it's saturday. thats what saturday is for. |
| 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 | yeoj___ | then i'll get back to work |
| 16:33 | yeoj___ | 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 | yeoj___ | 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 | Frozenlock | (and they send to SSL stuff to the domain email) |
| 16:53 | Frozenlock | *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 | Jaood | the little schemer pdf |
| 17:43 | bbloom | Jaood: is it? |
| 17:43 | bbloom | it was 2nd link on google |
| 17:43 | bbloom | *shrug* |
| 17:43 | JokerDoomWork | Eh, I'm ok on the Paul Graham, I try to steer clear of demagogues |
| 17:44 | JokerDoomWork | 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 | Glenjamin | this intrigues me |
| 17:46 | Glenjamin | as i'm generally of the opinion that top-down gives better results |
| 17:47 | Glenjamin | i may have to buy this |
| 17:47 | Glenjamin | 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 | bbloom | there's no correct answer, you need to do a little bit of both |
| 17:57 | bbloom | 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 | Hodapp | Claiming that it is a dichotomy and therefore that the right answer must lie in the middle |
| 18:03 | Hodapp | ...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 | Hodapp | 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 | justin_smith | 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 | justin_smith | next, start implementing the stuff that makes that code valid. |
| 18:15 | justin_smith | 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 | JokerDoomWork | tdd? |
| 18:18 | JokerDoomWork | oh test driven development |
| 18:31 | Glenjamin | Interesting, I think I'll have to read this now |
| 18:32 | Glenjamin | "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 | justin_smith | "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 | Glenjamin | 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 | Glenjamin | 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 | kenrestivo | :-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 | platz | and then having all your building blocks putting them in the final flow is the last step |
| 18:44 | platz | 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 | justin_smith | *thing I was using |
| 19:36 | JokerDoomWork | so reflection in Clojure, do I need to use the normal java facilities? |
| 19:36 | JokerDoomWork | 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 | justin_smith | and there are some other, easier to use libs too |
| 19:52 | justin_smith | sometimes it suffices to just use bean to find what I want |
| 19:52 | justin_smith | ,(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 | justin_smith | 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 | pandeiro | sure i guess that is what i thought of wrapping in a script |
| 20:36 | pandeiro | then the complexity came in with not knowing which arg would be the project name |
| 20:36 | pandeiro | `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 | justin_smith | 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 | mwelt | 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 | mwelt | 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 | mwelt | AWizzArd: its the same time even 2-3 times in a row ... |
| 20:44 | mwelt | this is a reald dealbreaker for me, but i hoped it did something wrong |
| 20:44 | mwelt | 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 | tolstoy | real 0m2.453s |
| 20:47 | tolstoy | user 0m3.579s |
| 20:47 | tolstoy | sys 0m0.241s |
| 20:47 | mwelt | tolstoy: this would be great :) |
| 20:47 | tolstoy | java version "1.8.0_05" |
| 20:47 | tolstoy | Nice fast iMac, though. |
| 20:49 | tolstoy | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | tolstoy: with my first lisp, the repl was a revelation and made everything in programming make so much more sense |
| 20:54 | justin_smith | 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 | justin_smith | 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 | mwelt | and this brought the language to me |
| 20:56 | mwelt | 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 | AWizzArd | 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 | justin_smith | 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 | justin_smith | but you can hypothetically extend your classpath at runtime and fudge things, if that matters to you |
| 21:02 | justin_smith | 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 | justin_smith | 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 | 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 | mwelt | 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 | tolstoy | mwelt: Surely "java -version" doesn't take a long time, right? |
| 21:06 | mwelt | tolstoy: mom |
| 21:07 | mwelt | java -version : |
| 21:07 | mwelt | real 0m0.067s |
| 21:07 | mwelt | user 0m0.052s |
| 21:07 | mwelt | 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:09 | justin_smith | mwelt: what are the deps in the project that takes that long anyway? |
| 21:09 | mwelt | no |
| 21:09 | mwelt | justin_smith: no deps just plain ne genrated projekt |
| 21:10 | mwelt | time lein run |
| 21:10 | mwelt | Hello, World! |
| 21:10 | mwelt | real 0m24.313s |
| 21:10 | mwelt | user 0m4.367s |
| 21:10 | mwelt | 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 | mwelt | java version "1.8.0_05" |
| 21:14 | mwelt | Java(TM) SE Runtime Environment (build 1.8.0_05-b13) |
| 21:14 | mwelt | Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode) |
| 21:14 | mwelt | real 0m0.064s |
| 21:14 | mwelt | user 0m0.046s |
| 21:14 | mwelt | sys 0m0.019s |
| 21:14 | AWizzArd | mwelt: but try this with java -server -cp clojure.jar |
| 21:15 | mwelt | k |
| 21:16 | mwelt | 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 | arrdem | 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 | AWizzArd | 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 | tolstoy | 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 | tolstoy | lein deps :tree might be interesting. |
| 21:31 | tolstoy | (I have nrepl snapshot, for instance.) |
| 21:31 | tolstoy | 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 | mwelt | 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 | mwelt | what is cljsbuild? |
| 21:38 | tolstoy | It's a plugin for compiling (and cleaning) clojurescript clients. |
| 21:38 | tolstoy | 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 | tolstoy | 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 | tolstoy | Put your html, js and css in /resources/public, try that. Hook up mongo or sql or something.... |
| 22:36 | tolstoy | 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 | tolstoy | People were amazed at how little code made that work. |
| 22:38 | tolstoy | 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 | tolstoy | 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 | benkay | 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 | justin_smith | 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 | justin_smith | 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 | arrdem | justin_smith: what was that doge json knockoff you linked? |
| 22:56 | arrdem | 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 | justin_smith | 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 | arrdem | 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 | arrdem | 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 | justin_smith | 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:07 | allenj12 | o i guess i should also ask although it might sound really dumb. when does cljs come into the picture |
| 23:07 | allenj12 | ? |
| 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 | justin_smith | useful for single page app kind of stuff |
| 23:10 | benkay | does anyone know how to return a value from deftest? |
| 23:10 | benkay | 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 | benkay | unless...crazy/stupid. |
| 23:11 | benkay | 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 | arrdem | *tests the compose of the individual elements. |
| 23:12 | justin_smith | you can use a fixture that runs once around all tests |
| 23:12 | justin_smith | 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 | justin_smith | right |
| 23:13 | benkay | man lisp is cool |
| 23:14 | justin_smith | indeed, I do love it as well |
| 23:14 | justin_smith | (inc clojure) |
| 23:14 | lazybot | ⇒ 16 |
| 23:14 | justin_smith | haha |
| 23:14 | justin_smith | (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 |