#clojure logs

2012-12-20

00:06mehworkapt-get install clojure installed 1.1, but i want clojure 1.4. what's the best way to get it? can i just add 1.4 to my leiningen's :dependencies?
00:08tpopeyes
00:08tpopedon't bother with apt for anything other than maybe java itself
00:08RaynesNever use a package manager for anything Clojure related besides Java.
00:08RaynesYou'll wake up naked and covered in blood.
00:09mehworkthanks
00:10RaynesLeiningen is totally independant of anything else. It downloads Clojure versions as necessary and manages all the pain for you to keep you waking up clothed, or at least clean with no blood.
00:10mehworkit's insane not having basic string splitting functions and stuff in 1.1
00:10RaynesThere is stuff like that in Java itself that you used in 1.1
00:10RaynesBut yeah, 1.1 is way too old.
00:10RaynesYou definitely don't want that.
00:10mehworki wanna stay as far away from java as possible
00:11RaynesThen you might be using the wrong languag.
00:11Rayneslanguage*
00:11mehworkprobably
00:11RaynesEverything calls out to Java somewhere. There are a lot of Clojure libraries around, but there are lots of Java libraries too, and chances are you'll find yourself wanting one eventually.
00:12mehworkthen i'll jus wrap them
00:12RaynesThought you wanted to stay away from Java? ;)
00:12mehworkas much as possible
00:13RaynesWords, words.
00:51bbloomwhen viewed with the experience of values and identities, the browser dom is completely fucking hopeless
01:13tomojit's hopeless because if you build something decent on top of it, it will be too slow?
01:13tomojor because you just can't build anything decent on top of it
01:13bbloomtomoj: both. heh
01:14bbloomi'm tempted to just write my own complete gui toolkit on canvas
01:14bbloomapparently even mozilla is toying with that idea: https://wiki.mozilla.org/Labs/Thunderhead
01:16RaynesObviously stealing your idea.
01:16RaynesAlso, my word. They need to quit with the names.
01:16RaynesWhat's next? ElectricStormParakeet
01:17brainproxyis the datomic crew more or less moving away from the ".dtm" filename extension convention in favor of ".edn"?
01:18tomojwhy is using canvas underneath much easier?
01:19bbloomtomoj: the main problem is one of shit changing under you
01:19bbloomthere are basically two approaches: play the DOM game with css/html/javascript, or own everything
01:20bbloomangular.js plays the DOM game
01:20bbloomcappichino or GWT owns everything
01:20bbloomin the own everything view, you can assume the dom only changes in controlled ways
01:20bbloombut it makes it hard for you to safely employ css, etc
01:20bbloomor custom event handlers
01:20bbloomor dom inspection
01:20bbloomif somebody changes some shit in the web inspector, you're fragile little view of the world may break
01:21bbloomif you wanted to have an immutible snapshot of the DOM state, you simply can't get it. because even simple things like event handlers aren't queryable from any dom API
01:21bbloomthere is no way to say getAllEventHandlers
01:22bbloomthe advantage of owning everything is that you can do more powerful stuff, like dynamic layouts. you just absolutely position everything via javascript
01:23tomojjquery's deep clone only copies event handlers which were added by jquery, I assume
01:23bbloombut then at that point, you're just using the dom as a finely optimized rectangle renderer with some native widgets for text input. and you'll want to skin everything for a professional app anyway, so you might as well skip the rectangle renderer and render arbitrary lines and shit :-P
01:23bbloomcorrect
01:24bbloomalso, i used to do game dev, sooo i part of me wants to say fuck it and go off and implement a compositor
01:24bbloomthat would be easier than dealing with the fucking dom :-P
01:25bbloomRaynes: are you seriously going to go implement this?
01:26ro_stimplement what?
01:26bbloomcanvas gui toolkit w/ clojurescript :-)
01:26ro_stfrom scratch?
01:27bbloom*shrug*
01:27ro_stambitious.
01:28ro_stwhen it comes to rendering, you want short stacks for performance. clojurescript doesn't make for short stacks
01:28bbloom"short stacks" ?
01:28ro_stcall stacks
01:28ro_ststack as in stack overflow
01:29bbloomyeah, but i'm not sure what you're getting at.... call overhead? since when does the height of the stack matter for performance?
01:29ro_stalthough, i've never done anything with canvas, so i could be totally wrong.
01:30Raynesbbloom: Am I going to what what?
01:30ro_stthe less stuff that happens in hot loops, the faster they go. if your logic has to work through the cljs abstractions to get at the 'raw' js in that loop, that means you're losing some performance
01:30bbloomRaynes: I said canvas gui, you said "Obviously stealing your idea."
01:30ro_stfor the same reason games use c/c++ for their 3d engines instead of lua
01:31Raynesbbloom: No sir, I was implying Mozilla stole your idea.
01:31bbloomah, heh
01:31RaynesI wouldn't touch that with a 10 foot career.
01:31bbloomhaha
01:31ro_st-grin-
01:47mehworkis there a diff between (defn- main) and (defn -main) ?
01:48tomojthe former defines a private function called 'main, the latter a public function called '-main
01:49mehworki take it it's a bad idea to do (defn- -main)
01:50ro_stonly if you want to be able to call main from outside the ns
01:55tomojevent handlers seem problematic (in the don't-own-everything approach), but I don't feel like I want an immutable snapshot of the dom which includes event handlers
01:57bbloomtomoj: i'm not actually going to build a canvas gui :-P just venting a bit. i'm still exploring the design space, so i'm not exactly sure how to deal with it
01:58bbloomi think the preferable approach is closer to angular.js
01:58bbloombut i want to embrace clojure's data view of the world
01:59bbloomcurrently, i have a prototype working that has a data structure, recursively expands templates and "styles", much like macro expansion, and the expanded form can be rendered to a dom
01:59bbloomclearly rebuilding the entire dom on every update is inefficient
01:59bbloomso i'm searching for a way to intelligently apply the delta to the dom
02:01bbloomit seems the only valid strategy is to assume no one is going to open the web inspector and muck with your elements. and you just pray that no extension is corrupting the dom in any serious fashion
02:02ro_stnot a valid assumption to make at all. lastpass does stuff to the dom, for example
02:02ro_stboth when rendering its noticebar and when populating fields with data
02:02bbloomhence the "serious fashion" qualifier
02:02bbloomit's one thing to add a top level div
02:02bbloomit's another thing to insert random elements and modify random properties scattered throughout the page
02:03ro_sttrue
02:03bbloomand when populating fields with data, a well behaved plugin would most likely trigger a value-change event
02:03bbloomwhich would be more or less indistinguishable from the user typing in that field
02:05mehworkis it wrong to put -main in core.clj? core.clj has (ns foo.core) and my project.clj has :main foo.core but when i lein run -m src/foo/core.clj i get an error
02:05mehworkit seems to work fie if i put the -main function in a diff file and set :main to that though
02:07ro_stand if you just lein run?
02:07ro_stno -m path
02:07tomoj(btw it's -m ns, not -m path: `lein run -m foo.core`)
02:08tomojbbloom: the thing you're describing is one-way only, right? data->dom?
02:08bbloomtomoj: i have one-way working with complete-re-render
02:09bbloomtomoj: my goal is full two-way
02:09bbloomtomoj: with efficient incremental updates
02:09bbloommy little template/styles macro expanding jazz is actually quite simple and pleasant to work with
02:09bbloomit's roughly analogous to microsoft's WPF logical and visual trees
02:09bbloombasically, i have some "logical tree" which is "template expanded" into a visual tree
02:10bbloomand the visual tree is roughly a static snapshot of the target dom
02:10bbloomso i just hiccup-ize it right now for proof of concept
02:10bbloomworks nicely
02:11mehworktomoj: hmm thanks. lein run by itself worked but lein run -m foo.core still errors
02:12tomojso ideally, in the data->dom case, web inspector tweaks would just be immediately undone? or a bit less ideally, next time the data changes?
02:14bbloomtomoj: i'm not super worried about web inspector tweaks, i just mention them as an annoyance
02:15bbloomtomoj: in theory, they'll immediately be overwritten by a re-render for that subtree
02:15tomojguess it's irrelevant since we want two-way. I don't understand what two-way would look like
02:16bbloomso angular works by having "directives" for each bindable thing
02:16bbloomfor example, ng-checked http://docs.angularjs.org/api/ng.directive:ngChecked
02:16bbloomi'm thinking that i'll do something similar
02:17bbloomsomething like {:tag "color" :attr/title "you see this on hover" :css/color "red" :bind/click xyz}
02:18bbloomer tag shoulda been "div"
02:18bbloombrain fart
02:20tomojso the model is an identity and dom changes and bound to mutate it
02:20bbloomsomething like that
02:21bbloommy goal is an order of magnitude productivity win over everything else out there :-)
02:21bbloomit's a hobby project though... if i had to do real work starting tomorrow, i'd just suck it up and use angular + coffeescript :-P
02:34tomojso you need one function to update a model given input from the dom, and one to update the dom given the model. and a binding is both functions?@
02:39alex_baranoskywhat's the current status of the Korma project? A quick look on clojars shows more than ten non-official Korma jars there
03:02mehworkis it bad to def a var, then on the next line def it again by apply'ing something to it? Effectively creating and manipulating the same state?
03:02mehworkor what is the convention
03:03ro_stnot bad. you might want to (def foo (let [foo (something)] <alter foo>))
03:04ro_stthe let binding replaces your first def
03:04mehworki see, thanks
03:07mehworkwhere can i read about <alter>?
03:07ro_stthat's just me saying "do something with foo"
03:07ro_st<alter> isn't actual clojure syntax
03:07mehworkoh :p
03:07ro_stsorry for the red herring :-)
03:07mehworkit's okay. I'm relieved
03:08ro_st(def foo (let [a 1] (inc a))) ; foo is 2
03:10alex_baranoskymehwork: imo that is bad form. something you only do if you absolutely must
03:11alex_baranoskymehwork: if you have mutable state why not use an atom or ref for it?
03:11alex_baranoskymehwork: do you really need this mutable state? <-- that's the real question. Usually the answer is "no".
03:12mehworkidk, i'm still a complete noob
03:15ro_stbaby steps.
03:15ebaxtI'm having a "there
03:15ebaxtI'm having a "there's a function for that" moment, anyone? https://www.refheap.com/paste/7744
03:17ro_stebaxt: looks like group-by might help
03:18ebaxtro_st: I don't want a vector for each key since I know they are unique
03:35amalloy(into {} (for [x coll] [(:foo x) x]))?
03:35amalloy(into {} (map (juxt :foo identity) coll))
03:36amalloyebaxt: ^
03:37tomojmy port of clojure.test to clojurescript seems to be basically working
03:38mehworkhow do you convert all integer key values to strings in a map? eg {1:"foo", 2:"bar"} becomes {"1":"foo", "2":"bar"}?
03:38mehworkdo i need to use doseq
03:39tomoj(into {} (for [[k v] m] [(str k) v]))
03:39ro_st(into) is a great bit of kit
03:39tomojI wish it were (into-kv {} (map-k str m)), but it's not
03:41mehworkor is there an option to do it during map-indexed hash-map seqname
03:41mehworkit would be nice if map-indexed took a callback to filter through first
03:43tomojwait, what? you're doing something like ##(map-indexed {1 :foo 2 :bar} [:baz :bing :bang :bong]) ?
03:43lazybot⇒ (:baz :foo :bar :bong)
03:44amalloyhah. i never thought of using a map as the map-indexed function
03:44mehworkinteresting
03:45tomojor, or ##(map-indexed hash-map [:foo :bar :baz])
03:45lazybot⇒ ({0 :foo} {1 :bar} {2 :baz})
03:45ebaxtamalloy: Thx, shorter at least ;)
03:45tomojfor the latter, ##(map-indexed #(hash-map (str %1) %2) [:foo :bar :baz]) :/
03:45lazybot⇒ ({"0" :foo} {"1" :bar} {"2" :baz})
03:46noidi,(zipmap (range) [:foo :bar :baz])
03:46clojurebot{2 :baz, 1 :bar, 0 :foo}
03:46noidiah, that's not what you were doing
03:47mehworkthat told me nested #()'s are not allowed when done inside a let
03:48mehworknoidi: what's the , mean
03:50ro_stit tells clojurebot to execute the code
03:50ro_st,(inc 41)
03:50clojurebot42
03:50ro_st,(* 3 7 2)
03:50clojurebot42
03:51mehwork,(= 42)
03:51clojurebottrue
03:51mehwork,(= 42 "meaning of life")
03:51clojurebotfalse
03:53tomojthe double # tells lazybot to eval: ##(+ 1 2)
03:53lazybot⇒ 3
03:53tomoj&(+ 1 2) ; (or initial &)
03:53lazybot⇒ 3
03:54mehworkwhy does zipmap return the map reversed
03:55ro_stit's conjing onto a list, which conj's on to the beginning
03:55ro_stvectors conj onto the end
03:56ro_stthis is for performance reasons
03:56ro_stnot because it's sensible -grin-
03:56mehworkis that to do with lazy sequencing
03:56ro_st,(conj (list 1 2) 3)
03:56clojurebot(3 1 2)
03:56tomoj&(-> {} (assoc 1 2) (assoc 3 4) (assoc 5 6))
03:56lazybot⇒ {5 6, 3 4, 1 2}
03:56tomojno list in zipmap
03:56ro_st,(conj [1 2] 3)
03:56clojurebot[1 2 3]
03:57ro_stoh. then it's something else. but what i showed about conj and lists/vectors is still good to know
03:58clgvwhat's the question?
03:58tomoj&(zipmap (take 9 (range)) (range))
03:58lazybot⇒ {8 8, 7 7, 6 6, 5 5, 4 4, 3 3, 2 2, 1 1, 0 0}
03:58tomoj&(zipmap (take 10 (range)) (range))
03:58lazybot⇒ {0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9}
03:58mehworkyeah the docs for conj say they may be in different places depending on the concrete type
03:58clgvmehwork: that's what the scala people did not like as well ;)
04:01tomojis there any hope for denotational semantics in clojure - not for proofs, just for design aid
04:04clgvtomoj: I think `conj` is the worst example and to a certain degree the querying and delting operations associated with it on sequential data.
04:05clgv,(peek '(1 2 3))
04:05clojurebot1
04:05clgv,(peek [1 2 3])
04:05clojurebot3
04:07tomojdo the semantic types include lists and vectors?
04:07tomojIReduce?
04:08tomojI guess I should read about semantics
04:10mehworkhow do you sort a map by it's numerical keys? i tried (into (sorted-map) mymap) but it's coming out disordered
04:11ro_st,(into (sorted-map) {3 2 1 6 4 5})
04:11clojurebot{1 6, 3 2, 4 5}
04:11clgvmehwork: `sorted-map-by` let's you provide a comparator
04:12ro_stkeys look sorted to me
04:13tomoj&(keys (zipmap (range 20) (range)))
04:13lazybot⇒ (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
04:13tomojcoincidence!
04:14tomojI misread as "#'keys looks sorted to me"
04:14clgv,(let [kvs (repeatedly 20 #(rand-int 100))] (println "kvs =" kvs "\nsorted-map =" (apply sorted-map kvs)))
04:14clojurebotkvs = (57 76 0 89 53 ...)
04:14clojurebotsorted-map = {0 89, 38 16, 42 15, 48 27, 49 16, ...}
04:15clgv&(let [kvs (repeatedly 20 #(rand-int 100))] (println "kvs =" kvs "\nsorted-map =" (apply sorted-map kvs)))
04:15lazybot⇒ kvs = (48 42 74 4 15 98 80 75 69 97 96 87 27 75 23 35 43 20 59 98) sorted-map = {15 98, 23 35, 27 75, 43 20, 48 42, 59 98, 69 97, 74 4, 80 75, 96 87} nil
04:15alex_baranoskyis Korma compatible with Clojure 1.2.1?
04:16clgvalex_baranosky: you should put in the effort to upgrade. I've been sitting on 1.2.1 until 2-3 months ago. it's a pain when all the libs move on and you cant use a decent number of them anymore
04:17clgv&(let [kvs (repeatedly 20 #(rand-int 100))] (println "kvs =" kvs "\nsorted-map =" (seq (apply sorted-map kvs))))
04:17lazybot⇒ kvs = (9 2 32 84 86 5 34 7 63 9 66 47 97 86 62 71 19 68 82 33) sorted-map = ([9 2] [19 68] [32 84] [34 7] [62 71] [63 9] [66 47] [82 33] [86 5] [97 86]) nil
04:17mehworkah sorted-map-by is what i needed cause now it's the values i need
04:19alex_baranoskycigv: in due time, but for the time being I am trying to fix a issue at work, by moving some old code off clj-record
04:20alex_baranoskyI can do that faster than I can do a move to 1.4
04:55clgvalex_baranosky: guess you have to try korma with 1.2.1 to get an answer. a profile for clojure 1.2.1 in the project.clj would be a good sign for you
05:12Raynesalex_baranosky: Clojure 1.2.1 lolnoob
05:16ejacksonRaynes: Now I know why you live out in the sticks - to avoid all the slaps !
05:16Raynesejackson: Yeah, but that's only until February. Then I'll be in slapping distance of everyone I insult on the west coast.
05:18ro_stwill me nattering on about how we've used Clojure end-to-end be interesting enough?
05:18ejacksonI'll get you a gumguard for Christmas
05:18ejacksonro_st: experience reports are always super interesting.
05:18Raynesejackson: Sweet
05:18ro_stwhat sort of details would be of value?
05:19ejacksonedges, corners, when you had to do something ugly
05:19ro_stwe're only launching on the 14th of jan, but by the time of the talk, we should be several thousand users strong
05:20ro_stwe are using values-based programming end to end.
05:20ro_stusing event sourcing for the main app's persistent data model
05:20ro_stdatomic, clj, cljs, pallet
05:21ro_sti think there's probably enough meat in there
05:21ejacksonyeah, people always like to hear about somebody actually winning !
05:22ro_stthat's true
05:55piranha_ro_st: do you do in-browser app, or what is it in the end?
05:55ro_stit's a webapp, yes
05:55ro_sthtml5 multi-platform
05:55ro_stdeskop/tablet for now. dedicated mobile ui sometime next year
05:56piranhaaha, how do you do user interface? FRP?
05:56ro_sti'd love to get there. we probably have a half-baked FRP hiding in amongst our code
05:56piranhaI see...
05:56RaynesTranslation to human speak is: "it's all broke"
05:56ro_stwe use shoreleave's remotes and pubsub along with enfocus for templating and event handling
05:57piranhaI'm trying to get in by using Flapjax, so far it's... well, works somehow for simple things, not sure if it will be good for big stuff
05:57piranhaI see
05:57ejacksonRaynes: maybe a helmet, actually...
05:57piranharo_st: how do you handle data on the client? :) Atoms? Or inside of the DOM? :)
05:57ro_statoms
05:58ro_stbut all the atoms are in one namespace; all the actual logic is pure
05:58ro_ston the client, the cljs uses the atom namespace as a singleton; on the server, i use binding to scope those atoms when working with the data
05:58ro_stwe use lein-cljsbuild's crossovers to share the model code in clj/cljs
05:58piranhaaha... I wrote my own abstraction for managing data in atoms, and I would love to hear some feedback (if I'm crazy or not, haha), clojure mailing list is keeping silence :))
05:59piranhaah, I see... I plan to write only browser part in clojure
06:00ro_stthe atoms only hold transient data only; the persisted data is event sourced. so loading a document merely replays events into a running session and that reconstitutes the state
06:00ro_stnever persist and repopulate atoms directly
06:00ro_stmakes undo/redo dead easy to do.
06:01ro_stmind sharing a link to your post?
06:01ro_stRaynes: we're using the some things that FRP uses, like pubsub
06:02RaynesI wasn't the one who asked about FRP, but thanks for letting me know. ;)
06:02ro_stbut by no means are we actually doing FRP. would love to spike out an FRP solution to properly understand it, but there's only so much damn time available.
06:03ro_stah, i was responding to your 'it's all broke' comment :-)
06:03ro_stpiranha: atoms + shoreleave-pubsub works really well
06:04piranharo_st: https://groups.google.com/forum/#!topic/clojure/shkr_3AD3UM
06:04piranharo_st: what means 'event sourcing'? I feel I don't really understand that :)
06:04ro_stah, i've seen this. it's queued in my list
06:05piranhaah :)
06:05ro_sthttp://martinfowler.com/eaaDev/EventSourcing.html
06:05piranhathanks
06:06ro_stessentially, instead of transfering the full state, instead just transfer the user's actions, and re-constitute the full state by 'replaying' those actions in order
06:07ro_ststock markets are event sourced
06:07piranhaI see...
06:07piranhahmmm, interesting
06:08ro_stwhy i love it is because we get undo/redo almost for free, and when we add websockets as a transport and start to do collaborative document stuff, all i need to do is add a bit of control flow logic and rewire pubsubs
06:08ro_stto have eg a websocket play events into a cljs workspace rather than keyboard/mouse events
06:10ro_stand we also have instant save/resume for mobile - no big state to upload. users just use the app and the rest happens like magic
06:11piranhaindeed, sounds nice :)
06:12ro_stpiranha: check shoreleave-pubsub. working demo code here: https://github.com/robert-stuttaford/demo-enfocus-pubsub-remote
06:12piranharo_st: thanks! I will
06:13piranhareading about event sourcing now :)
07:29ro_stanyone connecting to nrepl servers via ssh?
07:30ambrosebscan anyone think of a statically typed language that has keywords that are also functions?
07:30ambrosebsor similar
07:36ro_sti don't know. that guy who did Typed Clojure seems like someone to ask, though
07:36ro_st-grin-
07:36llasramambrosebs: Keywords in the syntactic sense, or in the Clojure sense?
07:38clgvro_st: roflmao!
07:39ambrosebsllasram: (:a coll) looks up :a in its argument.
07:39ro_stcemerick_: thank you, thank you, thank you for nrepl
07:39ambrosebsI'll scratching my head how to make that not hacky
07:39ambrosebs*I'm
07:40llasramOh. Hmm. Yeah -- the name defines what the value does. That is kind of weird when you think about it
07:42ambrosebsOne idea I had was to parameterise Keyword with the key it looks up. :a is of (Keyword :a). But that has other issues.
07:42clojurebotAlles klar
07:42cemerickro_st: :-) Anything in particular about it you're enjoying?
07:43ambrosebsI'm trying to get rid of my intersection type, but it comes in quite handy here. :a is just (I (Value :a) (All [x] [(U Any '{:a x}) -> (U x nil)]))
07:44ro_stdatomic licenses by jvm process. starting up a repl consumes one process. when your production stack is already using all 3 available processes makes starting a repl impossible. but embedding nrepl server makes that unhappiness melt away :-)
07:45ro_st...processes, that makes*
07:47ambrosebsThe definition of Keyword in CLJS gives a hint.
07:47ambrosebsWe definitely need to abstract over its "k" field.
07:48renderfulnice repl tip ro_st, that will come in handy one day
07:49ro_stalso a lot saner when it comes to server ram
07:49ro_stmakes me wonder why we've been hobbling along without nrepl embedded for so long
07:51ro_stcemerick: are you attending clojurewest?
07:52cemerickwell, other REPL servers were certainly embeddable in the past, though perhaps not as frequently as nREPL is
07:52cemerickro_st: probably
07:52ro_stbuy you a beer.
07:52cemerickheh, thanks
07:53cemerickhopefully Alex looks favorably on my talk submission.
07:54clgvcemerick: as clojure book writer you have no "auto accept status" on clojure conferencs? ;)
07:54cemerickheh, no
07:55cemerickAt this rate, all confs would be full-up with speakers without any submissions.
07:55cemerickIt'd get a little boring. :-P
08:05clgv:D
08:15squidzwhere else can I find clojure videos besides the new clojure youtube channel?
08:19ro_stsearch vimeo for clojure
08:19ro_stsearch infoq.com for clojure
08:20squidzro_st: okay so vimeo and infoq have a lot of clojure videos, thanks, anything else
08:20ro_sthttp://skillsmatter.com/
08:21squidzcool thanks
08:21ro_stplenty on those 3 for you
08:21ro_st90% of em, i'd say
08:21squidzyeah i think so, thanks
08:22ro_stsure thing
08:24squidzi'm almost done with Joy of Clojure, and am confident I can hack some clojure, but am kind of stuck on what I should actually program. I guess the opportunity will present itself at one point or another, but I can't wait
08:26ro_stwhat's your background?
08:26squidzI am working as a java dev developing a facebook app for career networking
08:27squidzbackend stuff mostly
08:27ro_stoh then you must be loving clojure
08:27ro_stjava devs love it once they invest enough time checking it out
08:27squidzyes so far i can't get enough of it. I took a detour and learned a little haskell but got frustrated with it so decided to check out clojure. I havent looked back
08:29squidzhere is our app https://apps.facebook.com/emplido/
08:33squidzso far I was only able to really do one thing with clojure, and that is, sneak in a small clojure script into our project for maven to execute
08:43ro_stthis looks ideal for clojure
08:43squidzreally? why?
08:43ro_stit's well suited to the sort of data munging you're likely doing
08:44squidzah I see. I guess the problem is as usual, how to convince others who know nothing of clojure
08:45ro_stusers create data > data is collated to create information > information is queried for ratings and fuzzy matching > outbound messaging & report displays
08:45ro_stwatch the talk from Amit at Zolodeck
08:45ro_stit's on infoq
08:45ro_sthe uses clj + storm + datomic to great effect
08:47squidzill check it out. What is storm btw?
08:47ro_ststorm-project.net
08:47ro_stdistributed real-time computation
08:47ro_stshit-hot.
08:48squidzlooks cool, but isn't datomic proprietary?
08:48ro_stit is
08:48ro_stexpensive, too
08:48squidzhm that makes it hard, but Ill check out the video anyways. Looks like it's interesting to learn
08:48ro_ststill, its net effect is a radically lower cost of ownership for us
08:49ro_stfar less developer time involved, and far less code
08:49squidzwhat did you use before?
08:50ro_stv1 stack is php+mysql
08:50ro_stv2 clj+datomic
08:50squidzoh okay, yes that must be much better
08:51ro_stway, WAY better :-)
08:51squidzive never done anything with php, and I don't really want to
08:51ro_stdon't
08:52ro_stit's horrible
08:52squidzI guess i'll just keep checkout out clojure videos until I get an idea of a miniproject. Small steps
08:52AdmiralBumbleBeephp isn't that bad
08:52ro_styeah. do you have clojurebook.com?
08:52AdmiralBumbleBeepeople just do awful things with it
08:53squidzro_st: ive seen clojurebook.com, but I havent read any of it
08:53ro_stgreat book. highly recommended.
08:54squidzokay, i'm almost done with Joy of clojure. Maybe checking that out afterwards will be good
08:55squidzmaybe starting from the practicums section, since the first part of the book may be a little repetitive
08:56ro_styeah
08:56ro_sti'm going over the book again this holida
08:56ro_sthaven't used it since the solid two weeks i spent reading it before i started coding
08:57squidzhave you made any projects on github yet?
08:57ro_styup http://github.com/cognician
08:57ro_sthttps://github.com/Cognician/fusebox is the most recent
08:59squidzcool
08:59cemerickro_st: fusebox looks promising :-)
08:59ro_stthanks. i had a look around for a flags system in clj but found zip.
08:59ro_sti've got a nice little addon for datomic as well
09:00ro_stwhich defines an entity for the whole system, and then allows you to enable for particular entities or enums - for example, on user roles
09:00ro_ststill need to tidy it up and release it
09:01ro_stthere's almost no code to it
09:02ro_stwe had 4 different projects doing the master/develop git branch thing and it was getting seriously tedious to manage versioning and dependencies between them
09:02ro_stso now we're just on master, and new stuff is wrapped inside fuse checks
09:03WokenFurycemerick: which is the best release of tools.nrepl for embedding? 0.2.0-RC1 or 0.2.0-beta9?
09:03WokenFurygetting this error in RC1: java.lang.IllegalArgumentException: Multiple methods in multimethod 'print-method' match dispatch value: class clojure.tools.nrepl.server.Server -> interface clojure.lang.IDeref and interface clojure.lang.IRecord, and neither is preferred
09:03squidzwhat is the need for fuses though? To have global flags?
09:03ro_stfuses happen to look precisely like datomic attribute names, which isn't a coindcidence :-)
09:03ro_stsquidz: http://stackoverflow.com/questions/7707383/what-is-a-feature-flag
09:04cemerickWokenFury: later is better
09:04cemerickInteresting re: the print error. I suppose I've never tried println'ing a server reference.
09:04squidzro_st: ah i see
09:05WokenFurycemerick: afaik neither am I, just using (nrepl/start-server :port config/NREPL-PORT)
09:05ro_stwe have one set of flags powering our web server, our background worker, and our cljs app
09:05WokenFurypossibly because it's the last call in my main fn
09:05ro_stsquidz: http://blog.asana.com/2011/04/using-flags-to-ease-new-feature-development/ is a great intro
09:06cemerickWokenFury: yeah, it's implicit if that's the last thing evaluated in e.g. a loaded file
09:06WokenFuryaha. must've been that. sorted now
09:07WokenFurywith beta9 it was spitting this out in console: #<Agent$Closeable$b14108b6@1ae57e12: {:ss #<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9991]>, :transport #<transport$bencode clojure.tools.nrepl.transport$bencode@706cac3b>, :greeting nil, :handler #<middleware$wrap_conj_descriptor$fn__8737 clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__8737@2d6f4087>}>
09:07cemerickYeah, that's to be expected.
09:07cemerickRC1 is certainly better
09:07cemerickWokenFury: would you mind filing a bug @ http://dev.clojure.org/jira/browse/NREPL for the printing issue?
09:07WokenFurywill do
09:11acron^Please excuse my ignorance, as I come from C/C++ so my mental model of operations in Clojure is lagging behind somewhat
09:11acron^I want to take a map and perform an operation on the value of each element in that map, depending on what they key is
09:11acron^I also don't want to keep fetching the map from the db
09:12acron^where would I even begin this, in the context of FP?
09:12acron^a massive 'do' function?
09:12acron^case?
09:13Ember-acron^: list comprehension?
09:14acron^do you have an example Ember-?
09:14Ember-acron^: http://clojuredocs.org/clojure_core/clojure.core/for
09:15Ember-and yes, you can pass a map to for
09:15Ember-and no, for is NOT a for loop
09:15Ember-in case of a map you are effectively processing key/value pairs
09:16acron^hmmm
09:16Ember-but it might not be an optimal solution for you, clojure has some much power in map and list processing
09:16Ember-some = so
09:16Ember-(what I was thinking when typed _some_ ??)
09:17llasramacron^: By "perform operation" do you mean "perform action for side-effects" or "generate a new value, assembling the sequence of new values into a new collection"?
09:17Ember-list comprehension is maybe one of the hardest things to graps coming from an imperative world
09:17acron^llasram, the latter
09:18tpopeI still haven't grasped it
09:18Ember-in that case list comprehension should be your tool
09:18llasramOk, then like Ember- is saying, the `for` comprehension will do it. Although IMHO you get more milage from the composable sequence operations
09:18acron^lets imagine i have {:a 1 :b 2 :c 3} - I want :a to be doubled, :b to be halved and :c should be trippled
09:19llasramOh!
09:19llasramWell that's differest
09:19noidi(for [[k v] my-map] (make-new-value k v))
09:19Ember-and yeah, I'd propably use some higher level functions
09:19acron^and i want the results in a new map using the original keys
09:19llasramSo you want a different function applied to the value for each key?
09:19Ember-for comprehension is kinda like the ultimate low level swiss tool for stuff like that :)
09:19noidiwhere make-new-value is a multimethod with implementations for :a :b and :c
09:19acron^llasram: yes
09:20acron^so {:a 1 :b 2 :c 3} -> {:a 2 :b 1 :c 9}
09:21Ember-what noidi said
09:21Ember-for comprehension + multimethod
09:22Ember-but how many different keys do you have?
09:22Ember-<10 or more?
09:22acron^potentially, yes
09:22acron^10-20
09:22Ember-ok, are they of what type?
09:23Ember-and what kind of operations?
09:23Ember-are they totally different from each other?
09:23acron^it's string in, map out
09:23acron^for all
09:24llasramacron^: ##(let [update-by-key (fn [fs m] (merge-with #(%1 %2) fs m)), fns {:a #(* 2 %), :b #(* 0.5 %), :c #(* 3 %)}] (update-by-key fns {:a 1, :b 2, :c 3}))
09:24lazybot⇒ {:a 2, :b 1.0, :c 9}
09:24Ember-yes, but can your keys be eg. "a", 1, true and so on?
09:24llasramBut this isn't honestly a typical solt of thing
09:24llasramsort even
09:24llasramWhat's your higher-level goal with this operation?
09:24acron^Ember-: keys are all str
09:25acron^llasram: i'm turning url paramters into monger queries
09:25Ember-hmm, sounds a bit hazardous maybe
09:25Ember-but I gotta run
09:26Ember-significant other called, time to meet her :)
09:26acron^so color=Blue,Red --> {$or [{:color "Blue"} {:color "Red"}]}
09:27acron^so color=Blue+Red --> {$and [{:color "Blue"} {:color "Red"}]}
09:27acron^etc
09:29noidiacron^, https://www.refheap.com/paste/7745
09:29llasramInteresting. I agree with noidi the multimethod approach is probably the way to go
09:29llasramYou can provide a :default for giving things a default treatment
09:30acron^noidi, this is really helpful, thank you
09:31squidznoidi: me likey
09:34noidi,(seq {:a 1, :b 2, :c 3})
09:34clojurebot([:a 1] [:c 3] [:b 2])
09:34noidiso a sequential view of a map is a seq of map entries
09:34noidi,(class (first {:a 1, :b 2, :c 3}))
09:34clojurebotclojure.lang.MapEntry
09:35noidiyou can add map entries to a map with conj
09:35noidi,(conj {:a 1} [b 2])
09:35clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0)>
09:35noidi,(conj {:a 1} [:b 2])
09:35clojurebot{:b 2, :a 1}
09:36noidiand "into" just conj's everything in its second argument (a sequence) into its first argument
09:36noidiso then there are only multimethods, which are too complex to be explained on IRC :)
09:37acron^:E
09:39squidzacron^: have you done anything with multimethods yet?
09:39acron^Nothing at all
09:39acron^reading up now
09:40squidznows a better time than ever I guess
09:42acron^noidi does "map" internall cally seq on the passed in map then?
09:43noidiacron^, yes
09:43acron^gotcha
09:45tbaldridgealmost every sequence function calls seq on its argument. Vectors are not seqs, so map wouldn't work with vectors otherwise.
09:47mmitchellweavejester: Quick question about Compojure... is it possible to dispatch on a query param and its value?
09:49mmitchellweavejester: i currently have 1 route to a controller. The logic in the controller is very complicated due to some wacky business logic around a single query param. I'd love to be able to completely separate the logic into 2 controllers using routes.
09:55clgvmmitchell: you just can dispatch the clojure function in the route depending on the query param
09:57clgv(GET "/myrout" request (dispatch request)) and (defn dispatch [{{:keys [myparam]} :query-params :as request] (if (= myparam "awesome) (awesome-fn request) (default-fn request))
09:59mmitchellclgv: very cool thanks!
10:08yediis there like a protocol or spec or format or something that can be used for storing/sending boolean rules (combinations of logical statements)
10:09weavejestermmitchell: You could also write it a little more concisely - there's usually no need to pass the whole request out
10:09weavejestermmitchell: (GET "/foo" [p] (case p "foo" foo-route bar-route))
10:09mmitchellweavejester: you mean by passing only the :query-params?
10:09mmitchellahh ok
10:10weavejestermmitchell: You can return another handler from a route
10:10mmitchellnice
10:23ppppaulanyone have suggestions for testing my ring?
10:24ppppauli see there is a lib ring-mock... it good?
10:24clojurebotlibraries is http://clojure.org/libraries
10:24weavejesterppppaul: There's some other systems built on top of ring-mock
10:25weavejesterppppaul: Let me see if I can find the name of the one I'm thinking of
10:25ppppauli'm also interested in mocking out http calls (my server is talking to other servers, and right now i'm in a hairy place where i could really use some testing fast)
10:25squidzdoes anybody do a blog in clojure?
10:26nathanicsquidz: this blog http://yogthos.net/ is written in clojure. src: https://github.com/yogthos/yuggoth
10:27nathanicit even supports .war deployment in an application server, which is nice for people with JEE day jobs like me
10:27weavejesterppppaul: Try looking at https://github.com/xeqi/kerodon
10:28squidznathanic: thanks
10:28weavejesterppppaul: if you're testing a web app
10:28weavejesterppppaul: Or https://github.com/xeqi/peridot
10:28weavejesterppppaul: if you're testing a web service
10:29ppppauli'm building an api
10:29ppppaulperidot looks sexy
10:30ppppaulkerodon looks like magic *_*
10:30ppppaulthanks weavejester
10:30ppppaul:D
10:33ppppauli have another issue. i'm using ring via 'lein ring server-headless' and i would like to see my logs going to the console. i am having trouble doing this. it seems like my logs are going into some void
10:37jweisshow would one generate a keyword in the current namespace (without explicitly mentioning the namespace). i tried *ns* but that didn't work at runtime, *ns* value ended up being clojure.core.
10:38jweissi mean, create it from a string
10:38jweiss,(keyword "::foo")
10:38clojurebot:::foo
10:38jweissdoesnt work
10:38jweiss,(keyword "foo" (-> *ns* .name name))
10:38clojurebot:foo/sandbox
10:41dhmjweiss: (intern *ns* (symbol (str (keyword "foo"))))
10:42llasramjweiss: Extracting from `*ns*` should in fact work... Are you sure you didn't have scoping issues?
10:43llasram&(keyword (-> *ns* ns-name name) "foo")
10:43lazybot⇒ :sandbox7657/foo
10:44jweissllasram: eg, (defn mkkey [] (keyword (-> *ns* ns-name name))) did not work
10:44jweisswas returning clojure.core, not the namespace in which mkkey was defined.
10:44jweisssorry left out the string part of the keyword but you get the idea
10:45llasramOh! *ns* is dynamic, so you'll get the value of *ns* where mkkey is called
10:46jweissllasram: yeah, so i was trying to figure out how to refer to the current ns, meaning at compile time
10:46llasram(let [kw-ns (-> *ns* ns-name name)] (defn mkkey [s] (keyword kw-ns s))
10:46llasram)
10:46llasram:-)
10:47jweissjust trying to avoid a gotcha where i refactor the name of the namespace and inadvertently introduce a mismatch if i forget to update the hardcoded name
10:48llasramRight. So like I have above, you capture the ns name string in the lexical scope of the function. When you re-compile the namespace, the forms get re-evaluated, so renames follow automatically
10:48jweissllasram: ok thanks
10:49ppppauli'm trying to do interactive ring dev via emacs. i have :dev-dependencies [[ring-serve "0.1.1"]] in my project however i'm not getting 'ring.util.serve on my classpath. any ideas?
10:49ppppaulreading docs form this url https://github.com/mmcgrana/ring/wiki/Interactive-Development
10:49llasramppppaul: Are you using Leiningen 1?
10:49ppppaul2
10:50llasramThen :dev-dependencies -> :profiles {:dev {:dependencies [...]}}
10:50ppppaulinteresting
10:50ppppauli'll do that no
10:50ppppaulw
10:51llasramI *think* you probably want ring-server instead of ring-serve though. It's more recent, and doesn't depend on an ancient version of hiccup
10:51llasram(I don't do much webdev so I can't say definitively, but that's what I found when I was doing a tiny compojure app last week)
10:52weavejesterring-serve is out of date, but I haven't got around to adding support for emacs debugging into ring-server
10:52llasramAh
10:52weavejesterBut the emacs debugging landscape for Clojure has changed a lot since then
10:52weavejesternrepl seems to be the future
10:53llasramYeah -- what does "support for emacs debugging" mean exactly?
10:54llasramOh, swank.core/break
11:02ppppaulllasram, the :profiles goes in my project.clj or it goes in .lein/profiles ?
11:04llasramppppaul: project.clj
11:20ppppauli started clojure with swank a few years ago. now i'm back into clojure and i see that i'm being told to use nrepl. can someone explain why?
11:21drewrppppaul: no one in the clojure community supporting swank-clojure coupled with nrepl being actively developed
11:21ppppaulis there a big difference right now?
11:22drewrlittle things mainly; I still use swank-clojure
11:23ppppaulso i have the same commands in emacs when i use it?
11:24nDuffThey're not exactly equivalent, no.
11:25ppppauli have ring.util.serve on my classpath now, but when i try (use 'ring.util.serve) i get an error
11:25ppppaulclassnotfoundexception :(
11:29drewrppppaul: no, the bindings are slightly different and the functionality is somewhat divergent; eventually I expect the nrepl interaction to be vastly superior though
11:29ppppauldrewr, the nrepl looks interesting
11:30ppppaulright now my problem is getting ring working in emacs
11:30ppppaul:(
11:34ppppaulany help with this would be appreciated... the ring docs for this are painfully incorrect :(
11:34weavejesterWhich docs?
11:34ppppaulhttps://github.com/mmcgrana/ring/wiki/Interactive-Development
11:35ppppauli do this -> user> (use 'ring.util.serve)
11:35ppppauli get back classnotfoundexception
11:35weavejesterppppaul: That's an out-of-date repository you've linked to
11:35weavejesterppppaul: https://github.com/ring-clojure/ring/wiki/Interactive-Development
11:35ppppaulwhen i do lein classpath | grep serve i find the class
11:35ppppauluuuuuuuuuuugggggggggggg!
11:35ppppaul:(
11:36weavejesterppppaul: But the ring-serve instructions are still the same
11:36ppppaullol
11:36weavejesterWhat happens when you (use 'ring.util.serve)
11:36weavejester?
11:36ppppauloh cool, you made it the lib
11:37ppppaulweavejester, pm
11:39weavejesterppppaul: It might be that ring-serve doesn't work with Jetty 7, which is used by the latest versions of Ring.
11:39weavejesterring-serve is an out-of-date library
11:40weavejesterYou might want to try using the Ring adapter instead
11:40weavejesterOr just using lein-ring
11:41ppppaulok, i didn't know about the alternatives
11:41ppppaulso long as swank/break works i'm happy
11:41ppppaulor if logging works
11:41ppppaulor anything to help me debug
11:42weavejesterLogging will work with lein-ring or the standard adapter
11:42ppppaullogging via (print/pprint)/?
11:42weavejesterI don't think anything works with swank/break. I'll need to find some time to look into the newer Clojure debugging tools
11:43weavejesterswank seems to be being deprecated for Clojure in favor of nREPL
11:43weavejesterppppaul: Yep
11:45ppppaulhmm, it doesn't seem to be working for me
11:45ppppaulmaybe i'm looking in the wrong place
11:46weavejesterppppaul: What's not working?
11:46ppppaulmy print statements aren't making it to the console
11:46weavejesterppppaul: Which console? A normal terminal? Emacs swank? Emacs nREPL?
11:48ppppaulterminal
11:49ppppauli couldn't get ring working in emacs
11:49ppppauli'm using lein ring server-headless
11:49ppppaulhowever, my code is currently throwing stack traces
11:49ppppaulit would be awesome to be able to have breakpoints working on my server
11:50weavejesterppppaul: You might want to look into Ritz
11:51ppppaullooking
11:52weavejesterBut to be honest I haven't found breakpoints to be useful enough to bother with
11:52ppppaul:)
11:52weavejesterAt some point I'll probably try Ritz
11:52weavejesterBut
11:52weavejesterIf your application consists of many small, pure functions, you can try out all parts in a REPL anyway
11:53ppppaulmy app is a bit hairy now. just started putting in tests
11:56tomojhmm https://www.refheap.com/paste/1f9f6acaced723eff69ce1e4f
11:56tomojclojurescript
11:56llasramI really want to just sit and watch someone who uses breakpoints in their workflow, so I can understand when they may be useful
11:57tomojseems you can't expand to a try/catch with a js/* for the class?
11:58tomojweird thing is that analyzing the output of cljs.analyzer/macroexpand-1 works fine
12:01tomojdnolen: https://www.refheap.com/paste/1f9f6acaced723eff69ce1e4f
12:02tomoj(ana/analyze env (ana/macroexpand-1 env '(defcatch foo [] bar))) works fine
12:02tomojbut (ana/analyze env '(defcatch foo [] bar)) throws that error
12:03tomojbug?
12:03clojurebotPaste the contents of project.clj and ~/.lein/init.clj along with the output of ls ~/.lein/plugins and lein version.
12:03S11001001llasram: I used them occasionally in Common Lisp, but never bothered in Clojure.
12:03S11001001Of course, SLIME's CL support for breakpoints and inspecting stacktraces is pretty spectacularly good
12:05S11001001llasram: I'd say FP makes them much less useful.
12:06llasramS11001001: I definitely used them in C, so maybe that's it
12:09tomojhmm, now (ana/analyze env (ana/macroexpand-1 env '(defcatch foo [] bar))) has the same error
12:10tomojbut if I take the output of (ana/macroexpand-1 env '(defcatch foo [] bar)) and copy it to (ana/analyze env HERE), it works
12:10tomojO_o
12:11dnolentomoj: hmm no idea.
12:11dnolentomoj: it looks like it thinks the name that holds the exception is js/Error
12:11ppppaulcan anyone help me get lein to run my tests on file changes?
12:11ppppauli would like to have a setup similar to testacular (JS) but for my clojure project
12:12tomojwhen the error happens, the try* form is (try* bar (catch js/Error e__8915__auto__ 42))
12:12dnolentomoj: yes that try* is wrong
12:13tomojyeah, but if I macroexpand-1, it's (clojure.core/defn foo [] (try bar (catch js/Error e__8915__auto__ 42))). hmmm
12:14dnolentomoj: and you're calling ana/macroexpand-1 ?
12:14tomojyeah
12:15dnolentomoj: it looks like somehow you're macroexpanding Clojure try and not CLJS try
12:16tomojtry is a special form in clojure, isn't it?
12:16dnolentomoj: it is, but it's a macro in CLJS that expands to a try*
12:19antoineBhow do you not enforce immutability in cljs? (dealing with gui stuff)
12:19dnolenantoineB: ?
12:21antoineBi use set! to do for exemple cross reference with a dom element and my type
12:22antoineBmaybe you have some project with good design?
12:22tomojaha
12:22dnolenantoineB: still not sure what you are asking.
12:23antoineBit's a bit unclear for me
12:24tomojhttps://github.com/clojure/clojurescript/blob/ebe40c8a/src/clj/cljs/core.clj#L866
12:24tomojthe try macro checks for list?
12:24tomojshould it be seq? ?
12:24antoineBsomething like that http://en.wikipedia.org/wiki/Functional_reactive_programming
12:27antoineBtomoj: you will write "(catch " not "[catch " so i think i will be a list
12:28tomoj&(list? `(catch foo))
12:28lazybotjava.lang.SecurityException: You tripped the alarm! catch is bad!
12:28tomojwell, it's false
12:28tomojbut that's probably not the exact reason why
12:30dnolentomoj: yeah that definitely looks like the problem.
12:31tomojI expected to find seqs in there, but looks like it is just the conses
12:33dnolentomoj: if you can confirm that fixes it for you, I can commit that change here.
12:33tomojyep, that fixes it
12:33tomojat least, on my stupid test case
12:34tomojby the way, I'm porting clojure.test to cljs.test by keeping the ns/var->test mapping in atoms cljs-side. will an official port have to wait until vars are reified?
12:35dnolentomoj: fixed in master
12:35tomojconfirmed that that fixed my real case, (is (thrown? js/Error ...))
12:37dnolentomoj: I see no reason to wait for that. run-tests can be a macro that uses the atom to generate all the test calls.
12:37dnolentomoj: a port of clojure.test would be most welcome.
12:38tomojI had run-tests as a macro
12:38tomojand all the rest
12:38tomojwith the mapping clj side. but that seemed to break when using the repl
12:39tomojnow run-tests is a function that accepts symbols and looks them up in the atoms (cljs side)
12:40tomojwhich incidentally means you can deftest in the repl, although I didn't really want that much
12:41tomojI had to change the namespace to cljs.test, which breaks tradition, because there are macros
12:42tomojcould stay with clojure.test and have a clojure.test-macros or something
12:45technomancyllasram: the one time I found stepping through breakpoints to be really useful was when I was investigating a bug in Clojure itself
12:47dnolentomoj: I think cljs.test makes the most sense. I think the only reason there are namespaces like clojure.string is because of the old namespace clobbered by locals bug.
12:48dnolentomoj: well I guess the argument for clojure.test is that feature expression might arrive one day, and that's one less hassle. that's a big argument for clojure.test actually.
12:49technomancyaha; it was a bug where you could read a form containing an invalid map in clojure 1.2 and it wouldn't throw an exception until you tried to access the map
12:49technomancythat was a fun one
12:50konr_trabAny idea why lein [ring] would not generate the uberwar, keeping the generation process going on indefinitely?
12:51weavejesterkonr_trab: When a compile process goes on indefinitely that's usually an indication there's some loop outside of a function
12:52weavejesterkonr_trab: e.g. if I tried to compile (def foo (doall (repeat 1)))
12:52hugodle
12:55konr_trabweavejester: thank you! That was exactly the case!
12:56mmitchellanyone here using sublime text w/nrepl?
12:56tomojdnolen: but that would mean putting the clojurescript parts of clojure.test in clojure.git?
12:57technomancymmitchell: pretty sure it can't do that yet
12:57mmitchelltechnomancy: yeah seems so
12:58dnolentomoj: really? I think I'm missing something here.
12:59llasramtechnomancy: Oh, wow. Yeah, I could see any tool you could weild being useful against that one
12:59tomojwould feature expressions let you define macros in clojurescript/.../clojure/test.cljs ?
13:00llasramI really need to fix erc-spelling-mode not working until I turn it off then back on...
13:00technomancyllasram: typically it's most valuable in worst-case-scenarios though
13:00tomojotherwise you have to put them in clojurescript/.../clojure/test.clj
13:00tomojwhich is.. taken
13:00tomojthe alternative I see is to have clojure/.../clojure/test.clj use feature expressions
13:01tomojnot sure how that would even work
13:01dnolentomoj: perhaps talking past each other. I don't see why you can't have clojure.test in the CLJS repo as a macro include.
13:02tomojwon't it conflict with the existing clojure.test?
13:03dnolentomoj: ah right. ok, then I guess it has to be cljs.test which has the macros. and people will need to resolve the ns differences w/ feature expressions
13:05tomojI wonder how we can do jvm-side fixtures
13:05tomojor if that requires something more like one.test
13:07tomojI also wonder how to compile with *load-tests* false..
13:09dnolentomoj: I think getting the minimal useful set is a good start :)
13:21dakronejkkramer: hey, when will clojuresphere be updated?
13:21dakronejkkramer: last updated was in October
13:23jkkramerdakrone: I'll run the script today. I keep running into issues getting a proper dump of projects from github and end up disablng the auto-update
13:23dakronejkkramer: ahh okay
13:24jkkramerthe project needs some love and I haven't had time
13:46augustlhow do you typically manage the creation of the base schema when using datomic? I'm thinking some kind of leiningen task would do.
13:52creasetechnomancy: slept on it. think you're right about multimethods
13:56aaelonyI have a map that may contain a variable number of (differing) keys, :k1, :k2, ..., :kn. Depending on the keys present, various functions specific to that particular key need to be called to process the values of that key. There may be a lot of keys to look for. Considering a macro or a function that tests if the map contains a paricular key and then finds the function to be called. Or possibily the Maybe monad? Curious to hear
13:56aaelonypeople's thoughts on how best approach. https://www.refheap.com/paste/7755
13:58S11001001aaelony: write a variadic version of update-in that takes pairs of keypaths and functions and ignores absent keypaths
13:59aaelonyS11001001: nice idea, thanks. I wonder if I should make a collection of the keywords (and names of the functions for each) and then pass that around.
14:00hyPiRionaaelony: when :k1 exists, should you assoc :k1-post or :k1 with the value computed?
14:00aaelonyfor debugging purposes, I'm keeping the both for now. Ultimately, only the post will matter.
14:00hyPiRionokay
14:01hyPiRionI'll see what I can come up with on the fly.
14:01aaelonywow, cool thanks.
14:03hyPiRionI've been working with merge functions for some time now, so it's kinda relevant to what I'm currently working on :p
14:03aaelony i think it may be a kind of (cringing…) design pattern.
14:04aaelonywas looking at http://clojuredocs.org/clojure_contrib/clojure.contrib.monads/maybe-m but not sure if it is a fit, or performant, clean, etc...
14:06hyPiRionaaelony: https://www.refheap.com/paste/7756
14:06aaelonyhyPiRion: that looks really nice
14:07hyPiRionI don't know how the functions you have look like though, but it should be pretty fast too
14:07hyPiRionIf there are many, you should probably pop a transient!, assoc! and persistent! in there.
14:07aaelonysome functions call java libraries, others call regexes, or compute stuff...
14:08aaelonyvery cool
14:10aaelonyi like the use of reduce-kv
14:10hyPiRionaaelony: If there are many keys - like, I think more than 16 hits per map, then this should be faster: https://www.refheap.com/paste/7757
14:11hyPiRionThough it is slower if you have many functions
14:11aaelonythere are something like between 10 and 50 keys
14:11hyPiRionfew*
14:11hyPiRionThen the first one should do just fine
14:11hyPiRionI think...
14:11aaelonysuper to know both, will test
14:12hyPiRionOh yeah, I haven't actually tested them, so I may have some typo in there. But the idea is idea, so it shouldn't be hard to fix it.
14:12hyPiRion/s/is idea/is there/
14:13aaelonyunderstood
14:13TimMchyPiRion is making up for the swearjure session yesterday. :-P
14:13aaelonyfor the more intense functions I might throw a future or something in there too
14:13ivaraasenTimMc: swearjure?
14:13aaelonybig thanks
14:14hyPiRionaaelony: Ah, sounds smart. You should do two passes then - one where you future everything, and another where you deref everything.
14:14hyPiRionAnd good luck
14:14aaelonythanks - sounds good
14:14hyPiRionivaraasen: swearjure is clojure without alphanumerics
14:15hyPiRionlike, uh
14:15hyPiRion,(`[#'~(`[~@'`[~@[]]](+))](+)) ; But I don't want to go there today
14:15clojurebot(var clojure.core/apply)
14:15TimMcivaraasen: https://gist.github.com/3916042
14:15TimMcivaraasen: and https://gist.github.com/3036120
14:16ivaraasenbeautiful
14:16TimMcThis is what will make everyone want to use Clojure.
14:17hyPiRion"Screw brainfuck and javascript, Clojure is the new obscuria"
14:17hyPiRionTimMc: I think the first function we should get is juxt, by the way
14:18TimMchyPiRion: JS is way better at this: http://utf-8.jp/public/jjencode.html
14:18hyPiRionIt'd be easy to do conditionals then
14:18TimMcUgh, except that site has encodign issues.
14:18hyPiRionTimMc: Currently yeah, but Clojure has potential
14:19hyPiRionand it runs on the jvm!
14:26gtrakTimMc: that's amazing
14:26llasram(inc TimMc)
14:26lazybot⇒ 27
14:29squidzif I have a function (myfun [p1 p2 p3] ...) how can I use a sequence (v1 v2 v3) for the parameters of myfun?
14:29amalloy&(doc apply)
14:29lazybot⇒ ------------------------- clojure.core/apply ([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args]) Applies fn f to the argument list formed by prepending intervening arguments to args. nil
14:30squidzamalloy: ah thanks, so that's what apply is for
14:37AnderkentCan anyone recommend a graph library for clojure 1.4?
14:38ohpauleezAnderkent: What sort of graph problem/features are you looking for? Like a Graph DB, or just nice graph DSs?
14:39brehautor graph rendering?
14:39Anderkenttransitive clojure, grouping, topological sort
14:39Anderkentbasic stuff
14:41hiredman~ping
14:41clojurebotPONG!
14:43ohpauleezAnderkent: I usually use a mix of the standard data structures, with functions to treat them like graphs, and zippers.
14:43ohpauleezBut you might also look at this: https://github.com/jkk/loom
14:44ohpauleezThere was an old contrib you could resurrect as well.
14:44Anderkentright, that's more or less what I found, though I hoped that there would be something already stable for something as basic as what I need. Thanks
14:44ohpauleezOr find a solid Java library, and just use it via interop (wrapping things into functions where it helps composition)
14:45brainproxyAnderkent: if you're at all interested in a graph database, OrientDB is pure java and pretty nice, and there is a clojure wrapper, clj-orient
14:45ohpauleezAnderkent: No problem - for most of my graph problems, I just end up using the basic clj ds's
14:46ohpauleezespecially with clojure.walk and zippers
14:46brainproxythe apis for the db support various graph operations, as you might expect
14:46brainproxyeh, looks like clj-orient is lagging behind orientdb by a couple of point releases
14:58bbloomdnolen: saw you starred namin / TAPL-in-miniKanren-cKanren-core.logic, and saw in the readme: " It turns out that implementing general set operations in a pure logic system, when the domain is not already known, is an extremely difficult open problem."
14:58dnolenbbloom: that's mostly about the difficulty of unifying sets, which isn't interesting to me at all.
14:59bbloomdnolen: are there any decent articles, papers, things to look at regarding infinite domain constraint problems? i'm curious how that would even work
14:59dnolenbbloom: now that we have a constraint system, I think we can bring most Clojure operations as constraints
14:59SegFaultAXdnolen: What's the best online resource to learn about unification?
15:00dnolenwe do (assocc x k v) the way we do (+fd x y z)
15:00dnolenwe can do
15:00bbloomdnolen: yeah, that's clearly the next step for core.logic and i'm excited to see it unfold
15:01amalloySegFaultAX: http://starwars.wikia.com/wiki/Unification_War
15:01SegFaultAXamalloy: Hah :)
15:01bbloomdnolen: I was just curious to understand "stubornly see for myself their limitations in expressing type systems."
15:02dnolenSegFaultAX: chapter 3 of William Byrd's thesis is a good introduction to the idea via miniKanren's implementation
15:02tbaldridgeamalloy: illogical in this context that article is
15:02SegFaultAXdnolen: You wouldn't happen to have a link handy, would you?
15:02bbloomSegFaultAX: http://gradworks.umi.com/3380156.pdf
15:02bbloomi've been meaning to read it myself
15:02SegFaultAXbbloom: Danke.
15:03dnolenbbloom: well Kiselyov & Byrd have show you can do some interesting things - HM type inference / checking / inhabitation very succinctly
15:03dnolenbbloom: nominal logic programming is also very interesting - Prolog style programming to do inferences about names, binding and scope
15:04dnolenbbloom: and I have a hunch that with CLP(Set) you could probably get through most of Types & Programming Languages
15:04bbloomdnolen: k, got Cheney & Urban's paper about that open
15:05mehworkis there a more clojuric/idiomatic way of doing System/exit
15:06ivaraasendnolen: know of any any semi-technical (applied) primers on logic programming?
15:06amalloyusually the answer is to type out (System/exit 0) then hit backspace 19 times and do something more flexible
15:06bbloommehwork: if you're using agents, remember to call (shutdown-agents) other than that exit 0 is fine
15:06SegFaultAX,(count "(System/exit 0)")
15:06clojurebot15
15:07amalloyoh, i made a mistake with wc
15:08dnolenivaraasen: I always recommend starting w/ a good Prolog text, Sterling & Shapiro Art of Prolog or Bratko's Prolog for AI book
15:08mehwork15?
15:09ivaraasendnolen: will look into it. thanks
15:09mehworkthe number of chars of the string, ah
15:09SegFaultAXamalloy: Even 25 would have been fine :) ##(count (str `(System/exit 0)))
15:09lazybot⇒ 25
15:09mehworkwhat's ##
15:10dnolenivaraasen: there's an early draft PDF of Concepts Techniques & Models of Computer Programming on CiteSeer, also a good read especially to understand the constraint aspect of core.logic
15:10bbloommehwork: inline evaluation for lazybot ##(inc 5)
15:10lazybot⇒ 6
15:10mehworkis lazybot on github
15:11amalloy$whatis source
15:11lazybotsource is http://github.com/flatland/lazybot
15:12ivaraasendnolen: I believe that book is part of my coursework next year actually
15:13dnolenivaraasen: that's cool! :)
15:13ivaraasenwe have a course on programming paradigms using Mozart/Oz
15:14ivaraasenlooking forward to it
15:14hyPiRionivaraasen: I have the book if you need. I'm not in Trondheim now though
15:15hyPiRionAnd I suppose it's going to be next year, not the upcoming semester.
15:15mehworkwhenever i read through others' clojure code i never see any if statements. Are they frowned upon beause there's usually a better alternative in clojure?
15:15ivaraasencorrect
15:17mehworkbasically i want to know what the best way to write: run this function if this var is equal to 5
15:17hyPiRionmehwork: no else?
15:18mehworknope, nothing approaching a switch/case
15:18SegFaultAXmehwork: With a lack of an else branch, when is usually good.
15:18mehworknor ternary
15:18hyPiRion(when (= 5 var) (funcall))
15:18mehworkah thanks
15:19mehworkcan you when / else or do you have to if/else
15:19hyPiRionmehwork: if
15:19dnolenbbloom: Nada Amin is at EPFL doing PL things like this http://www.cs.uwm.edu/~boyland/fool2012/papers/fool2012_submission_3.pdf
15:20hyPiRion,(when (= 1 1) (prn 1) (prn 2)) ; <-- mehwork
15:20clojurebot1
15:20clojurebot2
15:20SegFaultAXmehwork: And before you ask, if you have more than 1 branch/alternate, cond is usually good.
15:20mehwork,(if (= 1 1) (prn "hmm"))
15:20clojurebot"hmm"
15:20hyPiRion^ or case, if that's working
15:20mehworkshouldn't i just do that then since it reads better
15:21mehworkeven if there's no else
15:21bbloomdnolen: interesting. i'd be excited to see logic programming subsume typed programming
15:21hyPiRionmehwork: Noone's stopping you :p
15:21mehwork'when' feels like it's something that'd be related to a loop or event of some kind
15:21hyPiRionIf you feel it reads better, then do it that way.
15:21mehworkhyPiRion: i know :p just wondering what the convention is
15:21dnolenbbloom: she's porting Byrd's nominal logic stuff to core.logic which pretty exciting. It's forcing a generalization of the constraint stuff I have in place and in pretty interesting. I don't know of many constraint solvers that focus on reasoning about programs - so perhaps we going down a interesting path not tread by other constraint solvers.
15:22SegFaultAXmehwork: It's arguably more idiomatic to use `when` if there is no alternate.
15:22hyPiRionmehwork: There's no "when"-over-"if" rule, if that's what you're asking
15:22dnolenbbloom: heh, I don't see that happening. But certainly I think having logic programming available makes it easier to understand model what type systems can do.
15:22hyPiRionBut it explicitly tells the reader that there's no else-part here
15:22mehworkok
15:22amalloyhyPiRion: well, more like there's two conflicting when/if rules
15:23ivaraasenI mostly use "when" when the else clause would just return nil
15:23bbloomdnolen: i could see type systems being expressed in terms of extensible logic programs
15:23bbloomdnolen: i'm nto saying types go away, i'm saying that logic programming becomes the underlying mechanism by which types are more useful and less restrictive
15:23hyPiRionamalloy: conflicting?
15:23hyPiRionwat
15:24hyPiRionteach me, amalloy.
15:24SegFaultAXmehwork: One word of caution (and this is mostly personal choice), don't use else with if-not. Negating a negation can be quite confusing.
15:24amalloyhyPiRion: most people's style is to use 'when wherever possible, such that 'if implies there's two clauses; if you see an 'if with only one clause from such a programmer, it indicates a mistake
15:24dnolenbbloom: perhaps, tho typed logic programming is a thing - see Mercury.
15:25amalloya non-trivial minority use 'when only if there are side effects; thus the presence of a 'when helps notice the trickier spots with mutation
15:26SegFaultAXamalloy: That usage of when hadn't occured to me, but thinking back I've definitely seen code that used a convention similar to what you just described.
15:26bbloomdnolen: will look at it
15:27amalloySegFaultAX: technomancy is the most vocal about preferring that style, if you want to ask him about it
15:27hyPiRionWell, I'm in some middle spot then. I excplicitly expand (if test res) to (if test res nil) and use when pretty seldom. Probably when I need mutation.
15:27ivaraasendnolen: seen this paper? not sure if all of it would translate to core.logic, but it's a pretty neat example of applied Prolog. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.52.5750
15:27bbloomdnolen: my interest in all this stuff is purely intellectual entertainment at the point in time
15:28brehautamalloy: now i want 'when!
15:28clojurebotamalloy: therfor I return [previous] if rest is empty
15:28SegFaultAXbrehaut: What would the bang signify?
15:28amalloyreally, clojurebot? really? what do i have to unlearn you to avoid these echos from my past?
15:29amalloyclojurebot: forget amalloy: therfor I return [previous] if rest |is| empty
15:29clojurebotI forgot that amalloy: therfor I return [previous] if rest is empty
15:29brehautSegFaultAX: that its for doing side effecting operations that are unsafe within a transaction, just like it always does
15:29brehautit would probably be worth making 'when! wrap 'when in 'io!
15:30dnolenivaraasen: WOW that looks awesome. Yes using core.logic to generate Clojure programs is definitely a goal, not sure how easy it would be translate that. Someone should try :)
15:30dnolenbbloom: it is very intellectually entertaining :) tho it's been exciting to see people put this logic stuff into production.
15:31SegFaultAXdnolen: I watched a talk about miniKanren where they procedurally generated all the scheme programs that evaluated to 6. That was pretty neat.
15:31dnolenSegFaultAX: yeah that's a great talk, the relational interpreters are neat.
15:31ivaraasenSegFaultAX: that sounds awesome. any recordings of the talk?
15:31SegFaultAXivaraasen: Yes, let me find it.
15:32dnolenSegFaultAX: it's pretty easy to port that stuff to core.logic now Nada Amin has already done the quine generator.
15:32brehaut(defmacro when! [test & body] (list 'io! (list* when test body)))
15:32SegFaultAXivaraasen: http://blip.tv/clojure/dan-friedman-and-william-byrd-minikanren-5936333
15:33ivaraasenSegFaultAX: thanks
15:34SegFaultAXbrehaut: I didn't even know io! was a thing til just now. Thanks for that.
15:34SegFaultAXivaraasen: No problem! :)
15:35SegFaultAXdnolen: I hadn't heard about that! Source?
15:35TimMcbrehaut: Alternatively, (defmacro when! [test & body] `(when ~test (io! nil ~@body)))
15:35luckyhi
15:36dnolenSegFaultAX: http://github.com/namin/TAPL-in-miniKanren-cKanren-core.logic/blob/master/clojure-tapl/tapl/src/tapl/quines.clj
15:36brehautSegFaultAX: incidentally, compare 'swap! (for atoms) to 'send (for actors) for the semantic differences of bang names: send is safe in transactions because its held till the transaction succeeds, whereas atoms always swap
15:36TimMc(move the io! inside)
15:36brehautTimMc: i wondered about that too. im not sure about more precise warning vs consistently warning
15:36TimMcAlso note the nil.
15:37SegFaultAXbrehaut: Could you clairfy held till the transaction succeeds? Does that mean that it won't actually send until it's comitted by the STM?
15:37TimMcio! takes an optional first string arg...
15:37brehautSegFaultAX: yes
15:37brehautTimMc: oh really. huh
15:37amalloyTimMc: `(io (do ~@body)) seems more legible to me
15:39SegFaultAXamalloy: But that also prevents you from using a custom error message, no?
15:39amalloyso does his putting the nil in
15:39SegFaultAXOh, true.
15:40SegFaultAXamalloy: Is there any cost to having a redundant do block?
15:40amalloyno
15:41ivanIDEA costs less than Sublime Text today
15:41amalloyand it wouldn't matter if there were, because i'll bet you a dollar (io! nil a b c) expands to (io! nil (do a b c)) anyway
15:41SegFaultAXdnolen: I don't think I'm quite far enough long in my core.logic understanding to absorb this yet. But it is quite short and elegant _looking_.
15:42SegFaultAXamalloy: That's why I asked if it incurred any cost since yours would expand to (io! nil (do (do a b c)))
15:42dnolenSegFaultAX: heh yeah, it'll make sense in good time
15:42amalloywell, i suppose that's true, it probably does. doesn't cost anything though; it's just as expensive as a {} in a C language
15:45amalloyi prefix all my macros with `(do (do (do (do ~@whatever)))) because i want the user's code to sound like it's humming
15:45TimMc:-D
15:46brehaut(do (do (do (do (repeat "yeah")))) ← nirvana song
15:46zerokarmaleft`(do (do (do (do (do (do (do (do ,@menamena))))))))
15:46winklol
15:46TimMcdamn you
15:46dnolen,'(foo ~x ~@y)
15:46clojurebot(foo (clojure.core/unquote x) (clojure.core/unquote-splicing y))
15:46zerokarmaleftoops, semi-schemified that
15:48amalloyzerokarmaleft: good thing you didn't totally schemify it. it doesn't work nearly as well with (begin (begin (begin ...)))
15:53ivaraasenSegFaultAX: my jaw dropped when I saw the generated code. so cool
15:54bbloombut did they ever get 120 to produce 5! ? :-)
15:55SegFaultAXivaraasen: Tell me about it :)
15:59hyPiRionivaraasen: yeah, it's pretty awesome.
15:59dnolenbbloom: I believe one of their students might have
15:59bbloomdnolen: bad ass.
16:00bbloomhow long before rich can write down a slide deck and generate datomic? :-)
16:00dnolenbbloom: haha, it really only works for very simple languages - things bog down when you add too many features
16:00bbloomdnolen: of course, extreme combinatorial explosion
16:01hyPiRiondnolen: Are you telling us Clojure is not simple!?!?
16:01hyPiRion;)
16:01dnolenhyPiRion: :)
16:02hyPiRionMr. Hickey has been lying to us the whole time, then.
16:02dnolenhyPiRion: heh "toy" or "model" language may be a better choice of words.
16:02hyPiRiondnolen: I know what you meant :p
16:02bbloomdnolen: in an entertainingly abstract philosophical sense, all programming is a search problem: you're looking in the infinite sequence of 0s and 1s for the program that does what you want. but that would take infinite time, so you need to employ some novel ideas to reducing that search space. i could imagine if you started encoding those ideas into your distribution strategy, you could solve more and more difficult logic problems
16:03egghead~search and constraint~
16:03clojurebotI forgot that ~paste is forget ~paste
16:03TimMc~botsmack
16:03clojurebotclojurebot evades successfully!
16:03dnolenbbloom: yeah, Will used some called condp where you could weight different language forms to eliminate unlikely programs
16:03dnolenat the Conj
16:03bbloomdnolen: yeah, something like that
16:04bbloomdnolen: would be interesting to also describe things like structural recursion, such that logic programs could try to solve "what's the base case? what's the reductive step?" to generate a recursive algorithm
16:04bbloomdnolen: expressing those novel ideas is challenging, for sure
16:05TimMcNovel ideas? They were probably codified in the 70s. :-P
16:05bbloomTimMc: i mean novel in the sense that they are worth remembering
16:09ivaraasenbbloom: my dream would be to have a parser do amortized analysis of an algorithm, rewrite it and generate a complementary data structure as well, i. e. a monoid for a finger tree. but that would probably be insanely difficult to do correctly
16:09hyPiRionOh, the sufficiently smart compiler.
16:10Raynesweavejester: Are you going to put out a new version of codox?
16:11mehworkin a .clj file how do you go about a global/reusable var?
16:14TimMcmehwork: What do you mean by a global var?
16:15ivaraasenhyPiRion: do you know any NTNU faculty members that are enthusiastic about FP/logic?
16:15mehworkah def alone does it within the namespae it seems. Does order matter? eg do you have to declare the var at the top before you can use it
16:15TimMcmehwork: Vars are declare-before-use, yes.
16:15mehworkTimMc: just something i can def at the top of the file and then reuse it in diff methods in defn's
16:16TimMcSure, you could (def foo (atom 5)) and then later refer to foo.
16:16mehworkwhen you declare a ns at the top of a file clojure automatically applies it to just that entire file
16:18mehworkTimMc: why an atom instead of just (def foo 5)?
16:19TimMcmehwork: Just an example.
16:20mehworkthink i need a good book on clojure. piecing it together over google and irc is kinda hard
16:21S11001001mehwork: check the clojure mailing lists; several book discussions have occurred
16:27hyPiRionivaraasen: About logic, I'm not 100% sure. We had Tore Amble, but he died (:'( ) in January this year. Keith Downing is the only FP-guy I know of
16:28hyPiRionWe're an endangered species up here, it seems.
16:28ivaraasentoo bad
16:28ivaraasenPVV had a Clojure course though, right?
16:29mehworkdo lispers believe in reincarnation or just recursion
16:30ivaraasenmehwork: they believe in a higher order at least.
16:30mehwork:)
16:30mehworkand parallel dimensions
16:31mehworkhopefully in at least one of them i'm not a noob right now
16:31gtrakdo you guys ever feel like you want a null-object?
16:31hyPiRionivaraasen: No, NVG had. I remember since I held it :p
16:32gtrakor some kind of way to specify and propagate contracts up a function stack? (checked exceptions.. shudder)
16:34hyPiRiongtrak: null-object?
16:34gtrakrecursive docstrings...
16:34hyPiRionI'm pretty happy with nil.
16:34hyPiRion,(class nil)
16:34clojurebotnil
16:34gtrakhyPiRion: yea, it's not the nil that bothers me so much, it's the (if ..)
16:35gtrakwe use it for convenience, if-let, but it's not always obvious what it signifies
16:36gtrakabout 3 functions deep and it gets confusing... something needs to return a value
16:37m0smithrhc app start -a jbossas-7
16:37m0smithApplication jbossas-7 does not exist
16:37gtraknullity-overloading is obfuscating... I guess is what I mean.
16:40hyPiRionwhut
16:41hyPiRionAn element is truthy if it's not nil or false.
16:41hyPiRion(Except (Boolean. false))
16:42gtrakhyPiRion: I mean for example... say you have a database... (store/delete ... returns the entity or nil if it doesn't exist)... somewhere up the stack you can rely on this and use an if-let
16:42gtrakif there's too many steps in between the behavior and the branching... it's confusing
16:43gtrakI don't want to make all my functions polymorphic, because that's called java :-)...
16:44mattmosssomething like -?>
16:44gtrakI wonder if there's a better way to think about it
16:44hyPiRionSo it's the nil-punning you don't like?
16:44gtrakyea
16:45gtrakand the fact that it's so darn convenient :-)
16:45hyPiRionIt's a design decision with pros and cons
16:46gtrakah, yea, I'm not criticizing the feature, but rather looking for an alternative
16:47hyPiRionoh, right. check out the -?> as mattmoss mentioned
16:47hyPiRionit will short-circuit when nil is given as a result in the pipeline
16:48gtrakright :-).. I suppose that makes nil-punning more evident
16:48hyPiRionYou could also return a keyword instead if that makes sense
16:48hyPiRion:not-found for your database-example
16:49hyPiRionThough that depends on whether the object can be :not-found, of course.
16:49gtrakright, or exceptions.. it's an interesting lib-design problem
16:49weavejesterRaynes: Codox 0.6.4 released
16:49Raynesweavejester: You're a good guy.
16:49Raynesweavejester: Hope you feel better. :)
16:50arrdem,(inc weavejester)
16:50clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: weavejester in this context, compiling:(NO_SOURCE_PATH:0)>
16:50arrdem(inc weavejester)
16:50lazybot⇒ 6
16:50arrdemhur dur been a while
16:50clojure-newbcemerick: Hi, just trying to connect to your mock friend app with basic auth via curl…. but I'm getting stuck… getting a 404 atm, should be possible shouldn't it ?
16:50weavejesterRaynes: I made the mistake of going to work a little too soon, so I felt absolutely terrible on Wednesday, but a little better now :)
16:53janusmcintyreIs there a more idiomatic way to do something like https://www.refheap.com/paste/7763 ?
16:54janusmcintyreI want to resolve the namespace + function from a string at runtime.
16:57hyPiRion,(-> "clojure.pprint/cl-format" read-string resolve meta :ns)
16:57clojurebot#<Namespace clojure.pprint>
16:57hyPiRion,(-> "clojure.core/read" read-string resolve meta :ns)
16:57clojurebot#<Namespace clojure.core>
16:58hyPiRionDon't know if that's better though
16:58janusmcintyrehyPiRion nice
16:58janusmcintyre,(-> "clojure.core/read" read-string resolve meta :ns)
16:58clojurebot#<Namespace clojure.core>
16:58janusmcintyre,(-> "foo.bar/read" read-string resolve meta :ns)
16:58clojurebotnil
16:59hyPiRionIt'll resolve names available in the current namespace, so I'm not sure if it's good.
16:59hyPiRion,(-> "clojure.set/union" read-string resolve meta :ns)
16:59clojurebotnil
16:59hyPiRion,(require '[clojure.set :as set])
16:59clojurebotnil
16:59hyPiRion,(-> "clojure.set/union" read-string resolve meta :ns)
16:59clojurebot#<Namespace clojure.set>
17:02janusmcintyrehyPiRion it doesn't resolve namespaces that are not in the current namespace
17:03hyPiRionyeah, I figured as much
17:04meliponehiya!
17:04meliponehow do I get all the values of an assoc list? I knew how to do that and I forgot
17:04cemerickclojure-newb: definitely; but, instead of looking at mock_app.clj (which I only wrote for testing, really), go check out https://friend-demo.herokuapp.com/
17:05justin`melipone: vals
17:05cemerickthe sample apps there are very minimal, and should be easy to copy, paste, and run with
17:05meliponejustin`: thnaks
17:05cemerickFWIW, I'm not spreading that URL around yet; I want to have ~10 example apps ready, and it needs to not look like trash.
17:06cemerickclojure-newb: ^^
17:06janusmcintyrehyPiRion I guess that code is not that bad then.
17:08hyPiRionjanusmcintyre: I've not fiddled too much with ns and resolving vars in code, so I'm not the guy you should ask ;)
17:09hyPiRionIt's not looking bad though, if that's what you're asking.
17:10janusmcintyrehyPiRion Thanks anyways. I searched around Github for something similar, but found nothing. If this is too hackish, I guess I'll find out soon enough
17:10clojure-newbcemerick: thanks… must have missed that
17:10yediis there like a protocol or spec or format or something that can be used for storing/sending boolean rules (combinations of logical statements)
17:10cemerickdidn't miss anything; I've not linked it anywhere yet
17:14clojure-newbcemerick: thanks for the pointer
17:24meliponequit
17:40Thad_"Victim's rights group" ,<-- want to see if this str contains the values "rights" OR "group"
17:42callenThad_: http://clojure.org/other_functions#Other%20Useful%20Functions%20and%20Macros-Regex%20Support ?
17:42callenThad_: just do an (or ...) of two presence-checking regexes?
17:43pendlepa1tsor use the regex #"(rights|group)"
17:44callenpendlepants: I was trying to make it composable and able to treat as a list or something rather than a single block of regex.
17:44callenpendlepants: so that if it needs to be dynamically changed at runtime it doesn't lead to some kind of stygian horror.
17:49hyPiRion,(some #(.contains "victim's rights group" %) ["rights" "group"])
17:49clojurebottrue
17:50hyPiRion,(some #(.contains "not in this one!" %) ["rights" "group"])
17:50clojurebotnil
17:52Thad_hyPiRion: perfect.. just use Java's .contain .. right ??
17:52lazybotThad_: What are you, crazy? Of course not!
17:52hyPiRionThad_: yes, it's not harder :)
17:53hyPiRionhey lazybot, you're talkactive today eh
17:53hyPiRion$findfn [1 2] 2
17:54lazybot[clojure.core/second clojure.core/last clojure.core/count clojure.core/peek clojure.core/fnext clojure.core/rand-nth]
17:56borkdudefunny that rand-nth comes up
17:57borkdude$findfn [1 2] 2
17:57lazybot[clojure.core/second clojure.core/last clojure.core/count clojure.core/peek clojure.core/fnext clojure.core/rand-nth]
17:57borkdude$findfn [1 2] 2
17:57lazybot[clojure.core/second clojure.core/last clojure.core/count clojure.core/peek clojure.core/fnext clojure.core/rand-nth]
17:57borkdude(rand-nth [1 2])
17:57borkdude,(rand-nth [1 2])
17:57clojurebot2
17:57callen,(rand-nth [1 2])
17:57clojurebot1
17:58borkdudeI would expect findfn sometimes not to list it, other times it would
17:58aperiodic$findfn [1 2 3 4 5 6 7 8 9] 9
17:58lazybot[clojure.core/last clojure.core/count clojure.core/peek]
17:58borkdude$findfn [1 2] 2
17:58lazybot[clojure.core/second clojure.core/last clojure.core/count clojure.core/peek clojure.core/fnext]
17:59borkdudeah there it is('nt) ;)
17:59justin`jackpot
18:01Thad_hyPiRion: This channel has a REPL ???
18:01lazybotThad_: Yes, 100% for sure.
18:01Thad_cool
18:03aperiodic~botsnack
18:03clojurebotbotsnack is scoobysnack
18:04aperiodicclojurebot: forget botsnack |is| scoobysnack
18:04clojurebotI forgot that botsnack is scoobysnack
18:04aperiodic~botsnack
18:04clojurebotThanks, but I prefer chocolate
18:05aperiodicseems odd that inferences trump commands
18:06technomancyodd is what clojurebot does best
18:06amalloyaperiodic: botsnack isn't a command either
18:06callen$botsnack
18:06lazybotcallen: Thanks! Om nom nom!!
18:08borkdude$inventory
18:08amalloyit's just a thing someone taught him a fixed reply to, a while ago
18:08hyPiRion$findfn [1 2] 2 2 2
18:08callenamalloy: don't demystify it.
18:08lazybot[clojure.core/if-not clojure.core/dosync clojure.core/sync clojure.core/condp clojure.core/nth clojure.core/get clojure.core/and clojure.core/locking clojure.core/io! clojure.core/when]
18:09aperiodicamalloy: oh, i see. that's less odd, then
18:09hyPiRioncurious thing, this guy. I asked for fns, but got more or less just macros.
18:10callen$findfn [0 1] 1
18:11lazybot[clojure.core/second clojure.core/last clojure.core/peek clojure.core/fnext]
18:11callenk, so I'm not insane.
18:11callenwell I am, but not about that.
18:11amalloyfnext. if there's any function we don't need in clojure.core, that's gotta be it
18:12borkdude,(doc fnext)
18:12clojurebot"([x]); Same as (first (next x))"
18:12callenLOL
18:13callenamalloy: at least it's not (caadddddr ...)
18:13callenamalloy: I actually figured it was people like you that enjoyed having fnext in core.
18:13callenamalloy: so you could golf harder on 4clojure.
18:13amalloyfnext instead of second? no thanks
18:14callensaves one character though!
18:14amalloycallen: have you looked at https://groups.google.com/group/clojure/msg/0dfda3a9360cbc4b ? it's a cute cadar-thing
18:14hyPiRionI could swear that was the docstring for second
18:15hyPiRion,(doc second)
18:15clojurebot"([x]); Same as (first (next x))"
18:15hyPiRionOh, I see.
18:15amalloysomewhere i have a version with fewer bugs, but the broken version is just as entertaining
18:15Thad_Should I get an array / list when returned for this: (re-find #"rights|group" "Victims' rights group") ???
18:15lazybotThad_: How could that be wrong?
18:15callenamalloy: that tickles my black little ex-CL'er using soul.
18:16callen[cadr "1.0.2-SNAPSHOT"] <--- totally worth the bytes added to the jar.
18:17amalloythat implementation makes me so sad
18:18callenamalloy: did you use CL?
18:18amalloyfor about a month
18:18callenbecause I have to say, that pretty well numbed me off to "bad libraries"
18:18callenoh, it was my first real language
18:18callenafter GW-BASIC and C.
18:18callenI just kinda assumed after CL that most communities had god-awful libraries like that.
18:18callenthen I learned C# and Python. That was a bit of a shock.
18:26callenare async/await in C# analogous to futures and promises in Clojure?
18:28callenI guess they aren't.
18:28callensolves a similar problem though.
18:29brehautcallen: promise / future concepts are analagous to the primatives await/async in .net are built on i believe
18:29brehautcallan: the API differs though
18:30brehautcallen: i imagine that with (protocol) monads you could produce something very similar though
18:32callenbrehaut: well await is really just "dereference this promise and wait please.", right?
18:32callenor future, I guess.
18:32callennot promise. Sigh, sorry for bad clarity.
18:32callenbrehaut: I decided to go with Hiccup btw, for templating.
18:32callenso *raspberries*
18:33callenmain reason is that frontend guy wants to learn clojurescript anyway. Thinks hiccup would be a good way to force him to sink-or-swim with Clojure. Wouldn't normally be viable and definitely couldn't get away with it at the day job.
18:33brehautcallen: right. i think thats pretty much it. implementing and return bind on futures (or promises) lets you have nice syntax though
18:34callenbrehaut: to be fair, with C#, if you don't make it very obvious, the community won't know how to use it.
18:34callenbrehaut: I think that's partly why they made F#, to differentiate the community a bit and give them a good test bed for features for C#.
18:35brehautcallen: for reference, F# implements a comptuation expression over its primative values to do just that (computation expression ~= monads/do notation)
18:43callenbrehaut: I've always like F#'s balance of strict/lazy semantics
18:43callenit's a pity the Haskell people used their language as a test-bed for lazy semantics.
18:50mehworkis there a way using lein to make it so m clojure app is self executable, e.g., my if my project's name is 'foo' to be able to just invoke it with ./foo rather than java foo.jar
18:51AimHereThat introduces platform dependencies straight off, and loses you one of the reasons you're using the JVM in the first place, I'd have thought
18:54technomancymehwork: there's a lein-bin plugin that sorta does that; not sure if it's been maintained
18:54gtrakmehwork: there's existing solutions to turn jars into executables, by bundling a jvm
18:55mehworkok so it's bsaically acceptible to distrubute my app and have my users type 'java bla.jar'?
18:55znDuffmehwork, java -jar bla.jar is the usual thing, yes.
18:55znDuffmehwork, ...many operating systems will also let users directly run jars as executables, btw
18:55znDuffmehwork, ...including Linux, using the binfmt_misc kernel extension.
19:06Bergle_1ooh nice personal licenses 75% off jetbrains (intellij + others) http://www.jetbrains.com/specials/index.jsp
19:07mehworkend of the world sale lol
19:08mehwork(thanks technomancy gtrak znDuff)
19:08hyPiRionI've heard GNU is doing the same. They reduced their prices on emacs by 100% today
19:08gtrak100% less freedom?
19:08gtrakwhere do I sign up?
19:08mehworki heard they were doing the opposite: for the end of the world they were making proprietary code
19:10mehworkfree as in north korea
19:10znDuffIs the JetBrains site actually usable now?
19:10znDuffI tried buying an upgrade earlier today, and it was completely swamped.
19:11ivaraasenwho needs JetBrains when you have ed?
19:11ivanyou can buy but you don't get a license immediately
19:11mehworkidk, the idea of a sale on software feels like an abusive spouse who promises to only hit you once because it's valentines day. Still not excited
19:12mehworki've been using vim without any clojure plugins. It's been painfulish
19:12znDuff...yes, that would.
19:13mehworkbut i'm just learning the basis of the lang still, not working on a large project
19:13znDuffI can't do Clojure without paredit.
19:13ivaraasenIDEA does look very nice
19:14n_bIDEA is great for Java, could not make me dump vim for anything else
19:14hyPiRionSo it's worth buying even though you're not programming Java frequently?
19:14gtrakthe problem with me buying IDEA is it assumes I will have to use enough java some day to need it :-(
19:14gtrakit's depressing
19:14Bergle_1i can drive emacs a bit, im good with vim, but i am spending more time in emacs for paredit :) even though i dont like emacs much - maybe ill get use to it
19:15Bergle_1ive done a fair bit of javascript and webstorm or any of the ide's is great for javascript with refactoring.
19:19n_bBergle_1: tried paredit.vim?
19:21Bergle_1no havnt.
19:22RaynesBergle_1: I use Emacs with evil-mode.
19:22RaynesI enjoy it very much
19:23Bergle_1im plodding away with emacs-live, which i realise is lots more than just paredit, but some bits seem amazing
19:23RaynesNote that I was an Emacs user that tried Vim and then went back to Emacs and started using evil-mode. I don't use it because I have an attachment to vim keybindings, I use it because I like modal editing and thing it is a good fit in Emacs.
19:23ivannon-modal editing makes me corrupt something in my .org files every few hours
19:27hyPiRionUh, is there any specific reason why numerator and denominator throws exception when given integers?
19:28hyPiRionIt's okay that they call a method on a Ratio, but couldn't one make a protocol on top of it instead?
19:29bbloomhyPiRion: seems reasonable for those methods to be polymorphic. it might just be a case of evolution, an accident of history
19:29seangroveIs there a way to list keys for watchers given a ref?
19:30bbloomhyPiRion: did you search the mailing list? you may want to start a thread and or submit a patch
19:30seangroveref/atom/whatever was passed into (add-watch ...)
19:30hyPiRionbbloom: No, I'll do that later on
19:30amalloythe code in Numbers.java can't use protocols
19:30bbloomseangrove: not that i know of
19:30mehworkthere's no clojure convention for global variables?
19:31bbloomhyPiRion: that's the accident of history that amalloy is referring to: clojurescript is able to use protocols throughout, but jvm clojure can't for many things
19:31mehworklike all caps or an underscore prefix, etc?
19:31bbloommehwork: nope, because there are no global variables, all top level vars are always namespaced
19:31seangroveearmuffs?
19:31bbloomseangrove: earmuffs are for dynamic variables
19:31hyPiRionbbloom amalloy alright, thanks for input
19:32hyPiRion,(doseq [p '[bbloom amalloy]] (prn (list 'inc p)))
19:32clojurebot(inc bbloom)
19:32lazybot⇒ 3
19:32clojurebot(inc amalloy)
19:32lazybot⇒ 36
19:33amalloyseangrove: ##(.getWatches (atom nil))
19:33lazybot⇒ {}
19:33bbloomah amalloy didn't know that was there
19:33amalloynor did i
19:34mehworkbbloom: i'm having a hard time knowing when to create a top-level var and a local one that i pass around
19:34seangroveIs ## a lazybot prefix?
19:34hyPiRionseangrove: yup
19:34mehworkseangrove: yeah
19:35seangroveOk, phew
19:35mehworkas is ,
19:35hyPiRionmehwork: that's clojurebot, slight differences.
19:35bbloommehwork: use a local whenever the value is only relevant in one spot
19:35hyPiRionBut basically, yeah
19:35seangrovehrm, maybe .getWatches isn't in cljs?
19:35bbloommehwork: use a top level whenever you want to use something throughout a namespace or between namespaces
19:35bbloomseangrove: in cljs you can just #(.-watches %) probably, but it's an implementation detail
19:36seangroveOk, I'll take a look at it then, thanks
19:36mehworkbbloom: well my problem is diff than that. It's more to do with 'config' variables. I guess they should go at the top so they're easier to spot
19:36bbloommehwork: ah yeah, so config variables are labeled ^:dynamic and often (but not always) annotated with "earmuffs"
19:37bbloom(def ^:dynamic *config* {:foo "default"})
19:37mehwork:o
19:37bbloomthen you can use (binding [*config* {:foo "omg"}] ...) to temporarily override those values
19:37mehworkgood to know thanks
19:37bbloom(doc binding)
19:37clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
19:37bbloombut generally, top levels are good for config, functions, constants, etc
19:42juliendddHi all, new to Clojure here. I've played with TryClojure and it's been great. What's the next thing to get started ?
19:42juliendddI'm mostly interested in web app development, but I need more practice with the syntax, etc before jumping in
19:42SegFaultAXjulienddd: Perhaps a book? I suggest Joy of Clojure or Clojure Programming.
19:43juliendddanything free and online ?
19:43mehworkbbloom: well when would i want to use that config binding over a normal top level for a config value?
19:44dhmjulienddd: i think clojure programming is a better book when you're starting out
19:44hyPiRionjulienddd: Is the syntax, the concepts or both new to you?
19:44brehautjulienddd: if you know about functions and maps you are about ready to start mucking about with web stuff (ring)
19:44bbloommehwork: so each var has what's known as a "root binding" which is the top level default value
19:44juliendddbrehaut: Both, I'm a java/c guy
19:44dhmjulienddd: yeah i recommend ring too. the examples are pretty small and self-contained
19:45bbloommehwork: you can override it on a per-thread basis using binding, so you'd want that if you're going to have multiple clients of your API that need their own config. for example *current-user* or something like that
19:45mehworkok
19:45SegFaultAXjulienddd: Then I doubly suggest picking up a book. There are loads of new concepts that you'll be learning along the way and it would be good to have a guided tour.
19:46hyPiRionjulienddd: For syntax and learning about functions, the webpage http://www.4clojure.com/ is great
19:46bbloommehwork: you can also use a top level var like a mutable storage, but it's better to stick an atom into that var, and then mutate the atom... this way you can pass around a pointer to the atom and use it's compare & swap semantics
19:46bbloomvars are primarily only mutable for interactive development
19:46cemerickdhm: You can find a ToC and such for the O'Reilly book @ http://clojurebook.com
19:47juliendddThanks everyone
19:47SegFaultAXjulienddd: See cemerick's note.
19:47hyPiRionjulienddd: But as other say, I'd recommend finding some book. If not, then http://java.ociweb.com/mark/clojure/article.html may or may not be of help
19:47dhmjulienddd: yeah, see chapter 9 of cemerick's book. they have a bunch of java interop stuff there that might be fun to play with as a java person
19:47dhmcemerick: thanks
19:48hyPiRionI've seen it pop up time to time, but I haven't read it myself.
19:53nightfly_Practical Clojure was a good introduction for me after I had a few months experience with Common Lisp
19:54seangroveFor those familiar with the google closure/cljs compiler output, I'm trying to track down the source of an implementation of a protocol in the chrome web console
19:55seangroveWhen a function/closure is lifted out of another function and turned into a delegate, where can I find the source for that function?
19:56mrowesorry if this is a faq, but I've had no luck finding anything... I am getting ClassCastExceptions in clojure.lang.Reflector/invokeInstanceMethod when passing an int (e.g. 1) to a method that expects an Integer. I kind of hoped autoboxing would happen somewhere... do I have to do it manually?
19:56seangroveFor example, any function that takes variable arguments will call __some_other_function at the end, but I'm not sure where __some_other_function is stored
19:57amalloymrowe: boxing is not the problem; somethine else is but we can't tell from your description
19:57mroweamalloy: ok. what more info do you need?
19:58amalloywell, some actual code. so far i have "i pass an integer to a method expecting an integer, but it doesn't work"
19:58bbloomseangrove: a good trick is to stick a # in front of a form and paste it into the rhino repl
19:58bbloomseangrove: that echos a pretty printed bit of java code
19:58mroweamalloy: :) what is the preferred pastebin again?
19:58hyPiRionrefheap
19:58amalloyanything is fine. refheap or gist
19:58amalloyznDuff will complain if you use pastebin
19:59mrowehttps://www.refheap.com/paste/7768
20:00mroweif I call it with an object that has a method setMaxCount(Integer count) and a params map { :max-count 1 } it fails, but { :max-count (Integer. 1) } works
20:00amalloy&(class 1)
20:00lazybot⇒ java.lang.Long
20:00bbloomRaynes will complain if you don't use refheap
20:00mroweamalloy: ah
20:01amalloyit would work if the method took int rather than Integer, i think
20:01mroweyeah
20:01amalloythe compiler does that downcast for you
20:01mroweI think that's why it's worked for me before, but is tripping up now
20:01mroweamalloy: cheers
20:09seangrovebbloom: Do you primarily use the rhino for your cljs repl env?
20:09bbloomseangrove: no, rhino is slow as hell. it's just convenient to run ./script/repljs to get a rhino repl
20:09seangroveHeh, thought so
20:12technomancyoh dear
20:12technomancyoh dear oh dear
20:12technomancy" hasattr(object, name) The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)"
20:12seangroveDamn, it seems like Shoreleave just stopped adding atom watchers...
20:12technomancyhttp://docs.python.org/2/library/functions.html#hasattr
20:12brehauttechnomancy: im sorry to hear
20:12callentechnomancy: what's wrong?
20:12technomancycallen: the last sentence?
20:13callentechnomancy: Python?
20:13technomancybrehaut: makes clojure.core/contains? look positively well-adjusted
20:13technomancycallen: yeah
20:13callentechnomancy: Python is my day job, so I can sympathize.
20:13brehauttechnomancy: amazingly thats the most sane way to do it due ti the amount of 'magic happens' in object member lookups
20:13callentechnomancy: Python is resents what I subject it to. Like 6 call-deep pipes of map/lambda/filter/reduce
20:13callenPython resents*
20:14brehauttechnomancy: absolutely
20:14callenbrehaut: oddly, if getattr(obj, "field", False): hasn't burnt me yet.
20:14brehautcallen: because it does all that magic for you.
20:14callenbrehaut: most Pythonistas have enough taste not to abuse method_missing-esque DSLs like Ruby.
20:14callenI had an epiphany earlier today about Ruby and Python, actually.
20:15callenI realized Python had more function-oriented than class-oriented APIs than Ruby because Ruby doesn't have real namespacing.
20:15callenfor some reason, this hadn't occurred to me before.
20:15bbloomPython seems to not worry about using exceptions for control flow
20:15bbloomit's part of the iterator protocol!
20:15tpopecallen this recently dawned on me as well
20:15bbloomStopIterationExcepetion
20:15brehautbbloom: death to iter
20:15callenbbloom: slingshot?
20:15callentpope: it makes me happy to know this wasn't 100% obvious to everyone else.
20:16callentpope: it seriously explains a lot though.
20:16TimMcbbloom: Maybe that's where prototype.js picked that up from.
20:16tpopeI guess I've never seriously worked in a language with real namespaces before
20:16callenI *hate* class-based APIs.
20:16callenthey always end up abusing some stupid stateful series of instantiated class-scope data to make it work.
20:16bbloomtpope: it's actually a big deal. i've been considering writing a blog post about the importance of actual namespaces
20:16callenbbloom: you should tell the C people about it, see what they think. :P
20:16bbloomi was considering an inflamatory hacker news bait title like: "The Node.js REPL is Broken"
20:16bbloom:-P
20:17tpopeit's growing on me
20:17callenbbloom: I knew namespaces were a big deal, what I hadn't done was connect that to why Python users use more functions and Ruby people use more classes for exposing functionality.
20:17bbloomcallen: yeah, it makes sense
20:17callenFQNS 4life.
20:17seangrovecallen: Maybe
20:17bbloomcallen: but even python suffers from a dynamism fail with namespaces
20:18technomancycallen: modules work great in Ruby for namespacing, but for some reason people prefer classes. I don't understand it at all.
20:18callenbbloom: erm, yeah, I'm guilty of a few things there.
20:18seangroveMix-ins are kind of an interesting patch to get class-based things to look more like function-based things
20:18bbloomif you do `from foo import bar` and then re-def bar in foo, the previously imported name is not modified
20:18callentechnomancy: you can't be trusted, you work for sie enemy.
20:18bbloomhence you see advice to `import foo.bar as bar`
20:18callenseangrove: the mix-ins vs. MI thing is a total canard.
20:18seangroveMI?
20:18clojurebotNakatomi space is http://bldgblog.blogspot.com/2010/01/nakatomi-space.html
20:18callenseangrove: most Python multiple-inheritance gets used like Ruby mixins.
20:18callenthere's very little difference.
20:18tpopeyeah you can't do the selective import thing in ruby
20:19callenbeyond the fact that Python gives you a little more power.
20:19seangroveAh, I wasn't thinking of inheritance
20:19bbloomthere's also a few decent traits based libraries for python
20:19tpopeand there's no real replacement for refer
20:19bbloomwhich are slightly less shitty than mixins and multiple inheritence
20:19callenmost Ruby code I've seen is require "blah" -> BOOM GOES THE REFERENCES
20:19callen(enjoy yer monkeypatchin')
20:19bbloomdef Module.const_missing
20:19bbloom*cringe*
20:19callenI've never seen anything approaching sensible namespacing in Ruby.
20:20tpopeimagine if you had to call Clojure::String.join each time
20:20callenbbloom: ick.
20:20callenanother thing I noticed about classes/objects is that the composability and dimensionality is annoying
20:20bbloomUserPreferences -> const_missing -> user_preferences -> 'models/user_preferences.rb' -> require -> "oh that was cool" -> THE HORROR
20:20callenwhen you use very method-centric APIs you're basically forced to treat every single piece of code like a special snowflake
20:21calleninstead of as being a generic sequence, IFn, etc.
20:21bbloomcallen: or abuse send :-)
20:21callenI originally came to Clojure thinking it would fix everything I didn't like in CL. Realistically, it fixed what I didn't like about Python and Ruby.
20:21bbloomi've been guilty of writing modules with functions like frob_foo and frob_bar and then doing send("frob_#{thing.class.name.underscore}")
20:22bbloomit's sorta like multimethods :-P
20:22callenbbloom: that is *unholy*
20:22seangroveDynamic!
20:22bbloomwhen you don't want to make a class for every enum in your database, it's quite reasonable heh
20:23callenbbloom: no I understand it, I've had to do some evil stuff in Python as well. I just resent being forced to do so.
20:23bbloomagreed
20:23callenbbloom: most Python meta-programming for me involves getattr, setattr.
20:23callenbecause it works against classes, modules, etc.
20:23callenso I can dynamically snag database models by stringly name, etc.
20:23callengetattr(models, "User
20:23callen", None)
20:23callenthen I'll usually wrap up the None/Option/MaybeMonad stuff with a bind wrapper
20:23callenbecause I hate if-checking None.
20:23brehautclass Foo(call_to_class_generater("blah")):…
20:24brehautmy least favorite python dynamism trick ever
20:24callenbrehaut: I try to avoid piercing the veil between runtime and compile-time in Python and Ruby.
20:24callenPython tends to bite you very hard if you do things that trip-over into compile-time.
20:24callengood example of this: default args
20:24callenobviously if you understand the semantics it's not a big deal, but it's really not a great idea.
20:25callenit'll confuse most people who haven't run into it before.
20:25callenit's like a "run once" macro.
20:31lewis1711I just try to avoid python fullstop
20:32callenlewis1711: you could do a lot worse.
20:32callenlewis1711: I bet I could name 20 programming languages that are worse.
20:33technomancylewis1711: if you know of another SSH implementation that wouldn't require writing a C extension to OpenSSH lemme know =)
20:33lewis1711Cobol, Brainfuck, raw machine code... :)
20:33lewis1711technomancy: fair play. it does have nice libraries
20:34technomancyoh man there are pastebin links flying fast in this channel
20:35callenlewis1711: Erlang, most C libraries (yes, they're their own languages. Don't believe me? Look at ffmpeg. F!@#ing crazy frog.), Ruby, Common Lisp, C++, JavaScript, Go, Pascal, Java, Scala, Vala, C#, Haskell, Perl, PHP, Smalltalk, OCaml, APL
20:35callenoh and Ada.
20:35technomancythat's cheating
20:35technomancyalso, you forgot VB
20:35brehautand VBScript
20:36brehautseperate class of evil
20:36technomancyalso, OCaml is awesome
20:36tpopecobol if you really want to dig into the junk drawer
20:36brehautalso haskell
20:36lewis1711sorry were you listing all the languages people should use instead of python?
20:36technomancyand smalltalk, wtf dude?
20:36lewis1711PHP... I dunno that doesn't belong there. I'll give you that
20:36callentechnomancy: there is a hypothetical parallel universe where OCaml and I are like this: http://www.youtube.com/watch?v=5utC5fvY-Zs
20:36callentechnomancy: we are not in that universe.
20:37technomancythat is some wonderful CG
20:37lewis1711meh, suspend your disbelief :)
20:37callenwe are in the universe where obscure academic francophones implemented OCaml and batteries included came out way later than it should've been. Also, I don't want to work for Jane Street.
20:38technomancyI guess it depends on whether you're talking about quality of the language or suitability for use at $DAYJOB
20:39callentechnomancy: you've got a point there, but I try to incorporate my nighttime funsies into my day job
20:39callentechnomancy: privilege of working in startups I guess.
20:39brehauthuh 'ring.util.request/body-string
20:39brehauthandy
20:41seangroveHow can I use a local copy of a cljs library in lein-cljsbuild?
20:42seangroveNevermind, I think I'm doing it with clojurescript already, can probably figure it out via :dependencies
20:42gfrederickslein checkouts!
20:42callenso am I the only one trying to find ring.util.request right now and failing at life?
20:43weavejestercallen: It's in Ring 1.2.0-SNAPSHOT.
20:43callenoh god dammit
20:43callenweavejester: thank you.
20:43callenweavejester: do you know which github branch that is?
20:43weavejesterI'm going to try and release Ring 1.2.0 sometime within the next month or so
20:44weavejestercallen: master
20:44callenthat's what I was in.
20:44callenwait wait, I'm a moron. h/o
20:44callenno no, false alarm.
20:44callenweavejester: ring.core?
20:44callenring-core, that is.
20:44weavejesterRight
20:45callenoh. wrong fork.
20:45weavejesterhttps://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/request.clj
20:45callenweavejester: mmcgrana has too much google juice man.
20:45callensigh, sorry.
20:46brehautshit. i bet im not helping with that
20:46callenbrehaut: how so?
20:46brehautby linking to the mmcgrana repos
20:46callenbrehaut: s'not cool man, you confuse idiots like me :(
20:47brehauthuh. either i have completely forgotten about fixing the links, or someone has benevolently hacked my site
20:49brehautturns out you can thank utvc
20:49callenI started listening to the Neverending Story OST because of the earlier reference. I need to do this everytime I code.
20:52TimMccallen: ┬─┬ノ( º _ ºノ)
20:53brehaut(╯°□°)╯︵ ┻━┻
20:56callenTimMc: I'm happy to announce that the war is over, we were never at war with Oceania.
20:56callenTimMc: we've always been at war with Eurasia all along.
21:30TimMc&(let [& [1 2 3] [& &] & [& &] & [& &] &] &)
21:30lazybot⇒ (1 2 3)
21:44gfredericks&(let [& [1 2 3]] &)
21:44lazybot⇒ [1 2 3]
21:46Guest77224#lighttable
21:57TimMcgfredericks: Well, that too.
21:58TimMcDid you see the Swearjure session yesterday evening?
22:03gfrederickswat?
22:03clojurebotFor Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888
22:03TimMcgfredericks: Y'know, Curje.
22:03gfrederickscurrj?
22:03TimMcClojre without alphanumerics.
22:04TimMcand the letter \u, apparently...
22:04gfredericksoooh
22:04gfredericksman I thought you were talking about a meetup or something
22:04gfrederickslike some hip city whose clojure group is called swearjure
22:04TimMcMmm, swearjure meetup...
22:04gfredericksno I was at a meetup yesterday evening actually
22:05TimMcgfredericks: There *is* a meetup with a name reminiscent of that, I think.
22:05gfredericksseajure?
22:05clojurebotseajure is the seattle clojure group: http://seajure.github.com
22:05TimMcHah, no.
22:05gfredericksclojurebot: swearjure?
22:05clojurebotNo entiendo
22:06gfredericksdata science on the obama campaign
22:09TimMcOh hey, when did the clojure.org docs link move to Github and get versioned? (... v1.3, v1.4, v1.5)
22:10TimMc,(doc reset-meta!) ;; what's this useful for?
22:10clojurebot"([iref metadata-map]); Atomically resets the metadata for a namespace/var/ref/agent/atom"
22:12TimMc,(when-first [x (range)] x)
22:12clojurebot0
22:15TimMcHmm, how is drop any different from nthrest?
22:16amalloyTimMc: nthrest eagerly consumes the first n elements
22:17TimMcMmm, right.
22:20gfrederickswhile drop waits till you call first on it? so it's like rest/next?
22:21gfredericks(defn drop [n coll] (lazy-seq (nth-rest n coll)))?
22:21amalloyyeah, i think that's correct
22:21TimMcIt looks like drop doesn't allow GC on the head until the first call to first or seq.
22:28brehauti think i must be completely ignorant on how to use java.io classes
22:28brehautbut how do you create a stream that can be read from and written to‽
22:28amalloybrehaut: start from the assumption that they're rubbish
22:28brehautwonderful :/
22:28amalloywell, there's no such thing
22:28brehautamalloy: that seems to be the case
22:28amalloybut it sounds like you might be happy with a Piped[Input|Output]Stream pair
22:29amalloydepending on what you want that stream for. file writing, or what?
22:29TimMcConcurrent communication?
22:29brehautamalloy: interstitial stream for catting multiple other stream things to
22:30brehauteg, i have a bunch of files from clojure.java.io/resource and i want to make one stream that reads from them in order so i can feed it to std in of a conch program
22:31brehautso far i can only assume ive grabbed the whole problem complete bass ackwards
22:31amalloy$google SequenceInputStream javadoc
22:31lazybot[SequenceInputStream (Java 2 Platform SE v1.4.2)] http://docs.oracle.com/javase/1.4.2/docs/api/java/io/SequenceInputStream.html
22:31brehautphew
22:31brehautthanks
22:31amalloyyes, copying to a "buffer" is pretty backwards
22:31amalloyyou want to construct a stream which delegates. in this case, that is already written for you (though with a terrible API)
22:32amalloyyou'll also want ##(doc sequence-enumeration), i think it's called
22:32lazybot⇒ nil
22:32amalloy&(doc seq-enumeration)?
22:32lazybot⇒ nil
22:32brehautenumeration-seq
22:32amalloyno, that's the wrong direction
22:32brehautoh
22:33amalloybrehaut: you could also just steal from me: https://github.com/flatland/io/blob/develop/src/flatland/io/core.clj#L30
22:33brehautah that will do
22:33brehautthanks
22:33amalloyi wonder what the "opts" arg is for
22:34brehautconsistency with clojure.java.io/… ?
22:35jkkramerforward-compatibility with a version yet to be written
22:39amalloyah yes, consistency with c.j.io/make-input-stream
22:39amalloyi think in theory you can write (c.j.io/input-stream [stream1 stream2])
22:40amalloyand it calls (make-input-stream [stream1 stream2] nil), so we register an implementation of that
22:41brehautclojure.java.io is one of those libs that if you arent writing clojure regularly is quite confounding
22:42brehautlikewise
22:42gfredericksyou just try things and it always works for the 4th thing you try
22:42brehautit doesnt help that the java library is obtuse at best
22:42gfredericksthen you forget the details of what made it work and repeat that 2 months later
22:42amalloyit's certainly not as transparent as (most of) clojure.core
22:43gfredericks,(doc monitor-enter)
22:43clojurebotGabh mo leithscéal?
22:43amalloythinking about it now i'm quite impressed by how readable clojure.core is, on the whole
22:43brehautyeah both statements are true
22:44gfredericksI'm surprised that the define-the-first-four-arities pattern was never generalized
22:44gfredericksor automated somehow
22:44brehautmy impression of c.j.io is that it looks like it does a lot of clever for me, but i just cant work out what exactly
22:44amalloygfredericks: it's pretty hard to do. i think at some point rich welcomed someone to solve it
22:44brehautgfredericks: i think heroic efforts were undertaken around 1.2/1.3 but it stumped allcomers
22:45gfredericksamalloy: yeah I had the sense that might be the case
22:45amalloyi spent an hour or two on it and gave up
22:45brehauti think fogus might have got pretty close but not close enough
22:45gfredericksit's a bit like loop unrolling isn't it
22:46amalloyloop unrolling seems more structured to me
22:57TimMcWhat's this about arities?
22:57gfredericksI guess I need to find an example
22:58alandipertgfredericks: you mean like [] [a] [a b] [a b c & more], the stuff that's all over math?
22:59TimMcOh, all those monoids!
22:59gfredericksalandipert: I suppose...math?
22:59gfrederickshttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L600
22:59gfredericks^ there's an example
22:59gfredericksoh no not monoids
22:59gfredericksit's specifically when there's an unnecessary number of small arities defined before the vararg case
22:59brehautamalloy: am i missing something? i should be able to just require flatland.io.core and it should registers a make-input-stream implementation for seqable things (such as vectors) right?
23:00alandipertgfredericks: oh, i was thinking math because i've hung out there… another neighborhood in core.clj, lol. but yeah it's all over
23:00gfredericksI mean probably they are monoids but they're defined that way for perf, not just for being monoids
23:00amalloybrehaut: that's the plan, yep
23:00brehauti must be doing something stupid then
23:03technomancyflatland.io.core? =(
23:04brehautwhats the opposite of turtles?
23:04technomancyshredder
23:05brehautcause its those, all the way up
23:05brehautits shredders all the way up
23:05amalloy(dec shredder)
23:05lazybot⇒ -1
23:06TimMc[core.core/core "1.0.0-SNAPSHOT"] (:require [core.core.core.core.core :as core])
23:06brehauthttp://www.rottentomatoes.com/m/core/
23:07brehautaudiences agree: core is not good
23:12TimMcbrehaut: Oh lord, you prompted me to read the plot of that on Wikipedia... christ that's terrible.
23:13brehautTimMc: its a better movie than its plot
23:13brehautbut only just
23:13brehautand because its firm mocking itself
23:13TimMcIs it?
23:13brehautonly just
23:13brehautthe plot is rubbish, the movie is slightly entertaining rubbish
23:14brehauti still wouldnt watch if given a choice
23:22alandipertit does have that sweet shuttle LA river landing scene, which is how i justify naming my namespaces core
23:24brehautlol
23:41frozenlockwoohoo! Cljs in cljs!
23:45clj-newb-234is (= (m-bind (m-result value) function)) (function value)) correct? or should i be (= (m-bind (m-result value) function) (m-result (functoin value))) ?
23:45clj-newb-234http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/ (in referene to)
23:46amalloyclj-newb-234: the latter looks right to me
23:47TimMcfrozenlock: Really?
23:49amalloyclj-newb-234: i think actually it's the former. let's take the specific case of the List monad: f is then a function from x->[x]. so (m-result 5) is [5], and (m-bind [5] f) calls (f 5), which is expected to return a list
23:49frozenlockTimMc: taken from HN https://github.com/kanaka/clojurescript
23:49clj-newb-234amalloy: looking at http://www.haskell.org/haskellwiki/Monad_Laws , it appears to be the former
23:51TimMcfrozenlock: Hmm, what makes this *not* self-hosted?
23:53frozenlock?
23:54clj-newb-234can "(m-bind (m-result value) function)" be wrritten in domonad notation? I don't believe it's equiv to: "(domonad [x (m-result value)] (function value))"
23:56TimMcfrozenlock: Well, it claims to not be a self-hosted compiler, but it also claims to be a (mostly working) CLJS compiler that can compile itself.
23:57TimMcHmm, or is it that the standard Clojurescript compiler can compile it, but it has some parts it can't compile for itself yet?
23:58frozenlockThat would make sense