#clojure logs

2017-01-07

00:28sobeltensorflow is pretty neat. i heard google's vector processors can run TF models 10x faster than the best GPUs, so running models on their cloud is pretty advantageous
02:16domgetterIs there a data structure in Clojure that I can push to both sides of?
02:24hiredmanhttps://github.com/pjstadig/deque-clojure
02:43TEttinger,(doto java.util.ArrayDeque. (.addFirst 6) (.addFirst 5) (.addLast 7)) ;; not necessarily a good option, but an option
02:43clojurebot#error {\n :cause "java.util.ArrayDeque."\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.util.ArrayDeque., compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6719]}\n {:type java.lang.ClassNotFoundException\n :message "java.util.ArrayDeque."\n :at [java.net.URLClassLoader$1 run "URLClassLoader.j...
02:43TEttinger,(doto (java.util.ArrayDeque.) (.addFirst 6) (.addFirst 5) (.addLast 7)) ;; not necessarily a good option, but an option
02:43clojurebot#object[java.util.ArrayDeque 0x6e40a8fb "[5, 6, 7]"]
02:47domgetterawesome, thank you
02:47domgetterIt's not for production, it's just for a proof-of-concept mandelbrot viewer
02:50domgetterAny idea why (.repaint canvas) isn't repainting until a while loop is finished? The println's next to it are printing to the console, but the canvas isn't repainting
02:51domgetterhttps://gist.github.com/domgetter/12415657b9acb2494fa7271860301a0d#file-core-clj-L187
02:57domgetternvm, apparently repaint doesn't guarantee a refresh.
03:58amalloydomgetter: don't tie up the event dispatch thread. nothing in the UI can change while you're handling an event
03:59amalloyif you have expensive computations to do, you do it on a different thread
04:00domgetteramalloy the first version of the fractal viewer draws the whole thing as soon as possible. This version is me wanting to "see" the progress as chunks are finished recursively
04:01amalloyright. so you start a threat to compute a new chunk, and once you have a chunk ready you insert an event on the dispatch thread that renders it
04:01domgetteroh, you're saying I shouldn't be coupling computation to rendering
04:03amalloyindeed. rendering is time-sensitive
06:27jonathanjjeaye: that's sort of actively discouraged
06:27jonathanjhttps://www.youtube.com/watch?v=oyLBGkS5ICk if you want to know a bit about why
06:28dysfuntechnomancy: julia is a bit of a strange beast though. i was initially very in favour, but after a certain amount of use i realised it's got a while to go before it's useful
06:30dysfunpython is pretty much the language to learn about anything like machine learning these days. not so much useful material for other langs
06:59domgetteramalloy: It's already going quite a bit faster! https://i.gyazo.com/b62965215fbd81d9dedcf6bc4a3670d6.gif
08:38dysfunhow do i compare the value of a var against a keyword in selmer?
08:41dysfunoh, {% ifequal foo :bar %}
09:30lasse_Hey. I'm reading this tutorial about using clojure, postgresql, compojure to make a small blog.
09:30lasse_https://devcenter.heroku.com/articles/clojure-web-application
09:31lasse_My question is about keys and binds in general. The tutorial has a db-table "shouts" which they use in queries like so:
09:32lasse_ (defn all [] (into [] (sql/query spec ["select * from shouts order by id desc"])))
09:32lasse_Which is straight-forward.
09:32lasse_And inserting is handled like:
09:32lasse_ (defn create [shout] (sql/insert! spec :shouts [:body] [shout]))
09:33lasse_I don't like how the name of the table is hardcoded in the query-string, so thought about using (str "select * from" table-name)
09:33lasse_But how can I change the use of the key ":shouts" in the insert-function?
09:34dysfunadd another parameter?
09:34dysfun(defn create [shouts key] ...)
09:34dysfunthere is no mystical magical binding going on, they are just data passed as parameters
09:35lasse_Oh yeah. Thanks. How about defining a global (def table-name "shouts") and referring to that?
09:35dysfunthe only bindings your example uses is the parameter 'shout' to the create function
09:35dysfunwe don't much like globals
09:36dysfuni understand why you want to do this, but it's not a good idea
09:36dysfunwriting sql works great until you want to change the queries
09:37dysfuni'd suggest using a library to generate the queries at this point to avoid getting it wrong
09:37ziltiWhat is the boot equivalent of lein's :java-source-paths? I have a java file in my sources, but I can't access the class from Clojure whatsoever.
09:38dysfunzilti: the same as for your clojure sources
09:38lasse_Anything you can recommend? I'm not really a fan of ORMs because I've experienced problems with the queries that gets generated (fx for joins).
09:38dysfunworking with java is a bit sensitive to ordering of things
09:38ziltidysfun: So, :source-paths? Because that way, it compiles on "boot javac", but I still can't access it
09:38dysfunit's not just putting (javac) before running your clojure tests
09:39dysfunwhat cannot access it?
09:39dysfunwhat is the process you are trying to make succeed?
09:39ziltiI can't (:import namespace.MyJavaClass)
09:39dysfunlasse_: we don't do ORMs, we do query builders. korma is probably flexible enough for your needs
09:39ziltiIt says it cannot find that class.
09:40dysfunfrom where? the repl? a test?
09:40ziltiA repl. Also, it's of course not possible to run the application via task since I can't import the class in build.boot either
09:41dysfunrepl might be slightly more of a challenge, but tests should be easy enough
09:42dysfunmy test task just adds "test" to source-paths and runs (javac) before (test)
09:42ziltiSo basically, the class isn't going to change much, it's just a wrapper subclassing a java class and handing the class variables to a clojure fn.
09:42ziltiAs long as I can access it anytime I don't care if I have to manually recompile it on the rare occasion.
09:43dysfunokay, well try and get it going in your tests first
09:43ziltiI don't even have tests yet though ^^ It's mainly to try out how I can get this to work
09:43dysfunif you can get that working, it might just be as simple as boot javac repl
09:55vdmit11Hey guys, since clojure.spec is buzzing around, I have a little question. I would like to define specs for protocol methods. That is, when I use `defprotocol`, I would like to define some specs for the methods of this protocol. And I would like these specs to be checked automatically in runtime. So whenever I call the method, I would like some validation to be performed in runtime. And I would not like to do the validation manually in every implementation
09:55vdmit11So I would like to have a modified `defprotocol` macro or something that will instrument all methods to perform checks whenever I call the method. Is this possible?
09:56dysfunyou can't
09:56dysfuntwo workarounds that i see:
09:56justin_smithprotocol methods are 100% abstract
09:56dysfun1. write functions that wrap the methods, doing the checks in those
09:56dysfun2. use a multimethod, where you will be able to execute a spec check before it is run
09:58vdmit11Yeah, I noticed :pre/:post in multimethods, but I think that protocols are more handy for me. Because I have a lot of value objects (records) in may code, and it is super-handy to extend them with implementations of various protocols.
09:59dysfunsure, but it's easy with multimethods too
10:01dysfunit also has the advantage that it's actually possible with multimethods ;)
10:01vdmit11Maybe this is just a personal preference. In my opinion protocols provide more "documentation" of what operations are available on some kind of objects, so they somehow cleaner. Multimethods are good when you have a huge number of implementations of the single method, while protocols look better when you have not just one, but a bunch of coupled methods, and not that many implementations of them.
10:02dysfun"it depends"
10:02vdmit11yeah
10:02dysfunin practice, i prefer multimethods and use protocols when i'm performance gaming
10:02vdmit11specs look very attractive as contracts
10:02dysfunindeed they are
10:03vdmit11so maybe I'll reconsider my approach
10:03dysfunif you are adamant on using protocols, i'd recommend doing what cljs does
10:03dysfunfor example deref calls -deref (which is a method of protocol IDeref)
10:04vdmit11yeah, this is the thing I wanted to point out about functions... if you define a wrapper function around the method, you have to prefix all these methods
10:05vdmit11looks a bit dirty
10:06vdmit11but maybe I could implement a custom defprotocol/extend macros that work in pair and hide away this name mangling
10:07vdmit11ok, thanks
10:07dysfunyou might be overengineering it
10:07dysfunand you risk obscuring a well known pattern
10:09vdmit11well, you see, I also would like to use specs together with deftype/defrecord to describe the data contained in my objects
10:09vdmit11so I anyways need some set of helper macros
10:10vdmit11maybe I can live with methods prefixed with the dash sign
10:11vdmit11but I think I'll stick with records and protocols and a bunch of helper macros
10:11vdmit11thanks for the discussion anyway
10:11dysfuncool
10:12osfameronprotocols are oddly disappointing in several ways
10:12osfameronbut I do like the way that they "tag" the data
10:13dysfuni think they serve their purpose adequately
10:13osfameronsure
10:13justin_smithosfameron: what do you mean by tag the data?
10:13dysfunthey are just post-extensible interfaces
10:13osfameronjustin_smith: instead of being a map, it's a map with a type
10:14justin_smithosfameron: what 0 or more types
10:14justin_smithfor a record, that is
10:14justin_smitha protocol is just one of those types
10:14osfameronsorry yes, I'm confusing protocol and record :-(
10:14dysfuna protocol does tag the type with something, but only (satisfies? proto-name thing) finds it of use
10:14justin_smithI've used records for debugging - so that I could identify who created a given item in the profiler
10:15dysfunjust add a key?
10:15osfameron(I'm using them kinda in sync)
10:15justin_smithdysfun: the profiler doesn't show keys very readily
10:15dysfuni have really gone off records in the general case
10:15justin_smithbut it does show the class quite readily
10:15dysfunah
10:17osfameronI kinda want ADTs... I know there are extensions to get them, but there's no point working against the language, especially while you're learning
10:17vdmit11One more little question: is there some standard protocol or maybe an interface that I can use to implement math functions (like + and -) for my custom data types?
10:18justin_smith+ and - are not abstract
10:18justin_smithintentionally, for performance
10:18vdmit11but the Java method dispatch is almost free, isn't it?
10:18justin_smithnot cheap enough for the raw math
10:19justin_smithor so the implementors of clojure decided at least
10:20osfameronand there's no standard (with-abstract-maths) macro that rewrites e.g + into an abstract +' function? ;-P
10:20vdmit11ok, I expected that you have abstract versions by default, and provide some performance-oriented versions in addition (like the unchecked- functions are implemented)
10:24dysfunosfameron: i want ADTs too. but in clojure i settle for maps with a key
10:24dysfunand i use spec to make sure they're valid
10:25osfameronand one day spec will have a tutorial I can understand, and I'll use it too
10:25dysfunanyone know how to make boot do things like "copy the build artifact into this directory, git commit and git push"?
10:44Empperidysfun: can't remember how but yeah, that's possible
10:45dysfunwell of course it is :)
10:45dysfunas ever with boot, it's just more complex than it needs to be
10:59osfameronmore complex because of its design?
10:59dysfunyes
10:59osfameronah, so not just the lack of docs and supplied tasks
11:00dysfunanyway, you won't be surprised to hear i now have a shell script with a big case statement
11:00osfameron\o/
11:00dysfunbecause life's too fucking short
11:01osfameronthe basic idea of middleware and pipelines sounds sensible enough... but the extent of my tweaking so far is to add `(test)` to the build task generated by boot-new...
11:01dysfunoh sure, i buy the theory
11:01dysfunbut build is where i want tooling to just work, and boot rarely does
11:01osfameronit it worth persevering with?
11:02dysfunconsequently i copy and paste bits from files like it's 2005
11:02osfameron$boss pointed us at it because "it's more modern than leiningen"
11:02dysfunboot is more powerful than leiningen
11:02osfameronand I'm using it at home purely because might be useful for work
11:02dysfunwhile i don't *like* boot, i do grudgingly use it because it's powerful
11:02dysfuni don't use leiningen at all for my own projects
11:03dysfunmade the switch a couple of years ago
11:04osfameronah. interestingly, I got the feeling that people actually *liked* lein?
11:04dysfunoh yes, if it solves your problem, it's generally likeable
11:05dysfuni think only a handful of people like boot, but god is it useful
11:05osfameronas the only thing I want it to do is run tests, build a jar, run a repl, and create a new project, boot handles all of those things (except the last one)
11:06dysfunyou lack imagination so far
11:06osfameron(yes, I know about boot-new. I enjoy googling for it every time I need it ;-)
11:06dysfunthat's trivially wrappable with a shell script though
11:07dysfunyou don't have to forget the old ways just because you use a lisp, you know
11:07osfameronsure. googling is also one of the old ways I guess
11:07dysfundefinitely
11:07osfameronI'm sure one day I'll think of something else to do with a build system
11:07dysfunand i don't know how i'd program clojure if i weren't over 9000 in googling
11:10TimMcdysfun: When do you drop back to makefiles?
11:11dysfunwhen i want the built in mtime checks
11:11dysfunbut yes, that would be just as easy
11:58justin_smithwhy not just split calculating dependencies vs. build logic? almost makes sense
12:03osfamerondamn all this thinking. I now have a better idea for a data structure having already written lots of code :-(
12:09dysfundamnit, anyone good at css?
12:18ragepandemicIs there any guide explaining how to add a plain react library (E.g. for file uploads) to reagent?
12:33dysfunoh hey ragepandemic, i deployed my first rum app today
12:33dysfuna few minutes ago, in fact
12:36ragepandemicdysfun, I tried rum last night and me and tolstoy had a long discussion about it
12:36ragepandemicI couldn't get it to work with :did-mount, for some reason that behaviour was broken on my system
12:37ragepandemicwhich is annoying because it seems like a great library
12:40justin_smithoh, they call it :did-mount instead of :component-did-mount ?
12:42dysfunyes, rum is very into short names
12:42dysfunno argument from me
12:47ragepandemicso, the problem was that the :did-mount mixins return value was ignored. i thought it might be the CLJS version, but nah
12:55ragepandemicanyway, here's the code https://www.refheap.com/124527 I thought you might know since you're a "rum guy"
12:59ragepandemiccongrats on your deploy by the way, can we see it?
13:15jeayejonathanj: I've seen that talk and I don't think it applies.
13:15jeayeI was worried that my question might be interpreted as such.
13:15jeayeI'm not asking the common question of "How can I verify that my map _only_ has these keys?" I'm asking "How can I verify that my map has anything _but_ this key?"
13:16jeayeThat doesn't violate Rich's proposal, in the talk, the way I see it.
13:16dysfunragepandemic: the rum bit is private, i'm afraid
13:17dysfuni use rum quite simply i'm afraid, i'm not the best to help with all the lifecycle stuff
13:17ragepandemicah, shame. so, any conclusions? rum vs reagent?
13:17dysfunwell i never liked reagent at all, so yes
13:18ragepandemichow do you architect your frontend apps? redux/re-frame style?
13:18dysfunokay, 'at all' might be a little strong, i found it too limiting
13:18dysfuni have a single source of truth atom and everything is just subatoms into it
13:19dysfuneverything is wrapped into reusable components and reused
13:19dysfuni have things like a reorderable list that allows insertion of a new item at any point
13:20ragepandemicare subatoms conceptually similar to cursors?
13:21dysfuner they even call them cursors
13:22ragepandemicand how do you modify the app state? with events?
13:22dysfunragepandemic: okay, your bugs is that ::time is an atom
13:23dysfunso mix in @ or rum/react as appropriate
13:23ragepandemicso I should be doing @(::time state)?
13:23dysfun(i think)
13:23dysfunyes
13:24ragepandemicalright, let me try
13:24dysfunoh hang on
13:24ragepandemicnope, its a null value
13:24dysfunsorry, i thought you were using (rum/local
13:24dysfunwhich well, i'm not sure why you're not
13:25dysfuni hate frontend
13:25ragepandemicok, i think I know why. on-js-reload wasn't called on init
13:26ragepandemicor it was, but it wasn't called twice?
13:26ragepandemicI mean, it only works when I call (on-js-reload) again
13:26ragepandemiceven though its already called once
13:27ragepandemicso this fixes it https://www.refheap.com/124528
13:28dysfunthat's a bit fugly
13:28ragepandemicyea, that's not a fix
13:29ragepandemicit should work on first call, right?
13:29ragepandemicThe first time it just renders "The mount time is:" with no datetime
13:30dysfunwell, if you made it a state atom that was reactive and updated it on mount, that would work better
13:30ragepandemictrue, but I was following the readme
13:30dysfunthe readme could be better
13:30ragepandemichttps://github.com/tonsky/rum#writing-your-own-mixin
13:30ragepandemic4th example down
13:31ragepandemicits a bug though, right?
13:31dysfunno idea, far too tired to think properly
13:32ragepandemiceh, i'll continue using reagent for now
13:35ragepandemicthanks for your help
13:37dysfunyw
14:13jonathanjjeaye: i think it's more or less the same thing, isn't it?
14:42jeayejonathanj: Not at all. What Rich is speaking against is preventing the growth of code, and data, by limiting the shape of it to a specific key set. I'm talking about unrestricted growth of data, with the knowledge that a certain key will never be present.
14:43jeayeI think they're fundamentally different. How else would you write the :ret spec for something like dissoc? It's the input map, guaranteed to not have the specified key; it can have anything else though.
15:35TimMcI should watch the spec keynote. The inability to forbid keys is one of the reasons I haven't bothered to pick up spec.
15:36TimMcI want to protect against misspelling an optional key, basically.
15:42vdmit11well, a custom predicate function may be used to ensure that all keys belong to some pre-defined set of keys
15:43vdmit11so it is possible to forbid keys, but there is no first-citizen support for this
17:18jeayeTimMc: It's not an inability, as vdmit11 mentioned; it's quite simple, actually. There's just no built-in support for it.
17:19jeaye(s/def ::without-foo #(not (contains? % :foo))) ; does the trick
17:22dysfunwhich doesn't fit the states use case (key misspellings)
17:26jeayedysfun: As the one who originally brought up the use case, which was not anything to do with misspelling, it absolutely does fit it.
17:26dysfunsorry, i mean timmc's stated use case
17:27dysfuni didn't read quite far back enough to see your use case
17:27jeayeAh, right.
17:27jeayeI was looking to spec a function similar to dissoc, where I just want to convey that the output map would be anything without a specific key.
17:28dysfunnot a chance :)
17:28dysfunnot for the general case anyway
17:29TEttinger,(let [ugly {Double/NaN :a (/ 0.0 0.0) :b}] ugly)
17:29clojurebot{NaN :a, NaN :b}
17:29jeayedysfun: This isn't a general case.
17:29TEttinger,(let [ugly {Double/NaN :a (/ 0.0 0.0) :b}] (dissoc ugly Double/NaN))
17:29clojurebot{NaN :a, NaN :b}
17:29jeayedysfun: The spec I laid out above is exactly what matches my case.
17:29dysfunah okay
17:29dysfunin that case, great :)
17:29jeaye(defn clean-internal [data] (dissoc data ::internal)) ; basically
17:31osfameronwhat are the double-colon keywords used for?
17:32jeayeosfameron: They're fully-namespaced, which helps with cleanliness and prevents collisions.
17:33jeaye::foo may expand to :my.ns/foo if I'm in my.ns
17:33jeayeIt also works with required aliases, so I can (require '[foo.bar :as bar]) and then ::bar/spam to get :foo.bar/spam
17:34osfameronah
17:35osfameronI've not seen a need to namespace keywords *yet*, will try to remember that for when I do :D
17:35dysfunwell if you're using spec, you will
17:35dysfunoddly enough the reader got some namespaced keyword related adjustments in in the 1.9 series
17:37osfameronyeah, I've seen :: in the spec docs, but as those make my eyes glaze over, I hadn't figured out what they were for ;-)
17:37jeayeosfameron: Outside of spec, they're good to describing ownership of data. With normal keywords, anything goes, but dependencies are much more explicit with namesapced keywords.
17:38dysfunnote that i still haven't fully drunk the namespaced keywords koolaid
17:38dysfuni am much more inclined to use :req-un than :req
17:39osfameronright, after I've done my lambdalounge talk in a few weeks, I'll give spec another go
17:40osfameronI got really grumpy about the docs being full of meaningless waffle and not enough examples
17:40dysfunoh, will you be boring people about haskell?
17:40osfameronI suspect that will get better when spec gets stable?
17:40osfameronnope, clojure examples. data structures for text editors
17:40dysfun"docs will get better when clojure gets more stable"
17:41osfameronthis is the talk synopsis: https://github.com/RickMoynihan/lambdalounge-website/pull/1
17:41osfameronheh, no. which is why I might as well try to stop being grumpy and see if I can figure anything out despite the docs...
17:41osfameronbut I have enough on my plate for a few weeks
17:41dysfunwell, i did a launch today
17:42osfameronwoo
17:42dysfunand fuck, the prod build is insanely faster than the dev one
17:42osfameronyay
17:42dysfuni have now filled my frontend hump and wish to not do any frontend for the rest of the year
17:57jeayeIn two current ~2K line projects, I'm using namespaced keywords everywhere in one and nowhere in the other. When comparing, I very much prefer the former.
17:58dysfuninteresting
17:58dysfuni'm only using namespaces for specs, and keys in spec maps i'm stripping the namespace with :req-un
18:06machinewarany core function that does opposite of ffirst, looking for something like (comp last last)
18:06machinewarI really want to get the value in a 1 element map
18:07machinewar(llast {:name "foo"})
18:11WhiskyRyanHow can I create an empty collection of type x, where x is a var containing a collection of an unknown type?
18:11justin_smithmachinewar: I would use (comp val first) - at least that makes it clear you are getting something out of a hash entry
18:11ridcully_WhiskyRyan: empty
18:12machinewartrue
18:12machinewarthanks that makes sense
18:13WhiskyRyanridcully: That was easy... ha. Thanks!
18:13WhiskyRyanridcully_: That was easy... ha. Thanks!
20:06TimMc,{(rand) :a (rand) :b} ^_^
20:06clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: (rand)>
20:10scriptor,(defn f [x] (rand))
20:10clojurebot#error {\n :cause "SANBOX DENIED"\n :via\n [{:type java.lang.Exception\n :message "SANBOX DENIED"\n :at [clojure.core$eval29$fn__30$fn__43 invoke "NO_SOURCE_FILE" -1]}]\n :trace\n [[clojure.core$eval29$fn__30$fn__43 invoke "NO_SOURCE_FILE" -1]\n [clojure.core$eval29$fn__30 invoke "NO_SOURCE_FILE" 0]\n [clojure.core$eval29 invokeStatic "NO_SOURCE_FILE" 0]\n [clojure.core$eval29 invoke "NO_SO...
20:10scriptor{(rand 2) :a (rand 4) :b}
20:10scriptor,{(rand 2) :a (rand 4) :b}
20:10clojurebot{1.8215813500926088 :a, 3.8151065102200437 :b}
20:11TimMc,{(identity (rand)) :a (rand) :b} Or just this.
20:11clojurebot{0.7840885619436757 :a, 0.5429409650182597 :b}
20:11justin_smith,{(rand 1N) :a (rand 1) :a}
20:11clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: (rand 1N)>
20:11justin_smithwoah!
20:11TimMc,(= 1 1N)
20:11clojurebottrue
20:12justin_smith,(type 1N)
20:12clojurebotclojure.lang.BigInt
20:12justin_smithit mist just check equality of keys at read time
20:13scriptorlooks like it
20:13scriptor,(hash-map (rand) 1 (rand) 2)
20:13clojurebot{0.17756123528665302 2, 0.26561328496261327 1}
20:36WhiskyRyanIs there a function to do: "hello" -> ("h" "e" "l" "l" "o") ?
20:37ridcully_,#:foo{(rand) :a (rand) :b}
20:37clojurebot{0.7513892950513176 :b}
20:37ridcully_,(seq "hello")
20:37clojurebot(\h \e \l \l \o)
20:37justin_smith,(map str "hello")
20:37clojurebot("h" "e" "l" "l" "o")
20:37ridcully_oh you want strings
20:38WhiskyRyanthere we go... map str... thanks