#clojure logs

2014-05-16

00:09beamsoin https://github.com/swannodette/om/wiki/Basic-Tutorial#adding-contacts, what is going on in the let in parse-contact?
00:10beamsoin the second line are first, last and middle essentially being reassigned based on the first line?
00:11White_Flametechnically, they're new variables named first/last/middle, shadowing the ones of the line before
00:12quizdrbeamso however the effect is that the first binding of first/last/middle is no longer usable due to the second "shadowing"
00:12quizdrthe code appears to be binding them differently depending on whether the last name was provided during the first binding
00:12beamsookay.
00:12beamsoi hadn't seen anyone do it like that before
00:13quizdrit's not uncommon. you bind something, then based on what resulted from that, you bind it again. you can iteratively affect the final binding by doing it that way
00:13quizdreasier than nesting a bunch of forms to do it all in a single binding
00:14quizdrclearer to read too
00:15quizdrin that code, suppose there was no middle name provided? then the last name would mistakenly get bound in the first binding as the middle name. so the second binding fixes that
00:16White_Flameneed some good regex-like operations [first :? middle last]
01:06cflemingdanielcompton: See https://github.com/cursiveclojure/cursive/issues/186 for some suggestions about test conventions.
01:06cflemingI'm not aware of any official guidelines
01:09danielcomptoncfleming thanks!, I was meaning about naming test cases, not the files themselves.
01:09danielcompton,(inc cfleming)
01:09clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cfleming in this context, compiling:(NO_SOURCE_PATH:0:0)>
01:11cflemingdanielcompton: Ah, no, sorry - I just try to give them somewhat meaningful names.
01:29waynrtechnomancy: i have some lein release stuff done
01:30waynrsitting in airports for the next 12 hours, gonna try to get more done
01:51curiousmahcan someone help me to explain the word "reify"?
01:52waynrcuriousmah: explain it to whom?
01:52curiousmahto me, I don't understand it
01:53waynroh
01:53curiousmahis it a Computer science concept?
01:53waynrmaybe
01:53mangeAccording to Google, reify means: make (something abstract) more concrete or real.
01:54waynras far as clojure is concerned, it allows you to create an anonymous instance of the named protocol
01:54waynrat least, that's how i understand it
01:54mangeYeah, so in Clojure it lets you make a concrete instance of an (abstract) protocol.
01:55waynrcuriousmah: if you do a text search for 'reify' on this page: https://github.com/clojure-cookbook/clojure-cookbook/blob/first-edition/03_general-computing/3-09_polymorphism-with-protocols.asciidoc
01:55waynrthere is a pretty easy to understand example of reify
01:56curiousmahwaynr, well I got several examples of reify myself
01:56curiousmahbut I just feel not so sure about the concept
01:56waynrcuriousmah: are you familiar with creating an unnamed function
01:57curiousmahwaynr, yes
01:58waynrthen think of reify as being analogous to creating unnamed function, only instead of unnamed function you are creating an unnamed instance of a protocol
01:58curiousmahI meant the concept in CS, not just in Clojure
01:59waynri don't know if it's useful as a concept in and of itself, but think of the factory pattern where you want to be able to create instances of some kind of class (only instead of class let's think about protocol)
01:59curiousmahsorry about such an unclear question
02:00waynrsuppose you have the "Shape" protocol and you want to be able to programmatically generate new kinds of shapes, reify might be used in that situation
02:01curiousmahwaynr, thanks for your time. I did create several reify instances myself when working with some Java libs
02:01ddellacostacuriousmah: I'm not sure if this will help but check out a post I wrote on protocols: http://davedellacosta.com/cljs-protocols
02:02ddellacostacuriousmah: it's ostensibly CLJS specific but is mostly quite general
02:02mangecuriousmah: reification is just the idea of taking something abstract and making it real. For instance, Java generics have abstract type parameters (<X>, or whatever), if they were reified then you would be able to, at runtime in the class, use that X to check the generic type of your class. (Java generics aren't reified, though, so you don't have access to your generic parameters: they remain abstract.)
02:03curiousmahmange, so reification is just a not-so-serious idea, right?
02:04mangeWhat do you mean "not-so-serious"?
02:04curiousmahI mean understanding it as in a Clojure function is enough?
02:04mangeAlso worth a look: https://en.wikipedia.org/wiki/Reification_(computer_science)
02:05mangecuriousmah: The concept of reification is bigger than the Clojure reify function, but what the reify function does could be referred to as reification.
02:05ddellacostacuriousmah: it's definitely "serious," in the sense that it is used generally and outside of Clojure
02:05mangeYou certainly don't need to understand what exactly reification is to use the reify function effectively.
02:06srrubycore.logic:
02:06curiousmahmange, I hope so
02:06curiousmahThanks for all, you guys
02:06ddellacostacuriousmah: I would let it sit, don't worry too much about getting it too deeply at first--use it in Clojure and read more about it and eventually it'll click. That's how it did for me at least.
02:06mangecuriousmah: I've never once thought about refication when using reify. I just think of it as an anonymous function which can be called in a bunch of different ways (each method being a different way).
02:10curiousmahddellacosta, well, this question came to my mind after I'm quite fluent in Clojure ;)
02:11ddellacostacuriousmah: there is always more to learn, huh? ;-)
02:11curiousmah;-)
06:14noncomhi, i am interested in better defaults for emacs, but on its github page, there is no apparent installable content https://github.com/technomancy/better-defaults where do i find the installation instructions?
06:19noncomok, well, maybe anyone here who can asnwer some questions regarding installing CIDER?
06:24CookedGryphongeneral advice, have a look at emacs live or prelude
06:24CookedGryphonboth simple to set up opinionated defaults
06:24CookedGryphonwith decent readmes telling you how to customise basic stuff
06:25CookedGryphon(you'll probably want to turn off guru mode in prelude for example, but other than that the defaults are pretty good)
06:28noncomoh, i thought that CIDER is the most recent one.. ? you mean that live and prelude are simpler for newbs?
06:29CookedGryphonemacs-live and prelude are sets of emacs defaults, cider is included
06:29clgvnoncom: I think these are just emacs setuops no nrepl frontend alternatives ;)
06:30noncomoh its even that cider is included, well fine :) whats the difference between live and prelude?
06:32CookedGryphonlive has brighter colours and random flashy features, prelude is more sensible
06:33noncomuh, can't make a meaningful choice from this place ...
06:36CookedGryphonnoncom: I personally use prelude
06:36CookedGryphonhaving used live before
06:36CookedGryphonI think it's a bit more stable and solid, and has a better system for applying your own changes on top
06:37clgvnoncom: if both are ready to go for clojure dev. just try both for several hours ;)
06:41noncomyeah, guess i'll have to try..
10:06ampharmexj #matlab
10:41trap_exitin clojurescript, is there a way to test if a varaible is a function?
10:41trap_exitin clojurescript, is there a way to test if a varaible is a function?
10:41trap_exit(def x 20) (def y (fn [])) ==> (function? x ) = false, (function? y) = true
10:42teslanickIt would be either (fn? x) or (ifn? x)?
10:44trap_exitfn? appears to ahve worked
10:45master_opis the "?" symbol mean that argument is optional
10:46trap_exitno
10:46trap_exitit means it returns true/false
10:46trap_exitthsi is not compiler enforced
10:46trap_exitit's just convention
10:46trap_exitcat? <== is this object a cat?
10:46trap_exitdog? <== is this object a dog?
10:46trap_exitshibe? <== does this dog use dogecoins ?
10:46master_opok
10:46master_opit's clear, thank you
10:46teslanickYeah, question marks indicate simple predicates.
10:47trap_exitteslanick: let's build a fucking tesla museum
10:47teslanickAgred.
10:47teslanick*agreed
10:47teslanickAlso, it appears that clojurescript's fn? function delegates to goog.isFunction
10:47teslanickWhich is defined as http://docs.closure-library.googlecode.com/git/local_closure_goog_base.js.source.html#line985
10:49teslanickWhile ifn? does some in-clojure checking of protocols. So it checks if the thing you hand it implements the IFn protocol. (e.g. keywords, maps, vecs, etc)
11:04bltavareshi there folks. is there a reason for not having a `flip` function on core? I notice a PR on github proposing the addition but no relative card on the jira board. I am not aware if this have been discussed before as well, sorry if there was a discussion aready (searching for flip on the group yields lots of result)
11:05cbpwhat is a flip function?
11:07bltavarestakes a function and flips the argument order
11:08bltavarescbp: from haskell documentation http://hackage.haskell.org/package/base-4.7.0.0/docs/Prelude.html#v:flip
11:09bltavares(defn flip [f] (fn [a b] (f b a)))
11:09gfredericks(defn flip [f] (fn [a b & args] (apply f b a args))) ; better?
11:09cbpit says it just changes the first two arguments
11:09bltavaresgfredericks: yup
11:10dkinzerooh, that's kind of neat. So you can build inverse objects really intuitively.
11:10stuartsierraThat would probably be more useful in Haskell with its automatic function currying.
11:10gfredericksto do it really clojure-style, make 5 different arity clauses
11:10cbp:-P
11:10stuartsierra#(some-fn %2 %1)
11:11bltavaresthere was a PR https://github.com/clojure/clojure/pull/32 without a ralated jira card
11:11bltavaresstuartsierra: I was wondering if that is the alternative that the community usually goes for
11:11gfredericksstuartsierra: I lean toward functions like flip because they state what I'm trying to do instead of incidentally doing it, perhaps by accident
11:11cbpI'm not entirely sure what's the usefulness of flip besides making things harder to read
11:12gfredericksbut doing that everywhere leads to obnoxious point-free style
11:12stuartsierraI usually prefer `let` bindings and explicit arguments over point-free styles like `comp` and `partial`.
11:12gfredericksreadability; why don't we have an objective way to measure it :(
11:13bltavaresI agree with gfredericks, flip gives intention. I was more curious if there was a strong reason against it, or if it was ever discussed
11:17stuartsierraI do not recall any mailing list discussions on it.
11:17whodidthishit me up with a cool way to check that a vector does not contain nils, like [1 2 nil 3] => false
11:18pdk,(every identity [1 2 nil 3])
11:18clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: every in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:18pdk,(every? identity [1 2 nil 3])
11:18clojurebotfalse
11:18pdk,(every? identity [1 2 3 4])
11:18clojurebottrue
11:18pdkenjoy
11:19cbp,(every? identity [false])
11:19clojurebotfalse
11:19pdkwelp
11:20pdk,(every? #(not (null %)) [1 false 2])
11:20whodidthiscools, yeah i dont mind false values
11:20clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: null in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:20pdk,(every? #(not (null? %)) [1 false 2])
11:20clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: null? in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:20pdkman im rusty apparently
11:20bltavares,(every? (complement nil?) [false])
11:20clojurebottrue
11:20llasram(doc some?)
11:20clojurebot"([x]); Returns true if x is not nil, false otherwise."
11:21bltavares,(every? (complement nil?) [1 nil 2])
11:21clojurebotfalse
11:21bltavares,(every? (complement nil?) [1 3 2])
11:21clojurebottrue
11:21cbp,(some some? [1 2 3 nil]) ;lol everytime
11:21clojurebottrue
11:21cbpwait thats wrong
11:22cbpevery
11:46akazlouwhat is the easiest way to get char from the int (i.e. 2 => \2), so far I came with this (first (str 2))
11:46akazlouis there better way to do it?
11:47mpenet,(char 2)
11:47clojurebot\
11:47mpenetah no, not the same
11:48akazlouyes, not the same :)
11:48akazlouwas mine first attempt
11:59CookedGryphon,(char (+ (int \0) 2))
11:59clojurebot\2
12:00stuartsierra,(Character/forDigit 2 10)
12:00clojurebot\2
12:01CookedGryphonthat's better :P
12:02akazlouthanks stuartsierra
12:02stuartsierra'welcome
12:12CookedGryphonI'm having real trouble getting cider-jack-in to work with my custom profiles
12:12CookedGryphonI keep gettging oculd not find or load main class clojure.main
12:12CookedGryphonbut if i do exactly the same at the command line, the repl starts no problem and I can cider connect to it
12:13johnwalkerwhy does (map Integer/parseInt ["1" "2" "3" "4"]) give a runtime error?
12:13johnwalkerwrapping like #(Integer/parseInt %) causes the same expression to succeed
12:13cbpyou cant use static methods as functions
12:14technomancyyou can't use any methods as first-class functions
12:14johnwalkeraha
12:15johnwalkercool, thanks
12:46akazlouI usually find that I create a helper functions, for example, ranks, or similar, and call them inside (let) form, and I would like to assign the execution of this func into let binding, and ranks is a good binding name for this, so is it too common in Clojure:
12:46akazlou(let [ranks (ranks <some collection>)]), it seems it works, I just don't like it too much, but on the other hand I don't lose nice binding name
12:47akazloudon't like to lose
12:47akazlouof course I can write (let [r (ranks <some collection>)]) instead, but one letter binding is also not possible in every case
12:50cbp(let [rs (ranks)]) :-P
12:51akazlouor rnks :) I'm just wondering does anyone else have the same problem/concern?
12:53noncomwhat is the easiest way to tug a library from clojars without creating any lein project?
12:54akazlouok, so something to think about :)
12:54technomancynoncom: there's a lein-try plugin that iirc does that
12:56noncomakazlou: imho this is a code style question. clojure uses the same namespace for functions and variables, so there is no definitive answer to your question
12:57noncomakazlou: you could try an "m" prefix for your var names ahahah :)
12:57noncomor _
12:58llasramakazlou: I generally solve that by making identifiers for functions verbs and for values nouns. You still get some collisions, but not many
13:01technomancystraw poll: scm or vcs?
13:01technomancyfor the name of the lein task to interact with git, hg, etc
13:02mdeboardvcs
13:02llasramscm; then vcs will be the command for interacting with an Atari 2600
13:02hiredmanplace for files so when you change them you know it or pffswyctyki
13:02Frozenlocktechnomancy: Wells
13:02mdeboardthen you could add vcr for interacting with your clojure programs on videocassette
13:03mdeboardlein vcr play
13:03mdeboardsomething something play framework
13:03cbplein fix-my-maven
13:03technomancyneed a tie-breaker
13:05devntechnomancy: you around?
13:05llasramIf it matters, both git and hg seem to refer to themselves as SCMs and not VCSs
13:06technomancydevn: yeah
13:06technomancyllasram: I like SCM better as an acronym, but saying "source code management" sounds super weird compared to "version control system"
13:06technomancy"source code management" isn't even accurate
13:07llasramI'd thought it stood for "software configuration management", which is nice and vague
13:07technomancyit's not about config though
13:08technomancyexcept in some super-abstract sense
13:08devntechnomancy: PM?
13:08technomancywell if we can't even figure out what it stands for I'm inclined not to use it
13:08technomancydevn: sure
13:08gtraktechnomancy: but.. but.. the enterprise!
13:08technomancygtrak: talk to the spock
13:09gtrakVacuum Motion Management
13:09sdegutisIs there a Clojure tool that lets you dispatch a method based on a non-argument (external) value?
13:10technomancysdegutis: defmulti can dispatch on anything
13:10technomancyrandom numbers, environment vars, phase of the moon
13:10mdrogalistechnomancy: Oh my God. It is an anagram of High Perl Bagel!
13:10technomancymdrogalis: kinda spooked about that tbh
13:10FrozenlockM-x phases-of-moon
13:10mdrogalistechnomancy: :)
13:12mdrogalistechnomancy: Looks like you also match "Higgle Help Bar"
13:12mdrogalisGet a tattoo of that.
13:13technomancyat least it doesn't mention perl
13:13mdrogalisHaha.
13:15sdegutismdrogalis: I never understood how people can come up with anagrams. It requires holding so much information in your head all at once.
13:16sdegutistechnomancy: Oh. It did not look like it. It looked like you give it a function that only takes parameters as argument.s
13:16technomancysdegutis: yes, but it doesn't have to be a pure function
13:16mdrogalishttp://www.anagrammer.com/anagrammer/
13:16sdegutisC-b C-t C-c C-c
13:16mdrogalis*Shrug*
13:16sdegutistechnomancy: Oh so it can be a function that ignores its arguments and then observes other third party values?
13:16technomancysdegutis: ayup
13:17sdegutisThat sounds awful.
13:17technomancysdegutis: I actually have an example I just wrote, haha
13:17sdegutisI'm surely doing everything wrong if this is the best solution for me.
13:17llasramsdegutis: Isn't that exactly what you're asking for though?
13:17sdegutisYes but it doesn't fit in cleanly to what Clojure provides, thus I have the wrong problem.
13:18llasram*shrugh*
13:18technomancysdegutis: https://github.com/technomancy/leiningen/commit/051ec98f10b3bcd956e5d9f3e4aa10d9d73dc068#diff-a3ef52c31fdf9c0a4a7ba85b7e4ff1e6R8
13:18llasramIMHO fits pretty cleanly into what multimethods doo
13:18llasramdo even
13:18llasramNot drunk, I swear
13:19technomancyit's based on files on disk that are pointed to by the arg, but not the value of the arg itself
13:19technomancyso sorta similar
13:28gfrederickswww.clojureql.org
13:28gfredericks^ this is apparently what happens when people don't like a library
13:29sdegutisThank you.
13:38noncomgfredericks: clojureql is awsome!
13:45{blake}Random text generator?
13:47gfredericksnoncom: I liked using it back in the day
13:47gfrederickseverybody else poo'd on it and shouted about korma
13:53cbpthat is scummy
14:19bltavaresis there a project similar to om but for swing applications?
14:27llasramI think seesaw is the closest you get, which I guess means "no"
14:28eggheadclojurians, I'm trying to implement a persistent map and getting a null pointer exception from clojure.lang, no clue how to debug :/
14:28eggheadNullPointerException clojure.lang.APersistentMap$KeySeq.first (APersistentMap.java:154)
14:28eggheadhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L154
14:29eggheadanyone have *any* clue what might cause that in my weird map impl? I've tried putting printlns everywhere and it always blows up before it gets to them
14:31bltavaresllasram: I gave it a try. I believe it could be used in a simmilar sense. It allows you to re-render everything. seems like an interesting idea
14:43waynrtechnomancy: so in your email when you refer to prep-tasks and release-tasks are you thinking of having release subtasks that can be selected/reordered with :release-tasks in a project's project.clj
15:02technomancywaynr: :release-tasks should just be a vector of task invocations; probably defaulting to [["release" "bump"] ["scm" "tag"] ["deploy" "clojars"] ["release" "bump" "snapshot"] ["scm" "push"]] or something
15:06szymanowskihello! How can I turn a collection of channels into a channel containing a collection of corresponding values ?
15:09arrdem$seen tim___
15:09lazybottim___ was last seen quitting 22 hours and 1 minute ago.
15:10arrdemroight
15:10dbaschszymanowski: conceptually that’s what alts does
15:12bendlasdbasch: how so?
15:12dbaschbendlas: http://clojure.github.io/core.async/#clojure.core.async/alts!
15:12szymanowskimmm... I will try that
15:13bendlasdbasch: I know what alts does, but if I'm not mistaken, it doesn't maintain any correspondence
15:14bendlasquite contrary
15:14dbaschbendlas: nobody mentioned correspondence
15:15bendlasto me, what szymanowski is looking for would be taking values from a collection of channels round-robin, such that first messages, second messages a.s.o stay together
15:15bendlasakin to juxt
15:15dbaschbendlas: in a way that would defeat the purpose of having multiple channels
15:16bendlasdbasch: szymanowski did "... into a channel containing a collection of corresponding values ..."
15:16bendlasyes, it defeats the purpose of channels
15:16dbaschbendlas: my interpretation was: get messages from multiple channels into one
15:16bendlasyeah, that would be merge
15:17dbaschbendlas: yeah, you could merge and then take from that channel
15:18dbaschhard to know what’s the right thing without a more specific use case
15:18szymanowskisorry i'm still a bit confused about async
15:19szymanowskithe result of merge is a channel containing a collection of channels?
15:21bendlasdbasch: right, and alts is merge + tag, but there is no generic take from multiple channels simultanously, because it poses inherent synchronization problems that always need to be dealt with otherwise
15:21bendlasszymanowski: no, plz describe your use case
15:22bendlasmerge creates a channel containing messages from source channels
15:26szymanowskiok thank you very much
15:31ghadishaybanyeah there's not really a notion of "simultaneously" take, but there is async/map, which will grab an item from each of a list of channels, and then apply f to the result
15:31ghadishaybanwhich is a sort of barrier
15:32ghadishaybanbut just like core/map, will not apply f if any source stops short
15:36johncashare records recommended outside of code dealing with java interop?
15:37johncashthey seem pretty OO to me
15:46llasramjohncash: You can sometimes get a speed boost from using them, if you have actually performance-sensitive code
15:47llasramAnd frequently switch to them as a drop-in replacement for maps w/ the same keyword keys
15:47llasramThey can also participate directly in protocols
15:47llasramOTOH, I'd be hard-pressed to recall a time I've used them myself :-)
15:50johncashthe thing about using them as map is they don't implement IFn
15:52pjstadigjohncash: i use keywords as functions to get stuff out of maps way more often than i use maps as functions to get stuff out of maps
15:53pjstadigbut of course when you have non-keyword keys, then the fact that records don't implement IFn can be a drag
15:53arrdemso what's the historical rationale for always loading "user.clj"?
15:54sdegutisI don't understand.
15:54technomancyarrdem: "hey, we can do weird things as long as they're not documented"
15:54sdegutisHow do you call a defmethod with no args?
15:54arrdemtechnomancy: I need a good "it's a feature" reaction.
15:55technomancyarrdem: same justification as *read-eval* originally
15:55technomancythen it was like "oh crap security hole; better document this"
15:56arrdemgrrrrr ok.
15:56bendlasarrdem, technomancy: something to point to, when somebody asks "why always use at least 2-segmented namespaces"?
15:56arrdembendlas: wha... oh that "foo" can't be a symbol but "foo/bar" can be?
15:57pjstadigarrdem, technomancy, bendlas: because users like to use things... otherwise why would it be called user.clj. QED
15:57technomancybendlas: because reasons!
15:58arrdempjstadig: your rationale for compiling arbitrary code at boot time is compelling and by compelling I mean something I intend not to support.
15:58bendlasHey, I've got an idea, let's compile a list of stupid, inconsistent things about clojure, that should change and create tickets for them ...
15:59arrdemI'll get the pitchforks and torches...
15:59cbpill get the chips
15:59pjstadigbendlas: it's a flawless plan
16:00technomancyjust write a linter that yells at you
16:00arrdemin fairness, I'm reading into the clojure boot sequence and I'm impressed for the most part
16:01bendlastechnomancy: omg, almost got me with that one
16:01arrdembesides weirdness for user.clj, user defined reader literals and the total lack of whitespace or indentation control in clojure.lang.RT it's very nice.
16:02bendlasbtw, have you thought about alleviating data_reader.clj stupidity in lein?
16:02technomancy(when (bad-stuff?) (clojure.java.shell/sh "mplayer" "old-guy-yelling.mp3"))
16:02technomancybendlas: the java.util.Date stuff specifically?
16:02johncash-bash: mplayer: command not found
16:03bendlastechnomancy: more like library composability
16:03arrdempacman -S mplayer
16:03johncash-bash: pacman: command not found
16:03bendlasdata_readers interacts really badly with source distribution
16:03technomancybendlas: we have special handling for that during uberjar
16:04technomancynot sure what you mean about source distribution though
16:04arrdemtechnomancy: hints on where to start reading into the uberjar process?
16:05bendlastechnomancy: distributing .clj files in jars, that end up used with completely different data_readers
16:05michaniskintechnomancy: does lein do anything special with respect to fetching maven snapshot deps on windows? i'm using pomegranate directly and see weird issues (like a workaround for windows8 seems to be downcasing "snapshot" in the version string) and was wondering if this is known and dealt with in lein?
16:07bendlascore understandably advises against distributing data_readers in jars (even though datomic does it), so end user needs to recreate a proper data_readers env
16:07bendlasgot to look at uberjar support though
16:08michaniskinbendlas: where did you find the data_readers best practices recommendations? are they online?
16:08bendlasmichaniskin: an ML post by stuart sierra
16:09stuartsierradata_readers has been a learning experience for everyone. My current view is that there's almost no reason to use them in *code*, only in EDN data.
16:09bendlashttps://groups.google.com/forum/#!topic/clojure/B4_uGy1VhnA
16:09michaniskinbendlas: thanks!
16:09technomancyarrdem: hopefully uberjar isn't too complicated; it's only 150 lines
16:09technomancybut if you have questions let me know
16:10bendlasstuartsierra: true, but that's also self affirming, given the current state of affairs
16:10arrdemtechnomancy: kk.
16:10bendlasalso see datomic
16:10arrdemstuartsierra: idk... I've liked having custom reader literals for my units library...
16:10llasramarrdem: and/or me too, as IIRC refuctored it most recently
16:10stuartsierradata_reader tags are really only half-finished since there's no built-in way to print them.
16:11arrdemllasram: dvorak user?
16:11arrdemstuartsierra: eh you can define a print-method to generate the same format, but sure you don't get it for free.
16:11llasramstuartsierra: Or introspect on them. Mirroring EDN in e.g. Avro would be way easier if you could get (tag, literal) tuples instead of just the already-EDN-printed representation of the same
16:11llasramarrdem: Yes, but also intentional :-)
16:11arrdemllasram: :D
16:12stuartsierrallasram: Yes, Fressian does better at that.
16:12technomancybendlas: that sounds annoying, but I don't know much about the problem other than that lein tries to merge things during the uberjar process.
16:12technomancymichaniskin: I'm not aware of any windows-specific issues around snapshots
16:13llasrambendlas: Oh yeah, that's no longer a problem, at least if you're using Leiningen and a new-enough version
16:13llasrambendlas: Well, and people use reasonable namespaces for their tags
16:13llasrambendlas: The basic support finds all the data_readers.clj instances on the classpath
16:13michaniskintechnomancy: thanks
16:13llasrambendlas: And lein uberjar merges them for the one copy in the uberjar
16:14technomancyoh yeah, I think llasram was the one who wrote that =)
16:14bendlasllasram: that's exactly the problem, libs shouldn't dictate data_reader bindings
16:14llasrambendlas: I heartily disagree
16:14pjstadigif people namespace them, there shouldn't be a problem
16:14llasramtechnomancy: si :-)
16:14mikerodI'm getting a "java.lang.UnsupportedOperationException: Unknown Collection type" when trying to compile/emit bytecode for a form like: (eval `(new java.util.ArrayList '~(lazy-seq []))) or (eval `(MyDefType. '~(lazy-seq []))) In both cases it comes down to the clojure.lang.Compiler$EmptyExpr, but 2 separate methods both doing the same logical if-else-if flow.
16:14llasrampjstadig: exactly
16:14mikerodlet's try that again:
16:15mikerodI'm getting a "java.lang.UnsupportedOperationException: Unknown Collection type" when trying to compile/emit bytecode for a form like: (eval `(new java.util.ArrayList '~(lazy-seq [])))
16:15pjstadig"monkeypatching" your way into a reader literal tag that someone else wants is bad form
16:15mikerodor (eval `(MyDefType. '~(lazy-seq [])))
16:15mikerodIn both cases it comes down to the clojure.lang.Compiler$EmptyExpr, but 2 separate methods both doing the same logical if-else-if flow.
16:15amalloymikerod: what. why would you attempt to eval an arraylist or a deftype?
16:15mikerodamalloy: it is contrived as a simplified example
16:15pjstadigi thought there was some guidance somewhere that basically said unnamespaced reader tags are reserved
16:15mikerodwhat I really had was a macro
16:15amalloyokay, macros shouldn't emit those things either
16:15mikerodthat built a constructor call
16:15mikerod?
16:16amalloyyou didn't build a constructor call; you constructed the object at macro time
16:16technomancypjstadig: in elisp "namespaces" are done with prefixing function names with the lib name, and recently people started releasing a bunch of one-letter libraries because of how annoying that gets
16:16llasrampjstadig: I believe so, but there's also "generic" namespaces, like e.g. "dn"
16:16mikerod`(def ~'sym (new MyType '~(map identity ~some-arg))
16:16amalloyie, your macro should look like (defmacro foo [] `(MyDefType.)), not (defmacro foo [] (MyDefType.))
16:16mikerodamalloy: it does
16:16mikerodall syntax quoted
16:16llasrams,"dn","db",
16:16mikerodAOT-compile breaks on the LazySeq being thought to be an EmptyExpr
16:17mikerodsince LazySeq does not fit the if-else-if type checks
16:17bendlasllasram: idk about whether anybody can see it happen in practice, saying that is like saying "dynamic scope shouldn't be a problem, as long as people prefix their variables"
16:17bendlasit's just awkward, conceptually
16:17pjstadigtechnomancy: so because elisp is a terrible language, therefore no languages should have namespaces?
16:17amalloymikerod: do you have an actual example? i think the snippet you actually pasted should work fine
16:17amalloybut i'm not entirely sure, in the presence of AOT
16:17mikerodIn both the #emit method and the #getJavaClass method of teh clojure.lang.Compiler$EmptyExpr
16:18mikerodthe eval I posted breaks if you do (binding [*compile-files* true] <form>)
16:18llasrambendlas: I guess I don't see how using a bad/generic data-reader literal namespace is any different from using a generic code namespace
16:18michaniskinbendlas: this is, in fact how dynamic vars work in clojure, lol
16:18technomancypjstadig: no, it's more "be thankful for what you have"
16:18pjstadighehe
16:18technomancy"there are starving children in elisplandia" etc
16:18mikerodamalloy: it has to be compiled, I suppose "AOT" style
16:19bendlasllasram: it isn't. and core is right to do nothing about it, because it's a packaging problem
16:19amalloymikerod: so it sounds like in that case (def x (eval (lazy-seq []))) would break too
16:19llasrambendlas: k
16:19bendlasthat still doesn't help us
16:19pjstadigEVERYTHING IS TERRIBLE
16:19stuartsierrahaha
16:19arrdempjstadig: whelp, better become a hermit then.
16:19llasramMy cat has similar opinions, frequently at 3am
16:20mikerodamalloy: that works for me when I test it
16:20llasramMmmm.... hermit cat....
16:20pjstadigarrdem: i'm already basically a hermit. (work from home) :)
16:20arrdempjstadig: were you the JPL guy too or is that another lurker...
16:20pjstadigllasram: does it move into a new shell every few years?
16:20llasramI'm going to say yes, because that is adorable to contemplate
16:20pjstadigarrdem: i'm no lurker!
16:20mikerodamalloy: It seems to have to go through this flow -> clojure.lang.Compiler$NewExpr -> clojure.lang.Compiler$MethodExpr -> clojure.lang.Compiler$EmptyExpr
16:21pjstadigno JPL
16:21amalloymikerod: (binding [*compile-files* true] (eval `(def ~'x (Foo. ~(lazy-seq []))))) works fine for me
16:21arrdempjstadig: a thousand pardons saiib
16:21amalloyas does (binding [*compile-files* true] (eval `(def ~'x (Foo. '~(lazy-seq [])))))
16:22pjstadig~suddenly
16:22clojurebotsuddenly is !
16:22mikerod(binding [*compile-files* true] (eval `(new java.util.ArrayList '~(lazy-seq [])))) ; throws the exception for me
16:22pjstadigಠ_ಠ
16:22mikerod{:major 1, :minor 5, :incremental 1, :qualifier nil} though, perhaps its the clj version
16:23amalloymikerod: that fails for me too, but it's nothing to do with AOT
16:23bendlasllasram, michaniskin still, the correct solution IMO would be to implement lexical scope and give every .jar its separate data_readers binding
16:23johncashwould it be bad to overload class on a protocol
16:23amalloy(defmacro foo [] `(java.util.ArrayList. '~(lazy-seq []))) (foo) fails the same way
16:23johncashso (class weapon) == "mighty"
16:23mikerodb
16:23bendlashard to do with classloader badness java
16:24bendlasand I'm not sure whether core could do anything to support that
16:24mikerodamalloy: yes, good simplification
16:24technomancybendlas: during uberjarring you'd have to map namespaces back to the jar from whence they came
16:24mikerodI'm not sure what is making the type be LazySeq
16:24mikerodbut go through the Compiler$EmptyExpr flow
16:25amalloyso the problem is when you quote an empty collection, and then attempt to eval/compile that
16:25arrdemso.... how does clojure.core define clojure.core/ns on line 5305 and use it on like line 5...
16:25amalloybecause the compiler believes it knows how to produce an instance of an empty collection, but doesn't cover all possible types
16:25gfredericksit redefines things sometimes
16:25bendlastechnomancy: yes, and to be correct, that would also need to happen during regular load
16:25pjstadigi thought ns was sort of a special form, too
16:26mikerodamalloy: (eval `'~(lazy-seq '()))
16:26Bronsaarrdem: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L307
16:26technomancypjstadig: it's hard-coded in weird ways but not like other special forms
16:26amalloy(defmacro foo [] `'~(lazy-seq []))
16:26amalloyyeah
16:26arrdemBronsa: cheers
16:26mikerodhmm
16:26pjstadigtechnomancy: right maybe I mean a first among macros or something
16:26mikerodMy workaround where it occurred for me was to just not put a LazySeq there
16:26amalloywell, of course
16:26mikerodbut it is sneaky. I was trying to see if I could find a related defect somewhere
16:27amalloythere have been issues with emptyexpr somewhere before
16:27technomancypjstadig: sounds about right
16:28arrdemBronsa: AH. Cute! thanks, that block wasn't clear to me initially.
16:28johncashis there a way to see if a record implements a protocol?
16:28bendlasjohncash: satisfies?
16:28amalloy&(doc satisfies?)
16:28lazybot⇒ "([protocol x]); Returns true if x satisfies the protocol"
16:29johncash(inc bendlas)
16:29lazybot⇒ 1
16:29johncash(inc amalloy)
16:29lazybot⇒ 107
16:29bendlas... it's a start anyway ...
16:29arrdem(inc bendlas) ;; welcome to #clojure, have some karma
16:29lazybot⇒ 2
16:29Bronsaamalloy: mikerod I have a patch in a jira ticket that fixes that issue btw
16:30bendlas^^ thx
16:30amalloyoh, that's nice, Bronsa. i couldn't find it from google
16:30mikerodBronsa: well, that's good to hear
16:30mikerodI searched around the Jira, had no luck
16:30Bronsahttp://dev.clojure.org/jira/browse/CLJ-1093
16:31mikerodbest I found was http://dev.clojure.org/jira/browse/CLJ-62 ; and that's not it
16:31BronsaI don't really like my patch and I'll try to find a better solution in the next days btw.
16:32Bronsa,(print-dup (subvec [1 2] 1) *out*)
16:32clojurebot#=(clojure.lang.APersistentVector$SubVector/create [2])
16:33mikerodBronsa: I saw this Jira recently actually. I didn't connect the dots that it was related to the issue I just found.
16:34Bronsamikerod: the first half of the patch deals with your issue. instead of analyzing (lazy-seq []) in an EmptyExpr it leaves it as a ConstExpr and compiles it as a print-dup+read-string
16:34amalloyoh, i did find that one, Bronsa, but the title didn't look related to mikerod's issue
16:34mikerodYeah, I can see how it is connected now.
16:35Bronsaamalloy: mikerod essentially EmptyExpr can only compile PersistentList/Vector/Map/Set but will match any IPersistentCollection
16:35amalloyyes, i noticed that in the compiler
16:43mikerodmakes sense.
16:48noncom|2when using RT or Compiler from Java (note: I'm currently restricted to the old 1.5.1 way), is there any notion of Clojure environment, which persists between the evaluation calls, i.e. the same persistance as in a repl?
16:50amalloynoncom: the entire runtime persists
16:50justin_smithnoncom|2: isn't that persistence just based on the current namespace?
16:50amalloyit doesn't know whether you're calling it from java, or from a repl (which is, after all, java)
16:51arrdemBronsa: how is import bound? I'm not seeing it defined in RT.java, but it's used in core.clj prior to being rebound so I must be missing something.
16:51noncom|2justin_smith: but repl also persists in multiple nss
16:51noncom|2amalloy: that's very cool, so it will work for me then!
16:51gfredericksdoes it bother anybody else that C-u C-x C-e doesn't print stdout to the repl buffer?
16:52Bronsaarrdem: clojure.core/import* is a special form
16:52justin_smithwhat I am saying is def is a thing that stores a value to a symbol in a namespace, that's how things persist - if RT did not persist things, you would need to reload clojure between each call, and you would notice, because that takes a while
16:52nullptrgfredericks: yes!
16:52Bronsaarrdem: look for ImportExpr in Compiler.java
16:53arrdemBronsa: Ah. yeah it's import* I'm seeing used. osum.
16:53amalloygfredericks: what *does* it do, in cider or nrepl or whatever the cool kids are using now?
16:53gfredericksamalloy ignores stdout
16:53gfredericksprints result to the current buffer
16:53noncom|2justin_smith: oh that's true! i think me just wanted to be sure that using the internals from java code will behave the same way as from the repl
16:53amalloyin slime, it writes stdout and the return value both to the current buffer
16:54gfredericksI'm not sure I'd like that
16:54amalloyno, it sounds awful
16:54amalloyi never use C-u eval-stuff, myself
16:54amalloyi don't really get the use-case
16:54gfredericksI use scratch buffers a lot
16:54gfredericksfor clojure
16:54gfredericksand C-u is a nice way to have a record of what I was doing
16:55amalloyinteresting
16:55gfredericksby "scratch buffer" I mean an actual file that I keep uncommitted
16:55gfredericksso I'll have stuff lying around for weeks
16:55gfredericksfeels less transient than a repl
16:56amalloygfredericks: does cider remember your repl history yet?
16:56nullptrmy case: kicking off some api stuff that might take a few minutes to run, and not wanting to hunt around the *Messages* buffer for the result
16:56gfredericksamalloy: um; M-p works but I thought that was because of generic emacs
16:56amalloygfredericks: i mean across repl restarts
16:56gfredericksnullptr: I have a nice bg macro for backgrounding stuff, and would like the updat messages it prints to be in the repl buffer
16:57gfredericksamalloy: prollably not
16:57lemonodori do wish cider didn’t kill my repl buffers so eagerly.
16:57nullptrgfredericks: yes, it's annoying that the prefix arg changes that
16:57lemonodorpersistent repl history would be nice, but even just keeping my buffer around until i kill it would be cool.
16:57gfredericksnullptr: maybe I'll make a PR then
16:57technomancypersistent history is a thing
16:57gfredericksit feels more likely to be annoyed that the *out* is lost than that it's kept
16:58technomancyI don't know why it's not on by default
16:58amalloyi have stuff in my *slime-repl clojure* buffer that's about a week old, which i guess is the last time i closed/opened emacs? my input history goes back for a month or two, but i can see how it would be useful to use this C-u stuff to have the outputs associated with those inputs
16:58gfredericksI feel like scratch files are more flexible than a repl buffer
16:59arrdemgfredericks: here here... I like being able to save my scratch work.
17:00arrdemI actually have a ~/scratch project that's just bits and bats with a project dependency list as long as your arm where I prototype stuff before promoting it to a real project.
17:00pjstadiggfredericks: sounds like you want something more like session
17:01pjstadighttps://github.com/kovasb/session
17:01gfredericksyes but without a web browser :P
17:01pjstadigright :)
17:01gfredericksI'm not sure what features I'm missing though?
17:03arrdemso what was the rational for data_readers.clj rather than having a (define-syntax)?
17:04tuddinterop ? : does :exposes-methods param in gen-class only expose a protected SuperClass method?
17:04gtrakarrdem: the reader needs to be bootstrapped before anything else runs, and you can traverse classpath-resources recursively to assemble everything.
17:04gtrakarrdem: you need some kind of entry-point.
17:05tuddcan't seem to have clojure find protected methods. not sure why..
17:05gfredericksPR for cider & *out*: https://github.com/clojure-emacs/cider/pull/571
17:05gtrakarrdem: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6989
17:06arrdemgtrak: yeah I'm already looking at ti.
17:06gtrak notice it all runs at the end of core.clj
17:06gtrakso, before anything else.
17:06nullptr(inc gfredericks)
17:06lazybot⇒ 55
17:07arrdemhum.... close enought.
17:07arrdem(inc gtrak)
17:07lazybot⇒ 11
17:10arrdem(doc ..)
17:10clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
17:10arrdemoops. thanks clojurebot
17:11liflashhi everyone
17:12liflashi've got a problem starting a repl
17:12liflashi have a dev namespace that contains stuff for an austin repl
17:14liflashwhen starting a repl with the project.clj containing an init-ns with the dev namespace i always get the classnotfound exception for cemerick.austin.repls
17:14liflashwhen starting the repl without the init-ns in the dev namespace and requiring it in the repl everything works fine
17:14liflashany ideas
17:14liflash?
17:21kenrestivo(inc nobody-in-particular)
17:21lazybot⇒ 1
17:22kenrestivoalso, i thought .. was deprecated in favor of The Pointy Stuff, ie. -> and ->>
17:25amalloykenrestivo: not deprecated. just discouraged/displaced
17:26dgleesondoes anyone know if there is a plugin for lein or something to produce a dependency report?
17:27technomancydgleeson: like `lein deps :tree`?
17:27technomancyor maybe https://github.com/technomancy/lein-licenses
17:27dgleesonoh perfect
17:27dgleesonthanks!
17:27technomancynp
17:28dgleesonoh your plugin is even better, awesome, I'm trying to get all the libraries and stuff I'm using approved by legal at my work.
17:29liflashnobody any idea why a namespace wouldn't be found when starting a repl compared to being already in a repl?
17:33lemonodoreek. fear the number of “Unknown” licenses I’m seeing reported by lein licenses.
17:33technomancysadface
17:33technomancylemonodor: open issue reports if you can
17:33lemonodoralready in progress
17:33technomancyinvaluable man
17:34technomancythough don't trust the plugin's heuristic 100% either
17:34technomancythere could be a license that just isn't declared in a way that's easy to guess programmatically
17:34technomancythough it never hurts
17:34arrdemtechnomancy: don't you have a license as part of the project.clj?
17:35arrdemor are people silly and don't provide that..
17:35technomancyit's not required
17:35technomancythough lein yells at you during deploy if you omit it
17:36technomancyand you get it if you use lein new
17:38arrdemλα
17:40johncashso i have a record in an atom. im calling a function in that record that returns a new record. whats the idomatic way to update the atom? (reset! foo (func @foo "thing)) ?
17:40johncashidiomatic
17:41gfredericksnope
17:41gfredericks(swap! foo func "thing")
17:41johncashah
17:41johncashbrilliant
17:41johncashthis immutable stuff takes some getting used to
17:41tolstoyAnyone know if something changed in the latest OM such that "set-state!" no longer triggers an om render?
17:41gfredericksyep
17:41johncash(inc gfredericks)
17:41lazybot⇒ 56
17:43amalloyjohncash: it's not really immutable stuff if you're just shoving it all into an atom, eh?
17:43clojurebotGabh mo leithscéal?
17:46gfredericksamalloy: depends on how you interact with it; you still get snapshots
17:46johncashamalloy: isn't it still immutable, the pointer is just different ?
17:46sdegutisjohncash: swap requires pure function though
17:46amalloyyeah, what i said isn't really useful this time
17:46amalloy(dec amalloy)
17:46lazybotYou can't adjust your own karma.
17:46gfredericks(dec amalloy)
17:46lazybot⇒ 106
17:47amalloygfredericks: i know you've been fantasizing about doing that, so i thought i'd show you it was okay
17:47gfredericksamalloy: ...thanks man. I needed that.
17:47gfredericksI think I'm going to be okay now.
17:50gfrederickswhen are we going to upgrade this karma to LazyCoin?
17:50gfrederickswe just have to figure out how to enforce that mining for LazyCoin can only be done by helping people with clojure
17:52lemonodorthere, now everyone just has to accept my pull requests and then the whole world needs to update all their dependencies to the latest version, and lein licenses will give me a clean report. i do it not for myself, but for the clojurians of the far future.
17:53liflash2nd try: any idea why a class is not found on repl startup, but using it in a running repl is ok?
17:57johncashrace condition?
17:59liflashhmmm, i also thought about that... but it did work in the past and why would the repl init a ns without loading the classpath?
18:08arrdemliflash: some clojure code you load explicitly mutates the load path would be my bet.
18:10stuartsierraliflash: anything AOT-compiled? Try `lein clean`
18:11liflashyou're right, that's a possibility... it's the austin plugin and i think it does some stuff with the paths
18:12liflashthanks for the hint, stuartsierra, but that doesn't seem to do the trick
18:13liflashis someone able to reproduce this? maybe my project setup is kind of messed up
18:13liflashhere's my setting
18:15liflashproject.clj: :repl-options {:init-ns tools} :profiles {:dev {:plugins [[com.cemerick/austin "0.1.4"]]}}
18:15liflashin the tools ns i got the code from the sample project:
18:15liflash(def repl-env (reset! cemerick.austin.repls/browser-repl-env
18:15liflash (cemerick.austin/repl-env)))
18:15liflash
18:15liflash(defn browser-connected-repl []
18:15liflash (cemerick.austin.repls/cljs-repl repl-env))
18:15liflash
18:19liflashoh, and i get the classnotfoundexception for the cemerick.austin.repls
18:20stuartsierraliflash: Did you `require` the cemerick.austin.repls namespace before using it?
18:20liflashnot in the tools ns
18:21stuartsierraThere's your problem, then. :)
18:21streblowhat did people here do to learn clojure?
18:21liflashi thought it should work when referencing the whole classpath and name
18:21liflashbecause this works in the repl, too
18:22liflashand it did work in the past, already....
18:22stuartsierraliflash: No, Clojure namespaces are not loaded automatically, even when you refer to them by their full name, unlike Java classes.
18:22liflashhmmm, ok
18:22liflashlet me have a try
18:28liflashoh man..... this realy does the trick
18:29liflashthank you very much!!
18:29stuartsierraYou're welcome!
18:31liflashstreblo: i started with 4clojure
18:31liflashread a book
18:31liflashand started a small project to try out things
18:39noncom|2is there any example of using Var.alterRoot() from ajva?
18:39noncom|2*java
18:57gtraknoncom|2: you've gotta get the var instance, same as invoking a function.
18:58noncom|2gtrak: yeah, got success with it :)
18:58noncom|2too much boilerplate though
19:51hiredmanwhy would you use alterRoot from java?
19:52hiredmanI would hate to use it in clojure
20:02lemonodortechnomancy: thanks for the edn.all. i may also take a look at handling parent poms.
20:03technomancylemonodor: that would be sweet
20:03technomancylemonodor: unfortunately clojars has been a bit neglected recently
20:04technomancygood to get some fresh blood in
20:04lemonodorit’s an important resource!
20:05technomancyyeah, it has been working remarkably good for all the neglect it gets
20:05technomancy*well
21:32eflynnhi
21:46gfredericksholy crap rich likes clojure.core/update
21:46gfrederickssomehow I assumed that was impossible
22:12muhukIs there a more idiomatic way to do this? https://gist.github.com/muhuk/08bc80611590f2fe79b1
22:13muhukAssuming I idempotent-fn is a 3rd party function. And assuming I'm trying to avoid memoizing a local copy of it.
22:22gfredericksmuhuk: 3rd-party meaning a library or an external service-or-something?
22:24muhukgfredericks: no, 3rd party package, a lein dependency.
22:25gfredericksas long as it doesn't constitute a top-level side effect, it's fine
22:25gfredericksso looks good to me
22:25muhukgfredericks: let me ask you something else; does that form, fn inside a let seem ugly to you as well?
22:25muhukgfredericks: so, I guess no
22:25gfredericksyou could def the two results if you liked that better
22:25gfredericksthen you could keep a defn
22:26muhukgfredericks: right, but I was kinda trying to omit that
22:26muhukgfredericks: I wanted to somehow keep those 2 calls within my function definition (def or defn or whatever)
22:26gfredericksdecide what you hate more I guess :)
22:26muhukgfredericks: right.
22:27muhukgfredericks: thanks.
22:27gfredericksnp
22:36lemonodortechnomancy: i went with a really simple fix, but it seems to give much better clojars search results: https://github.com/ato/clojars-web/pull/210
22:38SegFaultAXIf I wanted to build my own http reverse proxy, what are some Clojure/Java libraries that I should start with?
22:40gfredericksI think I made quarter-assed one a couple years ago
22:42lemonodorthe world of pom parent resolution looks kind of nasty.
22:42gfrederickshttps://github.com/fredericksgary/lib-5141
22:42gfredericksSegFaultAX: ^ I'll bet you five bucks that isn't helpful
22:42SegFaultAXgfredericks: Actually that
22:42SegFaultAX's pretty helpful.
22:43gfrederickscrap
22:43SegFaultAXCought it up.
22:43SegFaultAXAnd your lunch money too.
23:13arrdemgfredericks: I can loan you a couple KƉ if you need it :P