#clojure logs

2012-08-11

00:19cemerickxeqi: Why strange?
00:19cemerickYeah, I guess I should make it clear that it's a dep.
00:19xeqiI considered it more a dev tool
00:20xeqi..
00:20cemericknREPL has a large footprint. :-)
00:20cemerickThe REPL you run is never part of lein's process.
00:20xeqiah
00:21xeqisounds like a case for the :dev profile
00:21cemerickperhaps
00:21xeqigot it running on my machine btw
00:22cemerickI wouldn't say cljs is common enough to make available everywhere. :-)
00:22cemericknice!
00:23cemerickThere's a couple of one-off differences between it and the default cljs repl, but I think it's good enough for government work.
00:24xeqihurray, lein-cljsbuild's browser repl works, now to see what happens when mess with piggieback
00:24xeqiwell, if I can drop the browserrepl in somehow
00:25cemerickafter a brief look, it should be easy enough
00:26cemerickthe environment should work as-is
00:27cemerickYou may even be able to use cljs-eval directly as the eval fn
00:50xeqicemerick: :)
00:50cemerickjoy?
00:50clojurebotjoyofclojure is http://joyofclojure.com/
00:51xeqihttps://www.refheap.com/paste/4239
00:54cemerickxeqi: oh, that's sweet
00:55cemerickI didn't think it'd be that easy.
00:55cemerickIn that case, I think my job is done here. :-D
00:56cemerickI thought I'd have to plumb some bits through to help with browser-repl too, but…damn.
00:56cemericknow just a bit more middleware (to unify file-loading across Clojure and ClojureScript), and we'll be nearly at parity.
00:57xeqithere might be some more, like a pointer to -tear-down
00:57xeqibut its functional
00:57cemerickxeqi: :cljs/quit will cause cljs-eval to take care of the -tear-down
00:58xeqiby wrapping squelch-rhino-context-error
00:58GNOSIS-is there anything wrong with having a transaction inside an agent?
00:58xeqiwhich doens't seem to cause any problems
00:59cemerickright, that won't cause any issues, even if you're not using rhino
00:59mkGNOSIS-: there shouldn't be, no
00:59GNOSIS-ah, great
00:59GNOSIS-I thought I read something about refs only being written at the end of an agent's execution
00:59GNOSIS-but I could be mistaken
01:00mkGNOSIS-: an agent is just another ... timestream, which is what the concurrency stuff is meant for
01:01mkGNOSIS-: yes, that's right, but the opposite. When you do a transaction, if during that transaction you send to agents, the messages will be queued up until the transaction finally succeeds
01:01cemerickmeh, I still don't grok what this stuff about static assets in browser-repl is for.
01:01cemerickThe real work will be in making it all easy to use. Should be as easy as :hooks [cemerick.piggieback.hook] or something.
01:02cemerickxeqi: Q: are you able to start a cljs REPL, stop it, and start another in the same Clojure REPL session?
01:02xeqicemerick: yeah, :cljs/quit followed by the start command + browser refresh works
01:02cemerickman, I get an error.
01:03cemerickhttps://gist.github.com/3317393 FWIW
01:03GNOSIS-mk: ohhh, that makes much more sense
01:04xeqicemerick: I'm guessing the static assets is just a quick way to serve an html page + complied js
01:04xeqirather then starting a full ring app
01:05xeqimaybe for testing ?
01:07xeqicemerick: ah, you're running that from a git checkout.. I didn't try that
01:07mkGNOSIS-: that's also the reason that agent queues are described as "potentially not in order - you can only depend on sends from a given thread being in order"
01:07cemerickxeqi: Yes, though it happens for me everywhere; git, maven dep, whatever.
01:07xeqibut I was able to restart the browser repl from within the same nrepl
01:08cemerickdnolen couldn't duplicate, and it sounds like you can't either, so…
01:10xeqiI'm running OpenJDK Runtime Environment (IcedTea7 2.1.1pre) (7~u3-2.1.1~pre1-1ubuntu3) on 64bit incase it helps
01:11cemerickI'm on stock OS X 1.6.0_33 *shrug*
01:11cemerickI'm not motivated to ramp up an ubuntu dev environment to track it down. :-)
01:17xeqiblah, nrepl.el gives me an error when trying to start the browser repl
01:18xeqinm, needed to remember to use lein from git
01:21mkhow does (hash) differ from hashCode?
01:22xeqicemerick: wee, emacs -> nrepl.el -> piggieback/cljs-repl -> browser -> noir -> browser -> alert box
01:23cemerickI'm confused by the multiple appearances of "browser", but: sweet!
01:23xeqinormal server response there
01:24cemerickwell, browser -> noir -> browser -> alert box is just a web app
01:24xeqimade from xhr invoked from browser repl
01:24cemerickoh, ok :-)
01:24cemerickremember, I'm a noob :-P
01:25xeqimk: looks like null hashes to 0, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L113
01:27mkxeqi: ah, thanks
01:28Cr8`(map hash [0 nil "" {} #{}])
01:28xeqi&(map hash [0 nil "" {} #{}])
01:28Cr8ah
01:29Cr8or not
01:29mkcemerick: don't worry, we were all noobs at one point. Just keep at it
01:29xeqiah, lazybots missign
01:29xeqi,(map hash [0 nil "" {} #{}])
01:29clojurebot(0 0 0 0 0)
01:29mkif you're having trouble try picking up one of the clojure books, I hear they're great
01:29cemerickmk: which one do you recommend?
01:30mkthe latest one's pretty good, forgot what it was called though
01:30cemerickmk: you mean http://clojurebook.com?
01:32mkyeah that one
01:33pyykkiscemerick: joy of clojure is an another great one
01:33cemerickyeah, I've got both of 'em :-)
01:33Cr8hey, i contributed a very minor correction to that clojurebook one
01:33xeqiheh
01:33Cr8I tweeted it to some Chas fellow.
01:34cemerickmk, pyykkis: sorry, I just had to do it ;-)
01:34mkcemerick: ;)
01:34cemerickIt's always so hard to know who's trolling who.
01:35cemerickCr8: thanks for that :-)
01:36pyykkiscemerick: hah, I just read your survay on state of clj :p
01:36cemerickxeqi: And thanks for verifying the browser-repl; will add that to the docs, just as soon as I figure it out myself. :-)
01:37cemerickah-ha! Cool
01:37xeqinp, I find the browser-repl one of the best things out of cljs, so had to jump and see if it worked
01:37pyykkisno wonder your nick felt familiar.. :P
01:38cemerickAnd tired. g'night all
03:50AustinYunanyone have any good tips on how to idiomatically solve this short problem?
03:50AustinYunhttps://github.com/austinyun/challenges/blob/master/array-iteration-interview-problem/PROBLEM.md
03:51AustinYuni have a clojure version mostly done but i'm not sure about the right way to traverse an array from the right
03:51AustinYunto avoid calling "reverse" on an array twice
03:51AustinYunhttps://github.com/austinyun/challenges/blob/master/array-iteration-interview-problem/add1.clj
03:55hyPiRionI'll have a look at it
03:55AustinYunits just a little thing i saw on hacker news last week or so
03:56AustinYunan interview problem a guy likes to ask, and his observation that ruby people tend to solve it by calling Array.reverse twice
03:57AustinYunsummary: write a function add1 that takes an array, a value, and a magic number "n"
03:57AustinYunadd 1 to each element in the array if it matches the value passed as a parameter, but only N times if N is positive
03:58AustinYunand if N is negative, do the same, but starting from the end of the array
03:58AustinYuni thought it was interesting because i can't think of how to do it purely functionally (every solution i saw was a variant of C style loops)
04:01AustinYunill admit that i spent a good 8 hours writing my javascript version, lol
04:03hyPiRionHm.
04:03clojurebotIt's greek to me.
04:07hyPiRionyeah, it's hard to do this functionally.
04:07hyPiRion:p
04:08AustinYunmy js solution (which my clojure is mostly a translation of) is to make a closure over the "count" idea from n
04:11hyPiRionIt's kind of messy, because you have so much data into that single n.
04:11AustinYuneven if you unroll it all into the "n is a negative number" scenario
04:12AustinYunthe idea of incrementing values from the end of an array, but only a certain number of times, seems difficult to deal with
04:13AustinYunn = 0 is trivial -- just (map incrementer input-array) where incrementer could just be an anonymous function (if (= x y) (inc y) y))
04:14AustinYunill have to ask some haskell people tomorrow, lol
04:15AustinYunbut i have a really hard time following haskell code
04:15AustinYuntoo bad i missed cemerick
04:31hyPiRionhttps://www.refheap.com/paste/4244 is my result
04:32hyPiRionan ugly pile of code, though.
04:46rod_hi - i'm trying to find a clojure event graphing server i read about ages ago (like statsd) but can't remember the name now - gah! can anyone help?
04:51DaoWenAustinYun: why not just use the loop macro?
04:51beffbernardrod_: http://aphyr.github.com/riemann/ ?
05:02rod_beffbernard: YES!!!!!! thanks very much, will bookmark now.
05:02rod_:D
05:03DaoWenAustinYun: it looks like you're actually using vectors instead of arrays in your sample code. if that's the case, you can call rseq on the vector, which returns a "reversed" sequence from a vector or sorted-map *in constant time* (it doesn't actually reverse it, but rather provides a reversed view of the sequence)
05:22_ulisesmorning all
05:23talios'lo
05:28daniel__1good morniiin
05:44mindbender1what's the modern way of managing external clojurescript libraries?
05:47talioshow are you building your project? lein? If I was using maven I'd just store them in a jar and use the remote-resources-plugin and use dependencies.
05:48taliosI should really look at clojurescript before talking about it tho ;)
07:26sayyestolifeHey, I'm wondering if there is some other nicer way to structure the following code? http://pastebin.com/AUsMDYcQ
07:35hyPiRionsayyestolife: Have you seen the -> and ->> macros?
07:36sayyestolifeI've used -> a bit yes
07:36sayyestolifeproblem is that I have several varying (in value) parameters
07:37sayyestolifeI've only used it in the case where I have functions of 1-arity (and thus have done like (-> var fn fn2 fn3))
07:39_atosayyestolife: you can go: (-> world (set-at x y :player) (set-at (inc x) y :player) (set-at ...) ...)
07:40hyPiRion^
07:40hyPiRionhttps://www.refheap.com/paste/4245 is the result I get
07:40sayyestolife_ato: I can? How can it know that world is suppose to be the first argument?
07:40_ato-> threads the first argument
07:40_ato->> threads the last argument
07:40sayyestolifeoh, kind of like currying almost?
07:40hyPiRionsayyestolife: Try to look at the code after macroexpand and clojure.walk/macroexpand-all
07:41sayyestolifewill do, cheers
07:42hyPiRionsayyestolife: Anyway, I think a more elegant solution would be like this: https://www.refheap.com/paste/4246
07:42hyPiRionJust throwing my 50 cents out there.
07:44sayyestolifeI suppose, but that got me thinking of an even better way, cheers again
07:46hyPiRionsayyestolife: That's awesome! Good luck onwards with the code :)
07:47sayyestolifethanks, I just love this language, even though what I write is crap compared to most on people on 4clojure and such, it is still so much more beautiful than what I write in other languages
07:52wmealingsayyestolife, i sometimes feel the same way
08:13wmealingcan you "require" a java library as a shortened name
08:13wmealingso that i dont need to spell the whole path out every time ?
08:30_uliseswmealing: you can :import classes in your ns
09:41mindbender1technomancy: I remember seeing a link to a style guide on leiningen page but I'm having trouble locating it.. mind giving me a hand?
09:44mindbender1ok found it, that was on swank-clojure (;
09:57Cheironwhat are the equivalent of assoc-in and update-in for transient data structure?
10:00cshellwhat do you mean by transient?
10:01Cheirontransient data structure in clojure is the counterpart of immutable one
10:02Cheironmodifiable data structure
10:04cshelloh
10:04cshellassoc in and update in allow you to specify a series of keys for nested associated datastructures
10:05cshellfor mutable datastructures, these semantics would still apply, they would just have the side effect of modifying the target structure
10:05Cheironactually both aren't working
10:06Cheironjava.lang.ClassCastException: clojure.lang.PersistentArrayMap$TransientArrayMap cannot be cast to clojure.lang.Associative
10:06cshellthey only work on associative structures (ie maps)
10:06cshellnot arrays
10:06cshelloops, you have an array map
10:06Cheironi created (def t (transient {}))
10:08cshell,(assoc-in {:a "a"} [:a] "b")
10:09clojurebot{:a "b"}
10:09cshellit works for the non-transitive
10:09xeqiCheiron: assoc!, dissoc! and conj! work, but I don't see equivalents to update-in/assoc-in
10:11Cheironwhile profiling my clojure code that calls update-in, i noted that the most created instances are Cons
10:11xeqiyou'd have to translate those yourself I think -- http://clojuredocs.org/clojure_core/clojure.core/update-in#source
10:11Cheironbut afaik, clojure don't embrace Cons concept since it has seq concept
10:12Cheironand why the most created objects are char[] ? according to Visual VM
10:13cshellcheiron
10:14cshellcheiron: you can try to use (get-in ) to get what you want to modify and then do a assoc!
10:14goodieboyis there a nifty, functional way to produce a lazy seq with this pattern? [[0 0] [1 0] [2 0] [0 1] [1 1] [2 1]]
10:15casiongoodieboy: there'd be plenty of ways to do it, depending on how the pattern extends beyond that
10:15Cheironcshell: I see, thanks
10:16goodieboycasion: OK, well what I'm trying to do is take a string like "ABC DEF GHI" and pull extract the first letter from each word, at the end repeat, but then the second word, repeat etc.
10:17goodieboyso in the example, "ABC DEF GHI" become "ADGBEH"
10:19goodieboyi was thinking about using loop, but that feels very imperative. I'd like to be able to "take" from this lazy seq, n items for example
10:21goodieboyanyway, i thought if i could come up with a lazy seq of indices, then i could use those to pull out the needed characters
10:21casiongoodieboy: sec
10:22goodieboynp :)
10:22xeqi&(clojure.string/join (apply mapcat vector (clojure.string/split "ABC DEF GHI" #" ")))
10:22lazybot⇒ "ADGBEHCFI"
10:23xeqigoodieboy: ^
10:25goodieboyxeqi: beautiful. I need to pull that apart and understand what's happening. Thanks for that.
10:25daniel__1anyone use Guard to auto run their tests? i would like to see an example Guardfile
10:25gfredericks&(clojure.string/join (apply str (clojure.string/split "ABC DEF GHI" #" ")))
10:25lazybot⇒ "ABCDEFGHI"
10:26gfredericksgoodieboy: ^ no reason for the apply mapcat vector
10:26gfredericks&(apply str (clojure.string/split "ABC DEF GHI" #" "))
10:26lazybot⇒ "ABCDEFGHI"
10:26gfrederickswhile we're at it no reason for the string/join either
10:27casionwell, I cant use clojure overnight for some reason
10:28casionthat was a badly formed sentence if there ever was one
10:28goodieboygfredericks: :) oh, well i don't want to just glue it all together in-order, the output is a little different than that
10:28goodieboyhaha
10:28xeqihmm, didn't know str did that
10:29goodieboyi need to spend an hour playing with mapcat
10:29gfredericksit's just (apply concat (map f coll))
10:30casionhumph. the namespace in my repl was wiped by sleeping my laptop
10:30casionhow weird
10:30casionno wonders nothing worked
10:31gfredericksclojure forgets everything at 3am every night
10:31casiongfredericks: it would appear so
10:31goodieboy,(apply mapcat vector ["ABC" "DEF" "GHI"])
10:31gfredericksit forces you to not make assumptions about code longevity
10:31clojurebot(\A \D \G \B \E ...)
10:31goodieboy,(apply concat (map vector ["ABC" "DEF" "GHI"]))
10:31clojurebot("ABC" "DEF" "GHI")
10:32goodieboyhmm
10:32gfredericks,(mapcat vector ["ABC" "DEF" "GHI"])
10:32clojurebot("ABC" "DEF" "GHI")
10:32gfredericksthat's the one I was thinking of
10:32gfredericksI don't think I've ever applied mapcat before
10:32goodieboyoh i see the diff now, yeah it's apply on mapcat
10:35casionxeqi: your solution doesnt produce a lazy sequence though?
10:36xeqicasion: cause string/join uses it all
10:36xeqiif he just wants the seperate characters it is lazy
10:36casionah
10:38goodieboyxeqi casion: how about making ["ABC" "DEF" "GHI" "J"] produce "ADGJBEHCFI" ? :)
10:51firesofmayis it possible for me to use Selenium Grid 2 with clj-webdriver?
10:52goodieboytotally struggling here.. how would i implement something that worked like this: (take 4 (xyz 2)) => '((0 0) (0 1) (1 0) (1 1)) where "2" is the dimension of the inner seq?
10:53goodieboyi smell iterate, but not behaving the way i thought it did
10:59DaoWengoodieboy: what does the "xyz" stand for?
11:02goodieboyDaoWen: sorry, that's a bad example. I guess what I'm trying to show with that is, i want the dimensions to be controlled by arguments. So the xyz function would some how produce a sequence of numbers, where the values would increment
11:02DaoWengoodieboy: https://github.com/clojure/math.combinatorics
11:03DaoWenI think selections would do what you need
11:03goodieboyDaoWen: wow, nice. That looks very much like what i have in mind.
11:04DaoWengoodieboy: (selections [0 1] 2) => ((0 0) (0 1) (1 0) (1 1))
11:04goodieboyDaoWen: ha yes! awesome, i'll try it out now
11:05DaoWen(selections (range 10) 2) counts from 0 to 99
11:06xeqifiresofmay: I don't see RemoteWebDriver in the list of keywords, so I don't think support is built in
11:06DaoWengoodieboy: all of the functions in that library return answers in lexicographic order
11:07xeqi* in the keyword -> driver map
11:09goodieboyDaoWen: ok thanks. Hey, would you happen to know the maven name/group and version for that lib?
11:09goodieboyi can't find it
11:10DaoWengoodieboy: org.clojure/math.combinatorics "0.0.3"
11:10goodieboyDaoWen: thanks!
11:10DaoWenthat's what I have in my project.clj
11:10goodieboyexcellent, that worked
11:20goodieboyDaoWen: thanks again! That's exactly what I was looking for :)
11:21DaoWengoodieboy: glad I could help :)
11:37firesofmayokay xeqi thanks
11:50beffbernardIs there an equivalent in swank/slime to clean -> build ?
12:43nsxti stumbled across project euler and decided to take a crack at #18 (http://projecteuler.net/problem=18). i figured i'd take a bottom-up approach, which "collapses" each row into the one above by taking the max of the summation of adjacent cells. (that probably sounds cryptic, but if you're following along with the sample problem on the site, the penultimate row would contain 125 164 102 95 etc..) problem is, i'm still a noob and
12:44metellusnsxt: your line cut off at "problem is, i'm still a noob and"
12:45nsxtmetellus: thanks - "problem is, i'm still a noob and i don't know how to model this succinctly (or at all...)"
12:47metellusnsxt: I don't know how to help, but maybe now someone else can
12:49llasram`Oh wow, redesign on the Project Euler page
12:49nsxtmetellus: i think i'll diagram a shorter problem to clarify what it is i'm trying to achieve
12:50llasramnsxt: I'm having trouble teasing your question out of your text :-)
12:52nsxtllasram: yeah, sorry... give me one second and i'll provide you with a better diagram/explanation
12:52yoklovnsxt: you might want to try a greedy approach
12:53yoklovinstead of a bottom-up one, but that's just a thought.
12:53llasramnsxt: As a side note, I learned Clojure by doing Project Euler problems, and I think it's a good approach. Maybe 4clojure would be even better for this, gave me a chance to wrap my head into the functional mindset for "real" problems w/o needing to tackle the stack of libraries and JVM interop you need for most real-world applications
12:53metellusI think it'd be pretty easy to make a triangle where the greedy approach fails
12:54metellusI like nsxt's bottom-up solution... I just don't know how to model it in Clojure
12:55yoklovoh, yeah, you're right
12:56llasramnsxt: Oh, I see what you're suggesting. I actually remember this one, because I did the same approach, only went down instead of up for some reason, so then needed to max the resulting set. Collapsing upwards and getting the final answer at the top is totally the way to go
12:57nsxtyoklov: the greedy approach, if i think we're on the same page, will take something like billions of years to calculate (if you move up to 100 rows)
12:57yokloverr, it shouldn't
12:57nsxtllasram: yes, so sorry for my convoluted explanation. here's a refheap which describes it better: https://www.refheap.com/paste/4247
12:57yoklovbut it might get the wrong answer, now that i think more.
12:58nsxtyoklov: what does the greedy approach entail?
12:59metellusthe greedy approach would be to start at the top and always choose the max of the two options below
12:59metellusit's called "greedy" because it decides based on short term gains only
12:59yoklovor keep a priority queue, and each time a node becomes visible push it on the queue, keeping the nodes updated
12:59nsxtmetellus: so top-down. right, it wouldn't take billions of years to calculate, sorry yoklov.
13:01llasramnsxt: So which is the part that you're having trouble thinking how to represent in Clojure?
13:01yoklovbut the priority queue isn't the most idiomatic for clojure. i think its what i did when i did these in scheme though.
13:02nsxtllasram: it's just the collapsing process. i've destructured the list so that i can get the last two "rows", but i don't know how to craft the function to do what i want.
13:03llasramWell, you want to reduce a sequence to a single value, so probably (drum roll) `reduce` :-)
13:04llasramIf you have the rows ordered from bottom to top, then using `reduce` the 'state' you're building is the last collapsed result, and you'll get the next row up with each iteration
13:05nsxtllasram: right, i guess the most difficulty is in crafting the lambda to pass to reduce
13:06nsxtllasram: and it's probably more conceptual than anything - a lot of the collections on 4clojure are identical in length, whereas here the collection lengths differ by one
13:06llasramOh, you may which to check out `partition`
13:07nsxtthank you, am checking now
13:08nsxtaha, so i can pad it out then
13:08antoineBhello is there a problem with closure and the map function?
13:09llasramnsxt: Well,
13:09antoineBi get an IndexOfBoundException
13:09llasramnsxt: I'm not sure padding is correct. I was thinking more repeating
13:09llasramEr, via the implications of the `step` argument
13:09antoineBi would like use : (map #(my-fun %1 next-level)
13:10antoineBand : (defn my-fun (text & level) ...)
13:10nsxtllasram: mind if i pm you?
13:10antoineBthe error come from those two line
13:10antoineB*lines
13:11antoineB* (map #(my-fun %1 next-level) a-list)
13:11antoineBnext-level lis a local binding
13:11antoineB*is a local binding
13:12llasramantoineB: Well, for one thing, that `defn` line can't be right -- function arguments need to be specified as vector, not a list
13:12dbushenkockirkendall, hi
13:12antoineBllasram: i just miss-spell, its a vector in my code
13:12dbushenkohow is it going with enfocus issue #22 ?
13:17llasramantoineB: Not enough there to really say much on... Can you post a gist which reproduces your problem?
13:18antoineBi will
13:19antoineBhttps://gist.github.com/3325837
13:25TimMctechnomancy: So what's the deal with kibit 0.0.4 and lein? Have you figured it out yet?
13:26danielglauserHas anyone worked with clj-oauth2 to connect to Salesforce? https://github.com/DerGuteMoritz/clj-oauth2
13:34antoineBllasram: any ideas?
13:35llasramantoineB: in `exceed-splitter`, > vs >=
13:35llasramoff-by-one -- you pass in a (0-based) index then compare it to a count
13:37antoineBllasram: thanks that was just a silly error
13:37antoineBbut println don't flush?
13:40DaoWennsxt: I've been doing project euler problems in Clojure as well. I have my solution for problem 18 here if you're interested: https://github.com/DaoWen/euler/blob/master/src/project_euler/problems_020.clj
13:41DaoWennsxt: oops, I didn't include the line number https://github.com/DaoWen/euler/blob/master/src/project_euler/problems_020.clj#L240
13:45DaoWennsxt: I did top-down rather than bottom-up, but at least it shows that all the calculations can be done succinctly
13:50antoineBis there a function to print "outside" of #(...) function used in the map function?
13:50antoineBexample if i use: (map #(do (println "a") 1) [1 2 3])
13:51antoineBi get: ("a" 1 "a" 1 "a" 1) as output
13:51antoineBwhere i expect "a" "a" "a" (1 1 1)
13:55DaoWenantoineB: does this work? (doall (map #(do (println "a") %) [1 2 3]))
13:55DaoWenthat worked in my repl
13:56DaoWenthe reason the prints are interspersed throughout the result is because the map function is lazy
13:56mattmoss,(map println [1 2 3])
13:56clojurebot(1
13:56clojurebot2
13:56clojurebot3
13:56clojurebotnil nil nil)
13:57DaoWenit only does the work of actually computing an element once it's forced to do so
13:57DaoWen,(doall (map #(do (println "a") %) [1 2 3]))
13:57clojurebota
13:57clojurebota
13:57clojurebota
13:57clojurebot(1 2 3)
13:57mattmossignore my example... I incorrectly read yours.
13:58DaoWenmattmoss: thanks, for some reason I didn't think the bot would handle the printlns correctly
13:58DaoWengood to know that it does
14:00DaoWenantoineB: the reason that adding (doall ) around the whole expression fixes the printing issue is that (doall ) forces the entire mapped sequence to be realized before passing back the result, so all of the (println "a") calls happen before the repl gets back the result and displays it
14:00dbushenko,(let [m (map #(do (println "a") %) [1 2 3])] m)
14:00clojurebot(a
14:00clojurebota
14:00clojurebota
14:00clojurebot1 2 3)
14:04mindbender1where is the clojure.instant namespace in clojurescript located?
14:05jam`I guess you need clojure 1.4 if you're getting cljs complaining about missing clojure.instant
14:07mjg123Hi - Is there a way in clojurescript to handle javascript objects with circular references inside?
14:07mindbender1jam: ok I think so, my project.clj has 1.3
14:07mjg123js->clj does a stack overflow, and JSON/stringify won't touch it either
14:09jam`mindbender1: yep, should be, I had a similar problem
14:12antoineBDaoWen: that works
14:12DaoWenantoineB: great!
14:13antoineBthank you
14:16yoklovwhat does the recursive? argument mean in read?
14:17yoklovoh, that it's happening within another call to read, got it.
14:50skaurusHi! I'm a Clojure novice and have a simple question: why this snippet doesn't work as expected (i.e. doesnt return 0): (defn func ( [param] (def param (- param 1)) param )) (func 1)
14:51danielglauserskaurus: I don't believe you are defining the function correctly
14:51gfredericksskaurus: you want let rather than a nested def; def creates globals
14:52gfredericks(defn func [param] (let [param (- param 1)] param)) (func 1)
14:53skaurusgfredericks: I tried that, it returns 0 too...
14:53skaurusgfredericks: let me check my typing, maybe there is subtle typo
14:53danielglauser(defn fund [param] (let [new-val (- param 1)] new-val)
14:53gfredericksskaurus: you want it to return 0, right?
14:54danielglauser,(defn func [param] (let [new-val (- param 1)] new-val)
14:54clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
14:54skaurusgfredericks: oh, I meant it returns 1 too
14:54skaurusBut I have a excessive brackets in my defn! :)
14:54metellusyou're missing a paren, but I don't know that clojurebot lets you defn anyway
14:54metellus,(defn func [param] (let [new-val (- param 1)] new-val))
14:54clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
14:55danielglauser:)
14:55gfredericksskaurus: it returns 0 for me
14:55metellus((fn [param] (let [new-val (- param 1)] new-val)) 1)
14:55metellus,((fn [param] (let [new-val (- param 1)] new-val)) 1)
14:55clojurebot0
14:57skaurusThanks so far!! But then I trying to create multifn like that: ( defn func ([] (func 1)) ([p] (let [p (- p 1)]) p) ) And (func 1) returns 1 too. Now I MUST have that brackets that was excessive, right?
14:57mkthe bot should probably trigger any time it sees an expression that compiles
14:58metellusskaurus: is there any particular reason that you're using p for both the param and the new value you're computing?
14:58gfredericksmk: you can trigger in the middle of a message ##(list :like :this)
14:58lazybot⇒ (:like :this)
14:59mkhas anyone ever said something that starts with (..symbol and ends with ), but it wasn't just a case of accidentally omitting ,?
14:59metellusparentheticals are pretty common on irc
14:59metellus(maybe not in this channel, though)
15:00metellus((see what I mean?))
15:00mkgfredericks: yeah, I recall that. I mean that it just seems pointless to even have a ,
15:00mkmetellus: the parentheticals you provide wouldn't compile :)
15:00gfredericksbut the bot would have to try it nonetheless
15:01gfredericksif I put a + in the middle of a sentence, that's a compilable expression
15:01gfredericks,+
15:01clojurebot#<core$_PLUS_ clojure.core$_PLUS_@2f71e573>
15:01skaurusmetellus: maybe that's my background, but I'm trying to avoid declaring of new unnecessary variables. Also in the end I'm trying to pass a "accumulator" var to my func; that func should add some values to it and calls itself recursevly with new value of "accumulator". After some number of calls it finishes and returns final value of "accumulator".
15:01mkgfredericks: don't print if it doesn't compile, unless preceded by ,?
15:02gfredericksmk: + compiles
15:02metellusskaurus: using def or let like that is very uncommon for clojure
15:02metellusand for functional programming in general
15:02mkgfredericks: if someone says just +, I sort of expect the bot to respond
15:03gfredericksmk: what about in the middle of a sentence like yours there?
15:04mkgfredericks: it would amuse me. But for longer messages, it might check for brackets or for the use of unknown symbols
15:05skaurusmetellus: so what would be a idiomatic way to accumulate values from recursive function calls? Maybe I should define global var and add to it (or rather redefine it) in each iteration?
15:05metelluspass the accumulator as a parameter to the function
15:06skaurusI'm trying exactly that, but in multidef as in example above I can't change argument value for some reason.
15:07skaurus"... ( defn func ([] (func 1)) ([p] (let [p (- p 1)]) p) ) And (func 1) returns 1"
15:07metellus(defn factorial ([n] (factorial n 1)) ([n acc] (* n (factorial (- n 1) acc))))
15:07metelluswith a base case in there when n = 1
15:07metelluserr, my example was terrible and should be ignored
15:08skaurusthank you! Right now I'm inexpectedly should leave but I'll try to understand what's going on using that example.
15:08skaurusoh)
15:08hiredmanso was skaurus's so it comes out in the wash
15:09mkskaurus: what do you mean by accumulator? The recursive function should never change the value of something passed to it
15:09metelluswriting on an irc input line is hard
15:14metellusskaurus: https://www.refheap.com/paste/4251 here's an example that actually works. I don't promise that it's the best way to do it, but it works.
15:18metellusskaurus: but in general, with Clojure you should prefer to declare new variables when necessary instead of changing the values of existing ones
15:19Chousukeor you structure your code so that you don't need variables :P
15:29cshellDoes anyone know of any geospatial clustering libraries for clojure?
15:35mkcshell: java libraries are compatible
15:41skaurusmetellus: Thanks!
15:42skaurusmk: well, doesn't reduce does exactly that?
15:44mkskaurus: no, reduce produces a new value
15:45skaurusmk: ok. I still wrapping my head around immutable variables :)
15:46cshellmk, that's what I was thinking - thanks!
15:48mkskaurus: they aren't variables. They're values. You might be imagining a single "thing" passing through some sort of function, and coming out differently. That's not quite how it works
15:48mkcshell: np
15:49mkskaurus: if you look at that refheap link, the "acc" is entirely different on each recursion. It isn't like an object that you add 10 to, and then give back.
15:50raekskaurus: you might find my answer to this so question interesting. the question is about immutable variables and loops. http://stackoverflow.com/questions/8540855/setf-in-clojure/8564082#8564082
15:51skaurusmk: that makes more sense now, thanks)
15:53skaurusraek: it looks like what I need. Hard to understand all semantic from first sight, but it is ok. Thanks!
15:53mkskaurus: if you're unsure about anything, feel free to ask in here. It takes a bit of time and several tries to finally get your head around, but that's fine
15:58NikelandjeloIs there a way to check if code is executing inside repl?
16:02NikelandjeloI'm writing some GUI and want frame to close and exit from jvm if it's running as script and only close when it's inside repl. So I need to determine somehow whether current environment is repl or not.
16:13xeqiNikelandjelo: DISPOSE_ON_CLOSE not working for that?
16:15Nikelandjeloxeqi: It doesn't kill jvm, only closes frame. But if I run app standalone (without repl) I want it to quit. It seems I can use *file* to determine if it's repl.
16:15xeqihmm, guess there are some threads still running
16:16xeqiwonder if thats a clojure artifact
16:16NikelandjeloIt's the same in java
16:16NikelandjeloIf you use DISPOSE_ON_CLOSE jvm is not killed
16:16lynaghkdnolen: can core.match be used to compile decision trees that execute all matching branches, or is it optimized to find the first matching branch only?
16:17xeqiNikelandjelo: if you use DISPOSE_ON_CLOSe the jvm stays alive if there are other windows or non-daemon threads
16:17xeqiotherwise it will exit cleanly
16:18lynaghkdnolen: I'm thinking about pubsub in cljs. Goog's implementation is exact string matching only. Things like redis allow "/approx/*/matches/*" and I'm wondering how performant we could make something like content-based matching. E.g., (subscribe {:x x :msg "ABC"} ...)
16:18xeqiI would think that would work for clojure, but the agent threadpool might be keeping it alive :/
16:19xeqihaven't done swing since moving to clojure so not certain there
16:19xeqibut it seems like you found a work around thats good for your situation?
16:20NikelandjeloI haven't tried yet. Want to check about DISPOSE_ON_CLOSE in java now :)
16:22dnolenlynaghk: core.match doesn't find all matches
16:23lynaghkdnolen: okay, that's what I thought, thanks.
16:23dnolenlynaghk: I've been thinking along the lines of where you're going tho ... could be interesting.
16:23lynaghkdnolen: yeah. I've gotten myself tangled up in the auto-watcher magic of my Reflex library a few times, so I'm looking around to other approaches
16:25lynaghkdnolen: the FRP thread on the dev list has pretty much entirely left my area of understanding; I'm trying to stay grounded and just tally up specific use-cases and try different approaches.
16:26lynaghkdnolen: anyway, it seems like the only reason not to use structured pattern matching on message content over string-based topics is performance, no?
16:26dnolenlynaghk: I think pubsub is a good place to start.
16:27dnolenlynaghk: I really dislike string based matching
16:27dnolenlynaghk: any pubsub matching should be based on data IMO.
16:28xeqiNikelandjelo: http://docs.oracle.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html - relevant auto shutdown docs, might be understandable if you come from java
16:38Nikelandjeloxeqi: thanks, interesting article
16:41kaoD_hi
16:41kaoD_are there any opensource projects using robert hooke I can check?
16:41kaoD_(besides leiningen)
16:43emezeskekaoD_: lein-cljsbuild uses robert hooke a little bit
16:43kaoD_thanks emezeske
16:43emezeskekaoD_: I don't know if it's a great example though :)
16:44kaoD_I'm curious: order of evaluation is completely random or does it follow a pattern?
16:45xeqifirst arg -> last arg
16:45kaoD_xeqi: I mean in robert hooke's hooks
16:46kaoD_(inter-namespaces especially)
16:46kaoD_I guess it depends on namespace loading order which is random without heavy hacking or dirty tricks, right?
16:47emezeskekaoD_: I believe it is true that there's no easy way to control the order that the hooks are applied
16:47emezeskekaoD_: I am not an expert on hooke though
16:53nkoza3How do you use simultaneously :keys and :or in map destructuring? This doesn't seems to work: (let [{:keys [a b] :or {:b 3}} {:a 1}] [a b]) ;=> [1 nil] but expected [1 3]
16:54gfredericks,(let [{:keys [a b] :or {b 3}} {:a 1}] [a b])
16:54clojurebot[1 3]
16:54gfredericksthar it is
16:55nkoza3ahh thanks
17:14CheironHi, how fnil is different from partial method?
17:14Cheironpartial *function
17:15gfredericks,(doc fnil)
17:15clojurebot"([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."
17:15gfredericks,(let [f (fn [a] (+ a 5)), g (fnil f 10)] (g))
17:15clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$fnil$fn>
17:15gfredericks,(let [f (fn [a] (+ a 5)), g (fnil f 10)] (g nil))
17:15clojurebot15
17:16gfredericksCheiron: it lets you specify default arguments, in case the ones gives are nil
17:16gfrederickswhereas partial lets you specify the arguments such that they don't need to be passed to the returned function
17:18CheironOh, eye c
17:18gfredericks,(let [+ (apply fnil + (range))] (+ 7 8 nil 3 nil nil nil nil))
17:18gfredericks&(let [+ (apply fnil + (range 50))] (+ 7 8 nil 3 nil nil nil nil))
17:18lazybotclojure.lang.ArityException: Wrong number of args (21) passed to: core$fnil
17:18clojurebotExecution Timed Out
17:19gfrederickswait does fnil only work up to arity 3?
17:19gfredericks,(fnil + 1 2 3 4)
17:19clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (5) passed to: core$fnil>
17:19gfredericks,(fnil + 1 2 3 )
17:19clojurebot#<core$fnil$fn__3361 clojure.core$fnil$fn__3361@d5e391d>
17:19gfredericksthat's so weird
17:19Cheironhttp://clojuredocs.org/clojure_core/clojure.core/fnil
17:20Cheironit looks yes, max arity is three
17:20gfredericksI guess that lets it return a fixed-arity function :/
17:23xeqi&(doc partial)
17:23lazybot⇒ "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."
17:23xeqichecking if partial was limited ^
17:23RaynesWho was it who was doing the array iteration problem thingy last night?
17:24RaynesAustinYun: https://www.refheap.com/paste/4252 is a fun little solution I hacked together.
17:25RaynesNot saying it is idiomatic, but it popped into my head when I saw the problem.
17:25RaynesAso, darn it. That should be highlighted as Clojure. refheap.el, why have you forsaken me?
17:27NikelandjeloDoes anybody know some interesting simulation (e.g. some game) where atoms (refs, agents) are very useful?
17:27xeqiRaynes: add nrepl-clojure-mode to the supported modes list?
17:28Raynesxeqi: That's probably the problem. Didn't even occur to me.
17:28xeqi~ants
17:28clojurebotants is http://clojure.googlegroups.com/web/ants.clj
17:29xeqiheh, its not there
17:29nkoza3so, swank-clojure is still ahead of nrepl.el ? which one do you use?
17:29xeqiclojurebot: forget ants is http://clojure.googlegroups.com/web/ants.clj
17:29clojurebot'Sea, mhuise.
17:30Raynesnkoza3: I'd recommend using nrepl.el.
17:31xeqinkoza3: I use nrepl.el. I think the main feature difference is swank has a way to do breakpoints
17:31RaynesIt is easier to use and is only prohibitive if you actually need things from swank that it doesn't have which is unlikely.
17:31nkoza3ok, I will try it, thanks
17:32xeqinrepl.el has all the developers behind it, so I expect it will overtake swank as better for clojure shortly
17:34llasramRaynes: I really depend on those congratulatory start-up messages when connecting to a swank instance. How soon until nrepl.el gets feature-parity there?
17:35Raynesllasram: It has it already.
17:35llasramAwesome! Time to switch!
17:35oskarthThis seems very verbose to me: (defn rand-in-range [range] (+ (* (+ (- (last range) (first range)) 1) (rand 1)) (first range)))) Ideas for how to make it shorter?
17:35xeqiI don't think it mentions lemondor fame anymore though
17:37llasramI didn't really get that one. I guess lemondor was famous among CLers while it was an active blog? Or was it more than that?
17:37xeqibasically that
17:37Nikelandjelooskarth: you need to get real number between (first range) and (last range) ?
17:38oskarthNikelandjelo: yes
17:38xeqi&(doc rand)
17:38lazybot⇒ "([] [n]); Returns a random floating point number between 0 (inclusive) and n (default 1) (exclusive)."
17:39xeqiaww, I was hoping it would just take the boundaries
17:39oskarthit doesn't, unfortunately
17:39dnolenoskarth: if range is actually a range and is large that seems like a bad approach.
17:40oskarthyes
17:40oskartherr so it's just small arrays [a b]
17:40Nikelandjelo(defn rand-in-range [[a b]]
17:40Nikelandjelo (+ a (rand (- b a))))
17:40Nikelandjelosorry
17:41xeqi&(rand 0)
17:41lazybot⇒ 0.0
17:42RaynesDoes anybody think that Clojure should have a rand-long function? Since longs are default now, seems weird to only have rand-int.
17:42RaynesNot that it's hard to type (long (rand ..))
17:42gfredericks,(type (rand-int 20))
17:42RaynesBut it isn't hard to type (int (rand ..)) either, so..
17:42clojurebotjava.lang.Integer
17:43Raynes&(rand-int 999999999999999999)
17:43lazybotjava.lang.IllegalArgumentException: Value out of range for int: 924440368767550720
17:43RaynesI run into that all the time.
17:43gfredericksweerd; it never ocurred to me that the "-int" might be referring to the java type
17:43Raynesgfredericks: The implementation is literally (int (rand n)) iirc.
17:44llasramYeah, that's weird. Why even bother having it?
17:45oskarthoh nvm btw, was a mixup
17:45Raynesllasram, gfredericks: Agreed, but if it is out of the question, adding a rand-long seems appropriate.
17:45oskarthmisread range input
17:46gfredericksRaynes: well I meant both
17:46gfredericksadd rand-long, deprecate rand-int
17:47gfredericksalso add rand-ratio just for kicks
17:47RaynesHah
17:47schaeferany core.logic expertise in the house?
17:47gfredericksschaefer: yes
17:47gfredericksand
17:47gfredericks~anyone
17:47clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
17:48schaeferthanks, clojurebot :|
17:48gfredericksthough I understand the point that you don't want to waste your time typing out the question :)
17:48Cheironclojurebot: besame mucho
17:48clojurebotIt's greek to me.
17:48casionmaybe he just wanted to know if anyone had experience.. and nothing more
17:48casionwhat then huh? what then?
17:49gfredericksclojurebot always simplificates nuanced issues
17:49schaeferi'm putting together a zork GPS app using core.logic. i've got relations for direct-path between two rooms. generally, i assume that a direct-paths between two rooms is bi-directional but, i've got a blocked relation that indicates certain directions from particular rooms are blocked
17:49schaefermy question is: i want to write a goal that lists all directions NOT blocked in a room
17:50gfredericksyou can certainly do it non-relationally
17:50schaeferi can't wrap my head around how to do a exclusion
17:50gfredericksthat's where exclusions normally lead if you can't re-express it in some positive way
17:50schaeferi'll start with a non-relational approach, though part of this is a learning exercise (not just about zork!) so if there is a relational solution, i'd love to learn it
17:51schaefergfredricks: i see. how would i do this non-relationally?
17:51gfredericks(conda ((blocked a b) fail) ((can-go a b)))
17:51gfredericksthat kind of syntax I think
17:52schaeferthanks. makes sense. let me give that a try
17:57schaeferok, so here's my not-blocked goal:
17:57schaefer(defn not-blocked [room direction]
17:57schaefer (conda
17:57schaefer [(blocked room direction)
17:57schaefer fail]
17:57schaefer [(fresh [ending-room]
17:57schaefer (direct-path room ending-room direction))]))
17:57schaeferthis returns success:
17:57schaefer(with-facts [[direct-path [['a 'b :n]]]
17:57schaefer [blocked [['a :e]
17:57schaefer ['a :w]]]]
17:57schaefer (run 5 [q]
17:57schaefer (not-blocked 'a :n)))
17:58schaeferbut, i'm surprised that running (not-blocked 'a q) fails
17:59gfredericksI bet this is why non-relationalness is unideal :)
17:59schaeferah :)
18:00gfredericksI believe when you use a non-relational goal, all the arguments should be ground
18:00gfrederickselse you will get unexpected results
18:00gfredericksif you add (membero q [:n :e :w :s]) to the top of your program, does that make it work?
18:00schaeferi was hoping that if i through in (membero direction directions) into the goal definition, it would magically work out
18:00schaeferha, see above :)
18:01gfredericksso did it? :)
18:01schaefernope
18:01schaefersame result
18:01gfredericksbooo
18:02schaeferyeah, i desperately want to change the not-blocked goal into a function that iterates over [:n :e :s :w] and test each one separately
18:02schaeferbut, i promised myself to use core.logic exclusively
18:03gfredericksschaefer: can you paste your whole bit of code on refheap so I can play with it?
18:03schaefersure. what the url of refheap?
18:03schaefernm, got it
18:04schaeferhttps://www.refheap.com/paste/4253
18:04dnolenschaefer: I think you can probably solve this one with disequality ...
18:04schaefergo on... :)
18:04dnolen(!= path ['a :e])
18:05schaeferi don't follow
18:06gfredericksthat would require an enumeration of the blockings outside of core.logic I think
18:06gfredericksrather than a blocked goal
18:06schaeferyeah, that's what i'm trying to avoid. i want to assume a bi-direction graph unless explicitly blocked
18:06schaeferi think this would be pretty straightforward otherwise
18:06gfrederickswell you have to enumerate it anyways using defrel/fact
18:07gfredericksso it's just a different mechanism. You'd loopish over your blockings vector and use disequality on each element
18:07dnolengfredericks: he's already specifying the blocked paths outside via facts.
18:08dnolenas a rel
18:08gfredericksdnolen: yep
18:08schaeferyou mean, this:
18:08schaefer(defn not-blocked [room direction]
18:08schaefer (membero direction directions)
18:08schaefer (fresh [a-room a-direction]
18:08schaefer (blocked a-room a-direction)
18:08schaefer (!= a-room room)
18:08schaefer (!= a-direction direction)))
18:08schaefermaybe i don't need the membero
18:09gfredericksno not that
18:09dnolenschaefer: try to not paste in channel :)
18:09schaefersorry :)
18:09gfredericksschaefer: assume you have (def blockings [['a :e] ['a :s] ...])
18:10schaeferk
18:10gfredericksthen you can define a (not-membero) goal that uses !=
18:10gfredericksso then (not-membero [room direction] blockings)
18:10schaeferah, so the trick is to treat blockins as a vector rather than a relation...
18:11schaeferi'll give that a shot. curious though: would the domain stuff in ckanren make this easier? i briefly toyed with it but i don't understand it enough
18:12gfredericksafaik that stuff is only numeric; so I don't see how
18:12dnolenschaefer: I'd have to think about that. but in this case I think disequality will do want you want and it'll be relational.
18:13schaefercool. i'm updating my code now. i'll let you know in a few minutes
18:13schaeferthanks for the pointer
18:17gfredericksschaefer: (membero q directions) makes it succeed for me
18:18gfredericksschaefer: added above (not-blocked 'a q)
18:18schaefercan you paste your solution into refheap? i'm obviously doing something wrong
18:19schaeferalso, i'm a bit surprised by the results of my not-membero. https://www.refheap.com/paste/4254
18:19gfrederickshttps://www.refheap.com/paste/4255
18:20gfredericksah yeah your not-membero does all the !='s independently
18:20gfredericksso what it really asserts is "There's something in v that is not u"
18:21gfredericks(defne not-membero [x coll] ([_ []]) ([_ [y . ys]] (!= x y) (not-membero x ys)))
18:22schaeferok. i'm going to have to brush up on my defne and dotted-list notation. i don't grok what this is doing
18:22schaefermy two week prolog class was lo so many years ago
18:23schaeferso, the first clause says that anything cons'd to the empty list will succeed
18:23dnolenschaefer: gfredericks goal ensures that x won't unify with anything in coll.
18:23gfredericks(defn not-membero [x coll] (conde ((emptyo coll)) ((fresh [y ys] (firsto coll y) (resto coll ys) (!= x y) (not-membero x ys)))))
18:23gfredericksschaefer: ^ same thing without defne
18:24schaeferthanks, that's hugely useful
18:24dnolenschaefer: your goal only guarantees that x won't unify with *something* in coll which is not what you want.
18:24schaefergotcha
18:25gfredericksschaefer: so yours only fails if v is all u's
18:25gfredericksand succeeds once for everything in v that is not a u
18:26schaefergfredericks: to jump back to your solution. you provided (membero q directions) in the run. i'm surprised that the first membero in not-blocked goal doesn't accomplish the same thing
18:26schaeferi'm sure this is because i'm thinking of the goal more like a subroutine but i'm having trouble internalizing what's going on
18:27gfredericksschaefer: ah ha -- that's a syntax issue
18:27gfredericksthat line has no effect
18:28schaeferoh! do i need an all?
18:28gfredericksyeps
18:28schaeferi've been bitten by that before
18:28schaeferi'm writing a defgoal macro to ensure that i don't get hit by that again
18:28gfredericksthe core.logic relations generally have no side effects, so if you (defn [...] a b c) then a and b won't do anything
18:29schaefersure. so, the good news is that i was thinking of things correctly but i hadn't defined a real goal (at least, not the goal i thought i was defining)
18:29gfredericksright
18:30schaeferah ha! it's so satisfying to see the little (:n)
18:31gfrederickswhat a weird emoticon
18:31schaefer:) thanks folks
18:34nkoza3where the println output goes when in clojure-nrepl-mode?
18:35RaynesWhat is the *nrepl* buffer, Alex?
18:38nkoza3if I type (println "hello|) in the *nrepl* buffer, then the "hello" is printed on that buffer, but if I do C-M-x in a (println "hello") on the file buffer then the return value shows in the minibuffer but I don't know where the println output goes
18:40RaynesYeah, that is weird.
18:40RaynesMight want to open an issue about that at https://github.com/kingtim/nrepl.el
18:50gfredericksslime is the same way isn't it?
18:57nkoza3i don't know, i'm just a newbie :)
19:11cshellIs there any clojure based k-means clustering libraries? I know I could try to use Mahout, but it seems like a Clojure native could benefit from the parallelism of Clojure
19:43zakwilsonI'm starting to think that making vars non-dynamic by default was a Bad Thing. Being able to dynamically rebind somebody else's function that's called in a third party's library code has been incredibly useful to me on occasion.
19:44RaynesIsn't that like monkey patching?
19:44gfredericksis var dynamicity mutable?
19:45RaynesIIRC, yes.
19:45gfredericks(defmacro monkey-patch ...)
19:46Raynes(defmacro please-god-no ...)
19:46gfredericksRaynes: clojure has to say yes to things
19:46RaynesSteve has Spoken.
19:46zakwilsonThat's exactly like monkey patching, except a little more controlled since binding itself is lexically scoped.
19:47zakwilsonAnd I actually did write a macro in CL called "monkeypatch". It made normal functions in to multimethods.
19:47gfrederickseither I totally misunderstand lexical scope or that's exactly wrong
19:47RaynesYou're like the expert on doing crazy things with functions and vars.
19:47RaynesSomeone is wrong on the internet, hold my calls.
19:48AustinYunRaynes: i'll take a look in a minute, thanks
19:48gfredericksRaynes: hey you started by disagreeing with monkeypatching
19:49RaynesI purposely avoided disagreeing with it and just asked if I was correct that what he described was monkey patching.
19:49RaynesI'm cleverer than I look.
19:49emezeskeI really like the Yegge "Say Yes" attitude, but I also think it's incredibly unhelpful to say "Yes, here is how you do an imperitive for loop with mutability in Clojure" instead of "You probably want to use this thing called reduce, here are the docs"
19:49gfredericksyou said "(defmacro please-god-no ...)"
19:49gfrederickswhich contains "no"
19:49RaynesOkay, I slipped up.
19:50nkoza3the semantics of calling a function using a Var are as if the Var is lookuped each time... but how is implemented? when you redefine the Var all the call places are somehow mutated to point to the new function so the Var isn't really lookuped in each call?
19:59zakwilsonCommon Lisp provides exactly the functionality I described with multimethods (:before, :after, :around methods, to be specific) - and yes, I misused "lexical" before. What I really meant is that binding has the structure of a with- macro in that it only applies to things that happen inside it.
19:59zakwilsonBut ultimately, I *am* advocating something like monkeypatching. The tar and feathers are over there if you need them -->
20:18dnolenzakwilson: is that what http://github.com/technomancy/robert-hooke/ is for?
20:18dnolenisn't I mean.
20:21gfredericksas long as he doesn't have a need for thread-locality
20:21clojurebotthe world <reply>what the world needs is more higher order functions
20:27zakwilsonYes, dnolen, that may be exactly what I wanted.
20:28antares_Raynes: heya
20:47zakwilsonI think the thing I didn't know about was alter-var-root. I guess I don't need to miss dynamic-by-default.
20:47gfrederickszakwilson: with-redefs is the root equivalent to binding
20:48gfredericksthe difference is that binding's effects are thread-local
20:52zakwilsonRight. I don't actually want thread-locality.
20:54zakwilsonWhat I do want is to be able to hook in to anybody else's code and bend it to my will regardless of the consequences. Looks like this does exactly that... now what happens when I try to hook core functions and do funny things to them?
20:54cshellshouldn't make a difference
20:55cshellthat's it's a core function you're hooking, that is
20:55gfredericksunless it's one of the inlined arithmetic functions
20:57zakwilsonI remember trying to do something related in Common Lisp and having it blow up when I used it on +. This was quite some time ago and I may well have been doing it wrong.
20:58gfredericks,(with-redefs [+ -] (+ 2 3))
20:58clojurebot5
20:58gfredericks,(with-redefs [cons -] (cons 2 3))
20:58clojurebot-1
20:59amalloyyou can't (usefully) redef functions that are inlined
20:59amalloy,(with-redefs [+ -] ((identity +) 2 3))
20:59clojurebot-1
21:00gfredericks,(with-redefs [+ -] (#'+ 2 3))
21:00clojurebot-1
21:00gfredericks(defmacro without-redefs [pairs & forms] (cons 'do forms))
21:02cshellwhat's the name of the function that applies a function to the first elements of each collection passed in and then the second, etc
21:02Raynesantares_: hi
21:03cshelllike (something + [1 2] [3 4]) => [4 6]
21:03antares_Raynes: I cannot reproduce your issue with Ring not being loaded. I don't think it has anything to do with Monger.
21:03Raynesantares_: I'm not sure what I'm doing wrong.
21:03llasramcshell: map
21:04antares_Raynes: can you be using noir checkouts by any chance?
21:04cshellllasram: ah, that's it - thanks -I've only used it with one collection before
21:04Raynesantares_: No.
21:05antares_Raynes: hm, I don't know then, but somehow you don't have ring on the classpath
21:05Raynesantares_: It works fine before your commit.
21:05Raynes*shrug*
21:05antares_Raynes: but monger never depended on ring
21:06antares_Raynes: can you try nuking your local repository?
21:06Raynesantares_: https://www.refheap.com/paste/cc26e83b8d9469bc111298fa7
21:06RaynesOutput of `lein classpath`
21:06Raynesring is on there.
21:08antares_https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/session/store.clj#L4
21:08antares_the protocol hasn't changed
21:10Raynesantares_: FWIW, I'm not blaming you.
21:11antares_Raynes: sure, I am just very confused how monger can affect ring loading
21:11antares_and I don't want refheap to be stuck forever on a beta version
21:19antares_Raynes: after nuking ~/.m2/repository, refheap still compiles for me
21:19Raynesantares_: After nuking it, refheap still doesn't compile for me. :\
21:20antares_Raynes: does REPL start? can you try requiring ring's session store ns?
21:23Raynesantares_: Can't find it there either.
21:25Raynesantares_: Well, I can require it.
21:25Raynesantares_: But it gives me the same error at startup.
21:27antares_I understand
21:28Raynesantares_: I can't access the SessionStore class.
21:29RaynesAh, yeah I can.
21:29RaynesIf I type the right class. ;)
21:29Raynesantares_: Yeah, I'm stumped, man.
21:29RaynesI feel like blaming Leiningen.
21:29antares_Raynes: I think it is something about the way I use protocols then
21:30RaynesYou use them in such a way that they magically don't work on OS X? :p
21:31antares_Raynes: that they may depend on load ordering
21:33antares_Raynes: can you try monger-1.2.0-SNAPSHOT? just pushed
21:33RaynesSure. One moment.
21:33emezeskeRaynes: Hey, regarding refh cljs stuffs
21:33emezeskeRaynes: What happens if you rename the file core.cljs instead of core.clj?
21:34RaynesOh man.
21:34Raynesemezeske: Did I name it clj?
21:34RaynesIf that's the problem, I'm going to kill myself.
21:34Raynesantares_: No change.
21:34emezeskeHmm, a simple self-flagellation would suffice; I don't know if you have to go all the way to full suicide
21:36Raynesemezeske: That fixes it. I'm sorry for bothering you.
21:37Raynesemezeske: emezeske: It is warning me that you should be using leiningen.core.main/about instead of numeric exit values, and then says cljsbuild failed.
21:37Raynes(but it doesn't fail)
21:38emezeskeRaynes: Is that lein 2?
21:38Raynesemezeske: Yes.
21:38emezeskeI haven't tested it against lein 2 in a while, it's constantly changing
21:38emezeskeI probably need to do a test+fix run sometime soon
21:38Raynesemezeske: Yeah, this wont work at all in the official lein2 release.
21:39emezeskeMaybe I can look at that tomorrow
21:41Raynesdnolen: ping
21:43dnolenRaynes: pong
21:44Raynesdnolen: Whenever I compile cljs targeting node, running the output prints "The "sys" module is now called "util". It should have a similar interface.". Looks like sys is util in later versions of node.
21:44RaynesAny thoughts on that?
21:44dnolenRaynes: patch?
21:44dnolen:)
21:45dnolenRaynes: seems like a one two liner to me.
21:45Raynesdnolen: https://groups.google.com/d/topic/clojure-dev/2kNEWsztyqw/discussion
21:45RaynesPretty sure I can't legally patch anything.
21:46RaynesAt least according to what one of the Stus told me.
21:46RaynesIt's probably to be a while before I can get that sorted out.
21:46RaynesI can see if amalloy will patch it for me though, if you're busy.
21:46dnolenoh that stinks, feel free to open a ticket - I'll take a look at it.
21:47RaynesAlright
21:49Raynesdnolen: http://dev.clojure.org/jira/browse/CLJS-354 <-- Pretty sure I can legally create issues under an assumed name! :p
21:52gfredericksdnolen: is the fd stuff in core.logic supposed to work with e.g. (interval -100 100)?
22:00gfredericksoh nm, my previously failing case seems to be working now
22:02dnolengfredericks: negative values are not supported in any way.
22:02dnolengfredericks: it may work, but I make no promises :)
22:02gfredericksoh ha; good to know
22:03gfredericksdnolen: can you point me to any resources that explain why the ckanren approach is limited to finite domains and can't be easily extended to e.g. all integers?
22:05dnolenRaynes: http://github.com/clojure/clojurescript/commit/67e120c53774cae1a71b0a021fcdd5e3f8f888ab, let me know if that doesn't work for you.
22:06dnolengfredericks: it's just more work, the solver has to be extended to handle it.
22:06Raynesdnolen: I have no idea how to run clojurescript without cljsbuild, which pulls it itself.
22:06Raynes:p
22:06RaynesI'm pretty sure that's all that was necessary though.
22:06dnolengfredericks: we're quickly approaching the point where enhancements will have to come from the community :)
22:06dnolenRaynes: just use lein checkouts
22:07gfredericksdnolen: I'm happy to contribute, I just don't find understanding the codebase to be easy
22:07dnolenRaynes: mkdir checkouts, :extra-classpath-dirs in your project.clj
22:07dnolengfredericks: always feel free to ask questions.
22:10gfredericksdnolen: since reading up on why lazy-seqs don't work, I've wondered how much simpler the codebase might be if it instead used an enhanced lazy seq (e.g., (defprotocol ITickableSeq (tick "Returns true if a new item is available" [self])))
22:10dnolengfredericks: I doubt it would be much simpler. The goal stuff is like 100 lines.
22:11Scriptorgfredericks: link to why lazy-seqs don't work?
22:11gfredericksokay; just a thought
22:11gfredericksScriptor: one sec
22:12gfredericks$google clojure the reasoned scheduler
22:12lazybot[Clojure and me » The Reasoned Scheduler] http://clj-me.cgrand.net/2012/01/30/the-reasoned-scheduler/
22:12gfredericksScriptor: ^
22:12Scriptorh, thanks
22:12Scriptor*ah
22:12dnolengfredericks: the reason core.logic is so much larger than miniKanren is nearly all performance related - unification for all the Clojure data types is tons of code.
22:13dnolengfredericks: but it's not really necessary to look at unification bits, they all look the same.
22:13gfredericksdnolen: I think it's more the monadish stuff I get bogged down in rather than the LOC; I don't at all mean that as a criticism since I haven't built my own in any other manner :)
22:14dnolengfredericks: the monadish stuff is actually pretty simple.
22:14Raynesdnolen: Either I don't know how to do this or checkouts don't work with things that don't have a project.clj.
22:14dnolenRaynes: yeah you need project.clj
22:14RaynesWhich makes sense, of course.
22:15dnolengfredericks: (== q 1) just returns a closure, it's effectively (fn [a] (unify a q 1))
22:15dnolengfredericks: all goals are exactly the same.
22:15dnolenso a miniKanren just threads the substitution map thorugh closures.
22:16gfredericksmaybe it would make more sense to me trying to dig in it since reading the scheduler blog post; prior to that I expected that (conde (a) (b)) would strictly alternate between a and b
22:16dnolenif you never use conde, it just threading a value through a bunch of functions.
22:16gfredericksbut now I believe it depends on exactly what a and b are doing how frequently each one emits a success
22:17dnolengfredericks: the alternating behavior of conde is a distraction, all conde does is take single substitution and return multiple ones.
22:17dnolen(bind (fn [a] ...) a) -> (a0 a1) is what conde does.
22:18dnolenbind just pushes the substitution into each closure to run it and it gets either nil, a substitution oor multilpe subsitutions.
22:18clojurebotI'm sorry, dnolen. I'm afraid I can't do that.
22:19dnolenat the end it simple looks up the value of q (the query variable) in each substition and outputs that.
22:19gfredericksright; that part seems pretty simple to me :)
22:20dnolenagain the alternating stuff takes a while to sort out, but at a high level you don't really care.
22:20dnolenit's just a giant mapcat
22:21Raynesdnolen: Is there any sort of release schedule for cljs yet?
22:21dnolenRaynes: not really.
22:21RaynesFixing the output manually take like a millisecond, so it isn't a big deal.
22:22gfredericksdnolen: thanks for the overview
22:25dnolengfredericks: http://gist.github.com/3329111
22:26dnolengfredericks: it's pretty easy to inspect what's going on. note that those anon fns must return a
22:26dnolengfredericks: returning nil will signal failure.
22:26gfredericksright
22:26dnolengfredericks: there's really nothing more to it as far as core miniKanren.
22:28gfredericksdnolen: the high level behavior makes sense to me. It's when I try to make sense of code like `(fn [~a] (-inc (mplus* ~@(bind-conde-clauses a clauses)))) and I start expanding things and there are four functions all nested in eachother and jumping through the codebase to see where everything goes makes a big tangle
22:29dnolengfredericks: so if you really want to know I can explain mplus and inc.
22:29dnolengfredericks: mplus will return a lazy list like thing
22:29dnolen(mplus (bind some-goal subst) (fn thunk [] ...))
22:30dnolenso that's a left and right branch of a search tree right there.
22:30dnolenhow do you get it bounce between the two?
22:31gfredericksis inc analagous to the ITickableSeq I brought up earlier?
22:31dnoleneasy make the left branch return a thunk
22:31dnolenif you get a thunk, flip the branches
22:31gfredericksah ha
22:31dnolen(mplus (fn thunk [] ...) inc-thunk)
22:32gfredericksit should also flip if it gets a substitution back, right?
22:32gfredericksto avoid starving the other?
22:32dnolenno a substition means you have a *choice*
22:33dnolenso it'll look like this (choice found-something (fn [] (mplus ...)))
22:33dnolenbecause conde's actually expand into:
22:33dnolen(mplus (bind ...) (fn [] (mplus (bind ...) (fn [] ...))))
22:34dnolengfrederick: https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L1103
22:34gfredericksso a choice holds a new substitution _and_ the remaining lazy stream?
22:34dnolenthat's precisely what Substitution IMPlus looks like
22:34dnolengfredericks: yep.
22:35dnolengfredericks: mplus is just a way to move around while looks for real substitutions
22:35dnolens/looks/looking
22:36Raynesdnolen: Thanks for patching that for me btw. Sorry I couldn't do it myself.
22:36dnolengfredericks: and here's the flipping on thunks http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L1891
22:36dnolenRaynes: np
22:37gfredericksdnolen: what about take?
22:38dnolengfredericks: take is just a trampoline that extracts choices
22:39dnolengfredericks: http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L1855
22:40gfredericksokay, so take is for reifying the stuff into an actual seq?
22:40dnolengfredericks: yes, the output that you actually see.
22:40dnolenrun*, run N is just sugar over take.
22:45tlowrimoreI'm rather new to Clojure (currently a full-time Ruby dev), and I'm curious to know whether there are any best practices when it comes to creating and managing a database schemas. Something like migrations in ActiveRecord?
22:45Raynesdnolen: Any reason something like this isn't in cljs? https://gist.github.com/3153856
22:46gfredericksdnolen: that was all very helpful.
22:47cshelltlowrimore: Isn't this something specific to relational databases and not different in Clojure vs Ruby?
22:48dnolengfredericks: another cool tidbit, why conda / condu work the way they do.
22:48dnolengfredericks: it all about how they deal with Choice.
22:48dnolengfrederick: https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L2240, conda actually works on the entire choice
22:49dnolengfredericks: condu https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L2262, ignores the remainder of the stream.
22:49tlowrimorecshell: if I understand your question correctly, I'm referring to the scripting of the db setup--at the application layer--rather than say, db specific DDL.
22:50tlowrimoreI see that Drift aims to provide part of this functionality, but it appears as a basic interface rather than a full-blown impl.
22:51cshellah, yeah that would have to be something in a library/app level - not in Clojure itself
22:51cshellWhy not use Mongo so you don't have to worry about schema migration?
22:51tlowrimoreyes, sorry for my ambiguity.
22:51tlowrimoreMongo doesn't really suit my need for this project.
22:52cshellIf you're using clojure you can put clojure maps directly into mongo without any transformation - it makes it really nice
22:52tlowrimoreHow does that work for report-style querying?
22:52gfredericksdnolen: I stared at that for a minute and now I can imagine how it might make sense :)
22:53cshellsomething like (mongo/insert! :my-collection {:attr1 val2 :attr2 val2}
22:53tlowrimoreBy using RDBMS, I'm hoping to index the shit out of the data.
22:53dnolengfredericks: a Choice might result in many possible answers.
22:53cshellyou can do indexes in Mongo
22:53tlowrimore...very read-heavy application
22:53cshellit's just a different way of thinking about data
22:54dnolengfredericks: condu just extracts the first one, conda doesn't
22:55gfredericksdnolen: those lines are in the context of the head of a cond[au] clause already succeeding?
22:55dnolengfredericks: if you have choice it must have.
22:55gfredericksgotcha
22:56dnolengfredericks: any implementation of any protocol on Choice means yes we found something that works.
22:58gfredericksdnolen: and the fact that "no further lines are tried" in either case is reflected in the fact that both of them ignore the 'c' argument
22:59dnolengfredericks: yep, that's the delay for the other clauses
23:01dnolengfredericks: it's why on nil we force c.
23:01gfredericksthe use of delay there I find surprising, since I figured that's something that -inc accomplishes
23:02dnolengfredericks: -inc means something very specific - it's about scheduling
23:02dnolengfredericks: we don't need that here.
23:02gfredericksgotcha
23:05dnolengfredericks: note that there's no interleaving for condu and conda unlike conde. so a bad branch can get you when you use them unlike conde.
23:05dnolengfredericks: so that's something that could (possibly?) be improved - I just adopted the miniKanren approach here.
23:06dnolengfredericks: but perhaps not ... since if you using conda/u you probably want something deterministic.
23:06gfredericksyeah I was just going through that thought process myself
23:07gfredericksif (conda ((run-forever)) (succeed)), the fact that the second line succeeds doesn't help until you've figured out the first line
23:08dnolengfredericks: so cKanren is just a layer ontop of all this that doesn't really touch the core of any off this stuff.
23:09dnolengfredericks: we have a constraint store which maps vars -> constraints.
23:09dnolengfredericks: constraints simply run when a vars value changes and refines the vars value.
23:10dnolenthe bulk of the new code is that we have 3 different domain reps
23:10dnolenFiniteDomain for small sets of pos integers. Intervals for larger sets and efficient interval math.
23:10dnolenand MultiIntervalFD for those cases where ranges get sliced out of IntervalFD
23:11gfrederickswhat effect does (+fd a b c) have when none are ground?
23:11dnolengfredericks: there's a protocol IRunnable, default is that if none of the vars have domains, constraint doesn't run.
23:12dnolengfredericks: +fd in general can't run until a b c all have domains.
23:12gfredericksbut if all have domains but still not ground?
23:12dnolengfredericks: I'm working on some stuff where +fd can run even if *c* doesn't have one, so that we can write less tedious code.
23:12gfredericksI just can't think of how to describe +fd in terms of intervals
23:12dnolengfredericks: a var is ground if it has a domain in the core.logic implementation
23:13gfredericksoh okay, so walking with the var leads to a domain object
23:13gfredericksso we say (infd a b c (interval 0 1000000)) then (+fd a b c); what does that do to the domains?
23:13dnolen(+fd (interval 1 2) (inteval 2 3) q), q clearly is (interval 3 5)
23:14gfredericksdoes the +fd start enumerating all triples?
23:14dnolengfredericks: no
23:14dnolengfredericks: in that case that's not enough information to do anything
23:14gfredericksso it literally has no effect?
23:14gfredericksor it might have an effect later if we learn more?
23:15dnolenit will intersection (interval 0 1000000) w/ (interval 0 2000000)
23:15dnolenwhich results in ....
23:15dnolen(interval 0 1000000)
23:15dnolenfor c
23:16gfredericksat some point this turns into enumeration...that happens within take?
23:16dnolengfredericks: later if a or b or c gets more specific values then the constraint will run again.
23:16gfredericksokay so the +fd stores something in the constraints store
23:16dnolengfredericks: only at the end right before reification, IForceAns is the protocols.
23:16dnolengfredericks: enumerating possibilities is last resort basically
23:17dnolengfredericks: all the constraints go into the constraint store.
23:21gfredericksoh -- was there any performance reason to use FDs in the sudoku code over #(membero % [1 2 3 4 5 6 7 8 9]) and a != -based distincto?
23:21gfrederickssudoku itself has nothing to do with numbers of course
23:21dnolengfredericks: big performance reasons.
23:21gfredericksso distinctfd must do magical stuff compared to !=
23:22dnolengfredericks: distinctfd can work on directly on Clojure sets w/o triggering search.
23:22dnolengfredericks: membero == serach
23:22gfredericksinteresting
23:22dnolengfredericks: distincfd basically adds a constraint on each var
23:23dnolenwhen a var gets single value, its constraint checks that no other var has it, and then removes it from all the others vars domains, which is fast just a (disj ...). then it remove itself from the constraint store.
23:25dnolengfredericks: the big idea here is that backtracking, searching is something to be avoided. constraints lets us shrink the space we have to search very quickly.
23:28gfredericksright
23:28dnolengfrederick: https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L3476
23:29dnolengfredericks: each distinctfd constraint knows all the other vars that are involved.
23:29dnolengfredericks: n* is the list of known values, y* is vars with domains (not yet single values)
23:30dnolen(process-dom d (difference (walk s d) x)) ... that's the var looping and removing it's value from the other vars domains.
23:32gfredericksthe explanation makes sense...the code less so; but I haven't been thinking about this constraint stuff for nearly as long as I have the core minikanren, so I suppose that's to be expected
23:33dnolengfredericks: makes sense. constraints all use reify, since we want them to be fns, but we also need to be able reflect on certain properties.
23:34gfrederickswhen I look at this to try to get a feel for it, I see four functions named -distinctfdc and -distinctfd and distinctfdc and distinctfd...
23:34gfredericksmy code tends to look like this too whenever I'm doing something complicated :)
23:34dnolengfredericks: all goals are wrapped in cgoal. cgoal does the meta stuff that every constraint needs to do.
23:34dnolenis it runnable? add it to the store etc.
23:35dnolenfoo is the wrapped constraint. fooc is the real constraint.
23:35gfredericksah ha
23:35dnolengfredericks: there reason there are two distinctfdc is that the list of vars can be fresh.
23:36dnolenso it's just a expressiveness thing.
23:36gfredericksrelevant? checks if a constraint could possibly have something useful to say in the future?
23:36dnolensoon as distinctfdc gets a ground list of vars, it creates -distinctfdc for all of them.
23:37dnolengfredericks: relevant? is the test to see if the constraint should be kicked out of the store.
23:38dnolengfredericks: we don't want to rerun constraints that won't give us new information
23:39gfredericksright
23:39gfredericksalright I think I need to let all this bake for a bit
23:40dnolengfredericks: heh, lot of info I know :) but if you've got some more questions let me know.
23:40gfredericksdnolen: I will, thanks much; I'm looking forward to hacking on it
23:43dnolengfredericks: I look forward to it as well. I'm open to ideas how to make this all more clear.
23:44dnolengfredericks: that includes var renaming patches, comment patches for subtle code etc. clearly the cKanren stuff is more up in the air ATM, but the core miniKanren is not going to change in the near future.
23:48gfredericksdnolen: all the constraint stuff we just talked about is straight from ckanren?
23:49dnolengfredericks: no, I took a lot of liberties - cKanren Scheme is very new so there a lot of perf design decisions I made that are specific to core.logic
23:49gfredericksokay
23:49dnolengfredericks: there also abstraction stuff, like runnable? relevant?
23:50dnolenin the Scheme, every constraint hard coded that stuff into it's invocation, I've broken that out.
23:50gfredericksrefactor/comment patches should just be jira tickets?
23:50dnolengfredericks: yes please.
23:51gfrederickscool; I've had ideas in the past but didn't know how welcome they were. I'll be more proactive now.
23:51dnolengfredericks: excellent!
23:51dnolengfredericks: look forward to the patch discussion :)
23:51dnolenheading out
23:51gfredericksseeya