Fork me on GitHub
#clojure
<
2020-06-18
>
pbaille07:06:29

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

raspasov07:06:30

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

pbaille07:06:29

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

raspasov07:06:01

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

raspasov07:06:07

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

pbaille07:06:17

90 % of the time I agree

pbaille07:06:52

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.

raspasov07:06:47

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

raspasov07:06:21

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

raspasov07:06:47

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

pbaille07:06:51

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

raspasov07:06:07

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

pbaille07:06:57

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.

raspasov07:06:26

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

rickmoynihan07:06:27

> 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)))

raspasov07:06:18

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

👍 1
pbaille07:06:14

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

pbaille07:06:28

just saying 🙂

raspasov07:06:42

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

andy.fingerhut13:06:38

There is also https://github.com/clj-commons/ordered for Clojure/Java, for preserving insertion order in maps.

andy.fingerhut13:06:48

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.

andy.fingerhut13:06:38

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.

noisesmith14:06:46

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

pbaille15:06:13

@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.

pbaille15:06:54

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

andy.fingerhut15:06:04

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

rickmoynihan15:06:49

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

rickmoynihan15:06:19

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

andy.fingerhut17:06:22

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.

pbaille07:06:20

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

pbaille07:06:59

@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.

rickmoynihan07:06:52

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

pbaille14:06:41

@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.

rickmoynihan15:06:32

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

(defmacro mymacro [other-param & args] `(ordered-map [email protected]))

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

pbaille08:06:41

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

👍 1
rickmoynihan07:06:12

You’d need to fork clojure

pbaille07:06:34

yes that is what i was afraid of

rickmoynihan07:06:17

Why do you need to do it?

pbaille07:06:45

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

phronmophobic16:06:25

I built this to play a board game with friends online: https://github.com/phronmophobic/wavelength_helper/tree/networking server: https://github.com/phronmophobic/wavelength_helper/blob/networking/src/wavelength_server/core.clj client: https://github.com/phronmophobic/wavelength_helper/blob/networking/resources/public/index.html 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

Dominic Pearson16:06:54

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.

noisesmith16:06:57

for

(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])

Dominic Pearson16:06:12

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

noisesmith16:06:37

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])

noisesmith16:06:43

for is definitely nicer

fadrian17:06:29

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

fadrian17:06:54

(fn1 arg0)

fadrian18:06:30

(->> (fn1 arg0 seq)

noisesmith18:06:07

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

noisesmith18:06:16

usually it's the latter, but not always

fadrian18:06:08

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

fadrian18:06:33

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!

souenzzo18:06:24

How do I call the "correct signature" here?

(java.nio.file.Files/copy
  ( "deps.edn")
  (java.nio.file.Paths/get "tmp"))
Execution error (ClassCastException) at user/eval221010 (form-init2777453331497094601.clj:2).
java.io.BufferedInputStream 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 java.net.URI
Which I really can't understand

alexmiller19:06:11

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

alexmiller19:06:38

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

dpsutton19:06:46

I use depstar as my reference for this

alexmiller19: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

👍 1
dpsutton19:06:43

Err, not reference but just a quick example

alexmiller19:06:57

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

souenzzo19:06:42

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

alexmiller19: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

noisesmith21:06:57

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

ghadi21:06:36

interop

1
ghadi21:06:46

one sec, I have a snippet somewhere

💯 1
ghadi21:06:31

untested, had to sanitize it

ghadi21:06:55

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

noisesmith21:06:06

it looks like a good start, thanks

noisesmith21:06:43

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

noisesmith21:06:58

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

noisesmith21:06:08

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

👍 1
noisesmith21:06:14

but with that change it works

devn23:06:14

bounded-count continues to bring me great joy

ghadi23:06:45

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

devn23:06:49

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