#clojure logs

2013-04-01

00:07technomancyarg... four years of doing clojure and still get bit by that stupid stupid dashes-to-underscores nonsense
00:08technomancythe things we put up with for no good reason =\
00:30callenbottechnomancy: worth it to be using a language that isn't spoiled-milk stupid.
00:31technomancycallenbot: sure, but that doesn't mean we shouldn't be embarrassed when it is stupid
00:31callenbotOf course.
00:32callenbottechnomancy: honestly I'm just grateful for the graceful nil handling. I could do without the copious if-statements I have to write in Python.
00:32technomancy"graceful" nil handling?
00:32technomancyspoken like someone who hasn't used an HM type system? =)
00:32callenbottechnomancy: I have, but you know what I mean.
00:33callenbottechnomancy: compared with Python and Go which just let your shit fall apart every time...
00:33MikeSethgoddamn you, just by lurking in here I learn something new
00:33technomancyI dunno; clojure's handling of nil is also fairly embarrassing, but at least in this case we can blame the JVM
00:33callenbotbladeeblah I know Maybe/Either is better but it's still an improvement.
00:34callenbottechnomancy: if you *really* cared you'd use algo.monad
00:34technomancyI haven't written any nontrivial python... clojure's nil handling seems the same as ruby's
00:34callenbottechnomancy: but deep down, you know that Haskell and Scala's type systems are the Gentoo Ricers of the modern age.
00:34technomancycallenbot: if I really cared I'd fork core.typed
00:34callenbottechnomancy: you want a typed lisp?
00:34technomancycallenbot: no, I just want NPEs to go away
00:35technomancythat accounts for 70-80% of type errors
00:35callenbottechnomancy: this is why I implemented my own func call chain + maybe monad wrappers in python
00:35callenbotNoneType errors were driving me up a wall.
00:35callenbotI don't really need it in Clojure though, the Ruby-esque nil handling is (usually) enough for me.
00:36callenbotPerhaps partly because I don't chuck shit at JVM libraries very often.
00:36callenbotnot directly, anyway.
00:37callenbottechnomancy: the unspoken assertion here is that one advantage Ruby has on Python is nil handling.
00:38callenbotshort-circuiting and kicking nils through the call chain is my preferred way of working.
00:38technomancybecause nil can receive certain method calls?
00:38technomancylike .nil?
00:40callenbottechnomancy: no, more monadically in that functions can receive a nil argument and just spit back out
00:40callenbotand a monadic wrapper can short-circuit before it gets to that if you have that available
00:40callenbotbut if you don't, the behavior is baked in.
00:41callenbottechnomancy: .nil? is pretty trivial and doesn't really fix anything, Python's problem wasn't that None makes every action except comparison fail, it was that some fairly common sense operations wouldn't just spit the None back out like Clojure tends to in similar circumstances.
00:42callenbottechnomancy: if Haskell and Scala type systems are the cost of wrapping and compile-time checking for nils properly, then I'd rather stay on the other side of the fence.
00:42callenbotI like HM, but I don't like actually being forced to interact with the practical products of it (currently)
00:42technomancyeh; from what I gather scala doesn't really prevent NPEs properly anyway
00:43technomancyOCaml does though, without all the hoops of Haskell
00:43callenbottheir Option handles it.
00:43technomancyright, but only if you explicitly opt-in
00:43callenbottechnomancy: gods, don't remind me of OCaml. That's a heartache like Common Lisp.
00:43MikeSethholywar commenceth
00:43technomancy=\
00:43callenbottechnomancy: I mean heartache like I wish it was more successful.
00:43callenbotyearning :P
00:43technomancyyep, I hear you there
00:44technomancyI had such a great time with the language and such a wretched time with the libraries/tooling
00:44callenbotMikeSeth: 'fraid not.
00:44callenbottechnomancy: well the system type sizes thing was annoying.
00:44callenbotand the 31-bit integers
00:44callenbotthe tagging
00:44technomancyoh, for numerics?
00:45callenbotyeah it was janky.
00:45callenbottechnomancy: that there are multiple stdlib alternatives is disconcerting as well.
00:45technomancyI have a hard time getting bothered by numerics that are less horrible than JS I guess
00:45callenbottrue.
00:45technomancyeh; are you sure you're not thinking of D?
00:46callenbotno I'm thinking of Jane Street + the batteries included ecosystem
00:46callenbotit's really ghetto.
00:46callenbotalthough D is too.
00:46technomancyoh, sure; it's a bit different
00:46technomancyI mean with D there are literally two libraries claiming to be "the standard library" right?
00:46callenbotI don't know if I'd put it like that.
00:46callenbotit's more that there's an old and a new
00:47callenbotphobos was the new one i think?
00:47technomancyI thought it was one with a good license and one that was "official"
00:47callenbotoh, yeah.
00:47callenbotI mean there's the GNU D compiler.
00:48callenbotBut really, if you want something with strict semantics and HM like Ocaml, what's your practical options?
00:48technomancyjane street seemed like just a bunch of guys tired of the slow evolution of the language
00:48technomancywhich I can empathise with
00:48callenbotof course, they had work to do.
00:48callenbotunlike the french.
00:49callenbotfrom the OCaml wiki page: "Influenced F#, Scala, ATS, Opa, Rust" - frick.
00:49callenbotA list best summarized as: Microsoft, Insane, More insane, Weird and misguided, 20% done afters of dev.
00:49callenbotafter years*
00:50technomancyOpa =(
00:50technomancyso much promise, and then they careened off the deep end
00:52callenbottechnomancy: I think they saw Meteor and Derby and said, "WE SHOULD DO THAT"
00:52technomancy"you know how we could get funding or something? JAVASCIRPT"
00:53callenbotthey weren't wrong.
00:53technomancysad but true
00:53callenbotRust is disturbingly gnarly though.
00:53technomancystatements, right?
00:53callenbotI'd call that one of the lesser sins.
00:54callenbotthe type system seems good, but the actual *experience* of writing code is Rust is generally fraught with fear, confusion, and hate.
00:54technomancyyes, but all the more damning due to the fact that you have to go out of your way to make it worse
00:54callenbotthat might be due to the fact that it's 0.6 right now, but I can't really know for sure.
00:54callenbotI'm not actually sure if the developers care if anybody other than the internal Mozilla Servo developers are able to use Rust
00:55callenbotI don't think they actually care because they're too busy being ecstatic that they're getting paid to write a compiler on top of LLVM.
00:55technomancyclojurebot: creating a language with statements is a great way to broadcast your inexperience with languages to the world
00:55clojurebotYou don't have to tell me twice.
00:56callenbottechnomancy: unlike Go and OCaml, Rust is actually intended to go head to head with C++.
00:56callenbottechnomancy: so I'm less apt to question the statements.
00:56technomancywhich means what, appealing to people with severe head trauma?
00:57callenbottechnomancy: funny but I could imagine some edge cases where being able to decl a var is somehow helpful to the compiler.
00:57callenbotthe thin red line separating systems and applications programming is usually the dividing line at which the programmer services the compiler rather than the other way around.
00:59technomancythink about what it means that no one who understood scheme or forth or smalltalk was exposed to the design of the language before the point at which it was considered too costly to fix
01:00callenbottechnomancy: I don't know, pcwalton seemed pretty intelligent to me. I don't know why they did it.
01:01callenbottechnomancy: they have random cherry-pickings of Ruby-esque syntax like implicit return
01:04callenbottechnomancy: case in point, if you need to declare a range of memory "volatile", how do you do that without statements?
01:08huwtHI
01:08huwthi*
01:09huwt(list '(:a :b)) vs (list '(a b))
01:09amalloycallenbot: the same way you do anything without statements: make it an expression that returns nil or some analogue thereof. statements are just "expressions that are invalid in some contexts"
01:09huwtI don't get the difference... just started studying it 3hrs in but confused
01:10huwtone is a keyword, but what does this mean in implication...
01:10callenbotamalloy: you could do that, and that occurred to me, but it's a weird special case to have functions or expressions that act as pragmas.
01:11callenbotI have no qualm with getting rid of statements, I just find the offensiveness of them to other people in non-Lisp languages to be a bit extreme.
01:11callenbotit's not like anybody expected Rust to be a particularly powerful or elegant language.
01:12callenbotit's an experiment in writing a highly concurrent and powerful web browser.
01:51rplacahuwt: one is a keyword and one is a symbol. They're just different things in clojure
01:51rplaca'a is a symbol. If you use it without the quote, clojure will try to use it as a name
01:51rplacafor a let-bound value or a var
01:52rplaca:a is a keyword, it will evaluate to itself
01:52rplacaso in most contexts, you can use it without quoting
01:59RayneshyPiRion: Dude. Your Github contributions graph is going crazy.
02:01RayneshyPiRion: A friend on another network was admiring swearjure a moment ago. I told him of your awesomeness.
02:19phatpenguin#neo4j
02:24amalloyspeaking of swearjure, hyPiRion, i think first/rest, and CPS are a universal solution to the large-number representation problem, as long as you have a way to get lambdas anywhere in an expression
02:24amalloylike, i don't know how you manage lambdas, but for large expressions the transformation at https://www.refheap.com/paste/13171 generates a large number of small lambdas instead of one large lambda
02:25tieTYT2what's the point of defining something as dynamic when you don't need to define something as dynamic to with-redef it?
02:25amalloyinstead it has stackoverflow issues, of course, but if you pass it through a trampoline or some other CPS transformer it will get you around the large-method problem
03:17noonianHi, is there a standard way to get the name and version of my project from leiningen as defined in project.clj?
04:34borkdudeso any nice clojure April fool jokes so far?
04:44ivanI believe the wise Clojurians have simply turned off their Internet for 48 hours
04:47hyPiRionRaynes: Well, I'm trying to do at least one commit per day, and one bugfix on Lein per week. It's not that much work really, but it looks nice on the contrib graph, yeah
04:49tomojhyPiRion: seen gitminder?
04:50hyPiRiontomoj: nope, what is it?
04:50tomojhttps://www.beeminder.com/gitminder
04:50tomojuh.. sign up to give someone money if you don't keep your commit rate goal
04:50tomoj:/
04:50borkdudewhat is the best practice when doing multiple apps using a postgresql db? one database, multiple schemas? or one db per app? and one user per app, or just one user to rule all dbs?
04:52borkdudeyogthos I am trying postgresql - I noticed I have to change the sql to make it work from the guestbook example
04:52borkdudeyogthos for example, I have to convert java.util.Date to java.sql.Date
04:53hyPiRiontomoj: heh, well, if I suddenly get ill I don't want even more expenses
04:53hyPiRionamalloy: "as long as you have a way to get lambdas anywhere in an expression
04:53hyPiRionis probably the hardest part of Swearjure as of now
04:54amalloyi thought it might be, which is why i included the stipulation :P
04:54amalloybut i thought you had solved it
04:55hyPiRionwell, I can do it if I make a form and eval it
04:57hyPiRionI'll have to revisit lambdas within lambdas soon I think
05:04McTehranBurger,"Hallowed are the Ori"
05:04clojurebot"Hallowed are the Ori"
07:19borkdudelol, stackoverflow has "chat with an expert" as 1 april joke?
07:22arcatanmy expert wasn't very fun :(
07:22borkdudearcatan who not
07:22borkdudearcatan why
07:23arcatanshe was like "Whatever you say" all the time
07:47bhenrywhat is the best java for clojure dev on ubuntu machine?
08:01simsalibimwith compojure, how are most people doing RPC calls?
08:01simsalibimand clojurescript
08:02ivanbhenry: openjdk-7-jdk
08:03bhenryivan: is that objective?
08:06ivanthere may be reasons to use the Oracle build, or IBM's JVM, or Azul's JVM, but I bet you do not need them
08:06hyPiRionbhenry: If you don't notice any difference, either openjdk-6-jdk or 7 works fine
08:07hyPiRionI alternate between both, and I haven't noticed any major differences for development purposes
08:07bhenrythanks guys
08:07tomojuse 7 to avoid having to get jsrwhatever to use reducers
08:07tomojor is it just fold now?
08:08hyPiRiontomoj: oh right, if you need core.reducers, then 7 is smart to have
08:08hyPiRionI think it falls back to the normal reduce
08:36sandbagsdoes anyone here use LightTable and know if there's ever any activity in #lighttable? I'm not sure if I've just been unlucky so far
08:52si14how do you "unzip" a sequence in Clojure, preferably in one pass?
08:52si14I mean getting 2+ seqs from each element of one seq
08:55bhenrysi14: partition and partition-all might be good starts
08:55hyPiRionbhenry: I think that does the opposite of what he wants
08:55hyPiRion,(partition 2 [1 2 3 4])
08:55clojurebot((1 2) (3 4))
08:55bhenryi guess i need to see a sample in and desired out
08:56hyPiRionhas [[1 2] [3 4]], want [1 3] [2 4]
08:56si14[[1 2] [3 4] [5 6]] -> [[1 3 5] [2 4 6]]
08:56si14hyPiRion: yeah, thanks :)
08:56hyPiRion,(apply map vector [[1 2] [3 4] [5 6]])
08:56clojurebot([1 3 5] [2 4 6])
08:57hyPiRionI'm not entirely sure of performance on that one though. If you're in dire need of it, you may want to make something yourself
08:57si14it's kinda works, but not in general case.
08:58si14I have something like [[a1 b1 [c1 d1]] [a2 b2 [c2 d2]] ...] and need to get 2 maps like {[a1 b1]: c1, [a2 b2]: c2} and {d1: c1, d2: c2}
08:59si14it's can be done with reduce, but I wonder if there is an idiomatic approach.
09:00bhenrysi14: i think whatever you're doing is not idiomatic.
09:00si14bhenry: why is it so?
09:00hyPiRionWell, that's not covered by the normal funcs at least
09:02si14ok, I need to compute 2 different metrics on one seq simultaneously. how would you do this? my current solution is r/map of fun that returns vectors of values for each element.
09:05si14and, btw, am I wrong or clojure.core has a typo in a released version https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj#L321?
09:06hyPiRionsi14: that may well be
09:07hyPiRion$google jira clojure monoid
09:07lazybot[Overview - Clojure v1.6 API documentation] http://clojure.github.com/clojure/branch-master/
09:07hyPiRiondamn you, google.
09:07tomojhmm, I think you need a postreduce step to do that nicely
09:08si14tomoj: what do you mean?
09:08tomojwhich reminds me of cgrand's suggested change to fold
09:09tomojwell, see http://squing.blogspot.com/2008/11/beautiful-folding.html
09:09tomojI haven't tried to make sense of it in clojure yet, but I suspect reducers as is is not very well suited
09:10tomojdata Fold b c = forall a. F (a -> b -> a) a (a -> c)
09:10tomojthe (a -> c) seems to be missing?
09:14tomoj(= [10 24] (r/reduce (__ + *) [1 2 3 4]))
09:16si14https://gist.github.com/si14/df5b9afe28835f8cc154 well, here is a pair of functions in questions
09:16si14lines 10-15 are there only for rearranging the data. personally I don't like it.
09:18tomojoh, I missed everything before "I need to compute 2 different metrics on one seq simultaneously"
09:18tomojI'm going to try to solve my problem instead of yours :)
09:19si14tomoj: :)
09:19si14I would really appreciate any comments/suggestions on that snippet.
09:19tomojhmm https://www.refheap.com/paste/44fb973a86835a8bc4d7ce9b5
09:19tomojthat was too easy
09:22si14tomoj: yeah, that works for simple monoids like + or *. but for the general case it doesn't
09:24tomojwhat is the problem for the general case?
09:24tomojI mean the combinef/reducef split in r/fold seems tricky
09:25tomojare there more problems?
09:28si14tomoj: no, that's the problem :)
09:29tomojmakes me kind of want one thing that can represent both the combine and reduce
09:31tomojhttps://www.refheap.com/paste/224956f9814740700a3e7f377 ? :(
09:32tomoj(defprotocol IMonoid (-empty [this]) (-combine [this ret ret']) (-reduce [this ret v]))
09:32tomoj?
09:33tomojyeah, bad name..
09:33tomojI'd say 'IFolder' but..
09:37tomoj(defprotocol ICombine (-empty [this]) (-combine [this cret cret']) (-reduce [this ret v]) (-postreduce [this ret]))
09:38tomoj(extend-type Fn ICombine (-empty [this] (this)) (-combine [this cret cret'] (this cret cret')) (-reduce [this ret v] (this ret v)) (-postreduce [this ret] ret)) ?
09:40tomojwould allow cgrand's idea without breaking existing monoids
09:44jcromartiewhat *exactly* is print-dup
09:44jcromartieit's undocumented and not self explanator
09:44jcromartiey
09:44jcromartiebut it pops up in various examples and discussions
09:44tomoj,(doc *print-dup*)
09:45clojurebot"; When set to logical true, objects will be printed in a way that preserves their type when read in later. Defaults to false."
09:46jcromartieit specifically seems to rely on read eval
09:46jcromartie,(print-dup {} *out*)
09:46clojurebot#=(clojure.lang.PersistentArrayMap/create {})
09:46hyPiRion,(pr-str (doto (ArrayList.) (.add 1) (.add 2) (.add 3)))
09:46clojurebot"[1 2 3]"
09:47hyPiRion,(binding [*print-dup* true] (pr-str (doto (ArrayList.) (.add 1) (.add 2) (.add 3))))
09:47clojurebot"#=(java.util.ArrayList. [1 2 3])"
09:48hyPiRionjcromartie: do you get its use now?
09:48jcromartiemore or less
09:48jcromartieI don't quite understand why people advocate using the print-dup function directly in certain cases
09:49jcromartieit might just be the specific example I was looking at
09:49bhenrywhere can i find a walkthrough on the current best practice of a .emacs that works great for clj dev?
09:50bhenryi have the standard emacs from apt-get install emacs
09:50hyPiRionbhenry: Bodil has a great .emacs.d at https://github.com/bodil/emacs.d, which you may want to look at
09:51hyPiRionI have stolen that design for mine (https://github.com/hyPiRion/emacs.d)
09:51hyPiRionThough they are more extensive than just Clojure though, so if you're new to emacs they are probably a bit overwhelming.
09:51rkneufeldFor something a bit smaller you might try bit.ly/clj-ready.
09:52stuartsierrajcromartie: I don't think print-dup is meant to be called directly.
09:52jcromartieI didn't think so
09:52hyPiRion(inc rkneufeld)
09:52lazybot⇒ 1
09:53hyPiRionThat's a way better introduction for someone completely new. :)
09:56rkneufeldOnce the Clojure/west videos are up you'll also be able to see my presentation on editing Clojure in Emacs. Until then there are my animated slides: https://www.dropbox.com/s/rwjer7p9mirbwfw/Editing%20Clojure%20with%20Emacs.mov
10:24otfromafternoon all
10:35borkdudehttp://clochure.org/
10:43gfrederi1ksborkdude: wat
10:44gfrederi1ksthis must be date-related
10:46nDuff*snerk*
10:48tbaldrid_"A better Clojure" https://github.com/videlalvaro/clochure/
10:51snowylikeat first I thought this was an April Fools joke
10:51snowylikebut then...
10:51borkdudetbaldrid_ clojure for the masses
10:52hyPiRionHas to be.
10:52snowylikequote: "So one the eve of April 1st we sat down in a brainstorm session with a team of PLT experts. Ideas starting flying around:"
10:52snowylikewith "April 1st" in bold
10:56hyPiRionObvious is obvious
10:58hyPiRionclochure.core looks rather blocky
11:01gfredericksgreat logo
11:02otfromlovely
11:02borkdudeuntyped Haskell would be an alternative worth exploring
11:02hyPiRiongfredericks: We need one of those for Swearjure!
11:03jcromartieooh, a new clojure project to poke at https://github.com/oakes/Nightweb/tree/master/server
11:04jcromartiewait a minute
11:04hyPiRionWell, it certainly is new.
11:05jcromartiehere's the interesting stuff https://github.com/oakes/Nightweb/tree/master/common/clojure
11:06jcromartiepretty neat idea though
11:06otfromIs there something in clojure core that lets you restructure a map based on the parameters to a function?
11:06otfromI found this: http://stackoverflow.com/questions/8999794/map-restructuring
11:06otfrombut I'm wondering if I'm missing something core
11:07gfrederickshyPiRion: I'm terrible at logos
11:07hyPiRiongfredericks: Not you, we.
11:08gfredericksotfrom: not sure what you're asking. the top answer says "it's not provided" which is accurate. did you want something slightly different?
11:09jcromartierestructuring, huh, interesting idea
11:10jcromartiebasically printf for data structures
11:10bbloomotfrom: not really workable with maps because the reader initializes them as real data structures
11:11bbloomif you wanted to d something like obj = {a, b, c}, then you'd have an odd number of keys
11:11bbloomyou'd need to do something like {:keys [a b c]}
11:11jcromartiejust like destructuring
11:11bbloombut then you have no way of differentiating between assignment and restructuring, you'd need some kind of marker
11:12bbloomjcromartie: right, i'm just saying that it couldn't be baked into the syntax w/o creating ambiguity, you'd need to specifically request restructuring
11:12otfromWhat I'd like to be able to do is (defn foo [bar baz] ...) call (foo 1 3) and have {:bar 1 :baz 3} available in the defn
11:12gfredericksthat's defnk ain't it?
11:13gfredericksno wait
11:13gfredericksnevermind
11:13gfredericksotfrom: so you want a special extra local that has the arguments
11:14otfromI'm not sure I *want* it, but if it existed, then I'd want to use it
11:14otfromand it seems like it doesn't exist
11:14jcromartieotfrom: it seems easy enough to make
11:14clojurebotHuh?
11:14otfromand it is always so difficult to proves something doesn't exist ;-)
11:14otfromjcromartie: it does look simple to make, which is partly why I thought there might be something in core already
11:15otfromand I'd just feel silly for re-implementing it
11:15gfredericks(defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [&args {~@(mapcat (juxt keyword identity) arglist)}] ~@body)))
11:15gfredericks^ that has a 14% chance of working
11:15otfromlol
11:15gfrederickswait no 0
11:15hyPiRion14%? That's specific.
11:15gfredericksthe splicing won't work
11:15hyPiRion,(rationalize 0.14)
11:15clojurebot7/50
11:15hyPiRionWorks 7 out of 50 times, every time.
11:16gfredericks(defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [&args ~(into {} (map (juxt keyword identity) arglist))] ~@body)))
11:16hyPiRionyeah, you need a ~@[] before the mapcat
11:16hyPiRionboo
11:17otfromI just hate re-implementing clojure.core badly. ;-) But at least it looks like I won't be doing that this time
11:17loliveirais there some way to implement "private" variables inside a defrecord?
11:17jcromartie(defmacro ?map [& names] `(into {} ~(mapv #(vector (keyword %) %) names)))
11:17gfredericksoh one more issue the fully qualified &args
11:17jcromartieI have no idea what to call it
11:17gfredericks(defmacro defn' [name arglist & body] `(defn ~name ~arglist (let [~'&args ~(into {} (map (juxt keyword identity) arglist))] ~@body)))
11:17gfredericksotfrom: ^ that seems to work in my repl
11:18bbloomloliveira: to what end?
11:20hugodI just found then when generating type hints on let bindings with a macro, you have to use class symbols, rather than classes themselves, or the type hints are silently ignored :(
11:20jcromartieloliveira: deftype's fields are public, deftype's fields are private
11:21bbloomjcromartie: huh?
11:21jcromartiebbloom?
11:21clojurebotbbloom: readability is not binary
11:21bbloomjcromartie: i assume you mean defrecord and deftype specifically
11:21bbloomer respectively*
11:21jcromartieoops
11:21jcromartieyea
11:21loliveirabbloom: I have a record that holds database credentials. (defrecord DB [spec] …) spec is a map, it holds user, pass, driver, etc.. I'd like to store a pool into the record, but I think it should be private.
11:22jcromartieloliveira: why combine the DB spec and the pool?
11:22bbloomloliveira: why do you need a record at all?
11:22jcromartie^^ that too
11:22bbloomrecords are an advanced feature
11:22bbloomthey are mostly a performance tool for when you need type dispatch
11:23loliveirabbloom: I need to work with 2 databases. it shoud
11:23bbloomso make two maps of credentials
11:23bbloomand stick them in a vector or something
11:23bbloomand stick that in a map with the pool
11:24tjgillieswhy do people use two semicolons for comments when one is fine? seems sort of redundant
11:24bbloom{:pool POOL :connections [{:username "foo" :url "xyz://..."} {:connection-string "asdfasdf"}]}
11:24bbloomtjgillies: common-lisp-ism. one semicolon is a line comment for stuff to the left of the ;
11:24jcromartietjgillies: https://github.com/bbatsov/clojure-style-guide#comments
11:25jcromartietjgillies: think of it like headline levels
11:25bbloomyeah, what jcromartie said
11:25loliveirabbloom: thank ypu
11:25loliveirai ll try.
11:25tjgillies...
11:25tjgilliesthat websites just says "do this because i say so"
11:25tjgilliesheh
11:25AimHereWell isn't that what all style guides are for
11:26bbloomi dunno anything about that particular styleguide
11:26tjgilliesthats kinda my point
11:26tjgillies;)
11:26bbloombut it's very common in lisps to have ; line comment, ;; block comment ;;; region comment ;;;; file comment
11:26technomancyriastradh' style guide says "do it this way because parens on their own line get lonely" which is pretty great
11:26AimHereMost of the content in most coding styles are arbitrary; but it's still good practice to follow one of them
11:27hyPiRionbbloom: there should be another one in project.clj, which has ;;;;; for project comments
11:27technomancy"do it this way because you'll sound funny if you don't" is basically the cornerstone of all human language though
11:27hyPiRionand then obviously ;;;;;; for system/application comments
11:28enquoraanyone have experience with pedestal yet?
11:28bbloomhyPiRion: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; line separators == "comment on the universe below this point"
11:28tjgilliestechnomancy: yet here we are programming with parenthesis and such ;)
11:29technomancytjgillies: all those crazy languages with curly brackets and semicolons just sound like gibberish to me
11:29tjgillieslol
11:30technomancyhttp://achewood.com/index.php?date=02212002
11:30bbloomi can't ever remember associativity rules anyway
11:30tjgilliesi just realized putting a semicolon on the end of each line is valid clojure
11:30hyPiRionI suspect John McCarthy invented the emoticon and just wanted to be able to insert ;) at any place within his source code.
11:30technomancyheh
11:31eggheadachewood rules
11:31tjgilliesomg thats messed up if not funny
11:31hyPiRiontjgillies: Putting a semicolon at the start of each line is also valid Clojure
11:32tjgillieshyPiRion: it tends to make my programs less buggy as well
11:32hyPiRionyeh
11:34stuartsierratjgillies: Emacs will automatically indent ; at right margin, ;; at current code indent level, and ;;; at left margin
11:35tjgillies(inc stuartsierra)
11:35lazybot⇒ 3
11:35ucbstuartsierra: I rather enjoyed your post on scope
11:35stuartsierraucb: Thank you.
11:35ucbno, thank you.
11:36stuartsierraYou're welcome. :)
11:37ucbstuartsierra: sorry if this is a silly question, but I got to your blog via planet clojure and I couldn't find an RSS link on your blog. Is this by design?
11:38stuartsierrano
11:38stuartsierraIt uses feedburner.
11:38bbloomwhich is surely going to be killed soon.
11:38ucbhmm
11:38ucbheh
11:38stuartsierraI changed the theme recently: maybe the link is broken.
11:39borkdudewhat advantage has defhtml in hiccup over a normal function with html form?
11:39ucbI couldn't even find the link :)
11:40stuartsierraucb: Yeah, I should fix that.
11:40ucbgood to confirm it's not my tired eyes then
11:41stuartsierraThanks for the heads-up. I'll try to fix that.
11:42stuartsierraucb: The link, by the way, is http://stuartsierra.com/feed
11:43borkdudeANN: Untyped Strictly Evaluated S-Expression Haskell for the JVM http://t.co/kQoxHEcmeM
11:46bbloomborkdude: lol.
11:46tjgilliestoday is gonna suck
11:46tjgillies:)
11:49stuartsierraThere, RSS links added.
11:49TimMcI've seen a defn+opts
11:50TimMcwhoops, I was in the scrollback
12:00estebannls
12:00lazybotbin lib opt proc root sys
12:03estebanni'm trying to get an internal maven repo setup and I'm having a bit of trouble with leiningen
12:04estebanndeploying works fine but the Authentication string is not sent when trying to download artifacts from the local mirror of central
12:04estebannhas anybody setup leiningen to use mirrors with basic http authentication?
12:06technomancyestebann: are you able to pull from it if you treat it like a regular repo instead of a mirror?
12:07estebanntechnomancy: i have been testing against an artifact available in central and it seems to try central first if I don't setup a mirror
12:07estebannI could be wrong about that, let me check
12:10technomancyyou can do :repositories ^:replace [["myrepo" {...}]]
12:10technomancyto disable central/clojars
12:10lyra77http://xteensx.info/young-amateur-czech-couple-very-hot-sex-scene/
12:11technomancy~guards
12:11clojurebotSEIZE HIM!
12:11estebanntechnomancy: cool, I didn't know that
12:13hyPiRion~gourds
12:13clojurebotSQUEEZE HIM!
12:13technomancyclojurebot: botsnack
12:13clojurebotthanks; that was delicious. (nom nom nom)
12:15estebanntechnomancy: yeah, that works
12:15hyPiRionAh, that's another plugin idea for lazybot/clojurebot: Say something whenever suspicious links appear here
12:15estebanni can pull the artifact from the proxy
12:16jcromartiebleh… mixing mutable thread-unsafe Java objects and Clojure concurrency
12:16technomancyestebann: so the problem there is that it might allow for transitive dependencies to skip the proxy
12:16jcromartieinstant pain!
12:16technomancyI haven't really looked into it, but I think the advantage of :mirrors is that *all* references to central go through your repo instead
12:17technomancywhereas with :repositories you can still have other repos sneak in through declarations of using central inside a dependency pom
12:17estebannah, gotcha
12:17technomancyI was mostly asking that to see if lein could authenticate at all
12:18technomancythat is, whether the auth issues were specific to the mirror functionality
12:18estebannmakes sense
12:18technomancyunfortunately I've never actually used mirrors myself =\
12:18borkdudeclojars april fools joke that didn't make it: for each jar you download, you have to contribute one library :P
12:19wtingHey guys, I'm trying to compile a hello world example via lein repl, but ('compile clojure.examples.hello) gives me a file not found in classpath. What the directory structure I should be using?
12:19estebanntechnomancy: should mirrors work like I am expecting them to? or have I misunderstood their capabilities
12:20hyPiRionwting: (compile 'clojure.examples.hello) instead, I suppose :)
12:20wtinghyPiRion: oops, that's what I meant. :p
12:20technomancyestebann: I'm not quite sure what your expectations are, but you haven't said anything obviously incorrect yet =)
12:20borkdudewting probably don't want to name your namespaces starting with clojure
12:20hyPiRionwting: but are you using Leiningen, or just pure Clojure?
12:20technomancyTBH the mirrors stuff is kind of hand-wavy from my perspective; I just hand off to Aether and it does the rest
12:21estebanntechnomancy: ok, I guess I'll look into what's going on in aether, thanks for the help
12:22wtinghyPiRion: Well I'm not using lein new to create the project, I'm just trying to compile it via `lein repl`. I just want to get a hello world compiled example working.
12:22technomancyestebann: how are you configuring mirror auth?
12:22technomancyit might be that Leiningen just isn't honoring auth settings or something
12:22estebann:creds :gpg like everything else
12:22technomancyyeah, that could just be an oversight of Leiningen that it doesn't check there maybe?
12:23technomancyif you put the creds inline does it work?
12:23estebanni'll check
12:25hyPiRionwting: Well, the docstring says "The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."
12:26estebanntechnomancy: yeah, that worked. should I submit a bug report?
12:26hyPiRionwting: So if have /some/dir in your classpath, then the file should be /some/dir/clojure/examples/hello.clj
12:26technomancyestebann: yeah, go for it
12:26estebanntechnomancy: thanks again
12:26technomancyno problem
12:33augustlare there any asset pipeline (name borrowed from Rails) systems around for Ring apps? For stuff like compiling non-JS to JS, only serving one minified file in production (from memory, probably), etc
12:37scottjaugustl: maybe dieter, see pdf in clojurewest slides Biggar-cljv8_dieter_asset_pipeline.pdf
12:37wtinghyPiRion: So I have a file in /tmp/hello/src/hello.clj with (ns hello (:gen-class)). In /tmp/hello I run `java -cp /usr/share/clojure/clojure.jar clojure.main`
12:38wtingHowever (compile 'hello) still fails. Should namespace be src.hello in hello.clj?
12:38hyPiRionwting: ugh, let me just find out what Leiningen does in a project :p
12:39wtingI have lein installed if that's quicker
12:39augustlscottj: looking it up, thanks
12:40hyPiRionwell, it's easier to make a project (`lein new app projectname`) and just use lein repl, then all classpaths and so forth are fixed for you
12:41wtinghyPiRion: ahh ok, I see. I managed to compile the classes just fine, now I gotta figure out how to run them. :p
12:42hyPiRionI think that's the general consensus in the Clojuresphere.
12:42hyPiRionwting: Leiningen can take care of that too :) `lein run` runs the project, `lein uberjar` creates a standalone jar
12:43hyPiRionwith uberjaring, the jar file lies within target/name-of-project-0.1.0-standalone.jar by default
12:43hyPiRion(run by `java -jar name-of-jar`)
12:46jaleymaking extensive use of the closure library from clojurescript is just asking for typos
12:51pl6306I am processing a seq of strings. Is there something like a take while? So I can create maps after the first instance of say "--------------------------"?
12:53hyPiRion,(take-while #(not= "---" %) ["a" "b" "hey" "---" "Not" "used"]) ; ?
12:53clojurebot("a" "b" "hey")
12:54pl6306How about if only want the tail of the seq?
12:54jaleypl6306: drop-while?
12:54pl6306thanks
12:54hyPiRionyeah, (rest (drop-while instead
12:55bbloomibdknox: i see you forked fipp. anything interesting in mind? (also, if you're using it, you should update as there was a major bug fix thanks to octagon)
13:05wtinghyPiRion: managed to compile and run the jar, thanks!
13:05tieTYThttp://stackoverflow.com/questions/15747774/whats-the-point-of-defining-something-as-dynamic-when-you-dont-need-to-define
13:08hyPiRionwting: you're welcome, enjoy :)
13:10gfrederickstieTYT: binding is thread-local, and with-redefs is not; thus the latter is not generally thread-safe
13:11tieTYTdoes that mean that with-redefs will have an affect outside of its scope if another thread tries to run the function?
13:12finishingmovehey guys, how would i do something like (int 2.6) but to get 3 instead of 2 ? (round up)
13:14hyPiRion,(int (Math/round 2.6))
13:14clojurebot3
13:14joegallotieTYT: yes, it's a global thing, often useful for tests, probably not useful for normal code
13:15joegallo,(int (Math/round 2.1)) ;; though
13:15clojurebot2
13:15finishingmovethanks guys
13:15joegallo,(int (Math/ceil 2.1)) ;; perhaps you want this
13:15clojurebot3
13:15finishingmovehm
13:16finishingmoveso i guess there's a Math/floor too :)
13:16joegalloaye
13:16tieTYTok but if you're single threaded, then the redef only occurs in the lexical scope of the with-redefs, right?
13:16hyPiRionyup
13:16tieTYTok
13:16joegallotieTYT: sure...
13:16technomancytieTYT: no, with-redefs has dynamic extent
13:16finishingmovenewbie question, but can i somehow add a 'use' statement somewhere and not have to write "Math/ ..." explicitly?
13:17tieTYTtechnomancy: i understand it redefines in a dynamic way
13:17tieTYTbut once the scope of the with-redefs exits, the function goes back the way it was defined, right?
13:17technomancyyes
13:18technomancy(which is not how lexical scope works)
13:18tieTYTright
13:18hyPiRiontieTYT: I think you flipped dynamic and lexical
13:19tieTYTwhat I was saying is that if the with-redefs is nested, its redef only takes effect under its scope and not outside of it
13:19tieTYTjust like how if you nest a let, those symbols only have those values under the let's scope
13:20technomancyno, let is different
13:20technomancyit doesn't extend inside the calls in the let body
13:20tieTYTi understand
13:20tieTYTi'm not talking about the functionality, i'm talking about the scope of their effect
13:20hyPiRionfinishingmove: I don't think there is, actually.
13:20tieTYTanyway I think I get it :)
13:21finishingmovehyPiRion hm... maybe some 3rd party support?
13:22hyPiRionfinishingmove: there was this thing called import-static, but I don't think it has been updated since Clojure 1.2
13:24hyPiRionyou could always try it out though
13:27TimMcfinishingmove: May I offer a compromise? (.importClass *ns* 'M Math) then (M/abs -3)
13:27finishingmoveTimMc yes that looks neat
13:30RaynesSigh.
13:30RaynesLooks like Charles Nutter is trying to 'fix' Lisp syntax as well.
13:31technomancyRaynes: I loled until I saw the "not an april fools joke" message at the top =\
13:31Raynestechnomancy: Yeah, I'm arguing with him and he is being very trollish.
13:32tomojwhere's this?
13:32technomancyhe should know better, but yeah... nothing to be done
13:32RaynesTwitter, tomoj.
13:34technomancyRaynes: I linked to his gist on the lein-xml announcement though =D
13:34callenbotRaynes: dude implements a slow Ruby implementation (original, yes?) and now he has something to teach everybody :P
13:35technomancy"a slow Ruby implementation" is there another kind?
13:35technomancyJRuby's fast for a ruby though
13:35callenbotkinda-sorta-not-really.
13:36callenbottechnomancy: MacRuby and Rubinius are neat.
13:36bbloomtechnomancy: yes, but they aren't really rubies so much as they are ruby look alikes :-P
13:36bbloomMacRuby is just objective C with ruby syntax & statically resolved metaprogramming, which, to be fair, is a huge step up from no meta programming
13:37callenbotwell I like Elixir too.
13:37Raynestechnomancy: I just hate it when I respect people and then they do things like that and it smells so much like trolling that I'm baited in and I have to make them hate me with logic.
13:38callenbotRaynes: can you link what he's doing?
13:38tomojhttps://gist.github.com/headius/5285216
13:39callenbotsigh.
13:39amalloywait, Raynes, if it smells like trolling that should do the opposite of bait you in
13:40callenbotnobody that actually writes Lisp, cares.
13:40callenbotthis is a stupid gist.
13:40tomojdoesn't his "Immutable data structure example" call the data structures with no arguments?
13:41tomojI guess he thinks functions are these special things and you always know whether a symbol resolves to a function
13:41bbloomtomoj: yeah, that's the main problem with these indentation based approaches. they assume static type knowledge
13:41Raynescallenbot: https://twitter.com/headius/status/318780382348726272
13:42RaynesThis is part oft he thread.
13:42RaynesBut there is a lot more spread out.
13:42RaynesLook at my or his twitter stream for more bitching.
13:42callenbotokay, so I admire Erlang
13:42callenbotbut I don't swoop into their community claiming to be able to solve what I think are their "problems"
13:42callenbotwhy is he doing that to us?
13:43RaynesBecause he can.
13:43RaynesAnd he really thinks he is right.
13:44callenbotRaynes: must not work with macros on the regular.
13:44RaynesI'm more concerned that 5 people have told him he is utterly wrong and he just keeps repeating the same pointless things.
13:44RaynesMake that 6.
13:44RaynesPeople are still hopping in to tell him he is wrong.
13:44callenbotmy mental bucket that says, "Ruby programmers are shallow" just had a few pebbles chucked into it.
13:44callenbottechnomancy: sorry!
13:44true_droidhey guys. I'm not very proficient with Clojure, but I'd like to find out how exactly existing Clojure collections reduce themselves with a given reducer
13:45true_droidcould someone point out places in Clojure source where to look?
13:45RaynesI don't think it has anything to do with what community he is from. It's more that he just hasn't even used Clojure and has decided it is broken and he is the messiah who can fix it.
13:45bbloomtrue_droid: grep for coll-reduce
13:45technomancycallenbot: more like "being good at compilers doesn't mean you won't suck at issues of crossing community divides" maybe?
13:46true_droidbbloom: thanks
13:46callenbottechnomancy: I'll go with that, but usually people that have tackled seriously large projects are more humble.
13:46technomancycallenbot: I'm a bit sympathetic because the enormous amounts of shit he gets from ruby people who are like "eww yuck java" when they read about jruby
13:47bbloomi'm once again struck by how forcefully cond resists being formatted cleanly in ANY syntax/notation
13:47callenbottechnomancy: if you need jruby's concurrency mechanisms, then you shouldn't be using Ruby anyway :P
13:48amalloybbloom: i have a cute trick for that, if you like
13:48technomancycallenbot: not always an option. but anyway, this gist is stupid; no argument.
13:48bbloomamalloy: oh?
13:48technomancyand yeah, cond is super annoying
13:48amalloythe biggest problem is when the conditions are long enough that you need to wrap the then-clauses onto the next line, right?
13:49bbloom*shrug* when that happens i tend to just indent all of the then-clauses
13:49amalloyso you indent the then-clause with two commas, and emacs doesn't know it can delete them to "fix" your indentation
13:49bbloomamalloy: hmm interesting heh
13:49bbloomi don't use emacs, so i don't fight with the indenter nearly as much
13:50hyPiRionWell, that's a limitation to clojure-mode though. I wouldn't be surprised if that can be fixed.
13:50jcromartieI didn't know people were so hung up on parens
13:50jcromartieon both sides
13:50bbloomjcromartie: it's just alien to people
13:50amalloyhyPiRion: it probably can, but nobody will. the indenter is hard to understand, and if it special-cases cond then your enhanced-cond macro will still be just as bad
13:52hyPiRionI'm not surprised.
13:52technomancyevery time I have to write a cond where the body clauses need their own line it just makes me think I should be using core.match
13:52bbloomtechnomancy: but matching has a similar problem. the issue is more generally: 2D structures are hard to work with in text
13:52TimMctechnomancy: core.match is still woefully undercooked.
13:53bbloompattern matching adds some extra brackets and syntax that aleivates the problem :-P
13:53bbloomalleviates* sheesh i can't spell and or type
13:53technomancyTimMc: yeah, we played with it at seajure and came to that conclusion
13:53technomancykind of bums me out that it's not under active development any more
13:54bbloomtechnomancy: on a totally random side note. have you ever seen jonathan edwards schematic tables?
13:54bbloomsuper cool.
13:54technomancybbloom: I think I saw some of that at his emerginglangs talk?
13:54technomancythat was like 2009 though so I'm a bit fuzzy
13:54bbloomtechnomancy: http://subtextual.org/subtext2.html
13:55bbloomtechnomancy: it's obviously just research/experimentation, but damn it's a cool demo
13:55technomancyflash =(
13:56bbloom*shrug* you have no way to view flash at all?
13:56technomancyI could get my wife's computer I guess?
13:56bbloomlol
13:56bbloomok, well if you ever get 40ish minutes to watch it, i recommend it
13:56bbloomit's a really cool demo
13:57technomancyIIRC his emerginglangs talk was pretty FRP-heavy?
13:57bbloomdidn't see it
13:57bbloomthis is an older demo about his idea of a GUI for visualizing decision trees & data flow
13:57callenbotStuff like FRP makes functional programming look bad to the muggles, IMHO.
13:57technomancyI get the feeling if I try to find it I'll find a bunch of fire-and-brimstone 18th-century sermons
13:58ztellmancallenbot: how so?
13:58callenbotztellman: making things they thought they already understood more complicated.
13:58amalloycallenbot: doesn't all of FP do that?
13:58callenbotztellman: speaking from what I saw of it in Haskell, anyway.
13:59amalloy"gosh dang, i already understand loops, why is this reduce stuff so friggin complicated"
13:59technomancythe FRP presentations I've seen aren't like that at all
13:59callenbotthe lengths one had to go to to simply make a game was obscene.
13:59technomancyelm and Edwards' stuff
13:59ztellmancallenbot: it's basically just the same conversation as callbacks vs promises, maybe you've just seen needlessly opaque presentations
13:59bbloompart of the problem with functional programming is that it makes complexity more apparent
14:00bbloomit seems harder b/c it IS harder than it seemed before :-P
14:00bbloomhowever, it's just as hard both ways lol
14:00callenbotztellman: I don't really have a problem with it
14:00seancorfieldthat sounds like a positive, not a problem, bbloom
14:00callenbotztellman: I have a problem with the impression it makes.
14:00bbloomseancorfield: you're right. let me qualify: the ADOPTION problem
14:00ztellmancallenbot: write a letter to your haskell congressman, I dunno
14:01callenbotztellman: I don't think anybody had serious trouble understanding promises
14:01callenbotand promises offer a simplification of code that I think most can grasp.
14:01callenbotI'm not sure the same is the case with FRP unless you've been deep down in the tarpit.
14:01ztellmancallenbot: honestly, promises are only a hop, skip, and a jump away from FRP
14:02bbloomcallenbot: 90% of the time, people just want to immediately resolve a promise, but lack of lightweight threads makes that a problem
14:02ztellmannot in terms of complexity, I mean, but in terms of actual underlying concept
14:03callenbotztellman: well if you put up a talk demonstrating as much, you'll probably solve some of the marketing problems.
14:03callenbotztellman: again, this might be a Haskell thing, but writing games with FRP was, "lets write a thesis!", not, "lets write a game!"
14:04ztellmancallenbot: oh, in academia FRP is a big wanky black hole
14:04bbloomztellman: you can say that again.
14:04hyPiRioncallenbot: It's all the formal words, I think
14:05hyPiRionmonoid? catamorphism? zygohistomorphic prepromorphism?
14:05hyPiRionIt frightens people.
14:05callenbotI was speaking of the code.
14:06callenbotI don't pay any attention to category theory.
14:06bbloomhyPiRion: i think it's different than frightening people. i think it's actually a cognitive burden to have such big words
14:06gfredericksmonoid is six characters
14:06gfredericksmonad is even shorter
14:07bbloommonoids are quite easy to understand :-P monads have a different problem
14:07gfredericksmaybe we should rename monads something longer and scarier so people will stop being improperly interested
14:07bbloomlol
14:08gfredericksendofunctorial-monoid maybe
14:08gfredericks(EFM)
14:08bbloomit's like the word "blog"
14:09bbloomthere were news sites and personal home pages with regular updates long before the word "blog"
14:09hyPiRionMaybe we should just enterprisify it
14:09bbloomif you had called it a "automatic personal news publishing home page" it would have never caught on lol
14:09hyPiRionConnectionListenerMonoid
14:09hyPiRionThere we go, now we can ship it.
14:10ztellmanbtw, since some people here have been down the FRP rabbit hole
14:10ztellmananyone aware of something that deals with how FRP interacts with TCP backpressure?
14:10ztellmanI've searched in vain
14:11bbloomztellman: huh?
14:11ztellmanbbloom: FRP in a server context
14:11amalloyztellman: the connection between those is hard to see, even knowing that you must mean in aleph/lamina. what's a more specific part of the problem?
14:12ztellmanso I was looking at all the various versions of Rx
14:13ztellmanit's not clear to me if there's a story for when you can't reach the end of the FRP chain synchronously
14:13ztellmani.e. there's a queue, or pending write over the network, etc.
14:14ztellmanthe main problem here is that I'm not even sure what the right terminology here is, as maybe evidenced by my question
14:14ztellmanbbloom, amalloy does that make any more sense?
14:14bbloomztellman: i know of many of the words & technologies you're talking about, but i have no clue what you're asking....
14:14bbloomztellman: rewind and simplify
14:15bbloomztellman: or maybe provide a concrete example
14:16amalloyi think so, but i'm definitely not qualified to answer it myself
14:16ztellmansure, trying to figure out the best way to unwind this
14:16ztellmanok, simplest example:
14:16ztellmanyou're a proxy between two different computers
14:16ztellmanyou're taking messages from one, doing some sort of transformation, and forwarding it to the other
14:17ztellmanin general, these messages can be considered in isolation
14:18ztellmanbut if the bandwidth of the producer outstrips the consumer, you start to run out of memory as the messages back up
14:18callenbotztellman: wouldn't backpressure throttling mean the promises block longer?
14:18bbloomztellman: aaah ok, i now think i get what you're asking
14:18ztellmancallenbot: promises representing what, exactly?
14:19callenbotdeliverable result of some sort.
14:19ztellmanbbloom: my reading of FRP is that each value propagation is calculated in isolation
14:19augustlhmm, is it true that the routing module is what adds a "href" attribute to all "a" tags?
14:19augustlerr, wrong channel
14:19bbloomztellman: so FRP is a totally overloaded and completely useless acronym
14:19ztellmanhaha, ok
14:19bbloomztellman: in this case, you're talking about Push Streams
14:19bbloompush sequences
14:19bbloommicrosoft's Rx
14:19bbloometc
14:19ztellmancorrect
14:20bbloomwhat FRP originally meant and is most commonly discussed in the literature as is for dataflow systems basically
14:20ztellmanso to greatly simplify my question: what happens with push streams when there's no more room to push?
14:20bbloomlet's ignore ALL that and talk about push sequences
14:21bbloomztellman: so yeah, this is a distributed systems problem
14:21bbloomyou have to choose a policy
14:21bbloomblock the sender (how?), drop messages (which?), etc
14:21bbloompush sequences are fundamentally no different than sockets in their design space
14:22ztellmansockets in the generic sense?
14:22bbloomyeah, like unix sockets, but more similar to zeromq sockets or message passing sockets
14:22bbloomone problem IMO with Rx is that the pipeline is opaque
14:22ztellmanyes, agreed
14:23bbloomyou can't look inside each phase of the transformation & modify it
14:23bbloomwhich is a problem w/ functions too, but it's not as big a problem cus functions rarely have internal state
14:23bbloomif you add an atom to cache stuff in your function, then suddenly your function is harder to work with, debug, etc
14:24bbloompush sequences inherently have some state/context and you can't see that easily
14:24bbloomone school of thought is that you don't NEED to see it
14:24bbloomthat's the zeromq way
14:24bbloomi highly recommend reading http://zguide.zeromq.org/page:all
14:25bbloomit's long, but it has some reeeaaaally good explanations about common patterns for robust distributed communication designs
14:25ztellmanI read it a ways back
14:25ztellmanbut i'll take another look, thanks
14:25borkdudejust checkin, this should be safe? db.config just contains a map with some settings (clojure.edn/read-string (slurp "resources/db.config"))
14:26ztellmanspecifically w.r.t. the policies you mentioned above, though
14:26ztellmanis there a first-class representation of that in Rx?
14:26amalloyborkdude: yes, that cannot execute any code as far as i know
14:26bbloomi dunno
14:26bbloomzero mq has different types of sockets & the pairing of sockets dictates policy for things
14:27ztellmanok, cool
14:27ztellmanI'm looking for prior art in that space, I think I glossed over that part of it before
14:27ztellmanin zmq, that is
14:27bbloomin theory, you could create Rx components that essentially map to the buffering and blocking policies of zeromq
14:28bbloomthe tables on this page summarize: http://api.zeromq.org/3-2:zmq-socket
14:29ztellmanperfect, thank you
14:30ztellmanon a tangential note, could you characterize the difference between push sequences and standard dataflow?
14:30ztellmanI think I've gotten them conflated in my head
14:31bbloompush sequences have a linear notion of time, dataflow as an instantaneous notion
14:31jcromartieany reason to use (Double. x) over (Double/parseDouble x) ?
14:31technomancyjcromartie: I think the former accepts things that are already doubles?
14:31technomancyat least for Integer that's how it works
14:32bbloomztellman: FRP dataflow systems tend to have concepts like signals, behaviors, etc. push sequences basically have subscribe/unsubscribe/push
14:32bbloomztellman: it's sorta like comparing lazy seqs to lazy evaluation
14:32bbloomonly it's push seqs to push evaluation
14:33ztellmanbbloom: ok, so behaviors vs streams
14:33bbloomi guess so
14:33bbloomlike i said, FRP is an overloaded and muddled term
14:33ztellmanand I've read a small subset of the literature, so I'm just trying to line things up to terminology I've already heard
14:33TimMc~frp
14:33clojurebotFRP is Functional Reactive Programming, or maybe fiberglass reinforced plastic (and sometimes Functional *Relational* Programming, just to be confusing)
14:33tomoja coworker decided he needed to make sure the internet (which was working) was going to work, so decided to fuck with the router. during an FRP discussion :(
14:34ztellmanbbloom: anyway, thanks
14:34TimMctomoj: We solved the whole thing. Sorry you missed it!
14:34tomojthe jonathan edwards stuff was "coherent reaction"?
14:35true_droidcan one add fields to a record in runtime?
14:35bbloomztellman: yeah, my pleasure. i hadn't made the zeromq analogy explicit in my head yet, so that was helpful to me too
14:36TimMctrue_droid: Basis fields? Probably not.
14:36true_droid(assoc rec :newfield value)
14:36tomojsubscribe/unsubscribe/push seems like an unsound basis for push seqs to me
14:36jcromartieis there anything that does (f m {:foo g}) => {:foo (g (get m :foo))}
14:36bbloomtomoj: sure, i was far oversimplifying
14:37bbloomtomoj: also, i really dislike the suscribe/unsubscribe thing in general, since it introduces a resource management concern
14:37hyPiRionjcromartie: update-in
14:37ztellmanbbloom: what's the alternative?
14:37hyPiRion,(update-in {:foo 1} [:foo] inc)
14:37clojurebot{:foo 2}
14:37TimMctrue_droid: Sure. Try it.
14:38bbloomztellman: i don't have a good one honestly. but it would look a lot more like the -> macro :-P
14:38bbloomztellman: so check out this file https://github.com/brandonbloom/fipp/blob/master/src/bbloom/fipp/transduce.clj
14:38true_droidTimMc: I'm curious how it works. If a record definition generates a Java class. Does associating new field creates a new subclass for it?
14:38bbloomztellman: i'm basically leveraging the eagerness of reducers to emulate push sequences
14:39ztellmanbbloom: transduce can't actually be a real verb, can it?
14:39bbloommap-state and mapcat-state enable reducers to have state
14:39jcromartiehyPiRion: no, I mean more like, {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)} => {:foo "1" :bar 2}
14:39bbloom$define transduce
14:39amalloy$dict transduce
14:39lazybotamalloy: verb-transitive: To convert (energy) from one form to another.
14:39bbloomeh, lol
14:39bbloomanyway
14:39bbloomztellman: the interesting bit is the state
14:40bbloomit's encapsulated in that atom
14:40bbloombut there isn't really an easy way to peek at it, which is problematic
14:40TimMctrue_droid: It handles the basis keys specially and stores all the other key-val pairs in a regular map.
14:40bbloomztellman: but look here: https://github.com/brandonbloom/fipp/blob/master/src/bbloom/fipp/printer.clj#L203-L208 you'll see how i stitch together the pipeline
14:40true_droidTimMc: I see, thanks!
14:40hyPiRionjcromartie: oh
14:40bbloomztellman: it's brain dead simple lazyness, but the t/each sucks out of the pull sequence & then starts pushing into the reducers
14:41bbloomztellman: this is a dramatically simplified example b/c the push source is actually a pull source
14:41bbloomi'm pushing to the console, but i'm pulling lazily from a document
14:41ztellmanbbloom: right
14:41bbloomwhen you have a real push source, things get messy.
14:41amalloyjcromartie: if you're interested in a little type theory, then that's the basic operation of an applicative functor
14:41hyPiRion,(merge-with #(%2 %) {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)})
14:41clojurebot{:foo "1", :bar 2}
14:42hyPiRionBut that's not exactly what you want, really.
14:42ztellmanbbloom: my domain here is (broadly) network programming
14:42amalloyhyPiRion: it sure is clever, though
14:42bbloomztellman: yeah, so i guess the idea that strikes me is that you don't have a resource management problem until you hook up your Rx chain to the source
14:42ztellmanwhich means that data sources and sinks appear and disappear all the time
14:43bbloomif you define a chain inductively, you have to attach to the source immediately
14:43jcromartieamalloy: interesting
14:43ztellmanbbloom: that assumes the chain's topology is not dependent on the messages themselves
14:43hyPiRionjcromartie: You could probably use reduce-kv here actually
14:43jcromartiehyPiRion: yeah, that's closer, I am just not sure if it already exists :P yeah
14:43ztellmanor on other resources which you don't have control over, like client connections
14:44ztellmanI think that trying to avoid the resource management problem narrows the useful domain pretty drastically
14:44tieTYToh man: (-> req :params :length)
14:44bbloomztellman: if i were to take a design crack at this, i'd ban state inside each stage of the push sequence, but give those states an ID
14:44tieTYTI like that better than get-in
14:44bbloomztellman: i'd also ban connecting to a source or sink until the end
14:44bbloomand then the sources, sinks, and state would live OUTSIDE the chain
14:44hyPiRion,(reduce-kv (fn [m k v] (if (m k) (update-in m [k] v) m)) {:foo 1 :bar "2"} {:foo str :bar #(Integer/parseInt %)}) ; jcromartie
14:44clojurebot{:foo "1", :bar 2}
14:44tieTYTi remember when I learned get-in, I didn't know what -> was, but nwo that I do, I think using it is easier to read
14:45hyPiRionIt was way prettier when I thought it out in my head though.
14:45jcromartie:)
14:45jcromartieI'd say that's pretty close, technically I want to throw out keys missing from the key-fn map
14:45bbloomztellman: i'll be back in a bit
14:45ztellmanbbloom: ok, I've got a question relating to that design
14:46ztellmanbut it can wait
14:46hyPiRionjcromartie: so a select-keys before or after
14:46hyPiRiondo*
14:49borkdudein a clojure project, a .clj is not loaded until needed… right?
14:49technomancyborkdude: user.clj is the only thing loaded implicitly
14:50borkdudeI mean, is it safe to put a lobos script somewhere, without the risk it being run, when no other namespaces refers it?
14:50technomancyborkdude: `lein compile :all` could trigger it
14:50technomancydon't put side-effects in the top-level
14:51gfredericks&foo should be a naming convention for anaphoric macros
14:51lazybotjava.lang.RuntimeException: Unable to resolve symbol: foo in this context
14:51borkdudetechnomancy if I define some actions as functions, that would save me then
14:51gfredericksor for the locals they introduce rather
14:51technomancyborkdude: right
14:51amalloygfredericks: that's an interesting proposal. i'm surprised to find i don't immediately hate it
14:51gfredericksamalloy: lol
14:52technomancyif lobos doesn't already tell you to put your changes in defns then that's worrisome
14:52gfredericksit came to me earlier when the fellah wanted an arguments map
14:52Raynesamalloy: April fools.
14:52hyPiRionRaynes: I was about to write that too
14:52technomancygfredericks: I saw some anaphoric elisp macros that I totally didn't hate, but I think that was because elisp's lambdas are more verbose
14:53gfrederickssomeone told me elisp doesn't have closures
14:53hyPiRiontechnomancy: lambda-as-lambdas?
14:53technomancygfredericks: it didn't until like two years ago?
14:53amalloytechnomancy: has it really been two years?
14:53borkdudegfredericks there is a setting that you must have at the top of an elisp file to turn lexical closures on
14:53gfrederickstechnomancy: at least it beat java?
14:54technomancyamalloy: not sure; I've been running trunk for so long
14:54technomancygfredericks: ziiiiiiing!
14:54hyPiRiongfredericks: What are you saying, you have Clojure
14:54hyPiRionJVM got it, that's enough for me
14:54borkdudetechnomancy it tells me to do that, but to activate the changes, I want to have some reference script for when I need to execute the db creation in the future or with other dbs
14:57hyPiRionborkdude: it's probably safer to leave it out of your clj and java source paths
15:04bbloomztellman: i haven't thought deeply about that design, so i offer nothing more than a willingness to think through it with you :-P
15:05ztellmanbbloom: understood
15:05ztellmanit's interesting, though, that your design is actually pretty 1:1 with how riemann is implemented, as I understand it
15:05bbloomhaven't seen riemann. googled it. by aphyr on github?
15:06ztellmancorrect
15:06ztellmanhttp://riemann.io/
15:06bbloomlooking at it now
15:06ztellmanhe's a coworker, we've had a few design discussions along these lines
15:07bbloomthe interesting thing is that once you hook up to a source, you've got a resource management problem
15:07ztellmanin this case, everything flows through the same topology, so it's just a question of how many sources are feeding into the same thing
15:07ztellmanit's a constrained use-case, so I'm not sure what works there would work elsewhere
15:08ztellmanthe question I wanted to ask had to do with something I have in lamina, though
15:08ztellmanbasically, it does split-apply-combine on streams of data
15:09ztellmanso every time a message comes in with a new facet, a whole new chain of transforms is built on the spot
15:10ztellmanI've spent a lot of effort on making the topology dynamic, thread-safe, able to do its own resource management, etc.
15:10ztellmana question I sometimes explore is whether that was strictly necessary
15:10bbloomztellman: does the topology itself really need to be dynamic? or can there be a static node w/ a dynamic subtopology?
15:10ztellmanbbloom: in this case, the latter would probably suffice
15:10bbloomie can i have source->transform->sink and then transform has some state which is a subtransform
15:11bbloomyeah, i'd probably go with that :-P
15:11ztellmanfair enough
15:11bbloomyour state then just gets stored in a tree & you have a transform node that acts as a state machine which switches the underlying topology
15:12bbloomanalogous in some way to defunctionalization :-)
15:12bbloomyou have a higher order transform & you can realize it as a non-higher order one by inlining
15:14ztellmanyeah, predefined chains of transforms can be useful
15:14ztellmanI've got some stuff which will split apart chains into distributable and non-distributable pieces, so you can process streams across multiple processes
15:14bbloomin theory, you can just make the root transform always be such a dynamic transform
15:15bbloomso then you just always store the topology itself in the state atom
15:16bbloomwhich i guess is what is happening with function composition. you're storing the topology in the Fn objects
15:16ztellmanbbloom: yeah, but that's not introspectable in any sane way
15:16bbloomagreed
15:16ztellmanhave a first-class representation of the topology is really useful
15:16bbloomsure, and by the same token, i really wish i could introspect functions lol
15:17ztellmanI wish I could introspect on how lazy-seqs are consumed, so I can tell if someone's holding onto the head
15:17bbloomthe nice thing about function composition is that you get an evaluator for "free"
15:18ztellmanI guess you could do something with weak refs, there, but I'm not masochistic enough to try
15:18borkdudeargh, why does lobos want me to have the migrations in a namespace called lobos.migrations
15:19tomojbut do you want to say (i'm-consuming! some-lazy-seq) or whatever?
15:19ztellmantomoj: no, but if you have a topology representing where data's going, you don't need to
15:19tomojbut then you can't just do (first coll), right?
15:19tomojor can you have it both ways
15:20bbloomztellman: even the haskell folks have no idea what to do about space leaks: http://www.haskell.org/haskellwiki/Memory_leak#Detection_of_memory_leaks
15:20ztellmantomoj: not with immutable data structures, as far as I can tell
15:21ztellmanif you forced each consumer to have its own queue, which it consumed at its own rate, you could tell how much data is "in flight"
15:22tomojwhy is having a first-class topology representation valuable? not disagreeing, just curious about the details
15:22tomojobviously those beautiful dot graphs are great
15:22ztellmantomoj: I just like pretty pictures :)
15:22bbloomtomoj: two things
15:23ztellmantomoj: one is that the code isn't necessarily a direct representation of what's happening to the data
15:23bbloomit gives you somewhere to extract local state to
15:23bbloom2) it enables debugging, etc
15:23bbloomthe topology EXISTS somewhere
15:24bbloomit has to be reified in some way at some level
15:24bbloomgenerally tho that level is just inside the functions as compiled
15:24ztellmanbbloom: I defy you to infer the data topology of lazy-seqs via the object graph
15:24bbloomit's impossible
15:24bbloomlol
15:24bbloombut it exists
15:24ztellmanoh, sure
15:24bbloomok not impossible
15:24tomojI was thinking the debugging benefit is primarily for operational issues
15:24tomojlike lazy seq realization
15:24bbloombut you'd have to decompile bytecode lol
15:25bdeshamI have a web app running with ring and jetty. what's the best way to run the server as a background process (so that I can log out of my shell with it still running)?
15:25ztellmantomoj: one is that it lets you understand what your code actually describes
15:25tomojbut you wouldn't need a topology graph for code working with only, say, vectors?
15:25ztellmanfunction composition over lazy seqs can happen all over the place
15:25bbloomif i had my way, everything would be introspectable at all times :-P
15:25ztellmanthe net effect of that composition is very difficult to infer
15:25tomojor maybe it'd still be helpful
15:26ztellmantomoj, if there's only a small number of transforms, and one source, and one destination, it's maybe not all that useful
15:26ztellmanbecause that can be described by a (->> s …) form
15:26ztellmanbut there are some issues there, too
15:26tomojtransform/source/destination seems to imply some operational trickiness
15:27ztellmantomoj: don't pay too much attention to my terminology
15:27tomojah, right, if source is a vector, destination is a vector, and transforms are just functions. still could be nice to get a graph I suppose..
15:28ztellmantomoj: basically in the simple case it doesn't harm anything
15:28ztellmanin the complex case, it's invaluable
15:28bbloomaside: Rx has this concept of schedulers that is worth studying too
15:29ztellmanit also lets you solve the resource management problem bbloom was mentioning, to an extent
15:29bbloomin theory, some intermediate step in the sequence can autonomously decide to emit an event w/o input from an upstream source
15:29ztellmansince you know whether there are any remaining consumers for any given subset
15:29bbloombut in deeper theory, that's just getting an event from another source: a timer
15:30ztellmanbbloom: yeah, in lamina all nodes can emit messages at any time
15:30ztellmanusing pretty much the same mechanism you describe
15:32ztellmananyway, tomoj, in general adding introspection capability is something you should design for
15:33bbloomztellman: note however that introspection often (not always) incurs substantial runtime costs
15:33mabesspeaking of Rx... has anyone here played around with netflix's RxJava (https://github.com/Netflix/RxJava)?
15:33bbloomhowever it is much much much harder to design OPTIONAL introspection :-)
15:33true_droidanyone knows of alternative clojure implementations in the works? I've heard of pyclojure
15:34true_droidcurious to know if there's anything else that fwould ree clojure from jvm
15:34RaynesWhoa
15:34ztellmanbbloom: I think this particular domain is really friendly to introspection
15:34RaynesThat f really ran off on you didn't it true_droid
15:34true_droidyeah
15:34bbloomztellman: assuming you're writing server software & are likely IO bound, then yeah, for sure
15:35ztellmanbbloom: I dunno, I've made a thread-safe dynamic topology that had to acquire locks, etc. and it take about 40ns per node
15:35ztellmanwhen propagating
15:35bbloomhow many nodes do you typically have?
15:35ztellmanwell, depends on the application
15:36bbloom10, 100, 1000, 10000?
15:36ztellmanthe server I was describing at clojure/west had about 500k, but not every node gets every message
15:36bbloomthat's a shitload of nodes lol
15:36bbloomi'm not even sure how i'd use that many nodes. is that like one per user?
15:36ztellmanit's an extreme case, I was partially using it to stress test the mechanism
15:37ztellmannah, it's a streaming analysis of structured data
15:37tgoossensI'm looking at rich hickey's ant demo. https://gist.github.com/spacemanaki/1093917#file-ants-clj-L45 . What is the reasoning behind the following documentation of the "move" function: "moves the ant in the direction it is heading. Must be called in a
15:37tgoossenstransaction that has verified the way is clear"
15:37ztellmanhierarchical code timings
15:37tgoossensWhy not put the transaction in there it if it has to be put in a transaction anyway ?
15:37bbloomoh right i saw your talk
15:38bbloomztellman: so that's a distributed 500k nodes? or all in one process? or what?
15:38nDufftgoossens: Because the check has to be inside the same transaction.
15:38ztellmanso basically each timing is analyzed about half a dozen different ways, and within each it's getting quantiles, rolling sums, etc
15:38ztellmanone server
15:38tgoossensnduff: makes sense!
15:38ztellmanit's distributable, but in my use case it's not necessary
15:38bbloomok got it
15:38bbloomthat's a big number :-P
15:38ztellmanthey're lightweight nodes :)
15:39tgoossensnduff: stupid me. The documentation actually said that:p "Must be called in a
15:39tgoossenstransaction that has verified the way is clear""
15:39ztellmanbut yeah, I'm looking at a constrained query language that will be distributable via storm, or something
15:39bbloomneat
15:39ztellmanit's got promise, I think
15:40ztellmanI tried using it to measure a full map/reduce job without client-side sampling, got about 15gb/minute via UDP packets
15:40ztellmanwhich have a maximum size of 64k, btw
15:40ztellmanthat made it fall over
15:40tieTYThow would you count the number of 0s in a vector? I used this: (reduce #(+ %1 (if (= %2 0) 1 0)) 0 vector)
15:40ztellmanso there's definitely a threshold at which you want to distribute this sort of analysis
15:40amalloy(count (filter #{0} v))
15:41tieTYTah yeah that's better
15:41tomojhow do you represent a dynamic topology (for e.g. the purpose of rendering to dot)?
15:41bbloomamalloy: tieTYT: might prefer zero?
15:41bbloom(count (filter zero? v))
15:41ztellmantomoj: check out lamina.walk
15:41amalloybbloom: doubtful
15:41bbloomheh ok then
15:41tieTYTso there you used a set as a function?
15:42ztellmantomoj: though that's just some sugar on top of the underlying data structure, no mechanism for making sense of a topology of 500k nodes
15:42amalloy&(zero? [])
15:42lazybotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number
15:42pl6306What is an easy way of generating [[year quarter] ...] e.g. [[1993 1] [1993 2] [1993 3] [1993 4] [1994 1] [1994 2] ... ?
15:42bbloomamalloy: oh! wow. that's annoying
15:43nDuffpl6306: lazy? bounded? ...?
15:43bbloomsurely the answer to that question is "false" lol
15:43true_droidwhat does reify return? can't find it mentioned in the reify doc string at all
15:43nDuffpl6306: ...well, if you really want it to be a vector on the outside, it can't be lazy...
15:43pl6306not lazy bounded just from 1993 to 2013
15:43hyPiRion,(for [y (range 1993 2013) q (range 1 4)] [y q]) ;?
15:43clojurebot([1993 1] [1993 2] [1993 3] [1994 1] [1994 2] ...)
15:44amalloy,(map vector (mapcat #(repeat 4 %) (range 1993 2014)) (cycle [1 2 3 4]))
15:44clojurebot([1993 1] [1993 2] [1993 3] [1993 4] [1994 1] ...)
15:44amalloybut hyPiRion's is better
15:44pl6306Nice thanks!
15:44pl6306Starting to get the hang of this.
15:44tomojztellman: is the 'dynamic' part represented in there? or do you just call node-data at various times to see what the topology looks like at different times?
15:45ztellmantomoj: oh, I see, yeah, you're just sampling it
15:45hyPiRionpl6306: might want to replace 2013 with 2014 in my code, if you meant "up to and including 2013"
15:45ztellmantomoj: you can hook into callbacks for when nodes close, etc.
15:46ztellmantomoj: if you want a fully consistent view you can recursively lock each node in the topology
15:47ztellmanbut by default you're not getting one, because the topology doesn't change atomically
15:47ztellmanat the global level, anyway
15:48borkdudehmm, lobos uses an old version of java.jdbc (1.1)
15:48borkdude(0.1.1)
15:49tieTYTi think one of the hardest things for me to take advantage of from a java/haskell background is that I can use non-booleans in an if statement
15:50tomojwould it be wrong to call that a bit less than first-class?
15:50tomojnot really sure what 'first-class' means in this context
15:50borkdudetieTYT many dynamically typed languages have this, javascript, common lisp, etc
15:50tomojthough if that's less than first-class it may be impossible to do any better :(. damned 'dynamic'
15:50ztellmantomoj: it depends on what you're trying to do
15:51tieTYTborkdude: yeah, I don't usually use that feature though
15:51borkdudeI guess C has it too?
15:51tgoossensWhy was the name "agent" chosen for well.. clojure agents?
15:51ztellmanone way to "sample" the topology is to send a message through it
15:52ztellmanthe return value of (enqueue ch …) will give you the return value of each endpoint, or an async-result representing the eventual return value
15:52ztellmanbut the topology may be changing around the message as it propagates
15:52ztellmanespecially if it's queued anywhere
15:53ztellmanwhich topology matters? the one that was in place when the message was enqueued, or the one that's in place when it arrives at its various destinations?
15:53Guest93639ok I am confused. I printed out the value of my protocol var, apparently the :impls has a bunch of identical-looking class keys with different values. how does that happen? https://www.refheap.com/paste/13179
15:53ztellmanor the frankenstein combination of the two that the message encountered as it was being propagated?
15:54ztellmanthough again, if you want some guarantees of atomicity, those are possible if you want to lock down the topology yourself
15:54ztellmanI haven't encountered a production situation where that's useful, though
15:55tieTYTwhere/how can I find the documentation on using a set as a function?
15:55tomojwould be sweet though to make an animation of the topology changing while following a message
15:55amalloyjweiss_: you have redefined a defrecord or deftype multiple times at the repl
15:55brehauttieTYT: clojure.org probably. (set key) is equivalient to (contains? set key)
15:55amalloythere are now multiple versions of that class, each with a registered implementation of the protocol
15:55brehautalmost equiv
15:56jweiss_amalloy: strange since there is no way to tell them apart that i can see
15:56amalloyjweiss_: they have different classloaders
15:57tieTYTbrehaut: ok
15:57brehauttieTYT: http://clojure.org/data_structures#Data%20Structures-Sets
15:57brehauttieTYT: very bottom
15:57jweiss_amalloy: do you have a recommendation to avoid this and/or fix it? just blow away the protocol var and re-compile?
15:57amalloyjweiss_: i recommend not caring
15:57ztellmantomoj: feel free to mess around with it a bit if you're curious
15:58amalloyit will not cause any problems whatsoever
15:58jweiss_amalloy: it seems to be causing problems.
15:58ztellmanI'm probably going to extract the graphviz stuff into its own library
15:58amalloyjweiss_: really? what problems?
15:58jweiss_i'm getting an error that one of my records doesn't implement one of the protocol methods.
15:58tieTYTthanks
15:58ztellmanmaybe you'll build up some opinions on how to best do that
15:58jweiss_but it does, it's just choosing the wrong class
15:58brehauttieTYT: contains? returns a bool, where as a set returns the object if its found. sets with nil or false can be funny if you use them for existence tests without using contains?
15:59Raynesbrehaut: You. Hi.
15:59brehauthi Raynes
15:59amalloyjweiss_: that happens if you re-evaluate the defprotocol form
15:59tieTYTi see
15:59amalloyyou defined a new protocol with the same name, and the previously-existing records implement the old version, not the new one. if you re-evaluate the records, new classes will be produced that implement the new one
15:59jweiss_amalloy: yeah, that's why i wanted to know how to avoid/fix - so i guess i shouldn't have recompiled the namespace with that defprotocol?
16:00amalloyjweiss_: make sure to let technomancy know: he enjoys protocol schadenfreude
16:00jweiss_hm ok the defprotocol and defrecords are in the same ns, so i guess i should not eval forms, just recompile the whole ns.
16:00RaynesThe shit.
16:01Raynesamalloy: That's the second time I've heard that word in two days.
16:01RaynesAnd yesterday was the first time I'd heard it in my life.
16:01technomancyamalloy: it's true
16:01jweiss_schadenfreude?
16:01amalloyRaynes: http://www.damninteresting.com/the-baader-meinhof-phenomenon/
16:01RaynesSo either you're a callenbot copycat or that's a hell of a coincidence.
16:02TimMc...or you're a young 'un.
16:02amalloyRaynes: it's a word, man. people using words you don't know is just a sign you're uneducated, not a sign from god
16:03RaynesThanks guys.
16:03TimMc<3
16:04jweiss_oh man this sucks, why didn't anyone warn me about protocols
16:04technomancyI did!
16:04amalloyclojurebot: technomancy is <jweiss> oh man this sucks, why didn't anyone warn me about protocols
16:04clojurebotc'est bon!
16:04technomancyyou just weren't listening
16:05technomancyin your defense, you might not have been on IRC at the time
16:05jweiss_lol
16:05jweiss_i don't suppose i can save my fellow co-workers by somehow defonce'ing something
16:06jweiss_so that when they edit something else in this namespace they won't end up chasing their tail
16:06TimMcjweiss_: http://www.mspaintadventures.com/sweetbroandhellajeff/comoc.php?cid=001.jpg
16:06pl6306Why does (map #(load-sec-quarterly-master-idx (first %1) (last %1)) (vec (for [y (range 1993 2012) q (range 1 4)] [y q]))) in the REPL? But (defn load-historical-master-idx  (map #(load-sec-quarterly-master-idx (first %1) (last %1)) (vec (for [y (range 1993 2012) q (range 1 4)] [y q])))) throws an IllegalArgumentException Parameter declaration map
16:06pl6306should be a vector  clojure.core/assert-valid-fdecl?
16:06jweiss_TimMc: lol
16:07amalloypl6306: you forgot the args to defn
16:07technomancyTimMc: nice
16:07pl6306ok so I should put in []
16:08amalloyTimMc: what on earth
16:08jweiss_i don't know which one is hella jeff, but probably the one falling down the stairs since my name is also jeff
16:09jweiss_although the other guy does refer to him as "bro" so maybe not.
16:12cdh473__i just noticed: ".../comoc.php..."
16:18TimMcamalloy: Intentionally bad webcomic. I think it started as a joke in the MS Paint Adventures forums.
16:21jweiss_alright I am still baffled. when i recompile a namespace it seems like not everything gets redefined. i still have old versions of records still laying around.
16:27TimMcYeah, they should have different classloaders.
16:29jweiss_TimMc: should, or that's why i'm having problems?
16:30TimMcThe latter.
16:30TimMcNot "this is a desirable scenario".
16:33maaclConsidering a porting the GUI part of ants.clj to Clojurescript/canvas and back it by a Clojure backend. Would fetch (by Chris Granger) be my best choice for syncing the world from the backend to the frontend?
16:35jweiss_TimMc: the repl seems to be telling me that both the protocol impl key and the new record i just created, have teh same classloader. and the impl also has a definition for the :product method. yet when i try to call it, it doesn't work
16:35jweiss_https://www.refheap.com/paste/13184
16:36jweiss_i wonder if this has anything to do with using keywords as protocol method implementations?
16:36jweiss_i mean, they are functions, so i figured that should be fine.
16:36sandbagsclojure newb here, is there a legitimate reason why (load-file "path/to/file.clj") might hang for minutes at a time?
16:36brehaut(while true) is a toplevel form
16:36sandbagsoh, I googled up "load-file" so I could totally be doing this wrong... i'm in a lein reply btw
16:36jweiss_not legitimate, no
16:37sandbagsjweiss_: okay, this perhaps explains why LightTable has stopped working for me
16:37sandbagsthanks
16:37jweiss_last i checked it wasn't compiled in a way that would run on my system
16:37sandbagsis there any kind of logging that i can get clojure to do that might let me figure out why
16:38sandbagsi note in passing that, until about 7-8 hours ago, i wasn't having a problem
16:38technomancysandbags: binary search is your best bet
16:38sandbagstechnomancy: you're thinking it's something about my source file?
16:38technomancysandbags: if it's happening in lein repl, yeah. if it's in light table it could be something else.
16:38jweiss_eval forms one at a time in that file :)
16:39technomancysandbags: also: load-file is very low-level; you should use require
16:39sandbagstechnomancy: LT was hanging on starting up a repl for the file, CG asked me to try in lein-repl
16:39sandbagslein-repl starts
16:39sandbagsbut then i figured that probably wasn't testing anything much
16:39sandbagsah, ok
16:41scottjmaacl: maybe look at pedestal
16:42maaclscottj: thanks, although looks heavy for just keeping a datastructure in sync
16:44sandbagsIIReadC clojure returning 'nil' signifies success, right?
16:44sandbagsreturning nil from a funciton such as 'require' i mean
16:45amalloysandbags: more like "no meaningful return value"
16:45amalloygenerally it means nothing broke, though. certainly that's true for require and its friends
16:45sandbagsthanks
16:49Bronsasandbags: that's not always true though http://sprunge.us/EQVL
16:49TimMcsandbags: Clojure functions *have* to return something. (Or throw an exception, or call System/exit, I suppose...) If your function doesn't have anything useful to return, nil is the standard thing o use.
16:50sandbagsthanks guys
16:55sandbagsokay so definitely something in the code hanging the repl, probably i have a bracket misplaced or something
16:55sandbagsalthough... i'd expect some kind of syntax error or something
16:56amalloysandbags: well, as i think someone suggested earlier, you might have (while true) at the top-level or something like that. or light table could have a bug; it would hardly be the first
16:57sandbagshttps://gist.github.com/mmower/2fb5f8ba95382084b4e5
16:57sandbagsamalloy: it's not LT, i'm in pure lein repl now
16:57sandbagswithout the comments, this is hanging my repl
16:58nDuffYou're decrementing i, but testing n
16:58nDuffso, yes, no surprise that that's hanging.
16:58sandbagsah, damn
16:58amalloynDuff: he's not calling that function, allegedly
16:58amalloyoh, but the println is there
16:58nDuffExactly.
16:58sandbagsyeah
16:58sandbagsthe println
16:58sandbagswhich is probably what i added that triggered this whole thing
16:59amalloysandbags: i don't know what LT recommends, but in any other clojure setup it's a bad idea to do anything but define functions at the topmost level
16:59sandbagsbut is so seemingly innocuous an action that when LT started to ahng
16:59sandbagsamalloy: i was really just playing around but, yes, i can see why this is recommended :)
16:59nDuffI _am_ somewhat surprised that LT doesn't have an easy way to interrupt a runaway execution
16:59nDuff(which, for instance, emacs+nrepl will do easily)
17:00sandbagswell the thing is in LT it *looked* like it was still starting the repl
17:00Glenjamin_every time i try LT it seems to hang for an unclear reason
17:00sandbagsGlenjamin_: well it is 0.3 :)
17:00Glenjaminyeah, i intend to keep coming back to it
17:01sandbagsin this case I am not sure what LT could do, since the nREPL underneath it has hung
17:01sandbagswell, been hung
17:01jweiss_ok i seem to be making headway here, having one protocol function point to another doesn't seem to work
17:02jweiss_eg (defprotocol MyProto (foo [x]) (bar [x])) (extend My.Class {:foo identity :bar foo})
17:03dsophmm sqlkorma doesnt convert types and retursn everything as strings?
17:03jweiss_(bar (MyClass. "baz")) -> IllegalArgumentException No implementation of method: :foo of protocol: #'MyProto found for class MyClass.
17:04jweiss_but (foo (MyClass. "baz")) works.
17:05luisgabrielI'm having some issues related to performance on a simple example that I'm writting in clojure. probably I'm doing something very wrong. If someone can help me, here is the code: https://gist.github.com/luisgabriel/5287722
17:07luisgabrielI'm trying to implement a simple search engine for text files
17:07jweiss_doh... /me should have referred to the protocol function using the var. (extend My.Class MyProto {:foo identity :bar #'foo})
17:07jweiss_that works
17:08amalloyjweiss_: ah, now that sounds like a protocol behavior that i consider a bug. if you capture a protocol function's *value* at the top level (as opposed to its var), then that function doesn't get updated
17:09dsophmm okay korma doe sconvert the types :)
17:10callenbotI've come to realize that scala and go represent two extremes of design principles.
17:10jweiss_amalloy: i'm not sure how it should work
17:11jweiss_in this case, foo is a protocol function and at the time it's being extended there was no implementation for that type.
17:23dsopwhats the easierst way if i have two list of intergers to find the disjoint set?
17:24TimMcdsop: Use some clojure.set operations.
17:25dsopTimMc: ah clojure.set/difference, thx
17:52inhortteDoes anyone here know how to properly include local jars in a project with leningen2?
17:54amalloy~repeatability
17:54clojurebotrepeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability
17:55technomancyinhortte: lein-localrepo or s3-wagon-private depending on whether you're doing real work or just playing around
18:01inhorttetechnomancy -> I'm just playing around for now. :)
18:02technomancylocalrepo is prolly fine
18:02inhortteI'll try lein-localrepo
18:02technomancybut also submit a bug report to whoever is giving you a jar that's not in a repo
18:02technomancybecause that's crazy
18:04inhorttetechnomancy -> it's this: https://github.com/macourtney/clj-crypto ... I wanted to play around with 'masques' (https://github.com/macourtney/masques).
18:04technomancyoh, if it's a clojure project you can just do `lein install`
18:06inhorttetechnomancy -> I am not going to read a bit of lein documentation. :)
18:06antares_shipped Money 1.0, a tiny library for dealing with moneyz and currencies http://blog.clojurewerkz.org/blog/2013/04/02/introducing-clojurewerkz-money/
18:08pmonksStep 1: develop Money 1.0
18:08pmonksStep 2: ??
18:08lazybotpmonks: What are you, crazy? Of course not!
18:08pmonksStep 3: PROFIT!!!1
18:09antares_pmonks: my last name is Gnome
18:20hyPiRionThe leprechaun in action.
18:20technomancymoney 1.0? I dunno man; everyone knows it's not a good idea to use floats for currency. =)
18:20antares_technomancy: there is a BigMoney type :)
18:20technomancyheh; nice
18:22hyPiRionStill doesn't fix the issue, does it?
18:22hyPiRion,(/ 1M 3M)
18:22clojurebot#<ArithmeticException java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.>
18:23technomancywell, dividing money by money doesn't make sense
18:23antares_hyPiRion: it's Java at the core and it uses rounding modes for division, if that answers your question
18:23hyPiRionah
18:23antares_all potentially lossy operations require you to specify a rounding mode and scale
18:23hyPiRiontechnomancy: by people, perhaps?
18:23technomancyhyPiRion: surely an integer?
18:25hyPiRiontechnomancy: sure, but ##(/ 1M 3) would still not be representable
18:25lazybotjava.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
18:25technomancyoh, true
18:30inhorttetechnomancy -> thanks, by the way. it worked fine.
18:32technomancycool
18:36angusiguessIs there any clear reason this wouldn't be displaying the image I load? It seems to get the dimensions right. https://gist.github.com/angusiguess/26ec9f33eaefcc2d9d8d
18:36si14what's the meaning of "NullPointerException [trace missing]"?
18:38technomancysi14: I think that's a bug in the JVM's tiered compiler
18:38amalloysi14: that is the clojure runtime letting you know you're going to be sad when you try to debug
18:39si14https://gist.github.com/si14/6781aa479e696b5690b9 here is the code
18:39technomancytechnomancy/leiningen#1025
18:39lazybot-XX:+TieredCompilation destroys tracebacks -- https://github.com/technomancy/leiningen/issues/1025 is closed
18:40si14it will be somewhat OK if I'll see that "Hello world" printout
18:40si14but I do not
18:41technomancytry disabling tiered compilation?
18:47si14but I still don't get why that printout is missing.
18:48technomancysi14: I guess it's not in the comments there, but someone traced it down to a bug in the JVM
18:49si14technomancy: "it" = ?
18:50technomancythe lack of a stack trace
18:50si14technomancy: can you take a look at that snippet please?
18:51technomancyhm; that's very strange
18:51si14when I uncomment line 38 I get NPE (thanks to your advice it's now somewhat traced), but no printout.
19:41si14technomancy: thanks for the help, anyway :)
19:47Oddmanwhat's everyone's preferred library for web, when dealing with clojure?
19:47Oddmanand fav mysql lib?
19:49technomancyOddman: I don't know if anyone in here will admit to using mysql by choice =)
19:49Oddmanclojure community is too elite for it?
19:50Oddmanwhat's the storage medium of choice here?
19:50technomancybut clojure.java.jdbc in theory connects you to any DB supported by JDBC
19:51Oddmangotcha. And is that an ORM solution, or a preferred solution to an ORM implementation?
19:51Oddmannew to java, clojure.etc. so starting from scratch :P
19:51technomancyit's not an ORM, but it's a good starting point
19:52Oddmandoesn't need to be an ORM, just curious as to options available
19:52Oddmanand for web - what is the preferred framework?
19:52Oddmanbeen looking at compojure, seems quite light
19:52technomancyit's the best
19:53Oddmanheh
19:55scottjOddman: maybe look at korma, clojureql, and pedestal if you want something else.
20:00Oddmanhaving a look at clojureql, this irks me:
20:00OddmanSELECT * FROM (SELECT users.* FROM users ORDER BY users.id asc) ORDER BY users.id desc
20:00Oddmanwhen calling multiple sorts
20:01Oddman=\
20:13callenbothttp://gearon.blogspot.com/2013/03/clojurescript-and-nodejs.html
20:37xeqiGlenjamin: have you found any other bugs with peridot? considering releasing a new version once I merge the two pull requests
21:53tomojhmm, if reifying vars in cljs (even just :dynamic ones) is unacceptable due to performance reasons, how about just adding a new metadata flag :reified or :var or something?
21:54tomojthen if you want bound-fn to preserve your var you have to ask for it
21:55tomojguess it would be pretty shitty to have some vars reified and some not
21:56brehauttomoj: that authentic javascript experience :/
21:56tomojbut is dnolen ever going to say something other than "can't reify vars, performance cost" or "can't keep binding frames for :dynamic vars, performance cost"
21:56tomojare those performance problems even solvable?
21:57tomojonly other option I see is some weird hack to get bound-fn working, to which dnolen will probably still say "performance cost"
21:58gfrederickstomoj: when you're running on a crazy-high-level host like JS there's a limit to how much further you can pile abstractions
21:58tomojare you suggesting we may never get bound-fn?
21:58callenbotmaybe clojurescript should be ported to asm JS
21:58callenbotfor SPEEEEEEEEEEEEEEEEEEEEEEEEEEEED
21:59Oddmanlol
21:59tomojthat seems unacceptable, though apparently dnolen disagrees, and he probably understands better than I..
21:59gfrederickstomoj: that wouldn't surprise me, but I definitely don't have my head in the relevant issues, nor know enough about JS
21:59gfrederickstomoj: cljs won't even get decent numerics
21:59callenbotthere's already an llvm clojure project, just point, aim at emscripten, and fire!
21:59brehautlets have a pool: how long will it take dnolen to write a fast generational collector in JS
22:00callenbotbrehaut: I'll take Never for $1000 Trebek.
22:00tomojgfredericks: decent numerics?
22:00callenbottomoj: it's all 754
22:00gfrederickstomoj: anything besides floats
22:00callenbottechnically 32-bit unsigned ints are allowed to fly past
22:01callenbotbut anything larger is gonna be a double.
22:01tomojsure
22:01tomojbut that seems irrelevant :)
22:01callenbotJUS SAYIN
22:01gfrederickstomoj: it's something you'd want in a language but can't get cuz speedz
22:01tomojI mean, yeah, there are some nice things we will never get
22:02tomojbut is bound-fn one of them?
22:02tomojif so,
22:02tomojI dunno. it seems like a big problem
22:02gfredericksRaynes: okay I got codez this time
22:03callenbottomoj: cljs is just a house of pain built on an indian graveyard called JavaScript.
22:03gfredericksRaynes: https://www.refheap.com/paste/13189
22:03callenbottomoj: the bedsheets are okay if you ignore the blood.
22:04tomojoften the only option will be to write manual bound-fns for specific vars of interest
22:04gfrederickstomoj: you do a lot of dynamic vars in cljs?
22:04tomojnot a lot
22:04gfrederickstomoj: also a macro could make that as easy as (bound-fn [*foo* *bar*] ...fn stuff...)
22:05tomojright, I guess it's not that big of a problem
22:06tomojcljs.test and any async framework can manually do that for the vars they need
22:06tomojthen the user just gets the pain of dealing with any other vars they need
22:06gfrederickscould you do this without reified vars?
22:06gfrederickshave binding log what it's doing somewhere?
22:06gfredericksso bound-fn knows what vars are active?
22:07gfrederickssounds like that wouldn't affect normal perf
22:08gfredericksI'm assuming you didn't want some kind of actual thread-local thing
22:08tomojthat's what I've been trying to figure out, I think it should be possible
22:08tomojbut not at no perf cost
22:08gfredericksare there JS runtimes where that's meaningful?
22:08tomojunless you have a :bindable flag or whatever like I suggested above
22:08gfrederickstomoj: what's the perf cost?
22:09tomojanyone using :dynamic who doesn't need bound-fn will suffer needlessly
22:09gfredericksRaynes: oh apparently I need to pass the zipper to l/fragment for some reason
22:09tomojif you do it for all :dynamic (dnolen has already pointed out that this is a concern)
22:10gfrederickstomoj: but only at the time they use binding, right?
22:10tomojright, or if they set!
22:10gfredericksit just makes binding itself a little slower?
22:10gfredericksoh hm
22:10gfredericksset! is supposed to only affect the local frame isn't it
22:10tomojtheoretically, which is another wrinkle
22:10gfredericksokay screw it all I give up
22:11tomojsince you probably don't want to change cljs so that people set!'ing without binding get broken (though I'd be fine with it..)
22:13tomojI guess I can accept that users will have to manually handle their own vars
22:14technomancyyou guys figure out that stuff before I find myself in the precarious position of needing to run code on a JS runtime, k?
22:14tomojhttps://www.refheap.com/paste/1631777863115a2e1e8ea16c9
22:14tomojyeah, macro would be nice..
22:15tomojmaybe you just tell your 'executor' which vars to carry
22:16gfredericksRaynes: I take it back again I have no idea what I'm doing
22:19tomojactually, that would really suck
22:21tomojit would force knowledge about dynamic vars to all be complected together in places that shouldn't care at all?
22:23tomojany place you use bound-fn, you have to know about all the vars you're in the _dynamic extent_ of?
22:28tomojI'm gonna go for a var flag and no reification
22:29howdynihaowhats a good / popular kata?
22:29brehaut4clojure.org
22:31brumhow long would it take one of you to do a problem like this.. http://www.4clojure.com/problem/77
22:32howdynihaothat site is nice, but i was looking for something i could git clone
22:32howdynihaoand run the tests and actually edit the code
22:32howdynihaoinstead of the 'fill in the blank'
22:33gfredericksbrum: a few minutes?
22:33brehautbrum: that would probably depend on how familiar you are with the standard lib and the features of for
22:34brehautactually, you might not even need for for that one
22:34howdynihaohttps://github.com/gigasquid/yellow_belt_clojure_katas there is this, but its old, and it doesnt run as is, (probably simple to fix)
22:35brumi would take the first word and compare it to every other word, add the word to the array if it had all the same letters
22:35brehautand gigasquid is a 4clojure contributor now
22:35brumremove the first word from the list and then do the same with the new first word
22:35gfredericksbrehaut: brum: got it first try
22:36howdynihaoi would like to note, catnip is very cool
22:36gfredericksseven lines
22:36brumlet me see
22:36gfrederickshttps://www.refheap.com/paste/13193
22:37brumthat's some fancy clojure knowledge
22:37gfrederickslike brehaut said, familiarity with the standard lib
22:37brehautmy solution was apparently #(set (for [[_ s] (group-by frequencies %) :when (next s)] (set s)))
22:38brehautwhich is kinda awkward
22:38brumhow long have you been programming for
22:38brumgfredericks: brehaut
22:38gfredericksa decade or so
22:38brehauti dont know
23:26rocco65536c-c , in emacs is giving me a compiler error
23:26rocco65536does anyone know what could be the matter?
23:26jack_rabbitWhat's the error?
23:27rocco65536class not found
23:27rocco65536am I supposed to run test via lein?
23:28rocco65536I tried adding clojure to classpath but it didn't work
23:28rocco65536maybe this test mode in emacs is outdated?
23:31jhnrocco65536: does it work from the command line when you do `lein test`?
23:32fbernierwhat's ->>
23:32fbernier?
23:32rocco65536yes lein completes the test
23:33rocco65536it just doesn't work in emacs
23:33rocco65536it can't find clojure.test.mode
23:35jhnrocco65536: did you install via marmalade or melpa?
23:36rocco65536the former
23:36technomancyrocco65536: clojure-test-mode 2.x needs nrepl.el; 1.x uses slime
23:37rocco65536I am using nrepl
23:37technomancyhm; weird
23:37rocco65536basically I just followed the tutorial here http://clojure-doc.org/articles/tutorials/emacs.html
23:37technomancyyou can do (run-tests) in the repl as a workaround
23:38rocco65536unable to resolve run-tests
23:39rocco65536which namespace should I be in to run this
23:39technomancyrocco65536: your repl would need to be in your test namespace
23:40rocco65536ok now it works