This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-02-02
Channels
- # aws-lambda (1)
- # beginners (46)
- # boot (190)
- # cider (12)
- # clara (6)
- # cljs-dev (9)
- # cljsjs (8)
- # clojure (152)
- # clojure-austin (3)
- # clojure-berlin (3)
- # clojure-finland (2)
- # clojure-france (5)
- # clojure-italy (3)
- # clojure-russia (92)
- # clojure-serbia (4)
- # clojure-spec (7)
- # clojure-uk (190)
- # clojurescript (115)
- # cursive (20)
- # datomic (20)
- # dirac (4)
- # emacs (9)
- # gsoc (5)
- # hoplon (1)
- # jobs (1)
- # klipse (4)
- # lein-figwheel (1)
- # leiningen (6)
- # lumo (2)
- # mount (18)
- # off-topic (57)
- # om (68)
- # om-next (14)
- # onyx (33)
- # perun (32)
- # portland-or (4)
- # re-frame (21)
- # reagent (85)
- # ring (6)
- # ring-swagger (23)
- # schema (1)
- # uncomplicate (1)
- # untangled (13)
- # vim (7)
Okay, say I'm trying to turn an options map into a seq of command line switches. {:wait true, :create false}
would return an empty string, while {:wait false, :create true}
would return ("-n" "-c")
, to provide two examples.
What's the best way to do this? I'm thinking maybe map something that eats individual key-val pairs over the options map, but I'm not sure if there's something better than a nested cond
and if
to do it with.
(def opts->cli
{[:wait false] "-n"
[:create true] "-c"})
(remove nil? (map opts->cli opts))
Do take-last
and drop-last
have transducer equivalents?
@aengelberg due to the way reduce works, from left to right, and given how transducers work on arbitrary "streams" of input which can be channels, collections, network sockets, or anything else, I don't think there's really a concept of "the end". take
yields the first n
items. drop
throws away the first n
and then yields the rest. But it doesn't make much sense to work from the other end of the pipe for transducers. At least, I think I'm correct about this.
I think the best you can do is to work off of a known collection size, and convert them as such:
- for a list of size n
, (take-last (- n x) v)
yields the same list as (drop x v)
- (drop-last (- n x) v)
is (take x v)
I know it's not what you want, but it might be the best you can do given the nature of how transducers work. I could be wrong of course, and would be interested to know how it can be done.
Transducers can utilize the 1-arity to know when the end of a stream is.
take-last
could keep a buffer of the last N elements, and when the 1-arity is called, reduce all of those N elements in succession.
I haven't tried it, I was more asking to see if this has been officially implemented or do I have to roll my own.
this is pretty naive but works using transduce (does not work for into
)..
(defn drop-last-xf [n]
(fn [rf]
(let [v (atom [])]
(fn
([] (rf))
([result] (reduce rf (rf) (take (- (count @v) n) @v)))
([result input]
(swap! v conj input))))))
(transduce (drop-last-xf 2) conj [1 2 3 4 5 6])
; => [1 2 3 4]
unfortunately there I've put the reducing function conj
back into the transducer, which is what a transducer removes in the first place, which is why it fails
if you just change reduce rf []
to reduce rf result
that should make it work with into
...
I think we can do better, i.e. we don't have to buffer everything in memory
(defn alex-drop-last-xf
[n]
(fn [rf]
(let [q (volatile! (clojure.lang.PersistentQueue/EMPTY))]
(fn
([] (rf))
([result] (rf result))
([acc x]
(if (> (count (vswap! q conj x)) n)
(let [front (peek @q)]
(vswap! q pop)
(rf acc front))
acc))))))
actually, i just realized we don't need state at all:
(defn drop-last-xf [n]
(fn [rf]
(fn
([] (rf))
([result] (reduce rf
(rf)
(take (- (count result) n) result)))
([result input]
(if (vector? result)
(conj result input)
[input])))))
your impls make an assumption of the type of the accumulator used in the reducer
we don't know that the reducer takes and returns a vector
that probably doesn't work on sequence
which has an unusual stateful accumulator
can you find a case where the above doesn't work? it seems to work fine. the whole thing feels "wrong" but i'm not experienced with writing custom transducers so it's new to me
;; with your latest version
user=> (sequence (drop-last-xf 2) [1 2 3 4])
()
I stand by my version above, it seems to work with sequence
and into
and transduce
thanks
I think where yours breaks down is that the 2-arity sometimes isn't actually used as an immutable accumulator
so you have to keep your own if you really want to accumulate things internally
agreed, custom transducers are a fun exercise 🙂
reading all of https://github.com/cgrand/xforms is a great way to expand your transducer-fu 🙂
my attempt at take-last
:
(defn alex-take-last-xf
[n]
(fn [rf]
(let [q (volatile! (clojure.lang.PersistentQueue/EMPTY))]
(fn
([] (rf))
([result]
(reduce rf result @q))
([acc x]
(when (> (count (vswap! q conj x)) n)
(vswap! q pop))
acc)))))
@aengelberg: you forgot to call the completing arity of rf on the result of reduce.
curious if it’s possible to have middleware in a compojure api only for a test environment. I’m playing with react native and can’t write http request test because of CORS constraints. Once the app is compiled natively it’s no longer a problem, and I don’t want a vulnerability in a production server
Thanks @cgrand, good point.
you're using assoc-in instead of assoc
@pesterhazy, using assoc also prints an empty result
1. test
is a symbol from clojure.core - use another one
2. we're not seeing whole file
3. try restarting the whole repl
4. try peppering the file with println's to see if the functions are getting called
thanks @pesterhazy
@joshjones @aengelberg take-last
and drop-last
now in xforms https://github.com/cgrand/xforms/blob/64eb4c6158ddfee8c5ac39dccea17a700d88c177/src/net/cgrand/xforms.cljc#L340-L365
Hi, I have a question about leiningen http://stackoverflow.com/questions/41986928/how-can-i-run-a-hook-before-specific-task-in-leiningen
@mdib I've read that one, but I feel it stops too soon as it only implements a single function, echo
.
There's also http://blog.oskarth.com/writing-a-dsl-in-clojure which is more about creating macros than a DSL.
@dacopare are you familiar with Instaparse?
@manutter51 I've never heard of it.
It’s really a parser generator, but it’s pretty nice, and kinda overlaps the concept of DSL
I mention it because you said you didn’t want a lispy syntax, and Instaparse lets you define basically any syntax you like.
@dacopare: that's my article, was wondering why I was highlighted by slack :) what are you trying to do more specifically?
@manutter51: maybe it's time for me to learn about context-free grammars! 😅 @oskarth: thank you for the article! My team have a partially-defined DSL, and I'm interested to see if I can parse and generate it using Clojure.
@dacopare There’s a #instaparse channel too, not very active, but it’s there.
Only used it briefly but it helps with a lot of the plumbing and has a nice declarative syntax IIRC
@dacopare writing DSLs is a pretty broad topic. What sort of DSL is this?
@dacopare my two rules of DSL building 1) Don't. Use pure Clojure whenever you can. It's a language people already understand. DSLs are something people will have to learn. 2) Start with a data-defined backend. Don't use macros or instaparse, start with a solid data interface. Then add construction functions to build that data if needed. Finally add instaparse/macros that emit your AST. Now you have both a machine interface and ahuman interface
that's one hell of a talk description @val_waeselynck
@tbaldridge: the DSL exists independently of Clojure, I am just hoping that I can leverage Clojure to use it more easily.
@dacopare so in Clojure we have lots of tools for working with data. So we want to base our DSL api of of data and functions. For example. Let's say your DSL has the ability to do this: "Y = X + 1". We could represent that as text (as I have done here), or we could represent it as machine-readable data:
{:op :assign
:left {:op :var :name 'Y}
:right {:op :+
:a {:op :var :name 'X}
:b {:op :const :val 1}}}
That's all hashmaps, you can use get-in and update-in to modify them, and you could in about 10 minutes write a multi-method based interpreter for that.
Now writing those hashmaps is a pain for humnans, so you could wrap it up with functions and macros: (assign :left (var Y) :right (add X 1))
And those functions could emit the hashmaps that are passed to your multi-method interpreter.
And finally, after all that, sometimes using Clojure is a pain for some users, so that's when you bring out Instaparse and parse "Y = X + 1" and have that use your functions or somehow emit the hashmaps that are fed into the multi-method interpreter.
I'm right in the middle of this talk's universe right now, this hurts so much...
Any recommendations for a nice free weather api so I can make a site where the weather forecast and current weather is shown
Thank you @tbaldridge, I'm very happy working with Clojure datastructures and multimethods. It was the transformation of this into a string and vice versa that I really meant to ask about. I'll have a look at instaparse.
#instaparse may not be very active but I'm fairly responsive if someone has a question for me :)
Instaparse is good at parsing, it doesn't have great capability to "unparse" or generate a string from data.
But I like @tbaldridge's point about leveraging Clojure or EDN for your DSL, not strings, if you can. In which case you don't need instaparse
Would Clojure ever consider setting the UNICODE_CHARACTER_CLASS flag to true in all of its regexes? Would be really nice to not inherit Java's Unicode brokenness there (so, for example, #"\w"
will match chars like ñ
).
Yeah, understandable.
having your dsl as edn also allows automated upgrades to future dsl versions. This is useful if you create and store a bunch of random snippets.
whats the function im thinking of? given a nested map
{:a {:b 1} :c {:d 2}
I want a sequence of [[:a :b 1] [:c :d 2]]
a forloop is pretty easy if its a known level of nesting, but I feel like theres a simple, perhaps even a core function im overlooking
don’t you mean [[:a :b 1] [:c :d 2]]
(fn f [path item] (if (map? item) (for [[k v] item i (f (conj path k) v)] i) [(conj path item)]))
There is a log service
user=> ((fn f [path item] (if (map? item) (for [[k v] item i (f (conj path k) v)] i) [(conj path item)])) [] {:a {:b 1} :c {:d 2}})
([:a :b 1] [:c :d 2])
user=>
yeah, that looks right! lol. sorry, was thinking there was a core function or something
not that I am ware of, I've written some variation of that a lot. maybe it could be turned in to a generic tree processing function like tree-seq
@tjtolton @bfabry @hiredman with specter:
user=> (use 'com.rpl.specter)
nil
user=> (def PATH-MAP-WALKER
#_=> (recursive-path [] p
#_=> (if-path map?
#_=> [ALL (collect-one FIRST) LAST p]
#_=> STAY
#_=> )))
#'user/PATH-MAP-WALKER
user=> (select PATH-MAP-WALKER {:a {:b 1} :c {:d 2}})
[[:a :b 1] [:c :d 2]]
user=> (transform PATH-MAP-WALKER str {:a {:b 1} :c {:d 2}})
{:a {:b ":a:b1"}, :c {:d ":c:d2"}}
has anyone experienced (require 'potemkin.collections)
failing the first time and then succeeding the second time? (on [potemkin "0.4.3"]
)
hello everyone, sorry if this is a stupid question, i'm new to clojure & jvm .. Im building some microservices and I would like to encode the response with gzip. is there any standart way to do it with compojure-api/compojure/ring ? searching google ive found only code snippets, but it is possible to configure the framework to do this?
there are various gzip middlewares for ring, but normally most people delegate to nginx to do things like TLS termination and gzip serving
thx @ghadi , found some of them in google, I was using bad keywords for the search 🙂 unfortunatly ngnix isnt a option in this case
you might also try configuring gzip using whatever underlying ring adapter (undertow, jetty, etc)
also, I've traced my problem to an issu ewith [metrics-statsd "0.1.8"]
(in case my previous question worried anyone)
@plins you said it's for a microservice, is it going over your internal network?
well, all of our infrastructure is hosted on AWS, and a php service will call the clojure one (still dealing with legacy code :~ )
@reitzensteinm , so its going on our internal network i guess
someone who has uses ez-web for pagination and wants to share the code so I can look how I can make things work
hi! I have some confusion working with inst in Clojure. It is java.util.Date object. Current Java 8 introduced new classes to work with time and java.util.Date became deprecated. Is there any plans to add support of new java classes for date and time?
I doubt it as it would probably break existing code. For reading data though, you can add your own handlers to parse into new date types
@tbaldridge thanks. Already implemented my own handlers, but it looks a bit rough
Hi I'm wondering how to append to a vector of maps in an atom.
(swap! atom-name [:vector 0] {:new "map}) replaces the first map in the vector of maps....
conj ... okay...
thanks 🙂
does anyone have a collection of important/well-written papers in persistent data structures?
I’m curious about what the state of the art is, and if/how clojures core data structures could be improved
https://www.youtube.com/watch?v=GibNOQVelFY&index=20&list=PLZdCLR02grLq4e8-1P2JNHBKUOLFTX3kb
Hrm... I want to conj into a nested vector... it has a keyword :blurbs ... How would I specify which sub-set of atom data to conj into?
(def atom ({:top [{:id 1} {:id 2} {:id 3]}))
how would one add a hypothetical {:id 4} in that fashion?
Yours truly, perpetual_beginner
dev=> (def a (atom {:top [{:id 1} {:id 2} {:id 3}]}))
#'dev/a
dev=> (swap! a update :top conj {:id 4})
{:top [{:id 1} {:id 2} {:id 3} {:id 4}]}
Awesome! Thank you 🙂