Fork me on GitHub
#beginners
<
2022-12-13
>
piyer04:12:00

How do I use https://github.com/juxt/tick in clojure? I was able to import them on repl and use them but during uberjar I see

{:error "unable to copy file", :name "data_readers.cljc", :exception java.lang.RuntimeException, :message "No dispatch macro for: ?"}

flowthing06:12:49

Not sure, but this sounds like it might be an issue with how the uberjar is created, rather than Tick specifically. How are you making the uberjar?

piyer17:12:02

I am using com.github.seancorfield/depstar

leinfink11:12:50

Hi! What's the best way of working with multidimensional vectors? Say I want to access a field on a grid. I've been doing ((grid x) y) for that, is there a better way? Or should I use a different datatype?

Ferdinand Beyer12:12:24

You could use vectors of vectors and and get-in?

leinfink12:12:45

Haha, thanks, that's exactly what I was looking for. I somehow assumed that worked only for normal (keyword) keys, not for vectors. Silly assumption, lol. Thanks!

stantheman12:12:20

Trying to learn spec (with Programming Clojure 3rd ed). In this snippet, before I (stest/instrument 'examples.spec/scale-ingredient) the let form works on function 'scale-ingredient'. Then I try stest/instrument fn and the stest/check fails; it feels as if there are some namespace or qualified var issues but I'm stumped !

lassemaatta12:12:17

you're mixing up namespaced and non-namespaced keywords

lassemaatta12:12:55

(update ingredient :quantity * factor) but the argument has ::quantity -> (* nil factor) -> boom

lassemaatta12:12:54

(s/keys :req [::name ::quantity ::unit]) specifies that the keys should be namespaced. If you wish to use plain keywords, there's (s/keys :req-un [::name ::quantity ::unit])

stantheman12:12:27

Oh brilliant thanks #lassemaatta. I think I'll have to make my own cheat-sheet for all these namespace quirks. Ill try that at the REPL and see what the proper grammar is if I use full namespace keywords. Cheers

lassemaatta12:12:46

https://blog.jeaye.com/2017/10/31/clojure-keywords/ some random article talking about different keywords in clojure, perhaps it might help

stantheman12:12:51

Looks good link I'll work through that thanks.🙌

leinfink16:12:33

Any reason not to use (seq (clojure.set/intersection set1 set2)) over (some set1 set2) if I know I'm dealing with sets? The former seems to be quicker, but I guess some would be more elegant.

Ed16:12:43

They give different answers, depending on the contents of the sets.

Ed16:12:16

(some #{1 2 3} #{2 3 4}) ;; => 3
  (require '[clojure.set :as set])
  (set/intersection #{1 2 3} #{2 3 4}) ;; => #{2 3}

leinfink16:12:41

Woops, yes true. I mean if I'm only interested in whether there's any overlap or not.

Ed16:12:53

I would think that if you want an intersection between two sets, then that would be more elegant.

pavlosmelissinos16:12:10

There's definitely a reason not to use the first version and that's because it's missing a closing parenthesis. 😛 If set2 is smaller than set1 I don't think some is slower but I agree that intersection is clearer if what you want to convey is "tell me if these two sets have any common elements".

☝️ 1
Ed16:12:23

intersection seems to order the operations based on the size of the sets. I would guess that would be the source of any performance difference.

👍 1
leinfink16:12:01

Ah, yes true, if I switch the order the performance is similar.

leinfink16:12:27

But then I guess intersection is better anyways for my usecase, thanks!

leinfink16:12:52

I'll give it a closing parenthesis for good measure.

😁 2
slk50016:12:18

example from 'the joy of clojure 2nd edition' 'Clojure’s hash map, just like hash tables or dictionaries in many other languages, has a mechanism to iterate through the entire collection. Clojure’s solution for this iterator is, unsurprisingly, a seq. Each item of this seq needs to include both the key and the value, so they’re wrapped in a map entry. When printed, each entry looks like a vector:'

(first {:width 10, :height 20, :depth 15})
;=> [:depth 15]
In the version of Clojure used while writing the book, we got [:depth 15] as our answer. But because map entry order isn’t guaranteed, you may see something different with a different version of Clojure. with version : Clojure CLI version 1.11.1.1182
(first {:width 10, :height 20, :depth 15})
;=> [:width 15]
So my question is: is something changed in clojure version? Or it always will be random - because it's unsorted map

Apple16:12:31

Order cannot be guaranteed but should be stable in the same version.

Apple16:12:14

Just don't do it.

slk50016:12:54

Just don't do it. - it's like anti Nike

slk50016:12:53

Order cannot be guaranteed but should be stable in the same version. That's really good explanation.

dpsutton16:12:26

I think i’d clarify a bit. (first x) should return the same item if called multiple times on the exact same x in the same process

slk50017:12:25

same prcoess?

slk50017:12:24

I would write something like this: Order cannot be guaranteed but should be stable in the same version. Don't ever rely on order of elements in unsorted map!

Miķelis Vindavs17:12:53

Even more insidious is the fact that for small maps the iteration order matches insertion order (small maps are backed by linear storage). So a bug in code relying on the order might not surface for a long time

Alex Miller (Clojure team)17:12:25

order is not random, but it has no guarantees. the ordering is based on hashed key order and the hash algorithms may (and have) change

👍 2
slk50017:12:11

"the ordering is based on hashed key order and the hash algorithms may (and have) change" that's super interesting

seancorfield18:12:03

An additional note: you said "with version : Clojure CLI version 1.11.1.1182" -- just to clarify: 1.11.1.1182 is the version of the CLI but not necessarily the version of Clojure being used; you can ask any version of the CLI to use whatever version of Clojure you want. The "1.11.1" part of the CLI indicates the default version of Clojure that will be used if you don't override it. You can specify the version of Clojure in your deps.edn or as a command-line argument or via aliases. Example:

(/var/www/worldsingles)-(!2008)-> clj -M:1.1
Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.pom from central
Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.jar from central
Clojure 1.1.0
user=> (first {:width 10, :height 20, :depth 15})
[:width 10]
user=>

Tue Dec 13 10:20:14
(/var/www/worldsingles)-(!2009)-> clj -M:1.9
Clojure 1.9.0
user=> (first {:width 10, :height 20, :depth 15})
[:width 10]
user=>

Tue Dec 13 10:21:03
(/var/www/worldsingles)-(!2010)-> clj -M:1.5
Downloading: org/clojure/clojure/1.5.1/clojure-1.5.1.jar from central
Clojure 1.5.1
user=> (first {:width 10, :height 20, :depth 15})
[:depth 15]
user=>
Interesting, it returned width in Clojure 1.1 and does again now but for a version or two it returned depth...

👍 1
seancorfield18:12:56

Here's the full list of versions and results:

(/var/www/worldsingles)-(!2012)-> for v in 1 2 3 4 5 6 7 8 9 10 11 12; do clojure -M:1.$v -e "[(clojure-version) (first {:width 10, :height 20, :depth 15})]"; done
["1.1.0" [:width 10]]
["1.2.1" [:width 10]]
["1.3.0" [:depth 15]]
["1.4.0" [:depth 15]]
["1.5.1" [:depth 15]]
["1.6.0" [:width 10]]
["1.7.0" [:width 10]]
["1.8.0" [:width 10]]
["1.9.0" [:width 10]]
["1.10.3" [:width 10]]
["1.11.1" [:width 10]]
["1.12.0-alpha1" [:width 10]]

❤️ 3
Alex Miller (Clojure team)18:12:59

1.6 was hash algorithm change, 1.3 was numerics (guessing that’s related)

1
seancorfield18:12:17

(I'm running CLI 1.11.1.1200 but the same is possible with any version)

seancorfield18:12:06

I have these aliases in my dot-clojure deps.edn file, in case you're wondering about that: https://github.com/seancorfield/dot-clojure/blob/develop/deps.edn#L78-L100

seancorfield18:12:01

(just noticed I missed testing Clojure 1.0 -- which also returns [:width 10])