Fork me on GitHub
#beginners
<
2019-01-20
>
simesy00:01:03

not sure how to ask.Can i get stuff out of dotimes? simplistic example…

``````(defn something
[count]
(dotimes [n count]
; do something with a side effect
(+ total-ran 1)
("Total: " total-ran)
``````
so that
``````(something 5)
-> "Total: 5"
``````

kingmob01:01:52

@simon223 If you look at the `dotimes` macro (https://github.com/clojure/clojure/blob/clojure-1.9.0/src/clj/clojure/core.clj#L3305), you can see the body of the `loop` is a `when` that always ends in a recur call, so it’ll always return nil when the iterations are done. `dotimes` is primarily for side effects. If you want to just return the number of iterations, you can do that from the `count` var, but that’s not very useful, assuming not every iteration has a side effect. What you might want is something like this:

``````(defn something
[count]
(loop [n count
total-ran 0]
(if (< n 0)
(str "Total: " total-ran) ; return final result
(if (even? n) ; some test to determine whether to do something
(do
(println "Did something with" n)
(recur (dec n) (inc total-ran)))
(recur (dec n) total-ran)))))
``````

simesy02:01:40

@kingmob thankyou!

👍 1
kingmob03:01:10

Happy to help. Feel free to reach out if you have any other questions

simesy04:01:42

is a binding basically a pointer/reference?

seancorfield04:01:52

A binding gives a name to a value. Each time you `recur` you give the same names to new values.

seancorfield04:01:12

A top-level name, bound with `def` (or `defn`) is more like a pointer/reference since a `Var` is created -- the name is bound to the `Var` and the `Var` "contains" the value. And you can alter what the `Var` contains (`alter-var-root`, for example, or just calling `def` again).

simesy06:01:05

thanks @U04V70XH6 and @kingmob i got what i needed with something like:

``````(defn do-stuff [total]
(loop [results []]
(if (= (count results) total)
(results})
(do
(let [new-thing (do-something)]
(recur (conj results new-thing))))...
``````

seancorfield06:01:43

`(take total (repeatedly #(do-something)))` should be about the same.

👍 1
N/A04:01:19

is there a type of prettier for clojurescript? where on save the file reformats automatically like this: https://github.com/prettier/prettier

soulflyer05:01:34

emacs with clojure-mode and aggressive-indent?

N/A06:01:01

Thank you!

Karol Wójcik13:01:03

How can I destructure extra_info keys from the map?

``````{
:categories ["A"]
:attributes {
:tags ["tag1"]
:unit_price "1"
:extra_info {
:neutrient_elements ["elem1"]
}
}
}

``````
I tried something like
``````[{:keys [categories] :as product
{:keys [tags unit_price] :as attributes} :attributes
{:keys [nutrient_elements] :as extra_info} [:attributes :extra_info]}]
``````
and it seems to work for attributes but does not destructure the extra_info 😞

yuhan15:01:55

you'll have to destructure it inside your `attributes` map

❤️ 1
yuhan15:01:18

``````[{:keys [categories] :as product
{:keys [unit-price tags] :as attributes
{:keys [nutrient-elements] :as extra-info} :extra-info} :attributes}]
``````

yuhan15:01:03

but at this level of nesting it's probably more readable to use `get-in` than use destructuring

simesy15:01:28

if i have `[{:type "cat" :age 5}, {:type "dog" :b 6}]` how can i get a list like `("cat", "dog")`?

simesy15:01:24

a little uncertain about my square/round brackets there, but my squigglies are definite 😅

eggsyntax17:01:46

Bit of feedback on the above, just for context: You can express it either as a `[vector]` or a `'(list)` (note the quote so that it doesn’t try to interpret `(list)` as a function). Either works equally well in this case; it seems to be more common to use vectors for literals. They have different performance characteristics, but those aren’t going to matter unless you’re dealing with a large number of elements. One way to think about it is that they’re both sequences (ie fulfill the sequence interface), and a ton of functions in Clojure operate on sequences, without caring what the concrete type is.

simesy17:01:14

@U077BEWNQ the “sequence interface” makes sense, I generally keep forgetting what’s what after i google it 😛

yuhan15:01:42

`(map :type <your list>) `

simesy15:01:02

ah i was close with map.. thanks!

simesy16:01:20

`map` is clearly where I need to get my skates on

simesy16:01:02

maybe i mean transducers

Oliver Marshall16:01:28

@simon223 If you're just starting out you'll probably have a better time focusing on the classics like map, filter and friends before moving on to transducers

👍 1
simesy17:01:24

Definitely starting out… sooo. i feel bad i couldn’t work this out, because it feels simple… but i’ve got beginners amnesty? Trying to turn:

``````{:First "foo", :Second "bar"}
``````
into
``````{:First
[:eq "foo"]
:Second
[:eq "bar"]}
``````
My latest non-working example.
``````output ((fn [[k v]] [:eq v]) (into [] input))]
``````
im just not quite getting how to process/transform items in a map 😕

simesy17:01:11

ok i think i’m … close

Oliver Marshall17:01:39

I PM'd you if you still need help btw 🙂

rakyi17:01:15

you can use `map` or `for` with `into {}` or `reduce-kv`

rakyi17:01:20

`(into {} (for [[k v] {:First "foo", :Second "bar"}] [k [:eq v]]))`

rakyi17:01:14

there are also utility libraries which implement `map-vals` for mapping over values in a map, which clojure doesn’t have built in

rakyi17:01:07

do you understand why your example doesn’t work?

simesy17:01:04

ah i got similar.. yeah i did mostly understand why my examples weren’t working from the errors.

simesy17:01:22

I got

``````output (into {} (for [[k v] input] [k [:eq v]]))]
``````

yuhan17:01:29

have a look at `update` also (edit: oops, misread the question)

👍 1
simesy17:01:29

looks same?

simesy17:01:10

that ended up as simple as i hoped 😄

tim19:01:59

you can also use `reduce` and be lazy: `(reduce #(assoc %1 (first %2) [:eq (last %2)]) {} {:First "foo", :Second "bar"})`

Lennart Buit19:01:31

(you can do code formatting with backticks (` ` `), how to escape backticks is beyond me for now)

tim19:01:29

k, thnx.. can u edit messages?

Lennart Buit19:01:04

yes, to the right is a menu with three dots

Lennart Buit19:01:29

OR, when it is the last message you wrote, you can simply press arrow up

tim19:01:02

ok, thnx