Fork me on GitHub

Hello, if I understand how clojure treats map literals, when a literal has more than 8 entries it builds an hash-map else an array-map. Can I easily change this? for exemple use hash-map only for literals that have more than 32 entries. thank you


You shouldn’t have to worry about this, they both behave identically


i'm concerned about key order (at macroexpansion time)


Yea… I wouldn’t use it that way, maps are naturally un-ordered


Perhaps a vector can work?

Daniel Tan07:06:26

using a map when you need key order doesn’t sound right

Daniel Tan07:06:11

if you want you could always keep the order as a property of item in the map, then sort it after vectorising it


90 % of the time I agree


What does not sound right to me is to lose the ordering of key when passing a map literal to a macro, I cannot really see a benefit for this.


The stuff running during macroexpansion is Clojure itself… it’s not text


That’s why you can transform the data using functions from Clojure itself


If it was just seeing the map literal “as is”, you’d be stuck with string concatenation


yes of course, but in this case I think we are throwing a potentially usefull information a bit to early


Maps are un-ordered data structures… Don’t rely on key order in any situation, I think that’s the general advice


Yes I agree, and i'm using map this way 99% of the time. It is just in this particular context that I came to think about this.


I understand… I’d try using vectors and see if they can solve the problem; what exactly is the macro trying to achieve?


> Maps are un-ordered data structures… Not entirely true, clojure provides sorted-map and sorted-map-by there’s just no data literal support for it… (apply sorted-map (mapcat vector (range 100) (range 100)))


@U06HHF230 I was referring to the regular maps with literals 🙂 but yes, that’s correct

👍 3

maybe keeping insertion order for maps will not yield to significant performance penalty


just saying 🙂


Haven’t used it, so I can’t chime in


There is also for Clojure/Java, for preserving insertion order in maps.


The only way I can think of to make those data structures used for normal map literal syntax in Clojure is to modify Clojure itself, which you are free to do on your own local copy, but that won't help you distribute a macro that relies on that to others, unless they also have your modified version of Clojure.


You can use tagged literals to create a literal syntax for insertion-ordered maps, and in fact the ordered library I linked above already has that, e.g. #ordered [[:a 1] [:c 3]] is (IIRC) the literal syntax for an ordered map with key :a and value 1 inserted first.


regarding map literals: the creation of the concrete map happens before any macro code is invoked, so the solution here has to be not using a standard map literal


@U0CMVHBL2 thank you for your ideas and links. It is nice but I really need raw map syntax literals, so I probably will go with trying to fork clojure.


@U051SS2EU yes I'm afraid there is no straightforward solutions to my problem


As long as you have 0 expectation that the changes in your fork will ever be merged into the official version of Clojure, that approach should work fine


> fork clojure really?!?! Surely it’s preferable just martial from a seq of pairs into an ordered-map.


When clojure 1.11.0 comes along will you want to rebuild clojure with your patch applied?


Hey, to each their own. They may decide that making their own local modification to Clojure has disadvantages later, but I have heard that multiple companies and dev groups using Clojure use a locally-patched version of it.


@U0CMVHBL2 yes I do not have any expectations for my changes to be merged 🙂 !


@U06HHF230 I think forking clojure is not such an esoteric thing, even if not so much people seems to do it. rebuilding when a new release comes is not so frequent after all. I think maybe it is more interesting to do this than to argue for a public change.


It’s totally doable; I just very much doubt it’s worth it; for something that’s entirely achievable in the existing clojure ecosystem.


@U06HHF230 the thing is that I really want to use raw map literals 🙂 (this is the start of the discussion) , so no it is not possible in the current clojure ecosystem.


Sure, I just meant your macro (tracking order) would be achievable without them e.g:

