Fork me on GitHub
#beginners
<
2022-11-16
>
valerauko01:11:05

is there a built-in way to un-namespace the keys in a map?

dpsutton01:11:17

there is not. Note that there's no way to do this in core you have to put extra requirements on the data in the map. The easiest way to see this is that it is trivial to come up with examples where you would lose information. if f un-namespaces the keys in a map,

(f {:a/foo 1 :b/foo 2})
-> {:foo ?}
which result would you want here?

dpsutton01:11:14

of course you can easily do this yourself:

core=> (update-keys {:a/foo 1 :b/foo 2} (comp keyword name))
{:foo 2}
but you'll need to figure out if you have collisions in your maps under this projection

dpsutton01:11:00

and of course, be aware if you have non-keywords in your map

core=> (update-keys {:a/foo 1 :b/foo 2 [:a :b] 2}
                    (comp keyword name))
Execution error (ClassCastException) at multiset.core/eval409 (REPL:30).
class clojure.lang.PersistentVector cannot be cast to class clojure.lang.Named (clojure.lang.PersistentVector and clojure.lang.Named are in unnamed module of loader 'app')

seancorfield06:11:34

My question would be: why do you want to do this @UAEH11THP? A common use case is to create JSON but the common JSON libraries all either do this for you or have an option to do it. In general, I recommend sticking with qualified keys -- they're idiomatic.

valerauko06:11:11

trying to satisfy coworkers who keep complaining about qualified keys ๐Ÿคท

seancorfield06:11:40

lemma at 'em! I'll "satisfy" them! :rolling_on_the_floor_laughing:

๐Ÿ˜‚ 2
seancorfield06:11:52

Why are they complaining?

valerauko08:11:06

"omg it's so many letters to type"

valerauko08:11:00

meanwhile they're okay with typing ReverseAuthorityLookupService in ruby so ???

1
seancorfield18:11:02

> "omg it's so many letters to type" I'll just say #:prefix{:a 1, :b 2} and ::alias/a, ::alias/b... typing problem solved ๐Ÿ™‚

valerauko04:11:23

that and destructuring with ::ns/keys

1
Oliver Marks07:11:12

Trying to convert some java code to clojure, I believe I bassically need reify and to define the methods myself in reify, how ever what I am less sure is how I create the private vars as part of reify, in this case img and type vars in this java code, https://github.com/codecentric/javafxsvg/blob/master/src/main/java/de/codecentric/centerdevice/javafxsvg/BufferedImageTranscoder.java Is reify the right direction even an if so how do I handle the vars ?

dumrat07:11:01

public abstract class ImageTranscoder
I believe you need proxy, not reify.

Oliver Marks07:11:28

okay thanks I will go look up proxy ๐Ÿ™‚

Oliver Marks08:11:30

Also worked out the vars, looks like you wrap it all in a let binding, found this example which is similar to what I want http://gettingclojure.wikidot.com/articles:extending-java-classes-using-proxy

Oliver Marks13:11:07

thanks for that tip, I may continue down my current path if only to get more familiar with interop, even if I come back to the above solution

๐Ÿ‘ 2
Benjamin09:11:10

(def f
    (future
      (loop []
        (Thread/sleep 500)
        (println "hi")
        (recur))))
  (deref f 10 :timeout)
I desire the thread to cancel after the timeout, how do I do that

dumrat09:11:44

How about the naive hack of just looking at a var and if set, terminating inside the thread?

dumrat09:11:18

(def flag (atom false))

  (def f
    (future
      (loop []
        (if (not @flag))
          (Thread/sleep 500)
          (println "hi")
          (recur)))))

  (deref f 10 :timeout)
  (reset! flag true)

Benjamin09:11:02

Actually I'll go to #C01ALH5JGRJ. I realized the more essential thing am wondering is if I can leak resources with deref a request

๐Ÿ‘ 1
Noah13:11:03

When I make a definition in the REPL and I evaluate one of my source files, the definition gets overwritten. What is commonly the cause of this?

kennytilton13:11:32

Lisps treat functions as first-class objects, meaning they have identity, meaning no matter where you define mynamespace/my-function, the compiler replaces the one incarnation of mynamespace/my-function.

