beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
dabrazhe 2021-06-01T10:02:58.195200Z

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

jkxyz 2021-06-01T10:09:46.196500Z

(empty? nil) ;;=> true

dabrazhe 2021-06-01T10:09:57.196700Z

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

2021-06-01T10:12:25.197Z

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

dabrazhe 2021-06-01T10:14:15.197400Z

it works, but empty? is enough, it appears

๐Ÿ‘ 1
2021-06-01T10:41:21.197800Z

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

2021-06-01T10:42:51.198Z

Iโ€™m combining sequential? with empty? to avoid unnecessary throwables

teodorlu 2021-06-01T11:26:06.198300Z

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

dabrazhe 2021-06-01T11:33:53.198500Z

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 )

๐Ÿ‘ 1
2021-06-01T11:36:44.198700Z

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

2021-06-01T13:09:06.203Z

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"

2021-06-01T13:10:49.203100Z

https://github.com/arachne-framework/valuehash this one works great

2021-06-01T13:12:48.203400Z

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

2021-06-01T13:22:10.203600Z

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)

2021-06-01T13:24:13.204500Z

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

2021-06-01T13:26:03.204600Z

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

teodorlu 2021-06-01T14:38:35.205500Z

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!

2021-06-01T14:44:00.207300Z

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/

2021-06-01T14:53:28.207500Z

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

alexmiller 2021-06-01T14:55:58.207800Z

the built in hash function is not order senstitive

alexmiller 2021-06-01T14:56:12.208Z

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

alexmiller 2021-06-01T14:56:32.208200Z

maps are unordered

2021-06-01T14:56:41.208400Z

that's pretty good to know actually, thanks Alex

alexmiller 2021-06-01T14:56:43.208600Z

the order you see printed is not relevant

dpsutton 2021-06-01T14:58:08.209Z

<https://borkdude.github.io/re-find.web/?args=0%20%5B1%202%203%5D> can be used a bit in that manner

2021-06-01T14:58:08.209100Z

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

alexmiller 2021-06-01T14:58:12.209400Z

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

2021-06-01T14:58:25.209800Z

ah yeah good point

alexmiller 2021-06-01T14:58:40.210300Z

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

dpsutton 2021-06-01T14:58:44.210600Z

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

2021-06-01T14:58:56.210700Z

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

alexmiller 2021-06-01T14:59:09.210900Z

no, or between clojure versions

alexmiller 2021-06-01T14:59:37.211100Z

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

2021-06-01T14:59:51.211300Z

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

2021-06-01T15:00:24.211500Z

thanks for your answers

2021-06-01T15:00:43.211900Z

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

az 2021-06-01T15:01:44.212900Z

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?

2021-06-01T15:02:37.213100Z

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

2021-06-01T15:04:25.213300Z

https://github.com/arachne-framework/valuehash/blob/master/src/valuehash/api.clj#L28-L32 this function is the only problem here.

2021-06-01T15:05:22.213600Z

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

az 2021-06-01T15:07:01.214Z

Iโ€™ve tried

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

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

Tero Matinlassi 2021-06-01T15:09:53.214300Z

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

az 2021-06-01T15:11:24.214500Z

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

az 2021-06-01T15:12:20.214700Z

I found something though when searching inner class

az 2021-06-01T15:12:31.215200Z

Might need to import the inner class

Tero Matinlassi 2021-06-01T15:12:40.215400Z

Yeah, was thinking that too

az 2021-06-01T15:13:06.215600Z

That worked!

az 2021-06-01T15:13:16.215800Z

Thank you!

dharrigan 2021-06-01T15:13:53.216Z

user=&gt; (AccessToken$Builder. "foo" "bar" "baz")
#object[com.twilio.jwt.accesstoken.AccessToken$Builder
        "0x1f208930"
        "com.twilio.jwt.accesstoken.AccessToken$Builder@1f208930"]

az 2021-06-01T15:15:19.216300Z

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

az 2021-06-01T15:15:42.216500Z

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

dharrigan 2021-06-01T15:16:02.216700Z

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

az 2021-06-01T15:16:13.216900Z

ah nice ok

dharrigan 2021-06-01T15:16:36.217100Z

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

az 2021-06-01T15:16:48.217300Z

beautiful

az 2021-06-01T15:16:50.217500Z

thank you!

dharrigan 2021-06-01T15:17:11.217700Z

I think the style is to put each underneath, depending on your personal tastes ๐Ÿ™‚

dharrigan 2021-06-01T15:17:34.217900Z

(or pain point when it comes to line width)

dharrigan 2021-06-01T15:17:38.218100Z

Have fun! ๐Ÿ™‚

az 2021-06-01T15:17:46.218300Z

Got it, thanks again!

evocatus 2021-06-01T16:31:10.219200Z

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

evocatus 2021-06-01T16:32:28.219300Z

https://imgur.com/a/39XtFoG

seancorfield 2021-06-01T16:43:45.219600Z

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

seancorfield 2021-06-01T16:44:04.219800Z

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

evocatus 2021-06-01T16:47:26.220Z

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

evocatus 2021-06-01T16:47:35.220300Z

called from -main

seancorfield 2021-06-01T16:48:35.220500Z

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

๐Ÿ‘ 1
evocatus 2021-06-01T16:54:54.220700Z

ok, thanks

MatthewLisp 2021-06-01T17:36:46.221800Z

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 ?

dpsutton 2021-06-01T17:42:10.222100Z

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

indy 2021-06-01T17:54:44.222800Z

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

MatthewLisp 2021-06-01T18:00:44.224200Z

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

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

dpsutton 2021-06-01T18:01:36.224400Z

that should do it. did you try it?

dpsutton 2021-06-01T18:02:16.224500Z

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

2021-06-01T18:17:19.225Z

Iโ€™ll play with that, thanks!

phronmophobic 2021-06-01T19:09:38.225200Z

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

MatthewLisp 2021-06-01T19:21:36.225600Z

Yes it works @dpsutton thank you

๐Ÿ‘ 1
dabrazhe 2021-06-01T21:02:40.226200Z

ah, another unknown function, thanks )

dabrazhe 2021-06-01T21:09:30.226400Z

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