Fork me on GitHub
#beginners
<
2021-06-01
>
dabrazhe10:06:58

what's the best way to check if an item in a sequence is not nil, nor empty, as in in (map #(if not nil % nor empty % then (func %)) coll) ?

jkxyz10:06:46

(empty? nil) ;;=> true

dabrazhe10:06:57

actually (map #(if-not (empty? %) (func %) coll) does the trick : )

Stuart10:06:25

(not (seq x))
? e,g..
(defn empty-or-nil [x]
  (not (seq x)))

(map empty-or-nil [[5] [] [:a :b :c] nil])
=> (false true false true)

dabrazhe10:06:15

it works, but empty? is enough, it appears

👍 3
delaguardo10:06:21

empty? will throw if argument is not ISeq (empty? 42) for example

delaguardo10:06:51

I’m combining sequential? with empty? to avoid unnecessary throwables

teodorlu11:06:06

Clojure 1.10.1
user=> (empty? nil)
true
user=> (empty? false)
Execution error (IllegalArgumentException) at user/eval3 (REPL:1).
Don't know how to create ISeq from: java.lang.Boolean

dabrazhe11:06:53

well I seem to work with sequences these days, to be pragmatic. and trying to achieve polymorfism everywhere (eg for numbers) feels like premature optimisation )

👍 3
delaguardo11:06:44

This is mostly about invalidating wrong input then polymorfism but yes, if you are not expecting non-sequable arguments it will work

madstap13:06:10

I like (cond-> x something? f) for these cases instead of (if something? (f x) x) . It lets you avoid repeating the x . I'd write it like this: (map #(cond-> % (seq %) func) coll)

dabrazhe21:06:40

ah, another unknown function, thanks )

Freddy13:06:06

does anyone know a hashing function for clojure hashmaps? I'd like to obtain digests from data maps... But specifically I need {:this :cat :that :car} to have the same digest as {:that :car :this :cat}. Eventually I want this digest for storing it inside a file rather than storing a full map and be able to compare versions of the data from digests. Only need really will be "same digest? ok same data. Different digest? ok different data"

Freddy13:06:48

looks nice thanks, I'll give it a go!

teodorlu14:06:35

I had a situation where I knew that there would always be maps, and no "recursive maps". So I just sorted the maps and hashed the sequence.

(defn hash-fn [_])

(-> {:a 1 :b 2} sort pr-str hash-fn)
If I had known about valuehash, I might have used that!

Freddy14:06:28

yep I think I'm going to end up doing the same, sorting the map to edn then hashing, because I need the same hashing being done on the client side with clojurescript and valuehash doesn't seem to support cljs

alexmiller14:06:58

the built in hash function is not order senstitive

alexmiller14:06:12

user=> (hash {:this :cat :that :car})
534635990
user=> (hash {:that :car :this :cat})
534635990

alexmiller14:06:32

maps are unordered

Freddy14:06:41

that's pretty good to know actually, thanks Alex

alexmiller14:06:43

the order you see printed is not relevant

Freddy14:06:08

it's probably exactly what I need for my usecase as I only need to check equality, thanks a lot

alexmiller14:06:12

