This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-15
Channels
- # arachne (6)
- # aws-lambda (3)
- # beginners (14)
- # boot (56)
- # cider (8)
- # cljs-dev (5)
- # cljsrn (11)
- # clojure (240)
- # clojure-dusseldorf (3)
- # clojure-greece (165)
- # clojure-italy (5)
- # clojure-romania (1)
- # clojure-russia (24)
- # clojure-uk (30)
- # clojure-ukraine (3)
- # clojurescript (29)
- # core-async (6)
- # css (1)
- # cursive (25)
- # datascript (6)
- # datomic (61)
- # dirac (1)
- # events (3)
- # hoplon (1)
- # instaparse (3)
- # jobs (4)
- # juxt (28)
- # lein-figwheel (7)
- # leiningen (19)
- # luminus (1)
- # lumo (2)
- # nyc (1)
- # off-topic (19)
- # om (25)
- # onyx (4)
- # parinfer (2)
- # pedestal (23)
- # perun (20)
- # re-frame (44)
- # reagent (20)
- # remote-jobs (3)
- # ring (3)
- # ring-swagger (5)
- # rum (12)
- # slack-help (3)
- # spacemacs (25)
- # specter (62)
- # sql (16)
- # unrepl (313)
- # yada (4)
@seancorfield Am I correct in understanding that with-db-connection
in clojure.java.jdbc
is useful only if you want to re-use the same connection for several different actions?
B/c functions like insert!
will automatically manage connections when given a DB spec
@xiongtx Yes, that is correct. The recommended approach is to use a connection pool anyway, then you don’t need to worry about “reusing connections” — see http://clojure-doc.org/articles/ecosystem/java_jdbc/connection_pooling.html for examples
Then you use the pooled connection (the map containing :datasource
) as a db-spec
in all calls.
(ns interface.a)
(defprotocol X
(x [this]))
(ns interface.b)
(defprotocol X
(x [this]))
(ns test.defrecord)
(defrecord Example []
interface.a/X
(x [_] :a)
interface.b/X
(x [_] :b))
(interface.a/x (->Example)) ; => :a
(interface.b/x (->Example)) ; => :a (not :b)
@ajchemist it seems that it is: http://stackoverflow.com/questions/4839013/how-does-clojures-defrecord-method-name-resolution-work
@tbaldridge now i see, thanks for the quick note
I've recently picked up Quil since I thought it was interesting to see the digital art created with it. I'm curious though. Is Quil actually used in production or is it more of a toy library for programming pleasure purposes ?
@jmb I am most interested in it as a vehicle for teaching functional programming with Clojure/Cljs as the vehicle. Quil (and Processing) make drawing/animation easy; this is attractive to students.
Yeah I think Clojure is friendlier towards taking you to the FP realm compared to other FP languages. I asked because I wanted to specialize in a certain area of Clojure for blogging purposes. I don't mind blogging about Clojure in general, but it just felt too generalized. My choices of specialization in Clojure were either Quil, Reagent, or Datomic. I was probably gonna go with Reagent sprinkled with Datomic since it seems more valuable for web development purposes.
@jmb not an awnser to your question, but I also like quil because you can also use it in clojurescript, actually I used it in clojurescript first, but in some time I will try the same draw function in clojure.
@jmb I’ve used Quil a fair bit but I’ve since moved to Karsten Schmidt’s http://thi.ng libraries: http://thi.ng
Quil is good but it imoses sequencing issues on where you can do what, which kept tripping me up (I’d try to calculate something outside the drawing calls then found I couldn’t refer to the calculation how I’d like)
The http://thi.ng libs don’t suffer from this. They’ve a much larger surface area, but there’s tons of great stuff in there if you’re into digital art generation
Just noticed Karsten’s on Slack at @toxi
I was at a http://thi.ng workshop on generative design last June, there’s a blog post about it (by Karsten) https://medium.com/@thi.ng/workshop-report-generative-design-with-clojure-7d6d8ea9a6e8#.208ff21e8
you can try also my clojure2d (https://github.com/Clojure2D/clojure2d), where you can also can separate calculations from displaying stuff. Still poorly documented though but I prepared 20+ examples.
I saw this pop up on github recently and it looks super-cool. Haven’t tried it out yet but I really like the motivation for the project and the example images you posted. Tangentially, do you have any recommendations for books/websites/other resources on digital art? I’ve been meaning to get back into it.
https://www.reddit.com/r/generative/comments/5z4uxj/beginners_guide_to_generative_art/
And thanks for kind words about project. I'm moving from processing gradually to make all my stuff in Clojure. This library grows with me and my progress. I'll be doing live coding soon and such example also appear in repo.
Thanks, I’ve seen some of the shiffman stuff (his enthusiasm is a thing to behold)! Definitely want to take a look at your generateme wordpress - I love it when people comment their process. Maybe I’ll try the blogging thing, seems like a good way to stay productive
I often get requests like "wow, can you elaborate how it's made?" and then I post a blog around the topic
Hi! I wrote a new clojure/script routing library. It looks like ruby on rails routing but different. It have support for mountable apps and named routes. I will be glad to see the feedback. Please add star to repo If you like it. https://github.com/darkleaf/router
@lvh that's a key part of how it achieves optimal performance
those are the inline caches
if you use select*
, transform*
those aren't created, but you lose all the callsite optimizations
i'll look into that
if it was like com.rpl.specter.pathcaches.my.full.namespace/pathcache12345 I wouldn’t care
(also if it was marked private it’d be … marginally better, this code would still care but presumably my editor wouldn't)
I want more info than (read-string (slurp fname))
I want the precise column/row of every symbol.
The meta information si only provided on lists/vectors, but not every symbol (like string + number).
@lvh easy fix, now in master
I'm seeing all these complicated examples, but I just want the tools.analyzer.jvm equiv of (read-string (slurp %))
@nathanmarz Cool, thanks 🙂
I'm writing a STLC type checker for a subset of clojure. I need to take a *.clj file, display it in SVG, and then annotate it with type info. For the "display in SVG part" -- I really want it to match the original layout, not just some "prettyprint of sexp". @bronsa
a reader goes string -> data, some data (e.g. numbers/strings/keyword) doesn't have a slot for metadata so there's no way to annotate it with line/col/original whitespace/comments info
where one of the field is the actual symbol, and the other fields ar emetal info like row/column
all the limitations of tools built on top of a reader thus cascade into tools.analyzer
so (1) tools.analyzer can't help me since it does sexp -> lots of info; and at the sexp level, the strings / numbers don't ahve meta data (2) tools.reader can't help me since it does "string -> sexp", but again, at the sexp level, strings/numbers don't ahve meta data
i've thought about splitting tools.reader into a parser and a reader and having t.a use the parser before
but it's a significant amount of work (esp trying to keep parity with current performance) and I don't have time for it
@bronsa: thanks for "verifying this can't be done with existing tools"; rather useful for time saved
doing what you're trying to do was never a goal of neither tools.reader or tools.analyzer
@bronsa: I don't need support for reader macros. Are ther eother libraries I should look into (or just roll my own) ?
dunno if any of them come with parsers defined for the clojure language but it should be easy
why not? suppose we have (+ x y) I want to display above it with + being float->float->float, x:float, y:float
if you're the parse tree just for overlaying info that you gather in other ways, then fine
suppose I had this problem: I want type info on every symobl in my source. How would I solve this problem? (I don't know anything better than what we hav ediscucssed so far).
you also seem to be glossing over the fact that type checking in clojure is really hard
I'm writing in a restricted subset of clojure where only STLC checkable programs are considered valid.
Is there an example of using httpkit client to do streaming chunked transfer requests to a server? (I want to upload gzipped batches of files)
@bradford so not exactly a stream, but chunks...
let me snoop around, it sounds familiar
So, just to clarify a bit...
you have lots of files, you gzip them on client
you want to send them to the server in batches, have the srvr weave them together? @bradford
Well, http-kit has :multipart which may work for you out of the box.
but if the files are large, you may not care to read their contents into client memory before sending them
(not fully anyway)
@sova That's correct. This is for a proxy network -- I have proxy clients that grab a few files, compress them, and send them back to the proxy server (which is running Pedestal). I'd like to simulate that client. Each server has about 200k open connections.
So I'm trying to solve 4clojure problem 85 (http://www.4clojure.com/problem/85) where you have to generate a powerset for the given set.I've solved it with a strategy that generates combinations of a certain size of the given set and joining the resulting sets together. It works for smaller inputs but times out for larger ones. I'm new to clojure and CS in general and wondering if there's a broad area I should tackle first as far as optimization goes. Here's my code:
(defn power-series2 [s]
(if (= s #{})
#{#{}}
(set (let [get-series-ele (fn get-series-ele [cur-set size]
(set
(if (= (count cur-set) (dec size))
(map #(conj cur-set %) (apply disj s cur-set))
(apply concat (map #(get-series-ele (conj cur-set %) size) (apply disj s cur-set))))))]
(apply concat #{s #{}} (map #(get-series-ele #{} %) (range 1 (count s))))))))
@bradford ah client simulation. nice.
httpkit has http/response ... i use web sockets via sente for client->server. If you want to stick to http kit only....
@bradford and in the case of Sente, there is a #connected-uids {} or somesuch that keeps unique track of connected peers that have successfully had their<ring> :session variable set.
But in the case of httpkit, I'm not certain how I would ascertain that I had 200k simulated connections. There's no array that keeps track of all "connections" as far as i am familiar. perhaps someone else knows more.
@sova Thanks for the advice! I'm not worried about simulating 200k connections, I just want to get the data right.
Clojure should add this function -- stateful map --
(defn smap [s f lst]
(letfn [(f1 [[s accum] x]
(let [[sn y] (f s x)]
[sn (conj accum y)]))]
(reduce f1 [s []] lst)))
@jdeisenberg Processing is a very un-functional system. Quil tries to make it as functional-ish as possible, but I wonder whether it's a good approach for teaching functional programming. However, I have only tried Quil once, and probably didn't go about it the right way. fwiw there was an introductory book by Paul Hudak The Haskell School of Expression that focused on graphics. I don't know it well, and then you have to deal with all of the type stuff in Haskell.
@qqq OK well you probably know it better than I do. Sitting on my shelf but I never did much with it. It did have some focus on graphics, unlike most Haskell books I'd seen around that time.
@mars0i : there was some stuff on reactive animations / frp systems -- but I think it was really "let's teach monads/functors" and dip it in a layer of graphics
@mars01 Processing isn’t functional, but Quil, with its middleware that lets you send a “state” variable from (setup)
into (draw)
and other handlers makes things much more functional. See https://github.com/quil/quil/wiki/Functional-mode-(fun-mode)
I've looked through https://clojure.org/guides/destructuring Is there a way to use ":as foo" with {:keys [row col]}
@bradford Ok, so you want to client-send chunks.
I think if you mess with the keepalive value, you may not need to, you can just invoke http/response over and over again
you're saying that you want to send one file in many fragments?
because then a stream is good, and people certainly do that.
Anyway, good luck sir.
(defn load
"When a transit writer writes to a target by calling transit/write
more than once, multiple reads are required to get all of that data
back out. Takes an input stream and reads in chunks until EOF is
hit."
[input-stream]
(let [rdr (transit/reader input-stream :json)
eof :_EOF_]
(loop [res []]
(let [chunk (try (transit/read rdr)
(catch RuntimeException e
(let [cls (when-let [cause (.getCause e)]
(class cause))]
(if (= java.io.EOFException cls)
eof
(throw e)))))]
(if (= chunk eof)
(walk/keywordize-keys res)
(recur (into res chunk)))))))
Could I get a spot check on this? Specifically the catch
portion, pretty sure I'm Doing It Wrong™.devn just use two catch clauses
devn in the first one do (catch java.io.EOFException _ eof) then the next (catch Exception e (throw e))
or just skip the second catch really
oh- wait, never mind - you care about the cause
@devn the when-let is a bit silly, (class nil)
just returns nil, so you can just do (let [cls (class (.getCause e))] …)
or even (if (= (class (.getCause e)) java.io.EOFException) …)
@noisesmith good call
@devn also the source of my initial confusion is that when I read on an empty transit stream, I get EOFException directly, not as a nested cause
maybe this has to do with the type of the stream you are using?
kingfisher.core=> (cognitect.transit/reader (java.io.ByteArrayInputStream. (byte-array 0)) :json)
#object[cognitect.transit.Reader 0x38cc9e60 "cognitect.transit.Reader@38cc9e60"]
kingfisher.core=> (cognitect.transit/read *1)
EOFException com.cognitect.transit.impl.JsonParser.parse (JsonParser.java:44)
@devn also, any particular reason to keywordize? I find it odd since transit supports keywords directly, unless you disagree with the producer of the data what the data should look like I guess
@hiredman oh - thanks, that was misleading
@noisesmith the stuff that's being read comes from a ruby application
OK - I mean it’s transit so they could write keywords if they wanted to I assume
@noisesmith I'm using a gzipinputstream
yeah- hiredman pointed out my repl printed EOFException but it was actually a RuntimeException though
tsulej lazy version
(defn smap
([f coll] (smap (first coll) f (rest coll)))
([s f coll]
(if (empty? coll)
nil
(lazy-seq
(let [[s' el] (f s (first coll))]
(cons el (smap s' f (rest coll))))))))
> (smap (fn [acc el] [(+ acc el) (* acc el)]) (range 10))
(0 2 9 24 50 90 147 224 324)
@noisesmith : but that consumes more stack space than normal map right?
qqq why?
@noisesmith : i used the reduce there in hopes it'd be constant stack space
qqq lazy things don’t consume extra stack, unless you stack lazy operations without realizing them
which this doesn’t do (as long as f doesn’t do it)
ok, I have similar solution here in my short article about signal processing (with lazy-seq)
qqq because lazy-seq turns its arg into a thunk - the self calls are each “lifted” up out and not nested in a deeper stack frame
@noisesmith : I must be missing something. Can you explain to me how lazy-seq causes
(cons el (smap s' f (rest coll))
to not create a bunch of (cons el waiting-for-return-value) stack frames ?qqq because smap returns a lazy-seq
so it returns (cons el -lazy-)
qqq then doall evaluates each thunk individually
the thunks are each a closure that knows how to generate the next item
they are not deeper in the stack compared to the previous item
how do you not have a bunch of stack frames of the form (cons 1 ...) (cons 2 ...) (cons 3 ...) (cons 4 ...)
qqq because lazy-seq doesn’t return a list
it turns its arg into a function, that you call to get the next item
a doseq can just take each next item, without going deeper on the stack
qqq how large a collection do I need to pass in to ensure a stack overflow happens? I’m glad to show a counterexample with my function
=> (last (smap (fn [acc el] [(+' acc el) (*' acc el)]) (range 1000000)))
499998000002499999
I’ll go larger if you like
@noisesmith: your explainatino makes sense now
My argument was: but it has to create the entire list, thus there are all these (cons 1 ...) (cons 2 ...) (cons 3 ...) calls lying around your arugment is: no, the list is processed one item at a time you want 1 item okay, it 'forces' the lazyseq, gets (cons BLAH (lazy-seq2)) it returns BLAH back to you you want item 2 it 'forces' lazyseq2 gets (cos FOO (lazyseq3)) it returns FOO back to you you want item 3 .... so at any point, (1) what is "realized" has already been returned to you (2) what "reamisn" is a lazy-seq
@noisesmith : is the above approximately correct?
yes, that sounds about right
ok, guys, question, I wrote such article month ago https://clojure2d.github.io/clojure2d/docs/articles/signalprocessing.html
and got such comment on reddit: This reads like reinventing the wheel. Swapping sample and state in the filter functions and changing state's shape to match the output reveals these are actually reducing functions. process-signal simplifies to reductions + map, no need to build lazy sequences by hand.
tsulej the advantage to your approach is that you can generate individual elements of a very long series without holding the whole thing in memory
the advantage of reduce would be avoiding the laziness abstraction - I don’t think that is neccessarily a big win here
signal usually is a stream, that's why lazy-seq is best here (I don't usually want to process whole stream at once)
on the other hand, reductions
could be an elegant approach here (it’s also a decent way to get the most common usages of smap)
but reductions shares the same quality of being lazy that your code has - it’s just a specific abstraction
I bet that code would be pretty tight if you used reductions
@noisesmith: is there a more generiic than lazy-seq? for things like trees, or maybe something that had 3 children nodes ?
not that I know of, and not in clojure.core
closest would be a lazy-seq of lazy-seqs I guess (each element having N lazy-seqs inside it)
I dont' ezpect lazyseq to turn arbitrary recursive defs into constant stack space via laziness
but it seems like there's some class, more generaly than just laszy list, but less general than arbitrary recursion, that can be forced into constant stack space by 'lazy expanding stuff'
qqq well they aren’t defs, but they will - each item in the spine contains N thunks you can follow if you wish
as long as N is reasonable, the space usage can be reasonable (if you consume it smartly)
or, you could have a lazy-seq of lazy-seqs as each item on the lazy-spine, if you want to go that far, but I think the resulting code would likely start to get messy
that works great until you want a number or a string or something
@qqq https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/impl/commons.clj
@bja: hmm, so they exist for numbers: https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/impl/commons.clj#L45-L47 but not for symbols?
interesting; I was wondering why you knew that regexps existed in the clojure tools reader impl files
I don't know offhand of any clojure lexer that has a public interface, but you can probably hijack LispReader.java with some effort
I'm actually writing a parser of sorts in cljs (posted in wrong channel), so will likely hack on top of https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/reader.cljs
any idea why https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/reader.cljs#L421-L439 <-- is named macros? it looks like the primary switch statement; I have noidea what it hsas to do with amcros
the way the reader works, there are builtin reader macros (defined in that cond) and then an alternate dispatch table (triggered by \#) for what we call tagged literals
@qqq yeah, you want to write your parser a lot like LispReader. Clojure's reader is a lot like a state machine, esp since cljc was added, now there's just too much to track to leave it to regexes.