This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-29
Channels
- # aws (3)
- # beginners (160)
- # boot (2)
- # bristol-clojurians (3)
- # cider (62)
- # cljs-dev (77)
- # cljsrn (15)
- # clojure (147)
- # clojure-brasil (10)
- # clojure-dusseldorf (2)
- # clojure-gamedev (1)
- # clojure-italy (128)
- # clojure-russia (1)
- # clojure-spec (19)
- # clojure-uk (34)
- # clojurescript (408)
- # code-reviews (2)
- # component (1)
- # core-async (56)
- # cursive (1)
- # datascript (1)
- # datomic (81)
- # emacs (11)
- # fulcro (39)
- # java (16)
- # jobs (3)
- # lein-figwheel (2)
- # leiningen (6)
- # lumo (89)
- # off-topic (11)
- # om (2)
- # om-next (1)
- # onyx (17)
- # parinfer (4)
- # pedestal (3)
- # perun (1)
- # quil (3)
- # re-frame (19)
- # reagent (8)
- # reitit (5)
- # remote-jobs (5)
- # shadow-cljs (145)
- # spacemacs (1)
- # sql (7)
- # test-check (15)
- # uncomplicate (1)
- # unrepl (122)
- # vim (2)
- # yada (4)
Is there a way to "arrange" the order of a key in a hash-map? I'm building a service which returns JSON, and I want to have control on which field gets displayed first in the JSON (e.g. I don't want the "id" and "type" field to be hidden somewhere in the middle of a dense object).
The order of the key in JSON will likely depend on which library you are using to encode it from Clojure. You might get away with using a sorted-map
You might be able to get away with something like this:
(into (array-map :id 17 :type "some-type")
{:an "unordered" :map "to dump in"})
Well, I guess I'll stick to the randomness then. I'm not going to convolute my function with that. I appreciate your inputs though @noonian
@hawari.rahman17 if you use Jsonista (or something else that allows access to the underlying Jackson stuff), you can use Jackson to do this:
(ns foo
(:require [jsonista.core :as json]
(:import [com.fasterxml.jackson.core JsonGenerator]
[com.fasterxml.jackson.databind SerializationFeature]
(def object-mapper
(doto
(json/object-mapper)
(.configure SerializationFeature/ORDER_MAP_ENTRIES_BY_KEYS true)
(defn encode [event]
(json/write-value-as-string event object-mapper))
although, I just realized that you want them sorted in a custom order, not alphabetically... my bad
No problem. Thanks anyway for taking notice of this, gave me another perspective on what can be done.
No problem. Thanks anyway for taking notice of this, gave me another perspective on what can be done.
CLJS related question
Can anyone tell me why this fails trying to call on null
(defn Get [url fun] (req/get url #((fun %2))))
try
(defn Get [url fun] (req/get url #(fun %2)))
(i've remove one parenthesis from the anonymous function call)while this just works fine ?
(defn Get [url fun] (req/get url fun))
Hi guys! How can I update a value inside a atom vector of maps? For example:
(def var (atom [{:a 1 :b 2} {:a 2 :b 2}]
and now I want to update the {:a 2 :b 2}
to {:a 2 :b 3}
Is there any easy way to do this? My first thought was to remove the element from the vector and then add it againbut how can i select the array element that I want to update?
u can use the index of the element of vector u want to update, like (assoc-in [{:a 1 :b 2}] [0 :b] 3) => [{:a 1 :b 3}]
vectors are associative data structures of index->value. it’s reallly useful to remember that. it’s often why I stick to vectors instead of lazy seqs.
Is there a way to destructure varargs on type? This works but seems unreadable:
(defn myfun
[x y & args]
(let [tooltip (some #(when (string? %) %)
args)
mykey (or (some #(when (keyword? %) %)
args)
:default)]
(do- stuff)))
What would be an idiomatic way to do this?@magra Hrm. If that last argument were instead a map, you could use map destructuring to pull out what you want. It seems tricker to algorithmically cope with a list of typed args...
@mfikes Maybe I will just write a function like string? that returns the string instead of boolean.
Yeah, you could then use juxt
to destructure as in
(let [[tooltip mykey] ((juxt first-string first-keyword) args)]
...
Why does the first example here work and the second one not?
(defn sitemap
[url]
(def host (get (liburl/url url) :host))
(def anchors (-> url
client/get :body
hickory/parse hickory/as-hickory
((partial select/select (select/tag :a)))))
(map :attrs anchors))
(defn sitemap
[url]
(def host (get (liburl/url url) :host))
(def anchors (-> url
client/get :body
hickory/parse hickory/as-hickory
((partial select/select (select/tag :a)))
(map :attrs)))
anchors)
Generally, you should never use def inside a defn - those create global vars with scope beyond the function
use let
instead
oops, that's good to know. Thanks!
on the second one not working, you’re using ->
which is thread-first
so it will effectively do (map anchors :attrs)
in this case if all the other functions are single arg, you can just switch to ->>
Supposing they weren't, how do I get around this? define a lambda that calls map with the args reversed or a partial function using map?
I probably just wouldn’t use a thread macro to combine those two sets of calls
you could use a thread-last at the end of the thread-first (-> url client/get ... (->> (map :attrs)))
I find mixing them is generally harder to read than not using them at all
and as->
can be used in some cases
I think this function might be guilty of doing too much
->
works best on a series of functions that take and return collections (maps, vectors, etc) - functions like conj, merge, assoc, etc
->>
works best on a series of functions that take and return sequences - functions like filter, map, reduce, etc
b/c all collection functions take the collection first and all sequence functions take the sequence last
just use let bindings to structure things rather than trying to force it all into a thread-first macro?
I find the ((partial select/select (select/tag :a)))
hard to read too and maybe not worth including in that threaded expr
Yeah I think pulling it apart some would help. Thanks for your time and expertise
can a defmethod be dispatched based on matching one of N values? i have a mutimethod that dispatches on a map key that represents a frequency of an event (:daily, :weekly, :monthly, :yearly [or :annual, :annually]). it is the "yearly or annually or annual" set of values that I would like to handle in a single defmethod handle.
you can’t define it directly in this way, but you can define multiple defmethods that invoke the same function - some people have macro’ed that up to avoid the duplication
or you can leverage multimethods ability to create arbitrary keyword hierarchies
then you’d have a “parent” keyword and just define one method on that
I like implementing a defmethods
macro — but it’s simpler to leave the defmethod
dispatch duplication while handling the logic duplication with a separate function
@bjr @alexmiller thank you both for the feedback. i had considered moving the logic duplication to a function defined outside the multimethod hierarchy, but was seeking for a way to avoid that. will try the keyword hierarchy after grokking it. thanks again.
@guilhermelionribeiro A lot of people like them as a starting point. Also check out Clojure for the Brave and True.
@seancorfield will do, thanks!!
Hi guys, why do the following return the same result:
(clojure.string/split "a_b" #"_")
(clojure.string/split "a_b_" #"_")
In the second case, I expect ["a" "b" ""]
instead of ["a" "b"]
@ahmadnazir by default trailing empty strings are discarded
Thanks! I didn't find that obvious from the documentation but now that you explain it, it makes sense.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-int-
I believe this behavior has changed in Java since the function was originally written
@alexmiller want me to file a Jira?
sure. there might be one so do a search
I vaguely recall this coming up before
Thanks, I incorporated the changes from CLJ-1857 into the CLJ-1360 patch and closed 1857

will try to get that closed in 1.10
pass -1
as the limit
to get them back:
=> (clojure.string/split "a_b_" #"_" -1)
["a" "b" ""]

Does anyone here have any Common Lisp experience? I'm trying to figure out an idiomatic way to map a basic snippet of code to Clojure
I've used common lisp ~6 years ago but ask away, I'm sure that if I can't somebody else will be able to answer
I'd like a function that maps over a few different ranges of numbers, and puts them all into a flat sequence of numbers, like this: https://github.com/HackerTheory/crawler2/blob/master/neighborhood.lisp#L216-L231
This is mutating the same lexical results list. I need a functional/clojure way to do the same within the same function
So given (range 0 5), (range 0 3), and (range -3 1), this theoretical function would return (0 1 2 3 4 0 1 2 -3 -2 -1 0)
(partial apply concat) returns a function that does that
The best I can think of is nested for
s with flatten
for
takes multiple bindings, and you can do :when
and :let
inside the bindings vector
(for [x [1 2 3]
y [4 5 6]
:let [foo (+ x y)]
:when (> foo 7)]
[x y])
([2 6] [3 5] [3 6])
oh yeah, that's just concat
Ok, well, that is the basic idea, although like the linked code, this function would be a HOF that calls a function on each number, and puts that in the returned sequence instead of the number.
Sorry I left that part out
also has a conditional to see if it even will call the function or just skip the number
That's just map + concat right? I need to map several times
(into [] (comp cat (map f)) [coll1 coll2 ... colln])
The idea is I'm collecting a list of neighbor cells of a 2D grid given an origin. If I were for example to collect a cross shape with an arbitrary size, I'd need to map from left to right, then from top to 1 above origin. and then 1 below origin to bottom, in order to skip processing the origin twice (because it already was with the left to right pass)
depending on the task, I would probably use a flat array to store matrix and generate the indices I need
Thanks. I'm porting that whole file that I linked, and that is the last function to write. It's basically a kernel for convolution-based image processing
I'm not sure what you mean.
(defmethod collector :horizontal [_]
(fn [{[_ max-extent] :extent :as kernel} f]
(for [x (range (- max-extent) (inc max-extent))
cell (neighbor-cell kernel x 0)
:when cell]
(f cell))))
Here is my function for processing a horizontal strip of cells given an origin. It's easy because there is no sparsity or multiple collections.a record or nil
You sure you didn't mean :let [cell (neighbor-cell ...)] then? Bindings in for work like a nested loop
oh yes
You're right
It could also return nil, hence the :when
Yeah and those coordinates are 3 different collections
left to right. top to 1 above origin. 1 below origin to bottom.
Can't you just call range to generate basically two strips: one horizontal (x is fixed, y is (range start end)), one vertical (y is fixed, x is (range start end))?
I could but 1 of those strips needs to be split, so 3 total.
otherwise I am processing the middle cell twice
Yeah I guess I'm just a newbie. I can create those 3 collections with a single for
with 3 different bindings?
I'd do something like (map vector (repeat x-of-origin) (range (- y-of-origin size) y-of-origin)) - it will give you a vertical strip above the origin
Ah nice. That seems easy enough. Thanks
Well, or you can apply "for" to get a full square around your origin, but you'll need to filter out the indices that don't fall into the cross anyway, so I'm not sure it'll be more concise.
Hello all! 🙂 Extremely new here. Im wondering why I get the space between "John" and "!" in my output. => ((fn [name] (println "Hello, " name "!")) "John") Hello, John !
ha! How can I avoid this? I also apologize for not wrapping the code as "code", just saw that ability, new to Slack
@mfiano: sounds like what you need is two steps, generating x/y pairs, then doing something with each pair
Thanks. I'll think about it. I'm actually porting that whole file that I linked, and this is the last function to write.
=> (str "Hello, " "John" "!")
"Hello, John!"
=> (println (str "Hello, " "John" "!"))
Hello, John!
nil
@noisesmith Thank you very much!
(defn testfn []
(map vector (range 0 5)))
Why would this give a NullPointerException when called if defined in a package, but not in the REPL?should be ok either place. can you share the NPE output?
What's NPE?
NullPointerException
looks like that error is coming out of slamhound, not your code
well, I guess not, that’s just in the middleware
odd. it's the same function defined in a package and the REPL. when called with the fully qualified package name it errors, but works fine with the REPL package
oh, it’s picking up mfiano.crawler.kernel/map not clojure.core/map
so map
means something different in the namespace
Oh I might have some funky refers going on there. Thanks
yeah, be careful overlapping clojure.core fns :)