#clojure logs

2014-04-07

01:19krasHow do I control the number of parallel threads using pmap?
01:20krasLets say I have 80 parallel jobs but want to use a pool of 10 workers only i.e, 10 threads at a time
01:24`szxkras: https://github.com/TheClimateCorporation/claypoole
01:41arrdemhum... so I have this handy dandy xsd schema file... is there a toolkit that will allow me to generate record definitions and an appropriate data.xml importer from it?
02:16miseria"el deseo de vivir un millon de años, me obligan a buscar y matar la muerte, antes que ella me convierta en calavera" bienvenidos: http://castroruben.com *temo_a_un_ser_sin_rival*
02:18deadghostnoprompt, how far as you along with sass for garden; I'll help out if I can
02:19deadghost*are
02:19nopromptdeadghost: not very far. i've been hung up on other stuff at the moment. but it's pretty easy to hack on.
02:20deadghostnoprompt, is it up on github?
02:22nopromptdeadghost: yeah, https://github.com/noprompt/thorn
02:22nopromptdeadghost: if you want me to explain more msg me
02:22deadghostemail or pm?
02:22nopromptpm is fine
03:56sm0keif i have some static enums define in an inner class with weird name like org.my.com.Abcdefghijk$Lmnop
03:56sm0keand i want to use enums inside a condp =
03:57sm0kehow do i avoid Abcdefghijk$Lmnop/ENUM1 ...
03:57opqdonuthave a clojure file that defines nicer names for them
03:58sm0kewhy doesnt clojure allows import *
03:58opqdonutyou can write a macro to do that :P
03:59sm0kebleh
04:22ambrosebsinstaparse case for parsing multi-line C-style comments?
04:36ambrosebs<MultiLineComment> ::= '/*' InsideMultiLineComment* '*/'
04:36ambrosebs<InsideMultiLineComment> ::= !( '*/' | '/*' ) (#'.' | LineTerminator) | MultiLineComment
04:36ambrosebsfrom https://github.com/Engelberg/instaparse/blob/master/docs/ExperimentalFeatures.md#auto-whitespace
06:48dsrxweasel users - new 0.2.0 release includes support for clojurescript 2202
06:53whodidthisinstaparse is such amaze
07:29devnwow. so parse.
07:29devnsuch insta.
07:46pradeepc_Hello how can i check if an element exists in a vector.
07:47beamso,(contains? [1 2 3 4] 3)
07:48clojurebottrue
07:48opqdonutnope
07:48opqdonut,(contains? [:a :b :c :d] 3)
07:48clojurebottrue
07:48beamsoouch
07:48opqdonutcontains? checks whether the index is valid, i.e. whether you have a valid key
07:48ambrosebs,(some #{:a} [:a :b :c])
07:48clojurebot:a
07:48opqdonutyep, that's the right one
07:49opqdonutbut it doesn't work for finding a nil, unfortunately
07:49AimHereIf you're doing that a lot, you might want to consider switching to a set or a map instead, of course
07:49ambrosebs,(some (some-fn nil? false? #{:a}) foo)
07:49clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>
07:50opqdonut:)
07:52pradeepc_AimHere: I want to check the ip of each client request and block if it exists in the blacklist.
07:52opqdonutyeah use a set for that
07:52AimHereUnless you have a good reason for them to be ordered, then go with a set
07:53ambrosebs,(contains? #{:foo :bar} :foo)
07:53clojurebottrue
07:54opqdonut,(#{"123" "456"} "123")
07:54clojurebot"123"
07:54AimHereGiven what an IP address is, there might be some sort of funky fast bespoke data structure that you can knock up that's more efficient
07:56ambrosebsI prefer contains.
07:56pradeepc_AimHere: can you point me somewhere.
07:56ambrosebsunless the operator is a set literal
07:57AimHereI can't, no. That was just a random thought popping into my head. I recommend you go with the set first, because it'll be quick and easy to knock up; if there's performance problems then consider looking up how grown-ups optimize their IP blacklists.
07:58beamsowouldn't people use network addresses and submasks to optimise?
07:58pradeepc_AimHere ambrosebs Thanks.
08:08sm0ke,(.getConstructor Integer Integer)
08:08clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to [Ljava.lang.Class;>
08:09clgvsm0ke: you need an array of classes instead of a class
08:09gfredericks,(.getConstructor Integer (into-array [Integer]))
08:09clojurebot#<NoSuchMethodException java.lang.NoSuchMethodException: java.lang.Integer.<init>(java.lang.Integer)>
08:09sm0kehmm
08:09gfredericks,(.getConstructor Integer (into-array [Long]))
08:09clojurebot#<NoSuchMethodException java.lang.NoSuchMethodException: java.lang.Integer.<init>(java.lang.Long)>
08:09gfredericks,(.getConstructor Integer (into-array [Integer/TYPE]))
08:09clojurebot#<Constructor public java.lang.Integer(int)>
08:09sm0kewhat da..?
08:09gfredericksInteger/TYPE is the type of primitive ints
08:10gfrederickscompare:
08:10gfredericks,(type (make-array 1 Integer))
08:10clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Class>
08:10gfredericks,(type (make-array Integer 1))
08:10clojurebot[Ljava.lang.Integer;
08:10gfredericks,(type (make-array Integer/TYPE 1))
08:10clojurebot[I
08:11clgv,(.getCanonicalName (type (make-array Integer/TYPE 1)))
08:11clojurebot"int[]"
08:11sm0keok so i have a use case where i define a record and wont too lookup its constructor lets say
08:11sm0ke,(defrecord MyRec [a b])
08:11clojurebotsandbox.MyRec
08:11clgv,(.getCanonicalName (type (make-array Integer 1)))
08:11clojurebot"java.lang.Integer[]"
08:12clgv,(.getConstructor MyRec (into-array [Object Object]))
08:12clojurebot#<Constructor public sandbox.MyRec(java.lang.Object,java.lang.Object)>
08:12sm0ke,(.getConstructor (Class/forName "sandbox.MyRec") Object Object)
08:12clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: getConstructor for class java.lang.Class>
08:12sm0keaha
08:12sm0kethanks clgv
08:12sm0ke,(.getConstructor (Class/forName "sandbox.MyRec") (into-array [Object Object]))
08:12clojurebot#<Constructor public sandbox.MyRec(java.lang.Object,java.lang.Object)>
08:12sm0kejust checking :D
08:13sm0keso why isnt Object/TYPE
08:13clgvthere is no primitive object ;)
08:15sm0ke,(Integer. (Integer. 1))
08:15clojurebot1
08:15sm0ke,(.getConstructor Integer (into-array [Integer]))
08:15clojurebot#<NoSuchMethodException java.lang.NoSuchMethodException: java.lang.Integer.<init>(java.lang.Integer)>
08:16sm0ke,(.getConstructor Integer (into-array [Integer/TYPE]))
08:16clojurebot#<Constructor public java.lang.Integer(int)>
08:16sm0kewtf
08:17sm0keam is missing something here?
08:17sm0keam i*
08:17clgvsm0ke: you are missing autoboxing and autounboxing
08:17ambrosebshttp://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html?is-external=true#constructor_summary
08:18sm0kesneaky
08:18sm0kemakes sense
08:18sm0kethanks
08:19sm0keso java is dynamically type to some sense
08:19sm0ketyped*
08:19beamsoi wouldn't say that
08:20sm0keint and Integer are different types!
08:20beamsoit's more that Integer came after int
08:20beamsoand the JVM attempts to help you go between the two, but you can get a NPE in certain circumstances (i.e. Integer -> int)
08:22sm0ke,(.newInstance (.getConstructor (Class/forName "sandbox.MyRec") (into-array [Object Object])) 1 2)
08:22clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: sandbox.MyRec>
08:23clgvsm0ke: no. afaik the compiler inserts code for you to do the (un-)boxing of Integer/ints
08:24clgvyour session namespace probably expired
08:25sm0ke,(defrecord MyRec [a b])
08:25clojurebotsandbox.MyRec
08:25sm0ke,(.newInstance (.getConstructor (Class/forName "sandbox.MyRec") (into-array [Object Object])) 1 2)
08:25clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: newInstance for class java.lang.reflect.Constructor>
08:25sm0ke,(.newInstance (.getConstructor (Class/forName "sandbox.MyRec") (into-array [Object Object])) (into-array [1 2]))
08:25clojurebot#sandbox.MyRec{:a 1, :b 2}
08:29sm0ke(inc clgv)
08:29lazybot⇒ 15
08:31clgv:D
09:18lunkhello, how can i take two seq's of equal length, one of digits and one of booleans, and emit from digits when the corresponding boolean is true?
09:18lunkfor loops are doing cross products
09:21tbaldridgearrdem: ping
09:22arrdemtbaldridge: good morning...
09:22tbaldridgearrdem: you had a question?
09:25arrdemtbaldridge: enjoyed your c.t.a(.jvm) talk, only thing that really stuck out to me was your comments about a potential SSA layer below or beyond c.t.a. What's the activity there? Not a project I'm aware of.
09:26TEttinger,(let [digits [1 2 3] bools [true false true]] (filter number? (map #(if %1 %2) bools digits))) ; lunk
09:26clojurebot(1 3)
09:27tbaldridgearrdem: I've threatened to write it, that's about it. core.async uses a form of SSA, but I'd like to pull that out and make it an actual library. Any non-bytecode output platform could possibly take advantage of it.
09:27mdrogalisSSA?
09:27arrdemmdrogalis: static single assignment
09:28mdrogalisarrdem: Thanks.
09:28arrdemmdrogalis: it's a ... style of bytecode, typically register machine modeling which makes some compiler analysis techniques much simpler to use.
09:28tbaldridgeclojurebot: SSA is https://en.wikipedia.org/wiki/Static_single_assignment
09:28clojurebotIn Ordnung
09:28TEttingerIn Ordnung
09:28TEttinger[06:25;32] * hoeck has quit (Ping timeout: 255 seconds)
09:28TEttinger[06:25;41] * si
09:28arrdems/bitecode/compiler internal representation/g
09:28TEttingerdammit
09:28lunkTEttinger: yes!
09:28tbaldridgefor once Wikipedia's view of something is actually quite nice
09:28TEttingerclojurebot: SSA |is| https://en.wikipedia.org/wiki/Static_single_assignment
09:28clojurebot'Sea, mhuise.
09:29TEttingerhm
09:29mdrogalisThanks for the info. Neat.
09:30arrdemtbaldridge: I guess my only issue with that is it seems like the kind of "only updated here" or "never updated" proofs you could do on values given a SSA structure you could probably do on the normal t.a tree.
09:30arrdemnot that I'm really opposed to reimplementing more of LLVM in Clojure for Clojure...
09:31lunkTEttinger: clever, i knew i was going down the wrong path. TY sir
09:31tbaldridgearrdem: yeah, I mean it's super useful for core.async as I basically take the SSA and emit it as a case+lets to create the state machine
09:31TEttingerno prob lunk
09:32tbaldridgeBut I think it could be useful for emitting to platforms that don't have "everything as an expression". For example, PyPy's RPython writes SSA code as C
09:32arrdemtbaldridge: yeah I'm reading that now. slick!
10:00BronsaIs there a good reason why `some` doesn't take multiple colls?
10:01BronsaI find myself doing (some true? (map pred c1 c2)) quite often
10:03AimHereBronsa, what's the obvious interpretation of (some foo? a b c) ?
10:03AimHereThat question broke him, evidently.
10:04opqdonutas he said, (some true? (map foo? a b c))
10:04opqdonutI think it's weird that map is multi-arity but e.g. some and filter are not
10:04AimHereSo you have to add in another function as well as the extra collections
10:04AimHereIt's not obvious to me
10:04BronsaAimHere: sorry emacs crashed
10:04opqdonutAimHere: no, the foo? just gets passed multiple arguments
10:05BronsaAimHere: look at the source of some
10:05Bronsait's pretty straightforward to implement that for multiple colls
10:05opqdonutthe true? is just a way of implementing it
10:05Bronsajust add another arity that calls pred on (first c1) (first c2)
10:05AimHereAh, sorry, not thinking clearly
10:06AimHereBut then, if I was to see (some pred? a b c), I could also read it as (some pred? (concat a b c)
10:06BronsaAimHere: no, that follows the same pattern as e.g. map
10:07Bronsa(map f a b c) applies f to (first a) (first b) (first c)
10:07AimHereThat's your intuition, though some doesn't act like 'map' to my mind
10:07AimHeresome takes a pred and a collection and spits out a member of that collection. Looks more like nth to me!
10:08BronsaAimHere: it doesn't spit out a member of the collection
10:08Bronsait spits out the result of calling f to a member of that collection
10:08Bronsa,(some inc (range))
10:08clojurebot1
10:09AimHereFair enough, but it's unlike map in some ways
10:09AimHereYours is one interpretation, but not the only one. It's non-obvious
10:09Bronsasure, I was just drawing a parallel
11:15ambrosebsany tips for figuring out where instaparse gets stuck if it overflows the heap? is there a "current token" variable?
11:19bbloomambrosebs: isn't "parses" lazy? you might be able to see some ambiguity if you just print the parses stream until it does
11:19bbloom(note: i've only used instaparse for very simple use cases and haven't had to debug any grammars yet)
11:20ambrosebsbbloom: ah I'll try
11:34zeeshanlakhaniIf anyone's done work w/ test.check or double.check, how could I write a generator that needed to combine two types... one gen/string and the other a regex on that string, for example?
11:34reiddraperzeeshanlakhani: how specifically do you want to combine them?
11:35reiddraperzeeshanlakhani: more than likely you'll want to use gen/fmap or gen/bind
11:35zeeshanlakhanihey reid! Yeah, I was trying to get it to work w/ gen/bind, but in the midst of trying to generate them from prismatic schema's s/both
11:36zeeshanlakhaniif I return two separate generators, i should just be able to combine them w/ gen bind?
11:37reiddraperzeeshanlakhani: gen/bind lets you take the randomly generated value from one generator and make a new generator out of it. fmap allows you to apply a function to a value generated. so really just depends on what you want to do
11:37reiddraperzeeshanlakhani: maybe you could describe in prose what you want
11:38zeeshanlakhaniYeah, the basics of what I want is that I have from a schemata a type that needs to be both a string and a string that fits a certain reg. expression. I just want to generate a set of samples that apply to both those types.
11:39zeeshanlakhaniI feel like I'm saying that I need a generator that's aware of the constraint of an input generator
11:40reiddraperzeeshanlakhani: hmm
11:40zeeshanlakhaniDoes that make any sense? :)
11:41reiddraperzeeshanlakhani: not quite sure i'm following. do you have these generators already written? if so, can you be more explicit about how you want to compose them
11:42xsynare incanter's datasets indexed out of the gate?
11:43xsynsomeone was describing R's dataframes, saying that they're really efficient due to their indexing
11:43xsynI was interested if incanter had the same functionality
11:43xsyns/if/as to whether/
11:48ambrosebsbbloom: phew parses is pretty amazing
11:48bbloomyup!
11:52zeeshanlakhaniTo be honest reid, the more I look at our prismatic schema-uses, the more I'm seeing a type that's more like a field's value will be both a map and a non-empty collection, which, if that's the case gen/such-that will be exactly what i need (predicate and gen) for most cases and fmap for others. Think I was over-complicating the situation :D
11:52pdurbinxsyn: due to their indexing?
11:53reiddraperzeeshanlakhani: cool. also take a look at gen/not-empty, which is a prewritten (such-that not-empty ...)
11:55zeeshanlakhaniyep, will do. Thank you reid! So much fun using test.check
11:55reiddraperzeeshanlakhani: np, and happy to hear :)
11:57ambrosebsinstaparse.core/parses + clojure.data/diff = holy crpa
12:01bbloomambrosebs: interactively debugging ambiguity beats the pants off cryptic shift/reduce errors, huh?
12:03ambrosebsbbloom: never used a parser in my life
12:03ambrosebsapparently a great place to start
12:05bbloomambrosebs: traditional parser generators only parse a subset of CFG. you get a weird error message if you accidentally create a grammar that isn't in the subset.... but the source of the issue is usually *very far* from the symptom
12:05gtrakIs it just me or is the lifecycle of core.async channels and implications a little unclear and discomforting? Trying to figure out how to test a small thing, considering implementing it with callbacks instead, but maybe I'm missing something fundamental, I have no idea :-). If I could instrument which channel(s) is/are getting blocked, then that would help immensely.
12:06ambrosebsbbloom: ah that sucks
12:06bbloomambrosebs: yeah, trade off is that instaparse's generalized algorithm can be *very* memory hungry
12:08bbloombut in practice it's not a big deal b/c you can debug your grammar interactively, find sources of ambiguity, excessive left recursion, etc, and eliminate those
12:08bbloomit's kinda like dynamic vs static typing ;-)
12:08ambrosebs:)
12:09ambrosebsI assume ambiguity is a severe performance problem
12:10bbloomso i dunno enough about instaparse's internals, but it doesn't have to be a perf problem
12:11bbloombut my understanding is that instaparse's algorithm ALWAYS supports back tracking
12:11bbloomwhich means high memory overhead for the parse context, to support that backtracking
12:11bbloomin general, you need most of that context saved for unlimited lookahead
12:12bbloomi'd really like to see tools to help you prove/falsify properties about grammars, like verifying that a grammar is LL(N)
12:39dokyhello is there any option to concat string in regexp ? and produce a map with it ? somethng like (map #(% (re-find #%" [\w ]+" "-p password -u username")) ("-p", "-u") ) ?
12:42dokywhat results to {:-p "password" :-u "username"}
12:42justin_smithdoky that question is confusing
12:42justin_smithfirst off, map does not produce a hashmap, it maps over some input
12:42TimMcdoky: No, but Pattern has a quote-for-regex method, and for this use-case you probably want clojopts anyhow.
12:43justin_smithyeah, it looks like clojopts may be what you want https://github.com/amalloy/clojopts
12:44dokyTimMc: but i need to parse string in cycle .. if no .. a can call different regexp and assoc results to map
12:56nopromptthe latest version of clojurescript randomly throws wacky errors.
12:56nopromptjava.lang.Exception: JSON error (unexpected character): ^@
12:57nopromptlike, uh, what?
12:57nopromptdnolen_: ^
12:57hiredmanlooks like a null character
12:57dnolen_noprompt: more details needed
12:57noprompti don't even know if i could give you any
12:58nopromptbefore that it was
12:58nopromptjava.lang.IndexOutOfBoundsException:
12:58nopromptand no vectors were used.
12:58nopromptor at least not in the part i changed.
12:58nopromptit could be one of the libraries though.
12:58AimHereThese errors don't look any weirder than normal clojure/javascript errors
12:58nopromptbut this wasn't happening before with the same code.
12:58hiredmannoprompt: are you using cljsbuild auto build?
12:58nopromptsometimes it's just a matter of adding some whitespace and saving the file again and everythign compiles fine.
12:59noprompthiredman: yes.
12:59hiredmannoprompt: check for multiple autobuild processes
13:00noprompthiredman: yeah, i'm familiar with "those" errors. there's only one cljsbuild process rolling though.
13:00dnolen_noprompt: paste a stack trace and maybe I'll see something
13:01nopromptdnolen_: https://www.refheap.com/73054
13:04dnolen_noprompt: looks like it's blowing up on the source maps, that what we use clojure.data.json for
13:04nopromptdnolen_: you can ignore the [cljsbuild] that's just a tag we have for the output
13:05nopromptdnolen_: any clue what might cause it?
13:05dnolen_noprompt: look at the json is it valid?
13:07nopromptdnolen_: looking into it.
13:11seangrovebbloom: I've been thinking about it, I'm pretty sold on the idea of Auckland-style layout model. With the right UI it makes a lot more sense for developers than raw iOS-style constraints
13:12bbloomseangrove: yup. then the next though that follows is that you that to be the default top-level layout, but you'll still want hierarchical layout managers
13:14seangrovebbloom: I control the top-level layout of these regions, but delegate layout within those regions to some other layout system?
13:14bbloomseangrove: right, since some layouts are super simple and make sense like "stack layout"
13:15bbloomseangrove: why bother with a constraint solver if you're just going to do y+=height ?
13:15nopromptauckland-style?
13:15bbloomseangrove: and some layouts are non-linear, so a linear constraint solver isn't a good plan at all
13:15bbloomseangrove: i'll let you explain
13:15bbloom(curious to hear your take on it anyway)
13:17seangrovebbloom: Been explaining it in person quite a bit, haven't yet over irc
13:17seangrovenoprompt: Reasonably simple idea - have you worked with a designer and see how they sketch things out in PS or Sketch?
13:18nopromptseangrove: yes. myself.
13:18nopromptseangrove: well, and other designer friends.
13:18bbloomseangrove: and now you're doing customer development!
13:18nopromptseangrove: i was a designer a long time before i was a programmer.
13:18seangrovebbloom: It's in no way my product :P
13:18seangrovenoprompt: Nice. So what I've seen is designers settings higher-level constraints on a design by defining regions
13:19seangroveEssentially starting with guidelines
13:19nopromptha, yeah. just drag one from the ruler.
13:19seangroveExactly
13:19nopromptand then snap elements to it.
13:19bbloomseangrove: instant understanding. that's how you know you've got a good user mental model ;-)
13:20seangroveSo for a top-level layout, you define these regions, and then set rules about them "This region in the middle is always this height, but it can expand in this direction if necessary, figure it out for me", etc
13:20bbloomi humbly request that you retune your classifier from "crazy homeless man on street corner" more towards "mo fuckin' profit"
13:20bbloomer prophet
13:20bbloom(dec spelling)
13:20lazybot⇒ -1
13:20seangroveFreudian slip??
13:20lazybotseangrove: Definitely not.
13:20bbloom~botsnack
13:20clojurebotThanks! Can I have chocolate next time
13:21seangrovelazybot, I <3 you
13:21bbloomdammit. wrong bot
13:21seangrovenoprompt: Anyway, you define these regions, and then your components inhabit them
13:21seangroveMaybe with another layer of layout managers in between, though
13:22nopromptseangrove: right. so does that involve a constraint solver or is it lower on the totum pole of how much shit i have to read to grok how it all works. :-P
13:22bbloomnoprompt: it may or may not be built on top of a constraint solver
13:22seangrovenoprompt: So you can imagine as a designer I set the guidelines, set the rules, strt dragging in your components into the regions, setting their data bindings to your app state, and then, finally, applying styling
13:22bbloomideally, yes, but most use cases can be implemented by solving trivial proportions
13:23seangrovenoprompt: No we can reason about layout, app-state data, component behavior, and styling separately
13:23bbloomyou may want to say "this region keeps a 4:3 aspect ratio" and the layout evaluator may decide to implement that as a proper linear constraint
13:23nopromptright
13:27seangrovenoprompt: But if you have those pieces in place, you can mould apps like you're working with clay - pieces that do what you want (layout, transform data, or style), but no more, so you can componse them together
13:28oinksoftis anything available for or built into clojure for managing workers? like supervisor/gen_server in OTP?
13:28seangrovenoprompt: I'm starting to see that as the holy-grail of UI programming.
13:28oinksoftor are clojure people using threads for this? immutable data structures are friendly (essential) for the OTP design
13:29oinksoftso i thought perhaps something similar to OTP existed
13:29technomancysadly there's nothing like OTP (anywhere)
13:29technomancyexcept OTP itself
13:30technomancybut yeah, there are typically no problems with using threads for that kind of thing
13:30oinksoftok, thanks technomancy
13:30tbaldridgeand when you do, there is core.async </shameless ad>
13:31gtraktbaldridge: I'm having a hard time visualizing what's going wrong in my core.async impl, are there any sort of introspection facilities that might be useful for debugging? I saw in the impls there's some ways to get counts on the buffers and things.
13:31oinksofttbaldridge: is that battle tested stuff?
13:31oinksofttbaldridge: to the extent that goroutines are battle-tested ..
13:32seangroveoinksoft: Nothing in the Clojure world will be as battle-tested as OTP ;)
13:32oinksoftseangrove: well yea :p
13:32oinksofti just meant, is core.async experimental or people are using this for real work?
13:32bmabeyoinksoft: we've been using core.async in production on the server almost as soon as it came out and we haven't had many issues at all
13:33oinksoftbmabey: nice! anything to be aware of? i do like the look of this api
13:33technomancyit's not really trying to solve the same problems as OTP though, is it?
13:33technomancyor rather, it targets a small subset of the problems
13:33bmabeyI have wanted OTP like supervisors with core.asycn in the past
13:33gtrakI guess I could maybe write a macro that creates a gensym and stacktrace for each channel instance and polls counts once in a while.
13:34bmabeysometimes go processes blow up on an unexpected error and I just want them to simply restart
13:34oinksofttechnomancy: yea, i can see how this would be useful though, so i was curious, it reminded me of goroutines
13:34bmabeyso having reusable policies to manage those restarts would be helpful
13:35technomancyoinksoft: sure, not saying it's not useful =)
13:35oinksofttechnomancy: i see otp like a padded cell :)
13:36gtrakbmabey: I would just wrap the internals in a with-error-fn macro that does a try-catch, used it with println initially.
13:36gtraki guess if you pass in a function, recur wouldn't work.
13:37gtrakbut that just requires a more complex macro :-)
13:37seangrovebbloom dnolen_: I'm contemplating a visit out there the be able to join in some of these mind-blowing conversations ;)
13:38technomancyoinksoft: the tooling around distributed async flows is just a lot better in erlang; on the jvm it's a lot more common to have trouble debugging once you give up the ability to get a proper stack trace.
13:38bmabeygrandy__: right, and that is what I did and moved on :) I never went the next step of extracting it but it seems like a lot of people using core.async would need something like this
13:38dnolen_seangrove: you're always welcome to come hang out in Brooklyn with us
13:39bmabeyoinksoft: you do need to be aware of not-blocking the go-routines. Here is a post explaining it: http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/
13:39oinksofttechnomancy: yea, the remote debugging capabilities are pretty nice in erlang
13:39oinksoftbmabey: so core.async uses all of the go terminology (goroutine, channel, etc.)?
13:40tbaldridgehopefully something like OTP is developed at some point for core.async. But as always the question will be what OTP for CSP even means.
13:40seangrovednolen_: Sounds good, I'll start thinking about it a bit then
13:40bmabeytbaldridge: yeah, and I'm hoping someone with a lot of experience in both and provide some insight
13:41tbaldridgebmabey: sadly I think that's one of the issues...people seem to either be experts with actors or CSP not both :-(
13:41hiredmanwell, microsoft's orleans thing claims not to need otp because of whatever
13:41bmabeytbaldridge: I have a friend at google who does a lot of go and he says they just panic, kill the whole process, and let the cluster start things back up again
13:41gtrakbmabey: lol, that's encouraging
13:41hiredman(but it sort of quacks like otp)
13:41hiredmanhttp://research.microsoft.com/en-us/projects/orleans/
13:42technomancybmabey: part of that is just because go is no good at live introspection
13:42bmabeytechnomancy: and fast at starting up
13:42bbloomwe definitely need something like linked/trees of processes
13:43gtrakbbloom: I could imagine a prismatic-graphlike thing that allows for introspection.
13:43bmabeybbloom: of course it all comes back to trees for you :P joking aside, I agree
13:44tbaldridgeand two things (in my mind) that are keeping that from happening in core.async right now are 1) first class processes, 2) the ability to kill a go (requires #1)
13:45bbloomwe need more introspection in general. don't worry, i'm on it :-)
13:45gtrakhow can I help?
13:45bbloomgtrak: wait patiently for a bit ;-)
13:46gtrakbesides tiny little one-off macros, that's my usual method for figuring things out :-)
13:46bbloomtbaldridge: processes are already reified, what's holding them back from becoming first-class?
13:46bbloomtbaldridge: is it just API design?
13:47bmabeybbloom: you never get a handle on the process though, just the channel it returns
13:47bbloombmabey: right, but in the implementation they are a state machine object
13:47tbaldridgeright, and the whole API is callback based so there's nothing there that describes how to terminate a callback, or even if that can be done
13:47gtrakwhat's first-class? I imagine that means a set of lifecycle protocols.
13:48tbaldridgeany impl I've thought about has had big caveats. For example: "(kill! pid) - kills the process the next time it attempts to read write or alt"
13:48bmabeyfirst class means you can assign it to a var, put in a datastructure, return it from a fn, blah, blah
13:48bbloomgtrak: first-class means that processes are things you can manipulate in the language directly as any other object/value
13:48tbaldridgebut that doesn't help at all with a process stuck in a loop.
13:48bmabeywhich you can with core.async's state machines as bbloom as pointed out but the API doesn't return them to allow you to do that
13:49bbloomtbaldridge: presumably you can instrument loops to check the kill flag
13:49bbloomtbaldridge: may murder perf tho...
13:49gtrakah, so just, more control on the continuum of opaque to transparent?
13:49tbaldridgesure...but what does that even mean if you want the same api to work for (thread) ?
13:49bbloomgtrak: transparency is orthogonal
13:49bbloom,(fn [x] (* x 2))
13:49bmabeyyeah, (thread) is tricky...
13:49clojurebot#<sandbox$eval25$fn__26 sandbox$eval25$fn__26@1cbeebb>
13:49bbloom^^ that's opaque, but first-class
13:50bbloombut in my interpreter, soon to be jit, you'd get something like #eclj.Function{:args [x] :expr (* x 2)} :-)
13:50bmabeyhaving the channel that is returned from a go process be linked to said process seems natural.. what if closing that channel would result in the process being killed? is that a horrible idea?
13:50gtrakah
13:51gtrakyea, I mean it seems like the channel from a go-block is the 1:1 link, analogous to function-object:semantics
13:51tbaldridgebmabey: I don't know yet :-) And whatever happens I need to talk to Rich about all this at some point. And he has the final say on this stuff.
13:51gtrakthe fact that it's a channel.. doesn't mean that's all it could be.
13:51bbloomspeaking of, tbaldridge: i'm almost finished separating syntax from the interpreter. there is a shallow "parse"/"analyze" phase & first-class "syntax objects" a la racket
13:52tbaldridgebbloom: nice
13:52bmabeygtrak: true, a Process protocol could be introduced or something which the returned val impls. as well as the Channel protocol
13:53bbloomtbaldridge: it's pretty cool b/c it looks sorta like the traditional analyzer, but there is no recursion. instead, the recursion that exists in eval will (eventually) be intercepted to produce deep ASTs. ie the analyzer will be parse+partial-eval
13:55gtrakI've been playing with om, so I'm in the lifecycle protocols mindset :)
13:58oinksoftok, i've got a big question. program abstraction in clojure? in an OOP language, for instance, maybe i have an adapter layer and my API user provides the implementation they desire to my adapter (like a DB adapter). how are API users doing this in clojure?
13:58oinksofti see in some cases people use (binding so define some value for a library
13:59oinksoftbut at a high level something feels very clumsy here
13:59justin_smithoinksoft: multimethods or protocols pretty often
13:59gtrakoinksoft: try to avoid binding please :-)
13:59justin_smithbinding is fragile
13:59oinksoftgtrak: yea, it looked very ugly to me
13:59justin_smithoinksoft: define a multi or proto in your lib, and then let a user provide an impl
13:59gtrakany library that uses it is likely to be making bad assumptions. It's more ok in an app.
14:00oinksoftlet's say i am designing an API for catching fish. now i don't care how you catch them, you can use a rod and reel, a spear, a net ... is the API user going to call (catch-fish reel-that-implements-fish-catching-protocol)?
14:00gtrakthey can use reify, extend-type or whatever they like.
14:00oinksoftin an OOP langauge I can register this with reel object in some way so i am not passing it around all the time
14:00justin_smithoinksoft: yeah, and define catch-fish as a multimethod or a protocol method
14:01gtrakoinksoft: you could define an adapter to an existing type with extend-type.
14:01oinksofta frustration i have when doing lots of heavy erlang programming comes when i want to make my API flexible. you use callback modules, but anyway i am blabbering...
14:01justin_smithoinksoft: fp is about replacing globals with args - things really work when you do it that way
14:02oinksoftjustin_smith: yea, this is smeothing i revisit a lot .. api design is so important.
14:02gtrakfor instance, 'slurp' calls clojure.java.io/reader on its arg, which might be a String, which is a 'final' class, meaning it cannot be extended. in clojure.java.io, it's specified how to handle strings, so the user just has to know that that's the case, and that it'll be treated as a URL :-).
14:02bbloomoinksoft: over here in clojureland, we do our data design before we do api design ;-)
14:03oinksoftjustin_smith: i want to make my program easy to maintain but also easy for the code user. one way i see epeople doing this in clojure is with macros (like sqlkorma does this)
14:03oinksoftbbloom: go on ... :)
14:03gtrakbut you can extend the IOFactory protocol to any object, then it'll be slurpable :-)
14:03bbloomoinksoft: take a look at datomic or the clojurescript analyzer or something like that. they are very narrow APIs
14:04bbloomoinksoft: datomic has a handful of functions, the cljs analyzer is basically just one "analyze"
14:04justin_smithoinksoft: macros can make things easier / cleaner for a specific use, but can make other uses more tedious. Please provide a sensible function only path also.
14:04bbloomeverything else about the public contract is part of the implicit schema of the data
14:04tbaldridgeYou should start with the data your system is working with, then write functions that manipulate that data, then configure the execution of those functions with more data, and finally (and only if needed) write an actual API/DSL
14:05oinksofttbaldridge: that's really good advice. it's easy to dwell on the API design. you know, fancy paint and stickers on the car :)
14:07oinksoftor maybe the steering wheel... b ut you can't steer something that doesn't drive, or uses the wrong gas
14:07technomancyhm; only ~300 responses on the leiningen survey. we had more last year.
14:07mdrogalistechnomancy: I wasn't aware it was even out.
14:08technomancyvote early; vote often
14:08technomancyno wait, that's something else
14:08yotsovtechnomancy: where was it announced? it seems I am missing some channels
14:08mdrogalisWait! No, I took the survey a while ago. :P
14:08mdrogalisJust forgot :)
14:09mdrogalisCrisis averted.
14:09technomancyyotsov: I posted it to the leiningen and clojure mailing lists a week or two ago
14:09technomancyalso twitter
14:09yotsovtechnomancy: ok thanks
14:09`szxso i'm trying to understand the reasoning behind the choice of seq functions implemented in core.reducers - e.g. i *think* first isn't there since it offers no benefit over lazyseqs, though not sure why take-while but no drop-while, no map-indexed, etc.?
14:10`szxalso, any idea why (into [] (r/map identity {:a 1 :b 2})) would work in clojure but not clojurescript?
14:11justin_smith`szx: maybe you need to explicitly call seq on the hashmap literal?
14:11bbloomclojurebot: working is what does "not working" mean?
14:11clojurebotPardon?
14:11bbloomclojurebot: working |is| what does "not working" mean?
14:11clojurebotI don't understand.
14:12bbloomi dunno how to use clojurebot :-P
14:12`szxbbloom: Error: No protocol method IReduce.-reduce defined for type cljs.core/PersistentArrayMap: {:a 1, :b 2}
14:12justin_smithcalling seq on the hashmap should fix that error, yeah
14:12hiredmanbbloom: the question mark at the end trips it up
14:12bbloomclojurebot: working is please define "not working"
14:12clojurebotc'est bon!
14:12bbloom~working
14:12clojurebotworking is please define "not working"
14:13`szxjustin_smith: yeah, it just looks like it should work fine - https://github.com/clojure/clojurescript/blob/master/src/cljs/clojure/core/reducers.cljs#L40
14:13bbloom`szx: might be a bug
14:15`szxbbloom: yeah, looks like to me
14:16bbloom`szx: can you put together a minimal repo case and report it on jira?
14:16`szxbbloom: sure. checking to make sure it hasn't already been reported
14:18`szxin the meantime, back to my other question - is there a reason some functions are missing from core.reducers or is it just because nobody got to it yet?
14:22brainkimDoes anyone have a good example project with unit-tests for an http-kit server? I'm trying to figure out if I'm going to have to mock websocket requests.
14:25mdrogalisbrainkim: Try introducing small, local queues with core.async to get around that.
14:26amalloy`szx: i think only one or two additional reducers have been added since the original release of reducers. having attempted to define a couple myself (and had them deferred indefinitely), i'd say there's some question about how to define a reducer rich finds acceptable
14:27nickmbaileyfa
14:28brainkimmdrogalis: That's prboably what I should do. I'm having a lot of trouble creating small functions core.async but that would be really testable.
14:30mdrogalisbrainkim: Yeah, it works out great because the processor of the request doesn't need to know which thread the request came from
14:33rtlgs
14:37brainkimmdrogalis: Thanks. That works great. I have a global channel because I don't really know how to structure the request-handlers and shit, but it's making repl-based testing a lot easier.
14:40mdrogalisbrainkim: Glad to hear it :)
14:40mdrogalisbrainkim: Try using stuartsierra's Component framework in conjunction with that technique. I've used it more than once so far, and I'm really happy with how it turns out.
14:40mdrogalisThat way you can use smaller channels and control the lifecycle easier.
14:42bbloom,(if-let [[x & y] []] "grumble grumble" "makes sense")
14:42clojurebot"grumble grumble"
14:43justin_smith,(if-let [[x & y] nil] "grumble grumble" "makes sense")
14:43clojurebot"makes sense"
14:43rasmusto,(if-let [[x & y] []] [x y "grumble grumble"] "makes sense")
14:43clojurebot[nil nil "grumble grumble"]
14:43rasmusto,(first '())
14:43clojurebotnil
14:44bbloom,(when-let [[x] [1 2 3]] x)
14:44clojurebot1
14:44bbloom,(when-let [[x & _] [1 2 3]] x) ; i'd rather write this
14:44clojurebot1
14:44justin_smith,(let [[x & y :as z] []] [x y z])
14:44clojurebot[nil nil []]
14:44justin_smiththe :as is what if-let actually sees I think
14:44justin_smitheven if you don't bind it
14:45bbloom*shrug* maybe... destructuring works great when unconditional, but the sematnics of if-let, when-let, etc are a little flakey and seem like impl-details exposed
14:45rasmustoI don't like if-let
14:45justin_smithwhy not expand on the principle of if-let - let-defn for example
14:46amalloybbloom: you seem to be asking for nil-punning for empty vectors? like, [] is truthy, so if-let really has to treat it as such
14:47amalloyit can't know whether the destructuring accomplished your goals - it's not pattern matching
14:47rasmustois it that? I thought it was just ##(let [[a & b] nil] [a b]) ; that was the issue
14:47lazybot⇒ [nil nil]
14:47bbloomamalloy: yeah, it's what justin_smith said about the :as
14:47bbloomit makes sense, but it's kinda pattern-matchy & i forget it's not proper pattern matching sometimes
14:47amalloybringing :as into it seems, to me, just to confuse the issue, but i guess if it helps...
14:48bbloomamalloy: logically speaking, it's testing the truthiness of the :as value... when i really wish it was testing match success/failure
14:48amalloybbloom: no, it's testing the truthiness of the expression you gave it; it doesn't know anything about :as, because there isn't one
14:49justin_smithamalloy: kind of agreed, the rhs is what if-let sees and :as binds, but that rhs has no name or binding so it was a shortcut to just refer to the :as value
14:49bbloomamalloy: sure, call it "as" or call it "rhs", same thing
14:51amalloybbloom: it'd be interesting to write a destructurer that returns whether or not each variable was bound successfully. or does that basically require writing most of core.match?
14:51ghadishaybanAny good solution for lagginess in Emacs/Cider repls when the output is huge?
14:51amalloyghadishayban: clear the output buffer?
14:52bbloomamalloy: the bulk of core.match is related to optimizing the decision tree
14:52mdrogalisghadishayban: I think rkneufeld just tweeted about that lol
14:52amalloyif a single output is huge, then probably don't output it all at once
14:52mdrogalishttps://twitter.com/rkneufeld/status/453230902542622720
14:52ghadishaybanoh wow
14:52ghadishaybanso the solution is don't
14:52rkneufeldYeppers, I've been using naked lein repl and/or inferior lisp instead.
14:52amalloyslime+swank for life
14:53amalloy<- trouble-maker
14:53rkneufeldI don't know if there is something I'm not doing with Cider to make things better, but it has generally been a pain.
14:53mdrogalisI tried it and put it down, just wasn't cutting it for me.
14:54bbloomamalloy: you can make indepent design decisions regarding the pattern, the conditional behavior, and the binding behavior
14:54bbloomamalloy: our pattern syntax & binding behavior are very simple/nice, but i dislike the conditional behavior
14:55amalloybbloom: i'm not sure i follow. the conditional behavior, if i understand what you mean, is not connected to patterns/bindings at all: if-let is an ordinary if, followed by a pattern-match/binding
14:56amalloyyou could write one that's a pattern-match/binding followed by some decision based on that, but it's not close to if-let, it's close to core.match
14:56bbloomamalloy: yeah, that's a design decision (and a reasonable one)... consider what happens when destructuring fails
14:57bbloom,(let [[x] 5] x)
14:57clojurebot#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Long>
14:57bbloomin theory, the destructuring could return success or failure instead of just crashing
14:57bbloomit's a relatively small change, actually
14:58amalloyi'm not sure it's *that* small, but i agree it'd be an interesting feature (as i did say above)
14:59bbloomsmall impl change, big impact to all code, of course
14:59bblooma naive impl would be pretty slow too compared to the existing approach
15:12root__can someone explain recursion ? (defn is-even? [n] (if (= n 0)
15:12root__ true
15:12amalloyroot__: www.refheap.com
15:14root__https://www.refheap.com/73072 what does "not" do in this case ?
15:15`szx,(not true)
15:15clojurebotfalse
15:15`szx,(not false)
15:15clojurebottrue
15:15cbpteletubs: it negates the value returned from (is-even? (dec n))
15:16teletubscbp: I am lost, this code work but I don't know why ?
15:17amalloyteletubs: think of it in words, as a definition of even: "a number N is even if it is zero, or if N-1 is not even"
15:17amalloynow try it on a few samples, by hand: 0, 1, 2, and 3 should be enough to see how it works
15:17teletubsamolloy: I did
15:18amalloyi mean like on paper or in your head, not typing it into the repl
15:18amalloydoing that should help you understand *why* it works
15:27trap_exitconsider a url of the form http://localhost:8080/?blah=foo
15:27trap_exithow do I read out the "blah=foo" part in clojurescript ?
15:29dnolen_(.. js/window -location -search) if you're trying to do this on the current url, or http://docs.closure-library.googlecode.com/git/class_goog_Uri.html
15:29trap_exitdnolen_: will read up on that, thanks!
15:33miseria"cuando la causa nos enloquece, el efecto nos destruye y el fin continuara siendo un sueño" bienvenidos: http://castroruben.com *temo_a_un_ser_sin_rival*
15:34teletubsamalloy: so its doing something along the lines of 2 -> not 1 -> not not 0 which is true right ?
15:34amalloyindeed it is
15:36teletubshaha THANKS. My head was begining to spin :)
15:39RakkoWhat's the best choice of text editor integration (especially in-editor REPL, syntax highlighting/indenting support, doc and symbol lookup) for a newbie to Clojure? I'm pretty comfortable with Vim, Emacs, and Eclipse.
15:40justin_smithRakko: if you know all equally, Emacs has the best integration
15:40Rakkocool
15:40bmabeythe others are decent too so you can't go wrong
15:40RakkoI have a tiny bit of experience with CL in SLIME
15:40bmabeyemacs does have the most mindshare however
15:42teletubsHow about big-integer recursion? https://www.refheap.com/73077
15:43justin_smith,(dec (BigInteger. "1")) ; it should just work
15:43clojurebot0N
15:44cbpteletubs: you don't need to distinguish between long and BigInteger in clojure
15:44justin_smiththough really there are better ways to check even / odd status than iterating until you hit 0, that is merely a good way to demonstrate recursion, not a good way to do that task
15:44justin_smith$source even?
15:44lazyboteven? is http://is.gd/LyGOJD
15:44amalloy&(inc Long/MAX_VALUE) ;; cbp
15:44lazybotjava.lang.ArithmeticException: integer overflow
15:45justin_smithteletubs: see lazybot's link above for the right way
15:46justin_smithteletubs: though extending *that* to bigints (probably by doing modulus) would be interesting
15:47justin_smithor maybe a bigint bit-mask if such a thing exists
15:47amalloyjustin_smith: it works fine for bigints, doesn't it?
15:47amalloyan unchecked cast to long should just drop off the top N bits
15:48cbpOk i mean you don't need to use the BigInteger methods when dealing with bigintegers, if your function gets passed a bigint it will work
15:48justin_smith,(bit-and 1 (long (BigInteger. "11111111111111111111111111111111111111111111111111111111111")))
15:48clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for long: 11111111111111111111111111111111111111111111111111111111111>
15:48justin_smithamalloy: or what did you have in mind?
15:49amalloy,(even? (BigInteger. "11111111111111111111111111111111111111111111111111111111111"))
15:49clojurebotfalse
15:49amalloy,(unchecked-long (BigInteger. "11111111111111111111111111111111111111111111111111111111111"))
15:49clojurebot1857484646311031239
15:49justin_smithoh, never mind then, thanks
15:50cbpyou can just add N to the end to turn it into a bigint :-P
15:54justin_smith,(= (BigInteger. (apply str (repeat 226 \1))) 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111N)
15:54clojurebottrue
15:56teletubsamalloy: What is going on inside of that loop?
15:57justin_smithteletubs: do you mean the source to even? - if so, that is not a loop
15:57amalloyhe means the refheap he pasted earlier
15:57teletubsjustin_smith: https://www.refheap.com/73077
15:57amalloytail-recursive even
16:08tbaldridgeoh awesome....tools.cps is getting a re-work with tools.analyzer http://www.chrisfrisz.com/blog/2014/04/06/progress/?utm_source=dlvr.it&amp;utm_medium=twitter
16:09bbloomtbaldridge: neat, but i've got my eyes locked on dynamic extent :-)
16:10tuft_,(def foo.bar 2)
16:10clojurebot#'sandbox/foo.bar
16:10tuft_,foo.bar
16:10clojurebot#<CompilerException java.lang.ClassNotFoundException: foo.bar, compiling:(NO_SOURCE_PATH:0:0)>
16:10bbloomtbaldridge: i'm definitely going to attempt what you suggested w/ JIT-compiling via clojure.core/eval
16:10rasmusto,#'sandbox/foo.bar
16:10clojurebot#'sandbox/foo.bar
16:10tuft_ah ok, thanks
16:11rasmustotuft_: I don't know what I just did
16:11bbloomtbaldridge: should be pretty doable to (clojure.core/eval `(fn [] ~(unparse ast)))
16:11tuft_tuft: er, actually yeah =)
16:11rasmusto,(identity foo.bar)
16:11clojurebot#<CompilerException java.lang.ClassNotFoundException: foo.bar, compiling:(NO_SOURCE_PATH:0:0)>
16:11tuft_,@#'foo.bar
16:11clojurebot2
16:11tuft_gross but works
16:11rasmustois it a clojurebot reader thing?
16:12tuft_i guess avoid dots in symbol names
16:12amalloyyou're "not supposed to" use symbols with dots in them
16:12rasmustooh, its looking for a class
16:12justin_smithrasmusto: all that will work the same in a repl
16:12justin_smithreader rules
16:12amalloyjustin_smith: not reader, evaluator
16:12rasmusto,(def -.-.-.- 2)
16:12clojurebot#'sandbox/-.-.-.-
16:12justin_smithoh, ok
16:12amalloyfoo.bar reads as foo.bar
16:13rasmusto,@#'-.-.-.-
16:13clojurebot2
16:14justin_smithis there a matching trick in let?
16:14sritchie_justin_smith: what do you mean?
16:15justin_smith,(let [... :silence] (apply str (repeat 2 (name ...))))
16:15clojurebot#<CompilerException java.lang.ClassFormatError: Illegal field name "..." in class sandbox$eval186, compiling:(NO_SOURCE_PATH:0:0)>
16:15justin_smith#' will not work there clearly
16:15justin_smithit's just a weird corner case of course
16:16michaniskinis there something like :refer-clojure that i can use in a ns declaration to exclude java mappings? like java.lang.Error is mapped to Error, for instance
16:17amalloymichaniskin: no, you're stuck with java.lang afaik
16:17clojurenewbhi, anyone know how to group a bunch of selector/transformer pairs to be able to re-use them with laser ?
16:18michaniskinamalloy: thanks :/
16:21justin_smithclojurenewb: I think you can make a map with selectors as keys and transformers as vals, then use apply
16:21justin_smithhmm... that could require a mapcat also
16:21amalloyclojurenewb: tell Raynes to release 2.0.0 - it turns those pairs into just vectors, so that you can hang onto them and combine them with just like (list pair1 pair2 pair2)
16:22amalloyhe's apparently been on 2.0.0-SNAPSHOT for nine months
16:22RaynesAnd decreases performance by about 400%.
16:22RaynesHaven't had time to figure that out yet.
16:22amalloyfeh, performance is for chumps
16:22RaynesApologies.
16:23clojurenewbso is the plan for now this map idea ?
16:23RaynesEither way, selector and transformers are just functions. I'm pretty sure you can compose them in a reusable way in any version of laser.
16:23justin_smithbased on an example, maybe something like this: (apply laser/document (laser/parse html) (apply concat {(laser/id= "hi") (laser/content "omg") (laser/class= "meow") (laser/content "omg)}))
16:23technomancy`clojurebot: it?
16:23clojurebotit is &env and &form
16:24amalloya map sounds like a terrible idea, because you'd lose ordering
16:24technomancy`hm; I was hoping for "it is just a function"
16:24justin_smiththough in practice the map would not be defined inline with the call of course
16:24technomancy`which I'm sure is buried in there somewhere
16:24RaynesI guess you can compose selectors and transformers individually, but not together.
16:24RaynesThat blows.
16:24amalloywell yeah, Raynes, that's why you made the changes in 2.0.0 :P
16:25RaynesI thought the reason was "this fundamentally makes more sense"
16:25RaynesI never realized that it was actually adding features.
16:25justin_smithamalloy: fair point, so the map could be replaced by a vec of alternating selector / transformer, or a vec of two element selector / transformer vecs
16:25clojurenewbmy only idea now is to combine then in some other element and re-write that… not a great idea
16:25RaynesAnyways, there are a few bugs in the 2.0.0 snapshot and the changes are woefully undocumented as such, but it works for the most part. It's slow as hell.
16:26vendethielwhat'd be the clojure community "framework of choice" for clojure (and maybe clojurescript)?
16:26RaynesIf all of those things are okay with you for now, then you can use that.
16:26vendethielluminus?
16:26justin_smithanother try: (apply laser/document (laser/parse html) [(laser/id= "hi") (laser/content "omg") (laser/class= "meow") (laser/content "omg)])
16:26Bronsamichaniskin: you can use ns-unmap though
16:26RaynesI think the Clojure community is too large for there to be any one canonical anything, vendethiel.
16:27RaynesLuminus is a great way to start.
16:27vendethielRaynes: that's the idea :)
16:27RaynesSome folks like Pedestal.
16:27RaynesI'm a compojure guy.
16:27RaynesI support luminus, if that matters to you at all.
16:27Raynesyogthos gets stuff done.
16:27RaynesI pretend to help.
16:28vendethielwell, I'm certainly interested at something that shows clojure's best parts, not something that "gets stuff done" but is hacky (if that's what you meant)
16:28clojurenewbjustin_smith: I don’t think thats what I am looking for, that is one selector and multiple transformations
16:28mynomotovendethiel: I think Hoplon is a good framework.
16:29justin_smithclojurenewb: really? it should bbe taking them pairwise
16:29vendethielmynomoto: thanks, noted
16:29justin_smithclojurenewb: so two selectors in the example I adapted above
16:30clojurenewbjustin_smith: I will see if I can get it to work, thanks
16:31justin_smithI assume laser/document takes any number of alternating selectors and transformers, if so that would be the usage pattern for reusing some set of selectors / transformers repeatedly
16:31justin_smiths/the/a
16:34clojurenewbjustin_smith: oh.. ‘Don't know how to create ISeq’ when I pulled in a function that used ‘apply’ over a few pairs of selector/transformer (pulled in to a defdocument)...
16:35yogthos@Raynes I just mostly glue stuff together and document it :P
16:36Raynesclojurenewb: I really don't think you can do this without digging into the 2.0.0 snapshots.
16:36RaynesThat whole branch of development is adding the feature you want.
16:36RaynesIt's very similar to compojure's middleware.
16:37RaynesCompiles all selectors and transformations into functions calling functions calling functions (yo dawg).
16:37RaynesAnd gives you the power to do that.
16:37justin_smithclojurenewb: they should be all in a flat list, not pairs
16:37clojurenewbRaynes: ok thanks… I probably can’t use it yet though as you mentioned the preformance difference… its to go into production :-)
16:37justin_smithlist/vector/whatever
16:37clojurenewbjustin_smith: I’ll try again
16:38Raynesclojurenewb: Well, the version you're using probably isn't bleeding fast fwiw. Enlive is inevitably much faster as Christophe put a lot of effort into making that be the case.
16:38michaniskinBronsa: ns-unmap was just the thing. thanks!
16:38RaynesI put a lot of effort into keeping the code base as small and trivial as possible.
16:39clojurenewbRaynes: I think laser is awesome by the way… did not mean to sound negative, thanks for a cool library
16:40RaynesOf course! Feel free to yell at it or me at any time. I've dug myself this hole by letting 2.0.0 go unworked on for so long despite squeeling for two months about how laser was going to be better maintained than enlive.
16:40RaynesIt certainly isn't abandoned though. I just need to spend a weekend or so on it.
16:41clojurenewbI know the feeling… so much to work on, so little time
16:45blake__Trying to comprehend this function definition, specifically the meaning/purpose of the "->": (defn func->func-info [func]
16:46bbloomblake__: it's just part of the name
16:46bbloom,(symbol "foo-><-bar")
16:46clojurebotfoo-><-bar
16:46bbloom,'<><><><>---<><<><---,
16:46clojurebot<><><><>---<><<><---
16:47blake__oh...huh...not used to all the punctuation yet...just got accustomed to minus signs not being minus signs =P
16:47rasmusto,(let [map->vec (fn [m] (mapv vec m))] (map->vec {:a 1 :b 2}))
16:47clojurebot[[:b 2] [:a 1]]
16:47tuft_blake__: even the minus sign is just a symbol name in clojure =)
16:47rasmusto(bad example, just showing the naming) :P
16:47justin_smithblake__: rule of thumb, anything but ()[]{}#. will be part of a name unless separated by some space
16:48bbloomjustin_smith: eh... or ~ or @ or , or a lot of things
16:48blake__Right...that's another one that gets me--significant spaces.
16:48bbloomblake__: the AMOUNT of space isn't significant. just the fact that it exists...
16:48justin_smitheven in c ab isn't the same as a b
16:49rasmustoquantity of space shouldn't matter though :)
16:49bbloomblake__: while we're at it... commas are whitespace in clojure
16:49blake__right...significant space...well, punctuation not used a separator...not complaining, just retraining the brain...
16:49bbloom,(+ 5 ,,,,,,,,,,,,,,,,,,, 10)
16:49clojurebot15
16:50blake__bbloom: That I knew and adapted to quickly. For whatever reason.
16:50rasmusto ,(,,+,,5,,,,,,,,,,,,,,,,,,,10,,)
16:50clojurebot15
16:51bbloomcommas as whitespace is one of those awesome ideas i could have never though of in a million years
16:51jcromartietrying to figure out how to render (╯°□°)╯︵ ┻━┻ as a symbol
16:51jcromartieI mean usable
16:51bbloom,(symbol "(╯°□°)╯︵ ┻━┻")
16:51clojurebot(?�?�??? ???
16:51bbloomheh
16:51rasmustoAHhaha
16:51blake__heh
16:51justin_smith&(symbol "(╯°□°)╯︵ ┻━┻")
16:51lazybot⇒ (╯°□°)╯︵ ┻━┻
16:51jcromartiewell aside from that
16:51justin_smith(inc lazybot)
16:51lazybot⇒ 24
16:51jcromartie:P
16:51bbloomno, don't reward lazybot for unicode support!
16:52bbloomit's fucking 2014
16:52bbloom(dec clojurebot)
16:52lazybot⇒ 39
16:52justin_smithhah
16:53amalloytruly we are in the future, where computers can recognize, like any sane person, that ┻━┻ is text
16:54rasmusto^I disagree
16:55technomancyclojurebot: ┻━┻ is text.
16:55clojurebotc'est bon!
16:55hiredmanring and the servlet api defaults to iso whatever
16:57technomancytechnically the IRC RFC states the encoding of messages is "unspecified"
16:58technomancyclojurebot: ┻━┻?
16:58clojurebot┻━┻ is text.
16:58technomancythe you have it
16:58technomancythere
16:58AmandaCMost of the english-speaking world has settled on UTF-8 for IRC though.
16:58justin_smith,(let [(╯°□°)╯︵┻━┻ (fn [WTF] (throw WTF))] ((╯°□°)╯︵┻━┻ (Exception. "TABLE"))
16:58clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
16:58justin_smithhmph
16:59technomancyAmandaC: sure; being pedantic
16:59AmandaC:p
16:59technomancy"You are technically correct." / "Which is the best kind of correct; amirite?"
16:59justin_smith,(let [(╯°□°)╯︵┻━┻ (fn [WTF] (throw WTF))] ((╯°□°)╯︵┻━┻ (Exception. "TABLE")))
16:59clojurebot#<Exception java.lang.Exception: TABLE>
17:01modulusHi, I'm having an odd issue with korma, I think related to macros. Say I have a db table called widgets. I can't do this:
17:01modulus(select wiedgets (if true (where {:id 1})))
17:01modulusI get a wrong number of args for where
17:02modulusthough (select widgets (where {:id 1})) works fine
17:02justin_smithmodulus: macros are weird
17:02modulusi need to be able to build conditional where clauses, so any clues how to go about it instead?
17:03justin_smithmodulus: to programmatically interface with code that is a macro, you should make another macro
17:03justin_smith(or find a non-macro-using way to do it, of course)
17:03modulusthat sounds like an awful idea....
17:03justin_smithremember that if is a macro
17:03scape_I'm having trouble with gen-class and creating my own class, I mocked up an example to show what I mean. #<CompilerException java.lang.ClassNotFoundException: cljtest.core.Test, compiling:(cljtest/main.clj:4:1)>
17:03justin_smith(if true (select widgets (where {:id 1})))
17:03scape_https://www.refheap.com/73085
17:05justin_smithmodulus: since a macro represents a changed syntax, it often won't do what you want with arbitrary inline values, which is why the solution is usually use yet another macro, or don't use macros in the first place
17:06modulusnwjsmith___: yeah but the problem is i need to build quite a few different where conditions, depending on several things, so if i have to put the select in the if i'm pretty screwed.
17:06moduluser wrong completion, apologies.
17:07justin_smithnp. Yeah, I would check if korma has a layer that just uses vanilla data as input. If not, construct the call in your own macro or don't use korma?
17:08modulushmm maybe the starred forms will work, I'm going to try that
17:08hiredman,(symbol "(╯°□°)╯︵ ┻━┻")
17:08clojurebot(╯°□°)╯︵ ┻━┻
17:09justin_smith,'(╯°□°)╯︵┻━┻
17:09clojurebot(╯°□°)╯︵┻━┻
17:09justin_smithsweet
17:09scape_Why do I receive a classnotfound when compiling my code? am I using gen-class wrong? what am I missing?
17:10justin_smithscape_: maybe try putting the constructor in a function so it is not called at load time, but can be delayed until after everything else is loaded and compiled?
17:11justin_smithscape_: since classes can have side effects at creation time, putting a constructor at the top level is probably a bad idea anyway
17:11justin_smith(otherwise loading the namespace has sideeffects, which is bad)
17:12scape_i'll try that
17:12justin_smithalso, I am not totally sure what that ^:skip-aot does, but it is suspicious
17:13scape_it shipped with my lein new app, I removed it and tried aot it also received same error
17:15modulusheh starred forms don't ... quite ... do it
17:15scape_justin_smith: I got the idea from here https://github.com/libgdx/libgdx/wiki/Using-libgdx-with-Clojure
17:15scape_where they use a class to initiate the game
17:15scape_i'll try another way, thanks :)
17:16justin_smithscape_: yeah, but they do the right thing and make the instance inside -main
17:16justin_smiththat is different from the top level, -main should actually have side effects
17:17justin_smithand you should probably similarly create the class inside -main - or restructure things and not use classes, since usually that pattern of usage is for when you are using some lib that is from java, and there is no need if the defining code is clojure
17:19scape_this is true, i also couldn't get their code to compile :-\ but the lib is from java hence the class thing. I probably have an alternative i'll check out
17:20modulushmm so
17:20modulus(-> (select* widgets) (where {:id 1}) (select)) works
17:20modulusbut again, using if breaks it
17:20modulusi don't understand what's going on with the macros here which is confusing me
17:21justin_smithscape_: if you have something that should always be a singleton, you can just have a namespace with an init function and some vars for "fields" and defns for "methods" (if the fields are not immutible the var should hold a ref or atom). Otherwise there are things like a defn that returns a map plus some functions that expect that map as an arg.
17:21rasmusto,(macroexpand (-> (select* widgets) (where {:id 1}) (select)))
17:21clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: select in this context, compiling:(NO_SOURCE_PATH:0:0)>
17:21rasmusto,(macroexpand '(-> (select* widgets) (where {:id 1}) (select)))
17:21clojurebot(select (where (select* widgets) {:id 1}))
17:24modulushow do i see the expansion of a macro?
17:24justin_smithmodulus: same way rasmusto did
17:24justin_smithmodulus: quote the form, and call macroexpand on it
17:25modulushmm
17:25modulusi forgot to quote
17:29tuftwas using this handy datomic-schema lib, but the side-effecting defs bit me https://github.com/Yuppiechef/datomic-schema/blob/master/src/datomic_schema/schema.clj
17:29modulusheh, some weird transform
17:29modulus(macroexpand '(-> (select* widgets) (if true (where {:id 1}))))
17:29modulus(if (select* widgets) true (where {:id 1}))
17:29modulusI've no idea how the first becomes the second
17:29tuftwere i to refactor, is the clojure test approach the way to go? i.e. use (ns-interns) instead of what this is doing with atoms?
17:29justin_smithmodulus: -> is a macro, it just inserts each form into the next
17:31justin_smith,(macroexpand '(-> long (very and boring) (a story)))
17:31clojurebot(a (very long and boring) story)
17:31modulusahh, i see now, so the problem is the if is being threaded
17:31justin_smithwell, a form is being threaded into if, but yeah
17:32modulusi thought if would execute first for some reason
17:32rasmustomodulus: yeah, stuff like that gets messy, and can be worked around (messily) with #(if blah % somethingelse)
17:32justin_smith~macros
17:32clojurebotBarking spiders!
17:32rasmusto~macro
17:32amalloynot sure whether to inc or dec clojurebot for that...
17:32clojurebotHoly Crap.
17:38modulusWell, thanks; I still don't know how to do conditional wheres but I'll think about it.
17:39justin_smithYou could make a function that constructs the form to be called at compile time. What could go wrong with that?
17:44tuftneed to stop programming clojure. python code getting hard to look at. =)
17:44bohfordhard to go back isnt it
17:44tufti keep trying to do structural editing, too
17:45rasmustomap(lambda x: x + 1, [1, 2, 3])
17:46justin_smiththere are also things like the runtime that will gladly let libraries write outside array bounds
17:46justin_smith(that whole "reading a utf7 web page corrupts your couchdb instance" bug for example)
17:47rasmustomap(lambda x: x.append("foo"), [[1, 2] ["a", "b"]])
17:47rasmustowhoops, missed a comma
17:49amalloyi just looked up utf-7. who would ever use that?
17:49justin_smithamalloy: no idea? but if a webpage says it is utf7, one should parse as utf7 or fail I guess
17:50bbloomisn't that for like MIME headers or something?
17:50bbloomyeah, imap uses it b/c email headers have to be in ascii
17:51bbloomso basically no one would ever use it... if they could help it
17:51justin_smithhttp://rspeer.github.io/blog/2014/03/30/unicode-deadbeef/ title is funny (they blame text encodings rather than the insecure architecture of their runtime)
17:59tbaldridgeunicode in Python is a mess anyways
18:00justin_smithI am tempted to generalize that statement
18:00tbaldridgetrue
18:00tbaldridgebut there are times where python obeys the encoding of the terminal the interpreter is started in
18:02justin_smithyou could generalize over "unicode" or "Python" actually
18:02justin_smiththe intersection is of course a little quagmire
18:33scape_justin_smith: got my test class to compile, I threw it in a main and then put :aot :all in project file. now i'll try fixing my actual issue with the java lib i'm using. thanks for the ideas
18:34justin_smithscape_: glad you worked it out
18:34justin_smithit should suffice to only aot the :genclass ns
18:35scape_yea, i figured but wanted to make sure :)
18:35justin_smithyeah, easier to have something that works and refine from there, to be sure
18:38NicoArghello :) im from argentina
18:38justin_smithhello
18:39NicoArgchat me.. i dont kwnow write in english so much haha
18:39NicoArgi want learn more
18:40rasmustoNicoArg: http://www.clojurebook.com/ http://joyofclojure.com/
19:04amalloyhuh, another function i didn't know was in clojure.core: find-var
19:04amalloyi've always seen resolve used instead
19:05`szxamalloy: just saw your response re: the missing reducers - so you're saying in principle you don't see any reason why one shouldn't use r/drop-while, r/map-indexed, etc.?
19:05tuft,(find-var `str)
19:05clojurebot#'clojure.core/str
19:05tuftcool
19:05bbloomhuh, how does it differ from ns-resolve? it only does namespace qualified vars?
19:06`szxs/use/implement i guess
19:06amalloy`szx: implementing transformers like that isn't too bad - it's implementing new sources entirely, like range or repeat, that's fraught with problems
19:08amalloybbloom: well, ns-resolve uses the current namespace (including ns aliases), and also lets you resolve in a different namespace
19:08amalloyit looks like find-var only accepts canonical names
19:08bbloomamalloy: makes sense
19:11justin_smithyeah, seems like find-var reduces the complexity and removes a potential failure point if you know the full ns and don't care about aliases
19:15gtrakif you tap into a mult, and that target channel is closed, seems like we need to untap it from the mult, too? What's the expected effect if you don't? also, if one of the taps of the mult has a full queue, does that also block the mult, and consequently all other taps?
19:19justin_smithI am trying to figure out how to use cemerick/friend - is there some simple example of using a :credential-fn (or replacement for one?) that does not require a map with an entry for every user?
19:19justin_smithI already have users in a db, and having to update some map every time I update the db seems like the wrong thing
19:21hiredmanjustin_smith: https://github.com/hiredman/ideapad/blob/master/src/com/thelastcitadel/ideapad.clj has a lot of moving parts, but it uses friend to do basic auth, authenticating a user against another service with a rest api
19:21justin_smithhiredman: awesome, thanks
19:22hiredmanjustin_smith: I think the thing you are missing is it doesn't have to be a map, it can be any function that takes a username and returns whatever friend wants
19:22hiredmanfor :credential-fn
19:22justin_smithah, that is much better, and totally compatible with my setup
19:24justin_smith(inc hiredman)
19:24lazybot⇒ 39
19:27bbloomamalloy: what i really need is ns-resolve that doesn't find java classes...
19:28oinksoftbbloom, why?
19:29bbloomoinksoft: crazy esoteric experiment bootstrapping reasons
19:32oinksoftbbloom, i see, just curious :)
19:38kenrestivoX-In-Like-Flynn? o_0
19:39hiredmanI needed to add an extra header for some reason which I no longer recall
19:39technomancyflynn from tron?
19:40justin_smitherrol flynn's autobio is a rollicking tale, btw
19:41hiredmanit rhymed *shrug*
19:46bbloomhow do people feel about the distinctions between clojure.core and cljs.core ?
19:46bbloomiirc, one gets re-routed to the other, right?
19:48oinksoftis it normal to design a clojure program around records/protocols?
19:48justin_smithoinksoft: in my experience program no, but library yes
19:49oinksoftjustin_smith, this is a logging library
19:49justin_smiththen yes, please do it that way
19:49bbloomi just replaced about 15 record types with two record types. my program got simpler AND faster
19:49justin_smithawesome
19:50oinksoftbbloom, i didn't bring it up yet, but performance was once concern i had about using a bunch of protocols. do i pay for that at compile time or runtime?
19:50bbloomyes
19:50oinksofthaha
19:50oinksoftok
19:50hiredmanmegamorphic calls not fast, news at 11
19:51bbloomoinksoft: seriously though, start with a multimethod if you only have one generic function.
19:51bbloomonly define a protocol if you need it
19:51bbloomonly define a record or deftype if you need it
19:51bbloombasically, use plain old data unless you need to dispatch on type a lot
19:52oinksoftbbloom, OK that was what i was wondering about. as i was designing i could see how most parts of it could be described through protocols
19:52bbloomoinksoft: that *might* be true for your problem or it could be brain damage from past languages
19:52oinksoftbbloom, in erlang it's normal to use a record /-type for anything because you only pay for that at compile time
19:52sdegutisHow do you usually distribute a .jar file created with `lein uberjar` but from another project than your own? I'm trying to distribute REPLy to my remote server.
19:52bbloomoinksoft: i couldn't tell you unless i tried to implement whatever you're implementing ;-)
19:52oinksoftbbloom, so i didn't just want to go headlong into doing it in the erlang way :P
19:53oinksoftbbloom, sure, let me provide a concrete example
19:53bbloomoinksoft: i dunno much erlang, but it's probably better to go erlang -> clojure style than to go java -> clojure style :-P
19:53technomancyerlang uses records in a lot of places simply because proplists are ugly and maps are too new
19:53technomancyclojure luckily has had maps since the start =)
19:54gtrakmaps, fancy
19:54oinksoftbbloom, as i typed out the concrete example i got my answer, this was not a place for a record/protocol
19:54technomancygtrak: http://thisotplife.tumblr.com/post/81168432835/when-i-heard-erlang-now-has-maps
19:54bbloomha
19:54sdegutisIt seems wrong to just compile the jar and stick it into my git repo..
19:55bbloomsdegutis: it is
19:55oinksofttechnomancy, heh i have no problem w/ records, keep programs simple
19:55gtrakhah
19:55sdegutisI could clone REPLy and create an uberjar on-demand, and use that..
19:55oinksofttechnomancy, proplists are mostly *slow*
19:55sdegutisIt seems equally wrong to make REPLy a submodule of my repo.
19:55gtraksdegutis: that IS wrong
19:55sdegutisgtrak: which one
19:55gtrakthe first
19:55sdegutisOkay yea.
19:55technomancyoinksoft: maybe they don't seem as ugly if you aren't accustomed to maps =)
19:56oinksofttechnomancy, probably more like stockholm syndrome
19:56gtraksdegutis: is reply pure clojure? just eval it :-)
19:56bbloomoinksoft: fast immutable maps are LIFE CHANGING
19:56oinksoftbbloom, ah well those i havent used yet, except now in clojure
19:57sdegutisgtrak: I don't want Leiningen on the remote server, just Java.
19:57technomancygtrak: also http://thisotplife.tumblr.com/post/76346999236/other-peoples-reaction-when-i-say-erlang-is-about-to
19:57sdegutisgtrak: REPLy is only gonna be there for debugging etc.
19:57gtrakwell, the normal clojure repl is always there, if it's a clojure app.
19:57gtrakyou can eval arbitrary strings in there, which can include full libraries if you're trying hard enough :-)
19:58gtrakgotta run though, later
19:58sdegutisAlternatively maybe I can compile REPLy into my app, and just run it through my app...
19:59sdegutisThat seems the easiest but maybe not the cleanest route.
20:03oinksoftwhat does it mean if i see (def fn (partial fn* unbound-thing)) ? where does unbound-thing come from?
20:04oinksoftif it matters, unbound-thing is also the name of a protocol method
20:05hiredmanprotocols don't have methods
20:05hiredmanthey are collections of functions
20:05oinksoftwasn't sure of the terminology
20:05oinksoft*function
20:06hiredmanthat name is the name of a function, just like (defn foo ...) and foo names a function (it actually names a var which holds a function but whatever)
20:08oinksoftbut there is no (defn unbound-thing) in this source file or imported
20:08hiredmanoinksoft: you said it is part of a protocol
20:09oinksofthiredman, it is, (defprotocol Proto (unbound-thing [arg] ....))
20:09oinksofthiredman, this defines unbound-thing, unqualified, globally to my source file?
20:10oinksofthiredman, that seems weird, what if i define two protocols that happen to share a function name
20:10hiredmanoinksoft: they have to go in different namespaces
20:11bbloomoinksoft: what happens if you name two functions the same thing?
20:11hiredman^-
20:12bbloomoinksoft: by "unbound" do you mean "unqualified"
20:12oinksoftoh!
20:12oinksoftWarning: protocol #'user/P is overwriting function f
20:12oinksoftthis is surprising but now i know what is happening
20:12bbloomwhy is this surprising?
20:12oinksoftbbloom, well typically if i don't spend jack shit to study something i just understand it, you know? ;)
20:13bbloom*shrug*
20:13oinksoftbbloom, if a protocol is just a collection of functions that can operate on a record type, it makes a lot more sense
20:13oinksoftbbloom, i was thinking about this inside-out
20:13bbloomthey can operate on any JVM type
20:13bbloomplus nil, which isn't really a type :-P
20:13oinksoftyea, this is very nice
20:15oinksoftbbloom, hiredman, thanks for the help
20:20tadni-Are there any introductory (as in near to complete beginner) to programming text, in Clojure? All I can find assumes prior knowledge.
20:20technomancytadni-: I don't think anything like that exists. clojure is not a great language to learn programming in.
20:21bob2suspect you'd be better off starting with python or ruby
20:21technomancyheavens no
20:21technomancystart with racket
20:21technomancyI mean, unless you are looking to use it professionally with little delay
20:22amalloyguys i found an amazing feature slime/swank has that's not present in cider: swank.core/read-from-emacs-minibuffer
20:22technomancyamalloy: I implemented that in nrepl-discover =P
20:22amalloythere's y-or-n-p support in there as well, although it's hidden
20:24tadni-I've been looking into elisp, for a practical skillset I could learn. Pretty sure they have an introductory text.
20:24Bronsaamalloy: woah
20:25technomancytadni-: elisp is certainly more practical than racket. unfortunately it is very imperative. but the built-in intro is good, and the first half of Practical Common Lisp is very relevant too.
20:25amalloyi don't know how i would use that, technomancy. even reading through the docs and the source for nrepl-discover
20:25technomancynrepl-discover has docs??
20:25lazybottechnomancy: Uh, no. Why would you even ask?
20:25Bronsanow I need to find a way to use that
20:25amalloywell it has a readme
20:25technomancyyeah
20:25technomancyit's pretty half-baked ATM
20:25amalloyBronsa: i actually discovered it because i had a way to use it!
20:25technomancybut it's a lot nicer to extend than swank
20:26scape_is it possible with leiningen to have it include certain dependencies based on something specific when running lein?
20:26amalloywriting a program for work that prompts the user to fill in the blanks in some auto-generated data; i was giving it swappable ui bits, for gui/cli, and discovered i could add a slime/swank backend for myself as well
20:26BronsaI feel a bit bad not using nrepl/cider but everytime I tried moving from slime/swank I ended up switching back after less than a day :(
20:27technomancyscape_: sure, as long as "something specific" is "which profiles are active"
20:27scape_okay, so it's profiles I should look into? thanks technomancy
20:29amalloyBronsa: see also (#'swank/send-slime-command-to-emacs-and-wait :y-or-n-p prompt)
20:29amalloysadly that's a bit fragile - if you C-g out of it, clojure gets really sad
20:30technomancyamalloy: in nrepl-discover you just attach metadata to a function that says it's a command that should be invokeable from the editor
20:30technomancyyou can even provide various completion options
20:30amalloytechnomancy: how does that help?
20:30amalloythe goal is to go the other direction: let clojure call y-or-n-p
20:30amalloyor, anyway, the goal of this feature in swank
20:30technomancyoh, but you can't prompt in the middle of an existing function call; never mind
20:31amalloyi have like (when (y-or-n-p "dude this looks bad, are you sure?") (jdbc/delete-everything-forever))
20:32technomancyyeah, nrepl is request/response
20:32technomancyno SSE
20:38tadni-Ok
20:38tadni-Well, thanks for the advice tech.
20:38tadni-I'll look into racket more in-depth.
20:38tadni-Peace people.
20:40technomancyoh he left before I could recommend HDTP =(
20:40technomancyHTDP rather
20:41cespareWhat's the general convention for naming your deftest? I've been browsing some popular projects and it seems like a common choice is either just the name of the general thing/concept (e.g. 'deftest serialization') or to suffix with -test if it's a unit test for a function ('deftest conj-service-test')
20:41amalloyi was in the middle of telling him he could use tab-completion instead of calling you tech
20:41cesparesome folks use test- as a prefix instead
20:42amalloynaming of tests is the wild west. stake your claim
20:42cespareamalloy: I'm coming up with a recommendation to replace the insano practice we seem to have here of calling it foo-bar-works-as-expected
20:42cespare:)
20:44krascan I control the number of threads spawned by pmap/pcall?
20:44krasEmulating a thread pool
20:45hiredmanyou don't, so use a thread pool
20:45hiredman~pmap
20:45clojurebotpmap is not what you want
20:45`szxkras: again, https://github.com/TheClimateCorporation/claypoole
20:49kras`szx: this seemed like a basic usage and I thought the language ought to have some built-in
20:49krassorry for the repetition
20:50`szxkras: no worries. nothing built-in afaik
20:51krasso when I say (pmap inc [1 2 3 4 5]) it spawns 5 threads?
20:51hiredmanno
20:51hiredmanit is much more annoyingly complicated
20:52kras:-(
20:52hiredmanright, it is a gimmick, looks good in demos, is bad
20:56hiredman,(doc pmap)
20:56clojurebot"([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."
20:57gfredericks"... and where function execution times have a low variance."
21:01hiredman"... and watch out for chunked seqs"
21:02gfredericksreally?
21:02gfredericksis pmap implemented in ignorance of chunking?
21:04amalloyyes
21:04amalloypmap is implemented in ignorance of everything
21:04gfredericks,(->> (range 10) (pmap print) (first))
21:04clojurebot#<SecurityException java.lang.SecurityException: no threads please>
21:05gfredericksthat's exciting
21:06amalloyi wrote like a mediocre pdorun earlier: https://www.refheap.com/feee08c4a29bbd104005e5240
21:08hiredmanwe have a pdoseq at work, which I like, because I wrote it, but no one else has ever used it
21:08gfredericksthere's a library that wraps all the executor stuff
21:08gfrederickshas its own pmap & such
21:08amalloyexecutors are fine though
21:09gfredericksa little bit noisy if you use them a lot
21:09amalloyand pmap using wrapped executors doesn't sound likely to be much better than clojure.core/pmap anyway?
21:09gfredericksI haven't jumped to using said library though so apparently I'm on your side of it
21:10gfrederickswell if you do it eagerly you're at least not subject to variance issues
21:10amalloylike, for my do-jobs, i was able to run job n+100, even if job n takes a really long time
21:10amalloy(because i don't care about order)
21:10gfrederickssure; but executors can do that
21:11amalloypmap needs to be eager to make that possible
21:11gfrederickssure
21:11gfredericks(like I said)
21:11amalloyright. it's just, you were saying it offhand, like "and pmap has to be eager". but that's a big deal
21:11gfredericksI say all my big deals offhand
21:12hiredmanI really want some like (pipeline [queue-size threadpool-size some-function] [queue-size threadpool-size next-function] [" " "] ...)
21:12gfredericksI guess my hunch is that most people who jump to pmap care a lot more about parallelizing than they do about laziness
21:20hiredmanclojure.core really doesn't have anything good for organizing multithreaded io stuff
21:22bob2may want claypoole
21:22gfredericksI think that's the library I was mentioning
21:32nopromptdnolen_: yeah, we have no idea what's causing the random errors. they're generally weird occasionally related to a ^@ character which we have idea what it's about.
21:32nopromptjava.lang.Error: Not a valid base 64 digit:
21:32nopromptit could be a library but it's hard to say.
21:34nopromptit still seems to be source-map related though. that last error comes from cljs.source-map.base64/decode.
21:57kenrestivoi feel bad for the guy who made gorilla. great idea, but now he's likely to get mired in browser incompatibility hell.
21:57kenrestivos/gorilla/any web app/g
22:23scottjkenrestivo: I felt bad for him because right after gorilla was released session was released and had a clojure/west talk and since they looked similar to me on first glance I thought gorilla would get overshadowed, but it appears that they have roughly the same number of github stars so I guess they're both doing fine.
22:34zanesHas anyone had issues AOT-compiling core.match :or expressions?
22:34zanesI think I may have found a regression.
23:16Jaoodis there a function to get only the values that have been realized in a lazy-seq?
23:18amalloyJaood: see: (doc take-while), (doc realized?)
23:18mercwithamoutho_O i'm looking at zippers and wow am i 'comfused'
23:25amalloymercwithamouth: i suggest you don't worry about it - you don't need zippers, whatever your problem is
23:26Jaoodamalloy: thanks
23:26mercwithamouthamalloy: good to know. i'll add them to my todo list and come back
23:27amalloyi guess the exception is "help someone gave me a zipper how do i use it"
23:27mercwithamouthdefinitely something i'd like to have a strong hold on but right now they're making my head hurt
23:27mercwithamouthi'm just going through 'clojure programming'
23:28Jaoodmercwithamouth: what page?
23:28mercwithamouthJaood: 152
23:29mercwithamouthskipping to concurrency and parallism...
23:29Jaoodhah
23:29Jaoodyou are ahead of me, page 95 still
23:31Jaoodamalloy now me wonder if I should skip that part too
23:33Jaood+made
23:33mercwithamouth=P i have a few days off from work. I spent around 7 hours the other night going through it
23:33mercwithamouthafter Part II i'll jump to the web programming in clojure book
23:35Jaoodsame, although some parts of chapter 8 are really useful to know
23:36Jaoodfor daily clojure
23:36mercwithamouthtrue...i've done a bit of tinkering on the side so i'm getting pretty comfortable with namespaces and organization in general. i'll take a look over it though
23:45Jaoodamalloy: so is there are pattern to replace zippers? or is a just don't do it that way?
23:46amalloyJaood: you just don't need them. like, in certain esoteric scenarios, they are handy to have for sure. but if you are learning clojure, and think "i need zippers for this", you are wrong
23:46amalloyand all you need is a recursive function, usually
23:47amalloythey're pretty good for working with xml, i guess, if you have a reason to do that
23:51Jaoodamalloy: got it
23:53oinksofti'm having a hard time writing recursive functions in clojure, i am used to processing off the head of a list in erlang ... how do i recursively process a list in clojure?
23:53oinksofti couldn't even find a function to take all but the head
23:55sjyoinksoft: use 'rest'
23:57bob2you may want map or filter or reduce instead though
23:58mercwithamouthany tutorials out there that go over building a compojure webapp 100% without hiccup?
23:58bob2what do you want to use instead?
23:59Jaoodmercwithamouth: do you already know ring well?
23:59oinksoftbob2, i just want the first non-nil value of a list of functions when applied
23:59oinksoftbob2, if-let looks promising if i knew what it did, the examples are not very clear to me
23:59Jaoodmercwithamouth: the book you mentioned covers that I think, the show how to use selmer too
23:59mercwithamouthJaood: well..no but i've toyed a little with it along with both enfocus and om
23:59beamsomercwithamouth: http://www.luminusweb.net/