#clojure logs

2014-09-12

00:27sdegutisis Delegate a horrible name for an app?
00:33TEttingersdegutis: it is great if you want to make a blame-passing app. like, I don't want to do this, let me consult Delegate to see who to give the project to
00:33sdegutis:)
00:33rpauloheheh
00:40craigglennieWhat’s the current state-of-the-art for web-scraping - is it Enlive?
00:42danielcomptonsdegutis: make sure it doesn't violate the single responsibility principle and you're fine
00:43sdegutisheh
00:43sdegutisI have given up on naming my app.
00:43danielcomptoncraigglennie: think it's Amazon Turk still
00:43sdegutisI'm just going to call it Concierge.app and be done with it.
00:43danielcomptonsdegutis: Mac app?
00:43sdegutisyes
00:43craigglenniedanielcompton: You mean MTurk? I’m thinking more of something equiavlent to Python’s beautifulsoup or lxml
00:44craigglenniedanielcompton: Something to help me parse data out of HTML
00:44jarjar_primehello all!
00:46seancorfieldcraigglennie sure sounds like Enlive to me...
00:46danielcomptonsdegutis: cool, what does it do?
00:47sdegutisyou give it a script and it runs your script, and it gives you an api for your script to use that hooks into low-level GUI APIs
00:47sdegutisor something
00:48danielcomptonsdegutis: what's the use case?
00:48sdegutisscripting your gui
00:48sdegutisi.e. write 4 lines so that any time you press a global hotkey, your mouse cursor moves to the center of the focused window
00:48craigglennieseancorfield: thanks
00:48sdegutisor bind some global hotkeys to move windows around
00:50sdegutisis there a version of Clojure for embedding in a C app?
00:51sm0kehttps://github.com/raph-amiard/clojurescript-lua
00:51sdegutisrequires a jvm still?
00:52sm0kei guess you could compile it , but yes for dev jvm would be required
00:52sdegutiswhy oh why jvm do you have to be so different, fricken hipster
00:53sdegutiseverything is written in C except suddenly theres java and now nothings compatible with anything else
00:53sm0kejava is written in C you know
00:53sdegutisthats the worst part!
00:53p_lactually what is really incompatible... is C++
00:53sdegutisits like its mocking us! just sitting there like "haha im written in C but completely incompatible with C"
00:54sm0ke:P
00:54p_lJava got JNI and I had seen stuff that looked like it had embedded Java
00:54sm0kehave you looked ar jnr
00:54sdegutiswelp
00:54sdegutisgonna name my app Concierge.app
00:54sm0keits frekin awesome
00:54sm0kehttps://github.com/jnr/jnr-ffi
00:54sdegutisalthough someone told me it has, umm, certain connotations
00:55sdegutisbut i cant find anything bad in the dictionary or wikipedia page about it
00:56sm0kewhy would you want to write in clojure if your stack doesnt have jvm
00:56sm0kewrite in ocaml, haskell, scheme, guile
00:56sm0keand a hundered more
00:56sdegutis+1
00:57sm0kesdegutis: still here?
00:57sdegutishi
00:57sm0keoh i though you will part from #clojure
00:57sdegutiswhy
00:58sm0kenothin
00:58sdegutisk
00:58danielcomptonsdegutis: "Adult" concierges exist and mean pretty much what you think they mean
00:58sdegutiscrap
00:58sdegutisugh
00:59sdegutisthere are no names.
00:59sdegutisall names are taken.
00:59sdegutisi have been trying to name this app for like 4 months no
00:59sdegutis*now
01:00sm0kechauffer
01:00sdegutisi wanted to do Minion.app but everyone will think of those dumb yellow things
01:00sdegutisi might do Lackey.app
01:00sdegutisbut i have no idea what people think when they hear lackey
01:00danielcomptonsdegutis: OTOH adding adult to any word makes it sound bad. Concierge sounds pretty good to me
01:01sm0kesdegutis: Sevak.app
01:03sdegutislol Manager.app
01:03sdegutisyeah ill stick with Concierge
01:04sdegutisif at least 20% of the people i tell this to say the adult-concierge thing, its gone. otherwise ill keep it
01:10TEttingerYourNameIsToby.app
01:10sdegutiscorrect
01:12dorkmafiatechnomancy: https://github.com/rplevy/clojure-python found this
01:13dorkmafiai'm going to give it a spin now
01:57TheMonarcgreetings, is there a good clojure book for someone who is new to both clojure and FP?
01:58TheMonarcnew to FP part not as important (did a little LISP in college)
01:59dbaschTheMonarc: you may like http://joyofclojure.com/
02:00dbaschactually http://www.amazon.com/The-Joy-Clojure-Michael-Fogus/dp/1617291412/
02:16zanesTheMonarc: You might also like http://www.braveclojure.com/
02:16zanesHas the added benefit of talking about tooling.
03:08zotmorning :) i'm new to it, and seeking the most natural/elegant way to iterate through a string, splitting at a regex, but iterating through both matches, and the goo in between
03:09zotthus: regex: "\d" with an input of "asdf 2 ff 33" -> seq ["asdf ", "2", " ff ", "3", "3"]
03:09zotis there something that i'm not finding to do this cleanly?
03:09zot(i can make my own groupings both inside and outside of the expression, but thought there might already be a better way
03:13engblomzot: http://clojuredocs.org/clojure_core/clojure.string/split
03:14zotengblom: i found that, but it drops the matching bit. re-seq appears to only yield the matching bit, and i haven't found a single thing threads them (or keeps them) together :)
03:20Bronsazot: you can use interpose on c.s/split and re-seq if you don't mind running over the string twice
03:22Bronsaerr, interleave
03:22zotinteresting, but the matching expression isn't fixed
03:22zotyeah, that looks much better. have to do first match manually to see which seq leads, but that's the right idea :)
03:23Bronsa,(require '[clojure.string :as s])
03:23clojurebotnil
03:23Bronsa,(defn f [p s] (interleave (s/split s p) (re-seq p s)))
03:23clojurebot#'sandbox/f
03:23Bronsa,(map (partial f #"\d") ["1 a 2 b" "a 1 b 2"])
03:23clojurebot(("" "1" " a " "2") ("a " "1" " b " "2"))
03:24Bronsauhm
03:24zotlooks pretty good to me :)
03:24zotthanks!!
03:24Bronsazot: it's dropping the last match on the first string
03:24zotdoh. missed that.
03:25zotyour karma is still on the up for this weekend ;)
03:25zotbut i'm curious about the dropping bit
03:25babygauhttps://www.refheap.com/90139
03:27tobikzot: if you change your regexp you can probably do this with re-seq
03:27tobik,(re-seq #"\d|[^\d]*" "asdf 2 ff 33")
03:27clojurebot("asdf " "2" " ff " "3" "3" ...)
03:28Bronsanice tobik
03:28zottobik: i was playing with that idea already, but my regex is much more complicated, so it was more like: #"(.*)(?:({{[…]}})|(.*))*"
03:28zotbut failing, as complicated regexs often do
03:29zoti needed a quick and dirty way to do some light templating, including env var substitution, and file content substitution. perhaps the other approach is to ask what already exists :)
03:30zotand i'm missing a * after the inner [token_letters]
03:31zotactual code i'm trying: (print (re-seq #"(.*)(?:({{@[A-Za-z0-9_]+}})(.*))*" "ao {{FOO_BAR}} do")
03:31zotbut doesn't compile
03:36tobik,(re-seq #"\{\{@[A-Za-z0-9_]+\}\}|[^\{\{@[A-Za-z0-9_]\}\}]+" "ao {{FOO_BAR}} do")
03:36clojurebot("ao " "FOO_BAR" " do")
03:38zottobik: thanks :) it hurts my brain.
03:39zoti dno't see how the second half of the expression works though — it's a multi-character match.
03:39zotis there a way to make .* not greedy?
03:40tobiki don't think so
03:40zotthen i think i just have to split on "{{|}}" and do a tiny "parser" with the interleave thing as input stream
03:41zotmaybe easier in the end
03:41tobikcan't you just use a templating library for this?
03:41zotthat's what i was asking before — i hadn't found sometihng that does what i need, and originally hoped it would be 15m of (learning experience) code to write. naïve.
03:42tobikyou can probably adapt selmer to your needs
03:42tobikhttps://github.com/yogthos/Selmer
03:46babygauhttps://www.refheap.com/90139
03:56Bronsazot: http://sprunge.us/EEKh?clj if you're curious, this should work as expected for every input string
03:59Bronsababygau: repeatedly pasting the same link won't help you getting answers if you first don't tell us what's not working
04:00babygauBronsa, sorry bro, I thought put my question in the link make my question look cleaner :(
04:00babygauBronsa, I can't compile #clojurescript to normal #javascript
04:01babygauBronsa, the output (as you can see over the link) looks weird >.<
04:04Bronsababygau: I have never used cljsbuild, but reading gulpfile.js it looks like you should find the output of your ns in gulpjs/core.js
04:06babygauBronsa, you're right, I found the compiled core.js but I don't know why it doesn't compile to `gulpfile.js` but `core.js`???
04:06lazybotbabygau: Yes, 100% for sure.
04:09Bronsababygau: as I said, I don't use cljsbuild so I can't really answer that question. you might want to wait until people in the US start waking up and ask that again
04:09babygauBronsa, what do you use then :-P
04:09BronsaI don't use cljs at all
04:10babygauBronsa, tks bro :)
04:18PeakCodeI get a 404 page when I try that link (https://www.refheap.com/90139). Do you have to be signed in?
04:19tobikits gone now
04:19PeakCodeOK, I see.
04:21babygauPeakCode, https://www.refheap.com/22172234ac498cee3cc18214d
04:25PeakCodebabygau: What is the path to the core.cljs file?
04:29PeakCodebabygau: I suspect that :source-paths should be just ["src"] instead of ["src/gulpjs"].
04:30babygauPeakCode, nope, as I read in #clojurescript up & running, it must be src/gulpjs because my namespace is gulpjs.core
04:35PeakCodebabygau: So the path to core.cljs is src/gulpjs/gulpjs/core.cljs then?
04:37babygauPeakCode, it is src/gulpjs/core.cljs
04:38PeakCodebabygau: I'm pretty sure you have to either change :source-paths or the path to core.cljs. :source-paths should point to the root of your source tree.
04:39babygauPeakCode, tks bro, pls give me a sec, I will check it out immediately
04:43babygauPeakCode, I changed `:source-paths ["src"]` but the code in `gulpfile.js` is still the same
04:47tobikbabygau: try this https://www.refheap.com/f946f21767954ea1b1afe82a6
04:48babygautobik, I will try it now
04:50babygautobik, it WORKED!
04:51babygautobik, I don't even have to put :target :node, I think the prob is in :optimizations
04:51babygautobik, PeakCode, I changed :optimizations :simple the the code run
04:52djcoinbabygau: tobik pretty cool experiment :)
04:56babygautobik, PeakCode, tks you guys
04:56PeakCodebabygau: OK, great! Perhaps adding :output-dir would have worked with :optimizations :none. You can also try :optimizations :whitespace.
05:05babygauPeakCode, it doesn't work bro :)
05:26zotBronsa: thanks, this is awesome :)
05:34AeroNotixwhen I run component/stop on a component system, does it call stop on every component?
06:56thesaskwatchHi .. I can use (source x) to view source of x ... but what if it's defmulti .. can I list / view defmethods of it in repl?
07:09sm0keis there a variant of (let [..]) which signifies non ordered declaration?
07:10Bronsasm0ke: letfn is parallel, but as its name suggests, can only bind functions
07:10sm0keBronsa: i am not really concerned if its parallel, more on readability
07:11Bronsathen no
07:11sm0kelike i use (if) for two condition and (when) for one
07:11sm0keok
07:12Bronsasm0ke: maybe you want if-let/when-let?
07:13sm0keno thats not the point,
07:13sm0kemy point it
07:13Bronsasm0ke: your last phrase seemed to suggest that :)
07:13clgvAeroNotix: hopefully, isnt that the point of that hierarchical composition?
07:14Bronsasm0ke: you want (let [a b b 1] a) ;=> 1 right?
07:14sm0keif i see a (let [a .. b ,..]) i cannot say if a and b are dependent on each other
07:14sm0kenot without looking deeply into what a and b does
07:14Bronsasorry I have to run
07:14sm0keno prob
07:14clgvsm0ke: but you know that "a" cannot depend on "b"
07:15sm0keclgv : (let [a 1 b (inc a)[)
07:15clgvyeah the otherway round is possible ;)
07:15sm0ke-.-
07:15clgvso you want that common lisp let back?
07:16sm0keno i just want to have a code convetion, lets say there is a (let ) for bindings which depend on each other and (let**) for non dependent bindings
07:16clgvsm0ke: is writing that yourself an option? I could give you a hint how to achieve it
07:17sm0keyes it is easy
07:17sm0kebut my point was if other people are foloowing something
07:17sm0kewhat will i do alone in my own world
07:18clgvwell, the question is if other people do rank this as important as you do
07:18clgvI for myself do not
07:19sm0keyep not critical but would be nice for readability imo
07:19clgvbut could also lead to pretty awful nesting of let and let*
07:20clgvah "let**" you said ^^
07:33SagiCZ1hi
07:34SagiCZ1,(= (conj [[5 6] [7 8]] [0 1]) (conj '([5 6] [7 8]) [0 1])
07:34clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
07:34SagiCZ1,(= (conj [[5 6] [7 8]] [0 1]) (conj '([5 6] [7 8]) [0 1]))
07:34clojurebotfalse
07:34SagiCZ1i need to do the first thing, but with list and not vector
07:35SagiCZ1append element to the end of list
07:36SagiCZ1,(cons 4 '(0 1))
07:36clojurebot(4 0 1)
07:36SagiCZ1,(conj '(0 1) 4)
07:36clojurebot(4 0 1)
07:36SagiCZ1they both do the same thing
07:36SagiCZ1how is that useful?
07:37clgvSagiCZ1: thats not possible efficiently. why do you need that for a list exactly?
07:38SagiCZ1well one of my functions is returning list
07:38SagiCZ1,(vector '(4 5 6))
07:38clojurebot[(4 5 6)]
07:38clgvcant you change it to a vector and keep it a vector?
07:38SagiCZ1,(vec '(4 5 6))
07:38clojurebot[4 5 6]
07:38SagiCZ1okay then..
07:39clgvmost of the time you want vectors anyway
07:39TEttinger,(concat '(0 1) '(4))
07:39clojurebot(0 1 4)
07:39clgvTEttinger: not efficiently though and not type preserving ;)
07:39TEttingeryep
07:39TEttinger,(class (concat '(0 1) '(4)))
07:39clojurebotclojure.lang.LazySeq
07:39clgvand not arbitrarily stackable ;)
07:41SagiCZ1and adding to end of vector is O(1) ?
07:41clgvyes
07:42SagiCZ1is vector also implemented by some tree?
07:42clgvyeah. son in fact its log_{32}(n)
07:58SagiCZ1is there a print statement that also returns what it printed? something like (defn print-return [x] (println x) x) ?
07:58SagiCZ1,(defn print-return [x] (println x) x)
07:58clojurebot#'sandbox/print-return
07:59clgvnope, but probably defined hundreds of times ;)
07:59SagiCZ1(print-return {:b 4 :a 5})
07:59SagiCZ1clgv: okay :)
07:59clgvthere is the "spyscope" library that does something similar
08:17inad922Hi
08:17inad922How can I go left and write in the interpreter?
08:18inad922+ up/down for walking history?
08:19engblominad922: Do you mean inside of REPL? Is not the arrow keys working for you?
08:22clgvinad922: do you use leiningen? if not, you should definitely change that
08:24clgvinad922: just with "java -jar clojure.jar" you wont' get those features
08:27inad922engblom: Yes, well I think inside the repl. I'm new to this. I run "clj" on the cli
08:27clgvinad922: how did you "install" clojure?
08:28clgvinad922: I recommend following the steps under "install" here http://leiningen.org/ and then use "lein repl"
08:28inad922clgv: pacman -S clojure. So via the package manager
08:28clgvinad922: probably not optimal.
08:29clgvinad922: what's your goal? learning the language with a quickly setup environment?
08:29clgvinad922: if so, give lighttable a try http://www.lighttable.com/
08:29inad922clgv: I want to use clojurescript for frontend development
08:30clgvinad922: so are you sold on any editor/IDE yet?
08:30inad922clgv: Yea, I use sublime. Light table seems to be the same
08:31clgvclgv: no lightable is definitely distinct from sublime ;)
08:31inad922clgv: I'm a python dev mainly, I just want to learn something more usable for frontend than js. That's just bad
08:32clgvbut try it out, it gets you setup pretty quickly. other options are eclipse with counterclockwise, intellij with cursive, vim with vim-fireplace and emacs with cider
08:32inad922umm
08:32clgvtoo much choices? ;)
08:32inad922Why would I need anything better than a plain editor?
08:33clgvbecause of integration of editor and repl
08:33inad922I mean does clojure have code quality standards like pep8 for python? Static code checkers, etc.?
08:33clgve.g. evaluating the content in the editor or the selected function in the repl by pressing a shortcut combination
08:33inad922I don't need editor integration
08:33xemdetiado you not use python repl for python dev?
08:33clgvintegration of editor and repl is a must-have
08:34inad922xemdetia: Nah
08:34inad922not really it isn't
08:34clgvin clojure it is
08:35inad922Why how do imports work in this language?
08:35inad922and modules
08:35inad922namespaces, stuff like that
08:36inad922Is this leiningen like a package manager for clojure?
08:37xemdetiainad922, it's closer to maven if you are familiar with that
08:37clgvinad922: kind of. it fetches the dependencies you declared, from default (or specified) repositories
08:38clgvinad922: it starts a repl for you where all dependencies are present and you can build deployable jar archives with it
08:38holoinad922 yeah leiningen is awesome. do you know the story?: http://www.classicshorts.com/stories/lvta.html really worth reading. The original author is like Leiningen who defeated the ants. sometimes he lurks in this #
08:38clgvinad922: for clojurescript there is "lein cljsbuild"
08:38inad922xemdetia: Ah maven. This stuff only runs on JVM?
08:39clgvholo: lol what? the background is that he defeated the "ants" :P :D
08:40holoclgv, sure!
08:40clgvinad922: your dev environment will run on JVM. you'll compile javascript files from clojurescript via leiningen
08:40clgvholo: damn, that one took long to notice (~3 years) ;)
08:41holoclgv haha :D
08:41clgvso leiningen defeats ants but is afraid of mavens?
08:42holowell, every brave man has a fear to conquer!
08:42xemdetiainad922, the main thing to note with a functional language is that not using a repl for interactive development makes it very difficult to determine that given what input, what does this function provide as output
08:43TimMcholo: Every brave woman as well.
08:43xemdetiathis is also important because the idea is 'many little functions chained together' and not 'one big code block'
08:43TimMc*person
08:43holoTimMc, sure, brave women are awesome!
08:45TimMcWasn't quite what I was driving at, but I guess I'll take it.
08:46inad922xemdetia: I don't say you should not use a repl. I obviously do with python. I'm saying that editor integration doesn't do too much good for me.
08:49clgvinad922: just try one of those options and experience the benefits ;)
08:52clgvinad922: just using "cli" from your package manager will be a pretty poor setup as you have already noticed
08:53inad922clgv: Yea, I just downloaded the leiningen script
08:53inad922Running lein repl
08:53inad922It does what I wanted
08:54clgv:)
08:54clgvone step forward. but I'd go the next steps as well
08:54inad922Also I'm a bit frightened about the fact that this stuff runs on the JVM
08:54inad922Java is horrific...
08:54xemdetiaonly if you are clumsy
08:54hyPiRioninad922: java != JVM
08:54clgvas hyPiRion said!
08:54inad922xemdetia: I don't want to start a flame war. I don't like that language, that's it.
08:55tbaldridgeinad922: who does? Good thing Clojure means you don't have to write in Java.
08:55inad922JVM is the bytecoder interpreter that runs the compiled Java code isn't it?
08:55holoinad922, just be afraid of the bootstrap times. if you follow the Stuart Sierra workflow though, you may save so much time
08:55clgvinad922: so you would not use a properly working program only because it is written in java? that's a strange world view
08:55hyPiRioninad922: the compiled JVM code*, but yes, that's right
08:56inad922clgv: If there is an alternative :)
08:57holoinad922 hy is fine. there is also rhine, on the llvm
08:57clgvouch!
08:58tbaldridgeholo: sadly hy is "mutation everywhere!", that's the reason I never really used it.
08:58hyPiRionholo: rhine is not working yet
08:58TimMcinad922: The JVM is a pretty different beast from Java.
08:58TimMcSun did a reasonably good job making them separate.
08:59holotbaldridge, I'm integrating hy with fn.py now for that reason. maybe it will be awesome
08:59inad922TimMc: Yes, probably you're right. I don't know much about this topic.
08:59TimMcxemdetia: Most people are clumsy most of the time, so that's no excuse for a poorly designed language. :-)
09:00TimMcinad922: For instance, the JVM doesn't know what inner classes or checked exceptions are.
09:00xemdetiaTimMc, fair enough.
09:00tbaldridgeinad922: the Clojure/JVM thing is an interesting beast. On one hand I'm not crazy about the JVM. On the other hand I've integrated fairly large libraries in Clojure.
09:01tbaldridgeBeing able to say " you can use this mountain of existing code from clojure " is huge in the "real" world.
09:02inad922tbaldridge: Yes, I have to agree with that.
09:03holoyeah, I integrated two of my own. it's a huge win
09:03hyPiRioninad922: I'll just say you should try out Clojure, and if you like it, stay with it. Just be aware that, although it runs on the JVM and has Java interop, it's not related to Java the language.
09:05hyPiRionAnd if you don't like it, then that's perfectly fine too :)
09:06clgvhe actually wants to use CLJS ;)
09:06inad922hyPiRion: Yeah well. I give it a try. I really like how well clojurescript integrates with already written js libraries. Also it seems like a well designed language unlike js. I just want to find an alternative
09:06hyPiRionclgv: oh well, cljs then!
09:07tbaldridgeinad922: personally I enjoy working with CLJS more than CLJ. You fire up cljsbuild and set it to auto re-compile. Then as you edit files they recompile in about 0.5 sec. Refresh the browser and you're on your way
09:07clgvbtw. are the days of the "hashcode versions" of cljs counted?
09:07tbaldridgeclgv: I highly doubt it
09:08clgvtbaldridge: is there a definied/described state for it to reach 1.0?
09:09tbaldridgeclgv: so I'll give you the reasoning I got from Rich once when I asked when core.async would hit beta...
09:09inad922tbaldridge: Nice. That's good for testing. Do you use clojure on the backend too?
09:10tbaldridge"Why are people so concerned about alpha,beta, etc.? Are they thinking that it somehow won't change after it hits beta? We try not to change public APIs, so why does beta matter? It's not magically stable or perfect because someone sticks 1.0 on it"
09:11tbaldridgeclgv: so I think the idea on that stuff is, if it works for you, use it. CLJS only gets more stable, version numbers are meaningless. :-)
09:11clgvtbaldridge: well it expresses the confidence of the maintainer. so we are lucky clojure has releases at all? :P
09:13xemdetiagmail set the groundwork for the mostly permanent beta future
09:13tbaldridgeclgv: but that would suggest that the confidence of the maintainer is something that has an absolute value.
09:14clgvtbaldridge: well it is at least indirect communication between maintainer and user
09:15tbaldridgeclgv: examples...Games from Blizzard are playable in alpha and beta. While games from EA often crap on the day after release. Gmail got out of beta after 10 years?
09:15clgvtbaldridge: I mean there is a version scheme and from the usual context it implies that there should be a 0.1 or 1.0 at some point ;)
09:16clgvtbaldridge: ok on that argument, why not just counting up from 1 for release numbers but instead employ a version scheme that implies some magical future versions that won't happen?
09:16tbaldridgeclgv: I get what you're saying, and I'm just arguing to make a point. But I do agree with those who state version numbers are rather worthless things, and it bugs me when managers say things like "Eh...don't use Kafka, it's only at v0.8"
09:17clgvtbaldridge: hehe, managers are why you need internal and external versions :P
09:17clgvuse "the new ClojureScript 2014/04" :P
09:18dnolen_clgv: that is in fact what Google Closure Compiler / Library does
09:18clgvdnolen_: the counting-up version scheme?
09:19dnolen_clgv: no version is just the date
09:19truebuddinewbie here so wanted to check if this can be written using thread-first -> macro??? (remove-person "Krishna" (add-person "Krishna" default-trip)) ... where add-person and remove-person both take a string and a map
09:19dnolen_com.google.javascript:closure-compiler v20140814, http://search.maven.org/#artifactdetails%7Ccom.google.javascript%7Cclosure-compiler%7Cv20140814%7Cjar
09:21SagiCZ1how do i load a file in clojure using relative path?
09:24SagiCZ1nvm got ti
09:24SagiCZ1*t
09:24SagiCZ1*it
09:24clgvtruebuddi: you probably need ->> since the map is last position
09:28SagiCZ1how can i find an element by tag after using xml/parse?
09:28AeroNotixwith midje teardown/setup is there a way to make something run before all the facts and after all the facts?
09:28truebuddiclgv: I was playing around with -> .. (-> data fn1 fn2) ... right? so i was trying to use (partial ...) and i get results I dont understand ..
09:28truebuddi((-> (add-person "Krishna" default-trip) (partial remove-person "Krishna"))) => "Krishna"
09:29truebuddi((->> (add-person "Krishna" default-trip) (partial remove-person "Krishna"))) ==> gives me a map that I originally wanted
09:29truebuddi(->> (add-person "Krishna" default-trip) (partial remove-person "Krishna")) gives me back a partial :(
09:30ToxicFrog...yes, it does
09:30ToxicFrogBecause that gets rearranged into (partial remove-person "Krishna" (add-person "Krishna" default-trip))
09:30ToxicFrogDid you mean (->> default-trip (add-person "Krishna") (remove-person "Krishna")) ?
09:31ToxicFrogtruebuddi: ^
09:32truebuddiToxicFrog: (->> default-trip (add-person "Krishna") (remove-person "Krishna")) this is what I wanted ... now I have to analyze it
09:33truebuddiToxicFrog: (add-person "Krishna") as is throws arity mismatch exceptions .. but it can be used in ->> without using partial ... thats interesting
09:33clgvtruebuddi: usually for usage in threading macros, map and plain values that might be threaded should be the first argument and sequences/sequential ds should be the last argument
09:33ToxicFrogtruebuddi: -> and ->> are macros, they rearrange the code before it gets evaluated.
09:33milos_cohagentruebuddi: use macroexpand to help your understanding
09:33milos_cohagen,(macroexpand-1 '(->> default-trip (add-person "Krishna") (remove-person "Krishna")))
09:33clojurebot(remove-person "Krishna" (add-person "Krishna" default-trip))
09:33ToxicFrogYes, that
09:35truebuddiclgv: i had add-person [person trip] where trip is a map .. and you recommend trip to be first and person to be the later argument?
09:36ToxicFrogtruebuddi: that would be more consistent with the clojure stdlib, yes
09:36clgvtruebuddi: if it shall be used in threading often, then yes
09:36ToxicFroge.g. assoc/dissoc take arguments [map key] rather than [key map]
09:36truebuddiToxicFrog: in that case how would ->> work out?
09:37clgvtruebuddi: ->> is the reserved for sequential datastructures and clojure's sequence functions, e.g. map, filter ...
09:37clgv"reserved" ;)
09:39truebuddiclgv: once i swapped the order of params like you suggested, i can use the -> as in (-> default-trip (add-person "person1") (remove-person "person1"))
09:41truebuddito understand how -> rearranged .. i am using macroexpand but it gives me what looks like =====> (remove-person (clojure.core/-> default-trip (add-person "person1")) "person1")
09:42truebuddiis there anyway i can see that it actually did a (remove-person (add-person default-trip "person1") "person1")
09:42ToxicFrog-> has more expansion stages, IIRC.
09:43ToxicFrog,(macroexpand-all '(-> default-trip (add-person "person1") (remove-person "person1")))
09:43clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: macroexpand-all in this context, compiling:(NO_SOURCE_PATH:0:0)>
09:43ToxicFrogHuh.
09:43ToxicFrog,(macroexpand '(-> default-trip (add-person "person1") (remove-person "person1")))
09:43clojurebot(remove-person (add-person default-trip "person1") "person1")
09:43ToxicFrogtruebuddi: ^
09:44truebuddiToxicFrog: I get ... but the inner -> isnt expanded ... (remove-person (clojure.core/-> default-trip (add-person "person1")) "person1")
09:45ToxicFrogtruebuddi: using macroexpand-1 or macroexpand
09:45ToxicFrog,(macroexpand-1 '(-> default-trip (add-person "person1") (remove-person "person1")))
09:45clojurebot(remove-person (add-person default-trip "person1") "person1")
09:45ToxicFrogHuh.
09:46ToxicFrogAlso, what version of clojure are you using, the internals of -> may be different between your version and the bot's version
09:47truebuddipretty old i guess [org.clojure/clojure "1.5.1"] ... just did a lein new and playing with cursive .. did not look at which version . thought lein new will take care of using the latest
09:47clgvtruebuddi: if you see the recursive expansion you have an older clojure than 1.6
09:49truebuddiFixing my project.clj to use latest version but is there a clojure function that returns the version? .. something like (version ) ??
09:49lazybottruebuddi: Uh, no. Why would you even ask?
09:49truebuddilazybot: sorry?
09:50zerokarmaleft,*clojure-version*
09:50clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
09:50augustltruebuddi: lazybot is a bot :)
09:51truebuddiaugustl : new here .. so easily fooled :(
09:53truebuddigotta go .. thank you all..learned a few things today ... will be back again in the evening with more questions.. thanks again
09:57clgv,(clojure-version)
09:57clojurebot"1.7.0-master-SNAPSHOT"
10:01inad922This lighttable is pretty cool
10:01inad922I like it
10:01TimMcI should give it another shot some time.
10:03SagiCZ1can i simplify this or make it nicer?
10:03SagiCZ1,(drop-last 1 (drop 1 (range 10)))
10:03clojurebot(1 2 3 4 5 ...)
10:04verma,(doc range)
10:04clojurebot"([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity. When step is equal to 0, returns an infinite sequence of start. When start is equal to end, returns empty list."
10:04TimMc,(range 1 (dec 10)
10:04clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
10:04verma,(range 1 10)
10:04clojurebot(1 2 3 4 5 ...)
10:04TimMc,(range 1 (dec 10))
10:04clojurebot(1 2 3 4 5 ...)
10:04TimMcSagiCZ1: But you probably mean a seq that is not a range. :-)
10:04SagiCZ1sorry that i didnt specify it but its should work for any coll.. i want to drop first and last
10:05SagiCZ1can i use -> somehow?
10:05TimMcThat only rearranges your syntax.
10:05TimMcIs that all you want?
10:06verma,(doc butlast)
10:06clojurebot"([coll]); Return a seq of all but the last item in coll, in linear time"
10:06verma,((comp rest butlast) (range 10))
10:06clojurebot(1 2 3 4 5 ...)
10:06SagiCZ1verma: thanks, that looks pretty good
10:07SagiCZ1any reason to prefer rest to next?
10:07verma(-> (range 10) butlast rest)
10:07verma,(-> (range 10) butlast rest)
10:07clojurebot(1 2 3 4 5 ...)
10:07vermaSagiCZ1, rest is lazy, but I guess wouldn't matter since we want the last element out as well
10:07SagiCZ1,(-> (range 10) drop 1 drop-last 1)
10:07clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
10:08SagiCZ1threading -> doesnt work with more than 1 param?
10:08TimMcSagiCZ1: -> doesn't magically know which things are arguments to fns
10:08vermaSagiCZ1, you gotta parent them
10:08vermaSagiCZ1, you gotta paren them
10:09SagiCZ1,(-> (range 10) (drop 1) (drop-last 1))
10:09clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
10:09verma,(doc drop)
10:09clojurebot"([n] [n coll]); Returns a lazy sequence of all but the first n items in coll. Returns a stateful transducer when no collection is provided."
10:09vermaSagiCZ1, use ->>
10:09SagiCZ1 ,(->> (range 10) (drop 1) (drop-last 1))
10:09clojurebot(1 2 3 4 5 ...)
10:10SagiCZ1so -> and ->> difference is only if it appends the param as last or first right?
10:10vermaSagiCZ1, yeah
10:10SagiCZ1cool stuff
10:10verma:)
10:11TimMcSagiCZ1: Well... last, or second.
10:11SagiCZ1so it generally works for functions with params like [n coll] or [coll n] ..
10:14vermaSagiCZ1, not necessarily, you can do much more with -> and ->>
10:15vermaSagiCZ1, there's no need to use them with just seq's, they are meant to insert things into expressions, so you can use them pretty much any way you like
10:15TimMcSagiCZ1: You can really abuse them.
10:16verma(-> (go (get-me-food)) <! (print))
10:16TimMc&(-> [a 1] (let a))
10:16lazybot⇒ 1
10:16vermanice TimMc :)
10:17TimMcEven this is an abuse: ##(-> + var meta :since)
10:17lazybot⇒ nil
10:17TimMc&(-> + var meta :added)
10:17lazybot⇒ "1.2"
10:18verma:)
10:21TimMc(var is not even a macro, it's a special form)
10:22szymanowskihello, i've implemented a custom vector-like data structure and I would like the "count" function works on it, how can i do this?
10:22tbaldridgeszymanowski: have it implement clojure.lang.ICounted
10:23szymanowskithank you tbaldridge
10:23tbaldridgeszymanowski: actually it's just Counted: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Counted.java
10:23szymanowskiok thank you
10:28CookedGryphonHey, I'm writing a test.check generator and have a vector of events. What I want to do now is batch those events to simulate the way they arrive in my real app, anyone know how i'd do that?
10:28CookedGryphon(so I have the full stream of events that i'd like to arrive, now I want to randomly slice up that vector so they arrive in batches
10:32TimMcCookedGryphon: I would get test.check to also a generate for you a vector of chunk sizes, and then have the inner portion of your test chunk the vector "deterministically" based on that chunk size list.
10:33TimMcso ask for a pair of data, chunking instructions.
10:34legittalonWhat do Clojure wielding developers call themselves?
10:34CookedGryphonthat makes sense
10:41Fenderhi there, is there some best practice how to program async stuff?
10:41Fenderfor example debug go-loops - once created they kind of run forever unless I implement a channel specific stop command
10:41Fenderbut this is also cumbersome
10:42smizellHello all, I came in here a few days ago talking about an idea where you could use JSON as code (Lisp flavored). I threw a very minimal example together for fun and thought I'd just link it here. Feel free to throw your head back in laughter. https://github.com/smizell/geneva
10:42Fenderalso, sometimes my channel msgs are printlned and they overwhelm my emacs when there are many of them
10:44stwSegFaultAX: thanks for the help yesterday, I was able to isolate the process in it's own thread and then interrupt it after a timeout
10:46CookedGryphonTimMc: I'm generating my chunks such-that the sum of the vector of ints adds up to the length of the vector, but in most cases this means I generate a much longer vector than I need... Any ideas as to how I can generate a chunking vector that works with the number of elements I actually have?
10:48stompyjlegittalon: clojurians
10:48stompyjnote: I made that up
10:49stompyjiclojoclasts
10:49ToxicFrogGoddamnit, core.typed
10:50legittalonI’m tryna decide if I want to go all in on Haskell or Clojure, first.
10:51clgvand that depends on the nicknames?
10:51legittalonYes.
10:51legittalonNo.
10:51cbpclojodites
10:51clgvah well, throw a coin ;)
10:52ddellacostalegittalon: Haskell is incredible, seriously mindbending, and insanely deep. Clojure is awesome and has a great community.
10:53TimMcCookedGryphon: If you've said more than your 2 messages as 10:34 and 10:45 ET, I missed them due to a probably router reboot.
10:54legittalonMy native tongue is Javascript. Right now I’m interested in Clojurescript which seems pretty cool. But the parens are annoying but not insurmountably so. I’m also interested in Elm which is heavly influenced by Haskell.
10:55legittalonI think the resources for Clojure are way better. I want a Haskell Koans.
10:55ddellacostalegittalon: fear of parens is absolutely the worst reason to not choose a lisp.
10:55legittalonIt wouldn’t be the main reason.
10:56legittalonOr really a reason.
10:56TimMcCookedGryphon: Can you give an example of the kind of test data you would like to send, and what the invariants are?
10:56cbpyou get more twitter cred if you choose haskell
10:56ddellacostalegittalon: gotcha. Wasn't sure from your statement above, just wanted to make that clear...
10:56ToxicFrogI should try out clojurescript one of these days, now that I have an actual use for Javascript (specifically, making Android apps)
10:56legittalonHonestly I really WANT to learn Haskell first but I can’t find very good beginner resources.
10:57dnolen_legittalon: the classic books are good starting points, Simon Thompson or the Paul Hudak one
10:58ddellacostalegittalon: some Haskell folks are jerks but there are also a lot of friendly Haskell folks in #haskell. #nothaskell is also work a look.
10:58dnolen_I think both have relatively recent editions
10:58ddellacostalegittalon: which is to say, I bet they could give you some good tips too.
10:58hyPiRionlegittalon: https://github.com/bitemyapp/learnhaskell/ and LYAH
10:58cbpthere's that fp complete site and a bunch of online haskell courses
10:58legittalonLol at the Clojure community being more helpful at learning Haskell than the Haskell community.
10:59zerokarmaleftlegittalon: there's also an entire youtube series of lectures taught by wadler
10:59legittalonAwesome! Thanks for your resources.
11:00hyPiRionYou've also got Real World Haskell, which I've heard is less theoretical than the other books. Not sure if that helps or not, but at least both are available online for free
11:01ddellacostahyPiRion: I've heard that RWH is a bit dated, but that's hearsay from some folks in #haskell
11:01CookedGryphonTimMc: The current test is generating multi-touch input, each pointer starts with a :down, might have some number of :move events and ends with an :up or :cancel event. Each event coming through has a unique :touch-id and a persistent vector of all the touch coordinates since that pointer went :down
11:02hyPiRionddellacosta: Hmm, maybe? I pick a bit here and there based on what I need to learn, but what I've seen so far in RWH is okay
11:02CookedGryphonTimMc: I am then checking that once all the events have run through, my system state is coherent (i.e. no buttons are stuck down or anything)
11:03ddellacostahyPiRion: yeah, I just remember hearing someone mention the way it approaches exceptions, perhaps? Anyways, not to invalidate your point, probably still a great resource for beginners
11:03CookedGryphonand the chunking comes because in my actual implementation, for efficiency, I might skip any number of the events apart from the :up or :cancel
11:04hyPiRionddellacosta: No worries, that may be the case. I'm not a good Haskell programmer, so it may very well be true
11:04CookedGryphonTimMc: ooh, I have just thought of a much more efficient way I could do this. I generate it as if there's an event coming through for every last coordinate, and then I randomly sample from that vector, as long as I can guarantee that I get the last point
11:05ddellacostahyPiRion: I'm barely a Haskell programmer, so there is even less point for me to be talking about it...haha
11:06TimMcCookedGryphon: Careful with that "randomly sample" part.
11:07CookedGryphonTimMc: yeah, that's the bit I need help with, I know I need to make a reproducible generator
11:07TimMcAny randomness should be coming through test.check so that it can report the exact conditions of a failure and shrink the failures.
11:07TimMcOr does test.check have a sampler?
11:08hyPiRionddellacosta: heh. Sometimes I get an error with the message "Maybe you wanted to add the language extension X?", I add X and it works. And I how no idea why.
11:10zerokarmaleftddellacosta: RWH is a bit dated, but the pedagogical approach is very good in places
11:10CookedGryphonTimMc: don't think so, but then I can always do what I was going to do before with the chunker vector
11:10CookedGryphonIt would be nice if there was a cleaner way of doing it though
11:11zerokarmalefthyPiRion: I've come to enjoy GHC's prescriptive error messages
11:12ddellacostahyPiRion: I may possibly have had that experience using ghc...
11:12ddellacostazerokarmaleft: gotcha, good to know
11:12ddellacostazerokarmaleft: I do have to say, ghc's error messages kick the butt of Clojure's
11:13ddellacostabut that's not really a fair competition
11:13TimMcCookedGryphon: Just ask for a sufficiently long list of random numbers that you can then massage into skips, repeats, chunkings, whatever.
11:14hyPiRionzerokarmaleft: it's good error messages, I just don't understand what RankNTypes are, for instance
11:15hyPiRionOr well, I kinda get it now, but eh
11:26ToxicFrogThe type of something that returns [{} [] "a"] is (HVec Map Vec String), right?
11:28seabreddellacosta: ghc is almost 22 years old, after all.
11:28ddellacostaseabre: what is that in regard to? that's amazing though, I didn't realize it was *that* old
11:29seabreddellacosta: Well, you'd hope that in 22 years they'd figure out how to do error messages right.
11:29seabreand clojure is pretty young
11:29ddellacostaseabre: ah, yeah
11:29seabreLike 7 I think?
11:29ddellacostaseabre: but I think Clojure still has a bit of an unfair advantage there, considering we're dealing with the JVM here
11:30ddellacostain terms of exceptions. A sore spot for Clojure. ClojureScript error messages can be frustrating too. I mean, you certainly get used to them, but they are a weak point.
11:31boodleHi, new to core.async, have ~100 values in a channel, can do all kinds of side-effect-ty things with them but want to return them as a seq/coll.. or sum them (transducers) but using 1.6.. any way to do this?
11:31ddellacostaer, I guess I meant Clojure has an unfair *disadvantage*
11:32ToxicFrogddellacosta: while this is true to some extent, it does not excuse e.g. the compiler reporting syntax errors by crashing
11:33ddellacostaToxicFrog: are you talking about ghc or clojure here?
11:33tbaldridgeboodle: look at clojure.core.async/into
11:34ToxicFrogddellacosta: clojure
11:36boodletbaldridge: I did try that.. called close! on the chan before calling it but still getting an empty vector.. it doesn't need to be a go block or anything?
11:37tbaldridgeboodle: I'd need to see some code
11:37tbaldridgeboodle: can you post a gist?
11:38boodleoh wait, it returns a chan, correct?
11:38tbaldridgeboodle: yes
11:38boodleah.. trying
11:51boodletbaldridge: here's what I'm getting: https://www.refheap.com/90157 versus https://www.refheap.com/90159
11:52tbaldridgeboodle, can I see the code thats writing to the channel?
11:52tbaldridgeboodle: I'm pretty sure you have a race condition somewhere
11:55boodletbaldridge: probably due to this then: https://www.refheap.com/90160
11:56tbaldridgeboodle: yeah, if you're getting an empty vector that probably means that whatever is closing the channel is closing it before the put! code completes
11:57boodleah, any way to force put! to complete before taking? <!! ?
12:00tbaldridgenot really (I haven't seen enough of your code to know for sure) but this code is async....so things will be async ;-)
12:00tbaldridgeboodle: the key is to not close the channel until all put!s are done
12:01boodletbaldridge: sure but a bit stuck on the 'how'.. this is all being generated wihtin a page render (selmer template 'filters' acting as callbacks)
12:02boodletbaldridge: well thank you for your time and help! Will look at redo-ing the selmer/filter stuff another way
12:25lavokadhi, what a is more "valuable, better" to learn for a studen of computer science in university. "Computer engineering" or "Software Engineering"?
12:26daniel___lavokad: what r u on about?
12:26xemdetiadepends on your uni, but most unis 'computer engineering' is closer to EE stuff while software engineering is usually closer to CS
12:27xemdetiavalue depends on what you are trying to do
12:29lavokadhere in Spain "Computer Engineering" module has Desing of operating systems, design of digital systems, technologies of networks, advanced architectures, embbeded systems, security, languages of parrelel computing, configuration of networks, distributed systems application develpment, real time
12:29lavokadit is far from EE
12:29lavokadthat is why I cant decide...
12:30jcsimslavokad: which program sounds more interesting?
12:31xemdetiait also depends on your background too- uni is a great place to shore up where you are weak
12:31xemdetiawhen I went back to uni I focused more on math because I had a good foundation in systems programming
12:32clgvlavokad: software engineering usually has a lot of courses on how software projects should be organized
12:32lavokadwell I think that sofware engineering is what I will need to know, when I start working, but the classes of "Software Engineering" are all about models, quality sofware, software design ...it is all about sofware organization
12:33lavokadso maybe one can learn this reading a few books?
12:33xemdetiaorganizing the infrastructure to make good software is just as hard as writing code
12:33lavokadIn this case i would choose "computer engineering" couse it will teach a lot of concepts about programming and computer in general
12:34lavokadxemdetia:
12:34lavokadok :)
12:34lavokadthis is what I needed to hear
12:34lavokad:D
12:34xemdetialavokad, it's never wrong to actually go to the uni and ask
12:34clgvxemdetia: and even worse to measure ;)
12:34xemdetiasomething I did was look online at the syllabus for some of these classes and see what books they were using and what are the current 'popular books' on the outside
12:35lavokadI watched presentation videos, read their stuff, but it didnt make me decide
12:35clgvlavokad: yeah they usually have students counselors you can talk to
12:36xemdetiathat's something that really helped me- some of the classes I took solely because it was a book I had not even heard of and it was very interesting (compiler theory, some computer crime law, etc)
12:36xemdetiait's not always obvious what the course covers by the syllabus at the higher levels
13:17owengalenjonescan anyone see what is wrong with this ring/friend/compojure setup? basically any routes in public return an empty response /home works and /authorized seems to work but only redirects to /login which is empty https://www.refheap.com/90164
13:17owengalenjonesif I remove the call to authorize / authenticate then those routes work as well, something with how I'm using friend?
13:27xeqiowengalenjones: friend requires one of the params middleware, so it needs to be inside the site or api middleware
13:27xeqiand I don't see a credential-fn, but maybe this is from a stripped down example
13:38jeffterrellWoohoo, Cognitect's webinar on Transit is starting in 20 minutes! http://go.cognitect.com/transitwebinar
13:39mdrogalisWebinar is one of my least favorite words. D:
13:39mdrogalisRight up there with 'synergy'.
13:41tbaldridgemdrogalis: you need to embrace cross platform webinars in order to synergize your backward overflows
13:41kenrestivorefactor your webinar with synergy. it's agile
13:41tbaldridgemdrogalis: better yet: http://www.atrixnet.com/bs-generator.html
13:41mdrogalistbaldridge: Gonna reach right through my monitor and slap you for that sentence.
13:41kenrestivotbaldridge: beat me to it
13:42mdrogalisOh this is lovely.
13:42mdrogalis"efficiently reconceptualize resource maximizing networks"
13:42dorkmafiathere are more people in #clojure than in ##java
13:43tbaldridgedorkmafia: might say more about the types of people that use IRC than anything else ;-)
13:43dogonthehorizondorkmafia: I think that recently speaks to the go-getter, upward trending nature of the Clojure language
13:43dogonthehorizonrecently -> really
13:43dorkmafiaheh
13:43dorkmafiado irc rooms have a limit to the number of people?
13:43tbaldridgecase-in-point, whenever I mention IRC to someone not in the fringes of programming the reaction I get is "IRC is still a thing?"
13:44xemdetiathere are other groups that still use irc heavily aside from programmers
13:44jeffterrellI was pretty impressed at the last Cognitect webinar, on core.async.
13:44dorkmafiafreenode is the place to be
13:45jeffterrellIt's not a sales presentation, but a technical one, for Clojure folks like us.
13:45technomancyjava channels are sad places where questions come to die
13:45dogonthehorizonIt could also be that #clojure is an official channel while ##java is technically not? I don't know, I'm newer to the irc culture than most :P
13:45kenrestivostackoverflow seems to have stolen a lot of the "how the hell do i...?" juice
13:46xemdetiairc just attracts a certain type of person
13:46kenrestivoquite honestly i feel a lot less stupid asking stackoverflow than asking on irc.
13:46technomancykenrestivo: but then your question is memorialized for all time
13:47kenrestivoindeed, but so is the answer, and everyone else's too
13:47kenrestivoand by "ask" i mean "google'
13:47technomancyoh, I thought you meant like if you were worried it was a stupid question
13:47mdrogalistbaldridge: How do I use core.async channels with webinars? Is there an API for that?
13:47kenrestivothere's just such a volume of answers for common things, in languages like java and html, css, javascript, android, etc, on stackoverflow.
13:48mdrogalistbaldridge: I think someone needs a cup of coffee.
13:49kenrestivobut what irc does well is interspersing entertaining banter amongst the technical q&a's
13:50xemdetiairc also gets visibility to weird corner cases
13:50xemdetiawhich can be very interesting
13:51technomancyit's good for learning by osmosis
13:51technomancyI feel almost qualified to answer certain clojurescript questions despite having never used it
13:51onielfaHello, I need a book recommendation. I'd like to learn Clojure and I have 0 experience with lisp-like languages, but I have an intermediate experience with functional programming, Haskell in particular. I have access in a local book store to Clojure Programming, Programming Clojure and The joy of clojure 2edition. Which book you think will be better suit for me? Thanks in advance
13:52xemdetiaonielfa, what's your favorite kind of pet project
13:52oubiwannonielfa: if you learn by looking at code, the Clojure Cookbook is a fantastic resource
13:52akayeah the clojure cookbook is great
13:52sorbo_onielfa: I’ve read and liked The Joy of Clojure
13:53oubiwannonielfa: otherwise, all of the books you've mentioned are great (I own them all)
13:53dogonthehorizononielfa: Currently working through the three you mentioned, Joy of Clojure 2ed has been my favorite so far. The pace is much quicker than the other two IMO.
13:53sorbo_what do y’all use for debugging Clojure? I mostly use tools.trace and the REPL, but not sure if there are better tools available
13:53sorbo_some have recommended hooking into the Java Debug Interface
13:54sorbo_but I sort of like to keep Java interop to a “use it when I need it” level
13:54tbaldridgeonielfa: Joy of Clojure is probably the best Clojure book and it's a bit more advanced than the others. I'd start there and move to a different book of JoC is too advanced.
13:54onielfaxemdetia: Writing small backend services, for example
13:54xemdetiaonielfa, hmm. not sure which is the best towards that end
13:54onielfawell
13:54justin_smithsorbo_: cursive is a clojure plugin for intellij idea that supports extensive debugging
13:54akathe webinar wll begin shortly please remain on the line...
13:55onielfaI am not interested in this kind of pet project
13:55sorbo_justin_smith: nice! I’ll look into it
13:55sorbo_I do like IntelliJ
13:55onielfaI am interested in learning the clojure way
13:55onielfathe lisps concepts
13:55xemdetiathere's nothing wrong with doing what you know the clojure way :)
13:55onielfato change my mindset, the same way that Haskell did it
13:55tbaldridgeonielfa: have you watched all the Rich Hickey talks/
13:56xemdetiayes that's probably a good concept starting place
13:56justin_smithsorbo_: there is also schmetterling, that hooks into jdi, and lets you interactively investigate state in stack frames in a very clojury way when exceptions are thrown. This is all done via websockets and a browser via clojurescript
13:56sorbo_I actually found that some of my philosophy courses from college were super helpful in understanding Clojure
13:56sorbo_particularly endurantism vs. perdurantism
13:56owengalenjonesxeqi: sorry got called away, not sure I understand, friend/authenticate is getting called after the app routes get wrapped by the api-defaults
13:56sorbo_e.g. “this man is the same man as 10 years ago, only he’s changed since then”
13:56sorbo_and “‘this man’ is a process applied to two atoms from different points in time
13:56justin_smithsorbo_: no resume or step options in schmetterling though (I think cursive supports these)
13:56sorbo_
13:57sorbo_justin_smith: hmm, ok
13:57justin_smithsorbo_: Hickey references these concepts in some of his talks
13:57sorbo_still interesting, I’ll look at that one too
13:57justin_smithregarding state and identity
13:57sorbo_yeah
13:57sorbo_I need to watch more of Rich’s talks
13:57tbaldridgeonielfa: I'd suggest watching most of these: http://thechangelog.com/rich-hickeys-greatest-hits/
13:57sorbo_coming from Ruby, I like having all the Lispy things I loved about Ruby
13:58tbaldridgeonielfa: Rich really goes through and explains a lot of the reasoning behind Clojure
13:58sorbo_but also I think the Clojure way of thinking about state and identity is, if not “more correct,” easier for handling large distributed systems
13:58justin_smithsorbo_: very much so
13:58bbloomsorbo_: it's easier for handling tiny systems too :-P
13:58sorbo_bbloom: haha I believe it
13:58sorbo_I converted a Node project to Clojure and it was a genuinely delightful process
13:59Bronsatbaldridge: I tried to link you this 2 times in the past but you were never here, take a look at this when you have a chance http://dev.clojure.org/jira/browse/ASYNC-86 :)
14:00TimMcsorbo_: I could really get into a presentation like "Identities and values as explained on Welcoem to Nightvale".
14:00TimMc*Welcome
14:00tbaldridgeBronsa: thanks! I'll take a look and try to get it applied soon.
14:00sorbo_TimMc: oh man, that would be awesome
14:01TimMc"This man is the same man you knew yesterday... and yet he is not..."
14:02Bronsatbaldridge: let me know if you have issues with that patch, it should fix a bunch of edge-cases around loops but also changes how some errors are handled
14:02justin_smith"ve have pervected ze prozess ov controlled mutation"
14:02justin_smith(que evil cackle)
14:03Bronsatbaldridge: i.e before (go (fn [] (<! ..))) was a "whatever not found for dispatch value :fn", now it compiles fine and throws at runtime -- old behaviour can be restored if you want, just let me know
14:03dbaschTimMc: (not= myself (yesterday-me / 2))
14:03dbaschI mean (/ yesterday-me 2)
14:04justin_smithhah
14:05justin_smitharguably the implied meaning of < rather than not=
14:05dbaschyeah, (< myself (/ yesterday-me 2
14:05dbasch)) ;; can't type
14:09justin_smithclearly your irc client lacks paredit
14:09sorbo_I wonder if you can get paredit in irc from inside emacs
14:09sorbo_the answer is probably yes
14:10xemdetiasorbo_, erc is actually pretty nice
14:10justin_smithdefinitely yes
14:10Bronsaparedit on erc in my experience is unusable
14:10justin_smithalso pretty useless
14:10sorbo_haha I see
14:10justin_smith"can you do <foo> in emacs" quickly becomes "is it actually sane to do <foo>"?
14:11xemdetiaI use erc about 50% of the time actually
14:11xemdetiahaving autocomplete from irc chatter to whatever I'm working on is handy
14:12justin_smithit's my only client - it lowers cognitive overhead to have the same UI wherever the activity is primarily textual
14:12xemdetiajustin_smith, I totally agree.
14:13Jaoodirssi has basic emacs keybindings :P
14:14Jaoodthe same ones you get in bash I guess
14:14nullptri use erc and while i don't use paredit you at least get the general purpose paren highlighting
14:14justin_smithJaood: lack of M-y kills it for me
14:14xemdetiaJaood, the point is that any tool I'm used to using is always there no matter what
14:14justin_smithto coin a phrase
14:14nullptrshow-paren-mode
14:15justin_smithnullptr: or rainbow parens!
14:15ToxicFrogThat'
14:15zotanybody use clostache, and happen to know of a simple way to use partials in a way that doesn't require knowing-in-advance which other templates have to be loaded? (i could use a regex parser to see, and load per template, but maybe i'm missing a more obvious/cleaner sol'n)
14:15ToxicFrogs something I really miss in ST. No rainbowparens.
14:17onielfaSorry, I was away from the computer. Coming back to the clojure book recomendations. I have watched some of the Rich Hickey videos, and that's why I have so much interest in learning Clojure. I am very tempted to buy the The joy of Clojure but I don't know if it will be too much to start off.
14:19justin_smithonielfa: its a good book if you already have lisp background, but not a great intro level book
14:19dbaschonielfa: you should check it out, and if it's too much leave it for later. It's definitely worth reading at some point
14:19Jaoodany opinions on smartparens vs paraedit? I started with smartparens and I haven't tried paraedit yet
14:20technomancyJaood: afaict smartparens has the edge with non-lisps
14:20technomancyJaood: smartparens behaviour out of the box is pretty crap though
14:20Jaoodtechnomancy: even using their default config?
14:20technomancyJaood: last I checked
14:22onielfajustin_smith: so I buy joy and which one also to start off?
14:22JaoodI'm still tweaking it but their recommended default config didn't seem so bad to start with ;)
14:23Jaoodbut maybe is just me not being a power user of that style of editing yet
14:23justin_smith,(shuffle ["clojure" "programming"]) ; onielfa
14:23clojurebot["clojure" "programming"]
14:23justin_smithit could have been the opposite easily :)
14:24dogonthehorizonClojure Programming is a bit shorter in length, FWIW
14:24dogonthehorizonsorry, reverse that
14:24dogonthehorizonProgramming Clojure*
14:24Jaoodonielfa: Clojure programming is nice to start with, you really only need like half of book ;)
14:24Jaood+the
14:25justin_smithglad to hear the shuffle chose wisely
14:28dbaschonielfa: you can also start with a good intro on the web, and move on to tjoc when you feel ready
14:29dbaschonielfa: e.g. http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome or http://www.braveclojure.com/
14:31dorkmafiawhen you use a create a checkouts dir and use a local library does it pick up that projects deps?
14:33justin_smithdorkmafia: I find using "lein install" to add my lib to the private local repo and then adding it as a normal dep to be much simpler than checkouts
14:35technomancydorkmafia: checkout deps are not transitive
14:35guest889any clojurians from Egypt¿
14:37dorkmafiajustin_smith: if i do that and update the lib will it just pick up the changes?
14:37justin_smithdorkmafia: no, you will need to re-run "lein install"
14:38justin_smithdorkmafia: that is the drawback
14:38justin_smithbut that is still simpler than checkouts, in my experience
14:38dorkmafiaah ic well checkouts isn't so bad then heh
14:38dorkmafiajustin_smith: have you ever used jython?
14:38justin_smithI've used tools that embedded it, but I have not programmed with it directly
14:39dorkmafiai'm trying to figure out how to get it to use my lib
14:39dorkmafiawell the skype4py lib
14:40blaenkI'm trying to figure out why my project hangs on lein uberjar on a separate computer
14:40blaenkit works perfectly fine on mine
14:41blaenkI diff'ed lein deps :tree from both and they're identical, if that's any indication of anything
14:41justin_smithlein versions?
14:41justin_smithwritable directory?
14:41blaenkI also looked around for anything that may be evaluating at compile-time but I didn't find anything, and afterall the same exact code is working on the one computer
14:41blaenkwill check
14:41mdrogalisCan anyone think of a way to use something like Schema to validate that a map is solely composed of keywords?
14:42mdrogalis(arbitrarily deeply map)
14:42blaenkjustin_smith: yeah they're identical versions. 2.4.3, perms are fine too
14:43justin_smithweird
14:43blaenkyeah, very
14:43blaenkit just prints out one message, 'compiling <some.ns>' but there's nothing unusual about that ns
14:43hiredmanblaenk: likely you are doing something sideeffecty in a top level form, which clojure executes, and it happens to hang on one computer and not the other
14:43hiredman(def db (connect-to-db-with-infinite-retries))
14:43blaenkthey're the same compilers too though. but yeah I looked around for something like that and the only thing I could find was a kroma defdb form
14:44blaenkahh, wasn't aware of retries
14:44blaenkwill try removing that for now
14:44justin_smithblaenk: you can use jstack to find out what lein is doing while hung
14:44hiredmanI mean, I dunno
14:44blaenkthanks I'll check that out
14:45justin_smithjstack <pid-of-lein>
14:45blaenkawesome
14:46hiredmanwell, the lein pid won't tell you much, you need the pid of the child jvm
14:46hiredman(project jvm or whatever lein calls it)
14:46justin_smithhiredman: good point
14:47blaenkyeah I got that one
14:47dorkmafiais there a way to force clojure to run on 32 bit jvm?
14:48hiredmandorkmafia: if you use a 32bit jvm to run clojure it runs on a 32bit jvm
14:48justin_smithdorkmafia: you can tell lein which jvm to use :jvm-cmd
14:48justin_smith(in project.clj)
14:48hiredmanclojure doesn't pick a jvm to run on, it is just a jar
14:48justin_smiththere is an env var too
14:48blaenkI think I got the correct pid, and it seems like it's waiting for something https://gist.github.com/blaenk/bf8edfea2b2b3b2599a9
14:48hiredmanclojurebot: lein
14:48clojurebotlein is http://github.com/technomancy/leiningen
14:48hiredmanclojurebot: lein |is not| clojure
14:48clojurebotA nod, you know, is as good as a wink to a blind horse.
14:49hiredmanblaenk: that is the lein jvm, not the project jvm
14:49dorkmafiacoo i'll check out the jvm-cmd thanks
14:49justin_smithdorkmafia: env LEIN_JAVA_CMD="/path/to/32bit/jvm" lein ...
14:49blaenkhmm
14:49hiredmanjps will list the pids of running jvms
14:49blaenkthanks
14:49dorkmafiacan i put that in my .lein profiles?
14:49hiredmanunfortunately clojure jvms tend to just show up with the name "main"
14:49blaenkyeah haha
14:50sorbo_just coming back to this, +1 for http://www.braveclojure.com/
14:50blaenkI think I found the project one. it's the one with a large classpath right?
14:50dorkmafiathere is also jvm-opts
14:50blaenkwith all my project's dependencies
14:50sorbo_sort of a spiritual successor to _why’s guide (Ruby)
14:50justin_smithblaenk: yes, probably
14:51blaenkalright I updated it https://gist.github.com/blaenk/bf8edfea2b2b3b2599a9
14:52blaenklooks like line 130
14:52justin_smithblaenk: that thread that is at FileDescriptor.sync looks suspicious to me - it should not be spending very long on that
14:52justin_smithblaenk: oh yeah, 130 does look suspicious :)
14:52blaenkseems like something with pandect
14:52blaenkline 107 I think more so
14:52SegFaultAXsorbo_: Haven't thought about _why's stuff in a while.
14:52blaenkyeah I think it's pandect
14:53blaenklook at line 61, pandect
14:53sorbo_SegFaultAX: yeah, ditto. I think about him and his work every now and then
14:53sorbo_wonder what he’s up to these days
14:53justin_smithblaenk: so I had the right stack trace, just alerted to a different suspicious part of it :)
14:53SegFaultAXsorbo_: Probably still being awesome. :)
14:54sorbo_hopefully!
14:54blaenkweird thing is I'm using pandect on my computer too, and it doesn't cause any problems there
14:54justin_smithblaenk: it is trying to download something, maybe it is a cached download, so you don't notice it locally
14:55blaenkwow, surprised it's trying to download something
14:55justin_smithmaybe I am misreading that...
14:55blaenkdefinitely seems like pandect though no?
14:55blaenkhttps://github.com/xsc/pandect
14:56amalloyjustin_smith: what?? what makes you think it's trying to download something? it looks like it's trying to write a classfile while AOT compiling
14:56elbenI need to (do a b c), but return b. On the top of my head, I can think of using try/finally, or a temp atom, or (let [_ a r b _ c] r). Any other idea?
14:56hiredmanyeah, I see nothing in the stacktrace about downloading anything
14:57technomancyelben: sometimes doto can be handy for that
14:57amalloyone of the namespaces that pandect.impl.message-digest depends on could be generating arbitrarily-many classfiles, via some infinite loop at compile time
14:57justin_smithamalloy: oh, right. I totally misread what was happening there.
14:58elbentechnomancy: not useful here, because ‘a’ and ‘b’ are java interops for resetting and closing a stream object
14:58amalloyhttps://github.com/xsc/pandect/blob/master/src/clojure/pandect/gen/hash_generator.clj looks vaguely suspicious with the nested defprotocols, but i don't think it's really an issue
14:58blaenkthere's a new stacktrace, I'll paste it
14:58blaenkI mean, it's been running and I just noticed that jstack shows something new, same style though
14:58blaenkokay, it's actually compiling the rest of the files now, it's like it was caught up on something
14:59blaenkit's like it took ages to compile pandect, or something
14:59amalloyblaenk: are you running this on a really slow filesystem, like over sshfs or something silly like that?
14:59hiredmanmaybe pandect probes the jvm to see what digests it supports and generates class files based on that and the jvms are different and one supports lots of digests
14:59blaenknah, well I'm ssh'ed to the other computer but no not on a mounted remote fs or anything
14:59blaenksounds plausible
15:01blaenkit's compiling stuff, it seems, from running jstack multiple times, it's just going very slow
15:01blaenkthe computer is much faster than mine however
15:02blaenkbarely 2/64GBs used
15:02blaenkand very low load across the 8 cores
15:02amalloyGBs...used...? what does that have to do with faster?
15:02amalloyblaenk: the disk is the bottleneck here, nothing else
15:02blaenknothing, I was wondering if maybe it was low on memory and so it was going to disk? idk
15:02justin_smithamalloy: less data fighting for CPU cache lines?
15:04blaenkwell at least now that the files are cached, it doesn't take too long to rebuild
15:04blaenkI guess at first I thought it was hung since it was taking forever, waited 5 minutes for it on the same ns
15:06TimMcamalloy_: I've been wonderinf if my encrypted filesystem is why compiling CLojure is so slow on my machine.
15:06hiredmandefinitely
15:07TimMcIs that based on write-then-read latency? Throughput is generally good on this fs...
15:07justin_smithTimMc: I have had much luck with putting non-sensitive / higher data throughput needed stuff on a secondary drive. Luckily those things often go together for me.
15:08hiredmancompared to what?
15:09TimMchiredman: I dunno, I just don't have trouble reading/writing large files.
15:09TimMcjustin_smith: I've seriously considered mounting a ramdisk for target...
15:12hiredmanencrypted filesystems encrypt things, non-encrypted filesystems don't, encrypted filesystems do more, doing more takes more, qed
15:13hiredmanI could easily imagine an encrypted filesystem were large files are the optimal case
15:13TimMchiredman: Right, but it doesn't noticeably impact most operations on my computer -- compiling Clojure is ht eonly thing that seems to be a problem.
15:14Jaoodall those little class files
15:14TimMcI sprinkled a codebase with printlns and :verboses and it was compiling a defn once a second. :-(
15:15hiredmanthat does seem excesively slow
15:15TimMc(possibly a factor 2 on either side of that)
15:15TimMcAnother reason to get rid of AOT!
15:16hiredmanI would check to see if you have the same problem outside of lein
15:16TimMcMaybe write a program to slurp all the classfiles out of a target/ and spit them somewhere else?
15:16TimMcor you mean compile "manually"
15:17hiredmanthat
15:17TimMcWorth a try.
15:17owengalenjonescan anyone see what is wrong with this ring/friend/compojure setup? basically any routes in public return an empty response; /home works and /authorized seems to work but only redirects to /login which is empty https://www.refheap.com/90164 If I remove the call to authorize / authenticate then those routes work as well, some problem with how I'm using friend?
15:18TimMcI should also try compiling on a ramdisk.
15:29xeqiowengalenjones: (-> app defaults authenticate) does authenticate first, then the default middleware, then the app routes
15:30xeqifor getting an opportunity to modify/handle the request
15:30xeqibut friend needs the params middleware to have already happened
15:31owengalenjonesxeqi: if I reverse the threading so that authenticate is first, then any of the routes results in chrome downloading an empty file
15:32xeqiyou don't need to reverse all of them. You still want app to be the last one to handle the request
15:33xeqijust defaults and authenticate. That way the default middlewares handle the request first, then friend gets to look at it, then your app handles it
15:34owengalenjonesxeqi: sorry I mean if the app-site threading is reversed https://www.refheap.com/90174 then hitting any route except for /home results in chrome downloading an empty file instead of displaying html
15:39hiredmanthat defroutes at the bottom looks weird
15:39hiredman(but maybe that works to concatenate routes, and I've just never done it)
15:39owengalenjoneshiredman: I believe so, at least I have found several examples of people combining routes like that
15:40xeqiowengalenjones: what happens if you switch the order the routes in site-and-api?
15:41xeqiso that public-site is first
15:42bultersanyone here watched the videos from purelyfunctional.tv?
15:43owengalenjonesxeqi: then the routes from public work but the ones from app return an empty response :-/
15:44amalloyTimMc: the clojure compiler calls fsync all the time. that's probably not the optimized-for usage on an encrypted fs
15:44TimMcamalloy: Aha.
15:44amalloy(note, eg, that blaenk's compiler was stuck on fsync every time he got a stacktrace from it)
15:45amalloyowengalenjones: having two different routes wrapped with handler/site-defaults looks super-sketchy
15:46amalloythat sounds like the kind of route that wants to be last and only-once
15:46owengalenjonesamalloy: right thats an artifact, Im trying to wrap one in site-defaults and the other in api-defaults
15:48amalloyyou can't just have two top-level-looking routes one after another. like if your route/not-found is before any of your other routes, it will trigger before them and cause them never to be looked at. the stuff in wrap-defaults could be similar
15:54arohneris there a way to check if a core.async channel has something in it, without taking?
15:54arohneror blocking
15:57bbloomarohner: any such query would risk a race condition
15:58amalloybbloom: only if you presume that the next <! should be guaranteed to not block
15:58amalloyit could be useful as a diagnostic feature for approximating stuff, like is my channel usually full or usually empty
15:59fifosineHere: http://clojuredocs.org/clojure_core/clojure.core/defstruct, someone has commented that it's preferred to use defrecord over defstruct as defstruct is obsolete. Is this true?
15:59amalloyyes
15:59arohnerok, acquiring the lock is fine. I don't want to take, and I don't want to block until a value goes on the chan
15:59hiredmanI think it is better to think of channels as a synchronization point, not as a collection that contains things
15:59amalloyarohner: you want to not block, but acquiring a lock is fine??
15:59lazybotamalloy: Definitely not.
16:00hiredmanthat said, there is value in able to ask "is someone waiting here?"
16:00arohneramalloy: I changed my mind about 'block'
16:00dnolen_arohner: there's no way to do that and there is unlikely to ever be.
16:00bbloomarohner: rewind a step and explain more generally about what you're trying to accomplish
16:01hiredmanjuc has some nice things for that, I find phasers are very useful
16:01arohnerI have a thread that's in an infinite loop processing events as they arrive. I need a signal to stop the thread
16:01stuartsierraarohner: Closest you can get is `alt!` with a default and :priority true.
16:01arohnerI know I can use a second go-loop, just felt verbose
16:01bbloomarohner: yeah, use two channels + alt
16:02hiredmanarohner: either close the channel it recieves on, or have another channel to signal close
16:11tbaldridgearohner: the problem with looking but not taking is that the answer will often be wrong. Perfect way to create a race condition.
16:16xeqiowengalenjones: working example - https://www.refheap.com/90176
16:18xeqiit looks like handler/site-defaults happening twice would cause a problem
16:18xeqiprobably something similar for site-defaults and api-defaults
16:19xeqiI usually try to use a `context` to move all of the authenticated routes somewhere, so that the different middlewares can be applied safely once
16:20xeqisomething like (routes (context "/app" (-> app-routes friend api-middleware)) (-> public-routes site-middleware))
16:22xeqipossibly with a 404 as the last one in app-routes, since there is an url difference between app and public
16:24owengalenjonesxeqi: ahhhh yes
16:25owengalenjonesalso
16:26xemdetiaIs there anything better than base64
16:26xemdetiafor doing base64 things
16:27TimMcbase65
16:27owengalenjonesxeqi: thank you so much, this was driving me crazy
16:29xemdetiaTimMc, the sad thing is I see a base65 on github
16:29xemdetianow I don't know if you are lying to me or not
16:33TimMc:-D
16:34TimMcBase64 is good because 6 and 8 have a relatively high GCD.
16:34TimMcerr
16:34xeqiowengalenjones: np. I seem to have gottne the flash stuff wrong, but hopefully you can take it in the way you need from here
16:34TimMcnot 1, that is :-)
16:38amalloyhuh, interesting. if you disassemble (fn [] [0]), it turns out that the value [0] is stored in the class's constant pool as an AFn. i would have expected either PersistentVector or Object; something in the middle is weird
16:38xemdetiayeah TimMc I'm just suddenly faced with the problem of 'base64 isn't quite small enough'
16:40TimMcxemdetia: What bytes *can't* you use?
16:40xemdetiaexactly all of them are important
16:40xemdetiaI need to squeeze the source more
16:40amalloyjust use base2. send it in binary
16:40technomancypff--morse code, come on
16:40amalloyit turns out this is the underlying transport used by ethernet
16:41dbaschxemdetia: bitcoin uses base58
16:41xemdetiaamalloy, for what I am doing the underlying transport is humanz
16:41xemdetiahence base64
16:41amalloyso use like, base 26
16:41amalloymaybe 36
16:41dbaschxemdetia: base58 was meant to remove human ambiguity when reading
16:41xemdetiadbasch, that's interesting
16:42amalloydbasch: i see. 58 removes O0o Il1 or something?
16:42dbaschamalloy: yes http://en.wikipedia.org/wiki/Base58
16:42technomancybase25; remove the ambiguity between U and V for ancient roman users.
16:42amalloytechnomancy: you need to scale down to 24 for rome
16:43technomancysorry, "AMBIGVITY"
16:43technomancyamalloy: oh right, I and J too
16:43clojurenoobgreetings!
16:44nairobiclojurenoob: hello
16:44clojurenoobI have a very simple question that I've been unable to resolve with stack overflow inquries...
16:44clojurenoobIf I have two vectors, how do I determine which entries appear on one vector but not on theh other?
16:45clojurenoobI've been playing with map and .indexOf and filters but they all seem to fail on me for some reason
16:45bbloomclojurenoob: what else can you tell us about the vectors? size, order, etc
16:45clojurenooblets say for example, twenty items in each vector
16:46clojurenooborder does not matter
16:46bbloomdo the simplest possible thing: convert to a set, use filter, etc
16:46bbloom,(require 'clojure.set)
16:46clojurebotnil
16:46nullptr,(difference (set [1 2 3]) (set [2 3 4]))
16:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: difference in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:46TimMcamalloy: What do you mean [0] gets stored as an AFn? Like, something that implements IPersistentVector and so forth?
16:47clojurenoobalright lets try that.
16:47nullptr,(clojure.set/difference (set [1 2 3]) (set [2 3 4]))
16:47clojurebot#{1}
16:47amalloyTimMc: i mean, the concrete class is obviously PersistentVector. but it's stored like: public static AFn const__0;
16:47dbasch,(remove (into #{} [1 2 3 4 5]) [2 3 4 5 6 7])
16:47clojurebot(6 7)
16:47clojurenoobthanks, brb, let me try this out
16:48bbloomdbasch: (into #{} ...) is just clojure.core/set
16:48dbaschbbloom: yes, but shorter :)
16:49amalloyand then the static initializer is something boring like static {const__0 = new PersistentVector(new Object[] {0});}, of course. i just found it interesting that the declared type is AFn
16:49dbaschbbloom: actually longer, never mind
16:49dbaschhabit
16:52clojurenoobYAY! Fantastic thanks for your help.
16:52clojurenoobboth solutions worked
16:52clojurenoobSo thank dbasch and nullptr
16:53TimMcamalloy: Ah, weird indeed.
16:53clojurenoobmuch appreciated
16:54dbaschbbloom: actually into #{} is much faster than set
16:54bbloom(source set)
16:54bbloom,(source set)
16:54clojurebotSource not found\n
16:54bbloom&(source set)
16:54lazybotjava.lang.RuntimeException: Unable to resolve symbol: source in this context
16:54bbloom$source set
16:54lazybotset is http://is.gd/Mya7JM
16:55bbloomdbasch: if that's the case, it sounds like clojure.core/set is just broken
16:55amalloybbloom: yes
16:55amalloyit doesn't use transients
16:55technomancyit's just old
16:55bbloomsurely there should be a ticket for this....
16:56amalloyso maybe i'm stupid, but i only today realized i can use no.disassemble to disassemble arbitrary java objects, not just clojure functions
17:01noncom|2if (def my-symbol "java.io.File") then how do i pass it to import so that (import my-sympol) would be equal to (import 'java.io.File") ?
17:01clojurenoobI am really enjoying functional programming. Once you get past theh mindscrew of not having loops, vars, mutability, etc... It can be quite a bit of fun!
17:02bbloomclojurenoob: more of a mind UNscrew :-)
17:05clojurenoobyeah, when you putit htat way...
17:05noncom|2figured out: (eval `(import ~my-symbol))
17:06amalloynoncom|2: that is just a totally bizarre thing to do. you don't need to import a class to use it
17:06amalloyall import does is let you save some characters when typing the class's name; if you don't know the name at compile time, you're obviously never typing it, so what is the import buying you?
17:06amalloyif for some reason you really wanted to do it, you don't need to eval: import is just a function: (import (symbol my-symbol))
17:06noncom|2amalloy: really..
17:07noncom|2right, i do not have to import it..
17:08noncom|2i can do (.newInstance (Class/forName "ClassName"))
17:09noncom|2yeah..
17:09amalloywhat are you doing that makes you think you want to use eval, class/forName, and runtime import? if you're not writing an IDE or a repl or something, or *maybe* a plugin system, you probably don't need any of those things
17:13noncom|2amalloy: an kind of an ide, right. :)
17:13rweirhighly recommend explaining precisely what you're doing, since it feels very XY-y
17:14rweir(same thing happens in python a lot - people discover eval/exec/__import__/etc and start using them when there are much simpler solutions for whatever they're doing)
17:16noncom|2rweir: umm.. well, i have a media software development IDE built on top of the jmonkeyengine 3 which has to load and run java sketches written in processing in order to pass the texture they generato into a jmonkey texture in real time..
17:16noncom|2so the sketches can be dynamically loaded from files in any time too
17:16noncom|2since textures for sketches can be created in real time
17:17noncom|2so them are like plugins too... yeah, i guess youre right
17:19noncom|2still i think that using a classloader for the java source files will prove right in the end..
17:30ghadishaybanbbloom: there is in fact a ticket for set+transient
17:30ghadishaybanas well as zipmap
17:46noncom|2oh no, again i am having the problem with leiningen being unable to find javac... could somebody please remind a fix to this..
17:46noncom|2i have added jdk path to PATH
17:47zotis there a way to cross this java/class boundary? (filter .isFile (file-seq (io/file "/tmp")))
17:47zotCompilerException java.lang.RuntimeException: Unable to resolve symbol: .isFile in this context, ...
17:50tuftzot: (filter #(.isFile %) [])
17:51zotironically i just thought to try that. and while it does compile, it returned directories. i must be doing sth else stupid.
17:53ghadishayban,*clojure-version*
17:53clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
17:54ghadishayban,(transduce (map inc)
17:54ghadishayban (completing conj! persistent!)
17:54ghadishayban (transient [])
17:54ghadishayban [1 2 3 4 5])
17:54clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:54ghadishayban,(transduce (map inc) (completing conj! persistent!) (transient []) [1 2 3 4 5])
17:54clojurebot[2 3 4 5 6]
17:54ghadishaybanlove that new idiom
17:54amalloyi don't think it's so much an idiom as a function
17:54justin_smithvery cool
17:59noncom|2does anyone use ccw here ? how do i setup the path for javac for ccw ?
17:59justin_smithnoncom|2: any particular reason to using ccw instead of cursive?
18:00justin_smithoh, different IDE, never mind
18:00noncom|2yeah, just being an eclipse fan... idea is good too, but historically i happen to use eclipse.. would you advice trying cursive ?
18:01noncom|2i also try emacs..
18:01justin_smithemacs is a whole other fish, if you already have a favorite environment it makes sense to stick with that
18:01justin_smithI just forgot that ccw wasn't for idea
18:28celwellHi, if I have a vector of maps, what is an idiomatic way to get the map that contains a certain value for a specific key? (e.g., get the map that has an :id of 5 in [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}], ultimately I need to get "Tom".)
18:32amalloycelwell: ideally you would use a more suitable data structure, like a map from ids to attributes
18:32celwellamalloy: well it's coming from another func that get's it from a database
18:33justin_smithcelwell: group-by helps
18:33amalloysure, and once you're done reading from the database, put it into a useable data structure
18:33amalloyyou don't want your whole program to be scanning back and forth over rows forever just because that's how the database gives you values
18:34celwellgroup-by should work nicely, thanks forgot about that
18:34falafel,(->> [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}]
18:34falafel (filter #(= (:id %) 5))
18:34clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:34falafel,(->> [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}] (filter #(= (:id %) 5))
18:34clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:34falafelok
18:35falafel(->> [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}](filter #(= (:id %) 5)))
18:35falafel,(->> [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}] (filter #(= (:id %) 5))
18:35clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:36falafel,(->> [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}](filter #(= (:id %) 5)))
18:36clojurebot({:name "Tom", :id 5})
18:36falafelfinally!
18:36amalloyfalafel: type it into a real repl, get it working, then demonstrate here :P
18:36falafellol
18:36falafelamalloy: I did, but I was copy/pasting from vim from the wrong buffer
18:37justin_smith,((group-by :name [{:id 1 :name "Chris"}{:id 3 :name "Jon"}{:id 5 :name "Tom"}]) "Tom")
18:37clojurebot[{:name "Tom", :id 5}]
18:37celwellfalafel: every vim buffer is wrong, should have used emacs. thanks though.
18:37falafellol, carpal tunnel no thanks
18:44justin_smithturning caps lock into a control key, and control into xcomponse, has had very nice results
18:44amalloythumb? hitting Ctl with a thumb seems pretty hard
18:45p_lamalloy: the trick is to use opposite hands
18:45celwelljustin_smith: I had caps for C- but i still had pinky pain, i guess i'm just weak
18:45justin_smithmaybe you just type more than me
18:45p_lthough I'll admit to remapping caps from habit :)
18:46amalloyp_l: i'm aware of that trick, but i still dno't know how i would hit either control key with either thumb, without having to go way off home row
18:46justin_smithalso, I have a kinesis freestyle, which allows my hands to be further apart, which helps with just about everything
18:46amalloyjustin_smith: i've had caps-as-ctl for years now, but i've just left ctl as another control. i guess compose sounds pretty nice, maybe i should try it
18:46p_lamalloy: doesn't help that many modern keyboards, well, suck
18:47amalloymine sucks, but it's full size. not a mac mini keyboard lite
18:47celwelljustin_smith: i play guitar and piano in my downtime so my fingers don't really get a break
18:47justin_smithcelwell: viola here
18:48clojurenoobquestion, how reaistic is using lighttable for a smaller clojure project?
18:49clojurenoobis it normal to have so many people joining and leaving in such short intervals?
18:49p_lclojurenoob: do you need to deal with non-clojure parts?
18:49p_land yes, that's why many people have filters that hide joins/parts
18:49clojurenoobp_l some text files, but I haven't hit too many issues so far.
18:50amalloyclojurenoob: yes, that's pretty normal. it's a crowded room. you want to configure your client to hide at least most of those
18:50p_lclojurenoob: I meant mostly in terms of "calling java" :)
18:50p_lmy experience was rather... bad
18:50amalloymine hides join/part of anyone who hasn't been talking ni the last few minutes
18:50clojurenoobah right, nope. NO real libraries I plan on using
18:50clojurenoobI'd use eclipse or something to navigate the infinite namespace that is the java core...
18:50celwellclojurenoob: ibdknox (creator) seems to be online.
18:50justin_smithclojurenoob: for a small enough project, you could probably get away with using ed. light table should be fine.
18:51clojurenoobseriously, celwell? That's awesome.
18:51justin_smithin the channel doesn't mean paying attention to the channel, but yeah ibdknox is logged in
18:58amalloyjustin_smith: now that i've turned on my compose key, i can type devilments like this: (let [a 1, a 2] a) ;=> 1
18:59justin_smithsee, the benefits start already
18:59justin_smithluckily, emacs displays nbsp in a bright underlined face
19:00amalloyyeah. i have a hard time telling it apart from underscore, in emacs, but i guess it is different
19:03Bronsa _
19:03Bronsayou can definitely tell them apart when they're near
19:49stompyjwhats the “correct” way to require the “HEAD” version of a lib that has fixes you need, but hasn’t been pushed to clojars yet/
19:49stompyjfork+self-publish?
19:50amalloystompyj: yeah
19:50stompyjdanke
19:56dbaschbbloom: you probably saw this ticket already http://dev.clojure.org/jira/browse/CLJ-1384
19:56nooniancan also just lein install locally if you don't need to publish your code right now
19:56splunkis there an easy way to identify namespace dependency cycles
19:57justin_smithsplunk: don't they fail to compile?
19:57johncashwhy does (keyword INT) return nil rather than throw exception?
19:57splunkjustin_smith: not clear--possibly?
19:58splunkjustin_smith: not sure what type of error message to expect with a cycle
19:58nooniansplunk: you won't be able to run the code or load it in a repl, it will give some message about a dependency cycle hehe
19:58splunknoonian: ah okay thanks. so what I have must be something else.
19:58splunknoonian: thanks!!
19:59nooniansplunk: welcome!
19:59noonian,(keyword INT)
19:59clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: INT in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:00noonian,(keyword 8)
20:00clojurebotnil
20:00justin_smithsplunk: Caused by: java.lang.Exception: Cyclic load dependency: [ /cyclic/core ]->/cyclic/big->/cyclic/apple->[ /cyclic/core ]
20:00justin_smiththat's with a three way dependency circle
20:01justin_smithfirst line of the exception: Exception in thread "main" java.lang.Exception: Cyclic load dependency: [ /cyclic/core ]->/cyclic/big->/cyclic/apple->[ /cyclic/core ], compiling:(cyclic/big.clj:1:1)
20:01justin_smithmuch clearer than most clojure errors actually
20:04splunkhaha indeed
20:05splunkI'm working with `lein test-refresh` and all of a sudden it's giving me protocol loading errors. Probably something I just broke. Thanks.
20:05nooniansplunk: i'd recommend running lein clean every once in a while
20:05noonianif you are aot compiling you can get protocol errors similar to that
20:06justin_smithsplunk: protocols and reloading code don't work together very nicely
20:06justin_smithnoonian: well, lein test-refresh stays running, reloading namespaces and rerunning tests, that is going to break with protocols I would think
20:06amalloyit's just the angry spirit of technomancy, come alive in your code to remind you that he hates protocols
20:06justin_smithheh
20:07splunkcurssesss!!!
20:08technomancydon't say I didn't warn you
20:08splunkholy smokes, yes, we tried to turn on AOT for uberjar, and yes lein clean just fixed a whole bunch of it
20:09noonianjustin_smith: yeah, i work around those issues by using a 'reloaded'ish workflow, but i don't use anything as fancy as test-refresh
20:09technomancyevery time someone says "lein clean fixed my problem" I hear "lein clean removed the symptoms of my problem so I can continue without addressing the actual cause"
20:10splunktechnomancy: what in your mind is the problem? the protocols, as opposed to the reloading?
20:10splunkor the reloading is the problem?
20:10technomancyreloading is what makes programming not unbearably tedious
20:11dbaschtechnomancy: bearably tedious?
20:11justin_smithtechnomancy: http://i.imgur.com/tXkAcGY.jpg
20:11splunkokay, so it's just a question of making the protocols compatible with the reloading. I've heard, as noonian just mentioned, that the "reloaded" workflow is supposed to solve this
20:12technomancybut supporting reloading well has a cost in terms of performance in very tight bottlenecks; protocols are designed to allow you to improve performance in exchange for reloading support, which is what you have to do to get self-hosted
20:12splunkbecause, something something, objects/values in memory get re-initialized with proper references to the properly reloaded protocols
20:15splunkokay, so the goal would be get abstractions and/or polymorphic dispatch without the protocols.
20:15splunkmultimethods being available the solve the latter, and like, something else longer discussion for the former about what it means to flexibly support abstractions / expression problem, whatever.
20:16nooniansplunk: i'd also try to avoid storing state in Vars and just have your entry point function build your system
20:22splunknoonian: yeah I have to dig into somebody else's code to uproot that
20:23jfojtlhi, is there any sample web application written in clojure? Something that could server as a tutorial, but complete app?
20:24technomancyjfojtl: https://syme.herokuapp.com maybe; it's ~500 lines but complete and nontrivial.
20:25splunkjfojtl: also, see more: https://github.com/clojure-cookbook/clojure-cookbook/tree/master/07_webapps
20:25dbaschjfojtl: and https://devcenter.heroku.com/articles/clojure-web-application
20:26jfojtlthanks guys
20:26jfojtlwill check it out. I knew about the cookbook, however I did not consider that as a complete app
20:28jfojtltechnomancy: that's what I like about clojure. Non trivial things solved in trivial/simple/short ways
20:46bbloomhere's a crazy question one of you fun crazy people may be able to answer.... YourKit's memory profiler can tell me which objects are highly referenced, but is there a way to get it (or something else) to tell me which / how-many / what-percentage-of objects have a ref count of 1?
20:48ghadishaybanbbloom: step one, jmap -dump for a heap dump
20:48ghadishaybanstep two: browse the generated heap dump with 'jhat', another built in tool
20:49bbloomghadishayban: ok thanks i'll check those two out
20:50ghadishaybanit starts a webserver that allows you to (among other things) run a little SQL dialect over the heap graph
20:52bbloomghadishayban: holy hell, this is awesome
20:54ghadishaybanI don't know how to do it with YourKit, but jhat and jmap are built into openjdk
20:54bbloomghadishayban: do you know if there is a way to run such a query without the browser?
20:54bbloomie in the console & get plain text out?
21:07ghadishaybanmight take like 10 minutes to start depending on the size of the dumped heap
21:11cflemingbbloom: Eclipse MAT is also really useful for those sorts of things, it also has a query language
21:11Bird|otherboxwill add-break-thread! allow a thread to be broken into via Ctrl-C if it's stuck in code completely outside the JVM's purview? (i.e. passing something to a native library that leads to a runaway exercise bike of sorts, my personal experience was with SQLite + JDBC taking a day or more to produce an OutOfMemoryException after a buggy join generated a result set almost 4 *billion* rows long)
21:12cflemingbbloom: An ex-workmate of mine was a wizard with the OQL, but I never played with it much myself.
21:13zenoliAnyone else having an issue with CIDER? I just updated, and I'm now getting "No response handler with id nil found".
21:13zenoliThe debug output points to nrepl-client-filter as the origin.
21:16zenoliThe error happens when trying to connect to an externally started REPL, and connection does not complete.
21:17zenoliVersion is 2014912.503.
21:17zeituequestion what book would be good for a beginner who has no programming knowledge to learn Clojure?
21:18Bird|otherboxI'd probably be more inclined to start them in another language first
21:18Bird|otherboxClojure is still in a phase where the tooling is a bit immature and even intimidating
21:18TEttingerBird|otherbox, yeah like java maybe. java's a surprisingly good language for beginners
21:19Bird|otherbox(some of the exceptions I get at the REPL somedays leave me scratching *my* head)
21:19zeitueyeah the java exceptions are pretty bad
21:19Bird|otherboxTEttinger: I'd personally argue that Python would be a better starting point. Java's *too* limiting
21:20TEttingeror even javascript, since you really need almost nothing to get started and can apply the knowledge quickly
21:20zeitueI see your point guys
21:44technomancyracket is great for beginner programmers
21:44technomancyhttp://htdp.org <3
21:45technomancymuch easier to transition to clojure from later since they already have homoiconicity and immutability by default
21:45technomancyplus the educational materials are top notch
21:45technomancyoh, he left =(
21:48caternbut muh sicp
21:53kenrestivohuh, start-stop-daemon really hates lein bin.
21:54kenrestivoi guess lein bin emits things that look like ":;exec java -XX:PerfDataSamplingInterval=10000 -client -D .....", and start-stop-daemon can't exec them
21:55truebudditechnomancy: any advice for experienced OO dev to "thinking in clojure" ?
21:55justin_s`agreed Re: racket for new programmers
21:55justin_s`(inc racket)
21:56justin_smith(inc technomancy)
21:56justin_smith(for the racket suggestion)
22:00truebuddijustin_smith: based on yday discussion wrote some clj at https://gist.github.com/krishnabhargav/2a92da3f5f161c7da197 .. you mind taking a quick review for some expert tips?
22:01justin_smithtruebuddi: checking it out
22:02akhudektruebuddi: I slightly prefer update-in rather than how you use assoc in +people and -people
22:02justin_smithtruebuddi: or assoc-in
22:02justin_smithagreed
22:03truebuddiakhudek: will try it
22:04justin_smithalso, something like name - for one, it is shadowing clojure.core/name which will cause an annoying warning message, for another, it is kind of pointless, it is better to document the :name key and expect it to be used directly
22:04justin_smithI understand the urge to abstract, but assoc is already abstracted - it works on maps or records
22:05akhudekyes, agreed
22:05justin_smiththe way you use default-trip is definitely good - but take out the static magic (the call to (t/today) - because it makes the time the app booted "magic"
22:06justin_smithyou can use a defn if you want it to always make the current day default
22:06truebuddiso instead of a def defaut-trip make a defn default-trip ?
22:06justin_smithtruebuddi: remember that unlike ie. python/php/ruby you probably have one app instance that stays running for months at a time
22:06justin_smithright
22:07truebuddibut then doesnt it "go against" FP that function call each time returns a different value?
22:07justin_smiththough immutible/static is better than dynamic when possible - it's just not compatible with the "today" thing
22:07justin_smithright, but you are the one who decided it should be today, and today is not immutible
22:08justin_smitha good compromise would be to make default-trip immutible and leave out the datas, then new-trip attach the dynamic defaults (the date part)
22:08justin_smith*parts
22:09justin_smithoverall, for beginner clojure code, it's quite excellent though
22:10justin_smithwhat I like to do for usage examples is put the whole working code fragment inside (comment ...)
22:10truebuddijustin_smith: thank you ... ok
22:10justin_smiththat way their editor will syntax highlight it like normal code
22:10akhudekgood old bottom of the file tests
22:11truebuddiif conj for multiple items is "into" whats for "disj" ?
22:11justin_smithnot a test, really - I see a usage example as a special form of added documentation :)
22:11akhudekin this case, yes :-)
22:11justin_smithtruebuddi: conj already works with multiple items
22:11justin_smithand dissoc works with multiple items too
22:11justin_smithif they are in a collection, you can use apply
22:12justin_smith,(apply dissoc {:a 0 :b 1 :c 2} [:a :b])
22:12clojurebot{:c 2}
22:12truebuddihmm ...
22:12justin_smithoh, but these are sets, calling disj
22:13justin_smith,(apply disj #{:a :b :c :d} [:a :b :d])
22:13clojurebot#{:c}
22:13justin_smiththough into is just fine - just pointing out that apply conj works too
22:13truebuddialso if i use update-in .. i did a (update-in trip [:people] into persons) ... adds all persons into ;people set .. but if i replace into with conj it adds one item into set
22:14akhudektruebuddi: yes, you want into there
22:14justin_smithremember I said apply conj
22:15akhudekapply conj won’t work well with update-in
22:15justin_smith,,(apply conj #{:a} [:b :c :d :e])
22:15clojurebot#{:e :c :b :d :a}
22:15akhudeksince it will thread the previous value after apply
22:15justin_smithyeah, good point, into is a better choice all around
22:15truebuddiso whats for "-person" .. into puts in .. anything to take out ?
22:16justin_smiththere is apply disj, or clojure.set/difference
22:16akhudeknot that difference expects two sets
22:16justin_smith,,(clojure.set/difference #{:a :b :c :d :e} [:a :b])
22:16clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>
22:17justin_smith,(do (require 'clojure.set) (clojure.set/difference #{:a :b :c :d :e} [:a :b])) ;; akhudek: nope
22:17clojurebot#{:e :c :d}
22:17akhudekoh interesting
22:17justin_smithjust the first arg matters there
22:18justin_smithone thing I love about clojure is how fast you can become an "expert" if you have a small bit of curiosity and an open repl all the time
22:18justin_smith(inc clojure)
22:18justin_smithlazy-ass lazybot
22:19justin_smithprobably out partying
22:19truebuddiwhats a lazybot?
22:19justin_smithit's a bot on this channel, that implements our silly "karma" system
22:19truebuddii see you can exec clojure code with "," ... interesting
22:19justin_smithyeah, it's a great tool for demonstrating how things work, or proving who is right without needing to dig up hyperlinks
22:20justin_smithyou can also message clojurebot (though usually using your own repl will be more convenient I am sure)
22:22truebuddigood to know ...
22:25ncthom91hey y'all. How can I apply two forms to the "logical true" case of an if block?
22:25justin_smithncthom91: do
22:25justin_smith,(if 1 (do (print :OK) 2))
22:25clojurebot:OK2
22:26ncthom91justin_smith thanks :)
22:29truebuddiupdated https://gist.github.com/krishnabhargav/2a92da3f5f161c7da197 with your comments
22:31truebuddiis the thread-first -> in the usage a good practice?
22:31justin_smithtruebuddi: one more little thing - assoc is varargs
22:31justin_smith(in the example that is)
22:31justin_smith,(assoc {} ;a 0 :b 1 :c 2)
22:31clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
22:32justin_smith,(assoc {} :a 0 :b 1 :c 2)
22:32clojurebot{:c 2, :b 1, :a 0}
22:33truebuddithanks for the input ..
22:35justin_smithoh, and I used clojure.set/difference in my code for laziness / convenience purposes here, but it's best to require clojure.set :as set in your ns block, and use set/difference
22:37ncthom91can anyone explain a quick syntax thing to me? in the memoize source code (http://clojuredocs.org/clojure_core/clojure.core/memoize) there's a call `(find @mem args)`
22:37ncthom91what is the @ symbol for?
22:38justin_smithncthom91: it is a a reader syntax for (deref ...)
22:38justin_smith,(macroexpand @foo)
22:38clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>
22:38justin_smith,(macroexpand '@foo)
22:38clojurebot(clojure.core/deref foo)
22:38justin_smiththere we go
22:38justin_smithmacroexpand will often help with the weirder parts of clojure
22:38truebuddibtw clojuredocs.org is outdated and theres a new docs site with some complex name ... saw it on r/clojure the otherday
22:38ncthom91interesting
22:39justin_smithtruebuddi: ncthom91: yeah grimoire
22:39justin_smithhttp://grimoire.arrdem.com/
22:39ncthom91so (let [mem (atom {})]) assigns a reference to `mem`, not an actual map
22:39ncthom91makes sense
22:39justin_smithyeah, that's what atom does
22:39ncthom91reminds me of my ocaml days
22:39justin_smithyeah, ocaml and clojure share some important concepts
22:39justin_smiththough sadly ocaml never figured out how to do proper concurrent gc
22:40ncthom91i never got that far into ocaml :P
22:41truebuddijustin_smith: when i do a (def current-trip (default-trip)) I am actually executing the function only once right?
22:41truebuddiand I remember reading somewhere that you can "redef" the same by doing a (def ...) again ...
22:43justin_smithtruebuddi: true on both counts - you can use defonce if the ns may get reloaded but it is important for correcness that the def not be re-bound
22:43justin_smith*correctness (ironic typo)
22:44justin_smithtruebuddi: but remember that this would make the boot time of your app "magic" - your app doesn't start up fresh for each request unlike some languages
22:45justin_smithI have sites that have uptimes of months before being restarted
22:45truebuddiI am just trying to now think where i would use a ref here
22:45justin_smithwhy would you use a ref?
22:45truebuddiexactly ... am trying to find a use case for ref ..
22:45justin_smithhaha
22:45tbaldridgetruebuddi: and now you have reached enlightenment....
22:46michaniskintruebuddi: justin_smith conj.io is easier to remember than grimoire
22:46truebuddilike i have a (def app-state []) ... technically i can "redef" it anytime i want to add to my app-state right?
22:46justin_smithmichaniskin: cool, did not know about that URL
22:46tbaldridgepeople come to Clojure for the STM, and stay for everything else
22:46justin_smithtruebuddi: don't use def at runtime, it has no sane concurrency semantics
22:47justin_smithtruebuddi: that said, you usually don't need STM, atoms and maybe the occasional lock should suffice
22:47justin_smith(inc tbaldridge)
22:47justin_smithI am so inc-happy tonight, and no lazybot
22:47tbaldridgelol, it's the thought that counts
22:48truebuddilet me get this ... [] is immutable .. so any modification doesnt effect other concurrent users .. and in the worst case the def again will give stale values right?
22:48justin_smithtruebuddi: right, but you can lose updates
22:48truebuddiyes .. in case of concurrent updates ... true
22:48justin_smiththink of what happens if two threads read the current value, calculate a new one, and redef, at nearly the same time
22:48justin_smithright
22:49justin_smithyou can solve this with atoms, refs, locks, or even local state in a core.async go block, depending on what you are attempting to do
22:50justin_smithin our experience, usually refs are not needed
22:50truebuddialso i have a general Java question about asynchronous IO in java ... in the .NET world, we have async calls where in the thread doesnt get blocked and there is a IO completion port that handles the "waiting" so to speak and calls back when the call is completed ... i cant find such a thing in Java .. usual recommendation is make a call on a diff thread or a thread pool thread ...
22:50tbaldridgetruebuddi: that's kindof what core.async is for
22:51tbaldridgenot Java, but clojure
22:51justin_smithtruebuddi: there is also java.nio, but core.async is a much better api
22:51justin_smithjava.nio is the more async-friendly update to java.io that comes with java 7
22:51truebuddiso if i make 1000 async server calls ... it isnt really going to spawn 1000 background threads right?
22:51justin_smithtruebuddi: not with core.async, no
22:51tbaldridgewith core.async, no
22:52tbaldridgelol
22:52justin_smithit's the #clojure chorus
22:52truebuddiwhat about jdbc calls? does core.async help here as well>
22:52tbaldridgeyou'd need an async DB interface, but using that with core.async isn't hard
22:52justin_smithtruebuddi: it can, if you wrap your jdbc usage in channel usage - I can see that working
22:54tbaldridgelol, go ahead justin_smith
22:54truebuddiwhat do you mean by async DB interface? I thought the whole JDBC protocol doesnt have anything non-blocking in design?
22:57sarcherdatabase access at the jdbc layer is not asynchronous
22:57justin_smithto quote tbaldridge https://groups.google.com/d/msg/clojure/Aj2njGQtPN0/PMVOigU2fDAJ
22:57justin_smith(regarding what tbaldridge would have meant by async db interface)
22:58sarcheryou can asynchronously perform db updates though using jdbc and core async i would assume.
22:58justin_smithright, as shown in some code in the link above
22:58truebuddithanks for the link . but there you can see (thread ... ) .. so there is indeed a thread being created
22:58justin_smithfor the db interaction, yes
22:59justin_smithbut it's not a thread per interaction
22:59justin_smithit's a thread that handles the interactions
22:59justin_smithyou can create as many as you like, and if they read/write the same channels, they scale transperently
22:59truebuddiso a thread is spawned ... it receives input through channels .. and for each input does some "db" work
22:59truebuddiright?
22:59justin_smithso you can decide how many need to exist
23:00justin_smithright
23:00truebuddiso if channel has a queue then long running db op can block the others in the same channel ...
23:00justin_smithand any number of threads can be spawning queries on the db based on grabbing them from the same channel
23:00justin_smithno
23:00justin_smithchannels don't work like that
23:01justin_smithif you have two threads reading from the channel, you can have two requests at a given time. Given that your bottleneck isn't CPU, it's network bandwidth (and some latency on the db end that scales with the nubmer of requests) a fixed size thread pool works nicely
23:02justin_smithyou can experiment to find the number of threads that performs optimally - beyond a certain count, you should see throughput drop when you increase the concurrency (due to the i/o bottlenecks)
23:03truebuddihmm
23:03truebuddiso when you do a (chan 4) ... channel with buffer of size 4 is created right?
23:03justin_smithright
23:06truebuddiso in tbaldridge example, he spawns 4 threads all reading from the same channel ... so 4 db operations could be done in parallel on 4 threads
23:06justin_smithright
23:08justin_smithbut unlike most thread pools, you wouldn't tune the pool size based on CPUs available, but based on the performance of the db (and factors like whether it is remote, network latency, db engine latency, etc.).
23:09truebuddiin a web app where you own/manage the deployment and constantly monitor .. may be tuning it by yourself is sufficient but imagine you are making servers that gets "sold" and the customer does his/her deployments ... tuning is going to be tricky
23:11justin_smithright, but you should be able to get a very good picture of the performance characteristics with load testing
23:11justin_smithand with a well designed app, you can access the back end and configure things like the thread count without a redeploy
23:11justin_smith(of course telling them "never ever touch this config" and finally telling them how to do it if it is needed)
23:12truebuddibut things like these only comes with experience (or getting burnt before) so when you build something you dont really worry about these until late (atleast where I work)
23:12justin_smithright, but you can design such that these things can be flexible in the future
23:12justin_smithand clojure has some nice features that ease that
23:13justin_smithclojure is very good at helping you prevent brittleness in apps, if you let it help you
23:13truebuddianyway point is .. with all the cool innovations that happens on JVM .. it's a little surprising of not having a non-blocking db access ...
23:13justin_smithtruebuddi: it would just end up being some defaults on top of threads anyway. It's not like the jvm implementors have access to something you as a dev don't functionality wise.
23:14justin_smithon this count at least
23:14justin_smiththough, a good easy to use async db lib would be awesome. I bet you could write it if you put your mind to it :)
23:15justin_smith(in clojure, of course)
23:15truebuddihaha..honestly i dont see how adding any layer ontop of jdbc can smooth it out ...
23:15justin_smithI say in Clojure because the bottlenecks are emphatically not in the CPU or heap usage of the app, so switching to java would be unlikely to gain you much
23:16justin_smiththe layer just makes it easier - the bottleneck isn't in the jvm, so a layer of abstraction will be a small constant factor, not a complexity increasing performance drain
23:17truebuddilayer cannot make something blocking at heart, non-blocking ... whether you see it blocking or not depends on the layer i guess
23:17truebuddianyway you use a lot of "promise"/"future" in clojure? or does core.async replace all those
23:17justin_smithon the contrary, if it uses threads it can - and that is how your hypothetical java async db api would have to work
23:18justin_smithI use future a lot
23:18justin_smithI consider promise an implementation detail that creates futures
23:18justin_smithfuture is good sometimes, core.async others - I don't consider future out of date at all
23:18justin_smithagents are great too
23:19justin_smithin fact agents for an async db api would likely be a pretty good match
23:19truebuddii always get confused between future ånd a promise
23:19justin_smithagents use a thread pool, you can deref a specific agent to get its result, or query as to whether it is ready...
23:19justin_smitha promise is just a thing you can deliver to
23:20justin_smithfutures use the promises as an implementation detail, and deliver to the promise from another thread
23:20justin_smithor that's how I think of it, it might not be precisely and literally like that in clojure
23:21justin_smithyeah, future doesn't literally use promises
23:21justin_smithbut that's the relationship - future is explicitly about threads, promises are more general
23:22truebuddifuture { result = somework; result} .. somework is done only once .. and promise is just a placeholder that someone else delivers the value .. right?
23:22justin_smithor you could deliver to it yourself
23:22justin_smithit's just a thing that goes from not yet having a derefable value, to later having one
23:23justin_smithfor example you could have one promise, and spawn N futures that could each fill the promise, first one to find an answer wins
23:23truebuddiany simple example of future with a thread?
23:23justin_smithfuture uses a thread, always
23:23truebuddiso i dont have to create a thread myself?
23:24justin_smith(dotimes [_ 10] (future (mapv println (range 10))))
23:24justin_smithI can't make clojurebot do that, he hates threads
23:25truebuddiand future uses threadpool?
23:26justin_smithit creates a java.util.concurrent.Future
23:26justin_smithhttp://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
23:27xeqiit uses the agent send-off pool
23:27justin_smith$source future
23:28justin_smithxeqi: yeah, I am seeing that now
23:28justin_smith(.submit clojure.lang.Agent/soloExecutor ^Callable f)
23:28truebuddiwhats that?
23:28justin_smiththat is a quote from the source of future
23:29justin_smithand here is the definition of soloeExecutor https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L53
23:29justin_smithit is a pool
23:30justin_smitha static field on Agent
23:30truebuddiand do we have things like .. when-all .. when-any ?
23:30justin_smithwe have realized?
23:30justin_smith(every? realized? futures)
23:30justin_smith(filter realized? futures)
23:30justin_smithetc.
23:31justin_smithif futures is a list of futures that have been spawned
23:31justin_smitherr. sequential, I mean sequential of course :)
23:31justin_smithhell, maybe even group-by would be useful here
23:32truebuddithat only allows u to check if they are ready to read from or not ... my intent with when-any was like (when-any future-list #(str %1 " retuns answer : " %2))
23:33truebuddiwhere i "assumed" it returns a future and its answer in the result ... jus as an example
23:34justin_smithok, use (filter realized?) and act on the first, or map on all results
23:35justin_smithor group-by realized, so you can act on all the ones that are done, and set aside all that are not done to check later
23:35justin_smith(by which I mean call recur with the list under the false key)
23:37truebuddisay i have 5 futures each of which talks to a http mirror ... we r really interested in only one answer and the first one to answer is what we are interested about .. if i do a filter .. none of them may be realized yet .. so i try again .. and again ... and again ... but this is basically spinning and spinning ...
23:38justin_smithtruebuddi: you can poll, or as I mentioned above, ask them all to attempt to fulfill the same promise, and then block on the promise
23:38justin_smiththen, cancel all futures once the promise comes through (cancel on a finished future is fine, it's a no-op)
23:39truebuddii m going to try it out .. anyway cancellation is not guaranteed right
23:39justin_smith(doc future-cancel)
23:39clojurebot"([f]); Cancels the future, if possible."
23:39justin_smiththat doc string is pure poetry, I swear
23:40truebuddilol
23:40justin_smithit's been a favorite of mine, before I ever needed to use future-cancel
23:45xeqifuture-cancel => if the future hasn't started, it won't be, but if the future has been started then the code would have to cooperate with shutting down
23:46xeqiby checking Thread/interrupted and handling it gracefully
23:46xeqiirrc
23:51justin_smithxeqi: cool, good to know
23:52justin_smithas I think about that task more - I wonder how often the latency at the other end of the http request is the main bottleneck (such that starting multiple requests and cancelling all but the one that finished makes sense)
23:52justin_smithalso, if I was running the service you were hitting with that kind of usage pattern, I would probably be annoyed
23:54justin_smithat a certain point, fewer parallel requests will perform better, as your interface or network saturate. The interesting question is whether that point is > 2 or not
23:58caternthe (or foo bar default) trick is so useful and I can even use it in Python
23:58justin_smithheh, indeed
23:58caternare there any other such cross-language tricks that I could learn about from Clojure?
23:59justin_smiththe value of immutible data (the trick is how well the language can fake immutibility of course)