#clojure logs

2016-04-05

00:01tolstoyNot (str (System/getenv "HOME") java.io.File/separator ".stuff.edn"))? ;)
00:01tolstoy(str (System/getProperty "user.home") java.io.File/separator ".stuff.edn"))
00:02cwgem|macIf there's a Java way (like what appears to show up there) to get home I'd probably use that versus trying to work with raw environment variables
00:04sdegutisbbl
00:52user__man
00:52user__everytime
00:52user__nil, nil, nil
00:52user__args
00:53user__TEttinger, I'm havinga brain fart
00:53tolstoyMapping println over values?
00:56TEttingereh?
00:57TEttingeryeah tolstoy likely has it
00:57TEttingerprint returns nil
00:57TEttingersame with println, prn, pr, pprint
00:57TEttingerthere's pr-str
00:57TEttingerwhich returns a string version of what pr would print, but doesn't print on its own
00:57tolstoyThe other one is some version of (map (when test :val) ...).
00:57TEttinger,(pr-str (map inc [1 2 3]))
00:58clojurebot"(2 3 4)"
00:59user__TEttinger, tolstoy could be a print
00:59TEttingercwgem|mac: I think clojure may still have trouble with so-called "astral plane" values outside the Basic Multilingual Plane
00:59TEttingerlike emoji chars, cwgem|mac
00:59user__but my printing is also print nil
00:59user__I feel like I'm so close to getting Clojure
00:59user__i'm very new to lisp
00:59user__but learning fast
01:00cwgem|macTEttinger: Not too worried about emoji yet. Just need it to be able to handle CJK
01:00user__,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (count (:paths(nth listInput 1)))))
01:00clojurebot2
01:00TEttingerit seems like you're getting there. you understand that there's no "void" returns in Clojure, right user__?
01:00user__oh
01:00user__thats not it
01:00TEttingersomething like Java's
01:00user__TEttinger, i guess
01:00user__TEttinger, what if an empty function is used
01:01TEttinger,(.println System/out "yay")
01:01clojurebotnil
01:01TEttingerprint is wrapped specially in clojurebot
01:01TEttingerSystem.out in Java isn't normally used to print in clojure, so clojurebot just shows what it returns
01:01user__,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1)))0))
01:01clojurebot#error {\n :cause "Wrong number of args (1) passed to: core/nth"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/nth"\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" 32]\n [sandbox$eval97 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval97 invo...
01:01TEttingerah, that's dense
01:02TEttinger,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1))0)))
01:02clojurebot[:node 2 :cost 1]
01:02user__,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1))0)))
01:02clojurebot[:node 2 :cost 1]
01:02TEttingerheh
01:02user__beat me to it
01:02user__,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (:node(nth (:paths(nth listInput 1))0))))
01:02clojurebotnil
01:02user__there
01:02user__nil
01:02user__that freaking nil
01:02user__ugh
01:03TEttingeroh!
01:03user__,clojurebot, what is this wizardry?
01:03clojurebot#error {\n :cause "Unable to resolve symbol: clojurebot in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: clojurebot in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: clo...
01:03user__ok thanks
01:03TEttinger,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (nth (:paths(nth listInput 1))0))
01:03clojurebot[:node 2 :cost 1]
01:03TEttingerso that's what you are trying to call :node on
01:03user__yes
01:04TEttingerbut that isn't a map, it's a vector
01:04TEttingermaps use {}
01:04TEttingervectors use numbers for keys
01:04TEttingerlike arrays, but resizable
01:04TEttingerI suspect you had that as a map at some point
01:05user__oh
01:05TEttinger,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (:node(apply hash-map (nth (:paths(nth listInput 1))0)))))
01:05clojurebot2
01:05user__wow
01:06user__that was cool
01:06TEttingerthankfully, maps are really easy to make in clojure compared to Java
01:06user__you got the :node in there
01:06TEttingeryep!
01:06user__Yes, java maps are terrible
01:06user__way too messy
01:06user__java should possibly stick with linked list or arrays lol
01:07TEttingerClojure makes them a lot better, so even though they extend Java's Map interface and that means they aren't considered Collections (which is silly), Clojure lets you call seq on a hash-map or other map as a special case
01:07TEttingerand since seq works, map works (operating on key-value pairs)
01:08TEttingerand a lot of other stuff Just Works because of seq
01:10TEttinger,(map (fn [[k v]] (+ k v)) {1 10, 2 20, 3 30}) ;; the extra square brackets inside the fn arg vector mean it's "destructuring" the argument it gets, turning the two elements of a seq-like thing it's passed into two named values, k and v (corresponding to the key and value)
01:10clojurebot(11 22 33)
01:11TEttingerdestructuring also makes maps much easier to work with
01:11TEttingerin addition to other collections!
01:13user__interesting
01:13TEttingeruser__: next time you're stuck in a deeply nested piece of code like that, try removing the parts that are related to any errors you get. if you don't know, try removing outer calls that do things first (so not let, since you usually need the let in examples like you gave, but I removed the "(print (:node" part and the parens on the other side
01:14TEttingerso you can try removing layers like peeling an onion, seeing if you need them first
01:14user__TEttinger, Yes, i love this about Lisp
01:14user__TEttinger, Makes function tracing easy
01:15user__TEttinger, but i still need to get my head around sequences, vectors, maps, coll, and the rest
01:15user__i get vectors and maps now which is great
01:16user__I'm considering takingmy vector I had upon and changing the multiple vectors into a map
01:17user__or sorry, changing the key values inside to use a map, but i don't want it cluttered either.
01:21TEttingersure! that's a good idea
01:35user__,(let [listInput [{:paths [{:node 1}, {:cost 1}], [{:node 2}, {:cost 2}]]},{:paths [{:node 2}, {:cost 1}], [{:node 3}, {:cost 2}]},{:paths [{:node 0} {:cost 1}], [{:node 1} {:cost 2}]]}]] (print (:node(nth (:paths(nth listInput 1))0))))
01:35clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
01:36user__,(let [listInput [{:paths [[{:node 1}, {:cost 1}], [{:node 2}, {:cost 2}]]},{:paths [[{:node 2}, {:cost 1}], [{:node 3}, {:cost 2}]]},{:paths [[{:node 0} {:cost 1}], [{:node 1} {:cost 2}]]}]] (print (:node(nth (:paths(nth listInput 1))0))))
01:36clojurebotnil
01:36user__TEttinger,
01:38TEttingeroh!
01:38user__nil is happening again :9
01:38user__:(
01:38TEttingerI know why
01:40TEttinger,(let [listInput [{:paths [{:node 1, :cost 1}, {:node 2, :cost 2}]},{:paths [{:node 2, :cost 1}, {:node 3, :cost 2}]},{:paths [{:node 0, :cost 1}, {:node 1, :cost 2}]}]] (print (:node(nth (:paths(nth listInput 1))0))))
01:40clojurebot2
01:40TEttingeryou were converting individual pairs to maps
01:40TEttinger,(apply hash-map [[:a 1] [:b 2]])
01:40clojurebot{[:a 1] [:b 2]}
01:40TEttingerhm
01:41TEttinger,(into {} [[:a 1] [:b 2]])
01:41clojurebot{:a 1, :b 2}
01:41TEttingerthere we go
01:41TEttingerI changed it by hand in the data because it seemed easy enough (it took longer than I thought though!)
01:43user__ah
01:43user__it makes sense !
01:43user__A map carries multiple key value pairs
01:43user__aha!
01:43user__i got it
01:43user__thank you TEttinger
02:15wombawombaSo I want to run a small, profile-dependent piece of code when any lein task runs, that sets some state in my application. As far as I can tell, I would have to write a custom leiningen plugin to do this. Does anyone know of an easier way?
02:20tolstoyOne way is to use boot, which is much more scripty and imperative.
02:20tolstoyThere used to be a way to do hooks (robert hooke library).
02:21tolstoyWhat do you want the code to do?
02:27tolstoywombawomba: Here's something: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#hooks, but maybe a bash script might work better?
02:50dysfunor a makefile
03:01kwladykawombawomba but if you only set state in the app, so i guess for example another date to database you can do it in lein.
03:02wombawombasorry
03:02kwladyka?
03:03wombawombatolstoy: I want the code to set ips/ports for a bunch of hosts my project talks to
03:03kwladykawombawomba maybe you need just that https://github.com/weavejester/environ ?
03:04wombawombakwladyka: sorry, how do you mean about date to database? don't understand
03:04clojurebotHuh?
03:04kwladykawombawomba ok i didn't guess your intention
03:04wombawombaand yeah, I guess environ could work
03:05wombawombathanks
03:05wombawombaalthough, if I go with environ, I'd still have to make sure the init code is called for every target manually
03:06wombawombaeg I'd have to find some way to make my test runner call something like `(my-init-fn (env :profile))` before running any code
03:07kwladykafor tests use fixtures
03:07wombawombaI also have a bunch of aliases on the form run -m ... (essentially scripts), that would all have to call that code as well
03:08wombawombakwladyka: I want to be able to run the exact same tests against a number of different host/ip configurations
03:08wombawombabut only one at a time
03:08wombawombaI don't think fixtures are appropriate, really
03:08renlhi in manifold is there a way to check if a stream has to take! from?
03:08kwladykamaybe you need profiles in the project.clj ?
03:09wombawombakwladyka: yeah, that's what I'd like to do ideally
03:09kwladykawombawomba https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md
03:09wombawombaI would like to have a bunch of profile, where each profile calls `(my-init-fn :profile-name)` as a first step for any task
03:10wombawombakwladyka: afaict, there's no way to do that with profiles
03:10wombawombaI can do it for the repl, e.g. by setting :repl-options > :welcome
03:10wombawombabut I can't make sure it happens for my test runner, or for any of my `run -m ...` aliases
03:12kwladykalein with-profile foo test don't satisfy you? I am not sure what is your problem :)
03:12wombawombakwladyka: how do I get lein with-profile foo to run `(my-ns/my-init-fn :foo)` before the tests are run?
03:13kwladykawombawomba use fixtures
03:13wombawombaand how do I get `lein with-profile foo run` to run `(my-ns/my-init-fn :foo)` before it calls main?
03:13wombawombakwladyka: use fixtures how?
03:14kwladykawombawomba something like that http://stackoverflow.com/questions/16350504/clojure-how-to-use-fixtures-in-testing
03:14wombawombaright
03:14kwladykabut i guess you can find better examples
03:14wombawombabut how do I run a fixture depending on which profile is active?
03:15kwladykawombawomba you can use environ BTW and in fixtures read that value and depend on that value set something
03:16wombawombayeah, if I use environ I can make it work
03:16wombawombabut I still have to manually make sure the proper code is called for every lein task, which is troublesome
03:17wombawombaI'd have to 1. do this in every fixture, 2. do this for the repl, 3. do this in every main- function I have
03:18wombawombaI am wondering if there's a way to do it once, in one place, without having to solve the problem in a different way for every lein task
03:18kwladykai believe there is but don't solve everything at once time :)
03:19kwladykayou can use high priority functions or other solutions
03:19kwladykato solve 3
03:19kwladykaand also 1
03:20kwladyka2, i guess in the REPL you want start with clear enviroment
03:20kwladykaanyway maybe you solve your solution in bad way
03:21kwladykafor example maybe you should load different config files depend on profile, or depend your conf on the variable in the system like MY_VARIABLE_FOR_SETTING in the bash
03:22kwladykamany solutions are possible, but i don't know precisely your problem. You have to find your own way :)
03:22wombawomba:) okay
03:22wombawombaI think I'll try boot
03:24kwladykawombawomba try it, but i believe the problem is in solution design what you try to do.
03:24kwladyka(but i can be in mistake, because i don't know details)
03:25wombawombayeah, it's possible
07:16Glenjamindoes anyone else find it really hard to read (> x y) vs (< y x) ?
07:17ridcully> and < in prefix notation don't work well with my brain
07:18Glenjamini find < works ok, because you then write the arguments in ascending order
07:18MJB47i 100% of the time
07:18MJB47get them in the wrong order
07:18Glenjamini just did exactly that
07:18MJB47even if i know im going to get them in the wrong order, so purposely flip them around
07:18MJB47they will still be in the wrong order
07:21dmsnellGlenjamin: confused me until someone said "it's always the same, just move the operator for infix in between the arguments"
07:21dmsnell(< 4 5) => (4 < 5)
07:21dmsnell(> 5 4) => (5 > 4)
07:22ridcullyyeah, that's what i do. but it's basically the only operator i have such trouble with
07:22mrcnxsGlenjamin, so if y was greater than x would you write (< x y)? and if it wasnt you'd write (< y x)? and what if you didnt know what x or y was?
07:22Glenjamini still know what i want to do
07:22dmsnellI would argue that you should use whichever is closer to indicating what you want to infer in the code
07:23mrcnxsdmsnell, yeah thats usually how it works
07:23dmsnell(if (> x y) (biggerX) (notBiggerX))
07:27Glenjamini just think that visually `<` looks like it's describing a little funnel
07:27Glenjaminand `>` looks like it's pointing at some numbers
07:28mrcnxsjust think of < looks like L for less
07:28dmsnellGlenjamin: try (funnel 4 5) and (point-to-> 4 5) XD
07:28ridcullymaybe time to alias them with gt, lt, gte, ... ;_
07:29tdammersidk, I think < and > are bad names for variadic comparison functions, especially in prefix notation
07:29tdammersif you write a < b, it's obvious that you want the thing on the smaller end of the < to be smaller, but (< a b c) requires a mental leap
07:30KneivaWhat do I need to import to use predicates like 'in' and 'like' in Korma SQL?
07:30Glenjamin(def ascending? <)
07:31tdammersGlenjamin: yeah, except that (ascending? a b) also requires a mental leap when what you really want to express is "a is less than b"
07:35Glenjaminalso true
08:16sdegutisGood evening.
08:20Glenjaminmorning
08:20Glenjaminis there a variant of cond/condp where I can pass a single argument and a series of predicates?
08:22TimMcGlenjamin: condp, if your argument is #(% foo bar)
08:22Glenjaminoh of course, that'll do it
08:22TimMcor hmm, maybe that's not quite it...
08:22Glenjaminthanks
08:22Glenjamini get the gist
08:22TimMcI don't use condp very often.
08:23luma(condp #(%1 %2) expr pred-1 result-1 pred-2 result-2 ...)
08:23Glenjaminyup, thats the one
08:24lumathat'll evaluate (pred-1 expr), and if it's truthy, return result-1 etc
08:24Glenjaminmuch nicer: https://www.refheap.com/116924
08:24TimMcIf all of your predicates are unary that could be annoying.
08:24sdegutisGlenjamin: what does your desired code look lik-- oh
08:24TimMcah yeah, that works
08:24Glenjamini was using normal (cond), but i'd forgotten to include the `number` argument with the sets
08:24Glenjaminso it was always matching the second clause
08:24sdegutisGlenjamin: hmm it seems like there really ought to be a pre-made macro for that
08:25sdegutisive wanted that too
08:25sdegutis(condf) or something
08:25TimMcYou forgot :VR, vice-regent
08:25sdegutis(condf x, pos? :positive, neg? :negative, zero? nil, :else (throw))
08:26sdegutisjustin_smith, TimMc, TEttinger3: does something like my conf exist?
08:26sdegutis*condf
08:27ridcullyalso you could cheat with your 42 numbered card ;)
08:28Glenjaminthere's a (card) fn with some preconditions
08:29GlenjaminI'm prepping a functional version of http://buildingskills.itmaybeahack.com/book/oodesign-3.1/html/blackjack/details.html for a workshop at the local FP group
08:29hyPiRionsdegutis: (defmacro condf [& body] `(condp #(%1 %2) ~@body)) ?
08:29hyPiRionExcept you must omit :else
08:30sdegutishyPiRion: hmm sounds right, but it seems like such a useful thing that im surprised it doesnt already exist
08:31Glenjaminit would be possible to check for an odd number of arguments and generate :else I think
08:31hyPiRioncondp #(%1 %2) isn't that much longer than condf
08:31Glenjaminhttps://github.com/glenjamin/defshef-blackjack/blob/master/clojure/src/defshef/blackjack.clj if anyone is interested in the rest
08:31hyPiRionGlenjamin: condp already does that
08:31hyPiRion,(condp #(%1 %2) 2 odd? :odd :even)
08:31clojurebot:even
08:31Glenjaminaha
08:32Glenjaminoh i see what you mean about omitting now
08:32Glenjaminoh, that also means my :else is wrong
08:33sdegutis:)
08:35Glenjaminoh, heh - it works either way
08:35Glenjaminbecause the (throw) evals
08:35FenderHi guys, I'm working with emacs/cider and I currently have the problem that after some changes to the code and C-c C-k my code changes are compiled successfully but they are not seen by the nrepl server. There are no changes to var/ns names and no indirections apart form a #'handler indirection due to being a ring app. Does anyone experience something similar? and is it a cider or a clojure 1.8 problem (-> invokeStatic)
08:36Fendermy workflow now requires often a cider-restart and that's annoying
08:42sdegutisFender: im using clojure 1.8 and cider 11, and dont have that problem
08:42sdegutisFender: i think the reason i dont see the same problem you see is because i dont use vars (e.g. #'handler) but instead i re-build the handler from a function after cider-refresh
08:43cwgem|macAny folks toyed around with Clojure on Java 9 EA out of curiosity?
08:43Fenderto be honest, I am not entirely sure what cider-refresh does and for what it is useful (other than what the name suggests)
08:44sdegutisFender: it's basically just a wrapper around tools.namespace.repl.refresh or whatever its claled
08:44sdegutisFender: it re-evals all your changed files in dependency-order and then optinoally calls a function you tell it to
08:45sdegutisin my case, system-start
08:45Fendersounds like something I should be using in these cases
08:47FenderOK, I think I found something re the how and why: https://github.com/clojure/tools.namespace
08:47Fenderthanks already
08:48sdegutisFender: also read about stuartsierra's Reloadable Workflow
08:48sdegutisit inspired me to adjust my code to be more reloadable
08:48sdegutiswhich is hecka aweasome
08:48Fenderwhere everything is saved in a context map?
08:48FenderI know about it but I didn't yet need it
08:49Fenderwell, I think I need to catch up on that :)
08:54sdegutisFender: :)
08:54sdegutishi all
08:54sdegutishow do you interpolate strings into a regex?
08:54sdegutis,(let[foo"bar"]#"#{foo}")
08:54clojurebot#<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.util.regex.PatternSyntaxException>
08:55sdegutisoh, re-pattern
08:55sdegutis,(let[foo"bar"]#(re-pattern foo))
08:55clojurebot#object[sandbox$eval47$fn__48 0x34af2848 "sandbox$eval47$fn__48@34af2848"]
08:55sdegutis,(let[foo"bar"](re-pattern foo))
08:55clojurebot#"bar"
08:55sdegutisyay
09:24sdegutishey
10:19sdegutisHello?
10:19sdegutisHow do you use ring-mock along with sessions?
10:19sdegutisI'm having trouble
10:34Glenjaminsdegutis: peridot might help there
10:34Glenjaminit builds a concept of a session over ring-mock
10:34Glenjaminwith a cookie jar
10:34sdegutisGlenjamin: I remember using it a few years ago, but it looks since abandoned, and I remember having issues with it
10:35Glenjamini somehow inherited it. it doesn't change much now - only major issues i'm aware of are around multipart uploads
10:35sdegutisGit says I removed peridot on April 29, 2013.
10:36Glenjaminto get a session in ring-mock, you need to make a cookiejar object, parse set-cookie headers from responses and pass cookie headers into requests
10:37sdegutisGlenjamin: which seems also to be what https://github.com/rreas/ring-test does
10:37sdegutisGlenjamin: see also https://github.com/rreas/ring-test/blob/master/src/ring_test/core.clj
10:38sdegutisGlenjamin: looking at our git history, peridot was very similar to webrat/capybara in its api, for better or worse, whereas ring-test is a lot simpler
10:40Glenjaminyeah, peridot is intended to flow between requests, and mostly exists for kerodon
10:47sdegutisGlenjamin: never mind yeah i was remembering kerodon mostly
10:56Glenjaminslightly off-topic, but does anyone know if there's a simple Haskell testing framework that's as easy to use as the tests in here: https://github.com/glenjamin/defshef-blackjack/blob/master/clojure/src/defshef/blackjack.clj
11:09jjmalinaanyone recommend some resources for getting around the limitation of tail call recursion? like what if you need two different recursive calls?
11:10arrdemjjmalina: if you really need unbounded mutual recursion trampoline is typically what you'll use.
11:10jjmalinaarrdem what do you mean by "unbounded mutual recursion"?
11:11arrdemjjmalina: if you have two fns which you want to mutually recur as if they had been tco rewritten into a goto block, you've got to use trampoline.
11:11jjmalinatrampoline could work i suppose, just adds more complexity
11:11jjmalinain this case i am calling the same function, just with different arguments
11:12arrdemIf it's a tail call you can just use recur
11:12arrdemSorry. A tail call of the same arity.
11:12arrdemIf you have to cross arities, you have to do a fn invocation.
11:13jjmalinabasically it's a tree traversal
11:14jjmalinaone recursive call goes left the other goes right, but then both results have to be handled
11:20arrdemUntil you know you have to do something more advanced I'd suggest simply let binding the results of simple recursive calls.
11:21sdegutisHi?
11:52sdegutisoh right, yeah
11:52sdegutishi
13:20someone1hi
13:24ben_vulpeshello!
13:25someone1is there a rails like web framework for clojure? also with clojurescript support. I want to use datomic
13:26ben_vulpesnope.
13:26someone1I tried to use jruby mixed with clojure and clojurescript in the rails asset pipeline ... but it is not that good
13:43Lewixhttps://github.com/6ewis/recruitersPickupLines/blob/master/bestLines.md contribute for the laugh
13:48tolstoyIs there a way to specific a list as a p/schema type, rather than vector or map?
13:53tolstoyI have a DSL-ish thing: (foo bar [:some "data"]) and want to validate that foo == foo and bar is a symbol, but the whole thing is in a list. Hm. Maybe convert to vector before calling validate?
13:55amalloyi would be surprised if validate cared about the difference between vectors and lists
13:56tolstoyI think you're right. I'm getting some other error I don't understand regardless.
13:57tolstoyLike, you know, using defn where I should be using def.
14:51backnforthSo Eclipses ide works with Clojure? Can I use it to get variables values at a breakpoint?
14:54aneI don't think it has debugging
14:54anecursive or cider can do debugging
14:59backnforthit does with java
15:12backnforthcan i retrieve variable values at a breakpoint with cider?
15:15bendlasdnolen: hi, we're here at the vienna om.next meetup. we are working with the todomvc demo and try to complete it
15:16dnolen@bendlas: ok might be a slightly tricky, also I haven't really looked at it in a very long time.
15:16bendlasdnolen: we were wondering, how we were supposed to trigger rerenders asynchronously in the reconciler
15:17dnolenbendlas: I don't really understand that question
15:17bendlasdnolen: there seems to be a mismatch with {:value {:keys [:foo]}} vs {:value [:foo]}
15:17dnolenwhat's there does demo basic async calls & render
15:18bendlaswe're trying to implement creation and it's already working, but the ui doesn't rerender
15:18dnolenbendlas: I think this is a typical misunderstanding
15:18dnolen{:values {:keys ...}}
15:18dnolendoesn't have a real meaning - it's just for humans
15:18dnolenthe only thing that triggers re-renderings are explicit re-reads
15:18dnolen[(change/it!) :foo :bar]
15:19bendlasright, we tried that, but doesn't work
15:19dnolencomponents that depend on :foo and :bar will render when you run this query expression
15:19bendlas b/c ui rerenders before server returns
15:19dnolenbendlas: well you need to be specific about whether that query is needed both locally and remotely
15:20dnolenthat is you can make it run twice
15:20dnolenbendlas: a better place to ask this question is in the Om Slack channel, lots of people there who can help this bit
15:21bendlasok, so to rerun it on the client after the server returns (that was my question about async rerender), we would call merge! ?
15:22dnolenbendlas: I dont' think so, all there's a bunch of simple defaults in place to avoid having to customize really basic stuff
15:22dnolenbendlas: sorry I can't say much more at the moment, busy with some other stuff
15:22bendlasya, sorry, don't want to keep you
15:23bendlasom.nnext? ;-)
15:38kwladykahmm agents run function 1 time, atoms can run many times during conflict. Why not just always use agents?
15:44rhg135agents use a thread pool
15:49kwladykaagent make new thread, atom operate on same shared state in the thread where is called
15:50kwladyka?
15:50kwladykabut still not sure why use atoms over agents when generally everybody want run functions 1 time
15:51amalloythere are lots of things you generally want
15:51amalloyeg, you generally want functions run at a particular time
15:52amalloywhich is not a feature agents offer
15:54kwladykaamalloy so it is the choice between run functions many times but immediately and one but don't know when?
15:55kwladykastill i can't imagine when atom is over agent? If i have to run something immediately for example to third part software i can just run that without atom. What i want to use with atom with danger of running it many times?
15:58kwladykaEven idempotent function, why run they many times if can be run once? Running them many times don't have anything.
16:05dysfunbecause it results in higher throughput on average
16:06kwladykadysfun ok that is the argument
16:09kwladykathx
17:26Lewisstupid question
17:26Lewis,`(1 2 3 4)
17:26clojurebot(1 2 3 4)
17:27Lewis,'(1 2 3 4)
17:27clojurebot(1 2 3 4)
17:27Lewis(= `(1 2 3 4) '(1 2 3 4))
17:27Lewis,(= `(1 2 3 4) '(1 2 3 4))
17:27clojurebottrue
17:27Lewis,(class `(1 2 3 4) )
17:27clojurebotclojure.lang.Cons
17:28Lewis,(class '(1 2 3 4) )
17:28clojurebotclojure.lang.PersistentList
17:28TimMcLewis: Correct. :-)
17:28Lewiswhats the difference between cons and persistentList?
17:29TimMc,(ancestors (class `(1 2 3 4)))
17:29clojurebot#{clojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq java.lang.Iterable ...}
17:29TimMchrmf
17:29TimMc,(apply println (ancestors (class `(1 2 3 4))))
17:29clojurebotclojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq java.lang.Iterable clojure.lang.IHashEq clojure.lang.Obj java.io.Serializable java.util.Collection clojure.lang.Seqable java.util.List clojure.lang.ISeq clojure.lang.IPersistentCollection java.lang.Object\n
17:30TimMc,(apply println (ancestors (class '(1 2 3 4))))
17:30clojurebotclojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq clojure.lang.Counted java.lang.Iterable clojure.lang.IHashEq clojure.lang.Obj java.io.Serializable java.util.Collection clojure.lang.Seqable clojure.lang.IReduceInit java.util.List clojure.lang.ISeq clojure.lang.IPersistentCollection clojure.lang.IPersistentList java.lang.Object clojure.lang.IReduce clojure.lang.IPersis...
17:32TimMcLewis: Anyway, to answer your question... not a whole lot. :-)
17:33TimMcThey're both sequential, serially accessed data structures.
17:34TimMcCons is a seq, whereas PersistentList is a list, and the difference is kinda subtle to nonexistent.
17:40LewisTimMc: in other words, you dont know the diff either?
17:41TimMcLewis: I can tell a story about what I think the difference is, but I don't think there's an official explanation.
18:02wombawombawhat's the best library for doing http requests in cljs these days?
18:05arrdemwombawomba: clj-http still works just fine
18:05arrdemwombawomba: if you need async the choice is less obvious
18:05wombawombaasync would be nice
18:06arrdemhttp-kit is probably more your speed then.
18:06wombawombahmm
18:06wombawombanotw I wrote cljs
18:07bsimawombawomba: I think cljs-http is the equivalent https://github.com/r0man/cljs-http
18:10wombawombaokay
18:31backnforthHow do I do a hot reload of my Clojure code when using the repl?
18:37Glenjaminanyone know how to go from 0x1F0A0 to the character at that unicode code point?
18:38TEttingerbacknforth: there's a :reload additional argument that can be passed to require
18:38TEttingerGlenjamin: that's going to be tricky since that's really two chars
18:38TEttinger,(Character. 0x1F0A0) ; just curious, not sure if this works
18:39clojurebot#error {\n :cause "java.lang.Long cannot be cast to java.lang.Character"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to java.lang.Character"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" -1]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.jav...
18:40Glenjaminoh good, the docs for Character have a brief discussion about how terrible a choice UTF-16 was
18:41Glenjaminwith no hint of an alternative
18:41justin_smithbacknforth: another options is load-file, especially useful when you want to load code from a local copy of a file (eg. if really you loaded from a jar, but want to redefine some of the code from a copy of the file from the jar)
18:42Glenjaminhrm, actually in my case the first byte doesn't need to change
18:44justin_smithbacknforth: also, environments like CIDER or fireplace should have a keystroke to send the current function or file to the repl (and this will use load-file under the hood)
18:46backnforthjustin_smith, interesting
18:46backnforthjustin_smith, I haven't gotten around to installing vim-cider yet
18:46backnforthjustin_smith, only vim-fireplace
18:50Deraenbacknforth: Fireplace includes the functionality to reload namespaces (cpr) and evaluate forms (cpp, cp<motion>).
18:52Glenjamin,(Character/toChars 0x1F0A0)
18:52clojurebot#object["[C" 0x9c32307 "[C@9c32307"]
18:52Glenjaminnow how do I turn a primitive character array into a string?
18:53Glenjaminoh, duh
18:53Glenjamin,(String. (Character/toChars 0x1F0A0))
18:53clojurebot"🂠"
18:53Glenjamin,(String. (Character/toChars (inc 0x1F0A0)))
18:53clojurebot"🂡"
19:28backnforthIs it ok to have a "let" function inside of a loop? I keep getting a NullPointerException because of it. I have done much debugging and the error is coming from the viable value I'm trying to assign with.
19:29Glenjaminbacknforth: can you post some code? (via a pastebin of some sort)
19:31backnforthGlenjamin, certainly
19:36backnforthhttp://pastebin.com/GA0cf55H
19:36backnforthGlenjamin, The error happens at the first let on the second iteration of the loop
19:37Glenjaminyou're trying to access some of those vectors as if they were maps
19:40backnforthGlenjamin, It accesses work outside of the let
19:41backnforthGlenjamin, And it should work because the vectors hold maps
19:41Glenjaminit's hard to follow what's going on, i'd suggest breaking it up into a series of smaller functions so you can check those bits independently
19:42Glenjaminbut for example, you do (:paths tempVector)
19:42Glenjaminbut tempVector is a vector, so that'l always be nil
19:43backnforthGlenjamin, Ah. How could I go about simply making it a map?
19:44backnforthGlenjamin, {} yes
19:44Glenjaminyes
19:44Glenjaminit's really hard to follow this function, i think mostly because it's operating at a bunch of different levels of abstraction
19:45Glenjaminhere's more detail on what I mean by that: http://principles-wiki.net/principles:single_level_of_abstraction
19:45amalloyregularization of whitespace would help a lot too
19:47backnforthinteresting, thank you
19:48backnforthGlenjamin, Weird. Now I'm getting an error at my first recur
19:48backnforthSaying I can only recur from tail possition
19:49backnforthI know recur can work with cond, but about if/else inside of a cond?
19:58backnforthGlenjamin, nvm, that was my fault for having a bad brace
20:51bsimaDoes anyone know much about core.match internals?
20:51bsimaI could use some help improving this https://gist.github.com/bsima/f48eeb3d4531be1408287727016beb2a
20:51bsimasee the tests on line 34. I'm pretty stumped about how to fix it
21:36cespareIs there a faster way to create an empty transient vector than (transient []) ? The cloning of the empty vector seems to be using a lot of cpu in a profile
21:37justin_smithcespare: transient shouldn't by cloning anything - all it needs to do is set a bit
21:37justin_smithunless I'm totally misremembering how transients work
21:38dmacjustin_smith: I'm working on this with cespare; this is the expensive line that's showing up in our profile: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L547
21:38dmacjustin_smith: specifically the .clone()
21:39cesparejustin_smith: well, if you do (transient foo), then foo needs to remain undisturbed by whatever mutate-y stuff you do with the transient, yes?
21:42justin_smithtransient calls asTransient https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L3209 which then calls transientvector's constructor https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L133 and all that does is flip some bits https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L523
21:42justin_smithcespare: oh, wait, the editableRoot and editableTail methods do clone an array - not the whole vector, but one node
21:43justin_smithwhich dmac linked while I was source digging, heh
22:51Lewisjustin_smith: how do you guys think in terms of recursion day in and day out
22:52Lewishttps://gist.github.com/6ewis/4e280967cf6f33aed05463f3e4ec41ab this piece of code give me headaches
22:52justin_smithLewis: you should almost always use cond instead of nested if
22:52justin_smithand you should use recur instead of that self call
22:52Lewisjustin_smith: thats not my code
22:53justin_smithoh, I had no way of knowing that
22:53Lewisjustin_smith: my solution is actually a one liner
22:53Lewis#(= (seq %) (reverse %))
22:54Lewisjustin_smith: i was looking at somebody else solution and I was flabbergasted by the fact that it made sense to him
22:54Lewisjustin_smith: is it me or this code is overly complex and hard to follow
22:54justin_smithit's a direct translation of how you would write it in C
22:54Lewisi still dont get it but i get the idea
22:55Lewisreally
22:55justin_smithcomplete with the annoying trailing braces
22:56Lewisjustin_smith: ok ill have to study it
22:57Lewis,(doc butlast)
22:57clojurebot"([coll]); Return a seq of all but the last item in coll, in linear time"
22:57justin_smithoh, I guess that part isn't like c, heh
23:11amalloywell, in C you'd simulate rest/butlast with start/end pointers
23:13amalloyincidentally that function is much simpler with no ifs at all: (defn palindrome? [xs] (or (not (next xs)) (and (= (first xs) (last xs)) (palindrome? (butlast (next xs))))))
23:22Lewisamalloy: wow any suggestion on how to make the it easier on the mental load?
23:23amalloypractice, like anything
23:23amalloydo exercises if that helps
23:27Lewisamalloy: i meant the recursion stuff
23:27amalloyyep
23:27amalloypractice
23:27Lewislike your example and the gist i gave
23:27amalloyuh huh
23:27amalloypractice writing and reading recursive functions
23:27amalloythat's it
23:27amalloyno silver bullets
23:32Lewisamalloy: ok im on it
23:48Lewisamalloy: ahhh its pretty easy now
23:48Lewisim black belt in recursion :p
23:53Lewisamalloy: your solution is even more complicated
23:53Lewissheesh
23:53amalloyit is literally less complicated: it replaces (if foo true bar) with (or foo bar)
23:54amalloyand likewise (if foo false bar) => (and foo bar)
23:54Lewis,(doc and)
23:54clojurebot"([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true."
23:54Lewis,(and 1 2 3 4 5 false 3)
23:54clojurebotfalse
23:55Lewis,(and 1 2 3 4 5 3)
23:55clojurebot3
23:55Lewis,(doc or)
23:55clojurebot"([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil."
23:56Lewis,(or 1 2 3 4 5 true 4)
23:56clojurebot1
23:56Lewis,(or false nil 3)
23:56clojurebot3
23:57Lewisamalloy: that's so misleading, i expect or to be || and and to be AND
23:57Lewis&&
23:58amalloyokay, and...it is
23:58amalloynot sure how you are misleading yourself here