#clojure logs

2014-06-26

02:30visofhi
02:31visofi tried to require (require 'clj-wordnet.similarity.algo.hso :reload) , but i got errors FileNotFoundException Could not locate clj_wordnet/similarity/algo/hso__init.class why it try to loat clj_wordnet not clj-wordnet
02:31visof?
02:32visofi'm using tutorial here https://github.com/delver/clj-wordnet
02:40vpmwillgorman: 25
02:41vpmoh fracking irssi, sorry :-/
03:06cesparetechnomancy: is there a way to change the column width slamhound uses?
03:11latkWhat does the hash symbol signify in this code: #(= contact %) ?
03:25justin_smithlatk: # introduces a reader macro
03:25justin_smithhere's a neat trick:
03:26justin_smith,'#(= contact %)
03:26clojurebot(fn* [p1__25#] (= contact p1__25#))
03:26justin_smithwe can see from the quoted form's expansion that it creates an anonymous function
03:26justin_smiththe var name is a bit weird, but it should be clear what it did
03:27justin_smithsometimes you get the # back in the read form
03:27justin_smith,#{1 2 3}
03:27clojurebot#{1 3 2}
03:27justin_smith,(class #{1 2 3})
03:27clojurebotclojure.lang.PersistentHashSet
03:29clodeindustriehi there, newbie here, can someone explain to me why I can do (= '(1) '(2)) and not (= (1) (2))
03:31cmdrdatsclodeindustrie: '(1) is a list with 1 element, (1) is trying to call 1 as a function
03:35clodeindustrieThe problem I was working on had ((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5) returning (5 4 3 2 1)
03:36clodeindustrieI guess I can't consider a list ?
03:52latkIs destructuring just the same as tuple unpacking in python ?
04:01ddellacostalatk: seems similar in the case of vectors, although I'm not sure what would be analogous for how hash-map destructuring works in Clojure--is there a way to do destructuring assignment with dictionaries in python?
04:02latkddellacosta: There wasn't the last time I used Python :p
04:02latkBut yes, I suppose I meant similar rather than the same
04:03ddellacosta&(let [[x y] [1 2 3]] (println "x: " x ", y: " y))
04:03lazybot⇒ x: 1 , y: 2 nil
04:03ddellacostalatk: & I guess that example is pretty similar to how Python does it, right?
04:03ddellacostaer, ^
04:03ddellacosta&(let [{:keys [x y]} {:x 1 :y 2}] (println "x: " x ", y: " y))
04:03lazybot⇒ x: 1 , y: 2 nil
04:04ddellacosta,(println "still locked out of clojurebot?")
04:04clojureboteval service is offline
04:04latkddellacosta: Pretty similar, yeah
04:21latkI see the function keys returns the keys of a map. What does {:keys [delete]} mean?
04:22latkIs this still using the keys function, or something else ?
04:24clgvlatk: that's associative destructuring of maps
04:24clgvlatk: it extracts the value bound to keyword ":delete" and binds it to symbol "delete"
04:25latkclgv: Ah, okay. That value can be any other datastructure, presumably ?
04:25latkclgv: Also, why does it get the value bound to :delete?
04:25clgvlatk: you mean the value that is finally bound to "delete"?
04:26latkclgv: Yes
04:26clgvyeah thats arbitrary
04:26latkOkay
04:27clgv,(let [my-map {:a 42 :b (zipmap (range 5) (range 5)}, {:keys [a b]} my-map] (prn a b))
04:27clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: }>
04:27clgv,(let [my-map {:a 42 :b (zipmap (range 5) (range 5))}, {:keys [a b]} my-map] (prn a b))
04:27clojurebot42 {4 4, 3 3, 2 2, 1 1, 0 0}\n
04:27clgvlatk: ^^
04:27latkclgv: Huh, okay. I would not have guessed that this is what :keys does :P
04:28latkclgv: Incidentally, where is the best place to search for this kind of thing? Is there a clojure-specific search that will understand :keys ?
04:28clgvlatk: just search for "clojure destructuring" or "clojure map destructuring"
04:29clgvthere are at least two blog post explaining the details
04:29latkclgv: No sure, I meant in general if I found something I didn't understand :p
04:29clgvlatk: ask here how it's called so that you can search properly ;)
04:29latkhah, okay :)
04:31clgvlatk: or if you are new get one of the recent books and work through it. in my experience thats the fastest way to learn clojure. depending on your speed you can be through a book in 3-5 days fulltime with trying examples
04:33latkclgv: I skimmed through a book, but found some tutorials online that seemed more interesting.. if I get stuck today, I will go back to it
04:51clgvlatk: ok, maybe that's the academic in me that wants to read such a book completely to get a solid basic knowledge ;)
04:52latkclgv: I tend to learn best by doing :P
04:58clgvlatk: that's tricky with clojure since you have to learn a lot of new concepts (depending on your background) and thus you simply can't do the thing you dont know the concepts of ;)
04:59clgvby working through the book I dont mean just reading but also experimenting with examples ;)
05:22latkclgv: I'm most comfortable programming in Haskell, so I'm relativley comfortable with functional stuff. Admittedly I have no experience with lisps..
05:27clgvlatk: yeah just wanted to share my thoughts ;)
05:27latkclgv: You may well be right - will have to see how it goes !
05:52latkCould anyone explain the let binding in: http://bpaste.net/show/VeTUgekGw8tdmudTfIqX/ ?
05:53latkIt is more complicated than the simple examples I have read, and I don't quite get it.
06:06viperscapelatk: http://bpaste.net/show/hyGOYllsePNAKNus2gh3/
06:07viperscapeit's destructuring the string's parts into a vector, called parts
06:09viperscapeyou could just as well do (second parts) within the let bindings, or simply "last" since it's techinically bound to it through the destructuring
06:11viperscapealso, I wouldn't suggest using key terms such as first and last
06:11latkviperscape: Isn't all of the stuff inside the first set of [] in the same let binding ?
06:13viperscape,(let [[f m l :as parts] (clojure.string/split "first last" #"\s+")] (= m (second parts)))
06:13clojurebottrue
06:15viperscapethe second line is simply reordering the f m l parts, essentially dropping middle-name if needed
06:15viperscapeor last, rather
06:15latkthis is what I suspected
06:16viperscapehttp://blog.jayfields.com/2010/07/clojure-destructuring.html
06:21clgvbe carefull with the combination of :or and :as ;)
06:44hyPiRionoh, that one's always "funny"
06:44hyPiRionAlso the fact that either :or or :as does its argument in reverse
07:06latk,(.. "string" (substring 2) (equals "ring"))
07:06clojurebottrue
07:07latk,(-> "string" (substring 2) (equals "ring"))
07:07clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: equals in this context, compiling:(NO_SOURCE_PATH:0:0)>
07:08ro_stif i use key destructuring inside a when-let, does the when part look at each of the destructured locals?
07:11luxbockhttps://gist.github.com/luxbock/425ae5912656b9ff7803
07:11luxbockwhat is the right way to translate the (new Date(d)) part to CLJS?
07:13hyPiRion,(= (subs "string" 2) "ring")
07:13clojurebottrue
07:13latkHow can I find the documentation on .. and . in clojurescript ?
07:18TimMclatk: It's the same as in Clojure. (doc ..)
07:19TimMclatk: . is a special form, though, and probably doesn't have doc from the REPL.
07:19TimMchttp://clojure.github.io/clojure/clojure.core-api.html#clojure.core/.
07:26clgv(doc ..)
07:26clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
07:50jonathanji feel like i'm being silly here
07:51jonathanji created a new project with lein and do lein repl but i can't access stuff defined in my code as i was expecting:
07:51jonathanjclj-neon.core=> -input-stream
07:51jonathanjCompilerException java.lang.RuntimeException: Unable to resolve symbol: -input-stream in this context, compiling:(/private/var/folders/qj/lb3tbsp97gg74jpcxtcw30zm0000gn/T/form-init698424686803171253.clj:1:941)
07:51jonathanjcore.clj:6: (defn -input-stream
08:27jcromartiecan any Enlive contributors comment on https://github.com/cgrand/enlive/pull/107
08:29jcromartie2 weeks and no comments or nuffin
08:49latkWhere can I find the docs for om.dom ?
09:07olliverahow can I access locale value in the array? :pageid "1" :translation [{:locale "ja_JP"},{:locale "zh_CN"}]
09:09bbloomthat's a "vector" not an array
09:09bbloom(doc get-in)
09:09clojurebot"([m ks] [m ks not-found]); Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied."
09:09olliveraokay, thank you
09:09bbloom(get-in yourmap [:translation 0 :local])
09:46visof,(clojure.string/split "helloWorld" #"(?=[A-Z])")
09:46clojurebot["hello" "World"]
09:46visof,(clojure.string/split "helloWOrld" #"(?=[A-Z])")
09:46clojurebot["hello" "W" "Orld"]
09:46visofthat's problem for splitting
09:47visofhow can i fix this ?
09:50TimMcvisof: You haven't explained why you tthink that's wrong. :-)
09:51visofTimMc: i need to split in the first upper letter
09:51visofif i got two or n upper letter consecutive then split at first one
09:52visof,(clojure.string/split "helloWOrld" #"(?=[A-Z][A-Z])")
09:52clojurebot["hello" "WOrld"]
09:52visof,(clojure.string/split "helloWORld" #"(?=[A-Z][A-Z][A-Z])")
09:52clojurebot["hello" "WORld"]
09:52TimMc,(clojure.string/split "helloWOrld" #"(?=[A-Z]+)")
09:52clojurebot["hello" "W" "Orld"]
09:52TimMcHmm, right.
09:53visofthis techinque do what i need, so the solution maybe to check if there is [A-Z]+ pattern
09:53visofif i got [A-Z] pattern then split at [A-Z]
09:53TimMcYou could include a negative lookbehind for uppercase.
09:53visofif there is two then split at [A-Z][A-Z]
09:54visofif there are n split at [A-Z]..n
09:54visofis there a good way to do this?
09:55TimMc,(clojure.string/split "helloWOrld" #"(?<![A-Z])(?=[A-Z])")
09:55clojurebot["hello" "WOrld"]
09:56TimMcvisof: but maybe you actually want the camel-snake-kebab library?
09:57Dutch|AFKquit
09:57visofTimMc: can it handle myAPI ?
09:57visofhave you checked it?
09:58TimMcvisof: Haven't used it myself, but I think it handles this sort of thing.
09:58visofTimMc: i'm trying it
10:18ShayanjmIs there a way that I can completely replace the values in a ref with totally new values?
10:18Shayanjmupdate-in seems to modify state with some applied function
10:18Shayanjmbut that seems a bit roundabout for what I'm trying to do
10:20TimMcShayanjm: ref-set
10:20Shayanjmwow.
10:20Shayanjmthanks TimMc
10:20Shayanjmi should probably just generally read the API docs shouldn't I
10:20TimMcShayanjm: I keep telling myself that one of these days I will skim through clojure.core.
10:20Shayanjmlol
10:20TimMchttp://clojure.org/cheatsheet is good though
10:21Shayanjmah
10:22Shayanjmso if I'm understanding correctly: refs have write guarantees when transacted upon?
10:22Shayanjmso I'm assuming to reap those benefits you would have to be transacting over multiple refs?
10:23Shayanjm(i.e: can't be a ref & an atom?)
10:23TimMcyeah
10:23Shayanjmk cool
10:23TimMcOnly refs (and in a certain sense, agents) participate in txs,
10:23TimMc.
10:24TimMc(Txns delay agent sends until they complete.)
10:26Shayanjmgotcha
10:27ShayanjmYeah basically I'm just getting a bunch of stuff from the NYT API, sticking it in (what used to be an atom) what is now a ref, performing SA on the URLS in the ref, and storing the results to a second ref so they can be 'gotten' easily
10:29TimMcShayanjm: Make sure you understand what ensure does.
10:31TimMc(Watch out for write skew.)
10:34Shayanjmwait what DOES ensure do?
10:34Shayanjmit says it provides 'more concurrency than ref-set'
10:34Shayanjmlooking online, the provided examples aren't really clear either...
10:35ShayanjmMy best guess is: if I'm altering ref1 via ref-set or something, i'd need to throw ensure on ref2 to make sure it's not accidentally transacted on in the meanwhile?
10:35Shayanjmbut if I'm ref-setting BOTH refs within a single dosync, would using ensure matter?
10:37TimMcYou got it. (in *2)
10:38TimMcIt prevents ref2 from being written to if you're only reading from it.
10:38ShayanjmI see
10:38Shayanjmbut isn't the whole clojure mantra 'no side effects'?
10:38Shayanjmerr, i guess lisp mantra?
10:38TimMcbut multiple txns can call ensure on the same ref without interfering with each other (more concurrency)
10:38Shayanjmoic
10:39Shayanjmso i could have 3x ensure on a ref without issues?
10:39Shayanjmdoes ensure just last the lifetime of the txn?
10:40TimMcyeah
10:40Shayanjmcool
10:40TimMc(Theoretically, haven't tested or read the source.)
10:40Shayanjmkk
10:41TimMcVarious Lisps use side-effects all over the place.
10:41TimMc(mutablle cons, etc)
10:41TimMcClojure is focused on reducing *uncontrolled* mutation.
10:42Shayanjmgotcha
10:43koreth__That's even true of something like Haskell, really -- they're not against side effects per se over in Haskell land, it's just about keeping them well-contained and nailing down the semantics.
10:43Shayanjmgotcha
10:55benzapwhen destructuring, is there a way to bind a key to a new key name? like (let [{:keys [x :as blah]}]...
10:56cbp(let [{a :c} {:c 1}] c)
10:56cbper
10:56cbp,(let [{a :c} {:c 1}] a)
10:56clojurebot1
10:57benzapah ok
11:21mockerIs there a difference between these two things?
11:21mocker,(merge {:a 1 :b 2} {:b 3 :c 4})
11:21clojurebot{:c 4, :b 3, :a 1}
11:21mocker,(conj {:a 1 :b 2} {:b 3 :c 4})
11:21clojurebot{:c 4, :b 3, :a 1}
11:22ndalyI think merge can take an arbitrary number of arguments and conj only conjoins one
11:22ndalybut I'm a total newb, so I could be wrong
11:22mocker:)
11:22mockernewbs unite!
11:24llasramWhen everything is a map I believe they have the same result, but `merge` makes that intent more explicit and handles a `nil` initial argument differently
11:24llasram,(conj {} {:a 1} {:b 1} {:c 1})
11:24clojurebot{:c 1, :b 1, :a 1}
11:25llasram,(conj nil {:a 1} {:b 1} {:c 1})
11:25clojurebot({:c 1} {:b 1} {:a 1})
11:25llasram,(merge nil {:a 1} {:b 1} {:c 1})
11:25clojurebot{:c 1, :b 1, :a 1}
11:25mockerNice, thanks.
11:26llasramHmm, and `merge` can apparently take 0 arguments
11:26llasram,(merge)
11:26clojurebotnil
11:26llasram,(merge {})
11:26clojurebot{}
11:26llasramFun times
12:04jjl`llasram: quite a few functions 'do the right thing' with zero arguments
12:08cbp(merge) => nil is hardly the right thing
12:08ddellacostacbp: what would the right thing be?
12:08cbp{}
12:09ddellacostacbp: but merge doesn't work exclusively on hash-maps
12:09ddellacostaalthough the docs seem to suggest it does...weird
12:10ddellacostahuh, the implementation is pretty generic. Not sure why the docs say what they do.
12:13ndalycbp: (seq {}) => nil
12:13cbpndaly: ?
12:14ndalycbp: not sure, just thought it might be relevant for the rationale behind (merge) => nil
12:15ndalysomething that's merging in a loop will probably need to know when the merge results in an empty map
12:15TimMcjjl`: That's a low bar, though. I mean, base cases are *kind of a big thing* in functional programming.
12:15ndalyand nil let's them use a truth test for that
12:15ndalyanyway, I don't know enough to know what the right thing would be, but that may be part of the rationale
12:15TimMcNil punning is the worst.
12:16cbp{} would be the identity value of merge
12:16cbplike how 0 is of +
12:16ndaly,(merge {})
12:16clojurebot{}
12:16TimMc(Worst reason for a design decision, at least.)
12:16ndaly,(merge)
12:16clojurebotnil
12:17jjl`TimMc: and there are many ways to solve them. e.g. the little schemer provides simple rules of recursion to catch them
12:18TimMcjjl`: I'm just continually surprised at how many Clojure fns don't support nullary or unary forms.
12:18jjl`TimMc: and there's where it comes down to opinion about what 'the right thing' is
12:20TimMc&(assoc-in {:a :b} [] 5)
12:20lazybot⇒ {nil 5, :a :b}
12:20edwDo we have a One True Matrix library? Or something resemblng one? I see clatrix…
12:20TimMcIt's shit like that.
12:21TimMcNot only is the base case not supported, it clearly wasn't even considered.
12:21seangrov`&(get (assoc-in {:a :b} [] 5) nil)
12:21lazybot⇒ 5
12:21seangrov`uhg, wow
12:21clgvTimMc: there is a ticket for that or update-in ...
12:21rplacathus foiling my PAAS platform arbitrage edw: core.matrix is headed that way - it can wrap Clatrix and others
12:21TimMc,(assoc-in {:a :b} [] 5)
12:21clojurebot{nil 5, :a :b}
12:21rplacaedw: core.matrix is headed that way - it can wrap Clatrix and others
12:21edwrplaca: Ah, thanks.
12:22edwrplaca: I don't see a clojure/core.matrix repo on GitHub… Is it unofficial yet?
12:24rplacaedw: it's not officially part of Clojure yet, but I think it's on that road
12:24edwrplaca: Ah. I'll widen my search.
12:24rplacathe subject has been discussed and Rich, et al., are open to the idea of adding it when the time is right
12:25rplacaedw: https://github.com/mikera/core.matrix
12:25edwrplaca: Thanks. Addin' it to my project.clj
12:25rplacaedw: cool
12:29amalloyTimMc: for what it's worth, it's not clear what the behavior of (assoc-in {} [] 5) should be, or the equivalent with update-in
12:30TimMcamalloy: The result should be 5.
12:30amalloythat's a result that's reasonable in this peephole focus, but do you really want to be the guy who tells everyone that assoc-in doesn't always return a map?
12:30amalloy{nil 5} is stupid, but there's nothing that's great. {}, 5, throw-an-exception, are all sorta plausible
12:32amalloyuseful has versions of assoc-in and update-in that do in fact return 5 in that case, but it's not really the kind of behavior i'd welcome in clojure.core - https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L95-L118
12:32TimMcI'm OK with it not always returning a map.
12:32amalloyi'd prefer it throwing an exception, personally
12:32TimMcI'd understand if people were upset, but... *shrug*.
12:32amalloyand if you want a version that returns 5 (which is a fine thing to want), that's easy to write
12:33clgvamalloy: for update-in there is a reasonable default, apply the function to the root map
12:33amalloyclgv: that's exactly the same as for assoc-in
12:33amalloyyou want to make update-in not always return a map; that's going to create as many issues as the current behavior
12:33TimMc&(update-in {:a :b} [] (constantly 5))
12:33lazybot⇒ {nil 5, :a :b}
12:34TimMc&(assoc-in nil nil nil)
12:34lazybot⇒ {nil nil}
12:34TimMcphweeee
12:34ambroseb_clearly that should throw an exception, but clojure.core error handling ..
12:35amalloyambroseb_: well, as a static-typing enthusiast, of course you want it to never return a non-map! but TimMc thinks it's just as clear that it should return 5
12:36clgvamalloy: well for update functions that return maps that would be useful. if you use it with a function that does not return a map its your fault. at least the regular use case for empty path works...
12:36amalloylet's have it return a Maybe
12:36amalloyclgv: i find it useful also; that's why i put it in org.flatland/useful
12:36jjl`and how is that going to be any different from using a sentinel value (such as nil) in practice, in a language like clojure?
12:36TimMcambroseb_: Does core.typed support the notion of "non-empty coll"?
12:37amalloybut it's hardly the only sensible behavior - i'd argue it's not much better as a default than the current nonsense
12:37clgvamalloy: ah ok^^
12:37ambroseb_TimMc: yes.
12:37amalloyjjl`: Maybe was not a real suggestion
12:37TimMcSo assoc-in could be described as returning a map if given a non-empty keyseq.
12:37jjl`amalloy: you never know. i saw a 2014 java article about a maybe type. and of course they missed the point :)
12:38ambroseb_assoc-in is special cased in core.typed, but it falls back on basically Any -> Any https://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/base_env.clj#L1024
12:38amalloyi'm a big fan of haskell and its types, but you can't just dump them into clojure
12:40ambroseb_rich declined an enhancement for fixing assoc-in, but I think it's really a job for linters like Dynalint anyway.
12:40ambroseb_same as the open ticket about `get` throwing on non-Associative
12:40amalloyfor linters? how can a static linter fix assoc-in?
12:41ndalyit can't, but it can point out pathological uses
12:42ambroseb_sorry, Dynalint isn't really a linter, it redefines core vars to include better errors and warnings on undefined behaviour.
12:42ndalyinteresting
12:42ambroseb_I consider assoc-in on empty path & get on non-Associative to be undefined behaviour, so Dynalint would complain if it gets evaluated.
12:43amalloyambroseb_: couldn't the type be [(U nil (Associative Any Any)) (Seqable Any) Any -> (Associative Any Any)]? assoc-in always returns a map
12:43ambroseb_amalloy: correct, it's a dumb type either way.
12:43cbp:-P https://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/base_env.clj#L865
12:43cbpJust in case comment doesn't work
12:43ambroseb_amalloy: ideally there'd be fancy dotted types linking the paths to the output map
12:44Bronsacbp: comment would insert a nil
12:44ambroseb_grep for "insane"
12:44amalloycbp: yeah, comment is no good there. the comment is in case #_ doesn't work; exactly the opposite of what you thought
12:45cbp:-(
12:45ambroseb_cbp: as someone pointed out to me, core.typed uses every kind of comment, and then some
12:46amalloywell, actually comment wouldn't insert a nil after all, Bronsa
12:46amalloybecause this is inside another macro
12:46amalloyso comment wouldn't even get macroexpanded, it would confuse the outer macro first
12:47amalloyjust like you can't write (defn (comment lol) f [x] x) - not because (comment lol) expands to nil, but because defn is baffled
12:47Bronsaamalloy: oh, sure. I assumed the wrapping expression was a function call
12:49ambroseb_I hear core.typed is in the new 7 languages book?
12:49ambroseb_oh core.logic
12:49ambroseb_haha, finger memory.
12:50ambroseb_anyway, that's awesome.
12:53ambroseb_on that note, I hope dnolen isn't still stuck in some airport :)
12:53ambroseb_heard he had a nightmare travel to EuroClojure
12:54TEttingerI spent 24 hours in transit from australia to california once
12:54ambroseb_ouch
12:54TEttingerand there were people on my flight who had further to go
12:54TEttinger(when the family got back, the car battery was dead too)
12:55ambroseb_haha
12:55TEttingerthere was everything, mechanical failure on a plane, while waiting for replacement there's a bomb threat..
12:56TEttingerso I hope dnolen doesn't have to deal with that
12:56ambroseb_my travel time to the US when everything goes *smoothly* is usually 30 hours.
12:56TEttingerouch
12:56TEttingergoing from asia or europe?
12:56ambroseb_Perth, Western Australia
12:56TEttingerah.
12:56TEttingereven further
12:57ambroseb_yea, I'm sick of it so I'm moving to Indiana.
12:57ambroseb_;)
12:57TEttingerperth is IIRC incredibly hot, has unusual weather and extremely poisonous wildlife?
12:57ambroseb_haha sure!
12:57TEttingerwhich is why the trip didn't go visit
12:58mdeboardWhat's wrong with Indiana
12:58dbaschmdeboard: have you been to Indiana?
12:58mdeboarddbasch: I am here right now :)
12:58dbaschmdeboard: is that where you're from?
12:58TEttingermy brother watched a cricket game in melbourne in the summer. the heat was rough
12:59TEttingertasmania was nice though
12:59mdeboarddbasch: ya, only been back a few years and moving out again next month
12:59ambroseb_I meant Indiana means I don't need to travel 30 hours to get anywhere :)
12:59dbaschambroseb_: it depends on where you want to go. If you want a more central location try Denver or Chicago
13:00TEttingeratlanta is where 2 of the airlines have hubs I think
13:00dbaschthe Traveling Clojurist Problem, also known as TCP
13:00dbaschIndiana Pacers, also known as IP
13:00mdeboardlol
13:01TEttingerbut it's hard to beat SF I imagine for meeting clojurists
13:01ambroseb_I have conferences in Montreal, St Louis and London, probably a few hours closer than Perth :)
13:01mdeboardIndiana has a really modern airport that is very uncrowded, TSA is best I've ever been through (and I *HATE* the TSA)
13:01dbaschSF rocks in that sense
13:01mdeboardI will miss Indianapolis airport and Indianapolis traffic the most
13:01mdeboardwhen I move to Austin
13:01rplacabut the only place to find Dan Friedman is in Indiana...
13:02rplaca:)
13:02dbaschSFO is not bad compared to other airports in the US
13:03amalloywait, is ambroseb_ actually moving to indiana? i can't keep track of the real statements in this conversation
13:03ambroseb_amalloy: yes, PhD starting at Indiana Bloomington in about a month.
13:04amalloyman, i'll have to start saying nicer things about core.typed
13:04TEttingerdr ambrose b
13:04amalloynow that i'm in striking distance
13:04dbaschambroseb_: funny, a friend of mine is there right now at the ACM Web Science conf
13:05amalloyweb science? i can't believe there's much science about the web, unless this conference is focused on actual spiders
13:05dbaschamalloy: go tell them :P http://websci14.org/
13:05ambroseb_amalloy: where are you?
13:05amalloyoh, LA. not actually that close, but closer than australia
13:06amalloymy sister's getting her phd at purdue, though
13:06ambroseb_certainly
13:06dbaschI'm in LA too, but only for today
13:06amalloyso i've spent two days in indiana
13:06amalloypractically a native
13:07dbaschmy friend speaking at websci is now "Head of Query Understanding" at LinkedIn
13:08cbpwat
13:08dbaschcbp: exactly
13:08dbaschbetter than another old coworker of mine who called himself "Chief Entomologist"
13:08clgvdbasch: you certainly need a head for query understanding :P :D
13:09dbaschclgv: and you want to hold on to it
13:09dbaschone time I collected all the ways in which people had ended up at britneyspears.com through a query
13:10dbaschyou wouldn't believe the spelling creativity of the web
13:10dbasch(you can tell this was 10 years ago, when Britney Spears was relevant)
13:11dbasch$google brittny spiers
13:11lazybot[britney spiers 123 remix - YouTube] http://www.youtube.com/watch?v=goeAUbtolEE
13:11amalloybuttery spores
13:11dbaschdamn, I get britney spears
13:11dbaschbtirnsy spirss works too
13:12dbaschyou can find britney spears on google while wearing box gloves
13:12amalloydbasch: by induction, any google search at all yields britney spears, yes?
13:12dbaschboxing gloves
13:13dbaschamalloy: enough monkeys typing will only create the works of shakespeare if they don't get distracted by britney spears first
13:14dbaschit would be a fun game: guess the google result
13:14dbaschrianah -> rihanna
13:15dbaschgoogle distance is always closer than Levenshtein's
13:21aconz2quick q on clojure-contrib libs. I'm looking to use clojure.contrib.java-utils, tho it seems like this has moved and/or been dropped from contrib? seems like a lot of libs listed on http://richhickey.github.io/clojure-contrib/java-utils-api.html have been dropped in the move to the clojure repo
13:21dbasch~contrib
13:21clojurebotMonolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
13:26aconz2thanks! @dbasch : could some work be done to update the page I linked? pretty deceiving, tho only as an artifact of googling. I'd be happy to do the work and make a PR if helpful
13:34amalloyaconz2: the work that should be done is to delete richhickey.github.io - no official clojure stuff has been hosted in his repo for years
13:35amalloyit's all just old and decaying versions of stuff long since superseded by clojure.github.io
13:42aconz2amalloy: has an attempt been made to delete already? I mean the problem of "misinformation" is solved for me, but I imagine it would still be an issue for any other new(ish)comer
13:43xeno__Given 2 similar web apps written in Rails and Luminus, running on a quad-core i7 with 32GB RAM, would Clojure + jetty be more efficient in resource usage compared with Rails + Unicorn? I will be deploying a single-box app soon and wondered about memory usage and process size.
13:44mdeboardxeno__: Withoutknowing anything abou tyour application that's basically impossible to answer. With the JVM you can set max memory usage
13:44dbaschxeno__: it's kind of hard to answer that question in the abstract. "web app" doesn't say much about memory usage, the question is more about what you're doing in the backend
13:46amalloyxeno__: with rails, memory usage scales pretty quickly with number of processes, right? since you need N different rails processes. whereas the jvm has a high up-front cost just to start a single jvm, but threads are very cheap
13:51xeno__amalloy: So you give up, say, 200MB RAM for the JVM but can then get each process using a fraction of a comparable Rails process?
13:51amalloyxeno__: it's not close to 200MB
13:51xeno__amalloy: What, then?
13:51amalloywell, maybe it is. it's hard to say because a lot of it is disk buffers
13:51amalloymmapped jars, etc
13:51xeno__amalloy: Typically, I mean.
13:51dbaschxeno__ amalloy it also depends on what you're using to run Rails
13:51amalloyhe said unicorn
13:52amalloynot that i'm a rails expert or anything
13:52dbaschI only used Passenger, which I believe lets you play with processes and threads
13:53xeno__amalloy: Just trying to get some idea of trade-offs for a CRUD app which also does some quick calculations for about 1 in 3 requests.
13:53amalloyxeno__: well, okay, maybe it is close to 200MB. i have some clojure servers running, with the java heap size set small, so most of the overhead is the jvm itself. they have a resident set size of around 150MB
13:53amalloyi've no idea how much of that they'd be willing to "give back" if there were memory pressure
13:53xeno__Just thinking if I have the basic principle correct, ie. allocate so much for JVM then each process is much cheaper?
13:54amalloyxeno__: well, there's only one process
13:54amalloythreads inside the jvm aren't full OS-level processes, although i confess i'm not sure exactly what they are
13:54justin_smithxeno__: unlike in ruby, in the jvm it is viable to have multiple threads in one vm
13:54xeno__amalloy: 200/300MB is no big deal for me if there is 32GB in total available.
13:55dbasch32GB for a web server. I feel old.
13:55amalloyyou should have no trouble running just about anything on 32GB
13:55amalloymy linode has 3GB and is running five or six different clojure webservers
13:55justin_smithxeno__: another data point: I have never had to restart a production clojure app because of a memory leak.
13:56amalloyi have!
13:56dbaschmy crappy mp3 search engine in 1998 handled a peak of 200k queries in one day with 128 mb
13:56amalloyi spent weeks, maybe a month, on and off trying to track down a memory leak
13:56cbpit certainly didnt use lucene amirite
13:57justin_smithamalloy: yeah, wasn't saying it was impossilbe. But from what I hear from ex ruby users at my old job, constantly restarting ruby tasks that had their memory usage balloon uncontrollably was a routine thing
13:57xeno__dbasch: Check 'em out at Hetzner. 32GB/quad-core i7 for under 500 quid a year.
13:57amalloyyeah, that seemed to happen all the time when i was at geni, justin_smith
13:57xeno__justin_smith: Yes, exactly what I'm trying to avoid.
13:57amalloythey had a monit task that hunted for ruby processes whose memory usage was too high and automatically destroyed them
13:59justin_smithxeno__: from what I can tell, in clojure a task that has memory usage blow up isn't routine, it's considered an anomoly. I have clojure servers with very long uptime, only limited by the need restart in order to deploy updates
13:59amalloyyeah, for sure
13:59amalloymy clojure servers have uptime that's the same as the machine itself
14:00amalloywell, except 4clojure. that one restarts itself all the time because its fundamental requirement is to do stupid stuff (ie, evaluate user-supplied code)
14:00xeno__justin_smith: Yes, I'm attracted to what seems to be easier server management with Clojure/JVM compared with Rails
14:01xeno__justin_smith: I started writing the app in Rails while learning Clojure and was going to rewrite later in Clojure but now I'm thinking get it done right at the outset.
14:02amalloyxeno__: that sounds like a good approach. it'll give you something concrete to work towards while learning clojure
14:02amalloyavoid the classic problem of "anyone know an OSS project that wants help from someone who doesn't know how to do anything?"
14:03justin_smithxeno__: I think that would be good. And about your above question, I think the only way clojure would use more ram would be a fixed size price you pay at the outset (the size of clojure, size of the jvm), and that size is not enough to flatten a server, and after that it scales much better than ror / unicorn
14:03xeno__amalloy: Trouble is you get too deeply into the Rails MVC OO mindset.
14:03tuftxeno__: you're probably in a similar situation to me with django. our provisioning is so complex compared to just installing the JVM and deploying fat jars
14:04xeno__justin_smith: That was my concern. If there's plenty of RAM available it sounds like JVM is more efficient as the app scales.
14:04tuftyeah, real threads always helpful with conserving that shared stuff =)
14:05justin_smithxeno__: at my previous place of employment we had an in house clojure web framework that started as a rails replacement
14:05justin_smithxeno__: this, as you can imagine, was advantageous in some ways, and in others was an impediment
14:06justin_smithit's pretty heavyweight, and in the clojure world we do prefer combining modular libs over big kitchen sink included frameworks, but caribou is out there if you want to try it
14:06justin_smithand it does work
14:07latkcould anyone point me to some more complicated examples of om applications? The example code I have found is pretty limited in scope.
14:07gtrakjustin_smith: the choice of domain wording can be a little uncomfortable? :-)
14:07xeno__justin_smith: Had a look at it a while ago briefly. So it's a Rails clone?
14:08xeno__justin_smith: But not heavier than Rails itself?
14:08gtrakhow would you make a rails clone?
14:08justin_smithgtrak: let-caribou.in ? heh, I picked let-caribou since that had kind of a clojure-esque feel to it, and my tech manager decided it should be a .in domain because he was a perv
14:08gtrakjustin_smith: hahaha
14:09justin_smithxeno__: not a rails clone, just developed as a smooth upgrade from rails
14:09gtrakwell, it doesn't even have to go there, 'let the caribou in to our house? you're crazy?'
14:09justin_smithxeno__: so it was a priority to re-implement workflows and functionality that the workplace had grown fond of
14:09gtrakit'll wreck all the china and scratch the furniture.
14:09xeno__justin_smith: Could be very useful to me then unless I just drop the Rails prototype approach altogether.
14:10xeno__justin_smith: Is it being developed actively?
14:11justin_smithxeno__: the company divested from clojure, and laid the clojure team off (both of us!)
14:11justin_smithwe still address bug reports on github, and some day I may start up where I left off with some of the features
14:11justin_smithbut it is less active after the layoff to be sure
14:12justin_smithmind that it has been used in many production sites, so it's pretty stable and mature (if very large)
14:13xeno__justin_smith: What's missing at present?
14:14xeno__justin_smith: I started out with Luminus.
14:23FrozenlockI'll give plenty of love to whoever can solve this https://github.com/dakrone/clj-http/issues/202
14:26gtrakFrozenlock: does http-kit actually verify the certs?
14:27gtrakI thought at least the server didn't do ssl at all.
14:30amalloygtrak: it uses java's http library, which does verify certs
14:31amalloyafaict java doesn't yet support SNI
14:31gtrakugh I hate security
14:32justin_smithgtrak: Frozenlock: I've generally gotten the recommendation to do ssl via an nginx layer
14:32justin_smithnginx should be in front of whatever you have public facing, regardless
14:32amalloyjustin_smith: oh, for sure. that's not the problem
14:32amalloythey're talking about client-side
14:32justin_smithoh, that
14:33amalloyif you have one server with nginx serving ssl for two different domains, then java clients get mad
14:34amalloyi had some trouble recently with the 4clojure.com server, which also hosts refheap, and does ssl for both of them. browsers can handle it because they have SNI support, but clojure and python do their ssl negotiation before sending the Host header, so nginx can't know which ssl cert to use
14:36gtrakat least you hide your lein-in-production behind an nginx
14:36amalloyi always thought lein was an abbreviation for leininproduction
14:36amalloygerman all sounds the same to me
14:37gtrakdid you konw taht a cbaimrgde uvenisitry stduy...
14:38arrdemow my face
14:38gtrakthat could be a really simple clojure app
14:39amalloygtrak: that story is actually a bit dubious - it's typically presented with "random" rearrangements that are easier to read than most orderings
14:41Frozenlockamalloy: "afaict java doesn't yet support SNI" I hope it's not the case. I've read it's somehow supported since 1.7, but I don't know enough about this particular subject :-(
14:42FrozenlockAbout 4clojure and refheap, did you find a solution? Different servers?
14:42amalloyuser> (munge "gtrak: that story is actually a bit dubious - it's typically presented with \"random\" rearrangements that are easier to read than most orderings") => "gratk: that sorty is atlucaly a bit douibus - it's tailclypy ptersneed with \"rdanom\" rgmaerenenrats that are eseair to raed than most orirnegds"
14:43amalloybasically it works pretty well for short or common words, but things like "ptersneed" or "tailclypy" are pretty tough to figure out
14:43gtrakptersneed is pretty funny
14:44benzapamalloy: you need to reduce the amount of characters movements from it's point of origin
14:44amalloyFrozenlock: we arranged for refheap's cert to be used in the case of clients that don't support SNI. that works fine because nobody ever uses 4clojure outside of a browser
14:46ndalyre: 4clojure.com: "So wait, I can't buy cheap real estate here?" … rofl
14:49Frozenlockhttps://github.com/OpenSourceFieldlinguistics/FieldDB/issues/1435
14:49FrozenlockDamned be my limited brain. I don't understand why it doesn't work for Clojure.
14:50DomKMAre URI fragments not available in ring request maps? I don't see fragment/anchor/hash in the ring spec and ring mock is not parsing them.
14:50amalloyDomKM: they're not sent to the server at all, right?
14:53amalloya difficult scrambled word: dtcnuesrutirg
14:53cbpdestructuring?
14:53clojurebotdestructuring is http://clojure.org/special_forms#binding-forms
14:54amalloywell, okay, not *that* difficult. but harder than wehre
14:55Frozenlock,(take 5 (slurp "https://www.4clojure.com&quot;))
14:55clojurebot#<SecurityException java.lang.SecurityException: denied>
14:55Frozenlockerr
14:56FrozenlockAnyhow, how comes slurping works?
14:56cbpFrozenlock: what is the issue?
14:56cbp(doc slurp)
14:56clojurebot"([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments."
14:56amalloyhm, good question. not sure; i thought that was broken
14:57cbp(doc clojure.java.io/reader)
14:57clojurebot"([x & opts]); Attempts to coerce its argument into an open java.io.Reader. Default implementations always return a java.io.BufferedReader. Default implementations are provided for Reader, BufferedReader, InputStream, File, URI, URL, Socket, byte arrays, character arrays, and String. If argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to
14:57Frozenlockcbp: clj-http can't handle SNI (https with multiple certs on the server), but `slurp' can.
14:57cbpoh
14:57cbpsorry i misunderstood :-P
14:57TimMcFrozenlock: What happens if you slurp a site with an invalid cert?
14:57FrozenlockTimMc: Good question...
14:58FrozenlockAnyone has one around?
14:58gtrak*BOOM* goes the JVM
14:58TimMcMaybe slurp just ignores the "cert failure" due to SNI.
14:58DomKMamalloy: I don't know. I guess I should find that out first.
14:58TimMcFrozenlock: https://www.cacert.org/ assuming you dno't have their root cert installed
14:59amalloy$google http spec fragment
14:59lazybot[RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax] http://tools.ietf.org/html/rfc3986
14:59DomKMamalloy: Looks like you're correct. Thanks :)
15:00FrozenlockBOOM! javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
15:00gtrakjust shell out to curl
15:00TimMcOK, so it doesn't ignore *that* kind of failure. :-)
15:01Frozenlocktechnology, y u no work?
15:02gtraksecurity is a pain-fractal
15:02tuftsoftware is hard =(
15:03gtraknormal software at least creates value :-)
15:03Frozenlocksecurity doesn't?
15:03gtrakunless of course it's getting hacked, sigh..
15:03cbpcreates more jobs to maintain it at least
15:04TimMcI guess there can't be a pathod-like service that responds with whatever SSL cert properties you specify in the request.
15:08TimMc(slurp "https://12345.sni.velox.ch/&quot;)
15:09ndalygtrak: "security is a pain-fractal" is now my quote of the day
15:09TimMcGreat! Your client [Java/1.7.0_51] sent the following TLS server name indication extension in its ClientHello: 12345.sni.velox.ch
15:10FrozenlockSo, java 1.7 indeed supports TLS
15:10TimMcSo slurp is doing the right thing.
15:10Frozenlockclj-http ---> javax.net.ssl.SSLException: hostname in certificate didn't match: <12345.sni.velox.ch> != <alice.sni.velox.ch> OR <alice.sni.velox.ch> OR <carol.sni.velox.ch>
15:11gtrakFrozenlock: most definitely httpclient doesn't use the same code paths.
15:12gtrakFrozenlock: https://issues.apache.org/jira/browse/HTTPCLIENT-1119
15:12gtrakcheck your version
15:12Frozenlockgtrak: https://github.com/dakrone/clj-http/issues/202
15:13gtrakoh, heh.
15:13FrozenlockThanks anyway ;-)
15:14gtrakwell, maybe clj-http is using an older version, is what I meant.
15:14cbpi think http-kit client should work? :-P
15:14gtraknope, I'm wrong.
15:17gtrakpain-fractal can be a black-metal overtone band.
15:57benzapis there a way to do exception handling on (load-string "")? It doens't seem like my try catch statement is catching anything
15:59amalloythere aren't a lot of good reasons to call load-string
16:00jcromartiebenzap: how do you mean? (try (load-string …) (catch Throwable t …)) works fine
16:00jcromartiewhen the code loaded from the string contains errors
16:07shaun_Om as string cursor question: why does this fail? https://gist.github.com/shaunlebron/bca0fd36f26dee6fc6dd
16:10ndalyI'm trying to understand the statement, "Elegance and familiarity are orthogonal."
16:10ndalyis there any chance someone knows in what context Rich said it?
16:10shaun_petehunt do you use Om?
16:10petehuntshaun_: no i don’t really know clojure very well
16:10petehuntand i don’t have time to get good right now
16:10bbloomndaly: you don't really need the context to process that statement
16:10nullptrpetehunt: do you have a hammock?
16:11bbloomndaly: it's simply the easy vs simple distinction rehashed
16:11petehuntnullptr: at work yes, not at home :P
16:11shaun_petehunt: I can imagine, well, thanks for react
16:11bbloomndaly: elegant == simple, familiar == easy
16:11bbloomndaly: assuming you've watched simple made easy
16:11ndalyI haven't watched simple made easy
16:11petehuntshaun_: ;) lots of people over here. we owe the cljs community for a lot as well
16:11ndalybut that does illuminate it some, thank you
16:11bbloom~simplemadeasy
16:11clojurebotTitim gan éirí ort.
16:11bbloom~easy
16:12clojurebotTitim gan éirí ort.
16:12bbloom~simple
16:12clojurebotGabh mo leithscéal?
16:12bbloom*shrug*
16:12bbloomndaly: you can find it. it's worth watching for sure
16:12ndalyI'll look for it. Thanks.
16:14benzapI have this, am I doing something wrong with (try? http://pastebin.com/6aEsBs1j
16:14ndalythink this is it, if anyone else is interested: http://www.infoq.com/presentations/Simple-Made-Easy
16:15oskarkvndaly yes. best video ever
16:15FrozenlockPff, Rich Hickey is good, but he's no Carl Sagan :-p
16:16oskarkv:p
16:16nullptr"...billions and billions of state changes, but only one identity..."
16:16oskarkvhehe
16:16shaun_I told my intern simple != easy when teaching her clojurescript
16:16gtrakhaha
16:16shaun_she interpreted that as meaning clojurescript is very difficult even though it's simple
16:16Frozenlockshaun_: clojurescript is neither simple nor easy ...
16:17arrdemRich also isn't a god sadly :P
16:17shaun_Frozenlock: I thought that was the whole argument, that cljs is simple
16:17arrdemFrozenlock: simple compared to javascript perhaps
16:18Frozenlockok, I could accept this comparison
16:18gtrakFrozenlock: the idealized CLJS is simpler than the current state of things.
16:18bbloomit's certainly simpler than javascript... up to, but excluding, javascript interop
16:18bbloomwhich of course has all the complexity of javascript itself, and then some
16:19shaun_Frozenlock: if you can learn the syntax in 15 minutes, I would say simple: https://github.com/shaunlebron/ClojureScript-Syntax-in-15-minutes
16:19amalloybenzap: map is lazy
16:19arrdemshaun_: syntax is almost universally easy :P
16:19Frozenlockshaun_: I'm pretty sure this doesn't cover dealing with externs
16:19benzapamalloy: so it's evaluated outside ofthe try?
16:19amalloyyour map immediately returns a lazy seq, then you exit the try/catch scope, then you realize the seq at some later date
16:19arrdembenzap: yep
16:19FrozenlockAlso, "b isn't defined" is a terrible error message :-p
16:19benzaphmm, how would I ensure it's not lazy? wrap it in (seq?
16:20arrdembenzap: doall
16:20gtrakif clojure didn't already exist, we might not accept the principles, but the principles and the kinds of programs you can write with those abstractions are what's 'simple'.
16:20amalloywell, (try (doall (map ...))) is the smallest change
16:20amalloyor i guess using mapv instead is smaller
16:21benzapah thank you
16:21benzapmapv did the trick
16:21amalloyi'd recommend using a more explicit side-effecting construct like doseq, since i bet you don't care about the results of load-string at all
16:21shaun_Frozenlock: true, you mean interop? or externs for advanced mode
16:21benzaphmm
16:21benzapi might care about the side effects, it depends
16:22amalloynot the side effects, the return value
16:22Frozenlockshaun_: advanced compilation
16:22amalloytbh i'm a little surprised load-string actually returns anything. i would have guessed it returns nil
16:26arrdemamalloy: well load returns the value of the eval of the tail form AFAIK, so that's not surprising..
16:27amalloyi just would never use load in a context where i want a return value; that's what eval is for. so i imagined that it doesn't give you a return value
16:27Bronsaarrdem: man you have short memory. load returns nil, you even patched t.e.jvm's load to return nil
16:28arrdemBronsa: why do you think I leave type signatures and verbose docs behind? I can't remember this crap.
16:28arrdemnor should I...
16:29Bronsawut https://twitter.com/raymcdermott/status/482222051659632640
16:30arrdemer....
16:31FrozenlockFor speed?
16:33arrdemBronsa: HAH the reason I patched t.e.jvm is that clojure.core as usually is silly. (eval-string "(+ 1 2)") -> 3
16:33bbloomBronsa: odd, i wonder why
16:34arrdems/eval-string/load-string/g
16:35Bronsabbloom: given the core.async impl I really cannot figure out what could go into the compiler
16:36bbloomBronsa: maybe just some of the analysis needed to trigger the state machine rewrite
16:38arrdembbloom: but what for? Clojure has eschewed TCO and other state machine rewrites for a long time..
16:39arrdembbloom: see amalloy's argument for this directed at me in the logs a few days ago, and Rich's old comments on TCO on Scheme lists.
16:40bbloomarrdem: i don't think i have those logs & our various bots seem down...
16:40amalloya few days ago? i don't remember talking about this recently
16:41bbloomarrdem: anyway, it's not just for TCO
16:41bbloomarrdem: core.async uses the state machine rewrite
16:41bbloombut there dozens of other useful reasons to do state machine or other transforms to avoid stack consumption
16:41Bronsabbloom: that seems a bit unlikely given that it just moved to t.a.jvm for that
16:41bbloommaybe he had another one in mind and needs some real compiler analysis data
16:42Bronsabbloom: oh you mean the ssa transformation?
16:42bbloomthe ssa transform depends on some ad-hoc analysis
16:42bbloombut yeah, the ssa transform may be useful for other compiler stuff
16:43bbloommaybe there's a particular hot path in datomic or something that needs some optimization that ssa would simplify, that could justify some local transforms in the compiler
16:43bbloomprobably not worth speculating, tho
16:43arrdembottom line: it's Rich's language and he's gonna do as he sees fit.
16:44Frozenlockinb4 clojure fork
16:44arrdemFrozenlock: inb4 inb4
16:44bbloomi mean, why even bother writing your own language if you're not gonna do as you see fit? :-P
16:45hyPiRionisn't the go block only able to detect visible <! and >! calls?
16:46bbloomhyPiRion: yes, but the compiler wouldn't help much with a dynamic extent transform b/c called functions are already compiled to byte code and need to support hot swapping vars
16:50benzapi'm wodnering, is there any clojure functions that sortof work like a rollback?
16:51benzapI want to try and load-string some scripts, but I want to make sure that I can rollback if anything doesn't evaluate
16:51benzapor does load-string take care of that?
16:51hyPiRionbbloom: Yeah, I wasn't thinking about the compiler analysis part though. Neither Go nor Erlang could do that either.
16:52bbloomhuh? i'm 99% sure that go does inter-function analysis optimizations, at least within a single compilation unit
16:52amalloythere's no such thing, benzap. load-string can perform arbitrary side effects, like delete your hard drive, if that's what the code you're loading says to do. how do you roll that back?
16:52arrdembenzap: clojure's namespace and var binding structures are not first class and are not trivial to manipulate or restore. Consequently what you are asking for is very, very hard.
16:53amalloyarrdem: easier, it's impossible
16:53m_mHi. What i can put at 'x' place for getting true: (= 2400 (reduce (fn [a b] (* a b)) x [1 2 3 4]))
16:53amalloym_m: do you understand what that code is doing?
16:53gtrakamalloy: arrdem: benzap: you just need an 'inverse' function that takes a function, easy-peasy.
16:53Frozenlockbenzap: if you want to deal with atoms you could use https://github.com/Frozenlock/historian, but otherwise I don't see how this could be done.
16:54bbloomBronsa: https://gist.github.com/philandstuff/299cda371c7e74b03f18#q-other-possible-extensions
16:54gtrakit'll run the bytecode backwards
16:54gtrakor forwards on an anti-jvm
16:54benzaphmm yeah, i'm probably going to be careful how I approach this
16:54amalloygtrak: inverse :: IO b -> (a -> b) -> a -- this would be awesome
16:54bbloomBronsa: had a brief chat w/ rich about generators/yield back when i gave a talk in NYC on Fipp
16:54m_mamaloy: I think that I need to add 1000 to vector [1 2 3 4]...but I dont know how. I understend rest of the code.
16:54gtrakit's like a turing machine, you just turn the tape the other way.
16:55bbloomBronsa: basically i used reducers to emulate generators, but he suggested i try core.async's >! to emulate yield
16:55hyPiRionbbloom: Not generally I think?
16:55amalloym_m: observe that reduce is being called with three arguments, a function, x, and a vector. you can't change the vector by changing x, of course - do you know what reduce does when it gets three args?
16:55hyPiRionLet me try to come up with an example
16:56bbloomBronsa: thread here: https://twitter.com/BrandonBloom/status/356873464461791234
16:56m_mamalloy: So my x will be an in line function which will be conj 1000 to vector [1 2 3 4] ?
16:57gtrakthe hard part is making sure that the inverse function halts.
16:57amalloym_m: what does (reduce f x y) do?
16:57bbloomthis is what i was trying to do w/ the CPS transform, where i labeled functions with :cps metadata... never did get it working, but i was operating at the macro level too
16:57bbloomcore.async puts locals in to fields on state machine object
16:57m_mamalloy: Use funtion 'f' on x and y ?
16:58gtrak((inverse +) 3) -> ([1 2] [0 3] [-1 3 1] ...)
16:59gtrak((inverse delete-my-hard-drive)) -> (for [x universe-of-possible-hard-drives] x)
16:59amalloyhere is an example: ##(reduce #(cons %2 %1) () '(a b c d))
16:59lazybot⇒ (d c b a)
16:59arrdem"declare a fn as async"....
16:59amalloythat's quite different from ##(#(cons %2 %1) () '(a b c d)), isn't it?
16:59lazybot⇒ ((a b c d))
17:01m_mamalloy: Aahhh i see...
17:01amalloyso (reduce f x y) is definitely not the same as (f x y), but rather (f (f (f x (first y)) (second y)) (third y)) ... and so on until ys is empty (and pretending here that third is a function that exists)
17:02sveriHi, I just found this thread, trying to store an uri: https://groups.google.com/forum/#!msg/datomic/4bZUz2JjlbI/hKB_s3t5nIoJ Is there still no way to store a uri?
17:03hiredmansveri: you can create your own data reader that creates uri objects
17:04hiredmansveri: it looks like according to that exchange you can store uris just fine
17:05alandipertor ye olde read-eval
17:05hiredmansveri: seems likely you are getting tripped up on loading a file but not evaluating it
17:05hiredmanalandipert: sure
17:05alandipert##{:x #=(list java.net.URI. "http://foo.com&quot;)}
17:06hiredmanalandipert: but that only works if the code is evaulated, in which case, why not just call the constructor?
17:06alandipert+1 tagged literal though
17:06hiredman,(read-string "{:x #=(list java.net.URI. \"http://foo.com\&quot;)}&quot;)
17:06clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
17:06hiredmanfeh
17:06hiredmananyway, you won't get a URL object
17:17aaelonyCan a defrecord defined in namespace A be instantiated in namespace B ? I've seen this (http://cyrax.wordpress.com/2013/07/22/clojure-importrequireuse-defrecord-from-another-namespace/) but I still get an "Unable to resolve classname" error. Perhaps due to bad aliasing... any help appreciated.
17:20bbloomaaelony: use the -> factory function that gets generated
17:20bbloom,(defrecord Point [x y])
17:20clojurebotsandbox.Point
17:20bbloom,(->Point 5 10)
17:20clojurebot#sandbox.Point{:x 5, :y 10}
17:20bbloom,(fn? sandbox/->Point)
17:20clojurebottrue
17:21aaelonybbloom: Thanks. I am using (->Point 5 10) and tried (->sandbox/Point) but not (sandbox/->Point)
17:21bbloomaaelony: the -> is just part of the name
17:22bbloom,`->Point
17:22clojurebotsandbox/->Point
17:22bbloom,'you-can<-have-#strange->names%like*this+
17:22clojurebotyou-can<-have-#strange->names%like*this+
17:23aaelonybbloom: that's perfect. Works like a charm, many thanks...
17:23bbloomit's not syntax, see (doc defrecord)
17:23noonianthere is also (map->Point {:x 5, :y 10})
17:26aaelonyOn a similar note, suppose I have several defrecords defined and I want a way to instantiate an appropriate defrecord based on a keyword. I'm currently doing a cond on the keyword and if it matches then instantiating. But maybe there is a better way...?
17:26bbloomaaelony: any reason you can't just use the function directly?
17:26bbloomie are you serializing these keywords or anything like that?
17:26bbloom->Point is a value
17:26bbloomit's just not round-trip serializable
17:27bbloom,(defrecord Rect [l t r b])
17:27clojurebotsandbox.Rect
17:28bbloom,(let [cmd [:rect 5 10 15 20]] (apply ({:rect ->Rect :point ->Point} (first cmd)) (next cmd)))
17:28clojurebot#sandbox.Rect{:l 5, :t 10, :r 15, :b 20}
17:29bbloomjust def a lookup table
17:29aaelonybbloom: well, here's what I'm trying to do. I have n file types, each in their own format. Each file type has a corresponding defrecord that knows about the fields expected in each file. Each defrecord also has a function that knows how to extract file datestamp information embedded in the filename (which unfortunately is different for each filetype). I know at runtime which file I'm interested in and I want th
17:29aaelonye dispatch to work to get the right parsing of the datestamp info
17:30noonianaaelony: if you know the set of possible file types then a lookup table as bbloom suggests should work fine
17:30noonianyou could also use multimethods for dispatch here
17:31aaelonynoonian: I already rely on the defrecords for other things as well. I'd love to be able to have a lookup table from keyword to defrecord that would instantiate the appropriate defrecord.
17:31bbloomaaelony: a map of format to line parser seems like the no brainer way to go
17:32aaelonybbloom: so defrecords are out?
17:32bbloomdefrecord is totally orthogonal
17:32noonian,(defrecord Markdown [content])
17:32clojurebotsandbox.Markdown
17:32noonian,(defrecord Org [content])
17:32clojurebotsandbox.Org
17:32aaelonybbloom: I kinda just want polymorphism
17:33bbloomaaelony: but you want polymorphism per file type, right?
17:33noonian,(def lookup-table {:md ->Markdown, :org ->Org})
17:33clojurebot#'sandbox/lookup-table
17:33aaelonyyes
17:33aaelonynoonian: that looks exactly like what I need
17:33bbloomaaelony: do you have any pressing need for *open* polymorphism?
17:33aaelonythanks
17:33bbloomaaelony: that's exactly what i showed you, go look at my example about :rect
17:33bbloomheh
17:34bbloombut i suspect that this isn't what you want really
17:34bbloomdo the different file formats have the same info in them?
17:34bbloomor are they totally unrelated?
17:34aaelonybbloom: maybe I didn't understand initially. Let me try noonian's answer
17:34aaelonythe file formats are completely unrelated
17:34bbloomand how many records are in each file type?
17:34bbloomorder of magnitude. 10? 10000?
17:35noonianaaelony: my answer is the same idea as bblooms, i was just trying to illustrate a possible implementation
17:35aaelonyeach file type can have as many records as it needs
17:35aaelonynoonian: yes, that is correct. I just didn't understand what was meant without the example implementation.
17:36aaelonybbloom: less than 30 records
17:36noonianbut do the files represent the same things? with the format being just the representation
17:36bbloomaaelony: don't bother with defrecord
17:36bbloomjust use amap
17:36bbloomit's overkill here
17:36noonianbecause in that case you might just want a single record with a polymorphic function to instantiate them from different formats
17:36aaelonyyes, I like maps a lot. But I wanted to try dispatch with defrecords
17:37bbloombut you want polymorphic construction
17:37bbloomyou said the records from different file types are totally unrelated
17:37aaelonycorrect
17:37bbloomdefrecord is for optimizing field storage (totally unecessary for small row counts) and for type dispatch on the record itself
17:37bbloomyou're dispatching on the file format... once.... before any records are created
17:38noonianto hook into the record dispatch you need to use protocols and have a record instance in the first place. since you want polymorphic construction you need to use a different method to get the instance in the first place
17:38aaelonythere are 2 unrelated concepts, defrecords for the data in each file, and defrecords for data in each file's name
17:38bbloomaaelony: don't bother with defrecords
17:38aaelonyunfortunate
17:38bbloom{:format :type1 :path "some/file"}
17:39bbloomput :type1 and :type2 in a map and look up a parse function from that
17:39bbloomno reason to bring complexity like types in to this
17:39aaelonymaps are nice
17:39aaelonywell this is one area where it would have been nice to have a more OO view
17:40bbloomaaelony: not that i can tell
17:40aaelonysuppose there are functions like parse-x where the implementation will differ depending on the file name format
17:41aaelonythere are many X's too
17:41noonianyou can think of a map as an object whose entries are its fields
17:41noonianthere are more ways than records to get polymorphism in clojure
17:41bbloom(def parsers {:format1 some-parser-fn :format2 some-other-fn})
17:41aaelonyyes yes
17:41aaelonyof course
17:41bbloomif you need open dispatch:
17:41bbloom(defmulti parser :format)
17:41aaelonybbloom: I'd prefer open dispatch
17:42noonianyeah, multi-methods are the way to go then
17:42bbloom(defmethod parser :format1 [file-map] (fn [line] ...)))
17:42aaelonyI have used multi methods in the past, and they were very slow
17:42bbloomyou're going to do ONE multimethod dispatch per file
17:42bbloomi promise you, they are fast enough for that
17:42sverihiredman: I see, I guess, thank you :-)
17:43aaelonyanyways, I appreciate the help. I've got the defrecord solution working the way I want it.
17:44aaelonybbloom: I believe you. Thanks again
17:44noonianyou could also just take an optional argument which is a parse fn or another lookup table that you merge with the first one
17:45aaelonycool
17:55ivanwhy does putting code into :repl-options {:init ... without a (do wrapper magically break things with "Wrong number of args (2) passed to [whatever]"?
17:56bbloomivan: i'm not an expert on this, but i think the init code is merged in to a bigger do in some way when you have plugins or layered protocols
17:56bbloomseems like the rule is just always use do
17:56ivanthat's depressing
17:56ivanthanks
17:56bbloomagreed
17:57bbloomseems like it should be straightforward to put it in to a nested do & not have this problem
17:57bbloom*shrug*
17:57bbloomlayered procotols => i meant profiles
18:00ivanmy new security-hole-free REPL setup is { cat init.clj; cat; } | java -Xmx192M -Dfile.encoding=UTF-8 -cp "$(lein classpath)" reply.ReplyMain
18:00ivanI need that second cat to prevent it from quitting immediately, but unfortunately I need to EOF/ctrl-c a second time to exit or something
18:01amalloyivan: i don't understand what problem you're talking about. :repl-options {:init (println 'hi)} works fine for me
18:01ivanamalloy: that's probably just println. try a load-file or an eval.
18:01amalloyif you mean :repl-options {:init ((println 'hi) (println 'bye))}, then of course that doesn't work
18:02amalloy:repl-options {:init (eval '(println 'hi))} works fine too, of course. what is a specific thing that doesn't work for you?
18:02ivan:init (load-file "init.clj")
18:03bbloomamalloy: iirc i ran in to an issue where a plugin adds repl-options & lein tries to compose them
18:03bbloomdunno if something has changed
18:04amalloythat load-file works fine too. i'm with bbloom: some middleware is putting stupid stuff in your project
18:04ivanamalloy: apparently it works without (do ...) if you don't have some lein plugins in your ~/.lein/profiles.clj
18:04amalloytry lein pprint
18:04amalloyi have plugins in my profiles. you just have one that breaks things
18:04amalloyprobably in the manner bbloom describes
18:05ivan:plugins [[lein-ancient "0.5.4"]] was responsible
18:05amalloy(ie, by concatting together two lists into a list)
18:05bbloomamalloy: i think it's lein that does it
18:05bbloomat least that's what i recall
18:05bbloomit assumes your :init value is a list beginning with do
18:05bbloomcalls `next on it, then concats them in to another do
18:06ivansorry, wrong culprit, lein-ancient is fine
18:06ivan:plugins [[mvxcvi/whidbey "0.2.2"]]
18:07amalloybbloom: i'd guess that it doesn't assume that, but rather just merges lists by concatting them
18:07amalloyas a generic merge on lists, not specific to repl-init
18:08cespareI'm having trouble with lein checkouts, where occasionally running 'lein jar' puts the .class files for a checkout dependency (say, mylib) into target/classes/. Once those are in there, they shadow any changes to the mylib source, so my project is broken until I run lein clean.
18:08cespareThis is with :aot :all in the profile I'm using for lein jar btw.
18:09cesparealso I've spent a long time trying to get a reliable repro without luck. I've seen it happen on a fresh pair of lein projects once, but now I can't make it happen again.
18:10cespare(It's an issue for our team because this breaks our projects for us once or twice a day on average)
18:10amalloyAOT compilation is a creeping misery, spreading sadness to all it touches
18:12amalloyright, i think https://github.com/technomancy/leiningen/blob/f73a9998ff2992ab7574448e5884e08417c21526/leiningen-core/src/leiningen/core/project.clj#L512-L518 is all that's responsible for combining your repl-init values
18:13amalloyif you were to lein-pprint, you'd see that your repl-init is set to something bad like ((load this) (print that))
18:13bbloomamalloy: is metadata "inherited"?
18:13bbloomseems like the base profile could specify a sensible merge policy for repl-init
18:13amalloybbloom: i dunno, he does all sorts of weird gyrations with metadata
18:13amalloyi don't try to keep up
18:14bbloomnor do i, i do the absolute minimum leinfu to make the couple plugins i use work... frankly, i totally understand rich's preference for CLASSPATH=whatever java -jar
18:14amalloyit does look like the base profile could have :repl-init ^{:reduce (fn [a b] `(do ~a ~b))} ()
18:15amalloybut i dunno
18:15stephenjudkinsi have asked this question before, but: where does the documentation for `->` live?
18:16arrdem#(clojure.repl/doc ->)
18:16hiredman,(doc ->)
18:16clojurebot"([x & forms]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
18:17stephenjudkinsthanks
18:18cespareamalloy: okay, I got a repro with :aot
18:18cespareso it's not actually that.
18:19cespare*without :aot
18:19cbplol arrdem
18:19amalloycespare: if you can reproduce it without a :main or :aot i'll be impressed
18:21amalloy(because :main implies AOTing the main namespace, which typically entails AOTing everything under the sun)
18:25cespareamalloy: yeah, you're right about :main.
18:26cespareAny ideas how to fix this? It seems like a bug
18:30amalloyi stay away from AOT as much as i can. what solution you choose will depend on why you have a :main and what tradeoffs you're willing to make
18:31cespareamalloy: all our projects have mains
18:31cesparethey are servers
18:31cesparethe problem i'm seeing is that it (apparently non-determistically) breaks checkouts
18:32cespare*deterministically
18:33cespareat this point, the main other alternative we're considering is getting rid of checkouts and going back to our old solution of symlinking our shared_lib code into all our projects.
18:33cesparewhich is pretty nasty, but at least doesn't break unexpectedly.
18:33amalloyyou're being too generous - it nondeterministically breaks all kinds of things, checkouts being just one specific case. but i also stay away from checkouts, so i don't have any particularly good advice for you
18:34cespareso to summarize, you're saying that lein is broken?
18:34amalloys/lein/clojure, really. aot just blows
18:34amalloycespare: you can put your shared_lib in a maven repo, and release it when there's a new feature, updating dependencies as needed
18:34amalloyit's a hassle, but it's reproducible and works
18:34cesparewe change it very rapidly along with our other code
18:34cesparethat overhead wouldn't be acceptable.
18:35hiredmanyou could just not aot anything
18:35cesparebut I need a main, yes?
18:35cj3kimHi. I'm new to clojure. I downloaded a library called gaussian_elimination and I have placed it into my project directory that has a src/core.clj and project.clj file. Gaussian_elimination has the same structure. How do I require gaussian_elimination code in my project src/core.clj code?
18:35cespareour projects are mainly ring servers
18:36amalloyyou can have a main which doesn't load anything else at compile time, but compiles it at app startup with a dynamic require
18:36hiredmancespare: there are tons and tons of possibilities
18:36amalloyit'll slow down startup significantly, but that's the price you pay
18:36possibilitiesbut there's only one @possibilities
18:36amalloy~lein
18:36clojurebotlein is http://github.com/technomancy/leiningen
18:37hiredmancespare: clojure comes with a clojure.main class that has a handy -m option
18:37hiredmancespare: you can write some java stubs
18:39hiredmancespare: you can create war files that run in some container instead of jars that run their own http server (althought the easiest way to do that stupidly aot compiles your code, but fixing that takes an afternoon)
18:41hiredmanspeaking of which
18:43hiredmanamalloy: I think we talked about lein-ring aot breaking stuff at some point, I made some changes to a fork and now it doesn't aot https://github.com/hiredman/lein-ring/commit/aa2f9ad12502e3502af03087f6bb2e72e850a917
18:43cesparewhat if I put ^:skip-aot on my main
18:44hiredmancespare: why have a :main then?
18:44hiredmancespare: just leave it out of your project.clj
18:44hiredmanuse java -cp … clojure.main -m foo.bar to launch
18:45cespareok, i'll give that a shot.
18:45amalloyhiredman: you must have a keyboard macro for "TODO: delete"
18:45hiredmanI should
18:46hiredmanit needs lots of clean up for a "release" but I did a lein install and have been using it for all the clojurebot bits that use lein ring
18:48cesparehiredman: where do I get the clojure jar to put on my cp if I'm using lein?
18:49amalloyjava -cp `lein classpath` # lol
18:49cespareah
18:49hiredmancespare: lein uberjar jars up all of a projects deps in to single jar
18:49amalloywell, the # lol is there because this is not really a great idea
18:49hiredmanthat includes clojure
18:49amalloyreally you want the uberjar
18:50cespareseparate issue, but yes we normally use uberjar.
18:51hiredmanthe uberjar includes clojure in it, including the clojure.main class
18:52cesparecool, got that working.
18:52cespareI think we'll be able to purge most of the aot.
18:52cesparethanks guys
18:59braI'm working on tuning a clj application via visualvm and the sampler is telling me that clojure.lang.Keyword.hasheq is my most CPU-hungry hotspot.
19:00braThis is a bit surprising to me, since IIUC keywords are interned and their hashes are computed at construction time.
19:00braIs there something I'm missing here?
19:00danneubeen stuck with node for a while on client projects. found out about this a couple days ago https://github.com/koajs/koa -- finally made node bearable
19:00hiredmanbra: are you processing json?
19:00brahiredman: Nope.
19:00hiredmanah well
19:00turbofailare you doing anything else that might convert strings to keywords?
19:01hiredmanbra: some other kind of deserialization?
19:01braI don't believe I'm converting strings to keywords anywhere
19:02braThe primary hot loop is taking strings and a vec of [:keyword parser-fun] pairs and generating a map of {:keyword parsed-string-bit}
19:02amalloyhasheq doesn't suggest to me that he's creating keywords, but that he's comparing them
19:02amalloyor using them as keys in a large map, i guess is more like it
19:02braYep.
19:03braEach map has ~36 keys, and I'm generating a few thousand per second in test.
19:03hiredmanah well, that makes sense
19:04hiredmanthe call to hash eq is a required part of sticking keys in the map
19:04hiredmanbra: what version of clojure?
19:04brahiredman: 1.5
19:04bra1.5.0
19:05amalloyif the main thrust of your work is building large hashmaps, then no matter how fast hashing is, it will take a large part of your computational time
19:05hiredman1.6 has some hashing changes, but I think those mainly effect the performance of hashing of collections
19:06braThanks all.
19:06amalloyyou might be able to reduce the amount of rebucketing that goes on by creating the maps all in one go rather than incrementally? i'm not sure
19:06hiredman1.6 may have a better distribution of hashcodes, but I am not sure, and I forget if that would even matter for keywords, they could just use the identity hashcode I think
19:07amalloylike, (apply hash-map (apply concat vec-of-kvs))
19:07braWould replacing my map with a record be a fruitful approach?
19:07amalloynot with 36 keys
19:07braAh, I'll test the all-at-once approach.
19:07brakk
19:08braWhy does the key count affect the performance?
19:08amalloyrecords perform best for small numbers of keys, because they have no structural sharing
19:08Bronsahiredman: IIRC in 1.6 keywords use the murmur3 hash of the internal strings rather than their .hashCode
19:08hiredmanobviously you should partition the keys up and do the merges in parallel using fold
19:09gfredericksamalloy: neither do array-maps
19:09amalloyuh huh...?
19:09braamalloy: FWIW these are never mutated after creation. It's all field accesses.
19:10gfredericksamalloy: I thought you were advocating for records over regular maps?
19:10gfredericksoh wait no
19:10hiredmanbra: if it is a fixed set of keys, use a vector assign each key to a spot in the vector
19:10gfredericksyou just meant records with a whole bunch of keys are bad?
19:10amalloymhm
19:11gfredericksenglish!
19:11hiredman(you could even use a transient or array while building up the vector if you need too)
19:12hiredmanif you aren't generating keywords it must be a fixed set I guess
19:12amalloyor just use an array as the canonical store. light speed!
19:12hiredman*zoom*
19:13amalloythen of course you'll have to write (case k :foo (aget arr 0) :bar (aget arr 1)) and so on, and you'll probably pay for hasheq in the case dispatch
19:13bra:D
19:13hiredmanamalloy: write a macro that translates the keywords to numbers for you
19:13braRight, I was a bit concerned about the API there.
19:13braMacro might be useful. Hm.
19:14amalloyhiredman: ztellman/vertigo. go big or go home
19:14hiredmanamalloy: sure
19:30cj3kim_Hi. I've been trying to require code in lein, but I've been having trouble. Here's a gist with the relevant description and files https://gist.github.com/anonymous/39f3a8148eeba430db14
19:31nooniancj3kim_: there are a few problems, firstly you should only have one require form in a ns form, and you should use the keyword :require instead of the function require
19:31hiredman~namespaces
19:31clojurebotnamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
19:32nooniani would also guess that the namespace you are trying to require is gaussian.elimination and then you want to refer to the functions gaussian and vector
19:32noonianoh, nvm i didn't see the other files
19:33amalloynoonian: you can have multiple requires in a namespace
19:33noonianyeah, try merging the multiple use and require statements i.e. (:use [gausian.elimination.matrix] [gausian.elimination.vector] ...)
19:33amalloyit's not stylistically popular, but it's equivalent
19:33noonianhmm, i didn't know, but surely it's not idiomatic
19:33cj3kim_hmmr
19:34amalloythe problem is not in his ns statements, but probably in where he's put the files
19:35noonianyeah, it cant find gaussian, that would also happen if it is failing to compile
19:36cj3kim_noonian: how do I know if it's failing to compile? And, what can I do to compile it?
19:37noonianif you have a repl open, i would try evaluating (require 'gaussian.elimination.gausian :reload) and see if you get an error or not
19:38cj3kim_I ran it and it returned a "FileNotFoundException"
19:38cj3kim_noonian:
19:38amalloywhy do you have a file named core.js which contains clojure code? and where is promethix.core?
19:38noonianwhat is the directory structure and file names of your source tree?
19:39cj3kim_A moment please. Need to type stuff out in a gist
19:40nooniangaussian.elimination.gaussian should be at path src/gaussian/elimination/gaussian.clj with the leiningen default src paths
19:40cj3kim_noonian: I am using lighttable, an editor, as well. C
19:40noonianalso, which file is the filenotfoundexception for? if it's a different source file of yours then your should try requiring that one
19:41cj3kim_noonian: Copy/pasting all relevant info to a gist. :)
19:43cj3kim_noonian: https://gist.github.com/cj3kim/abac1f85ce1b4cb50af8
19:44hiredmanhttps://github.com/LightTable/LightTable/issues/1520 learning clojure using lighttable seems like it would be hell
19:45cj3kim_hiredman: what would you recommend in its stead?
19:45amalloycj3kim_: whatever text editor you're already comfortable with
19:45amalloyand lein repl
19:46hiredmanpreferably something that has some kind of mode where it will help you match up brackets, but that is not a strict requirement
19:47nullptryeah, i think show-paren-mode is sufficient when you're starting -- paredit would be a bit much for a newbie
19:50amalloycj3kim_: everything there seems okay (except you misspelled gaussian in your repl example)
19:50amalloyyou'd probably have had an easier time just pushing the whole git repo for someone else to repro with
19:51nooniancj3kim_: (require 'gaussian.elimination.gausian :reload) you mispelled gaussian gausian
19:51nooniani was using light table for a while but using lein repl for the repl
19:54amalloynoonian: that's true, but it's also breaking in his ns clause, where it *is* spelled correctly, so i'd guess his dependencies are not present somehow
19:55amalloylike maybe you haven't restarted your repl since adding the dependency? but i have no idea what light table does automatically for you
19:56DomKMAnyone know why protocols are typically prefixed with `I`? Is this because of their similarity to Java interfaces?
19:57amalloythat is why, DomKM. but it's not a universal convention; you're free to ignore it
19:57amalloy(just like prefixing java interfaces with I isn't universal)
19:58DomKMamalloy: cool, thanks.
19:58noonianamalloy: i agree, i asked him to require it by hand to see if one of that files deps was missing
20:07cj3kim_noonian: amalloy: Thanks for the help
20:15ttasteriscohm, prefixing java interfaces with I was never the norm. that's from .net
20:15ttasteriscojava interfaces were always -able
20:16systemfaultList…able? :P
20:16ttasteriscoRunnable
20:16ttasteriscoCallable
20:16ttasteriscoIterable
20:16ttasteriscoetc
20:17amalloyttasterisco: it leaked in from .net
20:17amalloyit's not used in the jdk itself, but lots of people who write java do it
20:17ttasteriscodamn migrants
20:17ttasteriscoburn them
20:17bbloomBronsa: now i'm all self-conscious screwing up and force pushing on public repos :-P
20:17amalloyhow dare they force their lambdas on us
20:18bbloomi usually abuse the crap out of my own fork, but now i have observers....
20:18amalloybbloom: your nick is confusing to type. double-single-double? i propose you change your last name to Blloom
20:19bbloomamalloy: does bb<tab> not handle it?
20:19amalloywell, i actually do bbl<tab>
20:19amalloybut this time i was doing a google search to see if i could guess what repo you were talking about
20:19bbloomso does some random guy in #ruby, who has never actually talked to me, but mentions me with some regularity
20:20cj3kimamalloy: noonian: pushed to git for help. https://github.com/cj3kim/promethix
20:20Bronsabbloom: oh just ignore me. if it makes you feel better I screw up a lot on t.a/t.a.j and I cannot even force push because of autodoc
20:20cj3kimnoonian: my general feeling is gaussian_elimination isn't compiling
20:21bbloomBronsa: not just you, but you made me aware of the audience
20:21amalloycj3kim: version 1.0.0 of gaussian_elimination chooses to call its namespaces gaussian_elimination.gaussian
20:21amalloyrather than what's on github, which is gaussian.elimination.gaussian
20:21cj3kimamalloy: how do you know this?
20:22amalloyi opened up the jar and read it
20:22cj3kimand how can i check in the future?
20:22amalloyare you sure you want to use this library? it looks pretty slapdash
20:22Bronsabbloom: then I'll pat my back for being successful in screwing you up. pushing will never feel the same
20:22bbloomBronsa: i'm super careful when specifying what-to-push-where, but when i work on my own tracked branch, i view the server as a backup & push constantly
20:23cj3kimah, i see. thank you
20:24amalloycj3kim: it looks like https://github.com/skatenerd/gaussian_elimination/tree/358e9e9cb3c8c6f40b4684550c854874f3860173 is the code you are actually using
20:24cj3kimamalloy: oh my god >_>
20:24amalloyhm?
20:25cj3kimmy friend had downloaded an older version of that library which used all dots instead of the underscore
20:25cj3kimi just wasted three hours!
20:25amalloyi don't think your friend's download is relevant? that jar is being fetched from maven
20:26amalloyand dots are actually the "latest" code (ie, two years old), which he hasn't ever released to maven (but it's the latest git)
20:26cj3kimwe used this code <-https://github.com/skatenerd/gaussian_elimination/blob/master/src/gaussian/elimination/gaussian.clj
20:27cj3kimthanks for your ehlp
20:27amalloyright. that code is newest, not older
20:27amalloyand he just never released it
20:28amalloyanyway, have fun. it looks like the author probably knows his math but doesn't know his clojure
20:28bbloomi think "meth" is my new favorite symbol
20:29amalloybbloom: if you've been doing meth i need to tell you it's not just a symbol, it is an addictive and dangerous drug
20:29amalloysee, eg, the AMC documentary Breaking Bad
20:31bbloomamalloy: saw that. stellar investigative journalism. i need to figure out how to get out of the meth business and in to that empire business thing
20:34cespareIf i no longer have a :main, is there another way to specify the starting point for my lein repl?
20:34cesparestarting namespace I mean
20:34hiredmanthere is no such thing as a starting namespace
20:35noonianif you have a user namespace on the classpath it will use that though
20:35hiredmannoonian: you keep answering a question that is slightly different then the asked one
20:36noonianin this case i don't know the answer
20:36cesparehiredman: seems to me you very likely understand what I'm asking
20:36hiredmancespare: sure, you want lein to require and in-ins in to a given namespaces when you run lein repl
20:37cesparesounds about right, if that's what it does when you do :main myproj.core
20:37cespareis there another way to ask lein repl to do that?
20:37ttasteriscocespare: in there repl, there's no "main". if you mean when doing `lein run`, then you can use the -m
20:37hiredmancespare: I would suggest either you'll be in an editor, and evaluating the file at hand in the editor will in-ns the repl's state to the same namespace
20:38ttasterisco*the
20:38cesparehiredman: Yep, that's true 95% of the time. The other 5% it's convenient for the repl to automatically load the main namespace.
20:38hiredmancespare: why?
20:38cespareit's not a big deal, just wanted to know if there's a workaround, now that I'm removing :main from all my projects.
20:39hiredmancespare: how likely is it that you are going to be using stuff in the main namespace?
20:39cesparequite likely, if i'm just playing around a bit.
20:39hiredmancespare: sure you could use something like the repl-init options
20:39cesparei've been writing clojure for the past 9 months or so, and I know from experience that it's something I occasionally want to do.
20:40cesparehiredman: there we go.
20:40cespareI see :repl-options { :init-ns foo.bar }
20:40hiredmanin my experience using lein run means I am doing performance testing of some functionality of one particular namespace on an ec2 node
20:41hiredmanso I would have in-ns to the particular namespace anyway to start fiddling with it
20:41synkteWhat's the best way to seed a database in clojure?
20:41amalloycespare: try `lein help sample` next time you are looking for some lein feature
20:42amalloy(this is the same as leiningen's sample.project.clj on github, so you can look there instead if you prefer)
20:42cesparehiredman: sure, understood. It's just that starting out in a commonly used namespace of my project is better than not
20:43hiredmancespare: I think lein doing that kind of thing encourages people to form incorrect ideas about namespaces as something that contains in some way the execution of code
20:43TimMccespare: If you still need a main entrance point but don't want AOT, I wrote lein-otf a while back.
20:44tuft_cespare: the trick i'm using is creating a user.clj in the project that's just a bunch of requires, if we're talking about the same thing
20:44cespareTimMc: hey, neat!
20:46TimMccespare: You can do the same trick yourself with less infrastructure (just have a tiny AOT'd main ns that dynamically requires your real entrance point and calls it) but lein-otf is a drop-in.
20:47TimMcI actually don't know if I'd use lein-otf myself these days; it adds a potential complexity cost to the project and an explicit approach + plenty of comments might be better.
20:48cespareI think I'm just gonna go with the clojure.main -m ... approach for now.
20:49cespareIs there some PSA about AOT causing all kinds of problems that I've somehow missed since starting to use clojure?
20:50nooniangetting burned by AOT is a clojure right of passage
20:50TimMcNo kidding.
20:52hiredmanhttps://groups.google.com/forum/#!topic/clojure/Bs70_PUj-TY is maybe the first anti aot screed, a bit dated by now I am sure
20:53hiredmanhttps://groups.google.com/d/msg/clojure/Bs70_PUj-TY/azR1gNleT_oJ good for a chuckle
20:58cgagi'm using clojurescript and trying to do the equivalent of rangy.createRange() by doing (.createRange js/rangy), but running into undefined is not a function am i doing something obviously wrong?
20:59TimMchiredman: The C-in-C bit?
21:00bbloomBronsa: have you found a need to differentiate let and loop bindings at all?
21:01bbloomBronsa: for eclj i differentiate between locals via let, jvm classnames, and of course vars... i haven't needed to differentiate let & loop at all, but i definitely need to figure something out for object fields
21:02bbloomBronsa: for that, i'm torn between (symbol-macrolet [x (.-x this#) ... and true fields support
21:02ddellacostacgag: is rangy getting pulled in properly?
21:02bbloomBronsa: but seems like loop is just a shorthand for fn really, if you have tail calls like i do
21:03Bronsabbloom: in ta every local has a :local field that indicates where it comes from
21:03Bronsabbloom: uhm, there are some differences between loop/fn locals wrt type hints & primitive support
21:03bbloomBronsa: hm, interesting
21:04Bronsabbloom: not sure if that is a problem at all but fn args can only be long/double primitives while loop/let locals can be whatever primitive type you want
21:04bbloomi was looking at :local, but noticed loop & let seemed to mostly follow the same code paths
21:05Bronsabbloom: yeah I think in tej we never need to differenciate between :let/:loop locals
21:05bbloomBronsa: that's good to know, thanks. doesn't affect my environments, but will affect me when i get to the compiler
21:05Bronsabut I'm not 100% sure, let me check
21:05bbloom(hints, i mean)
21:06cgagddellacosta, now that I'm trying to use it with just pure js I'm not as confident as I was. The code fails in my test.js file fails even though it runs in the console, don't think it's clojurescript related anymore.
21:06ddellacostacgag: ah, okay. That happens too. But it sounds to me like rangy wasn't getting pulled in properly, perhaps.
21:10bbloomBronsa: luckily, i don't have to abide by the rules for eclj, so i'm going to implement symbol-macrolet & use that for fields :-)
21:10Bronsabbloom: yeah I checked, I never need to differenciate between :loop and :let locals
21:10bbloomBronsa: cool
21:11bbloomBronsa: any crazy thing about field symbols i should know? or is (intelligently) replacing foo with (.-foo this#) seem sane?
21:11Bronsabbloom: I was just thinking about that.
21:11Bronsaoh yeah
21:11Bronsabbloom: you cannot (set! (.-foo this#) bar) I believe
21:12BronsaI might be wrong on that one though
21:13Bronsabbloom: oh you indeed cannot but that's a compiler bug that I submitted a patch for, lol
21:13bbloomheh
21:13Bronsanothing else comes to mind then
21:14bbloom,(deftype A [x])
21:14clojurebotsandbox.A
21:14bbloom,(.x (A. 1))
21:14clojurebot1
21:14bbloom,(deftype A [^:unsynchronized-mutable x])
21:14clojurebotsandbox.A
21:14bbloom,(.x (A. 1))
21:14clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: x for class sandbox.A>
21:14bbloom^^ interesting....
21:14Bronsabbloom: yeah mutable fields are private
21:14bbloommakes sense, but i didn't think rich believed in encapsulation :-P
21:15Bronsabbloom: mh if you use symbol-macrolet I belive shadowing will be problematic? also using the symbol in macros
21:15bbloomBronsa: that would be an issue if symbol-macrolet was a macro, but i'm going to implement it in the interpreter
21:16Bronsabbloom: probably a better approach would be replacing the field at macroexpansion time
21:16bbloomBronsa: there really isn't a "macro expansion time" in eclj
21:16bbloomit's interleaved with evaluation
21:16bbloomthe assumption is that macros are pure & terminate
21:17BronsaI wish I could make the same assumption for clojure macros
21:17bbloomagain, i have the benefit of not having to follow the rules :-)
21:17BronsaI have to do crazy things like rebuilding the entire namespace map every macroexpansion because somebody could intern vars at macroexpansion time
21:17Bronsaand midje actually does it.
21:18bbloomyou're trying to match jvm/clj proper, i'm aiming for rough source-level compatability for idiomatic code
21:18bbloomlol fucking midje
21:18Bronsathat's exactly what I thought
21:19bbloominterning happens via an effect in my system, so i can intercept it
21:19bbloomi implement the dynamic nature of namespaces, but via continuations
21:19bbloomanother luxury you don't have :-)
21:19bbloombut then again, your stuff is actually useful
21:19bbloomso there's that :-P
21:20Bronsabbloom: me and ambrose were wishing clj namespaces were IRefs a while ago
21:20bbloomand setting fields with (.-whatever works fine for me. so macrolet it is!
21:20bbloomBronsa: for watches?
21:20Bronsayep
21:20bbloomwould be nice
22:03akurilinQuick prismatic schema question: is there a way of enforcing values of map keys being not nil outside of using predicates? As in, say I specify {:foo [{:bar "baz}]} as schema, {:foo nil} will validate correctly for some reason
22:17bbloomBronsa: amusingly, see the "Notes:" here: http://www.lispworks.com/documentation/lw61/CLHS/Body/s_symbol.htm
22:18bbloom"The special form symbol-macrolet is the basic mechanism that is used to implement with-slots."
22:18bbloomwith-slots is basically what i want for fields
22:18bbloomeverything old is new again :-P
22:18trptcolinthe HyperSpec - that’s pretty intense
22:19bbloomif you're going to implement something, you gotta do your homework :-)
22:20trptcolin:) that’s why i went straight to ztellman’s github when i decided to write a little code-walking macro for this book
22:21trptcolin not that this little faux-library is a comparable effort to what you’re undertaking ;)
22:25Jaoodtrptcolin: are you writing a book about clojure?
22:25trptcolinJaood: yeah, macros specifically
22:26Jaoodoh nice
23:33mlakewoodHi all. I just stumbled across component https://github.com/stuartsierra/component
23:33mlakewoodit feels like this might have some overlap with Protocols etc. could somebody explain the differences?
23:44trptcolinmlakewood: component is built on top of a protocol: https://github.com/stuartsierra/component/blob/030fe57eeb2f1ac0d0675d420db9614b78ecc857/src/com/stuartsierra/component.clj#L4-L12
23:44mlakewoodOh ok. thats good to know. Thanks!
23:47FrozenlockOh Gooood. Less than one week away from the Canada's Anti-Spam Legislation.
23:48FrozenlockWhy can't these lawmakers STOP making new laws? They just screw up anyway.
23:57boltRis there a way to throw an exception using fnil?
23:57boltR(fnil inc (throw (Exception. "foo")))
23:58boltRor can I only use an if-else for throwing exceptions
23:59dbaschboltR: you can throw exceptions anywhere, but I fail to grasp why you would want to use fnil for that