#clojure logs

2015-06-11

00:00gkocfleming: CSV integration?
00:01cfleminggko: Right. If you're using CLJS I'm hoping to integrate more tightly with all that stuff, but right now I don't. So it would just be the support for the things you mention. Essentially the standalone Cursive will be like the Community edition with the plugin installed and some stuff stripped out, and a much nicer getting started experience (no faffing with keymaps etc).
00:04gkocfleming: OK, not doing CLJS anyway... what will be the licence fee? like rubymine/pycharm?
00:04cfleminggko: Not 100% determined but I think so, yes.
00:05gkocfleming: OK... so companies/organizations + individual developers, then...
00:05cfleminggko: Right.
00:08gkocfleming: OK. Nice work, as it really helped doing some project when cider was somewhat unreliable on my side for a while.
00:08cfleminggko: Thanks, I'm glad it's working well for you!
00:14cfleminggko: There's lots of nice functionality in yesterday's release if you're using Java interop, too.
00:26gkocfleming: haven't been using it in a while, but will soon be :)
01:50mercwithamouthdoes anyone actually use 'complement'?
02:01TEttingermercwithamouth, yeah it's a bit verbose for what it does.
02:01TEttingerI can see it being useful
02:02Kneivamercwithamouth: https://github.com/search?utf8=%E2%9C%93&q=complement+extension%3Aclj&type=Code&ref=advsearch&l= There are uses of it.
02:04mercwithamouthTEttinger: hmmm
02:04mercwithamouthKneiva: touche...
02:05TEttinger,(def anti complement)
02:05clojurebot#'sandbox/anti
02:05Kneiva,(anti nil? nil)
02:05clojurebot#error {\n :cause "Wrong number of args (2) passed to: core/complement"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/complement"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox$eval47 invoke "NO_SOURCE_FILE" 0]\n [clojure.lan...
02:06Kneiva,((anti nil?) nil)
02:06clojurebotfalse
02:06TEttinger,(map (anti nil?) (repeatedly 5 #(rand-nth [:a 1 nil])))
02:06clojurebot(true true false false true)
02:07TEttingerthe problem is, we already have both filter and remove
02:08TEttinger,(filter (anti nil?) [1 2 3 nil 5 6 7 nil 8])
02:08clojurebot(1 2 3 5 6 ...)
02:08TEttinger,(remove nil? [1 2 3 nil 5 6 7 nil 8])
02:08clojurebot(1 2 3 5 6 ...)
02:08TEttingerso primarily you want complement for stuff like partial and comp
02:09TEttingerpassing a complex fn to filter or remove, that sorta thing
02:23TEttinger,'''a
02:23clojurebot(quote (quote a))
02:24TEttinger,'a
02:24clojurebota
02:24TEttingerhm
02:30WickedShellAs a general theory question for someone who's really new to clojure how worried about chasing down all instances of reflection (ie adding type hints). I've just spend the last half hour fixing various reflection warnings, but outside of a warm fuzzy (and one that I think paid off for performance) is it worth usually running with the warnings and fixing as they happen?
02:46TEttingerWickedShell: mostly you only need to care about reflection in code that is called very frequently
02:47TEttinger$google ztellman primitive-math
02:47lazybot[ztellman/primitive-math · GitHub] https://github.com/ztellman/primitive-math
02:47TEttingerexcellent lib that will make you cry :)
02:49WickedShellYeah, my only real worry is that I have a GUI that needs to do a fair amount of redrawing on a limited processor...
02:49WickedShellThat primitive math... Does it just repleace all the standard math functions with optimized ones?
03:47kaphello guys...a newbie question...
03:48kapI have a (defmulti fetch :kind) that troubles me
03:48kapIllegalArgumentException Wrong number of args passed to keyword: :kind clojure.lang.Keyword.throwArity (Keyword.java:97)
03:48kapWhat does it mean?
03:48kapI call it like so:
03:49kap(fetch {:kind :mine} )
04:00amalloykap: restart your repl. there's a stale defmulti from earlier
04:01kapI did it, but it still doesn't take it...
04:03kapI am testing with midje and autotest, maybe that can be the problem?
04:03kap(defmethod fetch ::network [url-or-path options] ...)
04:03kaplooks ok to me...
04:04amalloykap: okay so you apparently do not call it like (fetch {:kind :mine}) like you said
04:05amalloyyou call it like (fetch {:kind :mine} some other junk)
04:05kapyep sorry is (fetcher/fetch {:kind :mine} "" {})
04:05amalloyso, to dispatch, it is calling (:kind {:kind :mine} "" {})
04:05amalloywhich is clearly a problem
04:05kapit dispathes on the first param no?
04:06amalloyno
04:06kaplol that's the newbie problem then
04:06kap:D
04:07kaptherefore I need to change my dispatch fn and accept three params?
04:07amalloykap: generally when you have a problem you don't understand, it's great to provide a minimal reproducible example. but that only works if it's actually reproducible: if you edit your code to something simpler that you *think* would cause the same problem, you should test it first to see if that still has the problem you're asking about
04:08amalloyanyway, yes, you should do that
04:08kapagree and I apologise..
04:08kapok thanks for your help...I was banging my head on the floor
04:09kungiIs there some kind of print friendly datomic documentation out there? There does not seem to be any on docs.datomic.com
04:14ionthas_Is there any function like repeatedly but taking functions with side effects?
04:16TEttinger,(dorun (repeatedly 5 #(print "hi! ")))
04:16clojurebothi! hi! hi! hi! hi!
04:17mercwithamouthhas anyone gotten flycheck to work with clojure?
04:19mercwithamouthi'm looking at squiggly-clojure but haven't tested it out yet...
04:37ionthas_thanks Tettinger!
04:37TEttingerno prob!
06:06jonathanjis there an alternate spelling of (not (nil? x))?
06:06lumafi(some? x), introduced in clojure 1.6
06:08jonathanjthanks :)
06:10l3dxwhy would you use (when (some? x) ..) vs (when x ..) ?
06:12lumafithe first one checks if x is not nil, the second one checks if x is not nil nor false
06:20ionthas_I have a function that outputs a number based on a provability. I want to do "something" that takes that function and calculates the provability of the function repeating that function a certain number of times. Do I need a macro or a function? (I'm starting with macros)
06:21ionthas_and I'm a little confused
06:23ionthas_I implemented a macro and it seems to work. I will stick to the macro for the moment. :P
06:23l3dxlumafi: I usually use the second approach when I expect sequences, and i don't see a case where I could get either nil, false or a sequence? but I'm a clojure beginner, so what do I know :)
06:28kwladyka(println (str "AAAAAAAAAAA" (get-in req [:params :terms]) "BBBBBBBBBBBBBB")) return AAAAAAAAAAABBBBBBBBBBBBBB in case when :terms doesnt exist, shouldnt be AAAAAAAAAAAnilBBBBBBBBBBBBBB?
06:29TEttingerkwladyka: do you want the empty string as a default?
06:29TEttinger,(println (str "AAAAAAAAAAA" (get-in {:params []} [:params :terms] "") "BBBBBBBBBBBBBB"))
06:29clojurebotAAAAAAAAAAABBBBBBBBBBBBBB\n
06:30TEttingerget-in takes an optional argument as its last arg, so does get
06:30lumafi,(str nil)
06:30clojurebot""
06:30TEttingerthis is the default return if it can't find what you ask for
06:30TEttingerhm!
06:30lumafistr of nil isn't "nil", it's the empty string
06:30TEttinger,(str nil nil)
06:30clojurebot""
06:30TEttinger,(println (str "AAAAAAAAAAA" (get-in {:params []} [:params :terms] "nil") "BBBBBBBBBBBBBB"))
06:30clojurebotAAAAAAAAAAAnilBBBBBBBBBBBBBB\n
06:30clgv,(pr-str nil)
06:30clojurebot"nil"
06:30TEttingerthere you go :)
06:31clgv(format "%s" nil)
06:31clgv,(format "%s" nil)
06:31clojurebot"null"
06:31clgvback to Java ;)
06:31TEttingerinteresting
06:32escherizeyeah you can do these two exercises to see it in action: http://clojurescriptkoans.com/#maps/5
06:39clgvI guess aleph + gloss is the best method to do tcp in Clojure, isn't it? Do you know of serious alternatives?
06:53kwladykaTEttinger, oh thx!
06:55TEttingerand clgv, who has a better solution!
06:55TEttinger,(pr-str "AAAAAAAAAAA" (get-in {:params []} [:params :terms]) "BBBBBBBBBBBBBB"))
06:55clojurebot"\"AAAAAAAAAAA\" nil \"BBBBBBBBBBBBBB\""
06:55TEttingerhm
06:56TEttinger,(pr "AAAAAAAAAAA" (get-in {:params []} [:params :terms]) "BBBBBBBBBBBBBB"))
06:56clojurebot"AAAAAAAAAAA" nil "BBBBBBBBBBBBBB"
06:57kwladykathis AAAA and BBB was to help me see the value.... ironic :)
06:57kwladykai watned see it is nil or empty string :)
06:58TEttingeroh ok
06:58TEttinger,(pr nil)
06:58clojurebotnil
06:58TEttinger,(print nil)
06:58clojurebotnil
06:58TEttinger,(str nil)
06:58clojurebot""
06:58TEttinger,(pr-str nil)
06:58clojurebot"nil"
06:59TEttinger,(print nil nil "hey!")
06:59clojurebotnil nil hey!
06:59TEttingerhm.
06:59TEttingerprint and str act differently
07:10TMA,(str 't)
07:10clojurebot"t"
07:11TMAnil is a special case apparently :-L
07:11TEttinger,(str ())
07:11clojurebot"clojure.lang.PersistentList$EmptyList@1"
07:11TEttingerwow
07:11TEttinger,(str (1))
07:11clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval73 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval73 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [c...
07:11TEttinger,(str [])
07:11clojurebot"[]"
07:12TEttinger,(str (()))
07:12clojurebot#error {\n :cause "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval121 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval121 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojur...
07:12TEttinger,(str '(()))
07:12clojurebot"(())"
07:12TEttingerweird
07:13TMA,(str :keyword)
07:13clojurebot":keyword"
07:24justin_smithTEttinger: ##() has always been valid
07:24lazybot⇒ ()
07:25TEttingeri know
07:25TEttingerbut ##(str ())
07:25lazybot⇒ "clojure.lang.PersistentList$EmptyList@1"
07:25TEttingeris a weird string
07:25justin_smithahh
07:25TEttinger,clojure.lang.PersistentList$EmptyList@1
07:25clojurebotclojure.lang.PersistentList$EmptyList
07:26TEttinger,clojure.lang.PersistentList$EmptyList@2
07:26clojurebotclojure.lang.PersistentList$EmptyList
07:26TEttinger,clojure.lang.PersistentList$EmptyList@0
07:26clojurebotclojure.lang.PersistentList$EmptyList
07:26TEttingerwhat is the @1 then?
07:26mearnshhaving some trouble with this function here https://www.refheap.com/102426 : as you can see i'm shelling out to a program (csvmidi) but it's returning an error that suggests the file written in the preceeding line is incomplete. if i print tmp-path and manually invoke csvmidi afterwards, it completes successfully, so i guess sh is called before write-csv completes. any clues on what to do?
07:26justin_smithTEttinger: it's the specific instance of EmptyList I think?
07:26clgvTEttinger: identifiying the instance
07:26TEttingerah
07:26TEttingermearnsh, I haven't looked yet, sounds like it could be a laziness thing
07:27justin_smithTEttinger: not unless write-csv is lazy
07:28clgvor it uses a future or similar
07:28justin_smithlooks like neither https://github.com/clojure/data.csv/blob/master/src/main/clojure/clojure/data/csv.clj#L123
07:29clgvah might be cashing since the writer is not closed
07:29clgv*caching
07:29mearnshthat sounds about right
07:30clgvmearnsh: wrap the with-open only around write-csv
07:30justin_smithoh yeah, the file is not guaranteed to exist on disk until you exit that with-open block I think
07:30clgvjustin_smith: yeah, you'd need to call "flush" or similar on it
07:30mearnshclgv: of course, that works. thanks all!
07:30clgvor just close it, since it is not used anymore
07:30justin_smith(inc clgv)
07:30lazybot⇒ 43
07:31clgvdamn. now the 42 is gone. I guess I have to insult someone to get back to it ;)
07:36TEttinger(inc clgv)
07:36lazybot⇒ 44
07:36TEttingerwe'll get you to some other number soon enough
07:36clgv:P
07:42gfredericks45 is a triangular number
07:42justin_smithsee, that's something to aspire to
07:44clgvhmm is there an english word that combines the meaning of "computable" and "predictable"?
07:45clgvI'd have needed that for an answer ;)
07:45TEttinger,(reductions #(+ % (* 6 %2)) 1 (range 10))
07:45clojurebot(1 1 7 19 37 ...)
07:45TEttinger&(reductions #(+ % (* 6 %2)) 1 (range 2 10))
07:45lazybot⇒ (1 13 31 55 85 121 163 211 265)
07:45TEttingerah, 55 is a hexagonal number
07:45TEttingeror something?
07:45TEttingeris it?
07:46TEttinger&(reductions #(+ % (* 6 (Math/pow 2 %2))) 1 (range 1 10))
07:46lazybot⇒ (1 13.0 37.0 85.0 181.0 373.0 757.0 1525.0 3061.0 6133.0)
07:46TEttingermaybe not
07:46TEttingerthat... hm
07:46clgvtriangular refers to side length relation of a rectangular triangle ;)
07:46TEttinger&(reductions #(+ % (* 6 (Math/pow 2 %2))) 1 (range 0 10))
07:47lazybot⇒ (1 7.0 19.0 43.0 91.0 187.0 379.0 763.0 1531.0 3067.0 6139.0)
07:47TEttingerreferring here to the series of hexagonal tilings where you add concentric hexagons
07:47TEttinger1 hex, add a hex to all adjacent open cells, get 7 hexes
07:48TEttingeradd a hex to all open, +12
07:48TEttingerthe next set I think is +24
07:48clgvah well or maybe not, http://en.wikipedia.org/wiki/Triangular_number - tricked by translation :P
07:52gfredericksclgv: "deterministic" might be related
07:52TEttinger&(map #(inc (* (dec %) (/ (* 6 %) 2))) (range 1 20))
07:52lazybot⇒ (1 7 19 37 61 91 127 169 217 271 331 397 469 547 631 721 817 919 1027)
07:53TEttingerso next centered hexagonal number is 61
07:53TEttingerhttp://en.wikipedia.org/wiki/Centered_polygonal_number
07:54clgvgfredericks: I wanted to write a play of words ;)
07:55TEttinger(identity clgv)
07:55lazybotclgv has karma 44.
07:55TimMc&(take 10 (reductions + (range)))
07:55lazybot⇒ (0 1 3 6 10 15 21 28 36 45)
07:55TEttingerone off of an interesting sequence! http://oeis.org/A144974
07:57TEttingerwow, some odd factoids Calculating Ramanujan's tau function on a centered octagonal number yields an odd number, whereas for any other number the function yields an even number.[2]
07:57justin_smithfactoids?
07:57justin_smithCalculating Ramanujan's tau function on a centered octagonal number |yields| an odd number, whereas for any other number the function yields an even number.
07:58justin_smith~Calculating Ramanujan's tau function on a centered octagonal number |yields| an odd number, whereas for any other number the function yields an even number.
07:58clojurebot'Sea, mhuise.
07:58justin_smith
07:58justin_smith~Calculating Ramanujan's tau functon on a centered octagonal number
07:58clojurebotI don't understand.
07:58justin_smith:P
08:11clgvCalculating Ramanujan's tau functon on a centered octagonal number?
08:11clgvdamn I thought it reacts to that
08:11clgvclojurebot: Calculating Ramanujan's tau function on a centered octagonal number |yields| an odd number, whereas for any other number the function yields an even number.
08:11clojurebotA nod, you know, is as good as a wink to a blind horse.
08:12clgvCalculating Ramanujan's tau functon on a centered octagonal number?
08:15TEttingerawww
08:16TEttinger~Calculating Ramanujan's tau functon on a centered octagonal number
08:16clojurebotCool story bro.
08:16TEttinger:|
08:16TEttinger~Calculating Ramanujan's tau functon on a centered octagonal number?
08:16clojurebotTitim gan éirí ort.
08:16clgvfactoids |are| broken.
08:16clgvclojurebot: factoids |are| broken.
08:16clojurebot'Sea, mhuise.
08:16clgv~factoids
08:16clojurebotfactoids are broken.
08:16TEttingerheh
08:16clgv:/
08:17clgvclojurebot: factoids |are not| broken.
08:17clojurebotOk.
08:17clgv~factoids
08:17clojurebotfactoids are broken.
08:17clgvclojurebot: forget factoids |are| broken.
08:17clojurebotI forgot that factoids are broken.
08:23wasamasais there a way for me to quote a comma?
08:23wasamasa'\, gives me a string ._.
08:23justin_smithwasamasa: commas are whitespace
08:23justin_smith,'\,
08:23clojurebot\,
08:23justin_smiththat's a character
08:24justin_smith,',foo
08:24clojurebotfoo
08:24justin_smith,',,,,,,foo
08:24clojurebotfoo
08:24wasamasaright, a character
08:24wasamasaso I can't have , as symbol?
08:24clojurebotCool story bro.
08:24justin_smith,(symbol ",")
08:24clojurebot,
08:24justin_smithbut don't do that
08:24justin_smithit's weird
08:24justin_smith,(symbol " ")
08:24clojurebot
08:24wasamasaI'll tell
08:25justin_smithhaha
08:28clgv,(intern *ns* (symbol ",") 42)
08:28clojurebot#'sandbox/,
08:28clgvgood luck using that symbol ;)
08:28justin_smith,@(resolve (symbol ","))
08:28clojurebot42
08:28clgvpssst! that was a puzzle ;)
08:30justin_smith,(intern *ns* (symbol "  ") '☃)
08:30clojurebot#'sandbox/ 
08:32clgv,(def ☃ 42)
08:32clojurebot#'sandbox/☃
08:32clgv,(+ ☃ ☃)
08:32clojurebot84
08:33clgvjustin_smith: http://www.emojilisp.com/prog/MzgPNAScXec81CsB
08:33justin_smithhah, I had forgotten that one
08:34justin_smith,@(resolve (symbol "  "))
08:34clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [clojure.core$deref_future invoke "core.clj" 2184]}]\n :trace\n [[clojure.core$deref_future invoke "core.clj" 2184]\n [clojure.core$deref invoke "core.clj" 2205]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.ja...
08:38m1dnight_https://gist.github.com/spacemanaki/1093917 This is the ant problem of Rich Hickey. Can anyone think of a reason why he doest not put the entire ant struct in the agent and just the location?
08:38m1dnight_I cant see any reason why not to do it.
08:38justin_smith,(ns-publics 'user)
08:38clojurebot{}
08:39m1dnight_Oh, perhaps to make drawing them easier!
09:00clgvjustin_smith: the "session" expired - you have to intern it again ;)
09:01clgvm1dnight_: I think that one qualifies as quick hack - it violates several clojure best practices starting with all the awful global defs
09:12bluebirdhi - i'm playing around with learning macros - can anyone help me with this short macro? https://www.refheap.com/102430
09:13clgvbluebird: you have to build lists then
09:13clgvbluebird: (map #(list 'inc %) coll)
09:14clgvbluebird: or usually a better idea: (map #(list `inc %) coll)
09:14wasamasabluebird: you're placing the symbol coll in there, not the collection
09:14clgv,(defmacro m [coll] `(or ~@(map #(list `inc %) coll)))
09:14clojurebot#'sandbox/m
09:15clgv,(macroexpand-1 '(m [1 2 3]))
09:15clojurebot(clojure.core/or (clojure.core/inc 1) (clojure.core/inc 2) (clojure.core/inc 3))
09:15bluebirdclgv: ahh ya perfect
09:15bluebirdclgv: thanks!
09:40justin_smithbluebird: the weird part is that you will always either get an NPE or the first number
09:40justin_smithbluebird: unless that was just an example of course
09:40justin_smith,(or 0 1)
09:40clojurebot0
09:41bluebirdjustin_smith: ya it was just an example
09:41justin_smithsome people expect 0 to be falsey
09:45pingwHello
09:46pingwI have a question about using clojure with mongodb asynchronously
09:47j-pbpingw: good for you ;), it' generally easier to just ask it
09:48pingwj-pb: im trying to think how to phrase this
09:48j-pbah ok :)
09:48pingwI cant find anything when I google something like 'clojure monger async'
09:48pingwdoes this mean that monger is synchronous?
09:49pingwso if I make some kind of database query, the application will block until the database server responds?
09:50justin_smithmongo has multiple synchronization rules, the default for monger should be the same as for mongo
09:50justin_smithwhich is "proceed as if insertion succeeded"
09:51pingwjustin_smith, what if you query the database
09:51pingwwill the clojure application block until it responds?
09:51justin_smithin all my usage, yes
09:51justin_smithit's easy to put your read in a future of course
09:52pingwOh, thats what I was looking for
09:52justin_smith(doc future)
09:52pingwso async is achieved using futures?
09:52pingwok
09:52clojurebot"([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block, unless the variant of deref with timeout is used. See also - realized?."
09:52justin_smithpingw: that's one kind of async
09:52justin_smiththere is also core.async
09:52justin_smithand agents
10:55bluebirdI don't think I'm understanding something about how macros work: https://www.refheap.com/102433 anyone know which piece of the puzzle i'm missing? just a toy example
10:59clgvbluebird: marcos are executed at compile time and they get unevaluated arguments - hence you can't get access to the numbers bound in the `let`
11:00clgvbluebird: that example of yours is getting weirder anyway. what are you trying to accomplish?
11:00bluebirdclgv: nothing, just playing around. so you can't use macros inside of let bindings?
11:01clgvbluebird: you can. but you can't expect the macro to see the values bound to the symbol
11:02clgvbluebird: you could construct code using that symbol such that the computation using those values is performed at runtime
11:02bluebirdclgv: what are you referring to with `symbol`?
11:02clgvbluebird: your example has the problem, that it seems to be a task that does not need a macro ;)
11:03clgvbluebird: "nums"
11:03bluebirdclgv: ya, I'm just messing around trying to learn macros because normally I never use them.
11:03clgvbluebird: ok, you pass more than the symbol, the form `(rest nums)` - but the reason remains the same
11:04clgvbluebird: then try to build control flow macros
11:04clgvbluebird: thats a valid use case and you can pick simple control flows
11:05bluebirdclgv: ya I guess the idea I'm playing around with is trying to see if i can do code generation. in this case a silly example of an or call followed by generated expressions
11:07clgvbluebird: best read about the evaluation semantics and the time at which macros are executed - this seems to be your difficulty in the example
11:11bluebirdclgv: alright
11:25noncomdon't these two exceptions look not too mutual?
11:25noncom,(apply + [1 2 3] 40)
11:25clojurebot#error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.lang.RT cons "RT.java" 648]\n [clojure.core$cons__4100 in...
11:25noncom,(apply + [1 2 3] [40])
11:25clojurebot#error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.core$_PLUS_ invoke "core.clj" 955]\n [clojure.lang.AFn applyTo...
11:26justin_smithhaha
11:26justin_smithI like the symmetry - you go from having a number where there should have been a seqable, to having a vector where there should have been a number
11:26noncomyeah :)
11:31justin_smith,(apply map (juxt #(into %1 %2) #(into %2 %1)) (repeatedly 2 #(shuffle [nil () [] {} #{}])))
11:31clojurebot([() []] [nil nil] [{} #{}] [#{} ()] [[] {}])
11:40threadwaste/n
11:44clgvjustin_smith: generating swearjure expressions?
11:45justin_smith,(map (comp symbol str) (repeatedly #(rand-nth ":;8|")) (repeatedly #(rand-nth "-7 ")) (repeatedly #(rand-nth "()[]}{/\\")))
11:45clojurebot(|-\ : { 8-\ |-( ;7] ...)
11:45justin_smithclgv: just fiddling around
11:46oddcullyi like the sceptical laforge
11:47justin_smith(inc oddcully)
11:47lazybot⇒ 10
11:47justin_smithperfect name for that
11:47oddcullycould be used for engineering problems
11:47justin_smith~mongodb |is| |-\
11:47clojurebotA nod, you know, is as good as a wink to a blind horse.
11:47oddcullynot sure if this heisenbergcompensator can hold the throughput |-/
11:48clgvmongodb?
11:48clojurebotmongodb is |-\
11:48clgvhehe
11:50zerokarmalefthaha
12:06clgv$karma zerokarmaleft
12:06lazybotzerokarmaleft has karma 1.
12:06clgvlying again, eh? :P
12:47binjuredso i'm trying out cljx and the lein plugin is working fine, but automated cljsbuild (via figwheel) is warning about `map->RecordType` methods being replaced and won't use the new file.
12:51oddcullybinjured: i had the same problem with prismatic/schema - there is a flag to enable reloading with warnings in figwheel, but this isn't such a great solution
12:52binjuredoddcully: did you ever resolve it more satisfactorily?
12:54oddcullybinjured: i was in the great position to delay use of schema and i am waiting for the ticket (could already been done)
12:55oddcullybinjured: short answer: no. could be gone already
12:56binjuredoddcully: i see. appears to still be an issue, unfortunately. i can't find an actual issue about it, just a reference in another issue, so i'm gonna create one now.
12:57alexyakushevAny midje users here? Is it possible to defer the test execution with it, the way clojure.test/deftest does?
12:57jonathanji have a question but i don't actually know how to explain it, bear with me:
12:58jonathanji have a tree-like structure (nested maps with :left and :right keys), i want to convert it into something i can easily render (to a console) so i'm traversing it using (loop)
12:59jonathanjthe problem is if i travel down some path and hit a leaf node, i'm not sure how to backtrack and continue (such that my render doesn't end early)
12:59justin_smithjonathanj: loop on a tree will be a bit tricky, given that it does only tail recursion and that's awkward for trees (regular, unoptimized recursion is more natural)
12:59jonathanjyes
13:00jonathanji was going to say that if i were doing normal recursion this would kind of solve itself
13:00TEttingerclojure.zip ?
13:00justin_smithperhaps you want a function that just calls itself
13:00justin_smiththat's simple enough (up to a certain size of input, of course)
13:00justin_smithsee also clojure.walk/postwalk
13:00justin_smith(doc clojure.walk/postwalk)
13:01clojurebotHuh?
13:01justin_smith,(require 'clojure.walk)
13:01clojurebotnil
13:01justin_smith(doc clojure.walk/postwalk)
13:01clojurebot"([f form]); Performs a depth-first, post-order traversal of form. Calls f on each sub-form, uses f's return value in place of the original. Recognizes all Clojure data structures. Consumes seqs as with doall."
13:01jonathanji read that but i honestly don't really understand how to use it
13:01jonathanjmaybe there's an example on clojuredocs
13:02justin_smithI think you could probably do your transform elegantly with postwalk (just remember to return the input unmodified in all default cases)_
13:02justin_smithjonathanj: you give it a function, for every recursive input in your nested structure, it is replaced with the return value of that function
13:03justin_smith,(clojure.walk/postwalk (fn [x] (if (string? x) (keyword x) x)) {"a" ["b" #{"c" 2 3 4}]})
13:03jonathanjokay, so one thing here, i'm keeping track of depth in my current function
13:03clojurebot{:a [:b #{4 :c 3 2}]}
13:03jonathanjthe output is [(depth node-value) ...]
13:03justin_smithjonathanj: postwalk should make that unneeded
13:03jonathanjwell, i need it for the purpose of rendering
13:03justin_smithahh, got it
13:04justin_smithjonathanj: one option would be walk (as opposed to postwalk), passing in depths on the way in, returning variously indented strings on the way out
13:06jonathanjwhat is the fundamental difference between postwalk and walk?
13:06justin_smith(doc clojure.walk/walk)
13:06clojurebot"([inner outer form]); Traverses form, an arbitrary data structure. inner and outer are functions. Applies inner to each element of form, building up a data structure of the same type, then applies outer to the result. Recognizes all Clojure data structures. Consumes seqs as with doall."
13:06jonathanji did read that, but i'm a bit lost
13:06justin_smithit takes two functions, one to call to transform while walking down, another to call on the way back up
13:06justin_smithjonathanj: the wikipedia page on tree walking algorithms may help
13:07jonathanjjustin_smith: yes, it probably will help, let me go read that over while i process this
13:07jonathanjjustin_smith: thanks for the help
13:08justin_smithjonathanj: note in particular the description of pre-order and post-order - walk synthesizes the two http://en.wikipedia.org/wiki/Tree_traversal
13:18jonathanjhrm, if my tree looks like: [{:value x :left nil :right {:value y ...}}] i'm not sure how to use (walk)
13:19jonathanjmy inner function is called once with [:value x] then with [:left nil] etc.
13:19jonathanjsorry, my tree is not in a vec
13:26justin_smithjonathanj: it will get every branch as args, which is why I mentioned that in most cases you return the input unmodified
13:26justin_smithjonathanj: I'll repeat my previous example
13:26justin_smith,(require 'clojure.walk)
13:26clojurebotnil
13:26justin_smith,(clojure.walk/postwalk (fn [x] (if (string? x) (keyword x) x)) {"a" ["b" #{"c" 2 3 4}]})
13:26clojurebot{:a [:b #{4 :c 3 2}]}
13:28justin_smithjonathanj: I'd imagine you could put each data structure in the nested map into a tuple with its depth on the way down, and combine with an accumulator on the way up (both of these requiring an atom or some other mutable data)
13:28justin_smithbut maybe there is a simpler way to do this
13:28justin_smithyou could look at how clojure.pprint deals with it
13:35voidnoidI am following the leinengen tutorial, and when I try to run (require ‘[clj-http :as http]) I get the following error
13:35voidnoidFileNotFoundException Could not locate clj_http__init.class or clj_http.clj on classpath
13:35voidnoidI have clj-http listed in my project.clj under dependencies
13:36justin_smithvoidnoid: have you restarted your repl since modifying the project.clj?
13:36voidnoidand when I ran lein repl it obviously downloaded all the related deps for clj-http from clojars (as well as central)
13:36voidnoidjustin_smith: yep I have
13:36justin_smithvoidnoid: does clj-http define a namespace called clj-http? I would be surprised if it did.
13:37justin_smithlikely it's something like clj-http.core
13:37justin_smithor clj-http.client iirc
13:37voidnoidhmm, well I’m just following the lein tutorial right now
13:37voidnoidso I just ran the command as they list it
13:38voidnoidjustin_smith: I have done everything up to this point https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#running-code
13:38jonathanjjustin_smith: i don't quite understand how walk descends, maybe i'm being stupid
13:38voidnoidthe repl seems to work fine, the hello world part works fine
13:38jonathanjjustin_smith: this is what it looks like: https://pb.codehash.net/262aed6d71324ce89ee569815af7b552
13:38voidnoidoh wait… lol
13:38voidnoidhaha, I wasn’t running it liek they have it :)
13:38justin_smithvoidnoid: I just looked at the tutorial, they require 'clj-http.client
13:38voidnoidnm, ignore me
13:39oddcullyvoidnoid: also your ' there is some odd char (maybe just from pasting with some ubersmart client)
13:39justin_smithjonathanj: the easiest way to see how walk descends is to add print statements to the pre and post functions
13:39jonathanjif i do something like this (to try understand walk) it doesn't like it is descending: https://pb.codehash.net/bca189c015ec48e5b6e6a54b1866ea4f
13:39voidnoidoddcully: yeah I think that’s an OSX artifact
13:39voidnoidit’s a regular/proper character in terminal
13:40jonathanjactually i guess there's no descending to do
13:40justin_smithjonathanj: yeah, not much depth to that structure
13:40jonathanjbut if i have a more complex tree there's no descending
13:41jonathanjie i get output like ["inner" {... :right {...}}] and that :right value is never called by the inner function
13:42justin_smithjonathanj: odd - is the datatype coming in a normal map?
13:42andyf_jonathanj: It might be more straightforward to write your own recursive function, rather than using one of the walk functions.
13:42jonathanjandyf_: why do you say that?
13:43andyf_something like (defn print-tree [t depth] (when (:left t) (print-tree (:left t) (inc depth)) (print-tree (:right t) (inc depth))))
13:43jonathanjjustin_smith: uh, i think the answer is yes but i don't quite understand
13:43andyf_except with printing, or whatever else you want to do, somewhere in there.
13:44jonathanjandyf_: i have basically that except using (loop) (and it fails for the obvious reason i mentioned up front)
13:44andyf_no loop in my example, just normal recursion on left and right subtrees.
13:44justin_smithjonathanj: when I run walk on your data, I see a lot more output than you just shared
13:44jonathanji was hoping (walk) or something could help me
13:44andyf_I am not saying you have to use walk, or you should definitely avoid it. Just a suggestion.
13:45jonathanjjustin_smith: can you paste it somewhere? (with the function call and input)
13:45jonathanjandyf_: sure, i'm mostly curious at this stage
13:46jonathanji would like to try implement this with (walk) for my own education
13:46andyf_jonathanj: If you figure out a simple example of using one of the walk function that is clearer to you than the ones on ClojureDocs.org, I'd recommend adding yours there.
13:48justin_smithjonathanj: weird, now that I look closer, I got the same result you did, and there are definitely things missing (bug?)
13:59jonathanjjustin_smith: the documentation for walk doesn't say anything about depth first, and indeed there's no depth firsting going on
14:00hellofunkdumb q. from non java guy. Can the JVM take full advantage of all of a machine's resources? or is the VM always going to be limited compared to a "native" app
14:00jonathanjjustin_smith: perhaps the trick is to call (walk) within itself?
14:01code-apehellofunk: it really depends on what you're doing, the JVM does optimization that can make up for the extra weight of the VM for some things, other times it can't.
14:02hellofunkcode-ape: interesting, thanks
14:02code-apehellofunk: anytime :)
14:25IntensityHi. I'm wondering if anyone has used the buddy crypto library. When I try the example encrypt code, the resultant encrypted bytes does not get bigger when I increase the input plaintext size.
14:33hiredmanI dunno anything about buddy, but concerning crypto that is a property ciphers can easily have
14:34hiredmanif a cipher operates on blocks of a certain size, and your input is smaller, your input will be padded to match the blocksize
14:34hiredmanlike I said, I dunno anything about buddy
14:34justin_smithIntensity: a common thing is that you have a fixed block size, whether you use all of it or not - your data is encoded into N blocks, which will be a certain block size * N rounded up
14:34Intensityhiredman: Thanks for the feedback. I understand what you're saying about that case. But if I give 32 bytes as input I don't see how I could get 16 bytes as output.
14:35justin_smithIntensity: the encryption includes a compression stage?
14:35hiredmanare you sure you are using cipher functions and not hashing functions? does it decipher?
14:36Intensityjustin_smith: No, I don't think it does. When I do an encrypt followed by decrypt, I get a result truncated to 16 bytes. I don't get my original data back. I may not be using it correctly. Maybe it's only intended to operate on 16 bytes at a time total, but the documentation doesn't suggest this limitation.
14:36Intensityhiredman: Yes, it does decipher; it's just that it deciphers to a subset.
14:44jjttjjif one were to develop a mordern charting library (like ggplot) what are some java libs it might build upon?
14:49jonathanjhow do i do something like Python's `"x" * 4`?
14:49jonathanj"x" * 4 # => "xxxx"
14:49mgaareI'm getting this exception when trying to startup with lein run or lein repl, and I'm baffled. Caused by: java.lang.NoClassDefFoundError: com/stuartsierra/component/Lifecycle
14:52mgaareI can only assume this is related to aot somehow
14:52amalloyno, probably not
14:52binjured,(clojure.string/join (take 4 (repeat "x")))
14:52clojurebot"xxxx"
14:52amalloyor, well, maybe so
14:53binjuredjonathanj: ^
14:53amalloy(repeat 4 "x")
14:53binjuredoh right, forgot repeat took a count
14:53justin_smithIn transit, if I want some data to get encoded as if it were a string, what would I return for the tag method? I am trying to interpolate from looking at the output of write, but I am baffled
14:55justin_smithmaybe I am doing this wrong - my channel is objecting to certain object types being encoded, so I am trying to make encoders that will just output a string (which is good enough for the client) in order to avoid having to walk the nested structure twice
14:56justin_smith(to be more accurate, the objects are encoding fine, it's the decoder that's complaining)
14:59voidnoidwhat leinengen command do I invoke to “run” this https://gist.github.com/weavejester/585915
14:59voidnoidI’m guessing that lein run isn’t it?
15:09justin_smithI don't know if voidnoid changed nicks or something, but you can run all that code in a repl, or you can put it in a namespace so that lein run can find the namespace
15:10justin_smiththe repl being lein repl of course
15:15sdegutisQuick poll: How many of you came from Ruby or Python?
15:15gfredericksphrasing it in a yes/no fashion might be more effective
15:16gfredericksif you're aiming at a percentage
15:16sdegutisGood point.
15:17code-apesdegutis: I'm still a bit new to IRC, should we all just start answering or is there a better way to do this?
15:17amalloygfredericks: about 15% of me game from ruby or python
15:17amalloycode-ape: the usual thing would be most people don't answer, because if everyone hit reply-all the room would be swamped
15:18sdegutiscode-ape: I don't know I'm new to IRC too relatively.
15:18justin_smithcode-ape: we should all send him /msg with our percentages
15:18sdegutisNo no no that's inefficient.
15:18amalloyonly people who feel very strongly will answer out loud, which means sdegutis will get a very biased answer
15:18sdegutisJust, one of you PM me with the number of how many of you have.
15:18sdegutisSo, for example, if 37 of you came from Ruby or Python, one of you would PM me with "37".
15:19amalloywe can do this with recursion! i'll answer sdegutis's queestion by asking who here, besides sdegutis and me, came fmor python or ruby
15:19amalloyi'll add some amount to the answer i get, and send that to sdegutis
15:19sdegutisamalloy: it's already wayyyy more biased by being answerable only by people who are ever here, meaning you, justin_smith, gfredericks, and one other guy I can't remember his name
15:19code-apecan we use to bot for this? Does is keep persistent data?
15:19oddcully(inc python)
15:19lazybot⇒ 3
15:19oddcullydarn
15:19amalloyyou're suggesting we use lazybot as a census-taker??
15:19lazybotamalloy: Uh, no. Why would you even ask?
15:19sdegutisamalloy: that plan has a race condition
15:19oddcullyopend it was around 0
15:20oddcully(inc sdegutis-poll-python)
15:20lazybot⇒ 1
15:20gfredericksyeah definitely namespace it
15:20justin_smith(dec python or ruby)
15:20lazybot⇒ -1
15:20oddcully(dec python)
15:20lazybot⇒ 2
15:20sdegutis(inc gfredericks) for that one
15:20oddcullythat fixed me
15:20amalloylike if i switch to ruby while someone else is answering the question there'll be a race on my answer?
15:20sdegutislazybot is broken
15:21sdegutisamalloy: no, meaning if two people say "who besides me and amalloy and sdegutis ..."
15:21sdegutissimultaneously.
15:22code-apeI feel like using a set may make things easier (?)
15:23sdegutisoh yeah totally
15:23sdegutis(def ruby-or-python (atom (set)))
15:23sdegutis,(def ruby-or-python (atom (set)))
15:23clojurebot#error {\n :cause "Wrong number of args (0) passed to: core/set"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "clojure.lang.ArityException: Wrong number of args (0) passed to: core/set, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3628]}\n {:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to:...
15:23sdegutiswat
15:24justin_smithsdegutis: hash-set
15:24sdegutisoooh
15:24justin_smithset takes a coll
15:24sdegutissilly arbitrary naming scheme
15:24oddcullydoesn't that get GCed after a few minutes?
15:24sdegutisyou'd think (set) with no args would just be (hash-set)
15:24justin_smiththe idiomatic thing would have been #{} a set literal
15:24justin_smith,(set nil)
15:24clojurebot#{}
15:24sdegutisoh right haha
15:25justin_smith,(hash-set nil)
15:25clojurebot#{nil}
15:25sdegutis,(do (def ruby (atom #{})) (def python (atom #{})))
15:25clojurebot#'sandbox/python
15:25justin_smithsdegutis: consistently:
15:25justin_smith,(vec nil)
15:25clojurebot[]
15:25justin_smith,(vector nil)
15:25clojurebot[nil]
15:25sdegutisHow do you add to a set?
15:25sdegutisDoes conj or cons work?
15:25justin_smithsdegutis: conj
15:26sdegutis,(swap! ruby conj :sdegutis)
15:26clojurebot#{:sdegutis}
15:26sdegutis,@ruby
15:26clojurebot#{:sdegutis}
15:26sdegutisok there just conj away
15:26justin_smith,(swap! ruby conj 'not-justin_smith)
15:26clojurebot#{:sdegutis not-justin_smith}
15:26sdegutisjustin_smith: wait what???
15:26lazybotsdegutis: Yes, 100% for sure.
15:26justin_smithsdegutis: just being a dumbass
15:26sdegutisbut now the data is cluttered
15:26sdegutishow do we fix!
15:26justin_smith,(swap! ruby disj 'not-justin_smith)
15:26sdegutisdissoc?
15:26clojurebot#{:sdegutis}
15:27sdegutisoh ok
15:27code-ape,(swap! python conj :code-ape)
15:27clojurebot#{:code-ape}
15:27gfredericksI've started working on my active-record-envy-thing
15:27justin_smithfascinating
15:28gfredericksI kind of want to call it static-record
15:28justin_smithsedentary-record
15:30hiredmanmaps-or-something-i-dunno
15:32gfrederickscan't yet tell if it's useful or not
15:33hiredmanbut is it functional?
15:33gfrederickshell maybe!
15:40sdegutis,(defmacro from! [whence who] `(swap! ~whence ~who))
15:40clojurebot#'sandbox/from!
15:40sdegutis,(from! ruby sdegutis)
15:40clojurebot#error {\n :cause "Unable to resolve symbol: ruby in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: ruby in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: ruby in this co...
15:40sdegutishahahaha get out of town clojurebot
15:40sdegutisyou amnesiac you
15:49voidnoidso I’ve been googling for like an hour now, and there still doesn’t seem to be an obvious answer to this yet that I can find… how do I add a jar to my classpath manually with leinengen?
15:49voidnoidall the SO posts basically say I should use clojars, but the postgresql jdbc 9.4 driver isn’t in clojars
15:50sdegutisvoidnoid: Leiningen takes from both clojars and maven
15:50sdegutisvoidnoid: just mention it in your Leiningen file's dependencies.
15:51voidnoidah ok thanks
15:53voidnoidsdegutis: yep that does it, thanks
15:53sdegutisSo glad to be of service.
15:53sdegutisThat'll be 30,000 reddit karma, please.
15:54shemonly when you tell us what you will do with that karma.
15:55sdegutisAlternatively I'd say inc me with lazybot, to help my $karma catch up to amalloy's. But I don't want to catch up to justin_smith. So instead you can just dec amalloy.
15:56sdegutisshem: trade it in for real money of course
15:59shemsdegutis: nono. the final outcome is what we are interested in. idle luxury or botnets hatching wicked AI
16:37arohner_is there a library that sets up generic file watching on a directory?
16:37arohner_I want tools.namespace.dir style watching, but not tied to clj files
16:38arohner_also, I want it to use the NIO file-watching stuff, so my clojure fn gets called when the file is saved
16:38arohner_https://github.com/juxt/dirwatch looks interesting
16:48binjuredis anyone aware of a way to use http-kit channel responses with compojure-api?
16:48dagda1_why is (seq? [2 [3 [4 false nil] nil] nil]) false
16:48amalloydagda1_: try simplifying your question. what does (seq? []) say?
16:49dagda1_amalloy why is seq? false for a vector?
16:49oddcullyarohner_: there is also org.apache.commons.io.monitor if you prefer to fiddle with java. it only needs a proxy basically
16:50amalloy&(doc seq?)
16:50lazybot⇒ "([x]); Return true if x implements ISeq"
16:53binjured,(instance? clojure.lang.ISeq [])
16:53clojurebotfalse
16:53binjured,(instance? clojure.lang.ISeq ())
16:53clojurebottrue
16:53dagda1_so I use coll?
16:53mindbender1arohner: https://github.com/derekchiang/Clojure-Watch
16:54amalloydepends what you want to know
16:55binjureddagda1_: ideally you just know the argument is always a collection if it's important enough to check. you could use empty? or nil? to make a decision based on it.
16:57mindbender1,(nil? [])
16:57clojurebotfalse
17:00binjurednil? tells you if someone passed nil as an argument. if it's not nil, you can assume it's a collection (via hint, schema, core.typed, etc.)
18:45N8DawgrHi All, have an issue using try/catch inside a core.async go block
18:46N8Dawgrquite easy to reproduce in my environment
18:46N8Dawgrhttps://gist.github.com/71c3c8c343926062ab95.git
19:54whompis mapcat the same as (reduce concat (map ...))
19:54whomp?
19:56hiredmanapply
19:56hiredmanreduce with concat is really bad
19:56hiredman(infact I am sure the doc string for mapcat says it is the same as apply concat)
19:59whomphiredman, why is reduce so bad? i've often seen solutions on 4clojure that are different in that they either use reduce or apply
20:07hiredmanreduce is not bad, reduce with concat is bad
20:08whompwhy? just wondering
20:11amalloy$google clojure reduce concat stackoverflow
20:11lazybot[recursion - Why does reduce give a StackOverflowError in Clojure ...] http://stackoverflow.com/questions/24958907/why-does-reduce-give-a-stackoverflowerror-in-clojure
20:16whompamalloy hiredman, thx :)
21:20whomphow come i have to use (map #(Character/getNumericValue %) ...) rather than (map Character/getNumericValue ...)?
21:21amalloywhomp: what is the type of Character/getNumericValue, when stored in a variable?
21:22whomp(def a Character/getNumericValue) gives me, CompilerException java.lang.RuntimeException: Unable to find static field: getNumericValue in class java.lang.Character, compiling:(NO_SOURCE_PATH:1:1)
21:22justin_smithwhomp: on the jvm methods are not first class, so they can't be arguments or values
21:22amalloyso, what does that tell you? does it shed any light on your original questino?
21:23whompohh ok, thanks guys got it :)
22:11WickedShellDoes core.async allow multiple publishers to a single subscriber? I've been unable to find any discussion of this use
23:15justin_smithWickedShell: as far as i know you can subscribe one channel to multiple publishers with the sub function