#clojure logs

2013-05-06

00:03muhoois there some way to throw a 404 or other exception from deep inside an app and have it show up as a ring 404 error?
00:03muhooit seems like any exception shows up as a 500 in the ring response
00:04muhoowhich is kind of not ideal.
00:05tomojcatch it and return a 404
00:06tomojperhaps (ex-info "not found" {:your.ns/error-code 404}) or something
00:06tomojand maybe use https://github.com/fredericksgary/catch-data
00:06tomojor just return a 404 response :)
00:16muhooyeah the right way to do this is to make it purely functional, and return a ring response {:status 404 :body ..}
00:17muhooalso, is it a code smell to have (if cond (do some stuff here) (do more other here)) ?
00:18muhoothe explicit do's look ugly to me
00:19muhoothe probelm with returning ring responses is i do not want the entire app to have to understand ring
00:19muhooall the way deep down. that seems wrong. maybe i'll write somethign that catches custom exceptions and turns them into ring error responses.
00:19muhooi'm surprised nobody has done that already tho
00:19nightfly__sounds like the right way to go
00:20tomojI've considered using exceptions for that
00:20tomojbut I suspect it's.. not good
00:21muhooslingshot looks pretty cool
00:21tomojcatch-data is better :P
00:22muhooreally? why?
00:26tomojit does one simple thing
00:27tomojI don't understand your argument for throwing
00:29brainproxygah, what's the right way to use github markdown so that you can highlight html including script tags
00:29tomojeither you throw a ring error response, in which case the thrower has to know ring. or you throw something which signifies an error but isn't coupled to ring, and translate it into a ring response elsewhere, in which case couldn't you just return that thing?
00:30tomojI guess I can sort of vaguely see why throwing would be useful, which is why I considered it, but I don't understand the tradeoffs..
00:34tomojex-info and catch-data seem to maybe encourage using exceptions as part of normal control flow
00:43tieTYTclojure.repl has a pst. If I want to print the stack trace in my own program, what should I use?
00:44tomojI use pst
00:46lpvbanyone tried using clojure on avian's AOT compilation and compared performance with any other VMs?
00:47tieTYTok thanks
02:08tomoj&(seque (lazy-seq (/ 0 0)))
02:08lazybotjava.lang.ArithmeticException: Divide by zero
02:08tomojhmm
02:08tomojbroken in 1.5.1?
02:10tomojI get ()
02:14tomojamalloy: hmm, did you break it? :)
02:16ucbtomoj: nice (the async blocks)
02:29amalloyi might've done, tomoj
02:30tomojnot like it would really help me to get the exception
02:31totimkopfwhat is a good high performance web server for clojure?
02:33muhooi built this artifact, installed it in my ~/.m2/repository via "mvn install", but lein check can't find it https://github.com/tobie/ua-parser
02:34muhooalso uploaded it to a private repo, added the repo to :repositories, and it still can't find it, but it's right there.
02:34muhoois it the underscores/dashes in the name? mvn installed it in two different places, on with ua_parser, another with ua-parser
02:36muhooauugh, nevermind i got it [ua_parser/ua-parser "1.2.1-SNAPSHOT"] does it. damn dashes
02:46muhoointerestingly alembic and the repl hates those dashes, but in project.clj :dependencies it works fine
02:51alistairso I got asked to build a bog-standard CMS for a client today, and I told them I'd do it if I could do it in Clojure
02:51alistairis this an awful idea?
02:51zRecursivealistair: not auful if you know Clojure well
02:52alistairwouldn't it be a lot slower to implement than just using something off-the-shelf?
02:53alistairzRecursive: I gather there aren't a lot of pre-existing Clojure CMSs
02:53tomojwhy build a new one if something off-the-shelf would satisfy?
02:53zRecursiveseems Python has
02:54zRecursivesomething off-the-shelf will cause maintenance problem
02:54alistairbecause I want an excuse to be paid to write Clojure =)
02:55alistairI'm just wondering if there's anyway I can make it good for the client, and not just me.
02:56zRecursiveMany Java Library make it good, doesnot it ?
03:08chemistdeepanyone alive?
03:08HolyJaknot really ;-)
03:08chemistdeepaware of any cool clojure libraries that have come out recently?
03:18Foxboronalindeman: go to univ. Find a research group that needs something done, where you get paid. Code it in Clojure
03:18Foxboronbest excuse ever.
03:19totimkopfI'm trying out http://www.luminusweb.net/ but when I type 'lein ring server' inside the project folder I get : That's not a task. Use "lein help" to list all tasks.
03:19totimkopfseems like a typo of some kind?
03:19winktotimkopf: what exactly did you do before?
03:20HolyJaktotimkopf: not sure how it works but meybe you need to install ring plugin (or how is it now called) for lein?
03:20totimkopfwink: simply : lein new luminus myapp
03:21winktotimkopf: hm, tried "lein deps"?
03:21totimkopfwink, tried that just now, still no go
03:22winktotimkopf: if you're using lein2, that should be enough though.. hmm :)
03:22totimkopfi'm using lein 1.7.1
03:22totimkopfut oh
03:22winkthat could be it.
03:22winkring in this case (afaik) works as a leiningen plugin
03:23winkthe CLI part, that is
03:23winklein help should show ring
03:35totimkopfwink, fantastic, lein2 solved this issue
03:36winktotimkopf: nice, have fun then :) I'm doing my first luminus app as well right now
03:36totimkopfthanks, you too :)
03:41FoxboronNow srsly. Spent a little time with Midje last night. Best Testing framework i have encountered.
03:41FoxboronWas atually fun writing tests
03:41mthvedteven though lisp is the poster child for macros and code generation, i still have a hard time believing it when it actually works
03:41djcoinWhere did the defadt moved to (the link in http://clojuredocs.org/clojure_contrib/clojure.contrib.types/defadt is broken - the clojure.contrib has been split in several lib - but can't find the good one) ? Thanks!
03:42mthvedtas though after enough coding the machine just takes pity on me, and pretends my code generators are doing the right thing
03:50ucb,(source ->)
03:50clojurebotSource not found\n
03:50Guest15182q
03:51totimkopfmthvedt: I think that's one of the benfits of Lisp, more power to express something as intended
03:54mthvedttotimkopf: yeah, but it gets more unbelievable as you pile the abstractions and eval/macros higher
03:55totimkopfor maybe you're just that good at expressing yourself in Lisp that you just can't believe it;p
03:56mthvedtoh yeah, i did forget to account for my greatness
03:56mthvedtthanks for reminding me!
03:57winklol
04:01amalloytomoj: aha! i'm not the one who broke seque
04:02amalloyapparently in 1.5 if you deref an agent that's failed, you get nil instead of an exception
04:07tomojI see
04:07amalloyso seque is broken, and i'm the only one who touched it, but i'm not the one who broke it
04:07tomojI apologize for the accusation :)
04:07hiredmanamalloy: well, you get back whatever value was in the agent before the failure
04:07amalloyare you kidding? being accused of breaking clojure.core is great! it's nice to have some code that has the possibility to do that
04:08amalloyoh, okay. hiredman is right, i'm sure
04:08amalloywas that an intentional change, do you know?
04:08hiredmanI don't
04:09mthvedtnot re-throwing exceptions seems like a better behavior
04:09hiredmanI don't seen any mention of it in changes.md of course
04:10amalloyi expect it was unintentional fallout from the change to let you specify what executor to use for agents
04:12hiredmanI am looking at that now
04:13hiredmanthe diff for that doesn't have anything immediately obvious
04:15mthvedtwait, does the deref never throw at all? or just not throw subsequent derefs?
04:19amalloymthvedt: it never throws
04:20mthvedtoh, that's obviously wrong
04:20amalloythe only exception happens on the thread performing/computing the sent action. so if you don't catch it, you never see it
04:21hiredmanvery weird, you can see why it doesn't, but all those lines are at least a year old
04:24amalloyhiredman: 1.4 is more than a year old, isn't it? so a year-old change would be between 1.4 and 1.5
04:29hiredmanI don't think agents ever threw on deref
04:29hiredman(and this build of 1.2 agrees)
04:30hiredmanyou get exceptions if you send an action to a failed agent
04:38amalloyhiredman: weird. i wonder why seque "touches agent just to propagate errors", then, with (do @agt nil)
05:38pepijndevoswow my repl doesn't start 0_o
05:40tomojb
05:42pepijndevosok it does. a bit. whatever
06:04cmdrdatshey guys, is there a built in clojure equivalent to rember? ie - remove an item from a list once - (rember 1 [1 1 1]) -> [1 1]?
06:11noidicmdrdats, I don't think so
06:15clgvcmdrdats: it is pretty easy to build though. I think we had a task like this in our lisp course exercises ;)
06:30cmdrdatsclgv, noidi: cool, thanks - I found an implementation here : http://juliangamble.com/blog/2012/08/03/the-little-schemer-in-clojure-chapter-3/ - cleaned it up a little, but I had hoped there was way to just use core functions directly
06:31clgvcmdrdats: do you want it to be lazy?
06:31cmdrdatscljgv: probably better if it were lazy, but I'm not too fussed
06:31cmdrdatsclgv* :P
06:32clgvclgv: you could take it as example to learn how to build your own lazy function
06:32clgvlol oops
06:33clgvcmdrdats: ^^ keyword: lazy-seq
06:34cmdrdatsclgv: hehe, thanks :) I'm busy converting a php function across to clojure and they have a removeonce function - reminded me of the Little Schemer's rember function :P
06:37tomojif we have core-async check for clojure.core/binding before macroexpansion, it could maybe compile bindings inside async in cljs to clojure.core-async/{push,pop}-binding ?
06:37tomojbut still the problem of bindings established outside core-async
06:38tomojbut shit, that's easy
06:38tomojlight at the end of the tunnel :)
06:40clgvwhat type hast the "writer" in "print-method"? I got working examples and exceptions for both StringWriter and PrintWriter
06:41clgvhm ok they share the Writer ancestor...
07:56tomojwhy can't you let qualified names?
07:57echo-are`Because let only introduce symbols to locations?
07:57echo-are`*introduces
07:59echo-are`And they are compiled out
08:07tomojcompiled out?
08:09echo-are`I mean there are no indications about the symbols in let's binding form in the assemble code
08:10echo-are`I.e. they are like function arguments, only references to a location
08:13tomojso what?
08:14tomojI just want to be able to say (let [{:keys [foo/bar]} baz] foo/bar)
08:14echo-are`What do you need from "foo/bar" there?
08:15tomojoh, hmm
08:15tomojI was thinking it should mean the same as (let [{bar :foo/bar} baz] bar)
08:17tomojbut maybe ::foo/bar
08:17tomojwhich would be weird
08:17tomojso, OK :)
08:40dnolenstuartsierra: any chance for another CLJS release?
08:41stuartsierradnolen: I did it last week.
08:41stuartsierraDo we need another one?
08:42dnolenstuartsierra: we do, I introduced a regression, master is fixed.
08:42stuartsierraok
08:43dnolenstuartsierra: thx!
08:50stuartsierradnolen: Just released 0.0-1803 to Sonatype.
08:51dchnoob question, I'm using `lein repl :connect nrepl:host.name:port` a lot the last few months and after a project upgrade, this seems not to work anymore, but `lein repl :connect host.name:port` does. Is this leiningen that changed, or the project I'm using?
08:55dnolenstuartsierra: sweet, thanks!
09:16djcoinAre their macro composability problem in clojure ? I have no clue about that but I heard someone on an other chan talking about "fortified macro" in racket for example. Any thought on this subject ?
09:18nDuffdjcoin: Macros can't be composed in the same way functions can, correct. That's not a problem in any way specific to Clojure, and if Racket has a solution to it, I'm very curious to see it.
09:20djcoinnDuff: Well i don't have any links to give you :) I went directly asking there about this as one of the goal of clojure is composability whatever the subject
09:23nDuffdjcoin: Macros can certainly be composed from other macros. Composing macros and functions together is something of a mess by-definition, and I don't see how one could possibly "fix" it.
09:24jxxdjcoin: Clojure's macros excel at /that/ kind of composability. (You're conflating function-composition, a mathematical concept, with composabilty, the ease of building things out of smaller components).
09:24nDuffdjcoin: ...now, if one had both function and macro implementations of a thing, and used the appropriate one in the given circumstances, that would be a workaround applicable in some cases, and is also something Clojure supports (see definline).
09:25jxx(e.g. in Clojure I can easily build macros on top of macros and more macros, to a degree that I wouldn't dare, say, in Common Lisp...)
09:26djcoinjxx: what make it more composable ?
09:27nDuffdjcoin: ...to be clear, my answer was predicated on an assumption that we were talking about function composition.
09:27jxxdjcoin, in the sense that you can build big Xs out of smaller Xs...
09:29nDuffdjcoin: That is, you can certainly use macros and functions together; you can't use function composition to combine a function and a macro into a new function.
09:29dnolendjcoin: Racket's macro system is considerably more sophisticated/complex then Clojure's.
09:30djcoinnDuff: right :)
09:30dnolendjcoin: I think you could convincingly argue Racket's system is more composable at some cost to simplicity and ease of use.
09:33jxxWell, if ease-of-use is no object, then *anything's* composable... >:D
09:34djcoindnolen: unfortunately, apart from toy examples, i ahve no experience of racket. But I guess they aimed for composability/simplicity too
09:35djcoindnolen: are you familiar with their (fortified) macro system ?
09:36jxxdjcoin: really? http://docs.racket-lang.org/guide/macros.html
09:37djcoinjxx: maybe this http://lambda-the-ultimate.org/node/4071
09:37jxxRacket comes from Scheme, which is simple in nearly every way *except* macros...
09:39jxxdjcoin, that might be simple by L:tU standards, but that way lies madness...
09:39silasdavisany contraindications for using isa? as a defmulti dispatch function?
09:41silasdavisI have a page rendering function that I was considering accepting a hashmap {:content "blah" :footer "bleh"} or otherwise assume whatever is passed belongs as the :content
09:41silasdavisis it wise to overload the same function for this
09:41silasdavis?
09:42stuartsierrasilasdavis: multimethods already use `isa?` to compare dispatch values.
09:42jxx(my bias has always been for Lispy macros and against Schemey syntax-blarg (while recognizing the usefulness of a modicum of hygiene), so I'm enjoying Clojure immensely...)
09:44dnolendjcoin: only passing familiarity having the seen the paper on fortified macros.
09:44silasdavisstuartsierra, so I wouldn't write: (defmulti foo isa?) ?
09:45stuartsierrasilasdavis: `isa?` returns true or false, so I don't see how that's going to be very useful.
09:45dnolendjcoin: Racket is very cool, though I would say overall it has a bit more of an academic / research focus than Clojure does. It's considerably older as well, 1995?
09:46jxxdnolen, close. Racket was PLT-Scheme; 1994.
10:02silasdaviscan I convert a keyword to a symbol?
10:03silasdavisI was hoping something like (symbol (type {})) would work
10:03AimHere,(symbol :foo)
10:03clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String>
10:03stuartsierra,(symbol (name :foo))
10:03clojurebotfoo
10:05silasdavissorry I'm using the wrong word, I think I mean a symbol
10:05silasdaviswhat does (type {}) return?
10:05mikerod,(type {})
10:05clojurebotclojure.lang.PersistentArrayMap
10:06stuartsierraThat's a Java class.
10:06silasdavisa reference to itself I suppose, but how could I get that as keyword
10:08mikerod,(keyword (.getName (type {})))
10:08clojurebot:clojure.lang.PersistentArrayMap
10:10silasdavis,(symbol (name (keyword (.getName (type {})))))
10:10clojurebotclojure.lang.PersistentArrayMap
10:10silasdavismikerod, ah thanks, I think that straigtens me out
10:12AimHere,(symbol (.getName (type {})))
10:12clojurebotclojure.lang.PersistentArrayMap
10:12mikerodsilasdavis: I'm not sure what you are wanting to accomplish there, but no problem.
10:12mikerod,(type (type {}))
10:12clojurebotjava.lang.Class
10:12silasdavisgetting symbols and keywords the right way round is a start
10:13mikerodsilasdavis: `type` is just returning a java.lang.Class.
10:20silasdavishow is the following multimethod meant to work:
10:20silasdavis(defmulti foo class)
10:20silasdavis(defmethod foo ::collection [c] :a-collection)
10:21silasdavisfrom the clojure docs
10:21silasdavisthen apparently:
10:21silasdavis(foo [])
10:21silasdavis:a-collection
10:21silasdavis,(class [])
10:21clojurebotclojure.lang.PersistentVector
10:24silasdavis,(isa? (class []) ::collection)
10:24clojurebotfalse
10:25trptcolinsilasdavis: are you referring to http://clojure.org/multimethods ?
10:25silasdavistrptcolin, yes
10:25trptcolinthere's a bit on `derive` above the code you're looking at that sets up the hierarchy involving ::collection
10:26trptcolin[that is, ::collection means nothing by itself, you have to write code to make it mean something]
10:27gfrederickshas anybody used the multimethod inheritance stuff for realsies?
10:27trptcolingfredericks: no.
10:27trptcolin;)
10:28Pupnik--has anyone use macros for realsies? (for something you couldnt just use a function for anyway)
10:28gfredericksum
10:28TimMcPupnik: No such thing.
10:28gfredericksthat question totally hinges on "just use"
10:28Pupniki leave it up to the reading to make that judgement
10:29Pupnikif you used a macro, do you believe it offered a substantial advantage over a function alternative
10:29Pupnikreader
10:29Pupniknot reading
10:33nDuffPupnik: You use macros all the time. "and" is a macro. "or" is a macro.
10:33Pupnikthats not what i mean, as i am sure you are away
10:33nDuffPupnik: In those cases, the advantage offered is short-circuiting behavior.
10:33Pupnikwow my typing is awful tonight
10:33PupnikThat is not what I mean, as I am sure you are aware.
10:34nDuffPupnik: ...It's exactly the point I'm making, though. Macros are most useful for language extensions.
10:35gfredericksPupnik: macros can reduce syntactic ceremony in a way that functions can't
10:35Pupnikthat is true gfredericks
10:35Pupniki wasn't asking what they do, just if anyone has used them
10:35gfrederickspeople use them all the time
10:35nDuffPupnik: ...now, have I sometimes seen fit to write custom language extensions? Certainly.
10:36gfredericksevery significant project I've participated defines a few macros for one thing or another
10:36Pupnikok
10:36nDuffPupnik: ...for instance, I have one which builds accessors for JIRA service components.
10:36Pupniktahts good :)
10:36gfredericksmacros take the pressure off the language designer to include every conceivable useful feature
10:37nDuffPupnik: ...makes what would have been a huge chunk of code down to two words per service.
10:37nDuffPupnik: ...and it's a very domain-specific thing; wouldn't be justified elsewhere.
10:37gfredericksPupnik: https://github.com/fredericksgary/catch-data
10:37gfredericksthat library consists of a single macro
10:40silasdavisIf I want to dispatch based on whether something is a map, a keyword, or something else, what's the best way to do it?
10:42trptcolinmaybe start w/ multimethods using clojure.lang.IPersistentMap, clojure.lang.Keyword, :default as dispatch values?
10:43silasdavistrptcolin, am I right to think I need a (defmulti foo class) for that..?
10:43silasdavisor can I just right the (defmethod ..)s
10:43trptcolinclass or type; type is slightly more flexible
10:43silasdaviswhy is that?
10:44trptcolin,(doc type)
10:44clojurebot"([x]); Returns the :type metadata of x, or its Class if none"
10:44silasdavisah thanks
10:46gfredericks,(-> [] (with-meta {:type :foo}) type)
10:46clojurebot:foo
10:46gfredericks,(-> [] (with-meta {:type nil}) type)
10:46clojurebotclojure.lang.PersistentVector
10:52silasdaviswhy would you want to use :type metdata over defrecord?
10:54trptcolinmostly to prevent technomancy's hair catching on fire
11:01silasdavisanyone got a clue what might cause "No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil
11:01silasdavis"
11:01silasdavisusing lein ring server...
11:02weavejestersilasdavis: You're trying to make an io/reader out of nil
11:02weavejestersilasdavis: This can happen if you're using io/resource
11:03weavejestersilasdavis: Which returns nil if the resource is not found.
11:04silasdavisweavejester, thank you!
11:26ppppaulnil is the best reader
11:45gfrederickssilven: I'm actually considering using it for vectors, which defrecord would not be an equivalent drop-in for
11:45gfredericksalso if you want to use the inheritance facilities in multimethods I think :type metadata is the way to go
11:46dnolenlynaghk: new release of CLJS out w/ fix for your issue the other day
12:11tickingloooooool
12:13silasdavisdoes anyone know how to insert a node with laser?
12:13tickingdie telekomiker geben jetzt geld aus um ihre kupferkabel mit kuenstlicher dna zu sichern
12:13hyPiRionticking: I think you accidentally the channel.
12:14tickingdamn wrong channel sorry -.-
12:14silasdavisI've tried (l/id= "login-form") (l/insert :left (l/parse-fragment "<p>hello</p>"))
12:15silasdavisbut it complains that it's not a valid node
12:15tickinghyPiRion yeah I accidentally all the things ^^
12:15silasdavisRaynes, don't suppose you're about...
12:15Raynessilasdavis: Yep.
12:16Raynessilasdavis: It's your lucky day because I'm having such a bad day. I wouldn't be awake right now on any other day.
12:16silasdavisah great, I was just wondering how I can insert something with laser
12:16ucbcemerick: are you parsing regexes like (\w) is (\w) for @imho?
12:16RaynesJust a sec
12:16silasdavisoh dear
12:17cemerickucb: no regexes; it's clojure-opennlp + some core.match stuffs
12:17ucbcemerick: cool :)
12:17cemerickheh, we'll see
12:17Raynessilasdavis: Are you creating the node that you're trying to insert? Does it come from an HTML file somewhere?
12:18ucbwell, I recall doing something along those lines some time ago; matching regexes like the one above and then creating a graph of "is" relationships; once you have some stable nodes you can start matching for other types of relationships for those nodes
12:18ucbcemerick: I was curious whether you were going down the same route
12:18silasdavisRaynes, in this case it comes from an html file
12:19silasdaviswhat I really want to do is match a node and append as the last child
12:19RaynesYeah, we can do that. I'm trying to remember how. ;)
12:23Raynessilasdavis: (document (parse "<div><p>foo</p></div>") (element= :div) #(update-in % [:content] into (nodes "<p>hello</p>")))
12:24Raynessilasdavis: This could be a sign that an 'append' transformer is in order.
12:25silasdavisthanks... might be useful
12:25silasdavisalso insert is listed in the api
12:25silasdavisbut I can't find the source...
12:25Raynessilasdavis: insert puts the node either to the left or right of the matched node. If your example had worked, it would have resulted in "<p>hello</p>…login-form stuff"
12:26silasdavisah it's because the api docs link to an old commit
12:26Raynes(document (parse "<div><p>foo</p></div>") (element= :div) #(update-in % [:content] into (nodes "<p>hello</p>")))
12:26RaynesBah
12:26Rayneshttps://github.com/Raynes/laser/blob/master/src/me/raynes/laser.clj#L228
12:26RaynesYeah, I need to update the API docs.
12:26silasdavisRaynes, my example didn't work, can you see what's wrong wiht it?
12:27RaynesYes. parse-fragment returns a seq of nodes and insert expects a single node.
12:27Raynes(first (parse-fragment ..)) might have made it work./
12:28silasdavisah insert docstring says "Inserts node(s) in direction which can be..."
12:28RaynesHrm
12:28silasdavisalso looks like it has stuff to handle sequence
12:28silasdavis(if (sequential? nodes) ...)
12:31Raynessilasdavis: I'm looking into it. Good catch.
12:32RaynesOh, I see.
12:32Raynessilasdavis: It's because parse-fragment returns a seq of zippers, not just nodes. You'd want to call the 'nodes' function on it instead.
12:32Raynes(document (parse "<div><p>foo</p></div>") (element= :div) (insert :left (nodes "<p>hello</p>")))
12:32Raynessilasdavis: ^ This works.
12:33RaynesDoesn't do what you want, of course, but it does work like it is supposed to.
12:33silasdavisRaynes, thanks, yeah I didn't think it would do what I wanted, but I thought if I could understand how it worked I could do what I wanted
12:34silasdavisand thanks for the library
12:34Raynessilasdavis: If you need anymore help with anything let me know. :)
12:35silasdavisactually one other thing, I was wanting to conditionally perform one select-transform or another depending on whether the user was logged in
12:36silasdavisI tried doing this in the defdocument macro which unsurprisingly didn't work
12:37silasdavisI think the way to go is to move the conditionality into the transformation function, and make the selector 'static' (i.e. not conditional)
12:37silasdavisI guess I could drop the use of the defdocument, but I think I want the parse caching
12:37silasdavisis this the right approach?
12:38RaynesYou can do things like (defdocument … (if logged-in [(element= :something) (transform)]))
12:38RaynesWill that help?
12:39silasdavisoh yes
12:39silasdavisI tried (when logged-in (selector) (transformer))
12:39Raynessilasdavis: https://github.com/Raynes/refheap/blob/master/src/refheap/views/paste.clj#L79
12:39RaynesHere is an example
12:39silasdavisbut I guess that will return (transformer)
12:39RaynesYup.
12:39RaynesNo worries!
12:39RaynesThat's what this channel is for. :)
12:41trptcolini've got a domina event listener fn in which i'd like to swap! a closed-over atom. but i'm getting "No protocol method IWatchable.-notify-watches defined for type"
12:42dnolentrptcolin: what version of CLJS?
12:42dnolentrptcolin: and can you recreate the issue w/ a minimal setup?
12:42trptcolinlooks like 0.0-1586
12:42dnolentrptcolin: i.e. no domina or anything
12:43dnolentrptcolin: try 0.0-1803
12:43trptcolincool, will try that first
12:44ambrosebstools.cli and core.typed work nicely together https://gist.github.com/frenchy64/5526264
12:45dnolenambrosebs: neat
12:45ambrosebsdnolen: :)
12:47silasdavisRaynes, I tried (l/id= "login-form") (l/insert :left (l/nodes (l/parse-fragment "<p>hello</p>"))) as you suggested (just to try and get insert working)
12:47silasdavisbut I get the same error:
12:48silasdavisException in thread "main" clojure.lang.ExceptionInfo: Not a valid node: [{:type :element, :attrs nil, :tag :p, :content ["hello"]} nil] {:dom [{:type :element, :attrs nil, :tag :p, :content ["hello"]} nil]}
12:50Raynessilasdavis: Don't call parse-fragment at all.
12:50RaynesJust l/nodes
12:56silasdavisRaynes, so that works for that example, but actually my notes are coming from a file. Line 27: https://www.refheap.com/paste/14219
12:56trptcolindnolen: looks like the same error after updating, and seeing a couple wacky bits, one in clojurescript.test (can look there for update), and (js->clj (clj->js {})) ;=> {"" nil}
12:57trptcolini'll open a jira ticket for that last one if you agree it's a problem, and will eventually work up a repro case for the watcher error i'm seeing
12:57silasdaviswhere partial-template calls l/parse-fragment
12:58Raynessilasdavis: You have to call l/nodes there instead. You should be able to call it on the resource just the same. You might need to add another function for it like partial-template but that calls l/node instead of l/parse-fragment.
12:58dnolentrptcolin: yeah open a ticket for the data conversion bug
12:58trptcolinhttp://dev.clojure.org/jira/browse/CLJS-504
12:59dnolentrptcolin: and another for the atom bug with a minimal example
12:59silasdavisRaynes, when should partial-fragment actually be used?
12:59dnolentrptcolin: you might want to ping cemerick about clojurescript.test, I moved things around so we could have easily introduced other small regressions - would be great to get test cases for all these since they weren't picked up by the ones we have.
13:00Raynessilasdavis: When you need something to give to fragment
13:04trptcolindnolen: yep, that's my plan. the clojurescript.test thing that was immediately showing up was just about how each deftest name is printed [Object object]; maybe something around Symbol stringifying, but i'd have to look closer to find out for sure. gonna roll back and look for a workaround in the shorter term
13:05redline6561Hey folks. I'm having issues porting a common lisp lib to clojurescript. Could anyone help me see what I'm doing wrong? I'm having real trouble with my defaddress macro. https://github.com/redline6561/cljs-6502/blob/master/src/cljs/cljs_6502/addressing.cljs
13:06dnolentrptcolin: the persistent data structures no longer implement toString
13:07technomancyredline6561: is that ... named after the chip?
13:07technomancyO_O
13:07redline6561Yes it is.
13:07trptcolindnolen: this should just be a Symbol. or are you including that in the persistent data structures"
13:07technomancy6502 is on my list of languages to learn
13:07technomancy(not anywhere near the head, mind you)
13:08trptcolindnolen: nm, i can just REPL it :)
13:08redline6561technomancy: The cl lib may interest you then! I thought it would be a fun port but clojurescript macros are... a bit different. ;) http://github.com/redline6561/cl-6502
13:08dnolentrptcolin: oh probably an oversight
13:08trptcolinok, must be something strange under the hood, because (.toString 'foo) works just fine
13:09dnolentrptcolin: what about (pr-str 'foo) ?
13:09trptcolingood also
13:11trptcolindnolen: yeah, ok, it's a list under the hood
13:11trptcolinprobably because of nested (testing) forms
13:13dnolenredline6561: what's the problem?
13:14mikerodIs it a bad idea/inefficient to repeatedly call reify? Such as to fill a list of objects that all implement some protocol/s or some interface/s the same way. e.g. (map #(reify MyProto (foo [_] %)) some-list)
13:15dnolenmikerod: reify creates a class, so you just paying for creating an object
13:16redline6561dnolen: lein cljsbuild once works but trying to use nrepl.el and load the file (w/ C-c C-l) blows up saying: "clojure.lang.ExceptionInfo: Assert failed: set! target must be a field of symbol naming a var targetexpr at line 13"
13:16redline6561Which is pretty confusing as neither my defaddress macro nor any of the calling code uses set!
13:16dnolenredline6561: lots of moving parts. does lein cljsbuild auto work?
13:17redline6561Haven't tried. One sec...
13:17technomancywhy are there three separate lein invocations on https://github.com/magomimmo/modern-cljs/ ?
13:17mikeroddnolen: So if in my example (map #(reify MyProto (foo [_] %)) some-list), if (count some-list) ;= 100 , does that mean that there would be 100 different classes created as well as the 100 different objects?
13:18dnolenmikerod: 1 class
13:18redline6561technomancy: i wondered the same thing reading through it recently.
13:18dnolen100 objects
13:18technomancyI'm trying to help someone out who is using cljs and that page looks really complicated and confusing
13:18technomancyand it uses lein-ring =(
13:19mikeroddnolen: repeated calls to reify for the same protocols/interfaces and function implementations knows to create only a single class?
13:19dnolenmikerod: yes
13:19gfredericksman java.jdbc's insert! has a weird API
13:19technomancywhat happened to emezeske anyway; I haven't seen him in ages
13:19mikeroddnolen: Oh, that is interesting.
13:20dnolentechnomancy: haven't seem him on channel but I see deals w/ issues & pull request on GitHub for lein-cljsbuild
13:22redline6561dnolen: ... lein cljsbuild auto doesn't want to halt.
13:23redline6561cpu usage has stopped however. just sitting there eating memory.
13:23technomancyman; I don't want to write a jeremiad against lein-ring but I feel like if people keep getting confused by it I will have no choice
13:23dnolenredline6561: you have to edit the file to trigger a re-compile - i.e. modify some whitespace.
13:23technomancyattn: run-jetty is *not* special. it's just a function. call it like one. the end.
13:24redline6561ah, i see. neat. It encounters the same error btw.
13:24dnolenredline6561: auto avoids JVM startup time and allows the JVM to warmup so subsequent compiles are much faster.
13:24redline6561dnolen: Very cool. Thanks for the tip.
13:24TimMc$seen emezeske
13:24lazybotemezeske was last seen quitting 15 weeks ago.
13:24redline6561Still have no idea why this macro blows up when I use it in cljs though: https://github.com/redline6561/cljs-6502/blob/master/src/clj/cljs_6502/macros.clj#L3
13:25redline6561This seemed the most natural way to port the cl code.
13:29dnolenredline6561: hmm can't look at it more closely, looks like fairly portable Clojure code did you try it in Clojure?
13:29`fogusredline6561: What's the explosion?
13:29cemericktrptcolin: Looks like those PR's are breaking the build?
13:30trptcolinwomp womp
13:30`fogusredline6561: Those `mode` params look suspicious
13:30redline6561dnolen: Just requiring and
13:30cemerickwhoa, travis' lein isn't seeing the 'all' alias o.O
13:30redline6561* macroexpanding it in the clojure repl "worked" fine.
13:30redline6561`fogus: How so?
13:31dnolenredline6561: they'll get namespace resolved, you probably want mode#
13:31redline6561Ah, I'm dumb. Good call.
13:31`fogusredline6561: Do you refer to mode in your bodies?
13:31redline6561Sorry for dumb questions. Still getting used to things.
13:31redline6561`fogus: No.
13:31`fogusredline6561: No apologies needed.
13:32`fogusredline6561: So what dnolen said should be a start
13:33`fogusredline6561: Likewise, the `cpu` and `val` params. Are they referenced in the `body`?
13:34redline6561`fogus: Those will be, yes.
13:34redline6561The working CL this is a port of is here: https://github.com/redline6561/cl-6502/blob/master/src/addressing.lisp
13:35redline6561Basically, I have a simple protocol in cljs and want to extend it with a macro.
13:35`fogusredline6561: Clojure will ns resolve those bare symbols. You'll need the magic anaphora sauce to refer to those
13:36redline6561Aha.
13:36austinhIs there an easy way to copy resource files to an output dir using `lein cljsbuild`?
13:40trptcolincemerick: hrm, i'm seeing these tests as passing locally, fwiw
13:40trptcolinthere's some weirdness around fixtures (the name munging doesn't seem to match up w/ how the fixtures are looked up), but i don't see that exposed in the tests until this new one i have locally
13:41trptcolin[not new weirdness afaict]
13:43gfredericksI just walked up and read (out of context) fogus's line "Do you refer to mode in your bodies?" as if it were some weird mystical thing
13:44technomancyare the docs for lein-cljsbuild pretty comprehensive/trustworthy?
13:45gfredericksI don't recall feeling hostile toward the docs at any point
13:46technomancyseems like a pretty big pile of moving parts but I guess a lot of that is to work around JVM boot time
13:47dnolentechnomancy: I think they are
13:48trptcolindnolen: this feels like the underlying issue of that js->clj thing: (for [k (js-keys (js-obj))] k) ;=> (nil)
13:48trptcolinbut maybe there's a solid js/cljs reason for it that i don't see yet?
13:49dnolentrptcolin: looks like a bug
13:49trptcolink cool, i'll pursue that direction
13:49dnolentrptcolin: (js-keys (js-obj)) => #<Array [nil]>
13:49dnolenthat's the bug
13:50dnolentrptcolin: ticket welcome
13:50trptcolineven lower down: (for [x (array)] x) ;=> (nil)
13:51trptcolini'm assuming i'll attach this detail to the one i created earlier, cljs-504
13:52dnolentrptcolin: I think these are seperate issues
13:52tieTYT2i just got an email from my project manager that I'm not allowed to write any more clojure code (We're a java shop)
13:52trptcolinok, but one will fix the other
13:52dnolen(array) prints as #<Array [nil]> but count return 0
13:52dnolenso that's a printing problem
13:52trptcolinright
13:53tieTYT2what do I do?
13:53dnolen(for [x (array)] x) returns a seq count 1
13:54gfredericksthat sounds like an issue from like 6 months ago o_O
13:54gfredericksaround the PrimSeq type or something like that
13:55trptcolindnolen: so seems like the ICounted implementation is correct, but whatever allows traversal is not
13:56dnolengfredericks: maybe but I doubt it
13:56gfrederickssure I doubt it's a regression; just eerily similar
13:57dnolenquite a few things changed at the same time - array & strings are handle directly and not via protocols in core fns. for/doseq got chunked seq support, printing details changed.
13:57dnolenso could be any of those.
13:57kawIs there any way I can get better error messages in emacs / nrepl? Right now I'm getting an IllegalArgumentException when trying to C-c C-k a file, and the only line number reference I'm seeing is to the compiler code, "clojure.lang.RT.seqFrom (RT.java:505)"
13:58kawI'm sure the actual error is something silly and easy to resolve, but it's hard to spot when I have to look through a whole file to find it
14:00dnolenkaw: you probably have a malformed ns expression, or a malformed def
14:01kawYeah, probably, I've seen a similar error before in Clojure
14:01kawBut I really want to know how to get a line number, not how to fix this particular error
14:01kawOr to print the problematic form or whatnot
14:01dnolenkaw: there no way to improve that error w/o patching the compiler
14:02kawHuh, okay
14:03kawWell, I guess I can tolerate a little bit of terribleness for a lot of fairly-nice-ness
14:05technomancyyou build up an immunity after a while
14:05technomancywell
14:05technomancymore like a numbness
14:05aaelonylacij is awesome… just sayin'
14:05technomancystub your toe often enough and eventually you stop feeling it
14:06kawHeh, yeah, I've been there with other languages
14:06dnolenkaw: or send a patch that gives line numbers. I've made a few fixes to ClojureScript to provide more line number and file information where possible - it really helps.
14:06Raynestechnomancy: I don't think that's true.
14:06technomancyRaynes: ymmv =)
14:06dnolenkaw: ClojureScript can probably do even more when we switch readers
14:06Raynestechnomancy: Maybe if you somehow bash the nerves dead in your toe.
14:06kawdnolen: I'll try to remember it when I feel comfortable enough to start patching the compiler :)
14:06trptcolindnolen: i tracked it down to (seq (array)) ;=> (nil) - and also (seq "") ;=> (nil)
14:07technomancyI was amazed that racket's various beginner languages actually provide customized error messages tuned to beginners.
14:08trptcolini know how a patch to cljs.core/seq would work, so i can attach that to the ticket. if you feel like the patch belongs in IndexedSeq instead maybe we can work that out in jira (gotta take off here)
14:09dnolentrptcolin: oops right, I see the issue.
14:09dnolentrptcolin: no patch to IndexedSeq, just check that alength != 0
14:10trptcolindo strings have a fast length fn as well? i was assuming i'd use (count) for both, but yeah, can skip that extra fn call, that's fine
14:10trptcolinah, .-length
14:11dnolentrptcolin: or alength
14:11hiredmanwas the ability to comment on the clojure confluence wiki disabled?
14:11dnolenhiredman: don't think so
14:11hiredmanI can see comments, and see my old comments, but I can't seem to make new comments
14:12trptcolindnolen: alength is no good for strings afaict, but yeah, will use that for the array side
14:13trptcolinoh, derp, the cljs fn
14:13trptcolingot it
14:13hiredmandnolen: can you try and comment and see if it works? (or even if you can find the input box to do it?)
14:14technomancynote that you don't seem to be able to delete comments last I checked
14:14technomancyso make it count =)
14:14dnolentrptcolin: it works for strings
14:15trptcolinyep, for some reason i had .alength in my head
14:15dnolentrptcolin: alength just compiles down the .-length anyway
14:15hiredmantechnomancy: could you check?
14:15dnolendown to
14:15hiredmantechnomancy: if you can find a text input for leaving comments
14:16dnolenhiredman: I've been commenting on the specify CLJS has worked fine me all weekend
14:16technomancyhiredman: yeah, I can't comment either
14:17technomancynor edit pages, it appears
14:17hiredman:/
14:17technomancyshame since the emacs page still recommends inf-lisp and slime
14:18technomancyshould probably replace the whole thing with a clojure-doc.org link
14:18dnolenjust tried editing, seems to work
14:18hiredmandnolen: you must have a magic set of permissions the plebes don't
14:22austinhHere's my latest ClojureScript work: http://pettomato.com/games/restaurant/drawing_demo_1/
14:22austinh(Not actually a lot of cljs, but I'm really enjoying it.)
14:24redingerFixing up your permissions hiredman and technomancy. Anybody else while I'm at it? :)
14:25technomancydoesn't seem to have changed?
14:25technomancyoh, there we go
14:25redingerit's sloooooow.
14:26hiredmanredinger: thanks
14:26hiredmanpretty little "add comment" button :)
14:27technomancystill no "delete spam comments" button
14:27redingerHmm, I'm not sure where the comments permissions even are
14:27technomancybut I guess it doesn't matter if it's just forwarding to clojure-doc
14:27technomancydon't worry about it
14:29silasdavishow can splice a list into another list at the nth position like (splice 2 [:u :v] [1 2 3 4 5]) -> [1 2 :u :v 3 4 5]
14:29silasdavis?
14:30gfrederickssilasdavis: with careful use of split-at and concat
14:31gfredericksassuming you don't care if you get a vector back
14:32pl6306I am running windows. I would like to start the clojure repl from the command prompt with a directory added to the classpath. How do I do that?
14:33redingerFound it!
14:33Glenjaminweavejester: cheers for the merge, sorry about the commit length - I was lazy and typed it onto the command line without checking :)
14:34weavejesterGlenjamin: No problem. I'm just really picky about pull requests :)
14:34weavejesterWell, I guess less picky than big projects
14:36Glenjaminis there a reason ring-mock isn't part of the ring-clojure org?
14:37weavejesterGlenjamin: No, I'm been meaning to do it.
14:37weavejesterGlenjamin: Oh, since you're here...
14:37Glenjamini've got a branch going that has the tests passing on 1.5 and adds the lein profile if you'd like me to tidy up and push - there were some issues with order of hash maps
14:38weavejesterWould it be a big problem just to slim down the commit message with a git --amend and then git push -f?
14:38Glenjaminnot at all
14:38silasdavisgfredericks, i'd like the same type back like with inio
14:38silasdavisinto
14:39weavejesterGlenjamin: I'd also be happy to accept a 1.5 test pull request
14:39Glenjamincool, i've re-pushed that commit now
14:39Glenjaminis it worth me adding a travis yml as well, or is that best left to you?
14:40gfrederickssilasdavis: that would take more manual effort I think
14:51dnolenaustinh: neato!
14:51dnolenaustinh: re: game
14:52gfredericksaustinh: I get script-running-forever errors in FF
14:53gfrederickstrying to avoid passing DB connections around with the new java.jdbc API kind of precludes using transactions
14:55austinhdnolen: Thanks.
14:55avishaihi
14:55avishainoob question about style
14:55austinhgfredericks: I believe I just fixed that.
14:55hiredmanwin 15
14:55avishaiany takers?
14:55gfredericks~anyone
14:56clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
14:56dnolenaustinh: I'm impressed your giving a go w/ ClojureScript for this instead of JS
14:56Glenjaminavishai: just ask, and see if you get an answer, tis the IRC way
14:57avishaisuppose i have a variable that starts with one value
14:57austinhdnolen: I've gone back and forth, but this time around cljs was a lot easier than my last JS experiments, and I'm going to try to use pedestal, too.
14:57avishaithen alter initialized to another value
14:57avishaie.g. starts as nil
14:58austinhdnolen: I also wasn't sure if it would be a single page app at first, but now that seems certain.
14:58avishaiin a sense you can say it's "state"
14:58seangroveaustinh: looks very cool, what's the cljs script output size?
14:58avishaii can't use def
14:58seangroveOur app is ~400k, which is pretty considerable
14:58avishaiso do i need an atom?
14:58Glenjaminavishai: can you give a concrete example of why you init to nil?
14:58gfredericksavishai: s/alter/later/?
14:58seangroveavishai: Sure, why not def an atom?
14:58dnolenaustinh: neat
14:59TimMcavishai: Atom/ref, or possibly use binding if the change can be thread-local.
14:59avishaithat's what i did
14:59avishaican i rebind?
14:59avishaii thought binding was for inner scope
14:59austinhseangrove: 1009b right now, but this is only a tiny piece of the app.
14:59gfredericksyou swap! the atom to update is value
14:59austinhseangrove: Sorry, 109kb
14:59Glenjamin,(doc binding)
14:59clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
15:00seangroveaustinh: Hah, ok, I was going wide-eyed at how you got a cljs build down to 1k :)
15:00avishaidon't think i can use binding
15:00Glenjaminbut if it only ever has nil, or the new value - there might be a way to avoid having it be nil
15:00gfredericksavishai: you use swap! to change an atom
15:00avishaiyes, that's what i did
15:00avishaithe scenario is i use sns
15:00dnolenseangrove: I'm assuming you're gzipping?
15:00seangrovednolen: Yeah, definitely
15:01avishaiso i need to register an sns
15:01seangroveJust the initial output is large
15:01avishaitopic
15:01dnolenseangrove: how many LOC is the original CLJS?
15:01avishaiwhich is later used in other functions
15:01seangrovednolen: ~4k
15:01avishaican't pass the variable via function call since sns uses http callbacks
15:01seangroveBut it makes use of a lot of the google closure libs, especially the ui libs
15:01avishaineed to keep this internal
15:02Glenjaminavishai: i see, that's a common scenario - you can either use an atom - but then you only get one "instance" per application
15:03Glenjaminor you can use a ^:dynamic var, and provide a (with-sns {:config :values} ~@body) macro that uses (binding)
15:03Glenjaminor you can have require the config var to be passed into your functions which need it
15:04Glenjaminor you can have a factory-like function which returns a function that closes over the config and can then be called
15:05dnolenseangrove: well 400K sounds pretty good for 4KLOC of CLJS, that's a pretty big CLJS app!
15:05avishaiGlenjamin, how do i initialize the var from a function?
15:05seangrovednolen: I suppose. We just started the SF Clojurescript meetup, probably have the first meetup next month
15:05seangroveFeel like coming out to give a talk sometime?
15:06seangroveThere's a pretty big group of people using it out here at this point
15:06avishaii call def from the function?
15:06Glenjaminavishai: in which scenario?
15:06gfredericks(def my-var (some function to call))
15:06dnolenseangrove: oh wait, 400K after advanced compilation?
15:07seangroveYeah
15:07tomojsuppose you implement a slow with-bindings* for cljs, which uses maps of var name symbols to vals as binding maps, but leave binding as is. is it impossible to get correct semantics with mixed usage of with-bindings* and binding?
15:07avishai(defn init-sns [] (def sns-topic (sns/create-topic topic-nae)))
15:07avishaiand later defn with-init to use this in the binding?
15:08dnolenseangrove: w/ prettying printing turned off?
15:09seangrovednolen: No debug, no pretty printing, advanced optimizations => 470k
15:10seangrovegzipping cuts it down, of course
15:10dnolenseangrove: that's cool about the SF group!
15:10dnolenseangrove: I'm assuming you're pulling together a lot of external CLJS libs as well?
15:10Glenjaminavishai: something like this https://www.refheap.com/paste/14222
15:11Glenjaminif you're building a web-app, then middleware is usually a good place to use the with- macro
15:12seangrovednolen: Not a huge number of other libs, but a big chunk of the google closure library
15:12seangroveA lot of the network, UI, event, etc. stuff
15:12dnolenseangrove: oh, yeah OK, that does sound about right.
15:12avishaiGlenjamin, wouldn't that macro re-evaluate create-topic every time?
15:12seangroveI would really love a report at some point to figure out what require statements are responsible for final output size
15:13dnolenthe tests in CLJS which touch just about every fn and data structure generates a 630K advanced compiled file
15:13seangroveNot sure how you'd track it at this point
15:13Glenjaminyeah, does create-topic do expensive work?
15:13dnolenthat gzips to 96K
15:13avishaisuppose it does, for argument sake. i'm trying to learn the style
15:14dnolenseangrove: having lots of requires doesn't really matter, Closure will dead code eliminate anything you don't use.
15:14seangrovednolen: Sounds similar to us, gzip takes it to ~130kb
15:14Glenjaminavishai: if you look at the examples in https://github.com/jgrocho/clj-gntp
15:14seangrovednolen: That's what I mean - I want to know what code I'm using is causing the largest impact on file size
15:14seangroveMaybe I'm only using a few functions from a google closure require, but that adds another ~20kb, for example
15:15seangroveHard to tell at this point... cutting down on the app size (if we have to) is going to take a lot of trial and error
15:15Glenjaminthat's a different style, but i think it works well for letting apps do init work via a library
15:15muhooi vaguely remember a way in destructuring to get all the args as args. something like (defn wrapper [& :as args] (wrap (apply stuff args))) ?
15:16seangroveIt's not the biggest deal, but cringing a bit at the thought of having to do it under pressure
15:16muhoowithout using a macro
15:16dnolenseangrove: at 4KLOC of CLJS you're probably using a lot of CLJS, most of the weight really comes from the data structures.
15:16seangroveAh, I see
15:17seangroveWell then, compiled-code growth should be fairly slow from here on out then :)
15:17Glenjaminmuhoo: that will work without :as
15:17dnolenand many of data structures are kind of tangled together necessarily
15:17Glenjamin,((fn [& args] args) 1 2 3 4)
15:17clojurebot(1 2 3 4)
15:17dnolenObjMap required PersistentHashMap requires TransientHashMap etc
15:18dnolenso just writing {}, pulls in a lot of code
15:18muhooGlenjamin: Unable to resolve symbol: args in this context
15:18seangroveWell, ~150kb deliverable is acceptable, and if we've already incurred most of the cost at this point, it should be fine
15:18muhooGlenjamin: try actualy using the args inside the fn. they're optional, so they can't be used
15:18seangroveIs it documented somewhere though? Would have been nice to know so I wasn't wringing my hands so much. There's talk about eliminating dead code, but it isn't obvious how much it's helped
15:19svedubois;; Is this JavaScript to ClojureScript conversion correct?
15:19svedubois;;; JavaScript:
15:19sveduboisvar collection = [];
15:19sveduboiscollection.pusj ({foo: "a", bar: 1});
15:19sveduboiscollection.pusj ({foo: "d", bar: 4});
15:19svedubois;;; ClojureScript:
15:19Glenjamini'm not sure i follow...
15:19svedubois(def collection {:foo "a" :bar 1})
15:19svedubois(def collection {:foo "d" :bar 4})
15:19sveduboistypo "collection.push"
15:19SegFaultAXmuhoo: ##((fn [& args] (reduce + args)) 1 2 3 4)
15:19lazybot⇒ 10
15:19Glenjamin,((fn [& args] (apply str args)) 1 2 3 4)
15:19clojurebot"1234"
15:20seangrovesvedubois: No, not really, you're modifying the object in place in js
15:20seangroveYou usually wouldn't do that in cljs
15:20dnolenseangrove: it's not documented, but Closure just follows the call graph. I've teased things apart a bit in the latest release since I understand better what was causing issues for *trivial* programs
15:20muhooSegFaultAX: Glenjamin huh. ok, great, thanks, that does work. the space between & and args is significant, it seems
15:20dnolenHello World in CLJS now generates ~100 LOC
15:20gfredericksI'm deeply confused about how connection pooling could ever possibly work with java.jdbc
15:21gfredericksat least the old API
15:21dnolenbut optimizing real programs like yours - not much more I think we can do, since usage of the standard library really means needed a lot of stuff.
15:21seangrovednolen: Sure, just saying, letting people know that a reasonable cljs app is going to use datastructures, which are a bit heavy, so you're going to end up with ~100kb gzipped pretty quickly, but growth should slow from there
15:21gfredericksdnolen: given apparently most things aren't necessary for hello world, I'm terribly curious what _is_
15:22seangroveMore of the "growth should slow from there" part which is important for allaying fears
15:22dnolengfredericks: the fact that we don't have real keywords, if we get those it'll probably be 1 line of code or close to that.
15:23Glenjaminif i'm only going to write a few hundred lines of JS, it's worth knowing how much CLJS i'd get if i went that route instead
15:23gfredericksa whole lot
15:23GlenjaminI was considering looking at CLJS, but after seeing this discussion i suspect it's not well suited to what i'll be building
15:24gfredericksI wonder how useful cljs would be for using the js semantics, but making use of macros and such to get syntactic benefits
15:24Glenjaminwhich is a mostly non-JS app with a few UI niceities
15:24dnolenseangrove: well, it's better to hear that from you and other users :) People should blog about their experience with larger codebases.
15:24gfredericksGlenjamin: yeah cljs has a significant fixed startup cost in a lot of aspects
15:25dnolenGlenjamin: yeah, no win over plain JS - unless you want macros
15:25Glenjaminright, it's better suited for large JS applications?
15:25dnolenGlenjamin: if you're only writing a hundred lines of JS
15:25Glenjaminand if i understood the introduction slides correctly it's good for CLI tools via node?
15:25gfredericksdnolen: it's a curious use case for high-perf JS -- using macros to make a whole lot of low-level twiddling manageable
15:26dnolenGlenjamin: medium to large. If you're considering using jQuery, Underscore.js, BackBone.js, Ember.js or anything like that - I think CLJS offers a better story in many wyas.
15:26gfredericksI haven't really done high-perf JS so I'm just rambling
15:26Glenjaminmanaged to avoid jQuery so far, but might cave in and use zepto
15:26dnolengfredericks: yes, I think low level CLJS wins over low level JS because of macros.
15:27dnolenyou can pull some Jim Blinn C++ template meta programming tricks
15:28dnolenhttp://www.flipcode.com/archives/Faster_Vector_Math_Using_Templates.shtml
15:28SegFaultAXUgh, I came to clojure to get away from template black magic.
15:29Glenjaminis that basically advanced loop unrolling?
15:29sveduboisCould be something like this:
15:29dnolenSegFaultAX: macro-hell is real.
15:29svedubois(let [{:keys [foo bar]} collection] "a" 1 "d" 4)
15:30SegFaultAXdnolen: Yes, yes it is.
15:30seangroveGlenjamin: cljs is excellently suited for large, and especially long-running apps
15:32seangroveThat link is terrifying
15:34dnolenrelated http://github.com/clojure-numerics/expresso
15:46dnolenhuh wow
15:46dnolenmori got really fast
15:46sveduboisAny suggestion how to convert this?
15:46sveduboisvar collection = [];
15:46sveduboiscollection.push ({foo: "a", bar: 1});
15:46sveduboiscollection.push ({foo: "d", bar: 4});
15:47sveduboisto CLJs
15:47bbloomdnolen: what's "really fast"?
15:47dnolenreducers are better than sequencing JavaScript array ops
15:47gfrederickssvedubois: doto
15:47gfrederickssvedubois: unless you want to use cljs data structures
15:47dnolenyou can of course do that in JS but it's nice they're already there.
15:48dnolenbbloom: 55ms under Node.js to reduce 1-100000 in array, 86ms to do it with PersistentVector
15:48bbloomnice!
15:48bbloomis that using a transient under the hood?
15:50dnolenbbloom: yeah I started mori before all the data structures and optimizations got in
15:58SegFaultAXWill CLJS leverage ECMA 6 when it becomes more widely available? Are people already working on that?
15:59dnolenSegFaultAX: what do you see us leveraging?
15:59SegFaultAXI don't know I guess. Are there any new features that benefit CLJS?
15:59SegFaultAXEven if only to simplify the implementation.
16:00bbloomSegFaultAX: not without complicating the platform support story...
16:00SegFaultAXbbloom: Sure, that's always the case with new major versions.
16:02SegFaultAXA better question might be: what features, if any, from ECMAScript 6 will benefit CLJS?
16:02avishaiGlenjamin, back again
16:03dnolenSegFaultAX: I've seen little in ES6 that we could leverage
16:03avishai(def ^:dynamic *global-var* ...) is per thread, right?
16:03dnolenSegFaultAX: I mostly interested in seeing JS get fast, not get new features
16:04bbloomdnolen: i'm with you. i'd be even more interested in JS going away :-P
16:06callendnolen: could you use asm.js?
16:06callendnolen: since you spoke of speed. :)
16:06dnolencallen: no GC story
16:07dnolenyet
16:07SegFaultAXWould that be a welcomed feature?
16:07callenI figured.
16:07dnolenSegFaultAX: it could be in the future
16:07dnolenSegFaultAX: but right now, of little use
16:07bbloomasm.js is really (at this point) just for numerical code, AFAICT
16:07bbloombut i may be wrong
16:07SegFaultAXdnolen: What are the slowest parts of js, out of curiosity?
16:08dnolenSegFaultAX: GC, closures, no enough inlining
16:08dnolenat a low enough level, the variance in perf profiles between the different browser is obnoxious
16:09dnolenweird crap like null == x vs. null === x
16:09SegFaultAXdnolen: Is V8 categorically better in all cases?
16:09dnolenmakes a diff on V8 but none on SpiderMonkey, and JavaScriptCore
16:09bbloomthe bigger issue isn't what particular things are slow, it's that you can kill your perf with no indication of why
16:10dnolenSegFaultAX: V8 deals with CLJS better, which is allocation heavy
16:10SegFaultAXbbloom: That's mostly a tooling problem though isn't it?
16:10dnolenSegFaultAX: no because you don't know, implementations vary
16:11SegFaultAXdnolen: Does the standard specify memory managment? Is it just simple reference counting?
16:11bbloomSegFaultAX: it's a little harder than that… there is a fundamental attribution problem…. there is no way to match slowness to perf bugs without an absurd level of noise
16:11dnolenSegFaultAX: however the arms race has made some kind of operations uniformly fast. object/array access, array iteration, function call overhead
16:12SegFaultAXAre there low level profiling tools for V8 or spider monkey?
16:13dnolenSegFaultAX: probably, but I just use the browser + command line benchmarks
16:13trinarythis came out recently: https://trace.gl/
16:13trinarylooks fun.
16:13dnolenSegFaultAX: I mean for V8, I don't know of anything for SM or JavaScriptCore
16:13SegFaultAXLame.
16:14SegFaultAXdnolen: Does CLJS make any browser specific optimizations?
16:14dnolenSegFaultAX: nope
16:17brainproxydnolen: have you experimented with cljs on nashorn yet?
16:17dnolenbrainproxy: have not
16:17dnolenbrainproxy: but Bodil did
16:17brainproxyyeah, saw her repl port thing
16:18BodilWHAT DID I DO?!
16:18brainproxybut hadn't taken time to get setup to experiment with it myself
16:18BodilOh. Yes I did. :)
16:18dnolenbrainproxy: you're Michael Bradley right?
16:18brainproxydnolen: yes
16:19dnolenbrainproxy: thanks for the Mori push
16:19dnolenbrainproxy: I was kind of shocked to see how much faster Mori is now
16:19brainproxydnolen: you're welcome; I'm excited to have a good use for it :)
16:19brainproxydnolen: couple of quick things; I can open issues if you like
16:20dnolenbrainproxy: please do, it might be nice to get another release out after a few more changes.
16:20brainproxydnolen: if you point Travis at your github account and mori, the travis badge at the top of the readme will work
16:20dnolenbrainproxy: do I need to setup an account?
16:20brainproxyno, it uses passthrough to github
16:21brainproxyoauth i guess
16:23brainproxydnolen: cool; next time you push to master, it should trigger a build/test
16:23dnolenbrainproxy: cool thanks
16:23brainproxyI'll open issues for the other things
16:24beffbernardDoes anybody know if you can generate primitive type instance variables with deftype? I AOT'ed a deftype that was type hinted and it was an Object instead of the type I wanted
16:25dnolenbeffbernard: it should work
16:32beffbernarddnolen: it works for primitive types but not primitive arrays
16:32beffbernarddnolen: which is unfortunate what I need
16:32beffbernard:(
16:32dnolenbeffbernard: yeah that doesn't work
16:33dnolenbeffbernard: local type hints work though if you're trying to avoid reflection.
16:33beffbernarddnolen: I'm trying to avoid boxing
16:34dnolenbeffbernard: local type hints for the array not the things in it
16:34beffbernarddnolen: I have some performance sensitive code in a hot loop
16:35dnolenbeffbernard: hint the array outside the loop
16:35dnolen(let [^doubles xs xs] (loop ...))
16:39sveduboisIn CLJS is it possible to load external libraries with any command?
16:40beffbernarddolen: I can't really do that. I'm using the disruptor pattern and I have to get the primitive array every time.
16:42seangrovesvedubois: What do you mean?
16:43dnolenbeffbernard: you should take a look at gvec.clj
16:44dnolenbeffbernard: http://github.com/clojure/clojure/blob/master/src/clj/clojure/gvec.clj
16:45sveduboisseangrove: For example if raphael.js is inside the folder /resources/public/js, How I call it?
16:46sveduboisI suppose js/Raphael
16:46dnolenbeffbernard: rhickey works around this issue with an ArrayManager I think?
16:46beffbernarddnolen: reading...
16:47dnolenbeffbernard: I believe the issue is primitive array type hints are an open set, so he creates a wrapper that implements an interface and I think this stuff inlines well
16:47seangrovesvedubois: https://www.refheap.com/paste/e536371dfc6dd339b532f962e is an example of how I wrap the Firebase api
16:47n_bAm I correct in the understanding that Clojure-CLR isn't missing anything major that Clojure-JVM has?
16:47seangroveIt's not perfect, and you may need to use externs instead of this, but it's certainly possible
16:48seangroveThe loading-handle is there because firebase is loaded async, and may not be present to get a ref when we first load up
16:49tomojbbloom: dnolen: bound-fn! this test passes https://www.refheap.com/paste/da7a5901836377211615ed5c2
16:50bbloomtomoj: link to impl?
16:52tomojhttps://www.refheap.com/paste/f906600e0042363bbfa767310
16:53tomojWIP..
16:54bbloomheh, ok, interesting approach :-P
16:54tomojindeed :(
16:54tomojI can't figure out any way to touch binding that won't get shot down for making existing uses much slower
16:55tomojso here you get the slow stuff only when you actually use with-bindings*
16:56tomojthere's a get-thread-bindings macro commented out there that was the beginning of my previous attempt, using the analyzer to find all dynamic vars, but that didn't seem likely to work out because you'd have to go recompile everything every time you define a new dynamic var
16:56bbloomyeah, i was just looking at that
16:57bbloompersonally, i think it's totally OK to reify Var objects for the :dynamic case
16:57bbloombut that also has impact on the repl
16:57bbloomb/c dynamic vars need to be automatically deref-ed
16:58tomojso maybe we just need to convince the benevolent dictator that there's actually a use case for that dynamic-only reification?
16:59tomojmuch rather have a solution something like that if we can get it in, obviously :(
16:59bbloomwell so i had a fork that used bound-fn and a bunch of dynamic var stuff….. and it was extremely useful for me while i was exploring
16:59tomojyeah I remember, but last status I remember is that the use case is not appreciated
17:00tomojand/or the performance issues are too serious even for dynamic-only reification?
17:00bbloomyeah, well what happened was i got to a point where i only needed bound-fn in one very specific, very important place
17:00bbloomand it turned out that i could do static analysis there w/o any problem
17:00tomojmy sights are on core-async which requires just get-thread-bindings and with-bindings
17:00bbloomso i refactored my code & replaced that with a macro generated call to bindings w/ some values pulled out of a map
17:01bbloomyeah, those are basically what i need, but instead i had get-desired-thread-bindings and with-bindings-where-keys-are-known-statically-and-here-are-the-desired-bindings
17:01bbloom& that turned out to be good enough
17:01lazybotjava.lang.RuntimeException: Unable to resolve symbol: that in this context
17:01tomojheh
17:01bbloombut i would have never arrived there without my fork to explore with
17:03bbloomso if you reify only dynamic vars, the biggest issue is what happens when you redefine a var from dynamic -> static or static -> dynamic
17:03bbloomb/c you need to rewrite call sites to have the .deref indirection or not
17:03bbloomthat's the tricky bit w/ that approach
17:05bbloomtomoj: anyway, cool stuff.
17:06tomojthat does seem.. tricky
17:06bbloomtomoj: if you're going to continue to explore the approach here, you may want to combine getters & pushers into a single deftype
17:09tomojwith mutable fields pointing to maps?
17:10tomojI went with just atoms and maps for now because thinking about trying to make it fast left me wondering what to do about the symbol keys
17:12avishaisuppose i have some blocking operation, say ring's run-jetty
17:12avishaiand i want to do something after jetty started
17:12avishaido i need to use and agent?
17:13avishaiin general, how do i wait for other thread? java's thread.join? latch?
17:13tomojhmm, I think due to the trickiness in the reification approach, the accesses will still have to be like they are now, right? so a var access would always emit what it does now, just the binding-related functions would use the Vars?
17:13n_bshould just be able to do (future (do (run-jetty) (your-thing))
17:13tcrayfordyou can use :join? false for that in ring
17:13tcrayfordring-jetty even
17:13avishainice
17:13arrdemis there an idiomatic way to reduce with several pieces of state, or is the solution to reduce using a destructure and a return sequence?
17:13tcrayfordthat'll stop the current thread joining the jetty thread, but now you need a way to make sure the program doesn't exit immediately ;)
17:13avishaibut the real question for me is how to wait later on
17:13tomojsort of hybrid but far less ugly than my hybrid
17:13tcrayforda future is good for that
17:14avishaihow do i wait for it?
17:14hiredman@(promise) is a very simply way to block the current thread
17:14avishaideref?
17:14tcrayfordyeah, deref
17:14n_bA future will block on deref until it's fulfilled
17:14avishaiand how do i handle exit signals? say ctrl c
17:14tcrayfordtry and catch like java, iirc
17:15avishaitry and catch on what? do all threads get the exception?
17:15tcrayfordno
17:15tcrayfordI'm wrong
17:15tcrayford:)
17:15tcrayfordgoogle can answer that
17:15gfredericksdoes slamhound output require entries in a random order?
17:15avishaiit's a jvm question, not clojure?
17:16tcrayfordavishai: yep. Clojure doesn't do anything specific there to my knowledge
17:16technomancygfredericks: should be alphabetical order?
17:16gfrederickstechnomancy: also it splits up [foo :as :refer] into [foo :as] [foo :refer]
17:17technomancygfredericks: =(
17:17technomancywait
17:17avishaioddly enough ctrl+c does stop my programs
17:17technomancyoh, I see what you mean
17:17avishaiso something does handle it
17:17avishaii'll google and get back
17:17technomancygfredericks: yeah, that's kind of weird
17:17gfredericksphew
17:17technomancywould be great if you could fix it
17:17gfrederickswhat? your full time job isn't fixing slamhound??
17:17lazybotgfredericks: Uh, no. Why would you even ask?
17:19tomojarrdem: you got it
17:19gfredericksif for some reason I had a big company with lots of money I would hire A) somebody with the title "double-clicker" and B) technomancy to work full-time on slamhound
17:19tomojI'd like to see another option
17:19gfredericksmaybe A) and B) could be the same thing
17:19arrdemlol
17:19arrdemtomoj: figured as much
17:20hiredmanexcept technomancy hates mice
17:20tcrayfordgfredericks: I thought you ran groupon?
17:20NeedMoreDesuI wish to generate keyboard sequences when some keys are down. Those thinks are usually done in autohotkey or autoit, but my ahk script is just too big to understand. I found java.awt.Robot class, so I can press needed keys. How can I listen to keypresses?
17:20gfrederickshiredman: oh man what a choice to present him with: you can work full-time on slamhound, but you can't use a keyboard
17:21tcrayfordon screen keyboard only
17:21tcrayfordno voice input either
17:21tcrayfordTOUCH THE RODENT
17:21tomojarrdem: are they independent?
17:21gfrederickstcrayford: a double-clicking based on-screen keyboard
17:21tomojI mean are you basically trying to do two reduces in parallel, or do the states affect eachother?
17:21technomancycomputer mice give actual rodents a bad name
17:21gfrederickstcrayford: the idea that I run groupon is a grave exageration
17:22technomancyI had a pair of fancy rats a while ago that were very agreeable
17:22gfrederickstechnomancy: how were they as I/O devices?
17:22tcrayfordI: food O: poop
17:22arrdemgfredericks: they work out OK if you don't mind that they nip back when you click
17:22technomancyI: also the sofa
17:23gfrederickssubset of food?
17:30avishaiah
17:30avishaijava SignalHandler
17:30avishaiworks like charm
17:30avishaiused reify for the first time too! yippi!
17:31avishaii have to say, clojure make jvm fun for me!
17:32gfredericks(inc clojure)
17:32lazybot⇒ 12
17:32hiredman~clojure
17:32clojurebotclojure is like life: you make trade-offs
17:33gfredericks~clojure
17:33clojurebotclojure is not scheme
17:33gfredericks~scheme
17:33clojurebotscheme is Scheme is like a ball of snow. You can add any amount of snow to it and it still looks like snow. Moreover, snow is cleaner than mud.
17:33hiredmanclojurebot: that is not the universally positive message I am looking for
17:33clojurebotRoger.
17:33hiredmanclojurebot: idiot
17:33clojurebotExcuse me?
17:33gfredericks~idiot
17:33clojurebotGabh mo leithscéal?
17:33hiredman~clojure
17:33clojurebotclojure is the best
17:34nightfly__~common-lisp
17:34clojurebotPardon?
17:34nightfly__~common lisp
17:34clojurebotcommon lisp is howl's moving castle
17:34seancorfielda great movie!
18:15tacomanI've got a library I'm trying to use that only exists on GitHub, no Clojars push or anything. I tried making a checkout dependency locally, but it just gives me a "could not find artifact oin Clojars" error
18:16justin_smithtacoman: did you try running lein install in the project's directory?
18:16hiredman~checkout
18:16clojurebotLeiningen's "checkout dependencies" feature (see the README) allows you to override a declared dependency with a local copy symlinked inside the ./checkouts dir.
18:16__zerohello, I'm a little lost regarding the use of external jars and clojure. I already set up leiningen to include it in my classpath but from the repl I cannot seem to import it. Keep getting a FileNotFoundException. Any clues?
18:17tacomanjustin_smith: my directory, or the other lib?
18:17justin_smiththe other lib - lein install in the repo is an alternative to checkout, and I prefer it (as long as it is a lein project so installable)
18:18tacomanjustin_smith: got it. yeah, that makes it work. thanks!
18:19__zerobtw, I have used a local maven repo to set it up
18:19justin_smithjust remember that in order to run your app on another machine, you will need to lein install the same lib there
18:19justin_smithwhich is why clojars is preferable
18:19tacomanright. I'm not the lib author, though. is it considered rude to push a snapshot on someone else's behalf?
18:20justin_smithyou would basically fork it but not modify
18:20justin_smiththen it would show up under your project umbrella
18:20justin_smithit would be polite probably to ask them to consider hosting on clojars first
18:20tacomanI did that a week or two ago, actually. No reply yet
18:21tacomanso do you mean GitHub fork and then push to Clojars? the lib might be abandoned anyway, so I might have to pick up maintenance if my own work gets anywhere
18:21justin_smithso you could just make your own clojar of it, then other people are spared the hassle
18:22justin_smithnothing stops you from saying "I am not maintaining this code, I only forked it in order to put it on clojars" correct?
18:23technomancyjustin_smith: yeah, putting that in :description of project.clj is not a bad idea
18:23technomancythough putting it under an org.clojars.$USERNAME group-id kind of implies that too
18:23tacomanTrue. Just trying to make sure I understand community etiquette; I've never actually participated in the open source community in any capacity before
18:24technomancywhat's the lib?
18:24tacomanclj-libtcod. I used libtcod for my senior project, and am looking into doing a rewrite in Clojure
18:25tacomanclj-libtcod is really just a set of bindings with the lib packaged alongside it, I think
18:25technomancyonly one commit =(
18:25tacomanyeah. well, it's autogenerated I think
18:26tacomanthere's a clj-native library which apparently automatically goes through some JNA stuff for you
18:26tacomanit has been used a bit in one of his other projects, although I don't know how stress-tested it is
18:40tacomanshoot. looks like the library itself no longer supports OS X these days. :\
18:48Glenjaminis there a way to specify that one defmethod of a multimethod should match more than one dispatch value?
18:51Glenjaminaha, i can use parent
18:52Glenjaminderive, even - is it totally horrible to do this on a non-namespaced keyword?
18:52SegFaultAXGlenjamin: I think they must be namespaced, yea?
18:53Glenjaminah, i think i can do (derive :checkbox ::checkable) (derive :radio ::checkable) and get what i'm after
18:53SegFaultAXHmm, I thought both the parent and child had to be namespaced.
18:53Glenjaminoh, you're write
18:54Glenjaminright even
18:54Glenjamini get cryptic assertions failures otherwise
18:54Glenjaminhow do i turn a normal keyword into a namespaced one?
18:54SegFaultAXGlenjamin: In any case, you're on the right track I think. You should probably resolve this at the dispatch fn.
18:55Glenjaminthe dispatch function just returns the <input>'s type
18:55SegFaultAXGlenjamin: ::foo is just shorthand for :user/foo
18:55SegFaultAXGlenjamin: Keywords follow the same namespacing convention as symbols (since they use symbols under the hood)
18:55Glenjaminbut given :foo at runtime, via (-> elem :attrs :type), how do i translate to :user/foo ?
18:56Glenjaminthere has to be something better than (keyword (str *ns* "/" (name k)))
18:57SegFaultAXShouldn't the dispatch fn coalesce the input types?
18:58Glenjaminhrm, maybe
18:58Glenjamini've been trying to keep it generic so it's extensible - but perhaps that's a poor goal
18:59SegFaultAXGlenjamin: I mean if you have types foo bar baz but you want bar and baz to result in the same invocation, have the dispatcher yield barbaz or something. Ultimately the function can still inspect the proper type.
19:00SegFaultAXGlenjamin: Or just factor out the shared code and have both multimethods call it.
19:01Glenjaminmm, i've just got it working with (derive ::checkbox ::box) and (derive ::radio ::box)
19:01Glenjaminbut both those approaches would work too
19:01Glenjaminoh, keyword takes two arguments
19:01Glenjamin,(keyword :user :a)
19:01clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String>
19:01Glenjamin,(keyword "user" :a)
19:01clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String>
19:02Glenjamin,(keyword "user" "a")
19:02clojurebot:user/a
19:31devnRaynes: Dude, I just took down 4clojure. We're having a meetup here. /cc amalloy
19:31devnShowing the list of all users *kaboom*
19:31amalloyyeah, that's a feature we really should disable since we can't cope with it
19:32amalloyit'll be back in a minute
19:32devnamalloy: ill make sure no one hits that page again.
19:32devnthanks amalloy!
19:32jsmonkeyHi, I am thinking about learning clojure. I am lookg for a good book. I saw there is a joy of clojure 2ed coming out in aug but I can't wait that long. the first edition covers 1.2 I think and the stable version is 1.5 now. Are the difference that big, should I go with the first edition or any other recommendations? I rather read a book then documentation since I am not that experiencd in functional programming so I w
19:33Glenjaminjsmonkey: i think you can still get the MEAP edition of the second edition
19:33Glenjaminyou get the first edition, and chapters of the 2nd as they are written
19:34jsmonkeyGlenjamin: there was only like 2 avaible chapters for the 2ed edition. but I will of course read the 2ed if I like the first one.
19:34jsmonkeybut what I meant is. have the languge changed much since 1.2?
19:34jsmonkeyGlenjamin: or do you recommend another book or learning resource?
19:34Glenjamini think the core language hasn't changed, but the module layout has - i'm not certain, I only learnt recently
19:35GlenjaminI just read a few syntax tutorials and got stuck in, but I've done a fair bit of FP before
19:35Glenjamini suspect joy of clojure will still be useful if you're new to FP - but you might have read up on the docs afterwards to catch up with new language features
19:36jsmonkeyGlenjamin: ok cool I think I will go with it. I have done some haskell and my main language is js where I try to do as much FP as possible.
19:37Glenjaminah, then you might be ok with just reading up on the syntax and trying to build something
19:37Glenjaminthat's pretty much where I started from
19:37jsmonkeyGlenjamin: lets hope that is the case.
19:37jsmonkeydo you like it so far? how long have you been hacking clojure?
19:57muhooanyone using migratus?
19:58muhooi'm curious how it "knows" whether a migration has been run or not
19:59SegFaultAXI've never looked at it, but most migration systems use a migration table.
20:01muhooa table in the database? makes sense.
20:01trinarythat's how rails migrations work, and I'd expect that it's a common way to implement them.
20:01SegFaultAXmuhoo: Yea, if you look at the database.clj you can see the top few functions are for querying to see if a migration record exists.
20:02muhooah, i wasn't clear on what that was. table-name is kind of unspecific
20:02muhooyep, thanks. (log/info "creating migration table" (str "'" table-name "'"))
20:06jjttjjOI want to just catch all exceptions and log them somewhere
20:07jjttjjwrapping the -main function in a try-catch to catch all exceptions doesn't seem to be working
20:08jjttjjIt's a GUI app that uses swing and does most the work in a future. Am I missing something obvious or is this not enough info
20:08axle_512jjttjj: are you catching the exceptions somewhere so that they aren't thrown all the way to main?
20:09jjttjjI'm not explicitly, is this something other libraries might do?
20:09hiredmanguis in java are multithreaded
20:10hiredmanin the sense that the gui toolkit almost always has a special thread different from the main thread that it uses
20:10axle_512jjttjj: if you are doing all the work in a future, then the exceptions will be propogated up to the run method of that thread. (Not you rmain thread).
20:10SegFaultAXhiredman: Um, what?
20:11axle_512jjttjj: and what hiredman said. Swing GUIs will involve the swing event dispatch thread
20:11SegFaultAXhiredman: Swing is not threadsafe.
20:11SegFaultAXLike, at all.
20:11SegFaultAXAnd most GUI toolkits are not.
20:11hiredmanSegFaultAX: yes, but by using swing you now have at least 2 threads
20:11axle_512jjttjj: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
20:11hiredmanSegFaultAX: I am well aware of swings threading model
20:11jjttjjaxle_512: cool thanks!
20:12SegFaultAXhiredman: It's probably more correct to say that swing /event handling/ runs separately.
20:12hiredmanif you use swing you have at least the main thread and swing's thread (and the finalizer thread and the gc thread)
20:12hiredmanSegFaultAX: the swing thread is a real thread and the novice can unknowingly run real work on it
20:13axle_512jjttjj: working with the event dispatching thread takes some practice
20:13SegFaultAXhiredman: Yes, and?
20:13axle_512jjttjj: that 2nd to last paragraph that starts with "It's useful…"
20:14hiredmanSegFaultAX: so if you use swing your program is multithreaded
20:14SegFaultAXSaying "guis in java are multithreaded" is, in my humble opinion, misleading at a minimum. Swing may manage internally multiple threads but swing itself is not thread safe.
20:14axle_512jjttjj: any event that is called from Swing is running on the event dispatching thread.
20:14hiredmanSegFaultAX: I said nothing about safety
20:14SegFaultAXhiredman: Ok, if you use java your program is multithreaded. That's a really misleading argument.
20:14axle_512jjttjj: If that event triggers some long-running task, you want to move that work to another thread.
20:14hiredmanmultithreaded = more than one thread
20:15axle_512jjttjj: when your long-running task is finished, don't update the UI from that thread. Instead, make the event dispatch thread do it by using invokeLater() or invokeAndWait().
20:15SegFaultAXOh, pendantic arguments. Nevermind, I withdraw.
20:15hiredmanSegFaultAX: which means for example, if you put a try/catch around your main code and their are exceptions in the event loop, you won't catch them
20:15SegFaultAXhiredman: Okay.
20:16jjttjjyeah that's what was throwing me off :)
20:17axle_512jjttjj: also, take a look at this: http://stackoverflow.com/questions/4448523/how-can-i-catch-event-dispatch-thread-edt-exceptions
20:17hiredman"Even though the GUI frameworks themselves are singlethreaded subsystems, your application may not be, and you still need to consider threading issues carefully when writing GUI code." to quote jcip
20:17axle_512jjttjj: It looks like you can register a callback for any exceptions that are thrown in the event-dispatch-thread
20:17axle_512jjttjj: Never tried it though :-)
20:18jjttjjaxle_512: cool, I think I was basically doing most of that stuff by default due to seesaw nudging me in that direction
20:18jjttjjaxle_512: awesine yeah I just found that 2 minutes ago
20:18SegFaultAXhiredman: Yes of course you need to consider threading issues. Because you're probably using threads to do a lot of heavy lifting away from the main thread, but that work still needs to be updated on the main thread.
20:29alexykis there a separate pedestal channel or is it all in here for now?
20:30tomojalexyk: /msg alis list *pedestal*
20:30tomojor, hell, /join #pedestal ...
20:31alexyktomoj: thx!
21:03mmitchelltechnomancy: hey, i'd like to hook into a lein task (lein midje), specific for a project. What's the recommended approach for this?
21:54uvtcIn the cheatsheet, http://clojure.org/cheatsheet , under the "Strings" section, what does "See also IO/to string" refer to?
21:55amalloyuvtc: probably something really really old
21:56uvtcamalloy: thanks. Also, thanks for the help a few days ago (after I'd gone offline) re. .indexOf, removing an item from a sequential coll, and using recursion.
21:56amalloyoh good, i'm glad you got that after all
21:56uvtcI used it to update my notes at http://www.unexpected-vortices.com/misc-notes/clojure/examples/data-structures.html .
21:57amalloyi still think it's a lot better if it takes a pred rather than a specific entire item
21:57uvtcRight. To make it more generic.
21:57amalloyeg, (remove-once even? coll). and the args should definitely be x coll (or pred coll), not coll x
21:59amalloythe args are in the wrong order. it should take coll last, not first
22:00uvtcfound it: https://gist.github.com/amalloy/5500495
22:01uvtcHm... I'm suppose I'm not experienced enough with Clojure yet to see why the coll should come last...
22:01amalloyfunctions which operate primarily on sequences should take them last, just like map, filter, remove, reduce...
22:02gfredericksworks great with ->>
22:02uvtcamalloy: thanks. Now I want to make a table to see just which functions take coll first and which take it last.
22:03jxxeverything works great with as->
22:03gfredericksconj takes a coll first
22:03amalloywell, it takes a *coll*, not a *sequence*. i was careful to say sequence
22:04gfredericksdrat! fooled by care again!
22:09uvtcamalloy: do you specifically mean "sequences", or "sequential collections"?
22:10amalloythings which you will treat only as sequences
22:11uvtcThanks. Updated my notes.
22:13brehautyup
22:13brehautwhoops
22:24uvtcSeems like `(keep some-fn some-coll)` should be the same thing as `(filter (complement nil?) (map some-fn some-coll))`, and it seems to act that way. But looking at the source, `keep` does not appear to be implemented using `map` in that way.
22:25uvtcIs it maybe for performance that `keep` isn't implemented that way? Or am I misunderstanding `keep`?
22:25uvtc`keep` save typing in some circumstances, anyway.
22:26uvtcsaves*
23:17mmitchellOK, I'm having trouble creating a leiningen plugin hook. I'd like to hook into a task, copy a file on the resource/class-path and call the original task. The problem is that the classpath is not available to my hook. Any ideas on how to fix this?