(defmacro mymacro [other-param & args] `(ordered-map ~@args))

(mymacro :other-param
         "one" 1 "two" 2 "three") ;; => {"one" 1 "two" 2 "three" 3} 


@U06HHF230 yes I see what you mean, thank you for the exemple 🙂

👍 3

You’d need to fork clojure


yes that is what i was afraid of


Why do you need to do it?


i'm writing a macro that needs to see the ordering of map literals arguments

Daniel Tan13:06:32

has anyone tried using clojure to make a game server library?

Daniel Tan13:06:50

p2p with websockets if possible


I built this to play a board game with friends online: server: client: It uses a central server to broadcast data between browsers. I’ve looked into using tech like WebRTC, but you still need some form of communication to set up connections and for multiplayers, you need n^2 connections if everyone is connected p2p


hi! am super rusty, feel like my brain's rotted a bit since i last wrote some clj. what's the canonical way to do the following: given two vectors, eg: [1 2 3] [4 5 6 7 8], i want to take for each element of the first, create pairs, so the output would be: [[1 4] [1 5] [1 6] [1 7] [1 8] [2 4] [2 5] [2 6] [2 7] [2 8] [3 4] [3 5] [3 6] [3 7] [3 8]] doing it with loop would be easy, but i am sure there must be a better way.



(ins)user=> (for [x [1 2 3] y [4 5 6 7 8]] [x y])
([1 4] [1 5] [1 6] [1 7] [1 8] [2 4] [2 5] [2 6] [2 7] [2 8] [3 4] [3 5] [3 6] [3 7] [3 8])


doh. perfect. thank you. spent a good 20 mins with map and lambdas :face_with_rolling_eyes:


the map/lambda version

(ins)user=> (mapcat (fn [x] (map (fn [y] [x y]) [4 5 6 7 8])) [1 2 3])
([1 4] [1 5] [1 6] [1 7] [1 8] [2 4] [2 5] [2 6] [2 7] [2 8] [3 4] [3 5] [3 6] [3 7] [3 8])


for is definitely nicer


yep, i agree


In general, when using threading macros, starting with an initial sequence seq, which syntax is preferred:


(fn1 arg0)


(->> (fn1 arg0 seq)


it's a style question - the thing I ask myself is whether I imagine the first fn as the "source" of the data contextually, or the original sequence


usually it's the latter, but not always


That was sort of what I was thinking, but that seemed rather subjective. But I guess, isn't most code?


I was looking at the question previously... you might also want to check out the clojure.math.combinatorics/cartesian-product function which does the same thing and may be more understandable.

Joseph Hurtado18:06:53

Nice to join Clojurian Slack again, it’s been a while. Glad to see activity is pretty darn good!


How do I call the "correct signature" here?

  ( "deps.edn")
  (java.nio.file.Paths/get "tmp"))
Execution error (ClassCastException) at user/eval221010 (form-init2777453331497094601.clj:2). cannot be cast to java.nio.file.Path
java.nio.file.Files/copy has 3 signatures: a- Path source, Path target, CopyOption... options b- InputStream source, OutputStream sink c- InputStream in, Path target, CopyOption... options With 2 arguments, it end up into a When I try using ^"[Ljava.nio.file.CopyOption;" (into-array (Class/forName "[Ljava.nio.file.CopyOption;") []) as 3 arg it get me
Execution error (ClassCastException) at user/eval221072 (form-init2777453331497094601.clj:2).
java.lang.String cannot be cast to
Which I really can't understand

Alex Miller (Clojure team)19:06:11

I have an example of calling this method in some code I'm in and I'm using:

Alex Miller (Clojure team)19:06:38

^"[Ljava.nio.file.CopyOption;" (into-array CopyOption [StandardCopyOption/COPY_ATTRIBUTES StandardCopyOption/REPLACE_EXISTING])


I use depstar as my reference for this

Alex Miller (Clojure team)19:06:34

I think the bug in your example is that you're passing the array class in into-array, but there you want just the class

👍 3

Err, not reference but just a quick example

Alex Miller (Clojure team)19:06:57

I'm not sure how to square that with the error you're getting, which almost sounds like something else


Okay. I did it. But there is some issue with cursive/nrepl too. Also: i find io/copy 😓

Alex Miller (Clojure team)19:06:48

io/copy is based on a much older version of the JDK and is not as good or as featured as the newer JDK methods, fyi


thanks, I see someone has made an issue here:


what's the best library for HMAC signing a ring response - or is there a foolproof way to do it with interop?




one sec, I have a snippet somewhere

💯 3

untested, had to sanitize it


take the secret bytes as params, return a fn of bytes you want to sign


it looks like a good start, thanks


import accepts but doesn't require unquoted symbols btw :D


(this usually doesn't matter, as the right place to do it is in the ns form)


@ghadi thanks much - FYI that -> should be doto as .init returns void

👍 3

but with that change it works


bounded-count continues to bring me great joy


@devn "I'm going to count you.....nah, that's enough of that"


i was just looking at some really old code i wrote, and in like 3 places that are messy, bounded-count is my best friend