#clojure logs

2013-12-13

00:00rovarthe comment ;; This is a bit like Mult + Multimethods helps quite a bit
00:01bbloomwhoa lots of stuff totally gonna have to soak this stuff in a bit
00:02rovargot it.. makes a ton more sense now. I must say the docs for pub left me more confused than when I started.
00:37nmccartyalright, so im having a bit of an issue debugging something that uses a couple java timers
00:38nmccartysomewhere along the line, a function is being passed the wrong number of arguments
00:38nmccartybut since it snakes through every structure in the program, its a bit difficult to tell were
00:39nmccartyanyone got any ideas as to how i should go about finding where the bug is located?
01:04alsowhat's the right way to do this:
01:04also,(.indexOf "ab" \b 1)
01:04clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String>
01:05arrdem,(.indexOf "ab" \b)
01:05clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String>
01:06TEttingeralso: what's the 1 for?
01:06alsoit's the fromIndex
01:07gunsalso: that version of indexOf expects an int as the first argument, so you have to cast it
01:07TEttingeror string
01:07TEttinger,(.indexOf "ab" "b" 1)
01:07clojurebot1
01:10alsoah, http://dev.clojure.org/jira/browse/CLJ-445
01:10alsothanks!
01:10TEttingernp. javadocs are handy.
01:11TEttingerhttp://docs.oracle.com/javase/7/docs/api/java/lang/String.html
01:11alsoyeah, it would have worked in java, and will in clojure after CLJ-445 is fixed, if I'm understanding correctly
01:14TEttingerhm? there's no char argument version of .indexOf
01:14TEttingerjust int and string
01:14alsochar is widened to int
01:15dnolenom gets really a sophisticated batching algorithm https://github.com/swannodette/om/commit/ec5f7890d85295e8ffc942c2c873b55e5080dc96
01:15dnolenj/k, but with trivial change 10X faster
01:16TEttingerI'm honestly not sure how chars work on the JVM. I know they aren't an 8-bit equivalent to byte like in C, but UCS-16 might coerce to short.
01:17alsoTEttinger: http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html
01:17TEttingerindeed, "char to int, long, float, or double"
01:17TEttinger,(float \a)
01:17clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>
01:18TEttingerhm, boxed by default
01:25arrdemTEttinger: what with multibyte wierdness in UTF8 that makes sense...
01:25arrdem,(float (Byte. 4))
01:25clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Byte>
01:26arrdem,(doc byte)
01:26clojurebot"([x]); Coerce to byte"
01:29bitemyapparrdem: you missed out man.
01:29arrdembitemyapp: wat
01:29bitemyapparrdem: hackin' and discussin' Haskell with noprompt!
01:29bitemyapparrdem: I explained functors :D
01:29bitemyapp(kind oF)
01:29bitemyapp(I didn't explain the laws. sssshhhh)
01:29bitemyapparrdem: up for a game?
01:30arrdembitemyapp: noice. iff you do resume diff feedback.
01:30bitemyappdiff feedback?
01:31harjaHi guys, what's the preferred way of using the master branch of clojurescript on github in a project?
01:38seangrovednolen: Is there a reason that the react/om components have to mutate state in-place rather than typical clojure functions?
01:41dnolenseangrove: given how om works I don't really see this as a problem as you may have multiple components that share the same app state atom
01:42dnolenseangrove: also w/o the atom it's trickier to do simple optimizations with high value - like batched updates
01:42seangrovednolen: Hrm, interesting. I'm slightly dubious, but I'll try it out more first.
01:50dnolenseangrove: the alternative is more complicated, less flexible, and it doesn't really buy you anything - the state of your application is already pretty trivial to reason about in om because the entire state is available all the time
02:05nopromptgood times
02:11pmapback again
02:12pmapI know there's usually no reason to cast types in clojure
02:12pmapbut I think I actually have a legitimate need to
02:12pmapis it possible to cast to arbitrary classes in clojure?
02:12nopromptdnolen: is this library ready for use?
02:12pmapI can't find anything on google other than "clojure doesn't need casting"
02:13dnolennoprompt: definitely not :) working through TodoMVC to so I can tune the perf and find bugs
02:13nopromptdnolen: looks exciting.
02:15dnolennoprompt: it's getting there, it's tree oriented system so you always have to pass the current data node and path into the tree along - so far the repetition doesn't outweigh the benefits
02:16dnolennoprompt: I may collapse data and path into one value if benchmarks show that it doesn't hurt perf
02:17jasonjcknpmap: a casting is just an assignment + instanceof check, after an object is casted it hasn't changed in anyway
02:17jasonjcknpmap: so in clojure you can do instanceof with instance?
02:18jasonjcknperhaps you're trying to cause reflection lookups to be done with a different static type
02:18pmapoh, nevermind
02:18pmapI just found another method which will return the type I need
02:19pmapI needed it to be a WritableRaster instead of a Raster, so I could call the .setPixels method on it
02:19pmapI was going to use buffered-image's .getData method to get a Raster
02:19pmapand then cast that to a WritableRaster
02:20pmapbut BufferedImages also have a .getRaster method
02:20pmapwhich returns a WritableRaster
02:20jasonjckneither the object is a WritableRaster, in which case doing (.setPixels o) will work, or it isn't a WritableRaster in which case you can't downcast a Raster to something it isn't
02:20nopromptdnolen: ah, i see there's a new version of cljs. excellent. is the #js reader macro new?
02:21pmapI was just following a java code snippet I found on the web
02:21dnolennoprompt: no new release yet, yes #js literal is new
02:21pmapit did: WritableRaster raster = (WritableRaster) bufferedimage.getData();
02:21pmapis that not valid?
02:22jasonjcknyes so the equivilent clojure code would be (.setPixels (.getData bufferedimage))
02:22jasonjcknyou don't need to cast in clojure ;)
02:22nopromptdnolen: that's going to clean up so much ugly clj->js code. when's it coming?
02:22jasonjcknpmap: (add in appropriate arguments for setPixels)
02:22dnolennoprompt: probably pretty soon, couple other patches I'd like to get in
02:23pmapbut how will it know I need to cast it to a WritableRaster?
02:23pmapis it not conceivable that some other class would also have a .setPixels method?
02:23nopromptdnolen: that's what you said last week :-P
02:24nopromptdnolen: i'm just excited for this release. :-)
02:24jasonjcknpmap: sure that's possible, it's using reflection to enumerate through all the different methods of whatever object is passed to .setPixels, so as long as it finds a signature match it will invoke that function
02:24dnolennoprompt: heh, k I might push it out tomorrow
02:25pmapbut Rasters don't have a .setPixels method
02:25pmaponly their sub-type, WritableRasters do
02:25nopromptdnolen: ah, i was just giving you a hard time. just looking forward to the new patches.
02:26jasonjcknpmap: bufferedimage.getData() is returning an object which is instance of WritableRaster (or some child of it), inspite of the signature of getData being Raster, if that wasn't the case the java code wouldn't work, the cast would fail
02:28pmapbut WritableRaster is a subclass of Raster
02:28jasonjcknyah i know
02:29pmapand according to the javadocs, .getImage returns type Raster
02:29pmaperr, .getData
02:29pmaphow can it be the case that it's returning an instance of WritableRaster then?
02:31jasonjcknpmap: it's an instance of WritableRaster that was casted to Raster that's what's being returned
02:31pmapoh
02:31pmapok then
02:32jasonjcknif that wasn't the case you wouldn't be able to cast it to WritableRaster
02:32pmapI see
02:32jasonjckncasting is not some kind of "morph type X into Y"
02:32jasonjcknit's very 'dumb'
02:32pmapI have very little experience with java, or statically typed languages in general
02:33pmapso I always thought casting just meant "morph type X into Y"
02:33jasonjckni wish because then i would morph my user input into the program output
02:33pmapso then (long 3.0) isn't the same as java's (long)3.0 ?
02:33jasonjcknthere is a library like that https://github.com/twitter/bijection
02:34pmapbecause (long 3.0) actually creates a different type?
02:34jasonjckncasting primitive types is a special case in java
02:35pmapoh
02:35jasonjcknthat's more like morphing
02:35jasonjcknthe example you gave
02:35pmapwell I think I've actually only ever casted primitives in my experience
02:35pmapso I didn't realize there was a difference3
02:35jasonjcknI think if you try Long l = (Long)new Double(3.0); it'll fail
02:35pmapin fact, I didn't even realize you could cast non-primitives
02:35jasonjcknto illustrate my point
02:36pmapuntil today
02:36pmapand I thought you couldn't because it wouldn't make sense to be able to "morph" different classes
02:36pmapbut I guess there's really just 2 different types of casting, to address that issue
02:45seriously_randoma bit silly question regarding speed: http://pastebin.com/a29vhaqh
02:52SegFaultAXseriously_random: Well in the second case the REPL is forcing the evaluation of the filtered seq.
02:52jasonjcknseriously_random: if your list was larger then yes
02:53jasonjcknseriously_random: filter returns a lazyseq, if you call first on that, then pos? is only called once basically
02:54SegFaultAXjasonjckn: They will be the same as long as the entire seq in the second case isn't realized.
02:59bitemyappmumble?
03:23bitemyappucb: howdy!
03:23ucbbitemyapp: hiya!
03:24ucbI decided this morning I'm going to invest some time into trying a few simple approaches at time series second guessing. I predict this will all end in nothing and that my frustration/rage levels will be high.
03:24bitemyappucb: I've had a fun day, did some learning and hackin' with noprompt earlier.
03:24ucb</youve_been_warned>
03:24bitemyappucb: time series second guessing?
03:24ucbooh, any new shinys came out of your haxxoring?
03:25bitemyappucb: no, slow progress, was getting noprompt bootstrapped into some Haskell enlightenment :)
03:25ucbbitemyapp: I explicitly avoided the word "predicting" to dodge the adjective "lunatic" being thrown at me.
03:25bitemyappI had a ton of fun though.
03:25ucbbitemyapp: awesome. Haskell is something I'm going to invest in next year.
03:25bitemyappucb: ping me when you're ready to begin, I can put you on the golden path for that -- at least at first :)
03:26ucbbitemyapp: is the start to that path the learn you a haskell book?
03:26bitemyappnope.
03:26ucbgreat then!
03:26bitemyappI disliked LYAH
03:27ucboh?
03:30bitemyappucb: I found it tedious and boring, but a decent reference.
03:31ucbgotcha
03:31ucbI've tried following (a few times already) the building a scheme doc.
03:31ucbbut every time I find other clojure shinies to play with and get distracted
03:32bitemyappucb: the building a scheme thing is decent but only appeals in certain situations
03:32ucbyeah
03:47ucbincanter is full of gold
03:51arcatanis incanter alive? i wouldn't mind having some data analysis tools in clojure
03:51arcatan(currently i'm generating data with clojure and then graphing it with R or Python)
03:52bitemyappIncanter works fine
03:56ucbyeah, incanter works fine. Don't know about dev now, but whatever's there is stable/good enough for me :)
03:58harjaare there good libraries for working with js/Dates in clojurescript?
04:00arcatanclearly i should try out incanter, then.
04:00arcatansomehow i thought it was so dead that it does not even work anymore
04:46seriously_randoma bit confused about 'first': http://pastebin.com/Bey6iqVR
04:47pjstadigseriously_random: i think you are confused about filter
04:47pisketti(first [2]) vs. (first 2)
04:48divyansr,(first '(1 2 3))
04:48clojurebot1
04:49seriously_randomright
04:53harjawhere do the foreign libs have to be in order for cljsbuild to find them? I tried both relative path and file:// -url. The error is java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil
04:56harjaI've been reading http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html this
04:57piranhaharja: IIRC path should be relative to your 'project.clj'
04:58piranhayeah, just checked
05:00harjaYeah, I got it working now. I included the actual file in the index.html and just added reference to it in :externs as-is
05:00harjaI removed the reference from :foreign-libs alltogether
05:52cYmenWho's writing imperative code in infinite let expressions again?
06:04darkest_podHey everyone. I have a question about leiningen and custom exception printing. There is this library that allows nice colored clojure exceptions, called pretty https://github.com/AvisoNovate/pretty
06:05darkest_podThe problem is - instructions provided for leiningen does not seem to work. Same thing for clj-stacktrace library https://github.com/mmcgrana/clj-stacktrace/issues/29
06:06darkest_podDid something change in the last two years in leiningen exception handling?
06:27seriously_randomI suppose there is no visualizer for clojure like there is for python? http://www.pythontutor.com/visualize.html
06:53clgvseriously_random: very likely not
06:54justin_smithyou shouldn't expect lein plugins at runtime
06:54justin_smithlein is a tool that finds your deps and starts your project
06:54justin_smithif you want it at runtime, you want it as a dep, not a plugin
06:55justin_smithoh, don't mind me, you did have it as a dep
06:57justin_smithseriously_random: I think that let block needs to be in `` delimiters?
06:57justin_smitherr I mean preceded by `
06:57justin_smithmy brain is scrambled, I should shut up
07:06fizruk_hi guys! is there a short variant for this? http://pastebin.com/sZQ2XTva
07:07fizruk_it is pretty much like cond->, yet each predicate uses previous result
07:07clgvhow do I get the result of a background shell execution with "conj"?
07:07logic_proganyone managed to compile emacs to javascript?
07:07clgvargs
07:07clgv"conch"
07:09clgvRaynes: ping
07:09justin_smithfizruk (as-> x1 x (if (f1 x) (g1 x) x) (if (f2 x) (g2 x) x) (if (f3 x) (g3 x)) (if (f4 x) (g4 x) x))
07:13fizruk_justin_smith: thanks! can is there an even shorter version (I think specifically for (if (f x) (g x) x) )
07:13fizruk_s/can//
07:16justin_smith(defmacro f+g [f g x] `(if ~(f x) (~g ~x) ~x))
07:16justin_smith(f+g even? inc 4)
07:18justin_smithmore succinct? yes. Worth it? dunno
07:18justin_smithalso f+g is a terrible name
07:22justin_smith(defmacro f+g [f g x] `(let [x# ~x] (if (~f x#) (~g x#) x#)))
07:22justin_smiththe other version was wrong
07:26fizruk_thank you, I'll think about that a bit more
07:26clgvusing "conch 0.6.0" {:background true} programs' futures remain :pending forever... :(
07:35sm0keis dont get logs for a console appender in log4j on the repl
07:35sm0keis there a workaround for this?
07:35sm0kei dont think there should be a repl appender
07:38justin_smithsm0ke: as I understand it the problem is that the log4j output is defined before the nrepl process rebinds *out*
07:38justin_smithit is the classic problem with vars declared :dynamic
07:38justin_smithin a new thread it does not see the binding
07:38justin_smithso it uses the old one
07:39justin_smiths/new/any other/
07:39justin_smithlog4j being an older thread that does not see the new binding
07:41sm0kejustin_smith: can this be worked around?
07:41justin_smithfrom the repl, you could try using alter-var-root on *out* to be the repl's version of *out*
07:41justin_smithI don't know if this would help
07:43sm0kethere should be a clojure repl appender for log4j
07:43justin_smithimho timbre is more compatible with clojure ways of doing things than log4j (ie. being oriented for runtime rebinding, using edn for its config)
07:43sm0kei really dont like timbre, i think log4j is capable enough and much more flexible
07:44justin_smithcan you access the log4j object to set it's output stream? you could tell it to use the value of *out* as seen in the repl as its stream
07:44sm0ketools.logging is the best which worked for me
07:45sm0kejustin_smith: hmm i am using tools.logging
07:45sm0kethere is no log4j object
07:45sm0kei mean not in a way i can control it
07:46justin_smithI think part of this is it is considered a security thing
07:46justin_smithif someone is hacking your system, one of the first things they will want is to rebind / take over logging config
07:47justin_smithso they intentionally keep such functionality out of the design
07:48justin_smithhttps://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/WriterAppender.html you could try to find the instance of WriterAppender and call its setWriter method?
07:48justin_smithif I was wrong above
07:48seriously_randomanyone using light table? how to quit infinite loop in instarepl?
07:51justin_smithhave you tried control-c? I would try that, control-d, escape, control-g
07:51justin_smiththose are all common enough
07:54sm0kejustin_smith: ok this is kind of embarassing, but i had root logger set to warn and was logging an info msg
07:54sm0kejustin_smith: log4j already seems to be logging to repl
07:54justin_smithlol
07:55justin_smithcongrats
07:55sm0keheh
07:56justin_smithsometimes it is reassuring to realize the problem was pebkac
07:56sm0ke:D pebkac
08:11jph-newbie question, i have a map with numeric values as strings... how can i apply something like read-string to generate a new map with integer vals?
08:15solussdgood morning clojurians, does anyone have any recommendations for working with complex numbers in clojure? I kind of expected a Complex type to be in Clojure.math* by now. :)
08:16mdrogalisjph-
08:16mdrogalis,(into {} (map (fn [[k v]] {k (Integer/parseInt v)}) {:a "1" :b "2"}))
08:16clojurebot{:a 1, :b 2}
08:17jph-mdrogalis: cheers, lemme give that a try
08:17jph-i knew it was possible, i just didnt know the right building blocks to get it working
08:18mdrogalisjph-: Everyone wants a sort of map function that takes a hashmap and returns a hashmap. But it never seems to make it into core.
08:18jph-yeh
08:18jph-im dealing with shitty json apis
08:19mdrogalisjph-: I feel that. D:
08:20jph-uppercase keys, floats as strings
08:20solussd,(reduce (fn [a [k v]] (assoc a k (Integer/parseInt v))) {} {:a "1" :b "2"})
08:20clojurebot{:b 2, :a 1}
08:21mdrogalisYeah, normalize that all out first.
08:21mdrogalisOh yeah, solussd reminds me.
08:21mdrogalis,(doc reduce-kv)
08:21clojurebot"([f init coll]); Reduces an associative collection. f should be a function of 3 arguments. Returns the result of applying f to init, the first key and the first value in coll, then applying f to that result and the 2nd key and value, etc. If coll contains no entries, returns init and f is not called. Note that reduce-kv is supported on vectors, where the keys will be the ordinals."
08:21solussd:)
08:21jph-mdrogalis: also noticed fmap here https://github.com/clojure/algo.generic/blob/master/src/main/clojure/clojure/algo/generic/functor.clj
08:22smilerbostad. De ska inte vara där.." x~~~~~~
08:22mdrogalisjph-: Yep, that's a thing too. Take your pick. :)
08:22smilerOps, missclick
08:23jph-so a few minutes ago i had no options
08:23jph-now i have 3
08:23mdrogalisRule of life: You always have outs.
08:23jph-yeh
08:23jph-clojure kinda feels like unix
08:24jph-you know there's some awesome utility to do what you ened
08:24jph-need
08:24jph-but if you dont know about it
08:24jph-you're kinda stuck
08:24jph-i know i can do what i want in an ugly way... but im forcing myself to learn the clojure way
08:24jph-heh
08:26jph-there's like all these handy functions hidden away in libraries
08:26jph-ooh i know
08:26jph-i can benchmark these
08:28cursork " Things to 2-indent in Clojure. i.e. Midje, Compojure
08:28cursork let g:clojure_fuzzy_indent_patterns += ["GET", "POST", "PUT", "PATCH", "DELETE", "context"]
08:28cursork let g:clojure_fuzzy_indent_patterns += ["facts\?"]
08:28cursorkSorry!
08:40pazustepHello, people.
08:40mdrogalisMorning, pazustep
08:41pazustepI'm learning Clojure, and I wonder if anyone could do a quick review of 10 lines of code: https://gist.github.com/pazustep/d6cea23f43e0faceaeb9
08:41logic_progin develpping typical web apps in clojurescript,
08:41logic_progor in javascript, is there any time when one really needs vectors rather than lists?
08:42pazustepI wanna know if this looks like idiomatic clojure or if my past OO experience is holding me back.
08:42logic_progfor web apps, the more I think about it, the more I'm convinced all we need is just linked lists, not vectors
08:43pazusteplogic_prog: I'm not the expert, but… 1) vectors have different performance characteristics (fast random access) and 2) vectors aren't evaluated
08:45logic_progabsolutely, vectors have O(1) rnadom access
08:45logic_progwhile for lists, it's possibly O(n), and possibly with worse constants if one has to chase the "next" field of elements
08:45logic_proghowever, in web apps, I can't think of a single situation where I need O(1) access
08:45logic_progerr, where I need _random_ access
08:46logic_progwhereas I do randomly have shit like "insert this after this element", "delete that element" which seems to work better with doubly linked lists
08:47pazusteptrue, unless you're dealing with *a lot* of data, performance is probably not going to matter much.
08:48jph-sweet, clojure cookbook 50% off at oreilly today
08:48pazustephow about some fns working only on vectors, like subvec?
08:51pazustepI haven't done any clojurescript yet, but when doing client-side js, I often keep a representation of my data in arrays and render that to a table or something; events on each table row will use an index to retrieve the original data.
08:51pazustepam I making sense?
08:57logic_progoh shit
08:57logic_progthe clojure book is finished
08:57logic_prog?
08:58mdrogali`logic_prog: Yes.
08:58logic_progthere goes my wallet
08:58ddellacostawhich one, the 2nd edition of Joy of Clojure?
08:59mdrogalis`ddellacosta: Cookbook.
08:59ddellacostamdrogalis`: ah, cool.
09:00logic_progwhere is the TOC?
09:00logic_progit's still pre-order on amazon
09:01mdrogalis`Hm, maybe I mispoke. Perhaps it's not out-out.
09:02logic_progmdrogalis`: are you part of some secret clojure inner circle that gets books pre-pub ?
09:03logic_proghttps://github.com/clojure-cookbook/clojure-cookbook does not seem very insightful
09:03logic_progcan you post the TOC somewhere?
09:03jph-logic_prog: you can get early access to joy of cloj 2
09:03logic_progjph-: what's new?
09:03logic_progjph-: is it an update, or is it a series of new chapters?
09:03jph-no idea, i havent read the first one
09:04logic_progI've often found the delta from first to second is often trivial
09:04jph-i just picked up the early access to #2
09:04jph-and you get #1 free when you do that
09:04logic_progthe toc looks simiilar to joy of clojure 1
09:05tomcis anyone aware of whether the form (ns whatever (:require [parent [sub :as sub] [other-sub :as other]])) that we have in jvm clojure is available in cljs as part of a lib? Or whether there's plans to support it in the compiler at any point?
09:10borkdudeI asked this in ##java but no one answers there, so excuse me that I'm trying here: Would anyone know how to use build time openjpa enhancement in Intellij unit test running?
09:24schauehothe java.jdbc docs say that sqlingo.vo would produce compatible sql statements, is this still true?
09:24schauehocause I'm getting syntax errors (from mysql)
09:35ProfpatschI want do define a function `rand` that takes a seed and an optional keyword switch :paranoid. How would I do that?
09:37Profpatsch(defn rand [seed & {:keys [paranoid]}] …) would mean :paranoid needed a value, wouldn’t it?
09:37tomc@Profpatsch: you can use :or in that form to supply defaults.
09:37tomcNot sure of the exact syntax, but it shouldn't be hard to find.
09:38ProfpatschThe one above says I’m missing a value when I do (rand 234 :paranoid)
09:39CookedGryphonthere's a couple of things you could do, if you want a single flag, you can do either: (defn rand [seed & flags])
09:39CookedGryphonand check if (contains? (set flags) :paranoid)
09:39CookedGryphonthat's the best way, in case you want to add new flags in the future
09:39joegalloProfpatsch: that's because {& :keys ...} turns the extra arguments into a map behind the scenes
09:39CookedGryphonor, if you just want to check if it's there or not, you could do (defn rand [seed & [paranoid?]] ...)
09:39joegalloso it's for :paranoid true :extra-neat true :coolness-level 5
09:39BronsaProfpatsch: (defn rand ([seed] (rand seed nil)) ([seed paranoid?] ..)) is probably the best you can do
09:40binskiis it possible to recompile src/java into a running REPL session?
09:40CookedGryphonthen paranoid? will be either :paranoid (truthy) or nil (falsey)
09:40joegallojust paranoid by itself doesn't make sense...
09:40CookedGryphonbut joegallo's solution of having it as a map :paranoid true makes more sense in case you want to add more options in teh future
09:40ProfpatschBronsa: Oh, that’s neat.
09:42logic_progdoes clojure support persistentn red-black trees as a primitive?
09:42logic_progI know there are lists, maps, vectors, sects
09:42logic_progbut I want to know if clojure has primitive red black trees
09:43Bronsalogic_prog: a sorted-map is a persistent rb tree if that's what you're asking
09:44ProfpatschBronsa: Hm, but then I don’t have the :paranoid in the method call. So I guess I go with CookedGryphon’s first solution
09:44logic_progBronsa: https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L376
09:44logic_progwhat protocols does sorted-map satisfy?
09:45Bronsalogic_prog: It's a PersistentTreeMap, it's implemented in terms of java interfaces like all Clojure collections, not in terms of protocols
09:47BronsaProfpatsch: you can still do (rand w/e :paranoid)
09:48BronsaProfpatsch: my approach and CookedGryphon work essentially the same, except with his you can do (rand w/e :paranoid :foo :baz) and :foo :baz will get ignored
09:49ProfpatschBronsa: Ah, okay. But with yours the user can do (rand 234 'baz) and the second will be called.
09:49BronsaProfpatsch: that's the same with CookedGryphon's one
09:49ProfpatschSo I’d have to check anyway.
09:50ProfpatschBut can’t expand the interface afterwards.
09:50BronsaProfpatsch: yeah, if you really want to constraint to :paranoid there's no way to do that destructuring the args, you have to do a check
09:56silasdavisis there a 'point free' alternative to ->
09:57silasdavisso instead of (fn [x] (-> x f g h)) I can write (magic-> f g h)?
09:57Bronsasilasdavis: comp
09:57Bronsa,((comp inc inc inc) 1)
09:58clojurebot4
09:58silasdavisI want to thread into first argument, and go in that order
09:58silasdavisso I should have said
09:58Bronsasilasdavis: note that (-> x f g h) is ((comp h g f) x) though
09:58silasdavis(-> x (f y) (g z) h)
09:58silasdavisfor example
09:59CookedGryphonsilasdavis: you'd need to make function rather than a macro
09:59coventry(defn rcomp [& args] (->> args reverse (apply comp))) maybe?
09:59Bronsasilasdavis: not that I know then, you can get away with comp+partial for ->> but not for ->
10:01CookedGryphon(defmacro magic-> [& body] `(fn [x] (-> x ~@body)))
10:05dnolenClojureScript 0.0-2120 going out
10:06coventryMaybe (defn magic-> [fns] (fn [x] (reduce #(-> %1 %2) x fns)))?
10:06coventryHmm, still doesn't get the arguments. You definitely need a macro.
10:07silasdavisif I have some latitude in my argument order, do you think I should prefer partial'ised comp'ositions over threading?
10:07silasdavisI can probably rejiggle things to achieve that...
10:07coventrysilasdavis: Have you considered as->?
10:08silasdavisno what is that
10:08silasdaviscna't find docs
10:09silasdavisyou don't mena -?>
10:09coventry,(doc as->)
10:09clojurebot"([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."
10:09coventryHelps you avoid rejiggering the signatures.
10:12gdevdnolen, just in time for the holidays =D
10:20silasdaviscoventry, oh nice, like accumulated passed between lexical scopes
10:20silasdavisyes that will help, thanks
10:24xeqidnolen: hurray
10:32xeqicemerick: did you get notices for my piggieback/austin PRs while you were away?
10:33koalallamaHow do I apply a fn to a map without creating a new collection? E.g, similar to map fn list, but I just want fn to run on list, without creating a whole new list with the result of fn
10:33koalallamaapply fn to a list*
10:33cemerickxeqi: I did. Scrambling a.t.m. to burn through the backlog. :-)
10:33seangrovepoor tim visher, dnolen constantly teases him with mentions of new cljs release, before they're available
10:34xeqicemerick: np, figured you had a loooong "back from away time" queue
10:34cemerickxeqi: the heap is sorted by complexity / time to review/fix tho, so yours may be one of the last bits I look at :-(
10:34cemerickYeah, it's pretty deep. Doesn't help that I'll be traveling next week as well.
10:35xeqikoalallama: ##(doc doseq)
10:35lazybot⇒ "Macro ([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
10:35xeqi&(doseq [r (range 10)] (prn r))
10:35lazybot⇒ 0 1 2 3 4 5 6 7 8 9 nil
10:35S3thc0nYay! I think i kind of got monads.
10:35koalallamaxeqi: thank you, I was looking for an alternative to doseq, but I guess not
10:36xeqikoalallama: what would it do differently?
10:36koalallamaxeqi: run in parallel
10:37koalallamaI know map doesn't, but I was hoping to get to pmap eventually
10:37xeqisomething like `(doseq [r (range 10)] (future (prn r)))` ?
10:38xeqithough a good implementation reuires thoughts on workloads and chunking
10:39xeqicemerick: let me know if you have any questions to speed up the process
10:40S3thc0nI really do not get what the fuss is all about. They seem simple to me. But now that i try to say what they are, I notice - it is damn hard to explain.
10:45TimMcS3thc0n: What path did you take to enlightenment, at least so far?
10:45cemerickxeqi: sure
10:46cemerickoh, the piggieback patch is smaller than I thought it was. That may bump it up the queue a bit :-)
10:46coventryS3thc0n: You're right, there's not much to fuss over.
10:47S3thc0nI first watched a video using F# (which i do not know, but that did not matter much) by Brian Beckman, and just now read http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html which confirmed my understanding.
10:49brainproxyS3thc0n: I agree.. they're all about relationships between values and functions, which for some devs is a less "tangle" thing than an object or an object's api
10:49S3thc0nAnd you do not have to know any theory at all. Basically you make functions pure by actually extracting any side-effects, and put them in a wrapper which uses those additional data for the actual side-effect and removes it for the next function. No need for so much theory at all.
10:49brainproxy*tangible
10:49S3thc0nIf I got it right.
10:51S3thc0nWhat confused me a lot was people not really clarifying the purity aspect , as I read a lot they make functions pure (period). Having side-effects and being pure? Can't be, what the heck is this.
10:52murtaza52tbaldridge: here is a snippet of code that I found which is using core.async with http-kit - http://pastebin.com/2ZxiSvrv
10:53murtaza52I know that http-kit returns futures. The above code is just gathering them and conj ing them into a vector
10:53tbaldridgemurtaza52: take a look at this : https://github.com/halgari/clojure-conj-2013-core.async-examples/blob/master/src/clojure_conj_talk/core.clj#L290
10:53brainproxydnolen: what's the usual turn around time on your making a cljs release and it being available on maven central?
10:53murtaza52the real blocking will happen when I try to deref each future to use it. So what is the real use of the above code ?
10:54murtaza52looking at the link u sent
10:55tbaldridgemurtaza52: the code I sent returns a channel, so it doesn't use futures. From that you can use clojure.core.async/merge and async/take to combine the results into vector
10:56tbaldridge*vectors
10:56tbaldridgemurtaza52: I do something like that here: https://github.com/halgari/clojure-conj-2013-core.async-examples/blob/master/src/clojure_conj_talk/core.clj#L341
10:57murtaza52however httpkit returns futures, so wont the blocking call be when u try to use the returned result ?
10:59tbaldridgedon't use the return value, use the callback version and put! the value into the channel (see the http-get function in the link above)
11:01mdrogalisRemembering to use put! and take! rather than go/>!/<! is the hardest part of core.async :P
11:02`cbpcurse python and its unicode crap t.t
11:02pepijnd`cbp?
11:02murtaza52tbaldridge: thanks that is brilliant, I dont know why I couldnt put it together !
11:03murtaza52mdrogalis: a stupid question, what is the difference between put! and >!
11:03`cbper sorry i just chose this channel to vent :P
11:03mdrogalisput! can be used outside of a go block, where otherwise you'd need go with >!
11:04mdrogalisDefinitely not a stupid question, murtaza52.
11:04tbaldridgemurtaza52: and if there aren't any readers >! will park the go. put! will just put the value into the channel and move on. So put! is most useful at the edges of your system (eg with java interop)
11:05mdrogalistbaldridge: What happens if the channel is full? Thread blocks?
11:06murtaza52yes I remember from rich hickey's talk that there all buffers have to have a size, there wont be any infinite ones. So does that mean we start loosing data ?
11:06coventrymurtaza52: By default putting on a channel blocks when it's full.
11:07sw1nnmurtaza52: you can choose what do do. (chan 10) vs (chan (dropping-buffer 10)) vs (chan (sliding-buffer 10))
11:08tbaldridgemurtaza52: no data is lost unless you use something like dropping buffer
11:08tbaldridgemurtaza52: if you do 1024 put! and you have no takers the 1025th put! will throw an exception. This is very very rarely a problem, and the exception is there to keep you from writing bad programs.
11:09murtaza52that is if I have a (chan 1024) …
11:09coventryOh. When I experimented with async my puts were blocked once the channel had 1024
11:09coventryelements in it.
11:09tbaldridgemurtaza52: no, that's by default. if you do (chan 1024) then you can have 2048 pending puts
11:10tbaldridgemurtaza52: there are 3 "queues" in channels. The buffer (the number you give to chan), the pending reads and the pending writes. Thus if there are no takers, puts go into the pending writes, and vice versa.
11:11tbaldridgeThe pending writes and pending reads are both hard-coded to 1024. The buffer can be any size you want.
11:12sw1nntbaldridge: After seeing your talk at codemesh last week, I got my data pipeline app working well with core.async that evening, it's been downloading data pretty much ever since. thanks!
11:12tbaldridgeawesome!
11:12murtaza52why have a separate pending queue when you can set the buffer to any size ?
11:12murtaza52is that talk recorded ?
11:13sw1nnmurtaza52: code linked earlier is a goldmine of info...
11:13murtaza52yes let me mine it :) ….
11:14tbaldridgemurtaza52: it has to do with what you want to happen to writers. If a writer can put a value into a buffer then that writer go/thread can continue on executing. If there is no room left in the buffer, then the go/thread blocks and waits. So the buffer is a knob to set how far you want producers to get ahead of consumers.
11:14koalallamaso I guess calling (future somefn) where somefn calls java code may not be completely safe.
11:20murtaza52I understood how buffer helps me tune that. However what is the purpose of the pending queue ? If I understand correctly the pending write acts as a holding place before writing to the buffer. If the buffer is full then the writes start queuing up in the pending writes. Once the pending writes is full, then an exception is thrown. This is the case in put!. In >! it would just block once the buffer is full, irrespective of the pending writes queue.
11:21tbaldridge>! puts a callback into the pending writes queue
11:22tbaldridgeand yeah, as mentioned, it can be helpful to run through that walkthrough I linked above. Perhaps some day my video from the Conj/CodeMesh will be on InfoQ.
11:22murtaza52tbaldridge: thanks
11:22murtaza52it was very helpful
11:32radixI have googled a bit and can't find any; has anyone implemented a clojure-formatting tool that rewrites code to conform to a coding convention while also maintaining comments?
11:35technomancyradix: I think everyone just uses emacs =)
11:40TimMcradix: I recall someone playing with emacsclient to automate the use of emacs as a formatter.
11:40hyPiRionI wish there were some formatting tool, but alaz
11:40hyPiRionalas*
11:42S3thc0nradix: It should not be too hard to write one yourself, I guess.
11:42radixS3thc0n: yeah?
11:42technomancypprint has a code-dispatch mode
11:42radixright, but, comments
11:42technomancybut it's not great.
11:42technomancyyeah, it's tricky
11:42S3thc0nDepending on what you mean by 'coding conventions'
11:42technomancysjacket can do reading in a comment-preserving way
11:43radixS3thc0n: you know, the ones everyone uses.
11:43technomancybut I don't think anyone's hooked it up to output
11:43radixtechnomancy: I also saw rewrite-clj
11:44S3thc0nradix: If it is simple replacement it would work well. But if you have to replace unidiomatic code it would get quite complex, i think.
11:44radixS3thc0n: hmm, not sure what you mean
11:45indigoAh, I love 4clojure
11:45indigoEspecially when seeing that my 6 line solution could be done with two functions :P
11:45mdrogalisindigo: Yeah, I really enjoy that site.
11:45radixhmm, I guess unidiomatic newlines is a problem nobody's solved
11:47S3thc0nLet me make an example: If you only want to convert camel casing to '-'-separation, that is one thing. The next step would be adding a ? to (I'll call hem boolean functions, forgot the proper name). And then you can also try to convert checks within a function to :pre and :post statements.
11:47radixS3thc0n: oh, yeah, I only meant whitespace
11:48indigomdrogalis: I'm up to problem 40
11:48radixbasically, I want the equivalent of "gofmt" for clojure (I think, I've never actually used gofmt)
11:48mdrogalisindigo: Sweet good stuff.
11:48radixactually, I guess gofmt does a good bit more than whitespace.
11:48radixbut I only care about whitespace :)
11:49S3thc0nradix: I think you might be able to just traverse your code using a macro. Which uses a (or everal) regex patterns to match and replace, or even more advanced logic.
11:49justin_smithradix: consider that many macros imply specific formatting for their semantics
11:49justin_smithsince the point of the macro is to introduce a syntax
11:50radixjustin_smith: yep, I realize that
11:50justin_smiththough in practice I let emacs decide how things indent
11:50radixright, and emacs has special cases for a bunch of different forms.
11:50justin_smithbut I decide where newlines go (based on semantics, and often related to macro usage)
11:50justin_smithyeah, it does
11:51radixmaybe I should just use emacs in a script. I assume it's not *too* hard to run it headless to just process a file..
11:51S3thc0nAnd then print the new code. Great thign with LSP is that code is data. Means you can even convert to :pre and :post checks easily without writing half of an interpreter as an external tool.
11:51justin_smithI wish emacs highlighted #_ properly btw
11:51radixS3thc0n: comments :)
11:51scottjare there docs on #js? (cljs data reader)
11:51justin_smithradix: yeah, there is emacs as a batch job
11:51S3thc0nradix: Right, forgot about that...
11:51justin_smithit starts up pretty fast when you are not using the gui
11:52S3thc0nIf you don't care about ugly replace them with symbols ahead of converting it and then turn it back afterwards.
11:53radixI think using emacs in batch mode is probably the quickest thing to do (e.g. for a CI tool to check or rewrite code)
11:53S3thc0nSo code -> string -> code -> string -> code
11:53radixand then maybe rewrite-clj for more interesting things perhaps
11:53S3thc0nradix: Yes, considering you onyl want to manipulate whitespace it surely is.
11:53davshouldn't this work? => (defmacro blah [x] (list x)) (blah 1)
11:54justin_smithradix: yeah, I think you could just load clojure mode, set region to start/end of buffer, and run indent-region
11:54radixit's too bad clojure-mode won't insert newlines where necessary ,but it's a start
11:54justin_smithdav that is basically '
11:54justin_smithdav oh, never mind, it is not
11:55justin_smithradix: I bet there is a config or mode for that
11:56radixhmm, I'm skeptical, but looking
11:56radixI've used emacs a bunch and I've never seen a mode that would actually redo your newlines
11:57justin_smithradix: try calling fill region
11:57justin_smithbefore indent region
11:57justin_smithfill-region / indent-region that is
11:57radixoh, huh
11:58justin_smithhmm no
11:58justin_smithfill-region is not smart enough
11:58dnolenbrainproxy: supposedly up to 24 hours but in my experience just a couple of hours.
11:58radixok. I use fill-region for prose a lot and mostly what I remember is that if I accidentally did it on code it would mess everything up :)
12:00davjustin_smith: so, any ideas why it doesn't work?
12:01justin_smithugh, there is no emacs comment-defining rule that matches the behavior of #_
12:01justin_smithdav what do you expect it to do?
12:01davjustin_smith: return (list 1)
12:02justin_smithdav: a macro causes its expansion to be run
12:02justin_smith(list 1) expands to (1)
12:02justin_smithyou cannot call a number
12:02justin_smith(defmacro blah [x] `(list ~x))
12:03justin_smithquasi-quote is made for this kind of thing
12:03justin_smith('list x) would also work
12:03justin_smithif list is quoted it is returned and used in the code, not in generating the code
12:04justin_smithoh ('list x) would not work, because that is the symbol list, not the binding :)
12:05justin_smith,('list 1)
12:05clojurebotnil
12:05justin_smith,('list '{list :ok})
12:05clojurebot:ok
12:05radixjustin_smith: found a nice recipe: http://www.cslab.pepperdine.edu/warford/BatchIndentationEmacs.html
12:06justin_smithoh sweet
12:06justin_smithwe should totally have a clojure-set-style function, and one of the styles could auto-indent
12:06justin_smith*auto-newline / fill I mean
12:15eigenrickI just came here to express my undying love for merge-with
12:18hyPiRionit's a pretty thing
12:18hyPiRion,(merge-with merge {:foo {:a :b}} {:foo {:b :c} :bar {:g :e}})
12:18clojurebot{:bar {:g :e}, :foo {:b :c, :a :b}}
12:19justin_smith(inc merge-with)
12:19lazybot⇒ 1
12:19davjustin_smith: thanks a lot, that worked.
12:19justin_smithnp
12:21brainproxydnolen: cool, thanks
12:31coventryI wrote a silly implementation of group-by using core.async a few months ago. It hangs after splitting {1, ..., 2048} into odd and even, and I thought that was because the receiving channel for the evens group had 1024 elements in, it, but apparently that's not the case. Any suggestions for why it's hanging? I tried to come up with simpler examples, but they've all worked the way I expected. https://www.refheap.com/21730
12:32coventryActually, it's hanging after splitting {0, ..., 2047}, but anyway.
12:49TimMchyPiRion: That only does two levels. Can you combine merge-with and merge in a way that does arbitrary depth maps?
12:49hyPiRionTimMc: I made Fairbrook for that purpose quite a while ago, but I'm not satisfied with its API. It's too DSLy.
12:50hyPiRionTimMc: but you can make a recursive function for that purpose, sure thing
12:50TimMcCan you do it just with merge-with, merge, and various combinators?
12:51TimMcI guess partial isn't a combinator.
12:51hyPiRionI think I didn't manage to do so with merge-with and merge.
12:51amalloyTimMc: (defn merge-in [a b] (merge-with merge-in a b))?
12:51TimMcNo wait... yes it is? I dunno, bad with these definitions.
12:51CookedGryphonis there a way to check if a channel is closed in core.async without actually reading the value off?
12:51amalloyi haven't been totally following this discussion but that sounds like what you're talking about
12:52amalloydoesn't really work, i guess
12:53TimMc&((-> merge-in #(merge-with merge-in % %2)) {:a {:b {:c {:d 4 :e :hi}}} :f 5} {:a {:b {:c {:d 400}}} :f 60})
12:53amalloythere's https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L148, which probably doesn't meet your requirements for "using only merge and merge-with"
12:53lazybotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
12:54TimMcProbably only works with infinitely deep maps. :-P
12:54hyPiRionTimMc: well no, works fine when no nonmap values collide
12:55TimMc&((fn merge-in [a b] (merge-with merge-in a b)) {:a {:b {:c {:d {} :e :hi}}} :f {}} {:a {:b {:c {:d {{}{}}}}} :f 60})
12:55lazybotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
12:55TimMc&((fn merge-in [a b] (merge-with merge-in a b)) {:a {:b {:c {:d {} :e :hi}}} :f {}} {:a {:b {:c {:d {{}{}}}}} :f {}})
12:55lazybot⇒ {:a {:b {:c {:d {{} {}}, :e :hi}}}, :f {}}
12:55hyPiRionThe vararg version would be (defn merge-in [& maps] (apply merge-with merge-in maps)) I guess
12:58sw1nnmdrogalis: that lein deploy -> s3 repo 'lots of 307's error from yesterday went away so looks like an AWS 'feature'. All working fine now. thks
13:12brainproxydnolen: after bumping to cljs 2120, I'm getting an exception re: reducers.cljs line 301, but there's no stacktrace, only the message "Uncaught TypeError: Cannot read property 'prototype' of undefined"
13:12dnolenbrainproxy: need a lot more information
13:12brainproxyI can submit a ticket, but wasn't sure if you're aware of it; also, I'm not using the reducers library as far as I know
13:13brainproxywell this is an unoptimized build, so I'm getting all the cljs pieces via goog.require, even if I'm not using some of them
13:13dnolenbrainproxy: no ticket until some basic investigation has been done - I've been using 2120 for a while now with different libs and I haven't seen this
13:14dnolenbrainproxy: did you run a clean build?
13:15brainproxyah, it goes away if I don't require mori
13:15brainproxyI'm bundling mori in my build
13:15S3thc0nI wonder if it is generally preferred to accept an arbitrary number of arguments over a collection as input for a function. For example (+ [3 4]) vs (+ 3 4). Both has (dis)adavantages, but basically it results in a question of convention and where to cast the types.
13:18S3thc0nBut from basic function I would guess after thinking a bit about it that an arbitrary number is preferred (except you want to operate on a collection, obviously).
13:19seancorfieldclojure.java.jdbc 0.3.0-rc1 available on maven central... for all you folks slaving away over a traditional database :)
13:19bbloomS3thc0n: just think about the most common use cases that caused you to create the function in the first place
13:20S3thc0nbbloom: Good idea - didn't think of that as I am one who likes to postulate general rules. But it really is as obvious (objectively, not for me apparently) as it is useful.
13:20bbloomS3thc0n: what do you want the typical call site to look like? If the common case is (f x y) or (f coll), then the uncommon case is (apply f coll) and (apply f [x y]) respectively
13:23metelluswouldn't that last one just be (f [x y])
13:23bbloommetellus: er yeah, of course. sorry
13:26S3thc0nAlso one more thing about conventions: Vectors are usually used for readbility when defining collections, but as they behave differently I wonder if that is always smart (especially as long as people rely on conj order -.-). Is there a neat way to define a functions expected type and automatically cast the argument to it without doing it explicitly within the function (for example for performance reasons (which can be avoided by us
13:26S3thc0n...function or just writing two))?
13:27S3thc0nLoads of questions, i hope they aren't overly stupid or annoy people. i just want to do things correct from the beginning.
13:27tbaldridgeS3thc0n: who really relies on conj order? I think most of the time APIs either explicitly work with seqs unless you need random access, then the doc strings will say "given a vector..."
13:28tbaldridgeidk, conj ordering bugs are pretty rare in my experience.
13:28S3thc0ntbaldridge: I've seen quite a few people do it, unfortunately, as they prefer converting and then casting conj instead of doing it semantically correct.
13:29bbloomthe only time i've run in to conj bugs is when i was first learning & had not internalized the fact that all collection functions produce lazy seqs
13:29bbloomlike i knew it on the surface, but my brain was just so used to operating on arrays in rb, js, etc
13:30S3thc0nI understand what you mean.
13:30bbloomalso, until you learn about ##(conj {} [:x 1]) you tend to read conj as "append" which is just plain wrong :-P
13:30lazybot⇒ {:x 1}
13:30S3thc0nI come from that background, too. Even heavier, as my first language was C++ :b
13:30bbloomi do think that clojure is missing a push function
13:31bbloomor whatever the non-polymorphic appending function would be called
13:31bbloombut it hasn't ever been a problem for me
13:31S3thc0nbbloom: Exactly my thoughts! Yesterday I complained, actually noticed cause the 4clojure problems rely on conj ordering *cringe*.
13:32bbloomwell, frankly, push would be conj for sequences, since peek/pop work on seqs & vecs
13:32S3thc0nI love clojure for it's (also or even especially logical) beauty, but using conj for appending just feels terrible.
13:32bbloombut not maps, sets, etc
13:32tbaldridgewhy not use cons for appending?
13:32bbloomtbaldridge: cons is a constructor call
13:32bbloomessentially
13:33tbaldridgeyep, but it always append to the front of a seqable
13:33S3thc0ntbaldridge: because cons prepends afaik? I mean you can cast the type, but... BTW, How expensie are type casts between vectors and lists anyway in Clojure?
13:33tbaldridgeS3thc0n: there are no typecasts between the two
13:33S3thc0ntbaldridge: We are talking about 'adding to the right end', i think.
13:34tbaldridgeS3thc0n: a vector can be converted into a VectorSeq or a list can be converted to a vec via O(n) copying
13:35tbaldridgeI know what I'm about to say will mark me as a jerk, but here it is: you shouldn't try to make code foolproof. If people put garbage into a fn, give them garbage out. "Appending to the right" or "appending to the left" in a polymorphic way in Clojure is utter nonsense.
13:35S3thc0ntbaldridge: Yeah, no other means due to immutability ofc (or are there? Wondering if immutability still applies to objects having no symbol / being used nowhere else.)
13:36bbloomdnolen: https://github.com/swannodette/om/blob/master/src/om/dom.cljs#L29-L34 nice. see what i meant about the #js literal being like half the battle?
13:36bbloomdnolen: that just *feels* better, even tho it's really no different lol
13:36tbaldridgeinstead, teach people to understand how their datastructures work internally and issues like polymorphic conj no longer matter.
13:36dnolenbbloom: no argument, I like #js and I think a lot of people will
13:36S3thc0ntbaldridge: DOn't exactly get what you're trying to say.
13:37nDuffHrm.
13:37dnolenbbloom: so I think I have a design for om that doesn't suck now that avoids extra arguments and avoids dynamic binding
13:37bbloomtbaldridge: i agree, although i think that there is a bit of a layering violation in some of the polymorphic bits of clojure. ie you should build polymorphic things out of monomorphic things
13:37dnolenbbloom: I think the data at every level of the tree should get metadata with the state atom, path, and owning node
13:37dnolenbbloom: so always accessible
13:38dnolenbbloom: and you don't run afoul of losing the context under asynchronous actions
13:38bbloomdnolen: well you want to store MOST of your data entirely externally & then thread limited data around the tree. like for example i might want to have {:user-id 5 ...} but not actually put the user there
13:38tbaldridgeS3thc0n: your original question was about if there was a way to have a function automatically convert args to vecs or seqs. My reply is, don't try to do that. Write your function to take vecs, and if someone hands you garbage, give them garbage back.
13:39tbaldridgeS3thc0n: I would avoid at all costs doing something like clojure.core/nth. That function is O(log32) on vecs, and O(n) on seqs. And that's just wrong, IMO.
13:39dnolenbbloom: sure this is just about trying to get rid of explicitly passing stuff like owner and path around
13:40dnolenbbloom: you don't care about that stuff when you don't need it
13:40bbloomdnolen: why did you separate out all of those different lifecyclic protocols? why not just have one w/ default impls that are no-ops?
13:40S3thc0ntbaldridge: Hm. Especially if doing recursive sequence manipulations (if you end up ever doing that instead of using a core function), I think you start out with a vector but get a list after the first one.
13:40bbloomthen you don't need the satisfies checks everywhere
13:41bbloomdnolen: also, you should totally check in an example or test case or something :-)
13:41S3thc0nSince I did not do a lot of practical CLojure yet I can not say to what extend you actually end up doing this.
13:41dnolenbbloom: I don't see anything wrong with the satisfies checks and I prefer protocols w/ 1 method
13:41dnolenbbloom: yeah not there yet, I wanna kill this path and owner crap
13:42S3thc0nBut I think especially since vectors are jsut stated as a prettier way to write collections often, you should be ready handling both, as often generating functions return sequences, don't they?
13:43S3thc0n[I really need to stop using the word 'return' in Clojure context...]
13:43bbloomS3thc0n: your base assumption is wrong
13:43tbaldridgeS3thc0n: So in most cases I work with seqs, until I need random access, and then I convert it to a vec. And yes, most of clojure.core seq functions just call seq on any argument they are given. This is a no-op on a seq, so there's no cost involved.
13:43bbloomS3thc0n: vectors are not and never were a "prettier way" to write collections
13:43pjstadigS3thc0n: i don't use vectors for pretiness
13:43bbloomS3thc0n: the defining motivation was to decomplect between "evaluates as function calls" and "evaluates as data"
13:43pjstadigthey are for declarative data where you don't want the first thing to be executed as a function
13:43bbloomS3thc0n: that's why we have keywords too
13:43pjstadigand for building things front to back instead of back to front like lists
13:44bbloomS3thc0n: keywords are self-evaluating symbols, just like vectors are element-evaluating collections instead of function evaluating
13:44Osumhi, why can't I use this
13:44Osumuser=> (def c {:a 1 :b.c 3 :d 3})
13:44Osum#'user/c
13:44Osumuser=> (let [{:keys [a b.c]} c])
13:44OsumCompilerException java.lang.ClassFormatError: Illegal field name "b.c" in class user$eval8321, compiling:(/private/var/folders/zl/zbg23pfs2n1d8qpmzq1j1_fjygxdw8/T/form-init7645801555683632848.clj:1:1)
13:44tbaldridgealthough one could argue that [1 2 3] is prettier than '(1 2 3), but perhaps that's just me
13:44Osumare the keys not supposed to have '.' in the names ?
13:44S3thc0nbbloom pjstadig: I agree, but you could also use (quote data), which is why I said vectors are mainly used for prettyness.
13:45bbloomS3thc0n: no. because quote is different thing
13:45TimMcOsum: Symbol literals can't have . in their names.
13:45bbloomS3thc0n: quote stops all evaluation, vectors only prevent function calling
13:45tbaldridgeOsum: , (let [{foo :b.c} {:b.c 42}] foo)
13:45bbloomcompare:
13:45S3thc0nbbloom: I see....
13:45bbloom,(quote [(+ 5 1)])
13:45tbaldridge,(let [{foo :b.c} {:b.c 42}] foo)
13:45clojurebot[(+ 5 1)]
13:45clojurebot42
13:45bbloomer rather i mean:
13:45hiredmanTimMc: no
13:46TimMc&'foo.bar
13:46lazybot⇒ foo.bar
13:46bbloom,'((+ 5 10) (+ 2 3))
13:46clojurebot((+ 5 10) (+ 2 3))
13:46hiredmanit is a repl / compiler issue
13:46bbloom,[(+ 5 10) (+ 2 3)]
13:46clojurebot[15 5]
13:46TimMcOh, I', wrong!
13:46bbloomS3thc0n: the fact that vectors have nice syntax is totally orthogonal
13:46hiredmanif you look at the actually exception it is a problem with the generated bytecode
13:46hyPiRion,((fn a.b [] a.b))
13:46clojurebot#<sandbox$eval122$a_DOT_b__123 sandbox$eval122$a_DOT_b__123@8643e3>
13:47bbloomS3thc0n: rich could have very easily added a special to do that. clojure.core/vector is a function, but you could have some special symbol chagne evaluation rules just like quote does
13:47S3thc0nbbloom: Thank you for clarifyig, did not realize before. As most tutorials just say: Yeah, you could use '() but [] is nicer, as they use literals for the introduction.
13:47hiredmanbut I don't see how the code Osum pasted would generate that error
13:47hiredmanso either whatever repl he is using is rewriting code in a weird way, or he didn't share it exactly
13:49S3thc0nBut is it not kind of strange to use the vector and sequence/list difference on the one hand for storage implementation, and on the other for (restricting) evaluation?
13:49S3thc0nSeems kind of unrelated to me.
13:49hiredman,(let [b.c 1] (fn [] b.c))
13:49Osumhiredman: I did share the whole thing
13:49clojurebot#<CompilerException java.lang.ClassFormatError: Illegal field name "b.c" in class sandbox$eval173$fn__174, compiling:(NO_SOURCE_PATH:0:0)>
13:49bbloomS3thc0n: so now you're getting in to the INTERESTING part :-)
13:49S3thc0nOh wait.
13:50hiredmanOh
13:50hiredmanhuh
13:50hiredman,(let [b.c 1] b.c)
13:50clojurebot#<CompilerException java.lang.ClassFormatError: Illegal field name "b.c" in class sandbox$eval222, compiling:(NO_SOURCE_PATH:0:0)>
13:50S3thc0nI think, I might have just gotten it wrong. The correct way to use a list is not '(data-to-be-evaluated) but (seq data-to-be-evaluated)
13:50hiredmanOsum: right, I just didn't expect let to throw an error about field names like that
13:50bbloomS3thc0n: also consider: lazy sequences. they have the same syntax & evaluation rules as lists, but are very different in representation
13:51Bronsahiredman: locals are compiled unmunged by Compiler.java
13:51amalloyhiredman: the compiler doesn't munge names for locals like it does for record fields
13:51hiredmansure
13:51hiredmanbut locals aren't "fields" in the class sense
13:51bbloomS3thc0n: unlike most other lisps, clojure's SYNTAX is polymorphic. { ... } may give you a persistent *array* map or *hash* map depending
13:51Osumhiredman: so what's the solution ? I have this DS that comes like that from json ?
13:51Osumand I need to extract a field that has a '.' in name
13:51hiredmanin fact locals don't even have names, they are addressed via numerica slots, the only place the names for locals are emitted is in the debugging information
13:51amalloyOsum: give it a local name that's not silly
13:52amalloy(let [b_c (:b.c m)] ...)
13:52hiredmanOsum: the issue isn't the name in the name, the issue is the local name you are trying to bind a value to
13:52hyPiRionamalloy: b-c works too, but I he's working with Datomic
13:52S3thc0nHm...
13:53hyPiRion*I guess
13:53Bronsahiredman: that name is still stored in ghe class though
13:54Osumamalloy: that works, except it can get very verbose really fast 'cause there are a lot of filds like that
13:54hiredmanBronsa: where? outside of the debugging symbol table
13:54S3thc0n,(quote [(+ 1 2)]
13:54clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
13:54S3thc0nOops
13:55amalloyso? (let [[x y z] (map m [:b.c :q.m :foo.bar])])
13:55S3thc0n,(quote [(+ 1 2)])
13:55clojurebot[(+ 1 2)]
13:55Osumamalloy: got it
13:55S3thc0n,(seq (+ 1 2))
13:55clojurebot#<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Long {:instance 3}>
13:55S3thc0nouw
13:55amalloyS3thc0n: you mean (list (+ 1 2))
13:56bbloomS3thc0n: this is why i provide some good advice: go write a lisp interpreter :-) you'll learn a lot!
13:56S3thc0nYeah. Too easily confuse the two.
13:56S3thc0n,(list (+ 1 2))
13:56clojurebot(3)
13:57hyPiRion,(list? (list* 1 2 '(3 4)))
13:57clojurebotfalse
13:57hyPiRionClojure and consistency.
13:57S3thc0nSo list is the correct way. Actually i wonder if the compiler just ignores all cast hints and only does those necessary. As in if I have a list, make it a vetor for some reason without changing it afterwards and then give that to a function actually making it a sequence/list again, it could just stay one internally?
13:57technomancyclojurebot: lol
13:57clojurebotI don't understand.
13:57bbloomhyPiRion: heh, oh yeah the list vs seq dichotomy is fun times
13:58amalloyS3thc0n: you should stop thinking of these as casts
13:58S3thc0nBut as interfaces?
13:58amalloythere have not been any casts in any of these examples; they are all conversions
13:58ivanafter ClojureScript is self-hosting, will the non-macro reimplementations of everything go away?
13:58hyPiRionbbloom: "fun times"
13:58amalloycasting is only relevant in a statically-typed language like java or c
13:58S3thc0nThat is why i said I find it kind fo strange to associate a way of storage with it.
13:59hiredmancasting in java is very different animal from casting in c too
13:59dnolenivan: what do you mean?
14:00bbloomS3thc0n: it actually makes a lot of sense when you think about function application as going from something like (f x y) to splitting off the head and giving you [f (list x y)]
14:00S3thc0nMaybe it should have been different (IMHO which is based on probably barely any information), and [] should just be a way of writing a collection, with the difference between list and vector under the hood, dynamically converted to achieve good performance.
14:00bbloomS3thc0n: there can be no good performance with dynamic magic conversions
14:01bbloomb/c it would be O(N)
14:01bbloomS3thc0n: maybe you should spend a little more time with it before you recommend how it SHOULD be
14:03ivandnolen: I was thinking about CLJS' two namespaces for macros and functions, and why this isn't needed in Clojure proper, and was wondering if having compile phase available any time would reduce the need for two implementations, but my thought was not fully baked
14:03bbloomivan: your intuition is good, but there are a lot of subtle things to consider
14:04dnolenivan: the CLJS way has some advantages it's unlikely to change even if we bootstrap because it would be a lot more work.
14:04S3thc0n_Sorry, disconnected. Did not get anything after my own last message. I think I really need a bouncer.
14:05insejnI have this `with-url` macro in tentacles library https://github.com/Raynes/tentacles/blob/master/src/tentacles/core.clj#L148. Is there a way to make the binding work for all the functions in a file? Or do I have to call `with-url` in every function?
14:05bbloom[14:00:22] <bbloom> S3thc0n: there can be no good performance with dynamic magic conversions
14:05bbloom[14:00:26] <bbloom> b/c it would be O(N)
14:05bbloom[14:00:43] <bbloom> S3thc0n: maybe you should spend a little more time with it before you recommend how it SHOULD be
14:05ivanI wonder if Rich would take a patch to have dual namespaces in Clojure as well ;)
14:07dnolenbbloom: I do see your point about side information, for example in TodoMVC they put the handlers in the props, and in om I would want that to be part of the data
14:07dnolenbbloom: I'm thinking pure should take a map, one represents the actual data, the other is side information
14:07dnolens/would/would not
14:07bbloomright b/c functions have object equality, which is problematic if they are closures
14:08bbloomas opposed to resolved from vars or whatever
14:08bbloomit would weaken props equality
14:08Bronsahiredman: it looks like it's only stored in the LocalVariableTable indeed
14:08dnolenbbloom: not for us, since we provide our own shouldComponentUpdate
14:09Bronsahiredman: from the spec: [..] representing a valid local variable name stored as a simple name
14:09bbloomdnolen: no i'm saying that if you put an fn in to a map & then you re-create that map each frame then you have a freshly allocated fn in each new version, even if various subtrees of that map are identity-equal, the fn won't be
14:10dnolenbbloom: oh right, sorry I see you were agreeing w/ my point above them about keeping them separate
14:10dnolenbbloom: I think this will work out nicely, data, and extra stuff
14:10dnolenand data hold import tree context information as metadata
14:11bbloomi have some alternative ideas, but i'll refrain from sharing to see how your approach turns out
14:11dnolenimportant
14:11bbloomb/c i considered something very similar to that, but went a different way in my notes. curious to see what you come up with
14:11dnolenbbloom: feel free to share if you think it's significantly better this is like version 4/5 for me.
14:12bbloomdnolen: i'd rather you get something done with callbacks than wind up doing some architecture astronauting with me :-)
14:13dnolenbbloom: heh, right :)
14:13S3thc0nI hope it is a bit more stable now.
14:13S3thc0nSorry again. So, why would performance be worse than with explicit conversions?
14:13dnolenbbloom: re callbacks, I was thinking about sending down channels in the side information part of props
14:13bbloomS3thc0n: you're proposing strong AI :-P
14:14S3thc0nSorry that it ain't obvious to me.
14:14dnolenbbloom: probably won't use that approach initially, but I think the design allows it
14:14S3thc0nYes I am. Is that bad?
14:14S3thc0nIf we are compiling anyway, why not use that?
14:14pl6306I have a simple question. I want to find the all index (i.e. numeric position) of "<c>" with in "<S> <C> <C> <C> <C> <C> <C> <C> <C> <C> <C> <C>". There has got to be an easy way to do this in clojure. Thanks in advance for the help.
14:15bbloomS3thc0n: the first sentence in the wikipedia article on strong AI uses the word "hypothetical" :-)
14:15bbloomdnolen: yeah, channels have their own issues as far as UIs go too
14:15S3thc0nWait a moment. You mean that literally.
14:15bbloomdnolen: probably will need some macros for putting together the lifecycle states, etc
14:16dnolenbbloom: definitely, but I don't know if you've looked at React TodoMVC and how they communicate between app and todo item, a bit too much coupling for my tastes.
14:16bbloomdnolen: like i said, rock & roll w/ the "side data" idea & see where you land
14:16S3thc0nWhy would it have to be strong? Many other languages do implicit 'casting', conversion for us if I may.
14:17S3thc0nKind of the same as it is right now with PersistentArrayMap and HashMap.
14:17eigenrickp16306, find replace all <C> with C, then load into an array, then count all instances of C
14:17bbloomS3thc0n: it would require an O(N) copy and deciding when it's OK to add a copy like that without killing perf is a bad idea
14:17pl6306I just want to know what is the index of the instances of <C> when the string is treatetd as a char array
14:17llasramS3thc0n: Maybe what you're missing is ##(seq? []) ?
14:17lazybot⇒ false
14:17nDuffpl6306: If you can't think of a native algorithm, I'd start by thinking about how you'd do it in Java.
14:18nDuffpl6306: ...if the relevant Java standard library bits (String, Matcher, Pattern) have what you need (hint: they do), that at least gives you a fallback position.
14:19S3thc0nI do not see why there has to be a real difference between a list and a vector, so why a vector cannot be a sequence. What do whe even need them for except different storage (which can be abstracated away)?
14:19S3thc0n*abstracted
14:19pl6306ok I will look into that
14:19hyPiRionpl6306: Use .indexOf from the String class
14:19bbloomS3thc0n: they are wildly different data structures
14:20hyPiRion,(.indexOf "foo bar <C>" "<C">)
14:20clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String>
14:20nDuffS3thc0n: abstracting away details which have huge performance impact is a Very Bad Idea.
14:20bbloomS3thc0n: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentList.java and https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentList.java
14:20pl6306Yes but how do I do .indexOf repeatly whill feeding in the result of the first call
14:20hyPiRionclojurebot: what drugs are you taking, man?
14:20clojurebotExcuse me?
14:20bbloomS3thc0n: sorry make that second link https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java
14:21nDuffS3thc0n: One of Clojure's big goals is being a highly practical language. Doing expensive, slow things without being explicitly told to is not conducive to practicality.
14:21llasrampl6306: `iterate`!
14:21llasram,(let [f (fn [s] (->> (iterate #(.indexOf s "<C>" (inc %)) -1) (drop 1) (take-while (complement neg?))))] (f "la la la <C> la la <C> <C> foo <C>"))
14:21clojurebot(9 19 23 31)
14:21rrchi everyone, how might you go about looping when you need to recur from the body of a catch?
14:22S11001001rrc: trampoline
14:22rrcperfect, thanks!
14:22pl6306iterate look promising thanks!
14:23nDuffS3thc0n: ...it's one thing to have constant-factor performance penalties, but silently doing O(n) things which would otherwise be O(log32 n) is a whole different ballpark.
14:23S3thc0nnDuff: What I do not see is why it should be slower than currently, where vectors are often just used for the square brackets and then converted to a seq.uence. But maybe I'll have to read more on the datatypes.
14:24bbloomS3thc0n: because vectors are immutable, converting to a seq is a O(1) operation
14:24brainproxytrampoline is one of my fav "tricks" of late :D
14:24S3thc0nbbloom: And I guess that 1 is not a lot? That solves the whole thing kind of.
14:26bbloomS3thc0n: it's quite clear that you don't have a strong enough understanding of this subject to make recommendations on how to address any perceived problems. that's not an insult, that's a recommendation to go try to write some bigger things with clojure & learn as you go. if you get curious, check out the clojure source code, it's quite approachable
14:26eigenrickhaha
14:27eigenrickI love that trampoline is less like the os/kernel definition of the term, and much more like a real trampoline
14:27eigenrickit keeps bouncing...
14:28S3thc0nYeah, no offense taken. Actually that is what I thought is the reason for my suggestion from the very beginning. As I highly doubt everyone designing and using the language has overlooked something like that, especially since everything else (and that too as my assumption is wrong) is so perfect.
14:28S3thc0nbbloom: Mention did no fit in there anymore.
14:29S3thc0nI was rather trying to get where my current misunderstanding is.
14:30bbloomS3thc0n: it will become very apparent after more practice, i promis eyou
14:34Morgawrdnolen: is there a changelog for the new clojurescript release? Someplace I can browse?
14:34S3thc0nI think I made a big mistake as in that I thought (seq [something]) was kind of like (into '() [something]) (ignoring that the order is different due to conj instead of our suggested 'push')
14:34S3thc0nMemo: Sequences /= lists
14:35S3thc0nA list is just very close, which confused me. Is at least this assumption right?
14:35technomancyS3thc0n: IIRC a list is a seq, but not all seqs are lists because lists aren't lazy.
14:37divyansrIn this code snnipet http://nakkaya.com/2010/02/10/a-simple-clojure-irc-client/ author used ref. Can atom be used there since there is no coordinated change going on ? or I am missing something
14:37TimMcLists happen to implement ISeq, but it might help to pretend (seq some-list) actually returns soemthing else.
14:37dnolenMorgawr: my post the Clojure/ClojureScript ML
14:38dnolenMorgawr: otherwise - http://build.clojure.org/job/clojurescript-release/54/
14:38Morgawrdnolen: alright, thanks!
14:39zerokarmaleftS3thc0n: dspiewak gave a great talk at conj '12 on underlying data structures: http://www.youtube.com/watch?v=pNhBQJN44YQ
14:39S3thc0nTimMc: This is what I thought, too. It just happens that sequences are printed as lists.
14:39eigenrickdivyansr: it seems like atom would work there with swap!
14:39S3thc0nzerokarmaleft: Thanks.
14:40divyansreignerick : Thanks. Of late I am reading lots of code where atom is sufficient. Is ref overused in clojure ?
14:41eigenrickdivyansr: I can't comment on the performance characteristics of either, maybe it's underutilized :)
14:45technomancydivyansr: most synchronization problems grow to a larger scope than a single node, so the sweet spot for refs is somewhat narrow
14:47S3thc0nDamn it. The Scala in that talk makes me realize I am already turning in what is called a 'LISP snob', if I am correct....
14:47S3thc0nEven though having done so little in it.
14:49divyansr:technomancy you mean sweet spot of atom is narrow.
14:49technomancydivyansr: no, atoms are for when you don't have any synchronization
14:50technomancywhich is more common than synchronization that's limited to one node
14:50hiredmantechnomancy: coordination
14:51hiredmanatoms are synchronized, but you cannot coordinate changes to a group of atoms easily
14:51technomancyright, sorry
14:51hiredmanhttp://wiki.gungfu.de/uploads/Main/clojure-conc.png
14:52divyansrhiredman: Yup I find people using ref when atom is sufficient. May be atom are under utilized.
14:53technomancyit is common in very old code (swank-clojure) because atoms were introduced after refs =)
14:54bbloomi'm amused when i see these code bases with AST.ext that are thousands of lines of code long & then think about cljs which just sticks some shit in a map & gets the job done
14:56koalallamafixed my first Java threading / clojure bug today. Feel like Leo DiCaprio on the Titanic
14:56bitemyappkoalallama: :)
14:56technomancyclojurebot: near, far, where ever you are...
14:56clojurebotPardon?
14:59SegFaultAXclojurebot: Every form you eval, every macro you expand, I'll be watching you...
14:59clojurebotNo entiendo
15:00koalallamawas calling a function via a future, but was getting same result. second call to deref the future would either block or throw NPE. Issue was the Java object was being created in a def. Moving it to a let within the function fixed it
15:01SegFaultAXkoalallama: You were def'ing in a future?
15:01TEttingerbbloom, to be fair, cljs is probably thousands of lines of code too.
15:02koalallamaSegFaultAX: some code I was using was ;)
15:03koalallamaSegFaultAX: future would call a function and that function would use def to bind some Java objects
15:04bitemyappkoalallama: that is terrible.
15:04bitemyappkoalallama: where does this code live?
15:07koalallamabitemyapp: https://github.com/jlbfalcao/clojure-snmp
15:07koalallamaURL of source file is: https://github.com/jlbfalcao/clojure-snmp/blob/master/src/main/clojure/clojure/snmp.clj
15:07bbloomTEttinger: i'm referring specifically to declaration of the AST
15:07bitemyappkoalallama: this code was written 4 years ago and hasn't been touched since
15:07bbloomTEttinger: we just *don't do that* :-P
15:07koalallamabitemyapp: yup
15:08bitemyappkoalallama: don't...do that.
15:08koalallama(it's not my code)
15:08bitemyappkoalallama: fork it and fix it.
15:08bitemyappkoalallama: who gives a shit? fix it.
15:08bitemyappthat code is fuck-awful and not even formatted correctly
15:08bitemyappthis person didn't understand Clojure at all. my fucking god.
15:08devnplease chill.
15:09koalallamaIt's on my list. I'm not even 2 weeks into clojure.
15:09bitemyappkoalallama: it's a few lines, you could rewrite with an internal ns
15:09bitemyappkoalallama: then vendor or make your own library later.
15:09tbaldridgekoalallama: don't worry, bitemyapp is a bit...abrasive at times.
15:09bitemyappkoalallama: so you
15:09bbloomTEttinger: analyzer.clj + compiler.clj is less than 2500 lines. that's dramatically different than many compiler projects that have over 3k lines of AST definitions
15:09bitemyappare somewhat fortunate here.
15:09TEttingerwow
15:09koalallamatbaldridge: no worries ;)
15:10S3thc0nOuw.
15:10bbloombitemyapp: the trailing )s are a dead give away
15:10bitemyappbbloom: yep.
15:10bbloomdon't even need to read th e rest of the code to see the way defs are used *cringe*
15:10TEttinger##(+ 1 2 3))))))))))))))))))))))))))))))))))
15:10lazybot⇒ 6
15:11S3thc0nOooh. Thanks again, zerokarmaleft. This cleared it up.
15:11BronsaTEttinger tools.analyzer's analyzer is even more compact: ~600 lines of analyzer + ~400 of passes
15:11TEttingerneat
15:12koalallamabitemyapp: I'm reading Clojure Programming now. When I'm done with it, then I'll feel more comfortable making changes ot other people's code. But I can obviously tell this code has major issues
15:13bbloomyeah, and that can shrink dramatically if we used some kind of parser library rather than the adhoc parsing that does on for def and try/catch and all that jazz :-P
15:13bbloomwhich is like half of this file: https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer.clj
15:13bbloomheh
15:14Bronsabbloom: wanna talk about 'ns parsing in clojurescript? that's painful.
15:14jonasenBronsa: talking about tools.analyzer... What does an ':op :host-interop'? When the ast is produced with tools.analyzer.jvm/analyze?
15:14bbloomyeah. i've been meaning to rewrite that. afaict, it's a regular language, not context free or anything. should be easy to do with a hand-coded state machine
15:14jonasensorry... what does :host-interop refer to?
15:15Bronsajonasen: it's a (.foo bar) form that we don't know if it's a method call or a field access
15:15bbloomBronsa: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L500-L513 <- like that
15:15eggnogginI still can't tell the difference
15:15jonasenBronsa: ah, ok. So it must be determined at runtime?
15:15eggnogginbetween when to use - and . in cljs
15:16Bronsajonasen: yeah, it's like not :validated :instance-field/etc but we don't eve know if it's a field or a method
15:16bbloomeggnoggin: it's confusing, but dash on it's own doesn't mean anything. dot means call method and dotdash means get property
15:16bbloomthat's the whole rule
15:16Bronsabbloom: now that I look at it, looks like dnolen already refactored that a bit, looks nicer than what I remember
15:17bbloomBronsa: that was me :-P
15:17dnolenok this is getting awesome - https://gist.github.com/swannodette/7915826, using om from master now
15:17Bronsabbloom: oh, sorry :)
15:17dnolenno more pushing path around, nor more magic *state* dyn var, and pure can takes opts
15:18bbloomBronsa: no worries. dnolen is always a good initial guess for who wrote any of that, heh
15:18jonasenBronsa: what's the difference between :var and :the-var?
15:18bbloomBronsa: in any case, my point is that we can/should do stuff like that in more places
15:18eggnogginbbloom: but what about stuff like https://github.com/swannodette/om/blob/master/src/om/dom.cljs#L45
15:18Bronsajonasen: :var is +, :the-var is #'+
15:18dnolenbbloom: ha! untrue, most a lot of analysis stuff predates me
15:19bbloomdnolen: you're still a good guess for last person to show up in a git blame situtation :-)
15:19bbloomeggnoggin: that's the confusing part. it's just a convention for private protocol implementations
15:19Bronsabbloom: agreed
15:19bbloomeggnoggin: dash means nothing on it's own
15:19bbloomeggnoggin: the convention is -foo is the protocol method and you'd expect there to be a regular foo var
15:19eggnogginah okay so it is just a naming convention like *var*
15:19bbloomyeah
15:20bbloomunfortunately, it predates the .- syntax
15:20eggnoggindnolen: om looks awesome btw
15:20eggnogginwas pleasantly surprised that I could read and understand the entire implementation
15:20Bronsajonasen: so :the-var means (var something), :var means a symbol that resolves to a var
15:20bbloomeggnoggin: the exception to the rule however is this: https://github.com/swannodette/om/blob/master/src/om/dom.cljs#L43
15:20bbloomthe .. macro cheats a bit and parses the symbol
15:20dnoleneggnoggin: it's changed a bit, but it's still pretty straight forward
15:20bbloomi guess technically that works with . too: (. this -props)
15:21bbloombut the rule still applies: - means nothing on it's own, it's only when combined with .
15:21jonasenBronsa: got it. var is a special form which translates to an {:op :the-var} in the ast
15:21eggnogginhah, interesting
15:21eggnogginthanks bbloom
15:21bbloomnp
15:21bbloomi wish we had another character to use :-/
15:21Bronsabbloom: huh?
15:21Bronsauser=> (deftype x [a])
15:21Bronsauser.x
15:21Bronsauser=> (. (x. 1) -a)
15:21eggnogginbbloom: I met you at clj-west last year btw :)
15:21Bronsa1
15:22bbloomeggnoggin: if you don't tell me who you are, that just sounds creepy ;-)
15:22eggnogginwe had food truck eats together
15:22Bronsaoh, sorry, I misunderstood what you were saying
15:22bbloomah, i recall that, what's your name again?
15:22eggnogginThomas
15:22eggnogginanyhow, just a hat tip, thanks again
15:22bbloomcheers
15:23Bronsajonasen: I gotta go now, I'll be back in a couple hours, if you have any more questions query me and I'll reply when I come back
15:23Osumwhat am I doing wrong here
15:23Osumuser=> (defn myf #_=> [ m funs ] #_=> (loop [ ds m fun ( first funs) acc [] ] #_=> (if(empty? funs) #_=> acc #_=> (recur ds (rest funs) (cons acc (fun ds))) #_=> )))
15:24Osum#'user/myf
15:24Osumuser=> (myf '(1 2 3) [a b])
15:24OsumClassCastException clojure.lang.PersistentList cannot be cast to java.lang.Number clojure.lang.Numbers.minus (Numbers.java:135)
15:24Osumor is there a better way to do this
15:24S3thc0nbbloom: Ok, I think I see now.
15:24OsumI would like to apply a set of functions to a datastructure and obtain a concatenated list of the results
15:24bbloomthe first thing you're doing wrong is pasting unformatted blobs of code in to irc :-)
15:24llasramOsum: Well, first, use refheap.com or another paste service so we can see what you're doing
15:24Osumbblom : besides that :P
15:24Osumuser=> (defn myf
15:25nDuffOsum: how does this differ from juxt?
15:25coventryOsum: You need to recur on (rest funs), and take (first fun) inside the loop.
15:25Osumhttps://gist.github.com/fr0stbyte/7950783
15:26bbloomdnolen: why dyou need the ref "add" ?
15:26dnolenbbloom: oops I don't that was just testing ref capability
15:26bbloomdnolen: gotcha
15:26bbloomdnolen: really good solve the array problem :-)
15:26S3thc0nbbloom: By the way I really admire you helping everybody and having so much patience. :) Not to say others don't (thanks to those, too), I just have seen you hang around here quite a bit.
15:27OsumnDuff: juxt ?
15:27bbloomS3thc0n: i think you're the first/only person to ever describe me as having much patience
15:27dnolenbbloom: yep gonna put together an Iterator/PureIterator patch together for React
15:27coventry,(doc juxt)
15:27clojurebot"([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
15:27nDuffOsum: http://clojuredocs.org/clojure_core/clojure.core/juxt
15:27coventry~juxt
15:27clojurebotjuxt is the bestest option though if it doesn't weird you out
15:27bbloomdnolen: you gonna make the patch yourself? w00t
15:27dnolenbbloom: then we can just send sequences to React and om will wrap then in an iterator
15:27dnolenbbloom: I will yes when I get some time
15:28OsumnDuff : it's not . I didn't know about juxt
15:29bbloomdnolen: is data required to be a map?
15:29dnolenbbloom: no
15:29bbloomdnolen: well it has to support metadata, right?
15:29dnolenbbloom: it has to be IMeta
15:29bbloomok
15:30dnolenIWithMeta
15:30OsumnDuff : thanks, that works exactly like I needed to
15:30bbloomloving the #js
15:30dnolenbbloom: :)
15:31bbloomdnolen: i don't see where you do any dissoc-in or anything of the sort. how are you handling when stuff exists the dom?
15:31clojurebotCool story bro.
15:31S3thc0nbbloom: I now get why my entire point was completely invalid. If I undersood this correctly, the rest of a sequence of a vector will not be a list (that'd be so very unperformant).
15:31dnolenbbloom: what do you mean?
15:32dnolenbbloom: like removing stuff from the dom by dissoc-ing?
15:32dnolenor filtering something out?
15:32bbloomdnolen: i mean consider a path like [:counters 5]
15:32bbloomoh, those are atoms in the metadata
15:32bbloomhm
15:32bbloomi see
15:32bbloominteresting
15:33bbloomsorry, i thought you had a global state tree, but you have local state attached to the values
15:33bbloomnot sure how i feel about that
15:33dnolenbbloom: it's not local, that is the global atom
15:33bbloomoh, yeah then ok you have a memory leak :-P
15:33dnolenbbloom: by putting in the metadata we avoid dynamic binding and passing it around explicitly
15:33bbloomsure, but you need to handle lifetime of that data
15:34bbloomconsider if i make 1M counters, then delete them all
15:34bbloomyou'll have 1M counter states in your global atom
15:34bbloomthis is the lifetime management problem that react solves with state
15:35dnolenbbloom: I don't follow, if you delete something it will get collected
15:35dnoleneverybody shares the same atom
15:35dnolenthis is a DAG
15:36S3thc0nbbloom: If I am right all this casting I was thinking about never happens; and I maybe should just return the type I was given (vector -> vector, list -> list) (except if for performance reasons I would operate on a specific one of the two)?
15:36dnolenbbloom: we always rerender from the root, dead stuff gets blown away
15:38bbloomdnolen: oh sorry, i misread some of this a bit. thought the data had parallel state
15:39bblooms/parallel/isomorphic
15:40S3thc0nI have one question about Clojure datastructures left: What happens if no reference exists and that structure is then manipulated? Is a new one returned and the old one GCed (more in line with normal behaviour and simpler, maybe not as effective) or (ignoring immutability since it probably wouldn't grant any benefit) the old changed?
15:41coventryS3thc0n: Start here: http://hypirion.com/musings/understanding-persistent-vector-pt-1
15:41technomancyS3thc0n: what?
15:42bbloomS3thc0n: no, better yet, start here: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
15:42technomancyif no reference exists who's manipulating it?
15:42S3thc0nYeah, sorry. I'll giev an example fo what I mean.
15:42S3thc0n*give
15:42coventryHe means what happens to the old copy when you do something morally equivalent to update in place.
15:43nDuffS3thc0n: when that optimization is needed, it's available via transients.
15:43S3thc0nImagine (map inc [1 2 3]): Does [1 2 3] still exist alongside with [2 3 4] until GC gobbles it up or does [1 2 3] turn to [2 3 4] (I know there's also lazyness).
15:43S3thc0nnDuff: So not by default, but still possible?
15:43technomancysome manipulations share structure. map doesn't.
15:43bbloomS3thc0n: GC gobbles it up. the more interesting question is what happens when you (assoc (vec (range 10000)) 50 :x))
15:44bbloomS3thc0n: it's called structural sharing. watch the rich hickey video ^^
15:44S3thc0nbbloom: I know about that.^^ What i meant that you do not need the old structure if it is not known to anything else.
15:44bbloomS3thc0n: yeah, that's kinda the entire point of GC
15:45nDuffS3thc0n: ...right, and transients give you that, while doing some checking to ensure that there aren't any cross-thread references.
15:45S3thc0nNice, thanks for that info :)
15:45S3thc0nYou guys are great!
15:46nDuffS3thc0n: while dalvik is pretty awful at GCing lots of very small objects, the JVM is good enough at it that in a lot of common cases this isn't a pain point.
15:47S3thc0nnDuff: Yeha, I definitely won't employ it if I don't have to. Just was interested in that as a consequence of that 'new' (to me) immutability construct.
15:50nDuffS3thc0n: *nod*. The way things are implemented, one isn't copying (and discarding) big objects even when changing small parts of a large map or vector, so it stays pretty well within the JVM's sweet spot.
15:51expezWhy can a deref inside a transaction trigger a transaction retry?
15:51nDuffexpez: if you deref something, and it changes before you're committed, then your result isn't necessarily valid.
15:51nDuffexpez: ...since it's based on the old value.
15:52expezhow does altering the min-history and max-history change that situation?
15:52nDuffAhh.
15:53S3thc0nRight now and very often I think it is amazing how perfect CLojure fits the JVM. Oracle should just make Clojure the new main language of the JVM and make the resources becoming available available to Rich Hickey :b
15:53nDuffThat's a different case.
15:54nDuffexpez: if your transaction is anchored in an older version of state that isn't available any longer...
15:54hyPiRionWell, the JVM spec isn't that good for Clojure, really. The JVM implementations are, though.
15:54hyPiRionAlthough faster boot would be lovely.
15:55expeznDuff: the chapter in clojure programming makes it sound like the stm forgets the value at the start of the transaction and then offers the solution to keep all the states of the ref throughout the transaction. Why not just keep the first value which we need for camparison when committing?
15:56S3thc0nhyPiRion: There might come a time where a JVM will be permanently running anyway, and if you then precompile it should be quite fast, shouldn't it?
15:57hyPiRionyeah, but reality is that when you're developing, you end up having to reload the JVM from time to time.
15:57hyPiRionalso Leiningen
15:57nDuffexpez: I actually don't want to answer that one without checking against reference material; I'm not comfortable enough in my mental model to pretend to be authoritative.
15:57hyPiRionFor long-living processes, the boot times doesn't matter
15:57expeznDuff: aight, I can appreciate that. Thanks anyway!
15:58grauehi clojurists, what's a good way to read a binary file into memory in its entirety as a byte array? like 'slurp' for binary data
15:58S3thc0nhyPiRion: see what you mean, guess that is the price we got to pay for all the goodness^^
15:58graueevery suggestion i can find is either very low level and requires manually looping and reading in blocks; or refers to old stuff in clojure.contrib.io that doesn't seem to be around anymore
15:58ivanS3thc0n: all three approaches to changing Java code on the JVM (classloaders + class unloading, bytecode rewriting aka jrebel, DCE) have their problems
15:59technomancygraue: c.j.io/copy from an input-stream to a baos
16:01hyPiRionS3thc0n: Yeah, the JVM was the optimal choice because it's a good platform to bootstrap on (libraries, good perf). My comment related to Clojure being the main language of the JVM would certainly imply faster boot times for Clojure, but the underlying VM design isn't an "excellent" fit
16:01grauetechnomancy: thanks, assuming baos = ByteArrayOutputStream? will try
16:01hyPiRionGranted, no VM would be excellent except one designed for Clojure, so there's that.
16:03tbaldridgehyPiRion: and with a custom VM you loose one of the best JITs and GCs
16:03technomancygraue: yeah
16:03technomancyclojurebot: baos is ByteArrayOutputStream
16:03clojurebot'Sea, mhuise.
16:08hyPiRiontbaldridge: yeah, if not _the_ best JITter
16:09hyPiRionWell, I'd guess some JS impl could be faster?
16:09dsrxluaJIT is supposed to be pretty good
16:11andonilssonEmacs question: Is there a good way to get auto-complete work in clojure-mode?
16:11andonilssonCider gives me great auto-completion in the repl, and I would like the same in my source files. Googling "clojure auto completion in emacs" just gives me links about the repl, and not about the source files.
16:12sritchieandonilsson: ac-mode works well, I think
16:13sritchiedo you guys have any clue why "lein test" seems to be executing every test twice?
16:16hiredmansritchie: do you have symlinks?
16:16hiredmanI dunno, I guess that wouldn't do it
16:16hiredmansritchie: what makes you think they are running twice?
16:16hiredmansritchie: do you have some crazy fixtures?
16:16sritchiehiredman: I have a fixture in one spot, for schema
16:17sritchieI'm seeing printlns twice in a bare file
16:17sritchiethe real issue I'm debugging is this:
16:17sritchieCaused by: java.lang.ClassNotFoundException: taoensso.carmine.protocol.IRedisArg
16:17sritchieabout a protocol,
16:17sritchieand I'm worried that the tests are eval-ing a protocol twice
16:17sritchielet me try removing that fixture
16:18hiredmansritchie: is the file being loaded and run twice? or is it just each test running twice?
16:18sritchieit's a bare println, so the file's being loaded and run twice
16:19cmiles74andonilsson: I think ac-nrepl is what you're looking for. https://github.com/clojure-emacs/ac-nrepl
16:19sritchiealso, midje's future-fact forms are printing twice
16:19cmiles74andonilsson: It uses nrepl to build of the auto-complete list and then auto-complete to display the choices.
16:20coventrysritchie: Did you use :reload in any of your ns forms?
16:20dsrxI've gotta try ac-nrepl again
16:20sritchienope, nowhere
16:21andonilssoncmiles74: and that should work, not only in the repl-window, but also in my source-buffer? I have it installed already, but in that case I probably haven't configured it properly...
16:22sritchiecoventry: it only seems to happen before the tests start running
16:22cmiles74andonilsson: I believe it will *omly* work in the source files. It's using Cider to build up the list of completion options that it displays in your source code buffer.
16:23sritchiecoventry: one of them might make sense, since two namespaces require the namespace with hte println
16:23sritchiebut not the second call to future-fact
16:24cmiles74andonilsson: Do you have auto-complete installed? Like many bits of Emacs, it's spread all over. Cider for the options, ac-nrepl to supply the options to auto-complete and then auto-complete to display them.
16:24andonilssoncmiles74: yes, auto-complete is installed. adding some stuff to my .emacs right now. let's see if things get better...
16:26technomancysritchie: midje has some weird behaviour where stuff runs at compile time
16:26technomancynot a fan
16:27sritchieI'm running the facts as "lein test", though
16:27hiredmansritchie: oh, there is your problem, midje
16:28cmiles74anondilsson: It's working for me... It's been a while since I set it all up. Here's a link to me configuration on the off chance it's helpful in some way.
16:28S3thc0nIn 'Are We There Yet' Rich Hickey talks about possibly linking I/O to STM, is there anything in sight for that (either I am abd at googling or nothing is to be found), for example using STM to access an external database?
16:29sritchiehiredman: even without the midje runner,
16:30sritchieyou think midje is double requiring my files?
16:30coventryS3thc0n: STM hasn't turned out to be as big a deal as he expected back then. His talk "The Language of the System" talks about cross-machine co-ordination, though.
16:30hiredmansritchie: I wouldn't put it past midje
16:30sritchiehaha
16:30S3thc0ncoventry: Great, I'm minutes before starting that one. :)
16:30sritchiehiredman: I like midje for the mocking… is there a better lib I should be checking out?
16:30andonilssoncmiles74: thx for the help! got it working now. I was missing the setup of ac-nrepl in my .emacs
16:31hiredmansritchie: I dunno, I just use clojure.test
16:31technomancyclojurebot: mocking?
16:31clojurebotTitim gan éirí ort.
16:31cmiles74andonilsson: Good deal! You are welcome. :-)
16:31sritchiehaha, I knew it
16:31technomancyclojurebot: with-redefs?
16:31clojurebotwith-redefs is useful for mockin...
16:31cemericksritchie: It's mocking you? And you like it?
16:31hiredmanyeah lots of with-redefs
16:32sritchiemidje dogpile
16:34tbaldridge(inc clojure.test)
16:34lazybot⇒ 1
16:35technomancy(inc *1)
16:35lazybot⇒ 1
16:35technomancydoh
16:35technomancy(inc clojure.test)
16:35lazybot⇒ 2
16:36coventrylein test actually does a (require :reload) for each test namespace, so if the test namespaces are requiring each other, you could get duplicate evaluation from that.
16:37hyPiRiontechnomancy: you could implement (inc *1) for lazybot, that would save me a couple of characters from time to time
16:38amalloybut what if someone wants to give a karma boost to the *1 feature, hyPiRion?
16:38hyPiRionthen I'm sorry for their loss
16:39amalloy(inc '*1), clearly
16:49justin_smith(inc clojure.test)
16:49lazybot⇒ 3
16:51bitemyapp~midje is :(
16:51clojurebot'Sea, mhuise.
16:55bitemyapp~midje
16:55clojurebotmidje is :(
16:55bitemyappgood. GOOD.
16:56brainproxy~shared mutable state
16:56clojurebotshared mutable state is http://image.slidesharecdn.com/concurrencygotchas-100408105435-phpapp01/95/slide-7-728.jpg
16:56bitemyappbrainproxy: <3
16:57brainproxyalex miller (puredanger) put that together, but it makes me chuckle every time
17:07TimMc(inc midje) ;; sometimes
17:07lazybot⇒ 1
17:13sritchiecoventry: okay, that might be it
17:13sritchieyeah, I do
17:14sritchiecoventry: any way to turn that off?
17:14logic_progis there any "minimal apl written in clojure" blog post?
17:14sritchiemaybe I can refactor
17:15bitemyappTimMc: o_o
17:24sritchiecoventry: ugh, didn't help. still the double require.
17:24sritchiehmm
17:27sritchietechnomancy: is there an easy way to get leiningen to run tests on all tests in a subdirectory?
17:27sritchie"lein test some-glob", vs specifying thenamespaces directly?
17:27technomancysritchie: only if the subdirectory is a classpath root
17:28sritchieokay
17:28technomancyyou can write test selectors
17:28technomancybut they won't prevent the tests from being loaded, just run
17:28technomancyand iiuc with midje it's the loading that's problematic
17:29sritchiejust trying to narrow down the file that's doing this double loading
17:38sritchietechnomancy: odd - the double printlns don't happen if I manually include every single test namespace
17:38sritchiebut lein test by itself double-requires
17:41TimMcbitemyapp: I like some of the mocking in midje, and there are some nice destructuring matchers.
17:41bitemyappTimMc: *grumble should be just libraries grumble missing the grumble grumble point of Clojure grumble*
17:42TimMcYeah, I'd definitely be happier if it were more composable.
17:45sritchietechnomancy: I think I know what's happening
17:45sritchiecoventry: technomancy: I'm specifying my test-paths in the dev profile
17:45sritchieand I think lein test is merging the default test-paths with my specified ones
17:46technomancysritchie: yeah, you can use :test-paths ^:replace [...] if you don't want it to merge
17:47sritchieokay, that was it
17:47technomancynice object lesson in why it's nice to avoid side-effects at compile time though
17:48sritchie:)
17:49coventrysritchie: Maybe you could figure out what's requiring what by outputting a stack trace where your printlns are.
17:49sritchiecoventry: the issue was that leiningen was merging the default test-paths with my develop test paths;
17:49sritchieand then not unique-ing
17:50sritchietechnomancy: would unique-ing make sense?
17:50technomancysritchie: inside the test task, sure
17:51technomancyhappy to take a patch for that
17:52sritchiehttps://github.com/technomancy/leiningen/pull/1399
17:52technomancylightning fingers!
17:53technomancymerged
17:53hyPiRionI was sort of hoping Michael Klishin would come in and merge it in front of your eyes
17:54amalloy(inc hyPiRion)
17:54lazybot⇒ 26
17:54technomancyhehe
17:54sritchiehaha
17:54sritchiefastest merge in the west
17:55technomancygithub isn't showing enough granularity in timestamps to see if it was under 60s or not
17:56technomancyapparently it was
17:57technomancy51s ± timestamp skew
18:02sritchie:)
18:04sritchietechnomancy: does that earn me a sticker?
18:04technomancysure thing
18:04sritchieboom
18:04sritchieyears-long dream accomplished!
18:10eggnoggindnolen: where can I find org.clojure/clojurescript "0.0-2120" that om depends on?
18:11dnoleneggnoggin: it takes up to 24 hours to hit Maven Central
18:11eggnogginah, okey dokes
18:12eggnogginit's a real dep tho right? the older ones won't have the js reader literal?
18:12eggnogginhttps://github.com/swannodette/om/blob/master/src/om/dom.cljs#L29
18:17dnoleneggnoggin: yes real dep, first release w/ js reader literal
18:18eggnogginawesome, thanks
18:26dnolenlast dynamic var purged from om, life cycle methods now take the pure component as second argument
18:42augustlwhat am I doing wrong? https://www.refheap.com/21738 According to the reflection, the method exists.
18:43hiredmanaugustl: check the flags
18:44augustlah, it's a java type builder, and in java you can invoke static methods on instances directly. I guess you need to do something special to do that with Clojure?
18:44augustlthat = invoke a static method on an instance
18:45augustlaccording to the docs, you can do this in Java. OptionBuilder.withArgName("n").withDescription("Whatever").create()
18:45augustlnot sure how it actually manages to chain that to build it up when invoking static methods..
18:46hiredmanwell, withArgName most likely returns something that is not an OptionBuilder
18:46hiredmanso that .create() isn't a static method
18:46augustlwithArgName returns an OptionBuilder instance
18:47augustlaccording to the javadoc, they're all static methods
18:47augustlhttp://commons.apache.org/proper/commons-cli/javadocs/api-release/org/apache/commons/cli/OptionBuilder.html
18:47hiredmanOh, weird
18:47augustlI agree :)
18:48hiredmanthat must be terribly thread unsafe
18:48hiredmanhttp://stackoverflow.com/questions/12466955/java-apache-cli-optionbuilder-not-working-as-builder-pattern
18:49hiredmanit just mutates all these static fields
18:49hiredmanhttp://www.docjar.com/html/api/org/apache/commons/cli/OptionBuilder.java.html
18:49augustlhmm, the best I can think of now is harblfjgjgjgjgjgjg
18:50hiredmanfriends don't let friends, etc
18:52bitemyappI find that Java code is either not thread-safe, or the whole goddamn class is @synchronized and will choke your damn threads.
18:53bitemyappI blame JCIP.
18:55bitemyappand sometimes it'll end up not being thread-safe anyway because the authors didn't understand how synchronize works.
18:55justin_smithworst of both worlds
18:56bitemyappif you deploy performance/latency sensitive Clojure apps, as often as not, it'll be the Java code you're scrutinizing for thread starvation.
18:56technomancyclojurebot: j.u.c.?
18:56bitemyappNot the Clojure code. Unless you do something dumb.
18:56clojurebotExcuse me?
18:56technomancyaw come on clojuprebot
18:57bitemyapptechnomancy: https://www.google.com/search?q=java.util.concurrent&amp;oq=java.util.c&amp;aqs=chrome.0.0l3j69i57.2490j0j1&amp;sourceid=chrome&amp;ie=UTF-8
18:57technomancyclojurebot: juc?
18:57clojurebotTitim gan éirí ort.
18:57technomancyargh
18:57bitemyapptechnomancy: juc is half the reason people use Java.
18:57technomancyclojurebot: java.util.concurrent?
18:57clojurebotjava.util.concurrent is "When I find myself in times of trouble / Prof. Doug Lea comes to me / Coding lines of wisdom / j.u.c."
18:57technomancybots are hard
18:57bitemyapp...
18:58bitemyapptechnomancy: I didn't keep you out too late Weds did I?
18:58technomancybitemyapp: haha nah; got a good workout in while watching 70s doctor who
18:58bitemyappcool.
18:59technomancy80s doctor who, I guess
18:59technomancyhow time flies
19:07ProfpatschCan you import this dependency: http://search.maven.org/#search%7Cga%7C1%7Cmason ?
19:08ProfpatschI’m getting Could not find artifact gnujaxp:gnujaxp:jar:1.0.0 in central (http://repo1.maven.org/maven2/)
19:08mrcheeksProfpatsch: is it there?
19:09ProfpatschWell, mason downloaded without problem in Java & Intellij/Eclipse
19:09hyPiRionProfpatsch: Did you add [edu.gmu.cs/mason "14.0"] into your dependency list?
19:09Profpatsch[edu.gmu.cs/mason "14.0"]
19:09ProfpatschYeah, exactly like that.
19:10ProfpatschWhen I comment it out with #_, there is no error, so it has to be this one.
19:11hiredmanProfpatsch: it sounds like they published a library to central with a dependency on something that is not in central, which is sad
19:12hiredmanProfpatsch: try adding replacing [edu.gmu.cs/mason "14.0"] with [edu.gmu.cs/mason "14.0" :exclusions [gnujaxp]]
19:12mrcheeksnot a clojure, but can't you exclude that transitive dependency?
19:12mrcheeksProfpatsch: what hiredman said ^^
19:12hiredmangnujaxp is most likely not something you should have an explicit dependency on anyway
19:13mrcheeksindeed
19:13ProfpatschAnd Intellij IDEA is too stupid to notice?
19:13mrcheeksnot really about Intellij..
19:13hiredmanthe devs of edu.gmu.cs/mason must have put a dependnecy on it
19:13hyPiRionIf the error persists, JFreeChart is the one with the transitive dependency. I would guess updating the JFreeChart dependency may solve the issue too
19:13ProfpatschJust imported it again, no errors, no warnings http://i.imgur.com/M2C72c8.jpg
19:14hiredmanhyPiRion: weird
19:14hyPiRionAlthough the JFreeChart guys say it's not them putting up stuff on the Mave Central, so
19:14davALL - any reason why this doesn't work? (defmacro blah! [x] (swap! x conj "yo")) (def y (atom [])) (blah! y) ; getting ClassCastException clojure.lang.Symbol cannot be cast to clojure.lang.Atom clojure.core/swap!
19:14hyPiRionhttp://www.jfree.org/phpBB2/viewtopic.php?f=7&amp;t=26653 <- from 2009
19:15hiredmanoh, yeah, so a really old version of jfreechart
19:15technomancydav: macros must return a list
19:15justin_smithdav: macros are about building the list you need
19:15hiredmantechnomancy: that is not true
19:15technomancyhiredman: it's a convenient lie
19:15davtechnomancy: list meaning code?
19:15justin_smiththat code can just be a function, but to make it a macro you need to build the list that becomes the code
19:15davjustin_smith: ok thx
19:16justin_smith(doc `)
19:16hyPiRiondav: the values given to a macro is not evaluated, it actually tries to swap! on the quoted symbol y
19:16clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
19:16davfixed it thanks all
19:16dav(defmacro blah! [x] `(swap! ~x conj "yo")) (def y (atom [])) (blah! y)
19:16justin_smithstill doesn't need to be a macro, but sure
19:17davyes I know I need it to be a macro for other reasons
19:17davthanks for the help
19:22Profpatschhiredman: Thanks, it seems that worked
19:22amalloyi feel like if you're asking why that macro doesn't work, it's not 100% clear that you're right about whatever other thing needing to be a macro for other reasons
19:23Profpatschhiredman: How would I refer to it? (:require [mason.foobar]) or (:require [edu.gmu.cs.mason.foobar])?
19:23davamalloy: I need to traverse code and modify it in some other part of the macro..
19:24hiredmanProfpatsch: the maven artifact name has little to do with what namespace / classes are there to use
19:24bitemyappnoprompt: you still have a shirt sitting on my office desk.
19:24hiredmanProfpatsch: so check the docs or crack open the jar
19:25hyPiRionProfpatsch: additionally, if the dependency is a java dependency, you should use `import` instead of `require`
19:25ProfpatschhyPiRion: I can only require clojure namespaces, right?
19:25hyPiRionright
19:29Profpatschhiredman: Hm, I don’t get it. Here’s the packages in mason: http://i.imm.io/1mdIZ.jpeg
19:30Profpatschhiredman: e.g. there is sim.engine.SimState
19:30Profpatschhiredman: What do I have to specify to import that Class?
19:32hiredmanProfpatsch: have you read an introductory clojure material?
19:32hiredmanhttp://clojure.org/jvm_hosted
19:33ProfpatschYes, but it didn’t seem to work. But I guess I made a mistake in evalling that namespace.
19:35Profpatschhiredman: Shouldn’t that be good: (:import sim.engine.SimState)
19:36ProfpatschClassNotFoundException sim.engine.SimState java.net.URLClassLoader$1.run (URLClassLoader.java:366)
19:36hyPiRionProfpatsch: example here https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/eval.clj#L12-L13
19:36hiredmanProfpatsch: depends on how you are doing it
19:37hiredmanif that is in (ns … …) it should, if not, then you would get that exception
19:42ProfpatschUUUUUGGGGHHH. Simple solution: I had to restart my repl after doing `lein deps`.
19:42hiredmanyep
19:42ProfpatschSomething with the classpath I guess. Is there a way to do this without restarting?
19:43amalloyProfpatsch: no, although you don't really have to run lein deps
19:43ProfpatschI don’t?
19:43llasramProfpatsch: https://github.com/pallet/alembic ?
19:43hyPiRionProfpatsch: lein fetch dependencies and add them to the classpath automatically
19:44bitemyapphttps://github.com/clojuredocs/guides/issues/153
19:44amalloyyou really never need to run lein deps. it's like the Door Close button on elevators: just there to make you feel better
19:44hyPiRionIt is possible to add deps through e.g. pomegranate, although you rarely add dependencies to a project
19:45ProfpatschWell, since I’m starting out and experimenting a lot, it is really discouraging if stuff doesn’t work and I have no idea why.
19:45bitemyapphyPiRion: alembic is nicer than pomegranate for that.
19:45bitemyappI have a macro for injecting: "(require '[alembic.still :as alembic]) (alembic/load-project)"
19:52bitemyappnoprompt: http://chimera.labs.oreilly.com/books/1230000000929/index.html
20:02logic_progis there a nice way to use nrepl, clojure, and clojure.tools.reload in the folowing sitatution: the source code is stored on machine "laptop"; the clojure server is running on machine "server"; the source code is only stored on "laptop" and not on "server"
20:07justin_smithlogic_prog: what I do in that case is put source on server, and edit from laptop via tramp
20:08justin_smithtramp works nice, if you can handle emacs
20:08justin_smithotherwise there is also sshfs
20:11logic_progjusting_smith: yes, I'm using emacs + tramp, however I want to check my code into git
20:11logic_progjustin_smith: and I'm not sure I want to put git credentials on this particular server
20:11justin_smithyou can use git in password mode
20:13justin_smithalso, this is weird, but you could rsync from remote, then check it into git locally
20:13justin_smithno reason that would not work, though it is an odd workflow
20:14justin_smithor do it the other way, pushing the code to server with rsync
20:14justin_smithbut I don't see how running code not on the machine would work
20:15logic_prognrepl-send buffer
20:15logic_progallows me to send a buffer to the nrepl server
20:15justin_smithfor the entire codebase?
20:15justin_smithI guess
20:15logic_progso if the nrepl server is running on a remote machine, it's fine
20:16coventryYou could also have credential-free git on the server, then when you want to publish git clone that on the laptop, and git push from there.
20:16justin_smithlogic_prog: the problem there is the require statments, you would need to reverse engineer the deps
20:17logic_progjustin_smith: you're right
20:17logic_progI'm being an idiot, rever sengineering the deps would be messy
20:17logic_progI'll just send code to the server and live code there.
20:17logic_progyou know what else would be badass? reverse ssh
20:17logic_progerr. reverse sshfs
20:17logic_progif I can publish a local directory (on "laptop") to a directory (on "server") over ssh
20:18justin_smithyou could also have the repo in a mounted encrypted image on remote
20:18logic_progbut it's 'rever sshfs" since the ssh server is running on "server" and the ssh client is on "laptop"
20:18justin_smithmount -o loop etc.
20:18logic_progjustin_smith: mounted encrypted image on remote? how does that work?
20:19justin_smithhttp://www.techrepublic.com/blog/linux-and-open-source/create-encrypted-loopback-filesystems-on-linux/
20:19justin_smitha random file can act as a disk image, which is encrypted
20:19justin_smithand you can mount it wherever, use it as if it were an external device, unmount when done
20:19justin_smithif your concern is about what you store on the server
20:20justin_smithby random file I mean a large enough file to emulate all the storage for a block device, it is not file by file encryption
20:44coventryIn the "reverse sshfs" category, you could make a local webdav server, forward that over ssh to the server and mount it there. There might even be a way to tell it not to publish .git directories.
20:44coventryAnyway, not clojure anymore.
22:02sritchiebitemyapp: so, QQ -
22:03sritchiebitemyapp: about logging and monitoring zen :)
22:10devnThe wu wei.
22:32Osumhow do I use clojure.contrib.math in my project ?
22:32Osumadding [org.clojure/clojure.contrib.math "1.1"] to project.clj results in a bunch of errors
22:37gunsOsum: http://dev.clojure.org/display/doc/Clojure+Contrib+Libraries
22:37guns-> https://github.com/clojure/math.numeric-tower
23:32cljrwow, once you get used to threading swquences through multiple functions using 0> it gets hard to use any other languages...sounds stupid, but it is so simple but powerful
23:32cljr0> i mean
23:32cljr-> ....
23:34ivanhttp://stackoverflow.com/questions/4961017/clojure-style-function-threading-in-python
23:34Raynescljr: Doesn't sound stupid at all. I've wanted it in both Go and Python on several occasions.
23:34Rayneswhat
23:34Raynesivan: It's like you read my mind.
23:35cljrit is just refreshing to get away from dealing with objects and really just getting to something akin to pipes
23:35ivanyou'll be f1(f2(f3'ing for a long time if your Python code is being read by anyone else
23:35ToBeReplacedivan: not quite what you want but hy does this
23:35cljrgoing from one value to another, each step just applying a different function
23:36ivanToBeReplaced: yeah, saw that in hy a while ago
23:37ivanhttps://github.com/hylang/hy/blob/master/hy/core/macros.hy#L82
23:42cljrOk, im a bit stuck here
23:43cljr,0xff
23:43clojurebot255
23:43cljr,0x00
23:43clojurebot0
23:43cljr,(char 0x00)
23:43clojurebot\
23:43cljr,(char 0xff)
23:43clojurebot\�
23:44cljr,(apply str (repeat 10 (char 0xff)))
23:44clojurebot"����������"
23:44cljr,(apply str (repeat 10 (char 0x00)))
23:44clojurebot"
23:47ivanpoor clojurebot can't send a NULL over IRC
23:47clojurebotHuh?
23:53cljrhmm, does anyone know how i can go from "127" to 0x7f
23:54cljri though i had it with (Integer/parseInt "127 16), but nope
23:54amalloycljr: to 0x7f the byte value, or "0x7f" the string?
23:54cljrbyte value
23:55ivan,(= 0x7f (Integer/parseInt "127"))
23:55amalloythen...that's just 127
23:55clojurebottrue
23:55cljrjesus
23:55amalloy0x7f is not different in any way
23:55cljrim not sure why i was doing what i was doing
23:56cljramalloy: thanks for your work on the aleph docs, btw
23:56guns,2r01111111
23:56clojurebot127
23:56amalloyoh, you're welcome. i didn't think i had actually done very much
23:56amalloyjust a bit on the query language thingy
23:57cljrOk, you are just the most recent edit i guess, your name is at the bottom of quite a few of the pages