Fork me on GitHub
#beginners
<
2022-09-24
>
ahungry00:09:44

I want (dotimes [i 3] (something i)) to accumulate the result where the iterator is relevant - is (map something (range 3)) the best bet?

lsenjov01:09:34

(for [i (range 3)] (something i)) is also a possibility

thanks3 1
seancorfield01:09:31

There's also map-indexed which can useful in situations like this.

seancorfield01:09:37

user=> (defn something [n x] (* n x))
#'user/something
user=> (map-indexed something [2 4 8 16])
(0 4 16 48)
user=>

seepel08:09:32

Is there a way to call a function from a macro in clojurescript? I'm looking for something like

(defn do-foo [x] x)
(defmacro foo [x] `(do-foo ~x))
Right now I put the above in a clj file and in the clojurescript file I repeat the function
(ns foo (:require-macros [foo]))
(defn do-foo [x] x)
Is there a way to avoid the duplication?

Georgi Stoyanov11:09:36

Hi guys 🙂 I'm learning Clojure at the moment with Clojure for the brave and true. So far so good, I'm writing one of the exercises and it's pretty strange to me why it's not working. I need to write a function that is mapset -> works like map, but returns a set. Ex: mapset inc [1 1 2 2] => #{2 3} I've managed to make it to this state, but it throws an exception "Error printing return value (IllegalArgumentException) at clojure.lang.RT/seqFrom (RT.java:557). Don't know how to create ISeq from: java.lang.Long" Then I've changed the seq to be in brackets ( "[seq]") and this returns #{2}. seems to me like the map is applied only to the first value, not to the whole sequence. What could be the reason for that?

(defn mapset
  "docstring"
  [expr [seq]]
  (into #{} (map #(expr %) seq))
  )
(mapset inc [1 1 2 2])

delaguardo11:09:02

don't use destructuring for the collection you want to use as is later. just remove square brackets from arguments form of your function

✅ 1
Georgi Stoyanov11:09:01

yep, that one worked. Silly me

dpsutton13:09:28

and one thing, #(expr %) is equal to just expr. So just map the function expr and not an anonymous function that calls expr on an arg

Sam Ritchie20:09:35

If you move one paren you can use a transducer version and avoid an intermediate sequence!

(defn mapset
  "docstring"
  [expr seq]
  (into #{} (map expr) seq))

(mapset inc [1 1 2 2])

🙌 1
ahungry17:09:11

Howdy all - I have an :env/dev alias that I use to load some basic repl features - how can I apply this to all namespaces in my project?

(ns user
  (:require
   [clojure.main]
   [ahungry.overdexer :as od]))

(defn go []
  (apply require clojure.main/repl-requires))

(go)

ahungry17:09:35

I want to be able to do (doc something) regardless of what ns I am in

ahungry17:09:06

Hmm, maybe if it helps future readers, I just worked around it with my editor:

(defun my-cider-repl-set-ns ()
  "Like cider-repl-set-ns, but better."
  (interactive)
  (call-interactively #'cider-repl-set-ns)
  (call-interactively #'cider-switch-to-repl-buffer)
  (cider-interactive-eval "(clojure.core/refer-clojure)")
  (cider-interactive-eval "(clojure.core/apply clojure.core/require clojure.main/repl-requires)"))
The historic answer I found wasn't satisfactory (https://stackoverflow.com/questions/43196754/make-clojure-functions-available-in-every-namespace-during-development) for the goal

dpsutton17:09:00

What editor are you using?

dpsutton18:09:04

Cider or inf clojurr?

ahungry18:09:01

cider - it's having some funky behavior though - even though at first glance it seemed to work, it swaps back to 1 prior NS on the stack of ones I've went through - I tried subbing the cider-interactive-eval calls for cider-insert-in-repl - still being strange...almost a good solution, just gotta polish it a bit more 😄

ahungry18:09:25

like, the repl shows my.other.ns> but when I eval a form, it goes back to my.prior.ns>

dpsutton18:09:31

Weird. The reason I asked is that cider provides actions for those so you don't need to have doc in the current namespace

ahungry18:09:39

this guy seems to work, but sure is ugly - it leaves the forms unsubmitted:

(defun my-cider-repl-set-ns ()
  "Like cider-repl-set-ns, but better."
  (interactive)
  (call-interactively #'cider-repl-set-ns)
  (call-interactively #'cider-switch-to-repl-buffer)
  (cider-insert-in-repl "(clojure.core/refer-clojure)" nil)
  (cider-insert-in-repl "(clojure.core/apply clojure.core/require clojure.main/repl-requires)" nil))

ahungry18:09:15

hah yea, C-c C-d C-a or C-c C-d C-d and friends? That works well if I've entered a thing at point, but sometimes I like to do exploratory stuff locally and not just google it..

ahungry18:09:47

like, (doc pmap) or (source pmap), regardless of where I'm hacking at in the repl

ahungry18:09:22

(if anyone cares, the first solution works if the interactive eval calls are staggered by 1 second with a run-with-timer - I think cider has some race condition / async going on, and it was effectively evaluating those forms before the NS switch was totally done)

didibus05:09:17

What's the advantage of (doc pmap) over cider show doc?

didibus05:09:46

Like type pmap and press C-c C-d C-d ?

ahungry17:09:43

to me, it feels more natural to just type (doc whatever) when I'm already in the repl (rather than go back over to the source and do there)

ahungry17:09:24

if there was a solution outside of the editor approach, it would have been nice for the purposes of being able to do in inf-clojure or even straight from cli with clj

dpsutton17:09:34

What you're doing is exactly what I do for inf clojure. Just a keybinding to require the repl requires

didibus17:09:05

Oh, I guess since I never type in the REPL buffer, I assumed you could also show doc on a symbol in it just like other clojure buffer. Weird that it doesn't. What you can do is define a doc function in your user.clj, and then you can do (user/doc ...) from anywhere. In theory you can also just do (clojure.repl/doc ...) but I admit that's a lot of typing. The last thing you can do, but it's more involved, is write a nRepl middleware that auto-requires it on ns switch.