#clojure logs

2015-05-31

00:00dumptruckmanbut that would only do one of the players right?
00:00dumptruckman(that would work for now)
00:01dumptruckmandefinitely a lot more readable that way
00:01justin_smithdumptruckman: what I am saying is that if (-> entities :players first :segments) works, then (mapcat :segments (:players entities)) and (apply concat (for [player (:players entities)] (:segments player))) would too
00:01dumptruckmanah
00:02dumptruckmanNPE
00:02dumptruckman:D
00:02justin_smithI still say the mapcat version is clearest (it does the same as the one using for)
00:02dumptruckmanthat's my first NPE in clojure
00:02justin_smithdumptruckman: what gave you an npe?
00:02justin_smith,(-> nil first :key)
00:02clojurebotnil
00:03dumptruckmanmaybe one too many sets of parens
00:03dumptruckmanyep
00:03justin_smith,(-> nil :players first :segments)
00:03clojurebotnil
00:03dumptruckman,((-> nil :players first :segments))
00:03clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [sandbox$eval73 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval73 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [clojure.core$eval invoke "core.clj" 3079]\n [clojure.core$eval51$fn__52$fn__62 invoke "NO_SOUR...
00:03justin_smithyup, that would do it
00:05dumptruckmanhuh
00:05dumptruckman(-> entities :players first :segments) produces nil
00:05justin_smithso your data doesn't have the shape you expect
00:05justin_smithI would bisect it
00:06dumptruckmanright
00:06dumptruckmanbisect?
00:06justin_smith(-> entities :players)
00:06dumptruckmanseeing if entities even has anything
00:06justin_smithmove left if you don't see what you expect, move right if you do
00:06justin_smithright
00:06dumptruckmanokay, entities has what is expected
00:06dumptruckmanooh
00:07dumptruckmanit's not a map...
00:07justin_smithdumptruckman: the idea being if you have -> and the end isn't what you expect, you can split it in the middle, then remove or add until you see the anomoly
00:07dumptruckmanit's a vector with single element which is my map
00:07dumptruckmanthis library must be wrapping that
00:07justin_smithyeah, that would explain your error
00:07justin_smithI tend to jump to the (-> foo :bar :baz ...) form in the repl, because it makes finding out the real shape of the data very easy
00:08dumptruckmani am seeing that
00:08dumptruckman(i'm very new to clojure)
00:08dumptruckmanbeen wanting to play with it for quite some time... finally jumping into a project
00:08dumptruckmanonly really done koans before
00:09justin_smithcool
00:09justin_smithhow are you finding it so far?
00:09dumptruckmanhmm
00:09dumptruckman(-> entities first :players first :segments)
00:09dumptruckmanwouldn't that get the first element of entities?
00:09justin_smithwell it would give you the :segments from the first of :players if it was a nested thing
00:10dumptruckmani meant
00:10dumptruckman(-> entities first)
00:10dumptruckmanis the same as (first entities)
00:10dumptruckmanright?
00:10justin_smithright
00:10dumptruckmani am enjoying it
00:10dumptruckmanexcept
00:10dumptruckmanfor a lack of refactoring
00:11dumptruckmani love how elegant many of my solutions end up being
00:11dumptruckmancompared to what they'd have looked like in java
00:12dumptruckmanwoah
00:12dumptruckmanthe first thing in entities is not what i expected O.o
00:13dumptruckmansomehow
00:13dumptruckmanthe first thing in entites is EXACTLY the thing i'm looking for
00:13justin_smithdumptruckman: it might help you to look up how component entity systems work (I assume this is what you are using here)
00:14dumptruckmannah
00:14dumptruckmanthis is play-clj
00:14dumptruckmanthe weirder thing is
00:14justin_smithI think play-clj is a CES
00:14dumptruckmanit's not
00:15dumptruckmanit uses a kind of odd "entity system"
00:15dumptruckmanin that
00:15dumptruckmanall the main functions pass around this entity array
00:15dumptruckmanbut i'm basically trying to force my entire game state into that array
00:15justin_smiththat's the functional programming version of CES isn't it/
00:15dumptruckmanno
00:15dumptruckmani'm familiar with CES
00:15dumptruckmanand this isn't that
00:15justin_smithOK
00:16dumptruckmanthere's another lib called Ripple that merges play-clj and brute (an ECS)
00:16dumptruckmanplay-clj just has a kind of restrictive way of doing things
00:17dumptruckmanso you kind of have to do some weird workarounds like i'm doing.... i'm just trying to hammer down that workaround
00:19justin_smithdumptruckman: so what specifically does play-clj do that disqualifies it from being an ECS?
00:20dumptruckmanhttp://pastie.org/10215828
00:20dumptruckmanwell
00:20dumptruckmanit doesn't have components or systems
00:20dumptruckmani guess it kind of has components
00:20dumptruckmanbut really doesn't have systems
00:20dumptruckmanactually no
00:20dumptruckmandoesn't have components
00:21dumptruckmanso yeah
00:21justin_smithwait, why is it that when you print the first of the entities, it shows the :segments from the first of the :players in entities
00:21dumptruckmanthat's what i want to know
00:21dumptruckmanit doesn't make sense
00:22dumptruckmanit's like it's skipping the top layer
00:23dumptruckmanok weird
00:23dumptruckmansomething changes between those outputs
00:23dumptruckmanbut i don't know what..
00:24justin_smithdumptruckman: you said array before, if you actually meant that, arrays are mutable.
00:24justin_smithif you meant vector then yeah, something else is going on
00:24dumptruckmanvector, sorry
00:25dumptruckmanwell, i got those outputs from different runs
00:25justin_smithyour results would likely make much more sense in a single run
00:25dumptruckmanusing both printlns in the same run explains why (first entities) shows what it does
00:25dumptruckmanwell... it doesn't explain it entirely because
00:26dumptruckmanoh wait
00:26dumptruckmanthe (println entities) i pasted came from another part of the code.... so play-clj appears to be extracting what i'm trying to get at
00:27dumptruckmani don't know how or why it'd do that
00:28dumptruckmanor not
00:29dumptruckmanohh...
00:29dumptruckmani was returning the modified entities vector that i was trying to get in the render function
00:30dumptruckmanand i think play-clj was passing that modified one back to the render function
00:30dumptruckmanso the very first run would've looked different
00:30justin_smithright, the general pattern in functional code is that instead of mutating something, you return the updated version
00:31dumptruckmanright but my render function shouldn't be be returning a modified version
00:33dumptruckmanokay so
00:33dumptruckman(-> entities first :players first :segments) gives me what i'm looking for
00:33justin_smithso in that case your initial for/concat would work
00:33justin_smithas would my proposed mapcat alternative
00:34dumptruckmanor
00:34dumptruckman(mapcat :segments (:players (first entities)))
00:34dumptruckmanthat would be what i want
00:34justin_smithahh there is that difference yeah
00:34justin_smithforgot entities was a vector with the map inside
00:34dumptruckmanthe only problem is it's not rendering my shapes ;)
00:35dumptruckmani think it's probably because it's not a vector of shapes
00:35dumptruckmanand is instead a vector of maps
00:35dumptruckmanso i need to extract the shape from each of those maps
00:35justin_smithahh - for has a feature for this
00:36dumptruckmanwouldn't it just be
00:36dumptruckman(mapcat :shape (mapcat :segments (:players (first entities))))
00:37justin_smith,(for [p (:e {:e [{:s [1 2]} {:s [3 4]} s (:s p)] s)
00:37clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
00:37justin_smith,(for [p (:e {:e [{:s [1 2]} {:s [3 4]}]} s (:s p)] s)
00:37clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
00:38justin_smith,(for [p (:e {:e [{:s [1 2]} {:s [3 4]}]}) s (:s p)] s)
00:38clojurebot(1 2 3 4)
00:38justin_smithno need for concats!
00:38dumptruckmanhmm
00:38justin_smithit's actually readable if you put each binding in the for on it's own line, as you would in a let
00:40dumptruckmani can't parse that
00:40dumptruckmanso
00:40justin_smithdumptruckman: the idea is that for accepts nested bindings
00:40justin_smithI'll give the easer to read version
00:40dumptruckmanthe value for :shape in my :segment is #play_clj.entities.ShapeEntity{:object #<ShapeRenderer com.badlogic.gdx.graphics.glutils.ShapeRenderer@7471a313>, :draw! #<core$create_segment$fn__212 snake_clj.core$create_segment$fn__212@173fcf2e>, :type #<ShapeType Filled>}
00:41justin_smith,(def ent {:e [{:s [1 2]} {:s [3 4]})
00:41clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
00:41dumptruckmanbut when i do
00:41dumptruckman(mapcat :shape (mapcat :segments (:players (first entities))))
00:41justin_smith,(def ent {:e [{:s [1 2]} {:s [3 4]}]})
00:41clojurebot#'sandbox/ent
00:41dumptruckmanit merges everything inside that map
00:42dumptruckmanand doesn't include the map
00:42justin_smith,(for [p (:e ent) s (:s p)] s)
00:42clojurebot(1 2 3 4)
00:43dumptruckmanso
00:43dumptruckmanthe binding in for
00:44dumptruckmanallows referencing previous bindings
00:44justin_smithright
00:44justin_smithand each one is recursively expanded
00:44justin_smithin a way that can effectively be a concat at each level
00:44dumptruckmanand the return value of the for loop
00:44dumptruckmanis a concat
00:44justin_smithnot a loop, comprehension
00:44dumptruckman?
00:44justin_smithbut effectively, yes
00:45justin_smithbut it can do more than that, this is just a subset of what it can do
00:48dumptruckmanha
00:48dumptruckmanyes, i think that might have worked
00:49dumptruckman(let [snakes (for [player (:players (first entities)) segment (:segments player)] (:shape segment))] (render! screen snakes))
00:49dumptruckmanit works
00:49dumptruckman:D
00:50dumptruckmani don't really understand why mapcat made it all screwy
00:54justin_smithyeah, if that for comprehension works, the nested mapcat should too, but I think the for is better (as long as it isn't a one liner)
00:58dumptruckmanwell
00:58dumptruckmanthe different was
00:58dumptruckmanwith for i get (#Thing{shape-stuff} #Thing{shape-stuff})
00:58dumptruckmanwith the map cat i got
00:59dumptruckman(shape-stuff shape-stuff)
01:17dumptruckmandealing with collections in clojure takes some getting use to
01:31dumptruckmanhow can i check a map's values for a particular value and return the key associated with that value?
01:32dumptruckmanbasically i want to use a map backwards >.>
01:35TEttingerdumptruckman, this actually is surprisingly common
01:35TEttingerbut map values aren't guaranteed to be unique
01:35dumptruckmanof course
01:36dumptruckmani know they will be in this case
01:37TEttinger,(let [m {:a 1 :b 3 :c 2}] (into {} (interleave (vals m) (keys m))))
01:37clojurebot#error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 42]\n [cloju...
01:37TEttingereh?
01:37TEttinger,(let [m {:a 1 :b 3 :c 2}] (apply hash-map (interleave (vals m) (keys m))))
01:37clojurebot{1 :a, 3 :b, 2 :c}
01:37TEttingerthat gets a reverse map
01:38TEttingerthere's a lot of ways to do this
01:38gws,(clojure.set/map-invert {:a 1 :b 2 :c 3})
01:38clojurebot#error {\n :cause "clojure.set"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.set"\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.net.URL...
01:38TEttinger,(let [m {:a 1 :b 3 :c 2} target 3] (filter #(= (val %) target) m))
01:38clojurebot([:b 3])
01:39TEttingerwhich also works for duplicates
01:39TEttinger,(let [m {:a 3 :b 3 :c 2} target 3] (filter #(= (val %) target) m))
01:39clojurebot([:a 3] [:b 3])
01:39TEttinger,(require 'clojure.set)
01:39clojurebotnil
01:40TEttinger,(clojure.set/map-invert {:a 1 :b 2 :c 3})
01:40clojurebot{1 :a, 2 :b, 3 :c}
01:40TEttingernice, gws
01:40TEttinger(inc gws)
01:40lazybot⇒ 7
01:40TEttinger,(clojure.set/map-invert {:a 3 :b 2 :c 3})
01:40clojurebot{3 :c, 2 :b}
01:40TEttingervery nice
01:41gwsyeah even though it has nothing to do with sets so it's a little counterintuitive haha
01:42mercwithamouthpee
01:42mercwithamouthpeep* geeze
01:43brainproxywell hash-map literals do throw when encountering dup keys
01:43brainproxythough (hash-map ...) doesn't
01:44brainproxyso i guess in a certain sense a literal hash-map represents a set of keys
01:45TEttingeralthough ##(keys {:a 1 :b 2}) will be a vector, oddly, because sets aren't ordered
01:45lazybot⇒ (:b :a)
01:45TEttingerwell, seq
01:47brainproxythere's flatland/ordered :-)
01:47gwsmakes sense
01:47brainproxybut yeah, stock sets aren't ordered
01:52TEttingerbrainproxy, yeah, I do pretty strongly feel like not having the ordering data in maps and sets by default, even as metadata, is kinda a flaw
01:52TEttingerit might be a property of HAMTs that prevents it though
01:53brainproxyTEttinger: ah interesting, hadn't considered that
01:53TEttingermetadata or HAMTs?
01:53brainproxyHAMTs
01:53justin_smith,(clojure.set/invert (hash-map Double/NaN Double/NaN Double/NaN Double/NaN))
01:53clojurebot#error {\n :cause "clojure.set"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.set"\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.net.URL...
01:53TEttingeryeah they aren't by default ordered, since the whole hash thing
01:53justin_smithhmm
01:53TEttingeroh justin_smith
01:54justin_smith,(require 'clojure.set)
01:54clojurebotnil
01:54justin_smith,(clojure.set/invert (hash-map Double/NaN Double/NaN Double/NaN Double/NaN))
01:54clojurebot#error {\n :cause "No such var: clojure.set/invert"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such var: clojure.set/invert, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "No such var: clojure.set/invert"\n :at [clojure.lang.Util runtimeExce...
01:54TEttinger,(clojure.set/map-invert (hash-map Double/NaN Double/NaN Double/NaN Double/NaN))
01:54clojurebot{NaN NaN, NaN NaN}
01:54TEttingerhaha
01:54justin_smithahh
01:55TEttinger,(get (clojure.set/map-invert (hash-map Double/NaN Double/NaN Double/NaN Double/NaN)) Double/NaN)
01:55clojurebotnil
01:55TEttingerheh
01:56brainproxyI've only encountered a few situations that actually depend on ordered sets, per se
01:58TEttingerthe main thing I'm going to be doing is a bit odd, and it's partly why I'm making my own language instead of extending an existing one
01:58brainproxydo tell :-)
01:58TEttingerbut it kinda depends on having consistent ways to go between sequences
01:59TEttingerthe idea is to have, effectively, "first-class keysets" or in another way of looking at it, separating data from how it is accessed.
02:00TEttingerChapel, an obscure language made by Cray recently, has this and calls it Domains
02:00TEttingerthis means I can have one underlying seq type, like clojure seqs
02:01TEttingerbut you can access that seq as a 1d array if you have a 1d array-like domain (enforcing a limit on the length, like an array, and optionally starting at a non-0 index)
02:02TEttingeryou can access it as a hashmap, where the domain is a series of ordered unique keys, and it looks up the corresponding element by order
02:02TEttingeror a 2d array
02:02TEttinger(2 keys)
02:02brainproxyinteresting
02:02TEttingeror weirder domains, like ones that have special behavior if a key is not found
02:03TEttinger(interpolating between nearby keys')
02:03TEttinger(interpolating between nearby keys' values, for instance)
02:03brainproxysounds like it would conceptually apply some topology concepts to data structures, maybe?
02:03TEttingerit's a logical extension on the seq abstraction
02:03TEttingeryes
02:03TEttingerI know nothing about topology though
02:04brainproxydoes it have anything to do with cobordisms?
02:04TEttingerkobolds?
02:04brainproxyhttp://en.wikipedia.org/wiki/Cobordism
02:05brainproxysearch for a pdf paper titled "Physics, Topology, Logic and Computation: A Rosetta Stone"
02:07TEttingerthat article makes no sense to me
02:07TEttingerI mean I could probably generate random word sequences that would make more sense to me
02:08brainproxyokay, nvm, was just curious, I'm not sure I really understand it either :-)
02:09TEttingerthen again, wikipedia often is more complex than it needs to be
02:10TEttingerhttps://en.wikipedia.org/wiki/Low-discrepancy_sequence
02:10TEttingerthis makes it sound outrageously complex
02:10TEttingerreally it's just a deterministic sequence that has random-number-sequence-like properties
02:11TEttingerlike this is a good one https://en.wikipedia.org/wiki/Low-discrepancy_sequence#/media/File:Halton_sequence_2D.svg
02:12TEttingerthat looks close to random, right? if the points popped out one at a time, you wouldn't notice that they aren't near each other
02:12brainproxyright
02:12TEttingerbut it's generated by a pretty simple thing involving decimals in a different base
02:13TEttingerhttps://en.wikipedia.org/wiki/Halton_sequence
02:13TEttingeror rather, fractions would also work
02:14wasamasawoah: http://devmag.org.za/2009/05/03/poisson-disk-sampling/
02:15wasamasathis also makes for nice results
02:15wasamasafound it in the citations of the low-discrepancy sequence article
02:15TEttingerso the 3,5 halton sequence is a 2d sequence, where the x axis is drawn from the sequence of (1/3, 2/3, 1/9, 4/9, 7/9, 2/9, 5/9...) and the y-axis is drawn from (1/5, 2/5, 3/5, 4/5, 1/25, 6/25, 11/25...)
02:16TEttingerand that's really it
02:16TEttingerit looks random but it totally isn't
02:17TEttingerit's interesting how most "classic" libraries on subrandom sequences don't touch poisson disk sampling, but they're used pretty heavily in some games, apparently
02:19wasamasamust be that it matches one mistake humans keep doing when asked to think up random numbers
02:19wasamasaassuming a minimum distance :P
02:20wasamasaand once that is introduced for all values, the result looks less disconcerting than an actually random distribution of points
02:21TEttingeryup
02:22TEttingeralso, quasi-monte-carlo apparently has legitimate financial benefits https://en.wikipedia.org/wiki/Quasi-Monte_Carlo_method
02:23TEttingerhttps://en.wikipedia.org/wiki/Quasi-Monte_Carlo_methods_in_finance
02:31TEttingerone to three orders of magnitude over conventional monte carlo
03:55TEttingeroh geez... how do autogensyms work
03:55TEttingerif I have a macro that uses foo# , and it later uses foo# as a variable, they refer to the same thing, right?
03:55TEttingerbut if I then later have another macro that uses foo#, it doesn't refer to the same gensym
03:57TEttingerso I'm guessing the gensym is "bound" (not sure if right term) to the scope in which it is created
03:57TEttingerbut do macros even have scope?
03:57TEttingeris theirs the same as a function's scope?
05:15tim__I'm confused about :keywords that aren't in a map
05:15tim__I'm trying to pull access_code out of this
05:15tim__headers: {content-type: application/json, content-length: '289', connection: keep-alive, pragma: no-cache, expires: 'Sat, 01 Jan 2000 00:00:00 GMT', set-cookie: 'csrftoken=9c5bad8727db13908992e479d7f78c6b; expires=Sun, 29-May-2016 09:06:25 GMT; Max-Age=31449600; Path=/', date: 'Sun, 31 May 2015 09:06:25 GMT', vary: 'Cookie, Accept-Language, Accept-Encoding', cache-control: 'private, no-cache, no-store, must-revalidate'
05:16tim__sorry
05:16tim__body: access_token: xxxxx user: {username: tfdiddy, bio: '', website: '', profile_picture: 'https://igcdn-photos-e-a.akamaihd.net/hphotos-ak-xtp1/t51.2885-19/11055747_791331110950700_2073441790_a.jpg', full_name: Tim, id: '520163296'}
05:16SagiCZwhats the issue and what are you pasting?
05:17tim__Hi I'm trying to work with the instagram api via this code https://github.com/Rydgel/Clojure-Instagram-API
05:18SagiCZand?
05:18SagiCZwhats confusing about keywords?
05:18tim__sorry bear with me
05:18SagiCZ,(:a {:a :value})
05:18clojurebot:value
05:19SagiCZ,(:b {:a :value})
05:19clojurebotnil
05:19tim__we have this method (get-access-token *creds* "code-from-IG")
05:19tim__that returns
05:19tim__body: access_token: xxxxx user: {username: tfdiddy, bio: '', .......
05:19tim__body doesn't seem to be a map
05:19SagiCZhow can it return that?
05:19SagiCZwhats the type of that return value?
05:19SagiCZ,(type {:a 0})
05:19clojurebotclojure.lang.PersistentArrayMap
05:20SagiCZ(type (get-access-token *creds* "code-from-IG"))
05:20tim__its calling an rest api
05:20SagiCZcan you do this?
05:20tim__so maybe that is just the body of the response!
05:20SagiCZit could be a string
05:20SagiCZcall the "type" function on it please
05:20tim__ok, trying now, standby :)
05:21erleHow do I remove from a nested datastructure the objects whose (pr obj) representation doesn't comply to the EDN specification? Fx, {:a 1 :b (find-ns 'user)} → {:a 1}.
05:21erle"comply with"
05:25tim__hmm I can't get type to work in this
05:25tim__(defn save-auth [{:keys [params]}] (let [code (:code params) access-token (get-access-token *creds* code)] {:status 200 :headers {"Content-Type" "text/plain"} :body (-> access-token :body )}))
05:25tim__but I'm pretty sure that all of :body is a string
05:25SagiCZin that case you have to parse it
05:25tim__as I'm the object the I'm getting back is probably the http response from instagram
05:26tim__how do I convert this into a map so I can work with it ?
05:26SagiCZdo you use REPL?
05:27SagiCZanyways.. you can do this to read map from string
05:27SagiCZ,(read-string "{:a 0 :b 1}")
05:27clojurebot{:a 0, :b 1}
05:27SagiCZ,(:a (read-string "{:a 0 :b 1}"))
05:27clojurebot0
05:27SagiCZbut you should really find out what type is it..
05:28tim__Thanks
05:28erleMight be a good idea to use clojure.edn/read-string for such things.
05:28SagiCZerle: whats that?
05:28erleSomething that refuses to read evil things.
05:29erle,(doc read-string)
05:29clojurebot"([s] [opts s]); Reads one object from the string s. Optionally include reader options, as specified in read. Note that read-string can execute code (controlled by *read-eval*), and as such should be used only with trusted sources. For data structure interop use clojure.edn/read-string"
05:29SagiCZso stupid
05:29SagiCZgosh thats dumb
05:29SagiCZwhy is in some random namespace
05:30erleI guess they had to put it somewhere… And since the only thing it reads is EDN, why not put it in clojure.edn?
05:31SagiCZthe namespace has just two functions
05:31erle,(ns-publics (find-ns 'clojure.java.browse))
05:31clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [java.util.concurrent.ConcurrentHashMap hash "ConcurrentHashMap.java" 333]}]\n :trace\n [[java.util.concurrent.ConcurrentHashMap hash "ConcurrentHashMap.java" 333]\n [java.util.concurrent.ConcurrentHashMap get "ConcurrentHashMap.java" 988]\n [clojure.lang.Namespace find "Namespace.java" 188]\n [clojur...
05:32erleHmm:
05:33erleGuess I should require it first. Anyway, that namespace has only one function, for example.
05:38tim__@SagiCZ me again, so read-string didn't work, so I tried type am getting class clojure.lang.PersistentArrayMap
05:38SagiCZso its a map already
05:38SagiCZno reason for read-string
05:38tim__,(str (type (:body access-token)))
05:38clojurebot#error {\n :cause "Unable to resolve symbol: access-token in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: access-token in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...
05:39SagiCZnow explain what exactly doesnt work?
05:39tim__gosh I'm sorry I haven't used IRC before
05:39tim__ok this (:access_code (:body access-token))
05:40tim__doesn't give me the value of :access_code
05:41SagiCZevaluate this please
05:41SagiCZ(keys (:body access-token))
05:42tim__[access_token, user]
05:42tim__:)
05:42SagiCZwell as you can see.. tha map has no key :acces_code
05:42SagiCZthus it cant return the value for it
05:42tim__right, now let me try access_token, what the hell
05:42SagiCZ(:access_token (:body access-token))
05:43tim__yeah good, I'm not quite that stupid, access_code as a typo before
05:43tim__*was
05:44tim__@SagiCZ is it ok If I paste the method in here
05:45tim__that I've got so far
05:45SagiCZno
05:45tim__its only a few lines
05:45SagiCZwww.refheap.com
05:45SagiCZpaste it there
05:45tim__ok
05:45tim__thank you https://www.refheap.com/101909
05:46SagiCZwhats wrong with that?
05:47SagiCZwhat does it return<
05:47SagiCZ?
05:47tim__nothing, blank
05:47tim__but what is interesting it that this ...
05:47SagiCZumm
05:47tim__https://www.refheap.com/101910
05:47tim__works
05:47tim__that will put out test
05:48tim__but see :body in my test is a map, but in the response from get-access-token it isn't a map
05:48SagiCZoh
05:48SagiCZbut you called type on it_
05:48SagiCZ?
05:49SagiCZaccess-token is a map right_
05:49SagiCZ?
05:49SagiCZcould you paste what is in the access-token variable? just do (let [...] access-token)
05:51tim__this is all happening via http - as instagram api posts back to a URL which makes it tricky for me
05:51tim__but just a sec
05:51SagiCZyea
05:53tim__https://www.refheap.com/101911
05:54SagiCZgreat.. give me a sec
05:55kwladykaI use ring + compojure + selmer. How can i put URL to routes in templates in HTML? I don't want use static HTML link in href and forms. I want use something like UrlTo(user.register).
05:56tim__one more example https://www.refheap.com/101912
05:57tim__I that one without using (str) which makes it look more like a map
05:58SagiCZand (type access-token) returned PersistentArrayMap right?
06:00SagiCZi guess this should work ("access_token" (:body access_token))
06:00tim__@SagiCZ https://www.refheap.com/101913
06:00tim__I'll try that
06:00SagiCZin clojure maps, keys dont have to be :keywords.. they can be strings or integers as well
06:01SagiCZ,("hey" {"hey" "value"})
06:01clojurebot#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 [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n...
06:01SagiCZ,(get {"hey" "value"} "hey")
06:01clojurebot"value"
06:02SagiCZ(get (:body access_token) "access_token")
06:02SagiCZok sorry tim.. it should be this ^
06:02tim__OMG
06:02tim__it worked!
06:03tim__(get (:body access-token) "access_token")
06:03SagiCZsorry for not telling you earlier.. my clojure is a bit rusty
06:03SagiCZ(doc get)
06:03clojurebot"([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
06:04tim__thank you for your help! Why do you think it showed as keyword here https://www.refheap.com/101912
06:05SagiCZtim__: weird.. i guess the browser console just ate the quotes? who knows
06:06tim__SagiCZ: indeed, there is lots of mystery for me at the moment, early days :) thanks for helping anyway, this was killing me
06:06SagiCZno problem!
06:45kwladykaSomebody use bidi routing library? How it looks vs pedestal?
06:51kwladykai am trying answer myself which one should i use
06:51kwladykabecause i see compojure is too simply for me
08:47lxsameerguys I'm writing a clojure lib, my ns name is xyz.core and I have a function called test1 , how can I call it from repl ?
08:49jjttjj(require xyx.core) (xyz.core/test1 args)
08:50lxsameerbut i get this exception
08:50lxsameerCompilerException java.lang.ClassNotFoundException: mailgun.core, compiling:(/tmp/form-init4875882536837719255.clj:1:1)
08:51lxsameerwhile I'm requiring the namespace
08:51lxsameerjjttjj: ^
08:52jjttjjdo you have it as a dependency in the project.clj?
08:52lxsameerjjttjj: i'm using lein and created a library project, and I'm in repl provided by lein repl in my lib project tree
08:53jjttjjhmmm
08:58jjttjjlxsameer: ohhh, if you're using lein repl you need to use load-file
08:58jjttjjlxsameer: with the file path as a param. instead of require
08:59lxsameerjjttjj: ah ok thanks
09:01lxsameerjjttjj: is there any shorter way to test my lib
09:01lxsameer?
09:02SagiCZlxsameer: use a good IDE that helps you with painful tasks like this?
09:02lxsameerSagiCZ: I'm using emacs with ceder, is that enough ?
09:03SagiCZlxsameer: if it works for you then fine.. i personaly couldnt stand emacs and started using Cursive with IntelliJ IDEA
09:03lxsameerSagiCZ: thanks
09:04jjttjjlxsameer: do you mean CIDER?
09:04jjttjjyou should do m-x cider-jack-in while in a file in your project tree
09:04lxsameerjjttjj: oops .
09:04lxsameerjjttjj: yeah
09:04jjttjjthen you'll get a repl where require, etc will all work
09:05SagiCZyeah just press a couple of magic buttons together and it might just work
10:21justin_smithjjttjj: require outside an ns form needs quoting (require 'xyx.core)
10:53digiorgiwhy you personally choose Clojure over Common Lisp?
10:56justin_smithat first, because company infrastructure was set up to make using the jvm a convenient choice. Now because of the large range of jvm libs and relatively frequent update of the vm, and because I prefer many of clojure's design decisions in comparison to cl.
11:04dumptruckmani'm wondering if there's a simpler and more efficient way to do this:
11:05dumptruckman(let [new-entities [{:players (into [] (for [player (get-players entities)] (move player)))}]] new-entities)
11:07justin_smithI don't know about efficient, but you could have [{:players (mapv move (get-players entities))}] - I think that's clearer to read
11:09dumptruckmanhmm yeah, that reads a lot better
11:12dumptruckmani feel like it's hard for me to see where i should be using map
11:13justin_smithmap is usually clearer when you are applying a single function, with no nested comprehension
11:14justin_smithfor is usually clearer when you have nested functions to call, or nested comprehensions to do
11:19dumptruckmanso i should just think map instead of for, typically
11:31sw1nnCan anyone give any guidance on when I should be using fn? vs ifn? to check whether something is function? In particular I think liberator here: https://github.com/clojure-liberator/liberator/blob/master/src/liberator/util.clj#L8 should be using ifn? 'cos (fn? a-multi-method) => false
11:32justin_smithyeah, ifn matches keyword too :)
11:32justin_smiththe problem is that ifn also matches symbol
11:32justin_smithand most people supplying a symbol don't mean for it to be called (for example)
11:32justin_smith,(ifn? 'a)
11:32clojurebottrue
11:32justin_smithor vectors or maps
11:32justin_smith,(ifn? [])
11:32clojurebottrue
11:33justin_smith,(ifn? {})
11:33clojurebottrue
11:33justin_smith,(ifn? #{})
11:33clojurebottrue
11:33sw1nnwell for vectors, that's fine right
11:33sw1nn,([1 2 3] 3)
11:33clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.IndexOutOfBoundsException\n :message nil\n :at [clojure.lang.PersistentVector arrayFor "PersistentVector.java" 153]}]\n :trace\n [[clojure.lang.PersistentVector arrayFor "PersistentVector.java" 153]\n [clojure.lang.PersistentVector nth "PersistentVector.java" 157]\n [clojure.lang.APersistentVector invoke "APersistentVector.java" 283]\n [sandb...
11:33sw1nn,([1 2 3] 2)
11:33clojurebot3
11:33justin_smithsw1nn: well all those things are callable as functions, that's what ifn? tells you
11:34sw1nnwhen is symbol callable?
11:34justin_smith,('a '{a 0})
11:34clojurebot0
11:34justin_smithalways
11:34sw1nnhmmm I see
11:34justin_smith,('a '#{a b c})
11:34clojurebota
11:35sw1nnso what is fn? telling me that ifn? isn't
11:35justin_smithsw1nn: the important thing in that context, is whether a user of liberator would expect to provide 'x and get (constantly 'x) back, or provide 'x and have it be used as a function
11:35justin_smithsw1nn: ifn? is callable, fn? is made by (fn [] ...)
11:36justin_smithanother example:
11:36justin_smith,(fn? #'+)
11:36clojurebotfalse
11:36justin_smith,(ifn? #'+)
11:36clojurebottrue
11:36sw1nnright, so i think it should be ifn? in that case, because you are passing something to be called to handle a decision.
11:36justin_smithfor interactive development, sometimes people want to supply a var (that will be looked up each usage) rather than a function
11:37justin_smithsw1nn: OK, as long as people wouldn't be surprised / confused on what it does for symbols, vars, etc.
11:37sw1nn(ifn? a-var) => true
11:38sw1nnI'm confused when I pass the name of a function and it works, but I pass the name of a multimethod and it doesn't.
11:39sw1nnso have to #(a-multi-method %) or (partial a-multi-method)
11:40justin_smithsw1nn: multimethods are not fn? because they are not made using fn
11:42sw1nnyeah, I see the distinction now. ta
11:44justin_smithsw1nn: I came up against these same issues when someone posted a feature request on the polaris router for accepting multimethods
11:44SagiCZjustin_smith: do you think SICP is a good book to read when I need to learn how to design applications in a functional way? I already know a bit of clojure but struggle to transfer my OOP knowledge of Java to Clojure
11:45justin_smithSagiCZ: SICP is a great book. It also has online lectures from the original class, by the author, on youtube.
11:45SagiCZis the last section about Register Machines relevant for clojure>
11:46SagiCZ?
11:46J_ArcaneSagiCZ: I recommend How to Design Programs.
11:46J_Arcanehttp://www.ccs.neu.edu/home/matthias/HtDP2e/
11:46SagiCZJ_Arcane: thanks.. why would you recommend this book?
11:48J_ArcaneIt's very much explicitly about what you asked about. It's good at teaching how to design and compose functional programs (I think it doesn't even teach mutation until something like 8 chapters in), and the lessons even the first few chapters will give are quite handy.
11:48J_ArcaneMade me a better programmer, though as is the way with youth, I don't think I recognized it at the time.
11:48SagiCZJ_Arcane: sounds great! will definitely check it out
11:55chadhs is there an option to configure auto intent when working in the `lein repl` which i believe is repl-y?
12:02justin_smithchadhs: lein repl uses nrepl
12:05Jaoodjustin_smith: how does that answers his question?
12:05chadhsjustin_smith: this gets reported when you run `lein repl`
12:05chadhsREPL-y 0.3.5, nREPL 0.2.7
12:05justin_smithJaood: it doesn't answer the question, it's just addressing one part of what he said
12:05chadhsit's not biggy, just haven't seen anything in docs to configure behavior in the repl
12:07chadhsthere are some cool options to get colorized output which is nice. i chose venantius/ultra
12:07justin_smithchadhs: isn't that a grab bag of various tools / options thrown together?
12:08chadhsyes it is. it provides nice output, so rather than yak shaving tried it out and like the result thus far.
12:08justin_smithchadhs: yeah, if you look at the source of ultra it's got one namespace that consists of importing whidby, another that consists of importing puget etc.
12:09justin_smithgood to hear it's a good combo though
12:09chadhscorrect
12:09chadhseasy for newbie like me at this point ;-)
12:09justin_smithchadhs: the reason I brought up nrepl is that nrepl accepts various middlewares for modifying its behaviors
12:10chadhsill post something if i figure out auto indent, but for now i think i can handle hitting the space bar
12:10justin_smithI'm actually not sure if repl-y is pulled in as an nrepl middleware, or repl-y is invoking nrepl in that case though
12:10chadhsah gotcha… (gotta run an errand bbl to check messages thnx justin!)
12:22martinklepschweavejester: hey — is ns-tracker supposed to support reloading of .cljc namespaces as well or is there a difference?
12:31weavejestermartinklepsch: It relies on tools.namespace for that.
12:31weavejestermartinklepsch: So if you have an older dependency overriding it, it won't load cljc
12:31weavejestermartinklepsch: And tools.namespace doesn't currently support cljc files with reader conditionals in the ns declaration
12:32martinklepschweavejester: thanks, that's super helpful!
12:32weavejestermartinklepsch: See http://dev.clojure.org/jira/browse/TNS-34
13:10maiocan someone point me to some best practices regarding adding clojurescript to a project? how should I layout my repo for example?
13:10maiosrc/clj + src/cljs? or is there some problem with src/proj/x.clj + src/proj/x.cljs?
13:15tolstoymaio: for what it's worth, I use the src/clj src/cljs src/cljc style, then add those paths to the appropriate builders as needed.
13:16tolstoymaio: As far as "best practices", I don't know. I always figure best practices are what you hope your competitors are using.
13:16maio:)
13:18tolstoymaio: One issue I've had with cljsbuild is that if you want to use macros in CLJS, a "util.clj" in src/clj will somehow break a "util.clj" in src/cljs. I think it's a lein classpath issue, but don't know for sure.
13:43Jarvis2CuteStat 2.0 Site Worth Script NULLED Share & Rate direct link http://bit.ly/1EL693G
13:43Jarvis2CuteStat 2.0 Site Worth Script NULLED Share & Rate direct link http://bit.ly/1EL693G
13:43Jarvis2CuteStat 2.0 Site Worth Script NULLED Share & Rate direct link http://bit.ly/1EL693G
13:48justin_smithtolstoy: is this because the macros for cljs must be on util.clj?
13:48tolstoyjustin_smith: I think so.
13:49tolstoyI had `src/clj/app/util.clj` with some stuff in it.
13:49tolstoyAnd: `src/cljs/app/util.clj` (as well as a corresponding util.cljs) with a macro in it.
13:49justin_smithu
13:49tolstoyNo matter what I did, the macro never showed up.
13:50tolstoyOnce I changed the "cljs" namespaces to "utils" rather than "util", everything worked as expected.
13:50justin_smithyeah, that's gonna have path shadowing
13:50justin_smithsee also cljs.core.async stylr
13:51justin_smitherr that style of disambiguating by package
13:51tolstoyI just thought the :include-macros true thing had changed, so I never quite asked the right question on #clojurescript when I was asking about it.
13:51tmtwdhi when I do cider-jack-in it doesn't load the current namespace
13:52tmtwdand C-c M-n doesn't work either
13:52tolstoyjustin_smith: Strange, though, because cljsbuild paths did not include "src/clj".
13:52justin_smithtmtwd: try running lein check
13:53kwladykaSomebody have experience with Pedestal, Hoplon and Bidi? I am trying figure out which one should i use :)
13:53justin_smithtolstoy: aren't there profile merges in play?
13:53tolstoyjustin_smith: Perhaps, but it's invisible to me.
13:54tolstoyjustin_smith: As an example, lein-garden merges lein's top level :source-paths in with the declaration in its own area. End result, change anything and the css gets regenerated.
13:55justin_smithkwladyka: bidi and pedastal are not replacements for one another
13:55kwladykajustin_smith, if you have time there is my question with more details http://stackoverflow.com/questions/30557724/when-use-pedestal-hoplon-bidi-and-route-one
13:56tmtwdyeah, I still can't load the current namespace
13:57tolstoyjustin_smith: I submitted a patch for lein-garden (next release, whenever that is), but I didn't investigate lein-cljsbuild to figure out what I might have been misconstruing about namespace collisions.
13:59justin_smithkwladyka: bidi and compojure are routing libs, all they do is rpute requests to handlers
13:59tmtwdI get :reloading (funny.core funny.core-test)
13:59justin_smithhoplon os a templating lib
14:00tmtwdbut I still get user> in the repl
14:00justin_smithxompojure is not intended to do templating
14:00kwladykajustin_smith, hmm so hoplon is something like selmer?
14:00justin_smithiirc - double checking
14:02J_Arcanekwladyka: Hoplon is a single-page-app framework in Clojurescript.
14:02justin_smithyeah, I wad wrpng
14:03justin_smith*I was wrong, that is
14:03tolstoykwladyka: Maybe you're looking for a "full stack" framework? The usual pattern for Clojure web-devs is to mix and match libraries.
14:04justin_smithkwladyka: but beside that point you are comparing tools from different categories
14:04kwladykajustin_smith, maybe... did you look for my link?
14:04justin_smithyes
14:04tolstoykwladyka: As justin_smith is saying, each of those libs solve different parts of the problem.
14:04kwladyka"Write everything in Clojure and ClojureScript, clientside and serverside." <- Hoplon
14:05kwladykai undestand, but on http://stackoverflow.com/questions/30557724/when-use-pedestal-hoplon-bidi-and-route-one i explain my problem with details (i hope)
14:05kwladykaJ_Arcane, so Hoplon is for frontend or for front and backend side?
14:06J_Arcanekwladyka: Pretty much front end only, I think, though I believe they have a sibling library for back-end.
14:06J_ArcaneI've only used it for a front-end only SPA.
14:07justin_smithbidi is a router. hoplon and pedastal are full stack
14:07kwladykaor Hoplon is similar to metor framework?
14:07kwladyka*meteaor
14:07kwladyka*meteor
14:08J_Arcanejustin_smith: Ahh, right. I just never used the server side.
14:14Bruce_WayneAnyone know the best place to see a reagent, re-frame example
14:14Bruce_Wayne?
14:14justin_smithhoplon is more oriented to spa where you have a lot of (cl)js client logic, pedestal is ,ore focused on the backend loggic of building a resttful servvice
14:16eyepatchI'm pretty much a total newb to web development, and the tutorials I'm looking at assume more web dev experience than I have. I don't understand the deployment cycle of Clojure integrated with compojure. Where is the HTML file loaded by the browser?
14:16J_ArcaneBruce_Wayne: I did a simple weather app with reagent-template recently. Nothing special, but might be helpful for seeing the basics: https://github.com/jarcane/wunderprojectj
14:17kwladykabut hoplon has also backend support? Hoplon cl(js) doesnt work with REST on backend side?
14:17eyepatchCan a web app made with Compojure be as interactive as one with a technology stack including JS such as ASP.NET?
14:17Bruce_WayneJ_Arcane: Thank you!
14:17eyepatchDo people integrate JS into their web development with compojure somehow?
14:17weavejestereyepatch: Yes, any modern web stack has the same capabilities
14:18weavejestereyepatch: At least in terms of serving files
14:18kwladykaeyepatch, compojure is for routing only
14:18kwladykaeyepatch, you can load files using RING
14:18eyepatchI'm referring to the stack that's used with compojure on top of ring iirc.
14:19weavejestereyepatch: A web server receives HTTP requests sent by a HTTP client, like a browser
14:19kwladykaeyepatch, but if you want use template use hiccup, selmer or enlive
14:19weavejestereyepatch: And sends back a HTTP response in return.
14:19justin_smithkwladyka: sure, but they have a different focus. pedestal will help more if your development is backend-heavy, hoplon likely more useful if the work is frontend heavy
14:19kwladykajustin_smith, like always you help a lot :)
14:20justin_smithkwladyka: though pedestal doesn't use ring, which is the more popular backend abstraction
14:20J_Arcaneeyepatch: Have a look at reagent-template. Generally what you do is build a back-end that provides a route that serves the built front end.
14:20weavejestereyepatch: Each HTTP response will contain one of the files you see in your browser, be it a HTML page, an image, CSS styling, and so forth.
14:24weavejestereyepatch: Most web servers allow files to be served from a directory. So a URL like http://example.com/foo/bar.txt, will be converted into a path like /var/www/foo/bar.txt, and the response will contain the content of that file.
14:33sidharth1in the clojure java realm, is the use of the value of (Object.) a common thing ? I have this working code that says "(let [eof (Object.)]"..., is that at all a common thing to say ?
14:34justin_smithsidharth1: it's the idiomatic way to make a unique token that you would test for equality later
14:34sidharth1it looks ... yes.. i was thinking that
14:35justin_smithsee also gensym
14:35justin_smithwhich is a bit more clojurey, and is useful in macros
14:35sidharth1thanks for the consultation :)
14:35justin_smith,(gensym)
14:35clojurebotG__27
14:35justin_smith(doc gensym)
14:35clojurebot"([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."
14:36justin_smiththe key there being that within a single run of your program, it is guaranteed unique
15:21toxmeisteranyone got any bright idea how can i force `lein test` to *not* ignore .cljc files?
15:22justin_smithtoxmeister: I've found that I can require and test cljc files from clj test namespaces
15:22justin_smithbut I have not tried putting tests in cljc
15:30toxmeisterjustin_smith: been thinking about that, but means i'd have to generate dummy ns wrappers for all my tests and that per clj & cljs... i think it might have to do with builtitude & this call: https://github.com/technomancy/leiningen/blob/master/src/leiningen/test.clj#L145
15:31toxmeisterjustin_smith: doing `lein test my.cljc.ns` works fine, it's just the auto-selection which seems to ignore these files
15:31justin_smithtoxmeister: ahh, so you want to run the same tests from clj and cljs on a cljc file?
15:31justin_smithinteresting
15:31toxmeisteryeah, example here: https://github.com/thi-ng/ndarray/blob/master/test/core.org#complete-namespace-definition
15:32toxmeisterit generally works, but as i said only if you specify the namespace as command arg
15:32toxmeisterso for the above linked test, i can call `lein test thi.ng.ndarray.test.core` and it works fine
15:33justin_smithtoxmeister: in that case, a workaround would be to explicitly add that file to your test-paths in project.clj maybe?
15:33justin_smithand the real fix would likely be what you linked above
15:33toxmeisterbut don't you just state directories in :test-paths?
15:34justin_smithtoxmeister: I have noticed with other *-paths in lein that I can specify a directory or a specific file
15:34justin_smithbut I haven't tried with a test file tbh, you could try though
15:36toxmeisterjustin_smith: just tried, full file path in :test-paths doesn't make any difference :(
15:36toxmeisterjustin_smith: will file an issue
15:36justin_smithSorry to hear that. I guess we need a bultitude update?
15:36toxmeisterjustin_smith: thx though! :)
15:37toxmeisterjustin_smith: you any experience w/ lein hacking? always find it a bit daunting...
15:38justin_smithtoxmeister: there are straightforward instructions on getting the source repo running locally
15:38justin_smithafter that it's just a bigger than usual clojure project
15:39toxmeisterjustin_smith: interestingly: https://github.com/Raynes/bultitude/blob/master/src/bultitude/core.clj#L15
15:39toxmeisterjustin_smith: last edit "a day ago"
15:39justin_smithheh :
15:39justin_smith)
15:54toxmeisteryeah, a new library is born: https://github.com/thi-ng/ndarray/blob/master/src/index.org :)
15:55TEttingeris this an n-dimensional array lib?
15:56toxmeisterTEttinger: yes, currently up to 4D, but changeable
15:56TEttingerdoes it return primitive arrays when run in clojure?
15:57toxmeisterTEttinger: ...and everything type hinted and most transformations ops almost free (ie. no copying of data needed)
15:57toxmeisterTEttinger: yes
15:57TEttingergreat!
15:57TEttinger(inc ToxicFrog)
15:57lazybot⇒ 4
15:57TEttinger(inc toxmeister)
15:57lazybot⇒ 1
15:57TEttingerheh
15:57toxmeisterTEttinger: you can get at the primitive array (via `(nd/data my-ndarray)`)
15:58toxmeisterTEttinger: under CLJS it uses typed arrays
16:01Bruce_Waynewhat’s the difference be (register-sub …) and (register-handler …) in reframe?
16:18sveriregister-sub is triggered when something changed in the application state, register-handler is triggered by program code to change the application state
16:18sveriBruce_Wayne: ^^
16:19Bruce_Wayneso when someone clicks a button then register-sub is called?
16:19Bruce_WayneI’m working through this example: https://github.com/Day8/re-frame/tree/master/examples/simple
16:20sverino, the other way around, you click a button and register an event with (dispatch [:button-event]), then register-handler with the id :button-event is called
16:20sveriThere you can change the app-state
16:22Bruce_Wayneoh ok then once the handler is called, the app state changes, and then the sub is called because the app state changed?
16:23sveriexactly
16:23sveriOf course you have to define in register-sub what specific part of that app-state should change so that it's called
16:24sveriAnd finally you use re-frame/subscribe for that sub to actually be notified of that change
16:27Bruce_Wayneand can you register subs or handlers to multiple states?
17:32anti-freezeHi everyone. So, I'm trying to create a macro to make repetitive database operation definitions simple. Firstly, I can't get this to work, secondly, can anyone advise a better way of maybe going about this? Here's the sauce: https://www.refheap.com/be527722eea4862e4f2e347fc
17:33SagiCZif you can do it with a function, dont do it with macro
17:34anti-freezeSagiCZ: I constantly have to redefine the same functions again and again with only minor differences, I thought a macro would be a perfect fit
17:36SagiCZprobably a good idea then
17:38TMAanti-freeze: it might be possible to have one master function that takes one more parameter -- the difference
17:38anti-freezeSagiCZ: Its a simple enough macro. I define a function that returns a map with quoted forms containing a %name% placeholder. The macros job is to replace %name% with the model name. So for example {:create '(def %name% (partial create-* coll)} would become (def create-user (partial create-* coll))
17:38chouserI suspect you still don't actually need a macro and might in the long run prefer functions that take arguments rather than functions with special names (if I understand your goal correctly)
17:39anti-freezeSo then I can just go (generate-operations :user :users default-operations)
17:39SagiCZthe good thing about functions is that they are objects and can be used as input into function-manipulating functions whereas macros can not
17:39anti-freezeAnd it'll generate the standard stuff
17:39TMAanti-freeze: instead of (defn foo-N [...] (... (___ ...) ...)) where only the ___ changes, you could have (defn foo-generic [f ...] (... (f ...) ...))
17:39anti-freezeSagiCZ: Right, what I had before was something like (def create-user (partial create-* "users"))
17:39chouserthat said, I'm sure we'd be happy to help you write some ill-advised macros. :-)
17:39anti-freezeBut it would be the same in every file
17:40anti-freezechange the method and collection name
17:40chouserwhy not have replace usages like (create-user ...) with (create :user ...) ?
17:40chousers/have//
17:41anti-freezedoesn't seem very DRY is all
17:41chouserboth syntaxes use the word "create" once and the word "user" once. No added repetition either way.
17:42chouserBut again, if you want to learn to write macros, happy to help.
17:42anti-freezechouser: I could do, but I want to abstract collections away from the other accessors. Besides, If I want to overwrite behaviour for that single instance, I assume it would be difficult to do
17:42SagiCZi never got around learning about macro beacuse I just never run into a problem that couldnt be solved with a function
17:42chousercould use multimethods if you expect to tweak behavior.
17:43TMAin common lisp you can have eql-specialized method that would do the trick
17:43TMAis something similar possible in clojure?
17:43anti-freezechouser: I could do actually. Good idea. I hear multi-method performance is terrible though and considering its an integral part of the application
17:44chouseranti-freeze: if you're dispatching on a single parameter, you could use protocols, which have stellar performance.
17:44kristofTMA: dispatch on =
17:44chouserAnyway, if you want to write a macro, the standard recommendation is to start with a concrete specific example input to the macro, and write out what that example would expand to.
17:45chouseronly then try to write the macro, and if you get stuck it's then much easier for others to help.
17:45SagiCZchouser: um.. so if i have a multimethod dispatching on a value of a map via function ":keyword" i can subsitute that with a protocol?
17:46chouserSagiCZ: no, not quite. You'd probably use different record types (defrecord) instead of a map with a particular keyword value.
17:46chouserSwitching from a multimethod to a protocol, you give up flexibility for the better performance.
17:46SagiCZmy defmulti looks something like this:
17:46SagiCZ(defmulti observe :type)
17:46SagiCZand it dispatches according to the value of type
17:46thedoodPLwhats the goto test lib for clojure?
17:47SagiCZI am expecting to have around 20-50 of types eventually
17:47chouserSagiCZ: right, instead of different values for :type, you'd have to have different defrecord types.
17:47anti-freezewhere coll = :users
17:47SagiCZso the :type keyword (and value) would be a part of a record not a regular function right..
17:48SagiCZand the record would all implement the same protocol
17:48chouserThat is, instead of (defn make-a-foo [] {:type :foo}) you'd need (defrecord Foo ...) (defn make-a-foo [] (Foo. ...))
17:48chouserSagiCZ: exactly.
17:48chouserI wouldn't actually recommend it unless you're sure you need to perf. Multimethods are lovely.
17:49chousers/to/the/
17:49SagiCZchouser: well since my app is performance critical I will definitely consider it.. then again I kind of liked the idea of maybe dispatching via something else than type in the future
17:50SagiCZalso records are so ugly
17:50chouserSagiCZ: yep. Before making the change, you might try to measure the perf and make sure the multimethod dispatch is actually slow compared to the rest of the app
17:51thedoodPLDo you guys do tdd with clojure?
17:51SagiCZchouser: yup.. i am way before optimizing change
17:51SagiCZthedoodPL: I personally dont but clojure is very suitable for TDD
17:51SagiCZsince you have the whole referential transparent functions deal.. they are very easy to test
17:52chouserthedoodPL: clojure.test is a built-in test system. There's also 'midge' which I understand to be designed especially for TDD
17:52SagiCZchouser: s/change/phase
17:52anti-freezeWhy do you guys advise agains't macros so heavily anyway. I thought they were what made lisp ridiculously powerful (as preached by Let Over Lambda)
17:52anti-freeze%s/./?
17:52chouseranti-freeze: they are powerful. When you need them, not having them is terribly crippling.
17:53SagiCZanti-freeze: just what i said earlier.. they cant be manipulated at runtime because they are not objects like functions.. they are just rules for the reader
17:53chouseranti-freeze: when you do not need them, using them anyway just leaves you with their drawbacks.
17:53thedoodPLSagiCZ: thanks mate :)
17:53TMAanti-freeze: that is the responsibility part of 'with great power comes great responsibility'
17:53anti-freezeI see. What about the situations where a function will do, but it makes code marginally more complex and convoluted?
17:54chouseranti-freeze: I sometimes provide two APIs, one purely of functions and values, and then a trivial macro to tidy it up for the most common use cases.
17:55anti-freezeYea, I suppose that makes sense. Thanks everyone
17:55anti-freezeLove the clojure community :P
17:55kristofanti-freeze: Write functions for functionality. Write macros for language design. When Clojure ceases to be the proper language, make your own.
17:55chouserAs a trivial example, see the source of the 'source' macro.
17:55SagiCZchouser: which is very often done in the clojure core and other popular libraries
17:56kristofanti-freeze: And don't fall into the trap of using macros for functionality. Write functions to do those things. For instance, I've seen macros used to implement lazy evaluation, multiple evaluation, control flow...
17:57anti-freezeI think I'll stick to multimethods now until performance becomes an issue
17:58chouserEven libs like core.async which seems like it might be useless without its "go" macro, I sometimes wonder if a functional API wouldn't help it in some (perhaps relatively rare) cases.
17:58thedoodPLSagiCZ: any must read books that you'd recommend for a newcomer?
17:58kristofchouser: You can take my go macro out of my cold, dead hands
17:59chouser:-)
17:59SagiCZthedoodPL: I recommend just one -> http://shop.oreilly.com/product/0636920013754.do and disrourage from Joy of Clojure and Programming Clojure
18:11SagiCZchouser: i started tinkering with defprotocol and defrecord and I just wanted to ask you one minor thing.. suppose I have a protocol thats defined by 3 methods.. i want to have 20 defrecords that implement the protocol..
18:11SagiCZ1) can the implementation choose to not implement the function and have some default for it?
18:11SagiCZ2) what if all the implementations should have the exact same fields, can they somehow inherit them?
18:21hiredmanprotocols let you have different behaviours for different things, if you want the same behaviour for many different things, that just sounds like a function
18:22SagiCZno, the methods implementations would be vastly different for each record.. just the fields should be the same
18:22chouser1) I don't think so. Instead you could have three separate protocols of one method each, and then extend them to default Object, and only override that as desired.
18:23SagiCZoh.. cool
18:23chouser2) no, but you could write a ... macro ... to generate defrecords with the same field list each time. :-P
18:23SagiCZchouser: haha yeah here we go! thanks
18:24chouserok, dinner time. Good fortune to you in your adventures!
18:24SagiCZsee you around!
18:35thedoodPLIs anyone here developing in clojure professionaly?
18:36thedoodPLif so then where do you work ;)
18:50weavejesterthedoodPL: I do, and London :)
18:51thedoodPLweavejester: what industry?
18:51weavejesterthedoodPL: I'm a contractor, so no specific industry.
18:53thedoodPLweavejester: what kind of daily rates can you get in London? (clojure gigs)
18:54weavejesterthedoodPL: It varies but generally between £400 and £500.
18:56thedoodPLweavejester: well thats not bad although London is crazy expensive. I've heard that 500 pd is reserved for the 'lucky' ones working in the financial industry
18:56stainweavejester: are you generally hired as "Clojure dude" (e.g. for Ring and Compojure work) or as "Make me something webby"?
18:56thedoodPLweavejester: how much exp. do you have?
18:57weavejesterthedoodPL: Actually, most of my work has been with startups. I do have a fair amount of experience with Clojure, though.
18:58weavejesterI live outside London, and commute in when I'm needed on site.
18:58weavejesterstain: I'm usually hired for companies using or starting to use Clojure.
19:01stainweavejester: well, that's great that there are regular companies that consider Clojure right away
19:01thedoodPLweavejester: do you have a steady stream of contracts or are you on the bench often? I just want to get an idea about the job market there
19:01stainI generally just have to sneak Clojure in along the edges..
19:02thedoodPLstain: if I'm lucky I might be getting a full time clojure job this summer
19:02thedoodPL:)
19:02toxmeisterif you're interested in OpenCL + Clojure + rendering, you might like this little project: https://github.com/thi-ng/raymarchcl/ - most of it is actually from 2013, but only just got around last week to update it to work w/ latest Clojure versions
19:03weavejesterthedoodPL: Most of my contracts have been fairly long. I haven't been without work for more than a month or two in the past three years. Recently I've decided to take a fairly long break, but that was a deliberate choice.
19:03stainthedoodPL: congratulations dude :)
19:04thedoodPLstain: the company that I was interviewed by last week told me that they might be getting a clojure project and if I'd be interested
19:04clojurebotGabh mo leithscéal?
19:04stainthedoodPL: for our work it is often up to myself to decide technology.. but as I am generally the only one on the team using Clojure, then I know that if I use Clojure on a project I will end up also solely responsible for that code ..
19:05thedoodPLstain: where do you work?
19:05stainthedoodPL: well, it sounds good, although you should of course always be sceptical of companies who decide on technologies before a project has started
19:05stainthedoodPL: University of Manchester
19:05stainweavejester: thanks for your little IAMA :)
19:06toxmeisterthedoodPL: FWIW I'm not purely doing web/serverside stuff, but was lucky enough to work mainly in clojure/clojurescript for various design & data visualization gigs. have almost used no other lang for my freelance projects since 2012 (only bits of python, C and JS here and there)
19:07thedoodPLstain: I went there for an interview for a java job and left with a possibility of getting a clojure one, best feeling ever :0
19:07weavejesternp. I should also add that there are more companies that want permanent employees rather than contractors.
19:07stainweavejester: now, why did you make Ring? :)
19:08weavejesterstain: I didn't, actually. Mark McGranaghan started the project.
19:08stainweavejester: are they all the kind of "Move to London and come work "permanently" on-site for a start-up with bare brick walls and 1.5 years left of funding?
19:08thedoodPLweavejester: there are almost none clojure ads on jobserve though :/ I was pretty sure that clojure job market in london was dead
19:09stainweavejester: my apologies.. still, responsible for a large chunk of it, right?
19:09stainring is cool stuff, so simple and flexible
19:09weavejesterstain: I'm the current maintainer, and I believe I've written the vast majority of it, yes.
19:09thedoodPLstain: btw moving to london is kinda tricky i don't think I'd move there for a permie position for less than 50k, because its so freaking expensive
19:09stainthedoodPL: 50k? You need at least 75k.. and a partner earning the double
19:10stainand then you can afford to rent a one-bedroom flat
19:10weavejesterthedoodPL: I can only judge by the companies that I work for and the recruiters that contact me.
19:10thedoodPLstain: nah one bedroom flats run for 1200-1500 in decent areas dude ;)
19:11thedoodPLstain: then again here in Warsaw you can get a pretty luxorious apartment for 700 quid
19:11stainthedoodPL: that is still insane.. when I moved to Manchester 10 years ago I paid £550/month for a two-bedroom flat
19:11stainto be fair, it was not a decent area
19:12stainjust a bit of car tires burning in the street.. two neighbours strangling each-other.. That kind of thing!
19:12thedoodPLstain: ;)
19:12staingood learning experience for a culture-poor Norwegian
19:13stainbtw, I stopped the two stranglers so nobody died
19:14weavejesterOutside the M25 it gets more reasonable, but that's a long commute in.
19:15thedoodPLweavejester: I've found you on twitter ;)
19:22thedoodPLweavejester: is there a functional or clojure'an equivalent of SOLID principles or uncle bobs clean code? Or some guidelines on writing good clojure code
19:24stainthedoodPL: just forget anything you might still remember from Java
19:24stainexcept perhaps the String methods
19:25stainkeep things simple and concise. Don't overengineer it, but make reusable functions.
19:25weavejesterthedoodPL: Have you watched "Simple Made Easy"?
19:25staindata structures are king. Yet they should also be simple and consise.
19:26stainbtw.. I was not concise in my spelling of consise there
19:26thedoodPLweavejester: no I have not, I'll watch thanks :)
19:26thedoodPLI'll watch it*
19:26thedoodPLstain: xD
19:27weavejesterthedoodPL: IMO it explains a lot about Rich's reasoning behind a lot of the decisions in Clojure.
19:27weavejesterLike *why* Clojure prefers data structures
19:29thedoodPLOK guys thanks for the chat I'm going to get some sleep I've got to wake up before 7 today ;)
19:29thedoodPLhave a good night :)
20:13stainif I have a couple of protocols, and also some imported Java classes which I (extend-type) to support those protocols, is there a general naming style I should follow? E.g. I've gone with P* for the protocols, so that I have (extend-type Graph PGraph (blah [g] (.getBlah g)))
20:14stainor should I just call them without any prefix and use fully qualified names for the Java types
20:21toxmeisterstain: i generally don't like prefixes, but for protocols have always been using "P*" as well...
20:27amalloyP is a bizarre prefix i have never seen used for protocols. i think the two main camps are Foo and IFoo, since it's like an interface
20:28justin_smithamalloy: the hawaiian-detective naming convention specifies that all protocol names must be suffixed with -PI
20:43Bruce_Waynehey what is the best way to use clj files in cljs files?
20:43Bruce_Waynelike require a clj ns in a cljs ns?
20:50chouseryou can't really. clj runs in jvm, cljs in javascript.
20:51chouserwith the 1.7 RCs you can write a .cljc file that can be require'd by both clj and cljs
20:52Bruce_Waynechouser: interesting
21:47TEttingerpharaoh, you made the same mistake as the horse naming competion
21:47TEttingercompetition
21:47justin_smithoops
21:47TEttingerthe horse that won the kentucky derby was American Pharoah
21:48TEttingerspelled just like that
22:27justin_smitheventually the horse people are goingto break down and just use UUIDs
22:27justin_smiththey aren't allowed to reuse names
22:28justin_smithbest horse name ever, potoooooooo
22:28gfredericks,(def horse-count (atom 1000000))
22:28clojurebot#'sandbox/horse-count
22:28gfredericks,(str "horse-" (swap! horse-count inc))
22:28clojurebot"horse-1000001"
22:28justin_smithclojure version ##(apply str "pot" (repeat 8 \o))
22:29justin_smith,(apply str "pot" (repeat 8 \o))
22:29clojurebot"potoooooooo"
22:33Bruce_Waynejustin_smith: is there a way to require a clj ns in a cljs ns?
22:33Bruce_WayneI’d like to use some of the clj functions in my cljs handlers
22:33Bruce_Waynejustin_smith: I’m working in reframe
22:33justin_smithBruce_Wayne: like chouser mentioned, you can use cljc
22:34Bruce_Waynewhat about cljx?
22:34justin_smithwith cljc being a part of the core language, I wouldn't make something with cljx right now
22:37Bruce_Waynejustin_smith: do you know any good examples using cljc?
22:37justin_smiththere are some good examples here - it's not complex so the stuff here was enough for me to do everything I needed http://dev.clojure.org/display/design/Reader+Conditionals
22:43bbloomBruce_Wayne: fipp uses cljc to good effect now
22:44bbloomhttps://github.com/brandonbloom/fipp/tree/master/src/fipp