and cljs hash should have this same property (but we don't guarantee the hashes will match between clj and cljs)

Freddy14:06:25

ah yeah good point

alexmiller14:06:40

well keep in mind, two objects that are = will have the same hash, but the opposite is not true

delaguardo14:06:56

it is not even gurantied to stay the same between JVM instances/runs, isn’t it?

alexmiller14:06:09

no, or between clojure versions

alexmiller14:06:37

but the property will remain true (= objects have the same hash)

Freddy14:06:51

ok I see I'll stay on sorted maps to edn

Freddy15:06:24

thanks for your answers

delaguardo15:06:43

btw, looks like it should be possible to make valuehash support cljs as well

Freddy15:06:37

good, I might give it a go then, could be a fun exercise for me

Freddy15:06:22

was more concerned about the impl namespace personally to guarantee same results on the two implementations

introom13:06:13

HI. I’d like to poll a service every 3 mins, which approach is more preferred? core.async with timeout or ?

delaguardo13:06:03

https://github.com/jarohen/chime I used once that library for that

dabrazhe21:06:30

I used this library once, very useful for testing requests, like the ab command https://github.com/brunoV/throttler

Rob Haisfield14:06:00

Are there any tools to go up and down the ladder of abstraction with Clojure functions? i.e. view concrete examples of functions all the way up to versions abstracted over all possible values of a parameter? In this example, there's an algorithm for a car trying to stay on the road by turning when it's off the road, and you can change the angle that it turns when it's off the road. One of the screenshots basically shows all of the possible values of the angle between 0 degree and 10 degree turns at once to help you figure out which is the best angle to pick. http://worrydream.com/LadderOfAbstraction/

phronmophobic19:06:38

You could do this with clojure.spec https://clojure.org/guides/spec#_exercise. You would just need a way to visualize inputs and outputs

dpsutton14:06:08

can be used a bit in that manner

Rob Haisfield18:06:19

I’ll play with that, thanks!

dpsutton14:06:44

here searching on input shows output under a number of functions. not exactly what you're asking for but the closest thing i'm aware of

az15:06:44

import com.twilio.jwt.accesstoken.AccessToken;

public class Main {
	public static void main(String[] args) throws Exception {
		AccessToken token = new AccessToken.Builder();
	}
}
Hi all, any idea how I would convert the http://AccessToken.to clojure?

az15:06:01

I’ve tried

(ns dev.user
  (:import (com.twilio.jwt.accesstoken AccessToken)))

(new AccessToken/Builder)
;; => Syntax error (IllegalArgumentException) compiling new
;;    Unable to resolve classname: AccessToken/Builder
 ;; 
(AccessToken/Builder.)
;; => Syntax error (NoSuchFieldException) compiling.
;;    Builder.

Tero Matinlassi15:06:53

I think inner classes are accessed with $, so maybe (new AccessToken$Builder) ?

az15:06:24

@U023S3BQRFB Thank you. Just tried it. Still getting an error: Unable to resolve classname: AccessToken$Builder

az15:06:20

I found something though when searching inner class

az15:06:31

Might need to import the inner class

Tero Matinlassi15:06:40

Yeah, was thinking that too

az15:06:06

That worked!

az15:06:16

Thank you!

dharrigan15:06:53

user=> (AccessToken$Builder. "foo" "bar" "baz")
#object[com.twilio.jwt.accesstoken.AccessToken$Builder
        "0x1f208930"
        "[email protected]"]

az15:06:19

@U11EL3P9U thank you. Yes just got it working. I also needed to add the import

(:import (com.twilio.jwt.accesstoken AccessToken)
           (com.twilio.jwt.accesstoken AccessToken$Builder)
           (com.twilio.jwt.accesstoken VideoGrant))

az15:06:42

@U11EL3P9U is there a better way of doing it? Or is this the right way to import?

dharrigan15:06:02

yes, you can put all in a package on the same line

az15:06:13

ah nice ok

dharrigan15:06:36

i.e., (:import [com.twilio.jwt.accesstoken AccessToken VideoGrant AccessTokenBuilder])

az15:06:48

beautiful

az15:06:50

thank you!

dharrigan15:06:11

I think the style is to put each underneath, depending on your personal tastes 🙂

dharrigan15:06:34

(or pain point when it comes to line width)

dharrigan15:06:38

Have fun! 🙂

az15:06:46

Got it, thanks again!

evocatus16:06:10

Hi! I'm trying to compile uberjar of a simple project and lein just freezes and I have to break it's execution after some time

seancorfield16:06:45

Most likely you have a def form that is performing some long-running process?

seancorfield16:06:04

(top-level forms should not do any side effects)

evocatus16:06:26

The code is basically minimal example from this page https://github.com/cljfx/cljfx

evocatus16:06:35

called from -main

seancorfield16:06:35

Ah, building a cljfx JAR requires some special care as I recall… Ask in #cljfx

👍 3
MatthewLisp17:06:46

Hello! Given a map with this representation: #:album{:name "Magical Mystery Tour", :artist #:artist{:name "The Beatles"}} How do i convert this to the "normal" representation at the REPL ?

indy17:06:44

If you're looking to actually unqualify the map, something like this should work

(comment
 (def unqualify-keyword (comp keyword name))
 (defn deep-unqualify [m]
   (if (map? m)
     (reduce-kv (fn [m k v]
                  (if (map? v)
                    (assoc m (unqualify-keyword k) (deep-unqualify v))
                    (assoc m (unqualify-keyword k) v))) 
                {} 
                m)
     m))
 (deep-unqualify #:album{:name "Magical Mystery Tour", :artist #:artist{:name "The Beatles"}}))

dpsutton17:06:10

(set! *print-namespace-maps* false) in your repl

MatthewLisp18:06:44

when i mean normal it's not about unqualified keywords, its:

{:album/name "Magical Mystery Tour"
 :album/artist {:artist/name "The Beatles"}}

dpsutton18:06:16

user=> {:album/name "Magical Mystery Tour", :album/artist {:artist/name "The Beatles"}}
#:album{:name "Magical Mystery Tour", :artist #:artist{:name "The Beatles"}}
user=> (set! *print-namespace-maps* false)
false
user=> {:album/name "Magical Mystery Tour", :album/artist {:artist/name "The Beatles"}}
{:album/name "Magical Mystery Tour", :album/artist {:artist/name "The Beatles"}}

dpsutton18:06:36

that should do it. did you try it?

MatthewLisp19:06:36

Yes it works @dpsutton thank you

👍 3