This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-03-31
Channels
- # admin-announcements (1)
- # beginners (16)
- # boot (25)
- # braid-chat (7)
- # cider (4)
- # cljsfiddle (6)
- # cljsrn (1)
- # clojure (256)
- # clojure-austin (4)
- # clojure-ireland (1)
- # clojure-poland (15)
- # clojure-russia (80)
- # clojure-uk (2)
- # clojurescript (30)
- # core-async (14)
- # core-typed (3)
- # cursive (35)
- # datomic (1)
- # editors (28)
- # hoplon (32)
- # immutant (1)
- # jobs (8)
- # jobs-discuss (1)
- # juxt (6)
- # leiningen (8)
- # liberator (7)
- # off-topic (16)
- # om (69)
- # onyx (38)
- # re-frame (10)
- # spacemacs (1)
- # untangled (117)
I got code shamed about my documentation today so was looking to improve it. JSDoc format seems ok.
if you are talking about what seancorfield linked to before, those are prose documents, any blogging platform / wiki will let you write those, they aren't generated from docstrings or comments in the code
I have been interviewing, around and had a 200 line answer to a coding challenge (200 lines including some function docstrings and tests) dinged for not including documentation
@base698: Yes, I used to run the SF Clojure meetup (for a couple of years). Kind of a pain since I live out in the East Bay and it’s a hike into SF at rush hour.
As for the prose docs I linked to, they’re maintained by a team of folks and use Jekyll to generate static HTML from Markdown, as I recall.
World Singles is 100% remote. We might (may be, possibly) be hiring a junior Clojure dev later this year.
Far too junior for you @hiredman — sorry 😞
I know your background! Unfortunately I think we’re more likely to hire fresh out of college this time around and grow someone into the team.
(so we may well look for someone who is interested in FP, played with Clojure, but has pretty much zero actual workplace experience)
We haven’t fully decided yet.
I’m a bit surprised there aren’t more remote senior roles out there, to be honest.
Remind me where you’re based?
Ah. You’ll be at Clojure/West in a few weeks?
oh cool I am looking forward to meeting all of you guys 😉
I may bend your ear about that java.jdbc reducers ticket you opened…
Esp. after the unfold
post on the list.
ahahahah
I read that too nice
I made a proposal of adding unfold as a function to clojure.core after our discussion yesterday
@hiredman, @base698: one problem with blogging platforms are that once the source code changes or the api changes, the tests have to be rewritten
It’s trival to change tests… but it’s a bitch to change documentation because you don’t even know where it broke
anyways… so by having documentation examples that are tests, the documentation can be updated very easily
so there is something there: https://github.com/helpshift/hydrox/blob/master/src/hydrox/analyse/test/clojure.clj
yeah, I don’t use midje. I don’t like adding more deps than I need to. And when I was learning clojure, clj.test was easier to pick up.
https://github.com/helpshift/hydrox/blob/master/test/hydrox/analyse/test/clojure_test.clj#L16-L24
so:
^{:refer example/hello-world :added \"0.1\"}
(deftest hello-world-test
"Sample test program”
(is (= 1 1))
(is (identical? 2 4)))
@zcaudate: have you seen Midje-readme? Runs the code / output in your readme as Midje tests.
so if you don’t run that command import, then no, the docstrings will remain the same
I had never heard of it until I saw someone sent a PR for clj-time.
@base698, @roberto, @seancorfield: once a project reaches a certain size (when readme.md starts getting really heavy), the testable documentation becomes invaluable.
there is no way I could have produced (and maintain) something like this: http://docs.caudate.me/hara/hara-event.html
this was a while back… http://z.caudate.me/midje-%60lite%60-for-clojurescript/ the clojurescript documentation was generated: http://purnam.github.io/purnam/
I just think it was not sold
appropriately, it took me a while to understand its benefits
most of the demos were focused on demo candy
, and I couldn’t figure out the why
and when
hey whats the best way to send initial data to the client? if I have a server should I wait for a websocket on-open event and then send the initial data over transit?
Is there some kind of macro toolkit/helpers? In particular, is there libraries that find all possible return values of form? (By walking into common structures like case/cond/when
etc...).
@rauh: have a look at http://clojure.github.io/tools.analyzer.jvm/spec/quickref.html
Not sure I'd suggest using tools.analyzer.js
, it depends on an ancient version of clojurescript and hasn't been updated in a while
what I want to be able to do is something like ...
(ns my.module
(:require [com.somelib :as somelib]))
...
(defn myWrapperAPICall []
... modifies args, other stuff
(somelib/APICall modifiedStuff))
// another ns
(ns another.module
(require '[my.module :as m]))
(m/myWrapperAPICall ...)
(m/someLibAPICall ...) <- not explicitly wrapped/exposed
But I'm not sure how to provide only a subset of enhancements without wrapping the entire api? For example, if I were wrapping ring, I wouldn't want to provide my own implementation for each and every function, 99% of which would just refer to the actual ring implementation.
How can I require a lib and all it's functions, then "expose" it as my own with just a few overrides?How do I override behavior of a library or "shield" myself from its own changes (at some point int the future)?
for e.g., in the javascript world, apis change every other day and frameworks go in wild directions that I dont necessarily agree with.. rather than fork /maintain my own, I usually bring the module into my project but maintain my internal app-specific api
you use the version that you started with, as long as you don't upgrade - everything is fine
thinking of React, for example - 13.1/2/3/4...15.1/2/3 etc.. They all provided some much-needed performance updates / bug fixes, but they also introduced non-trivial api changes with regards to object creation, etc. If I didn't have a facade in my internall app api, I would spend hours every week just trying to keep up.
So this facade has to manually provide each and every api that I might need in the app, even if it's a direct call to the lib api?
here the top ns is a huge bag of all functions in sub-nses, but this would work with other dependencies as long as they are in the classpath
This is helpful, thanks @dm3 and @mpenet. To give you some larger context (if you care at all), my plan was to use component [https://github.com/stuartsierra/component] as a IoC container for my app, and to inject my own implementation of necessary libs so I could override/enhance with ease. Something like:
(ns app-reframe.core (:require [reagent.core :as reagent])
(defrecord Reagent []
component/Lifecycle
(start [component]
reagent)
(stop [component]
component))
(defn init [] (->Reagent))
and I'm quite sure I could maintain them if the original maintainers went a way I didn't like
"Shielding" aside, just using the IOC pattern above ^ it would be really great for testing purposes to be able to stick in a mock via injection. What stinks is having to someone expose the entire api of reagent inside that (start [component] reagent/a /b /c ... etc)
(not sure the syntax to do this even)
Interesting, I'll have to take a look at Mount. I have investigated Hoplon but it just didnt fit my usecase as neatly as reagent, I don't think.
Well, the major weak-point with Hoplon is there's no react-native option... so when things like https://github.com/ptmt/react-native-desktop start to appear, I just feel disadvantaged not having react around.
The value prop is just too tempting. Taking 1-2 weeks to make some modifications/fork to support an entirely different platform or take months to learn a whole new stack and write parts of your app twice.
I just peaked at Mount, thanks for that tip btw... it actually seems like a better deal right from the get-go.
not everything is method-object-ey like in component, and there's no full-app buy-in
Yea me neither, I've always wanted to poke around with electron/nwjs but just haven't had the time.
hi everyone! I have this problem with compojure and multiple middlewares I use components
:site-handler (handler-component (:site-app config))
:http (jetty-server (:http config))
:site-endpoint (endpoint-component site-endpoint)
:api-endpoint (endpoint-component api-endpoint)
with deps
:http [:site-handler]
:site-handler [:site-endpoint :webhook-endpoint :api-endpoint]
:site-endpoint {:db :db
:input-chan :notification-worker-in-channel}
:api-endpoint {:db :db
:channel :notification-worker-in-channel}
in site routes I have something like this:
(defn site-endpoint [{{db :spec} :db input-chan :input-chan}]
(-> (routes
;; more routes
(POST "/send-message/:channel-id" [channel-id :<< as-int :as request]
(message-route/send-message db input-chan channel-id request))
(resources "/"))
(wrap-routes (fn [handler]
(-> handler
(wrap-access-rules {:rules rules :on-error on-error})
(buddy-middleware/wrap-authorization backend)
(buddy-middleware/wrap-authentication backend)
(defaults/wrap-defaults defaults/site-defaults)
)))))
and in api
(defn api-endpoint [{{db :spec} :db channel :channel}]
(api
{:swagger {:ui "/api-docs"
:spec "/swagger.json"
:data {:info {:title "PushToTelegram Public API"}}
}}
(context "/api" []
(GET "/send/channelMessage" []
:return {:channel-id s/Int
:recipients-count s/Int}
:query [message ApiChannelMessage]
(api-route/send-channel-message db channel message))
)))
and then in handler component they are combined with (routes api-routes site-routes)
in post route I have ring antiforgery exception, because of api-middleware, and the only way I can fix it is to wrap api routes with some context, e.x (context "/my-api" [] (api ;; etc))
but then I have swaggers docs broken with wrong api urls
What is the right way to split api and site routes in web app?@andfadeev what kind of antiforgery-exception do you get? Have put all the static routes too under api. wrapping into undocumented
makes them not to appear in swagger-docs.
api-middleware uses ring-middleware-format, which might cause problems as it consumes the body (which is the mutable part of the request).
I get Invalid anti-forgery token in site post routes, recently I did not use compojure-api, it was compojure route with (context "/api" [] ...) wrapped with api-defaults
but - creating the API with a separate function and mouting it to /api context works I believe?
yes, with context in works, but then in swagger docs urls are "/api/method" but with context they really are "/api/api/method"
https://github.com/metosin/compojure-api/wiki/Swagger-integration#via-api-with-options
dm3: component is not really "method-object-ey", you can just use maps if you dislike records and has the merit of being mutation free compared to mount
Good morning! Anyone know what :>> is? I see condp uses it, but that's the first i've been aware of it
I'm trying to "rotate" a matrix, and if each column doesn't have the same number of items, that column goes missing, but I'd like to keep it. Here's my approach:
(def m [[1 2 3] [4 5 6] [7 8]])
(apply map vector m)
I've thought about padding shorter rows with nil
, but I don't want to artificially change the matrix for just processing reasons. Thougts?For example, even this returns an empty list:
(apply map vector [[1] [2] []])
I want to keep all vectors, so in the second example, I'd like [1 2]
not quite, I'd like [[1 2 3] [4 5 6] [7 8]] to turn into [[1 4 7] [2 5 8] [3 6]]
possible?
the problem lies with map
, it maps until one of the collections is "exhausted", or out of items. But I want it to keep going...
do I need to roll my own map
? I think there'd be an easier way...
(loop [remaining [[1 2 3][4 5 6][7 8]] result []] (if (not (every? (comp not empty?) remaining) ) result (recur (map rest remaining) (conj result (mapv first remaining)))))
😞 If I pad, I'll need to pad + unpad over many iterations. It seems wrong to modify the data like this to allow it to process correctly, no?
(loop [remaining [[1 2 3][4 5 6][7 8]]
result []]
(if (every? empty? remaining)
result
(recur (map rest remaining)
(conj result (remove nil? (mapv first remaining))))))
This works. Check it out!you inspired it
or more generally:
(defn rotate [mat]
(loop [remaining mat
result []]
(if (every? empty? remaining)
result
(recur (map rest remaining)
(conj result (remove nil? (mapv first remaining)))))))
(rotate (repeat 5 (range 5)))
actually, I think that flips the matrix around a diagonal, this should rotate it:
(defn rotate [mat]
(loop [remaining (map reverse mat)
result []]
(if (every? empty? remaining)
result
(recur (map rest remaining)
(conj result (remove nil? (mapv first remaining)))))))
(I map reverse
over the input matrix before processing it
@josh.freckleton: I usually stick to higher level functions to do the legwork of transforming a data structure
(defn- keep-each
"Applies f to each seqable in coll with keep to eliminate nils.
Runs until every seq is exhausted"
[f coll]
(when-not (every? empty? coll)
(lazy-seq
(cons (keep f coll)
(keep-each f (map next coll))))))
where rotate
now becomes
(defn rotate [matrix]
;; Take the first element of each seq producing a new seq
(keep-each first matrix))
It sounds like you’re writing a transpose
matrix function, but with some data missing. If you’re willing to pad (and then remove, of course) with nil
Here’s a non-general idea
(def items [[1 2 3] [4 5 6] [7 8]])
(->>
; pad with nils
(for [[x y z] items] (vector x y z))
; do the transpose
(apply interleave)
; remove padding
(filter some?)
; Resort back into partitions
(partition-all 3)
; Convert back into vectors
(map vec)
; Convert entire list back to vector
vec)
Have you looked at core.matrix
?
It has a function just for you https://crossclj.info/fun/clojure.core.matrix/transpose.html
@jr: awesome! Ya keeping it higher level is a good idea, I like what you did.
@jamesleonis: the padding is a good idea, just a little expensive of an operation to do/undo many times. And I looked at core.matrix
, but transpose isn't quite the same as rotate, right? Maybe it has something else I'd need though, and I like how it can use BLAS, sounds fast.
@josh.freckleton: as far as your “rotate” function is concerned if you want [[1 2 3][4 5 6][7 8]] to turn into [[1 4 7][2 5 8][3 6]] it might be easier to first write a function which extracts a column from a matrix by going over each row and taking the nth item from it. then you could map that function over your matrix using a range from 0 to the number of columns in your matrix - 1. by then end you should have a set of vectors representing each column in the matrix effectively rotating it 90 degrees
(def mat [[1 2 3] [4 5 6] [7 8]])
(defn column [matrix index]
(->> matrix
(map #(get % index))
(filter (complement nil?))))
(defn rotate [matrix]
(let [columns (apply max (map count matrix))]
(for [c (range 0 columns)]
(column matrix c))))
(rotate mat)
=> ((1 4 7) (2 5 8) (3 6))
Is this what is best practice? https://wiki.jenkins-ci.org/display/JENKINS/leiningen+plugin
hmm, I have not used that, we just always have latest lein
installed on the jenkins workers
yes, most of our builds involve multiple calls to lein
among other things so we just wrap everything in a bash script and have jenkins call that
@adamkowalski: Ah, I hadn't heard of Neanderthal, that looks awesome, thanks
This has happened to me twice now: I’m in the repl, I run a rethinkdb query that throws an exception that renders the repl unresponsive. If i kill the repl (and any running java processes) and try to run lein repl
again it keeps timing out. Any ideas? (Im on Mac)
@afhammad: Is the REPL’s port still in use by any chance?
@manutter51: as far as i can tell, no.
I found this SO question that has some info about how to check: http://stackoverflow.com/questions/3855127/find-and-kill-process-locking-port-3000-on-mac
Other than that, all I can think of is lein clean
@afhammad: where is the exception coming from? Is it thrown by the library, or by your code?
Are there any side effects that are being run on lein repl
startup, e.g. connecting to RethinkDB?
@danielcompton: exception from lib, no nothing explicit happening on repl start
in my project.clj
:ring {:handler search.api/handler
:init search.main/init
:nrepl {:start? true :port 7804}
:auto-reload? true
:configurator
~(fn [jetty]
(doseq [connector (.getConnectors jetty)]
(.setHeaderBufferSize connector 8388608)))
As far as I know, Lein-Ring doesn’t support the :configurator option, @jasonjckn
@weavejester: you wouldn't know by chance how to solve HTTP 413 FULL head would you?