Noah13:11:11

Is there some way to use multiple namespaces at once?

delaguardo13:11:01

better to evaluate the form in the editor and not in the repl.

๐Ÿ‘ 1
delaguardo13:11:58

that way you will have some parity between the code and the state of your program

skylize14:11:22

A common pattern is using "Rich comments" to hold code to evaluate only during repl development. Then you can use the editor as the only input for repl evaluation.

(defn foo [bar] bar)

; A `comment` evals to nil, essentially being discarded
;  at runtime.
(comment
  ; But you can place your cursor on the internal form
  ;  and command the editor to evaluate it in the repl.
  (foo :baz)
  )

๐Ÿ‘ 3
dumrat14:11:09

When I was beginning in Clojure, I had the same issue as OP. The trouble was that I had no one to look at and I started Clojure by myself. So I didn't quickly pick up the common idioms and tools. I think this is something that gets overlooked quite often. Things like evaluating code in editor instead of the repl that seem so obvious to me now - I did not even know about back then. I guess when people tout the virtues of the REPL they forget to mention that you really shouldn't actually directly use the REPL. Anyway, what @U90R0EPHA mentioned. Those comment blocks end up as documentation in the end also where you can come back to the same code file some time later and look at the comment block and get an idea of how the code is supposed to work. (The only gripe I have about comment blocks is that it gets invalidated as the code evolves - some of the stuff in there won't work as function signatures and impl change. But I haven't found this a huge issue yet)

practicalli-johnny18:11:35

To evaluate code at the REPL prompt in a terminal, then (in-ns 'another-namespace) can be used to switch to anther namespace. To use functions from other namespaces in the current namespace, the other namespace should be required, then specify the fully qualified name (directory-filename) of the function to call.. To make this very easy, Clojure editors will evaluate a function or other code within the namespace defined in the current file, so regularly switching and requiring namespaces is not required. This is an overview of the REPL driven workflow I use for Clojure (with some example videos) https://practical.li/clojure/repl-driven-development.html

Gerome14:11:53

Hello everybody! I have this API that returns me paginated data. So, I the response for the first page is a vector [result1 result2 result3...] and I need to send another request, sending page number 2 as a query param and I get [result10 result11 result 12...]. I would like all of this in one vector. I'm using http-kit as a client. I get all the results in a @promise or a callback and all my mind wants to do is shove everything in an atom and deal with it later (which of course only defers the problem because when is later?). Anyway, how would you pull all that asynchronous data into one vector?

Gerome14:11:02

Now that I think of it, this seems to call for a reducer of some kind.

Gerome14:11:23

I just need to collect all promises in a vector and then pull out the data in a reduce...

dumrat14:11:02

Just pseudocode:

(mapv 
  (fn [page-start page-end] 
    (deref 
      (future 
        (query page-start page-end)))) 
  (get-page-ranges))

dumrat14:11:11

Something like that ^ ?

Gerome14:11:40

I need to look up what deref and future does

dumrat14:11:48

Actually let me check this. Not sure if this blocks ๐Ÿ˜„

dumrat14:11:03

Please keep in mind I'm also a beginner

Gerome14:11:17

It probably does.

Gerome14:11:38

Hehe, it's not life or death code

R.A. Porter14:11:55

Assuming youโ€™re on Clojure 1.11, paginated queries beg for the iteration function. Hereโ€™s a good intro post about it: https://www.juxt.pro/blog/new-clojure-iteration

๐Ÿ‘ 2
Gerome14:11:13

@UC1DTFY1G I think what's an issue here, though is that the predicate to mapv should be side effect free afaik. However, that's a good start because it would allow me to at least collect all the futures in one vector. I could then handle all of them in a doseq.

๐Ÿ‘ 1
dumrat14:11:21

@UPJP9G4G1 or: (pmap (fn [i] (Thread/sleep 1000) (* 2 i)) (range 1 10))

dumrat14:11:31

Don't know if you are ok with n amount of parallel API calls

dumrat14:11:41

But otherwise looks fine to me

Gerome15:11:33

I need to go but I'll try it later. Thanks!