#clojure logs

2016-02-25

00:03tolstoyI imagine the botnet folks have something special.
01:44adamzHi. Is there anyway to improve the performance of instanciating Java classes from clojure? Im calling `(java.util.Data. etime)` > 30k/s. running VisualVM against the clojure VM process shows that `java.lang.Class.forName()` is the most expensive method. To me, that sounds like Clojure is looking up the class on every invocation.
01:45adamzsorry, `(java.util.Date etime)`
01:46jeayeinstantiate
01:52hiredmanadamz: there are things you could look at to speed that up, but it would be way better to just not allocate all those new data objects, are you sure you can't get by with a long?
02:14adamzhiredman: unfortunatly, im passing them onto a libaray (the DataStax Cassandra driver) which /expects/ Date objects — i’ve looked at ways to avoid passing Date and insted just long, but it’s not possible without modifying the driver code :(
02:37Vishal_any1 active?
02:40Vishal_any1 familiar with atoms and their usage?
02:41mangeVishal_: anything in particular?
02:50paul_muadib666can someone recommend a clojure web app tutorial that covers datomic and compojure. I found one but its out of date and it uses this compojure-api library that I'm having issues with..
03:10Vishal_Link: https://gist.github.com/longdongjohn/5bdbada220b2e4a2bb06 ; I keep getting a Null pointer Exception on the atom variable temp3, which i have initialised... Any suggestions?
03:14hiredmanVishal_: this code is poorly formatted, and is full of mistakes
03:14hiredmandef always creates a global, don't use it inside a function
03:15hiredmanevery time you wrap something in () parens that means a function call
03:15TEttingerVishal_: (prn temp3) returns nil
03:17TEttingerand yeah, hiredman's right about def especially, it looks like you're using (def m2_flag 0) where you should use let
03:20TEttingerfor someone whose nick on github is longdongjohn he doesn't seem to take criticism well...
03:25somenamenope..... i went for lunch... and the channel pinged out
03:25somenamethanks for the input anyways
03:27Vishal_Thanks for the input btw
03:28TEttingerI was wondering what happened! there's a few quick things to try
03:29TEttingerdef should be changed to let, like this
03:29Vishal_i can't use let because I'm trying use that value in another function
03:29TEttingerah, that's bad. that sounds like m1_flag and m2_flag should be atoms if they're changing
03:29KneivaIs there better way to transform [[:a [1 2]] [:b [3 4]] [:c [5 6]]] into {:keys [:a :b :c], :values (1 2 3 4 5 6)} than https://www.refheap.com/115180 ?
03:29TEttingercurrently they're var, which is kinda mutable
03:30TEttinger(gt) on its own seems like it may be a bug
03:31Vishal_that's what i tried ...but i get a null pointer exception at the location of temp3 in the code
03:32Vishal_https://gist.github.com/longdongjohn/2b274f1b6d786ce07373
03:32Vishal_thats the complete fiel
03:33TEttinger,(let [coll [[:a [1 2]] [:b [3 4]] [:c [5 6]]] ks (map first coll) vs (mapcat second coll)] {:keys ks :values vs})
03:33clojurebot{:keys (:a :b :c), :values (1 2 3 4 5 ...)}
03:33TEttinger,(let [coll [[:a [1 2]] [:b [3 4]] [:c [5 6]]] ks (mapv first coll) vs (mapcat second coll)] {:keys ks :values vs}) ; to be exact
03:33clojurebot{:keys [:a :b :c], :values (1 2 3 4 5 ...)}
03:35KneivaAh, right. That's more readable, I think. Thanks.
03:35TEttingerI am sure someone more experienced than I could clean it up even more!
03:36TEttingercpu_threshold is undefined, thus nil, Vishal_
03:37TEttingerI think the error may be in an odd place and getting bad info
03:37Vishal_its part of the includes "globals.clj"
03:37TEttingerah I was wondering what that was
03:39Vishal_ill try changing the m1 and m2 flags as atoms and run it... will let you know of the changes
03:40TEttingerI wonder if (prn temp3) is the issue, should that be (prn @temp3)
03:41TEttinger,(def temp3 (atom 0))
03:41clojurebot#'sandbox/temp3
03:41TEttinger,(prn temp3)
03:41clojurebot#object[clojure.lang.Atom 0xcaf670e {:status :ready, :val 0}]\n
03:42TEttingerVishal_: I think where you have (prn temp3) should actually be (fn [& children] (prn @temp3))
03:43TEttingersince in all other cases you have a fn and onlythat case evaluates to nil
03:43Vishal_ will try it now
03:51Vishal_TEttinger: https://gist.github.com/longdongjohn/2b274f1b6d786ce07373 this is the updated code.. Im getting an exception long cannot be cast to IFn on line 42
03:54Vishal_somename: asd
03:55TEttingerlet's see...
03:57TEttinger,(doc reset!) ; let me refresh my memory
03:57clojurebot"([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."
03:58Vishal_ok will check it out
04:00TEttingerVishal_: the long to IFn thing usually means that a number is at the start of a parenthesized call, like (1) will throw that
04:00TEttinger,(1)
04:00clojurebot#error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval47 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval47 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval47 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6927]...
04:01TEttingerif it's the other way around, IFn cannot be cast to long, that's usually because you have a fn by name in the middle of a math thing like (+ 1 inc)
04:01TEttinger,(+ 1 inc)
04:01clojurebot#error {\n :cause "clojure.core$inc cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.core$inc cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.lang.Numbers add "Numbers.java" 3640]\n [sandbox$eval71 invokeStatic "NO_SOURCE_FILE" 0]...
04:01TEttingerhm different error, same sort of thing
04:03TEttingerohhhhh
04:03TEttinger,(def temp3 (atom 0))
04:03clojurebot#'sandbox/temp3
04:03TEttinger,(reset! temp3 20)
04:03clojurebot20
04:03TEttingerthose reset calls are returning Long numbers
04:03TEttingeryou may need to pass a fn to where
04:05TEttingerI don't know what "where" does or from which lib it's from
04:06Vishal_its part of riemann
04:06Vishal_and ill try passing a function to where
04:06Vishal_getting into a meeting ...will be afk for 15 mins
04:08solatisok, i'm looking for someone with an opinion on data/type validation in clojure and when to do it
04:08solatisi am used to languages with strong types (e.g. Haskell and C++) that validate as early and as often as possble
04:08solatishowever, I don't think that's an optimal approach for Clojure / LISP
04:09solatisi am thinking that the best fit for Clojure would be to validate as late as possible, but let the error "bubble back up", to provide accurate feedback on what/where it went wrong
04:09solatisis that a reasonable approach?
04:10solatiscase in point: using some REST api, do i validate the data before I send it, or do I just let remote server generate an error in case the function was called with incorrect data
04:11TEttingern0lan: are you the typed clojure ninja-in-chief :)
04:11MJB47solatis: i like to do both
04:11MJB47client side validation is much faster and gives the user a better experience
04:11MJB47but cant be trusted
04:12n0lanno I was bored looking for "popular" IRC channels on google, lol
04:14solatisMJB47: right, but in this case it's for internal code
04:14solatisand speed is not really a concern
04:15solatisand i don't like to do things twice, that means that when there's a change, i need to change my validation code twice :)
04:15MJB47maybe not with reader conditionals
04:17solatislet me look that up
04:17solatisthat looks scary
04:41adamzHi. Is there anyway to improve the performance of instanciating Java classes from clojure? Im calling `(java.util.Date. etime)` > 30k/s. running VisualVM against the clojure VM process shows that `java.lang.Class.forName()` is the most expensive method. To me, that sounds like Clojure is looking up the class on every invocation.
04:46amalloyadamz: because the clojure compiler doesn't know what type you expect etime to be, and Date has multiple constructors
04:46amalloytry (java.util.Date. ^long etime) or whatever type is appropriate
04:46adamzcool. i’ll give that a shot. thanks!
05:00adamzyup. that certainly made a difference! thanks amalloy :)
05:03magopian_hello there :) Can someone tell me what is ^{} ?
05:03magopian_eg: ^{:key timestamp}
05:03magopian_it looks like a map, but what is the "^" for?
05:05qsysit's meta-data
05:07qsyshttp://xahlee.info/clojure/clojure_metadata.html
06:08edmondo1984Hello, anyone could help a Clojure newbie to tackle one of the exercise of Clojure for the brave and the true? Quite a basic one
06:13paul_muadib666edmondo1984: i maybe can, whatsup?
06:19magopian_thanks qsys :) (and sorry for the lag ;)
06:44edmondo1984so I need to write a function to update a nested hash
06:44edmondo1984something that you can write like this
06:44edmondo1984(update-in :key1 :key2 value {} )
06:44edmondo1984and would result in { :key1 { :key2 value } }
06:45TEttingertypically you'd have keys in a vector
06:45paul_muadib666so reimplementing update-in?
06:45TEttinger,(update-in {} [:key1 :key2] :value)
06:45clojurebot{:key1 {:key2 nil}}
06:45TEttinger,(update-in {} [:key1 :key2] (constantly :value))
06:45clojurebot{:key1 {:key2 :value}}
06:46TEttingeredmondo1984: is the task to reimplement the built-in update-in fn?
06:49TEttinger,(defn build-nested [v & ks] (update-in {} ks (constantly v)))
06:49clojurebot#'sandbox/build-nested
06:49TEttinger,(build-nested 1 :a :b :c)
06:49clojurebot{:a {:b {:c 1}}}
06:53edmondo1984how do you make the clojure bot evaluate?
06:53TEttingercomma prefix
06:53edmondo1984, (update-in {} [:key1 :key2] "hello")
06:53clojurebot#error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [clojure.core$apply invokeStatic "core.clj" 641]}]\n :trace\n [[clojure.core$apply invokeStatic "core.clj" 641]\n [clojure.core$update_in invokeStatic "core.clj" 5950]\n [clojure.core$update_in doInvoke "c...
06:54edmondo1984, (update-in {} [:key1 :key2] (constantly "hello"))
06:54clojurebot{:key1 {:key2 "hello"}}
06:54TEttinger,(defn build-nested [& args] (update-in {} (butlast args) (constantly (last args))))
06:54clojurebot#'sandbox/build-nested
06:54TEttinger,(build-nested :a :b :c )
06:54clojurebot{:a {:b :c}}
06:54edmondo1984ok got it the third parameter is a function
06:54TEttingeryep!
06:54edmondo1984now the problem is that I have to reimplement updatein
06:54luma,(assoc-in {} [:key1 :key2] "hello")
06:54clojurebot{:key1 {:key2 "hello"}}
06:54TEttingerwhy though?
06:55TEttingerah
06:55TEttingerforgot about that one, (inc luma)
06:55lumathere's get and get-in, assoc and assoc-in, update and update-in
06:55edmondo1984I am learning Clojure and I come from a non lisp background
06:56edmondo1984let me find my wannabe-implementation that doesn't work
06:57TEttingerI would suspect that being able to reimplement the -in group of fns might be best done later
06:57TEttingerI imagine the core implementations of them are a little complex
06:57edmondo1984(defn assoc-in "Associate a key inside a nested map" [m [k & ks] v] ((loop [mymap {} ] (if (empty ks) (assoc m k v))) ((recur (assoc-in m ks v) [m ks v]) mymap)) )
06:58edmondo1984http://paste.ofcode.org/WdwLuA3cgBdaegQgzPzAg
06:58edmondo1984this stuff obviously rdoesn't work
06:58TEttingerthe two parens seems like a problem
06:59TEttinger"((loop"
06:59TEttingerthat calls the result of loop as if it is a fn
06:59edmondo1984and loop is not a fun ?
06:59edmondo1984fn
06:59TEttingersame with recur, looks like a bug
06:59edmondo1984is a macro?
06:59TEttingerloop is a macro but it doesn't return a callable thing
07:00TEttingeryou need one paren to call
07:00TEttingeranother paren if you want to call what the first call returned
07:00TEttinger,(+ 1 2)
07:00clojurebot3
07:00TEttinger,(constantly (+ 1 2))
07:00clojurebot#object[clojure.core$constantly$fn__4614 0x246ee771 "clojure.core$constantly$fn__4614@246ee771"]
07:00TEttinger,((constantly (+ 1 2)))
07:01clojurebot3
07:01TEttingerthe first calls +
07:01TEttingerthe next calls constantly and gives it as an arg 3
07:01TEttingerand you can see that prints a messy fn
07:01TEttingersince constantly returns a fn
07:01TEttingerthe last calls the fn constantly returns
07:02TEttingermake sense?
07:02TEttingerparens don't do grouping in lisps
07:03TEttingeryou can't just stick more in like in C or Java
07:03edmondo1984not sure I understood
07:04TEttingeruh hm.
07:04TEttingerso you understand that fns are values and can be passed as arguments and returned from other fns and macros, right?
07:05TEttinger,(map inc [1 2 3])
07:05clojurebot(2 3 4)
07:05TEttingerinc is a fn and we can pass it as an arg to map
07:05edmondo1984yes
07:05TEttingerthere's a bunch of fns in clojure's core lib that return other fns
07:06TEttingerconstantly, comp, and juxt are good examples
07:06edmondo1984what do comp and juxt do?
07:06TEttingercomp composes multiple fns
07:06edmondo1984ah comp is composed
07:06edmondo1984right
07:06luma,((comp inc :foo) {:foo 3})
07:06clojurebot4
07:06luma((juxt :foo :bar) {:foo 1, :bar 2})
07:07luma,((juxt :foo :bar) {:foo 1, :bar 2})
07:07clojurebot[1 2]
07:07edmondo1984so juxt take an array of function and applies it
07:07TEttinger,(map (comp inc inc) [1 2 3])
07:07clojurebot(3 4 5)
07:07edmondo1984just a second
07:07edmondo1984,((juxt str #(+ 1 %) [ 2 3] ))
07:07clojurebot#error {\n :cause "Wrong number of args (0) passed to: sandbox/eval194/fn--195"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: sandbox/eval194/fn--195"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 28]\n [clojure.core$juxt$fn__4744 invoke "core.c...
07:08edmondo1984,((juxt str #(+ 1 %)) [ 2 3] )
07:08clojurebot#error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.lang.Numbers add "Numbers.java" 3640]\n [sandbox$eval221$fn__2...
07:08lumajuxt takes any number of functions and returns a function that calls all those functions on its parameter and returns a vector of the results
07:08TEttingervector, not array, but essentially yes. and it doesn't exactly apply
07:08edmondo1984,((juxt str #(+ 1 %)) 2 )
07:08clojurebot["2" 3]
07:08edmondo1984gooot it!
07:08edmondo1984I don't know how I could have survived without Clojure
07:08TEttingerthere's also partial, which is handy
07:08lumaso basically ((juxt :foo :bar) param) => [(:foo param) (:bar param)]
07:09TEttinger,(map (partial * 2) [1 2 3])
07:09clojurebot(2 4 6)
07:09edmondo1984what's the benefit of using partial with respect of an anonymous function?
07:09TEttinger,(map (juxt identity (comp (partial * 2) inc)) [1 2 3])
07:09clojurebot([1 4] [2 6] [3 8])
07:09edmondo1984is partial a macro that gives you a better syntax?
07:09edmondo1984(partial * 2) is equal to #( * 2 % ) right?
07:09TEttingerthey're very similar. partial works for any number of arguments
07:10edmondo1984got it
07:10hyPiRionpartial is just a function afaik
07:10hyPiRion$source partial
07:10TEttinger,((partial *) 1 2 3)
07:10clojurebot6
07:10TEttingerlazybot ded
07:10edmondo1984got it
07:10hyPiRionsad times
07:11edmondo1984so now what about loop and recurse?
07:12TEttinger,(loop [a 0] (if (>= a 5) a (recur (+ a (rand-int 5)))))
07:12clojurebot6
07:13TEttinger,(loop [a 0] (if (>= a 5) a (recur (+ a 1))))
07:13clojurebot5
07:13lumarecur is a special form that recurses to loop (or the top of the function if there's no loop)
07:13lumaand loop is a special form that's just like let, but also serves as a recursion point
07:13edmondo1984so loop sets the recursion point
07:14TEttingerand what you change between recursion
07:14TEttingerlike I set "a" to 0
07:14edmondo1984the a variable gets bound to the argument of recur
07:14TEttingerwhen I recur, I specified I wanted a different value for a, (+ a 1)
07:15TEttingerand you can use the name a throughtout the loop body
07:15edmondo1984so loop [ variable initialAssignment] (recur (+ variable 1 )
07:15TEttingerlike it's used when we stop recurring to get the last value
07:15edmondo1984it just recur infinitely increasing variable of 1
07:15edmondo1984starting from initialAssignment
07:15TEttingeryes
07:15edmondo1984good
07:15edmondo1984now what about the paranthesis around loop?
07:15edmondo1984loop return a function right, I need to evaluate it?
07:15TEttingerno
07:16TEttingerloop doesn't return a fn, it returns whatever the last statement is in the loop that didn't recur
07:16edmondo1984so loop evaluates the loop
07:16edmondo1984is not lazy somehow
07:16TEttingerso in my second loop example, it returned 5
07:16edmondo1984got it
07:16TEttingerclojure defaults to not lazy
07:16edmondo1984now
07:17edmondo1984right
07:17edmondo1984so now I think I have all the elements except aybe the recursive call
07:18TEttingeryeah, loop/recur is a tricky thing and examples help
07:18TEttingerit's after 4 AM here, I should *head hits keyboard, instantly snoring*
07:19edmondo1984ok I still can't write the assoc-in
07:20edmondo1984(defn assoc-in "Associate a key inside a nested map" [m [k & ks] v] (loop [mymap m ] (if (empty ks) (assoc mymap k v)))
07:21edmondo1984this part looks reasonable right? If in the loop I have no other keys (ks), I just associate the current value to the current key and return the map
07:21lumaright
07:25edmondo1984what's the recursive part now
07:26edmondo1984can I assign two values in the loop recursion?
07:26edmondo1984can I do something like loop [myvar1 initialVal1 myVar2 initialVal2] ?
07:26lumasure
07:26lumait's just like let
07:27edmondo1984what's the syntax?
07:28edmondo1984loop [myvar1 myvar2 initialval1 initialval2] or
07:28edmondo1984loop [myvar1 initialVal1 myVar2 initialVal2]
07:30MJB47second
07:31MJB47same with all similar constructs (let, for, doseq etc)
07:35edmondo1984MJB47 maybe you can point me to a page where it explain the syntax for all those construct?
07:36MJB47i suppose https://clojuredocs.org/clojure.core/let is a good start
07:38edmondo1984ok let uses pairs in vector
07:38edmondo1984reading the documentation can be very useful
07:39edmondo1984now getting back to my recursion problem in assoc-in
07:53edmondo1984hello, is anyone here who can help me re-write assoc in?
08:47Leonidasedmondo1984: I would check whether there is just one element and then do the assoc
08:59renlhi aside from play-clj are there any recommended clojure libraries for doing visualization?
09:35EmpperiI've got a strange problem with clojure regular expressions
09:36Empperigot this regexp (escaped): #"[^\\s()\"]+\\*"
09:36Empperi,(re-matches #"[^\\s()\"]+\\*" "foo")
09:36clojurebot"foo"
09:36Empperithat shouldn't match as far as I understand
09:36Empperiand if I run that against plain java that is the case
09:36Empperifoo* should match
09:37EmpperiI'm guessing I should apply some flag to make it work like I want it to but...
09:37Empperioh
09:37Empperiremove one backslash before the asterisk
09:38Empperiand it works better :)
09:38Empperinevermind!
09:38Empperi(complaining in IRC, best way to solve problems)
09:41mpenetyou can use (re-pattern "") if you insist on escaping stuff
09:41mpenet <Empperi> ,(re-matches (re-pattern "[^\\s()\"]+\\*") "foo")
09:41Empperino I don't insist :)
09:41mpenet:>
10:17sdegutisDo you keep ~/.emacs.d/elpa/ under version control along with its parent directory? If not, how do you ensure that you can quickly and easily get your packages back when cloning your emacs configs?
10:17sdegutisSorry wrong dir.
10:26sdegutisOops I meant wrong channel.
10:26sdegutisBut I guess it still kind of applies here.
10:26sdegutisamalloy_: what's your solution to this? Do you use cask, or do you keep ./elpa/ under version-control, or something else?
10:34free_beardsdegutis: just use the package.el api man, :))
10:34sdegutisfree_beard: thanks bbl
10:46TimMcsdegutis: The only thing I gitignore there is .emacs.d/auto-save-list/*
10:51aurelianis there a way to go over a list with reduce for example but to know the index? I need to transform the list into another data structure
10:52aurelianlike map-indexed but with reduce or something
10:52aurelianhttps://www.refheap.com/115194
10:53aurelianso, if the index is even add to the first vec, if odd to the second
10:53sdegutisTimMc: Hmm my .gitignore has /auto-save-list /backups /autosaves /eshell /tramp /ac-comphist.dat /url/cookies *.elc /ido.last
10:59TimMcsdegutis: I suppose if I used those features I would probably ignore those as well. :-)
11:02sdegutisok
11:12aurelianpartition-by with index would be nice :|
11:14ToxicFrogaurelian: isn't that just (map-indexed vector ...) + (partition-by (comp partitioner second)) ?
11:15aurelianhmm
11:15aurelianthat would go over the coll twice
11:18aurelianmaybe I just don't have data in best format
11:19aurelianthe amount of clojure functions with index makes me wonder if this is a good idea
11:53TimMcaurelian: Your accumulator could include an index that you increment.
11:53TimMcor just use loop :-)
11:54aurelianthat could also do it
11:54aurelianI ended up with something like this: (partition (/ (count data) 2) (map #(-> (:pace %)) (sort-by #(-> (:race %)) data)))
11:54aurelianis a list of lists
11:55aurelianpotentially I can have the data already sorted by race
11:56aurelianI'll always have 2 races that's why the partition in the middle
12:00aurelianis basically comparing results of bunch of runners over 2 different races, but the sort was by runner, turns out sorting by race simplifies it a lot
12:17justin_smithaurelian: resisting the urge to make some sort of "race condition" pun here
12:17aurelianxD
12:17j-pb_justin_smith: without the context I am not sure wether they are talking about continuous integration stuff or about on which olympic runner to place their sport bets...
12:18aureliansecond
12:20j-pb_I think in the last two olympics there were only black athletes qualified for the 100m sprint, so sorting by race is pretty useless
12:20justin_smithaurelian: you may be aware, #(-> (:pace %)) is just :pace but with an arity restriction
12:21justin_smithsame with #(-> (:race %)) and :race
12:21aurelianI'm still learning
12:21justin_smithaurelian: np
12:21justin_smithjust an fyi
12:21aurelianwhat's a better way to do that?
12:22justin_smith(map :pace (sort-by :race data))
12:22aureliancheers
12:22justin_smithlike I said, #(-> (:pace %)) is just :pace with an arity restriction, and the arity restriction didn't help you there :)
12:22marcfontainetrying to find a way to use a macro with a def on a set of values
12:22marcfontaine(defmacro t [val] `(def ~(symbol val) ~val))
12:22marcfontaineuser> (t “a”)
12:22marcfontaine#'user/a
12:22marcfontaineuser> a
12:22marcfontaine"a"
12:22marcfontaine(doseq [v ["b" "c" "d"]] (t v))
12:22marcfontaineuser> b
12:22marcfontaineCompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context
12:23aurelianjustin_smith got it. thanks!
12:23justin_smithmarcfontaine: macros cannot use data that is not present when the form is compiled
12:24justin_smiththat doseq hides the argument from the macro, the macro just sees "v"
12:24justin_smitherr, just sees v, the symbol
12:25justin_smithat the time of compilation it does not run the macro on the args it would see at runtime - just the literal args in the form
12:25justin_smithmarcfontaine: a macro is a function that takes a form as an argument and returns a new form. That form is compiled. Only later is anything run.
12:26marcfontaineI don’t follow, if I do (t “a”) that works if I do (doseq [v [“a”]] (t v)) that doesn’t work the only difference is that it’s in a doseq
12:26justin_smithmarcfontaine: if you use intern instead of def you don't need to mess with macros, it's much simpler
12:26justin_smithmarcfontaine: the difference is that the argument is v not "a"
12:27justin_smithmarcfontaine: macros only run before compilation, and they are functions that transforms forms, macros do not see runtime data.
12:27justin_smithif you use a function instead of a macro, and the function uses intern, this is much easier. Just use intern instead of def.
12:28justin_smith,(doc intern)
12:28clojurebot"([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var."
12:29justin_smith,(intern 'sandbox 'a "foo")
12:29clojurebot#'sandbox/a
12:29justin_smith,a
12:29clojurebot"foo"
12:32justin_smith,(doseq [v ["b" "c" "d"]] (intern 'sandbox (symbol v) v))
12:32clojurebotnil
12:32justin_smith,b
12:32clojurebot"b"
12:32justin_smith,c
12:32clojurebot"c"
12:32justin_smith,d
12:32clojurebot"d"
12:48rhg135I love cljs
12:49marcfontainejustin_smith I need this for clojurescript and intern is not implemented
12:56justin_smithmarcfontaine: oh, that's rough, because that also rules out eval (the only way to use def with a name only known at runtime)
12:56justin_smithmarcfontaine: what about using a hash-map with keys instead of defs in a namespace?
12:59justin_smithmarcfontaine: oh, the other option is the fact that "def" doesn't create vars in js, it just creates js variables. So you could just use interop on the namespace or on the window itself
13:00marcfontaineit’s for using bootstrap classes from reagent https://gist.github.com/marcandrefontaine/c32b566b2e981d867967 right now I have to do them one by one, I am trying to rewrite the macro by passing it all the class names but I can’t figure it out.
13:03justin_smithmarcfontaine: yeah, macros can't use runtime data. What about just using aset? aset does in cljs what intern does in clj, considering that vars don't exist in cljs.
13:04justin_smithotherwise you could make a macro that expands to all the def calls in one body - eg. you would pass all the names to the macro, rather than calling the macro inside a doseq, the macro would have a for or map inside it to do all the defs
13:05marcfontaineyes that’s what I was trying to do with a doseq in the macro which didn’t work at all I’ll try with the for/map
13:07justin_smithmarcfontaine: yeah, doseq is totally useless in a macro - a macro must return the form you want to evaluate
13:09justin_smith,(defmacro defs [& bindings] (cons 'do (for [[sym value] (partition 2 bindings)] (list 'def sym value)))) ; marcfontaine
13:09clojurebot#'sandbox/defs
13:09justin_smith,(defs a "a" b "b" c "c" z "z")
13:09clojurebot#'sandbox/z
13:09justin_smith,[a b c z]
13:09clojurebot["a" "b" "c" "z"]
13:10justin_smithmarcfontaine: the above should work in cljs
13:12marcfontainebeautiful
13:16rhg135Actually, I'm pretty sure vars exist in some form on cljs so def would be the way to go
13:28justin_smithrhg135: no, they explicitly do not exist in cljs
13:29justin_smithrhg135: unless the clojurescript wiki is severely out of date
13:29justin_smithhttps://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#vars-and-the-global-environment
13:32justin_smithrhg135: oh, my bad, the wiki is out of data
13:32justin_smith*date
13:32sdegutisIs there a more convenient way to use clojure.data.csv than (write-csv) with a temporary java.io.StringWriter which you just call (str) on afterwards in order to get the CSV as a string?
13:32sdegutisPlease tell me the answer is yes, because I'm certain it'sn o.
13:32justin_smithrhg135: if vars exist, then it should have intern :(
13:34rhg135They usually don't at runtime
13:35justin_smithrhg135: ahh, so vars are a thing but only in the compiler, not in the runtime
13:35justin_smithick
13:35rhg135sdegutis: with-out-str
13:35justin_smithrhg135: it doesn't print anything interesting
13:36sdegutisrhg135: Oh right! Why didn't I think of that? Actually, I remember thinking of that, and it for some reason not being viable in this usage.
13:36rhg135Oh, then no
13:36sdegutisI can't remember why I thought so. Hmm.
13:36justin_smithrhg135: the issue is that instead of returning or printing a string, it wants an arg it can write to, which means making a stringwriter
13:36matthaveneranyone know how to get leiningen to copy CSS files from a cljsjs package into my resources dir?
13:36sdegutisOh right, that's why.
13:36sdegutisI should probably just sign the dang CSV or whatever it's called, and send a PR through Jira.
13:37puredangersdegutis: http://clojure.org/community/contributing
13:39sdegutisYeah that.
13:40sdegutispuredanger: if I go through all this hassle do you think there's a chance that I could get clojure.data.csv fixed to not be so inconvenient?
13:40puredangersure - what's the issue again?
13:40sdegutis(The beautiful thing about Github Issues and PRs is that it's really quick/easy to figure that question out.)
13:41sdegutispuredanger: write-csv is inconvenient when all you want is a string
13:41sdegutispuredanger: you have to create your own StringWriter and then call (str) on it and discard it. 3 lines to do something that should take 1.
13:41rhg135(defn as-str [f] (str (doto (StringWriter.) (f))))
13:41sdegutispuredanger: not the end of the world obviously, but not as convenient as it should be.
13:41sdegutisrhg135: yes I have that now, and I only use it for this one use-case and would like to get rid of it
13:41puredangerwhat would you propose?
13:42sdegutispuredanger: this function be inlined as a convenience function called csv-to-string or something that just wraps write-csv with a StringWriter and returns the inner string
13:43puredangerseems like a reasonable request to me
13:43sdegutispuredanger: (defn csv-to-string [x] (let [out (java.io.StringWriter.)] (write-csv out x) (str out)))
13:43sdegutisOkay. Then I'll do it!
13:43puredangerit's an e-form, no scanner required
13:44sdegutisWoo!
13:45puredangersee http://dev.clojure.org/display/community/Developing+Patches for making patches
13:45puredangerI need to move that stuff onto clojure.org
13:45sdegutispuredanger: Am I right to understand that it's common to not need to fill out the top three fields (and in fact you can't) in the e-form? Or am I totally misunderstanding this thing?
13:46puredangeryeah, those populate based on later fields
13:46puredangerwhich is weird, but I can't change it
13:47sdegutisOk just checking thanks alex :)
13:48sdegutispuredanger: woo signed and verified! thanks for the link
13:48puredangerI see it! :)
13:49sdegutis:D
13:50puredangerhttp://dev.clojure.org/jira/secure/Signup!default.jspa
13:50TimMcOh, how the process has changed.
13:50TimMcA couple years back I would *not* have seen a ":D" anywhere near a discussion around the contributer agreement. :-P
13:51justin_smithhaha
13:51justin_smithTimMc: I had to walk uphill both ways in the snow to get to the snail mail
13:51TimMcI had to hand crank the fax machine all night in case something came through.
13:51puredangerhey, there's still a filing cabinet somewhere with printed versions of all these :)
13:51justin_smithmaybe I shouldn't ever quote a cosby joke ever again, now that I consider it
13:53TimMcjustin_smith: Because stuff?
13:53justin_smithTimMc: stuff pretty much - I don't like the idea of repeating his jokes any more, after hte other stuff he did. I dunno, maybe it's no big deal.
13:55TimMcNo one is all good or all bad. I think it's fine.
13:56TimMcbut I hear you
14:04sdegutisTests pass!
14:07puredangerI hope so. :) CI runs them all the time so it would be surprising if they did not.
14:11sdegutispuredanger: so, the instructions I'm following say to include the JIRA ticket's number in the commit, so I'm creating a JIRA ticket before committing.. but the JIRA ticket says it requires a patch, and I have no idea how to create patch files but I have a commit prepared (all except the name). I feel kind of stuck on how to move forward.
14:11puredangercreate the ticket. create the patch. add the patch to the ticket.
14:11rcassidysdegutis: git format-patch -1 HEAD
14:11rcassidyIf HEAD is the commit with what you wanna make a patch based on
14:11sdegutisrcassidy: thanks!
14:11rcassidynp
14:11rcassidyand that's a 1 (one) not L
14:11sdegutisI just copy/pasted it ;)
14:11sdegutisWow, I have a newfound appreciation for GitHub's Pull Request based workflow.
14:11puredangerif you do it like 20 times a day for a few years, it gets really easy
14:11sdegutisHaha.
14:11ToxicFrogsdegutis: yeah, this is why I never submit patches to clojure and only rarely to bup
14:12sdegutisCreatd!
14:12sdegutisWoo!
14:14sdegutispuredanger: are the appropriate people notified when I create a ticket including a code/test patch like I just did?
14:14puredangerusually, although you created it in the wrong project (CLJ not DCSV)
14:14puredangerI moved it
14:15sdegutisDang, sorry. Thanks puredanger.
14:16puredangerJonas Enlund is the project owner so you could ping him too
14:16sdegutispuredanger: Okay now I see how to find the right project and create it there.
14:16puredangerI think it should be set up so that happened on creation, but not positive (not all of the contribs are set up the same)
14:18sdegutisWow Jira is something else.
14:18sdegutisHow do you @ping someone in a comment, the @at syntax isn't pulling up a dropdown list of names?
14:19puredangerJonas is "jonas" on slack if you're ever on there or @jonasenlund on twitter
14:20puredangerin jira, I forget - you can look it up in the formatting instructions
14:21sdegutisPhew glad that's done with.
14:22TimMcHAHAHA it has only just begun
14:22sdegutisThanks puredanger for all your help with this process, and you have my condolences that you have to go through that every day.
14:22puredangerit's really not that bad
14:22puredangerif you don't hear from Jonas in the next week, ping me
14:23sdegutispuredanger: nah don't worry about it, he'll see it when he sees it
14:41sdegutisjustin_smith: I was pretty convinced you were right about the with-out-str thing not working, but now I don't remember why, and it's the thing Jonas is proposing as to why the helper function isn't necessary.
14:42sdegutisHmm. It does in fact work.
14:42justin_smithsdegutis: oh does it like use *out* by default and I forgot it did that?
14:42sdegutisjustin_smith: yeah
14:42sdegutisjustin_smith: wait the CSV lib? no
14:42justin_smithsdegutis: oh so you pass in *out* and surround that with with-out-string ?
14:42sdegutis,(do (require 'clojure.data.csv) (with-out-str (clojure.data.csv/write-csv *out* [["a" "b"] ["c" "d"]])))
14:42clojurebot#error {\n :cause "Could not locate clojure/data/csv__init.class or clojure/data/csv.clj on classpath."\n :via\n [{:type java.io.FileNotFoundException\n :message "Could not locate clojure/data/csv__init.class or clojure/data/csv.clj on classpath."\n :at [clojure.lang.RT load "RT.java" 456]}]\n :trace\n [[clojure.lang.RT load "RT.java" 456]\n [clojure.lang.RT load "RT.java" 419]\n [clojure.co...
14:42justin_smithOK right
14:43sdegutisHowever, I thought one was a printer and one was a writer.
14:43sdegutisSo I thought it just simply wouldn't work.
14:43justin_smithsdegutis: is that really that much better than a StringWriter?
14:43sdegutisNo, I personally think it's still worth a patch.
14:43sdegutisBut it's a harder argument to make.
14:47amalloyi think c.d.csv does the right thing already, by working with streams (or writers, i forget) and *not* encouraging you to turn a csv into one giant string
14:48amalloyyou already can do it if you want to, quite easily, with with-out-str, but you usually shouldn't, so there's no convenient shortcut for it. just like there's no dissoc for vectors because it's expensive to remove elements from the middle
14:48justin_smiththat's a good point
14:48sdegutisamalloy: very good point
14:49sdegutisamalloy: how do you return a CSV from a Ring handler function without turning it into a string first?
14:49rhg135,(dissoc '[a b c] 1)
14:49clojurebot#error {\n :cause "clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap"\n :at [clojure.lang.RT dissoc "RT.java" 848]}]\n :trace\n [[clojure.lang.RT dissoc "RT.java" 848]\n [clojure.core$dissoc invokeStatic "core.clj" 1462]\n [clojure.c...
14:49rhg135cool
14:49amalloysdegutis: ring accepts a lot of things other than strings
14:50amalloynotably, a lazy seq of strings
14:50amalloyso you can stream the response
14:50sdegutisamalloy: But still, what do you create and use as the out-param?
14:51sdegutisI've closed the issue so this isn't an argument in favor of the stringifying function. I'm just curious what's a better output writer than StringWriter.
14:51amalloyring will also accept an InputStream, i believe; one option would be to use a pipedinputstream/pipedoutputstream pair
14:51amalloybut that's a bit clunky
14:52amalloydoes c.d.csv have a row->string function or something?
14:52amalloyunhelpfully, it has that function but marks it private
14:54hiredman~private
14:54clojurebotnot even once
14:54justin_smithyeah, I think the piped stream combo is actually the whizbang thing
14:54hiredman~o/
14:54clojurebot\o ... High five!
14:54amalloypersonally i would just not use c.d.csv because it's just getting in the way. {:status 200, :body (interpose "\n" (for [row csv] (interpose "," row)))}
14:54amalloythis of course has the problem that it doesn't handle cell data with commas
14:55amalloywhich would be easy to fix if c.d.csv exposed its functions for working with data smaller than a whole file
14:55sdegutisamalloy: right quoting is a nice behavior of this lib
14:55sdegutisamalloy: you know, I was actually thinking "why don't I just write this myself, it's not that fricken hard of a data format" but then I was like "no, no, I should be using the appropriate libs for things like this, that's the Right Way™" and decided to keep using this lib
14:56amalloyyeah, i agree with you on that, it really sucks to reimplement it
14:56sdegutisBut you're right. In this case, I only use the lib in exactly one route, and in that case, there are no quoting issues and never will be.
14:56amalloyi think a much better PR to c.d.csv would be to make its private functions mostly public
14:56amalloyand then you could actually use it to stream to ring pretty easily
14:56amalloyor, as i said, you could dedicate a thread to streaming the response using piped io and the existing api
14:56sdegutisMeh, I'd actually much prefer a CSV API similar to clojure.pprint/print-table
14:57justin_smith,(let [o (java.io.PipedOutputStream.) i (java.io.PipedInputStream. o)] (.write o (.getBytes "hello\n")) (.close o) (slurp i))
14:57clojurebot"hello\n"
14:57sdegutisWhere you give it the keys and a seq of maps and it just spits out the right CSV. That's a sweeter API.
14:57sdegutis,(clojure.pprint/print-table [{:a 1 :b 2} {:a 3 :b 4}])
14:57clojurebot#error {\n :cause "clojure.pprint"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.pprint"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.n...
14:57amalloyactually, something i just remembered: compojure (or maybe it's ring?) has a helper function for creating a piped io pair out of a function
14:57amalloymakes it super easy
14:57justin_smithamalloy: oh, nice
14:57sdegutis,(do(require'clojure.pprint)(clojure.pprint/print-table [{:a 1 :b 2} {:a 3 :b 4}]))
14:57clojurebot#error {\n :cause "require'clojure.pprint"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: require'clojure.pprint, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.ClassNotFoundException\n :message "require'clojure.pprint"\n :at [java.net.URLClassLoader$1 run "URLClassLoade...
14:58sdegutis,(do(require 'clojure.pprint)(clojure.pprint/print-table [{:a 1 :b 2} {:a 3 :b 4}]))
14:58clojurebot\n| :a | :b |\n|----+----|\n| 1 | 2 |\n| 3 | 4 |\n
14:58justin_smithamalloy: that would also be easy to implement
14:58amalloyhttps://ring-clojure.github.io/ring/ring.util.io.html#var-piped-input-stream
14:58amalloyso it would be like: {:status 200 :body (piped-input-stream (fn [o] (write-csv o my-csv))))
14:58amalloymodulo mismatched delimiters
14:59hiredmanhow perfect would it have been if that was also a private function
14:59amalloyweavejester knows better though
15:01sdegutisamalloy: really!?
15:01sdegutissweet!
15:02sdegutisamalloy: it's kind of ugly though because you have to write a helper function, but still it's mostly nicer
15:02amalloywhat helper function?
15:02sdegutisamalloy: on your example the (fn [o] ...)
15:02sdegutisI also like that Compojure allows you to return a variety of formats.
15:02sdegutishttps://github.com/weavejester/compojure/blob/master/src/compojure/response.clj
15:03amalloyi think "helper function" generally means something quite different from that lambda
15:03sdegutisamalloy: wrapper function then
15:30sdegutisEvery time I need to use defrecord and definterface I have to look them up to see which one of them takes a "self" first-param and which doesn't.
15:30clojurebotGabh mo leithscéal?
15:30sdegutisIs there a good mnemonic for this?
15:31ystaelsdegutis: "conj.io"
15:31ystael:p
15:31sdegutis???
15:31sdegutisOh https://www.conj.io/
15:31sdegutisystael: is that your site?
15:31ystaelwhich doesn't, at all, address your issue
15:31ystaelnamely having to look them up :)
15:31ystaelno, I forget who runs it, it isn't me
15:33KamuelaWhich is the correct answer? Which requires self?
15:34sdegutisKamuela: defrecord apparently
15:34sdegutis(doc defrecord)
15:34clojurebot"([name [& fields] & opts+specs]); (defrecord name [fields*] options* specs*) Options are expressed as sequential keywords and arguments (in any order). Supported options: :load-ns - if true, importing the record class will cause the namespace in which the record was defined to be loaded. Defaults to false. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (metho
15:35sdegutis"Note that a parameter must be supplied to correspond to the target object ('this' in Java parlance). Thus methods for interfaces will take one more argument than do the interface declarations.”
15:35KamuelaI would just repeat record yourself over and over
15:37sdegutisKamuela: that didn't work for hippocampus in college
15:37sdegutisKamuela: when I try to remember what hippocampus means, I think of a hippo standing on top of the campus building shouting
15:37sdegutisKamuela: I have absolutely no idea what it's supposed to represent
15:38KamuelaMemory
15:38sdegutisBut how does that relate to its function?
15:38ystaelsdegutis: "horse area"
15:38sdegutisstupid mnemonic
15:38KamuelaAmygdala emotion
15:39KamuelaCerebellum balance? Not actually sure anymore
15:42sdegutissee?
15:42sdegutisuseless
16:05amgarchIn9http://pastebin.com/P8T44STu
16:06amgarchIn9hi, is there something wrong with snag-quotes? I see some deadlock for n = 2048. New to clojure and dont know many debug techniques.
16:07justin_smithamgarchIn9: "launching" is done by calling future, you don't need to mapv deref, you just need (doall q)
16:07justin_smithamgarchIn9: what happens is the next future is not even started until the previous completes, because deref blocks and for is lazy
16:08justin_smithalternatively you could do the silly (mapv identity q), but just (doall q) instead
16:09amgarchIn9(mapv deref (vec q)) I forced the q and the performace degraded. Chunks of 32 seem to work for arbitrary n
16:09justin_smithamgarchIn9: when you map deref you only start at most a chunks worth at a time, (doall q) makes all the futures start immediately
16:10justin_smithif you want only N active at a time, use a proper thread pool instead of futures
16:11hiredmandon't do io in a go block
16:11amgarchIn9well, snag-futures was there as a reference. The actual problem is with snag-quotes
16:12hiredmanwhat does that have to do with anything?
16:13hiredmandon't do io in a go block
16:14hiredmanyou most likely should be using pipeline-blocking
16:14hiredmanhttps://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L546-L550
16:17amgarchIn9thatnk, reading. (show s) was not there when the problem first occured. Without IO which (wget) also does there is no point in the excersize.
16:19hiredmanright, so do your io, but don't use a go block
16:19hiredmanpipeline-blocking runs each blocking task on a real thread https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L497-L500
16:39sdegutisOh man I already forgot when to use defprotocol vs definterface :/
16:39sdegutisOh right. I want defprotocol.
16:40amalloyalso don't start an unlimited number of threads to perform IO at once. you'll just DoS your system when it reaches capacity
16:40hiredmanwhich is why pipeline makes you pass in a `n`
16:41hiredmanon a virtual machine a useful 'n' for io is going to be a relatively small number
17:02amgarchIn9that why I thout go blocks and "the state machine" on a predefined fixed size thread pool is fine. I have "netstat -aon | grep <the ip here> | wc" about 60. Fore some reason all "takes" from the channel are "delayed" (exclamation singns here http://pastebin.com/B05czQTB )
17:03justin_smithIO in go blocks just starves core.async's fixed size pool, use pipeline-blocking instead
17:04ystaeljustin_smith: i'm not familiar with core.async at all, is this analogous to other situations where you are doing blocking operations on a thing that needs to be a nonblocking asynchrony reactor?
17:05justin_smithystael: pretty much - core.async has a state machine and runs multiple go blocks in a specialized thread pool, doing blocking IO in those go blocks subverts that design (and can lead to bad failures)
17:06ystaelgot it, i remember a similar thing from working with rxjava
17:06justin_smithystael: simplified version is <! turns into a parked state meaning some other code can be run in your thread >! similarly parks but also wakes up whoever reads from the chan if they were parked
17:07ystael"open mouth" and "feed toddler"? :)
17:07justin_smithso it's a combination of coroutines and actual threading, copied from golangs goroutines
17:08justin_smithystael: something like that - the way I remember it is (let [x (<! chan)] ...) the data is moving from chan into x
17:09ystaeljustin_smith: i tend to conceptualize all other areas of my life in terms of toddler management tasks at the moment :)
17:12amalloyjustin_smith: <! and >! both have the same behavior re waking up other code, right?
17:13amalloy<! will wake up anyone who was parked trying to write, and >! will wake up anyone who was parked waiting to read
17:13hiredmanamgarchIn9: mixing blocking tasks and non-blocking tasks in the same threadpool is problematic, the blocking tasks will starve the non-blocking tasks, and the level of parallelism to get the best performance out of each type of task tends to be different
17:14hiredmanamgarchIn9: the threadpool core.async uses for go blocks is a global resource, any code libraries, whatever, you load could be using it
17:15hiredmanamgarchIn9: as a shared resource it needs to be designated for blocking or non-blocking tasks (so different people don't use it for different kinds of tasks)
17:15hiredmanit has been designated for non-blocking tasks
17:18hiredmanand, more specifically, the core.async threadpool is a forkjoin threadpool, which is designed for compute bound tasks (https://stackoverflow.com/questions/8206318/is-javas-fork-and-join-thread-pool-is-good-for-executing-io-bound-task)
17:33amgarchIn9thank you all. Apparently posting to a channel does not necessarily wake up the reader. But other writers in my case. I got you message, just wanted to understand what is going on here.
17:49ashnuron an non unrelated but distant note... check this out: https://www.youtube.com/watch?v=K4vyRvMASPU
17:55justin_smithamalloy: oh yes, right
18:08sdegutisHello. Good afternoon and I hope you're all doing well. What is the standard way of creating a Date that's precisely 300 seconds from now, without requiring third party libraries?
18:09justin_smith,(java.util.Date. (+ (.getTime (java.util.Date.)) (+ 1000 300)))
18:09clojurebot#inst "2016-02-25T23:09:07.031-00:00"
18:09justin_smith,(java.util.Date. (+ (.getTime (java.util.Date.)) (* 1000 300))) ; OOPS
18:09clojurebot#inst "2016-02-25T23:14:18.314-00:00"
18:09sdegutisjustin_smith: Thank you. Do you happen to know why some people recommend using Calendar instead of that small simple solution?
18:09justin_smithsdegutis: the chance of a bug like using + instead of * ?
18:10sdegutisjustin_smith: no, they still suggest using *, so the chance is still there
18:10justin_smithhaha, no idea then
18:12sdegutisjustin_smith: Also why not use this?
18:12sdegutis,(System/currentTimeMillis)
18:12clojurebot1456441941419
18:12justin_smithsdegutis: because I keep forgetting that exists
18:12sdegutis,(.getTime (java.util.Date.))
18:12clojurebot1456441955900
18:12sdegutisWell they seem to produce different values.
18:12justin_smithsdegutis: time has this habit of doing things
18:12sdegutisSeveral thousand units apart, too.
18:12justin_smithvery mutable, that time thing is
18:13sdegutis,(= (.getTime (java.util.Date.)) (System/currentTimeMillis))
18:13clojurebottrue
18:13justin_smith,(- (.getTime (java.util.Date.)) (System/currentTimeMillis))
18:13clojurebot0
18:13justin_smithwell, then
18:14sdegutisSo 1000 milliseconds = 1 seconds. Okay, will remember htis.
18:14justin_smithsdegutis: if our country used metric you would know by the milli prefix
18:14justin_smithmaybe we need to use hogsheadseconds or something
18:15amalloytemporal ounces
18:17TEttingertime is measured by the accumulation of cheeto dust in the US department of weights and measures' trailer
18:19rhg135time is only an abstraction we use to explain how values succeed one another
18:20sdegutis,(java.util.Date/from (.. (java.time.LocalDateTime/now) (plusMinutes 5) (atZone (java.time.ZoneId/systemDefault)) (toInstant)))
18:20clojurebot#error {\n :cause "java.time.LocalDateTime"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.time.LocalDateTime, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.ClassNotFoundException\n :message "java.time.LocalDateTime"\n :at [java.net.URLClassLoader$1 run "URLClas...
18:20sdegutis,(import 'java.time.LocalDateTime)
18:20clojurebot#error {\n :cause "java.time.LocalDateTime"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "java.time.LocalDateTime"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.ja...
18:20sdegutis,(System/getProperty "java.version")
18:20clojurebot#error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkPropertyAccess nil -1]\n [java.lang.System getProperty ...
18:20sdegutishaha stupid clojurebot
18:21sdegutisoh that lovable rascal
18:24sdegutisThat said, I like this solution best: (-> (java.time.LocalDateTime/now) (.plusMinutes 5) (.atZone (java.time.ZoneId/systemDefault)) (.toInstant) (java.util.Date/from))
18:28rhg135why do you need to know about tz to add 5 minutes to your time
18:28rhg135unless minutes depend on zone
18:28rcassidy,(-> (java.time.LocalDateTime/now) (.plusMinutes 5) (.atZone (java.time.ZoneId/systemDefault)) (.toInstant) (java.util.Date/from))
18:28clojurebot#error {\n :cause "java.time.LocalDateTime"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.time.LocalDateTime, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.ClassNotFoundException\n :message "java.time.LocalDateTime"\n :at [java.net.URLClassLoader$1 run "URLClas...
18:28rcassidy:(
18:31sevviewe should use french metric time.
18:32rcassidyalso, this is confusing -- i am using a script that uses the sum of the ascii values of a IRC nick to choose chat name colors
18:32justin_smithrhg135: clearly, you want a different result if there's a DST change between now and 5 minutes from now
18:32rcassidy,(mod (apply + (map int (seq "clojurebot"))) 256)
18:33clojurebot57
18:33rcassidy,(mod (apply + (map int (seq "rhg135"))) 256)
18:33clojurebot218
18:33rcassidy,(mod (apply + (map int (seq "sdegutils"))) 256)
18:33clojurebot212
18:33rcassidyhmm
18:33rcassidyyou all look the same color of red to me
18:34sdegutisrhg135: I have no idea?
18:34sdegutisrhg135: I just know you can't get an #inst without doing that
18:34justin_smithrhg135: minor thing, that seq call is not needed, map already calls seq
18:34justin_smitherr
18:34justin_smithrcassidy: ^
18:35rcassidythanks justin_smith ! still lerning that stuff
18:35rcassidy*learning
18:36rhg135(inc justin_smith) ; I totally forgot about DST
18:36justin_smith(map int "lazybot is gone now :(")
18:36justin_smith,(map int "lazybot is gone now :(")
18:36clojurebot(108 97 122 121 98 ...)
18:36rhg135I might run that code a few minutes before the time shift
18:36rcassidyand I figured out it's because I'm not mod'ing by 256 in my actual irssi plugin, it's just mod'd over how many colors exist in the plugin, so maybe it isn't very many
18:36rcassidytoo many collisions though
18:37sevvie,(mod (apply + (map int (seq "sevvie"))) 256) ; vanity thy name is...
18:37clojurebot146
18:38justin_smith,(mod (transduce (map int) + "justin_smith") 256) ; yet more vanity
18:38clojurebot33
18:38sdegutis,(let [a (java.util.Date.) b (java.util.Date.)] [(= a b) a b])
18:38clojurebot[true #inst "2016-02-25T23:38:58.227-00:00" #inst "2016-02-25T23:38:58.227-00:00"]
18:39sdegutis,(let [a (java.util.Date.) b (java.util.Date.)] [(= a b) a b])
18:39clojurebot[true #inst "2016-02-25T23:39:02.516-00:00" #inst "2016-02-25T23:39:02.516-00:00"]
18:39sdegutisHaha silly clojurebot.
18:39justin_smithrcassidy: fwiw I showed how to combine the apply and map into a single thing with transduce above
18:40rcassidyah that's neat
18:40rcassidy,(mod (apply + (map int (seq "sdegutils"))) 15)
18:40clojurebot5
18:40rcassidy,(mod (apply + (map int (seq "rhg135"))) 15)
18:40clojurebot9
18:40rcassidygrrr
18:41rcassidy,(mod (apply + (map int (seq "clojurebot"))) 15)
18:41clojurebot1
18:41rcassidythis doesn't make sense!
18:41justin_smith,(mod (transduce (map int) + 0 "clojurebot") 15)
18:41clojurebot1
18:41justin_smith,(mod (transduce (map int) + "clojurebot") 15) ; aha, the 0 is optional
18:41clojurebot1
18:44rcassidyi wonder how i can make irssi tell me how many colors it's choosing from
18:44sdegutisOf course you can't.
18:45rcassidy:(
18:45rhg135`tput colors` can show you how many it should think to use
18:47rhg135terminals are weird with colors
18:48rcassidyyeah, tput colors gives me 256
18:48rcassidyand i'm reading my irssi script, but i don't think it picks from terminal colors
18:48rcassidylooks like it picks from a list 11 items long
18:49rcassidybut my own tests with mod 11 / 10 don't work
18:49rhg135it's a handy feature for sure
18:49rhg135you are yellow-orange
19:26TEttingerrcassidy: if you have an xterm-based terminal, it probably supports a certain escape code for 256-color selection, but almost all terminals support 16-color using a different escape code (notably windows cmd.exe doesn't support ansi escape codes)
19:28TEttingerhttps://github.com/shabble/irssi-docs/wiki/Notes-256-Colour
19:29{blake}Can laziness "get" you in React? Like, if your rendering routine contains a map or for or whatevs, will that potentially not be realized without forcing it?
19:30{blake}'cause I got a situation where I'm changing the underlying data atom and it's not updating the screen.
19:31{blake}But the rendering function is being called.
19:32sdegutisWooo!
19:32{blake}Who?
19:32sdegutisJust replaced all our clj-aws-s3 usages with plain old aws-java-sdk Java stuff!
19:33sdegutisThat was one situation where using the Java-based SDK actually resulted in fewer lines of code than using the Clojure wrapper around it.
19:34TEttingerwow
19:34TEttingerclojure does have durn good interop
19:35sdegutisWell in this case it's mainly because of the design of the wrapper.
19:36TEttingeryeah, I just think it's nice that wrappers aren't always needed
19:37TEttingerand you can just use the java one "just like that"
19:37sdegutis:)
19:42TEttingerhm, just curious: is cfleming or any other cursive expert around? I'm not sure if I'm experiencing a bug
19:44TEttingerthis is my project.clj, very small, and cursive (but not lein) can't seem to see the deps. https://github.com/tommyettinger/squidlib-clj/blob/master/project.clj
19:44TEttingerlein runs just fine
19:54{blake}TEttinger: I have occasional problems with deps in cursive, also.
19:54{blake}Sometimes I just restart IJ.
20:11KamuelaI actually think cider and paredit are working with Emacs. I'm just not doing well with it yet
20:22TEttinger{blake}, hm, I've restarted at least 3 times
20:22{blake}TEttinger: I'm sorry, I didn't mean to imply that it actually worked, just that I did it. =P
20:23TEttingeroh haha
20:23TEttingerit's odd that there's no leiningen context menu like there is for maven and gradle
20:24{blake}Hey, did you "lein clean"?
20:24TEttingerhm, no
20:25{blake}I've been having to do that a ton lately. Not sure what evil I'm perpetuating.
20:26{blake}I'm thinking I don't have a handle on this whole react/reagent thing. My desire to set a defaultValue launches me into this whole world of "controlled components" where I'm now manually updating the app state.
20:26TEttingeralso my "External Libraries" in cursive just shows leiningen and Java 8
20:27{blake}TEttinger: Where is that? It's not "Libraries", right?
20:29TEttingernot sure. http://i.imgur.com/wDJ0pOm.png
20:30{blake}Oh, in the project navigator thingy.
20:30{blake}Yeah, that doesn't seem right at all.
20:30{blake}I get carpal tunnel trying to go trhough my External Libraries.
20:30TEttingerI agree
20:32TEttingerit's like it isn't really a clojure project
20:32{blake}Oh, could that be it?
20:32TEttingerno idea
20:33{blake}I've been using Cursive for so long, I haven't checked lately as to its project generation. I always do a "lein new" from the command line.
20:33TEttingerthere's no clojure facet I can add. I think I did lein new as well
20:33{blake}But trying to create a new Clojure project =inside= IJ has never worked out well for me.
20:34TEttingerI don't know how I made it, but I think it was "lein new"
20:35{blake}When I do that, I get the 1.8 JDK, clojure-complete, clojure 1.8 and nrepl, and that's it for exterinal libraries.
20:37TEttingeryeah, looks like that for me
20:38TEttingerhow do you add deps? does adding them to project.clj automatically pop those suggestions up in sources when it's working?
20:39{blake}TEttinger: Yes, eventually. Sometimes it's real smooth. Other times, not so much.
20:39{blake}Like I just added in clj.time, and it's not seeing that.
20:40TEttingerhm, ok
20:40{blake}Oh...I may also do a "lein deps" from the CL.
20:41{blake}But I don't think that's necessary any more.
20:42{blake}Be worthwhile to ask cfleming about: how deps get into the environment and what we're doing wrong.
20:42TEttingerit works in the repl in cursive but not in the editor, oddly
20:42{blake}Like, I just added clj-time and it didn't show up. I restarted twice, now it's in the REPL.
20:43{blake}I've seen that, too. I've gone cuckoo trying to figure out that one.
20:44{blake}I've got that now with my simple clj-time example. Works in REPL, editor doesn't see it.
20:49{blake}Yeah, I don't get this thing. I've got this atom with my app data in it. I've changed it, which triggers a redraw. "Controlled components" have onChange events which...change the data in the atom, which (it seems to me) would trigger the redraw again.
20:53TEttingerit's definitely odd
20:53TEttingerthanks for confirming that this is not isolated to my computer, {blake}
20:53TEttingeror my miiiiiind
20:54{blake}It's AAALLL in your MIIIIND!
20:55{blake}Yeah, love Cursive, but this is a weak spot.
20:57TEttingerI mean I'm trying to make a clojure wrapper for this java lib, and not being able to see the lib I'm wrapping is trouble
22:10sdegutisTIL you can't merely (import) a namespace you created containing a defprotocol, you have to (require) it first.
22:45rhg135Does that work with a non-aot definterface?