beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Iulian 2020-11-16T00:09:35.294100Z

Hi! I am trying to use the re-com library for a single-dropdown component. I added it to the dependencies and the code compiles fine, but if I use the single-dropdown component in my main component, it simply does not render anything anymore, without issuing an error or something of the like. This is how I import the library:

[re-com.core     :refer [h-box v-box box gap single-dropdown input-text checkbox label title hyperlink-href p p-span]]
And this is how I try to use it:
[single-dropdown
    :width     "200px"
    :choices [{:id :inline :label "Inline"} {:id :dropdown :label "Dropdown"}]
    :placeholder "Issue Group"]
If I place this component inside the component that I render, it simply does not render anything anymore. Do you have some troubleshooting tips?

gregg 2020-11-16T00:15:02.295Z

You're missing two mandatory args: :model and :on-change

gregg 2020-11-16T00:17:07.295500Z

I'm surprised there is no error message in the DevTools console

Iulian 2020-11-16T00:20:36.296Z

[single-dropdown
    :width     "200px"
    :choices [{:id :inline :label "Inline"} {:id :dropdown :label "Dropdown"}]
    :model nil
    :placeholder "Issue Group"
    :on-change #(print "Dropdown: " %)]
I updated the code, but it still does not render anything

dpsutton 2020-11-16T01:09:39.296500Z

i would imagine it needs all of those args in a map? {:width "200px" :choices ...}

dpsutton 2020-11-16T01:11:36.296800Z

oh wow. that's not the case. ignore me

2020-11-16T05:15:20.297100Z

@andy.fingerhut Perfect, thank you very much for your help! I'll try this.

gibi 2020-11-16T11:56:53.300200Z

Hi, I’m stuck at exercise http://www.4clojure.com/problem/30 , the code below throws this error Don't know how to create ISeq from: java.lang.Character

(defn remove-if-conseq-dup [acc r]
  (if (= (str (last acc)) r)
    acc
    (str acc r)))
(reduce remove-if-conseq-dup "Leeeroy")
If I pass '("L" "e" "e" "r") instead of "Leer" it works. Could you please help me? Thanks

Laurence Pakenham-Smith 2020-11-16T12:23:50.301100Z

default behaviour of reduce is that if you don't supply an initial value for acc, then it'll use the result of applying remove-if-conseq-dump to \L and \e - since \L is not a sequence, last doesn't make sense (in (last acc)). So you can either pass in an empty string as the initial acc value or do (last (str acc)) to make it a sequence that can have last run on it. After this there's still one logic error in it -- it's on the same line.

Laurence Pakenham-Smith 2020-11-16T12:25:06.301300Z

It works with '("L" "e" "e" "r") because "L" is a sequence whereas \L is not

2020-11-16T12:51:37.302900Z

I just read that proxy can only implement methods which are present in interface. So I must go with gen-class right?

gibi 2020-11-16T13:54:14.303Z

Thanks Laurence for your help, I’m still a little bit stuck

gibi 2020-11-16T13:54:38.303200Z

(reduce
  (fn [acc r]
   (if (= (last (str acc)) r)
     acc
     (str acc r)))
 "Leeeroy")
It works now this way, without initialising the accumulator

gibi 2020-11-16T13:56:07.303500Z

when I initialise it doesn’t work anymore and as you said, it’s failing the conditional logic

(reduce
  (fn [acc r]
    (if (= (last (str acc)) r)
      acc
      (str acc r)))
  "Leeeroy"
  "")

gibi 2020-11-16T13:56:46.303700Z

I guess it’s due to the type of acc and r ?

Laurence Pakenham-Smith 2020-11-16T13:57:59.303900Z

yep, acc is a string but r is a character, e.g. "A" is not equal to \A

gibi 2020-11-16T14:01:30.304100Z

this should work then, but it still seems to fail

(reduce
  (fn [acc r]
    (if (= (last acc) (str r))
      acc
      (str acc r)))
  "Leeeroy"
  "")

2020-11-16T14:22:40.304300Z

Cant you just use dedupe ?

2020-11-16T14:22:52.304500Z

(= (apply str (dedupe "Leeeeeerrroyyy")) "Leroy")
;=> true
?

2020-11-16T14:35:53.304700Z

But looking at the 4clojure, your method can't work by returning a string, as it also needs to work for vectors (and vectors of vectors) 🙂 You could to this?

#(map first (partition-by identity %))
?

gibi 2020-11-16T14:38:52.304900Z

Thanks Stuart, yes that is the best solution for the whole problem. 👍

gibi 2020-11-16T14:39:17.305100Z

I still don’t understand what’s wrong with the code above though 🤕

2020-11-16T14:42:21.305300Z

You have a couple of issues, the starting value for reduce should go before the collection. (reduce foo "" "Leerrrroooyyy") But also, put this (prn "acc::" acc ", r::" r ", last acc::" (last acc)) before the if statement

2020-11-16T14:42:26.305500Z

and you will see what is happening 🙂

2020-11-16T14:48:57.306100Z

EDIT: I was wrong, your version works if we change it to this:

(reduce
  (fn [acc r]
    (if (= (last acc) r)
      acc
      (str acc r)))
  ""
  "LLLLLLeeerrrrroooooyyyyy")
;=> "Leroy"

gibi 2020-11-16T14:50:26.306300Z

yep, anyway I was looking for a way to print the values and learn more. It will be useful in the future, thanks for your help!

Remy 2020-11-16T15:53:42.316600Z

Hello! I'm generating a pom.xml file with clojure -Spom . I haven't been able to find how to parametrize this in order to dynamically set eg. the &lt;version&gt; of my package... The end goal is to generate a jar with depstar. I know there's a channel for this tool and I could also use ${<http://env.MY|env.MY>_VERSION} in the pom directly, but the tool doesn't seem to parse these... so I figured i'd try here first.

lread 2020-11-17T16:22:05.390500Z

@remy, @rickmoynihan recently created https://github.com/RickMoynihan/pom-update which might work for ya!

2020-11-17T16:36:39.393800Z

Beetlejuice beetlejuice beetlejuice! I’ve not officially announced that library yet; as I was wanting to find some time to fix up the github actions so it would be able to deploy itself. However it should do exactly what you want, and also provide an example of how to use all the various pieces, clojure -X:deps mvn-pom, depstar and deps-deploy. See a script to tie everything together here: https://github.com/RickMoynihan/pom-update/blob/main/bin/deploy And the deps.edn: https://github.com/RickMoynihan/pom-update/blob/main/deps.edn

2020-11-17T16:40:18.394300Z

Also I recently made some changes to deps-deploy (on my fork only) to support private s3 wagons, and filed some issues on depstar that sean graciously fixed, that now make it possible to tie these things together as APIs to script custom builds in clojure. I haven’t shared a public example of this yet, but it’s pretty easy to do now, and was hoping of possibly pulling it all together into an easy tool for doing this job. Though hopefully tools.build will happen soon and make it all obsolete.

Remy 2020-11-17T16:51:39.394500Z

Nice, thanks for that tip. I was reading the conversation on #tools-deps from a couple days ago on the subject, and came to the conclusion i would just work around it for now. I'm really curious about the example tho.

Remy 2020-11-17T17:07:46.394700Z

Ok so I'm doing most of the things exactly like you are including depstar. Thanks for sharing!

gibi 2020-11-16T16:21:53.318800Z

Hello, is it correct to say that Clojure (or lisp languages) are functional but also imperative - in the sense that list of forms can be executed sequentially in a function and that it is also possible that their behaviour depends on the state of the program? For example if an atom is used.

Bob B 2020-11-16T16:24:26.318900Z

I'm not sure you need to - based on some little experiments, you can set the version, group id, artifact id, etc in your pom, and running clj -Spom doesn't change/reset them - it mostly just tweaks the dependencies (afaict)

Remy 2020-11-16T16:26:59.319100Z

Thanks, but I'm trying to generate the pom out of clojure source files. I want a generic way to setup the version since I generate several jars...

2020-11-16T16:32:45.319300Z

correct

👍 1
Bob B 2020-11-16T16:52:48.319600Z

in that case, you may want to consider something like Leiningen or Boot, which I believe contain more project config attributes, and probably have more in the way of creating build configs. Alternatively, you might want to ask in #tools-deps - presumably that's where the experts on clj are 🙂

adityaathalye 2020-11-16T17:13:57.319800Z

Clojure, yes. However, not all Lisps are functional languages by design. For example, Emacs Lisp (elisp) has dynamic scope and anything can potentially mutate anything. Suffice to say, it takes a lot more manual discipline to write functional elisp, than to write functional Clojure.

adityaathalye 2020-11-16T17:26:26.320100Z

Related: Whether Clojure or elisp (or many other languages for that matter), "Functional Core Imperative Shell" can be a powerful way to structure one's logic: https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell

Remy 2020-11-16T18:44:54.320400Z

thanks i'll look into those options 🙂

2020-11-16T19:53:07.322600Z

I'm having what is a new issue for me. The compiler is throwing the following error: ; Can't take value of a macro: #'clojure.core/loop Here is the code:

{:tag :qualifiedIdentifierExpression :xform (fn [node]
                                                 (loop [idPath []
                                                        idx 1]
                                                   (if (or (&lt; (count loop) idx)
                                                           (= "." (nth node (inc idx))))
                                                     (recur (conj idPath (nth node idx)) (+ idx 2))
                                                     idPath)))}

2020-11-16T19:53:45.323300Z

(count loop) - what is this supposed to do?

2020-11-16T19:54:17.324300Z

perhaps you want (count idPath)

2020-11-16T19:54:43.325200Z

loop itself is a macro, so you can't just use the value at runtime (and the value isn't really useful anyway)

2020-11-16T19:55:27.326Z

It transforms the data from the node in the form of (:qualifiedIdentifierExpression "a" "." "b" "." "c") into ["a" "b" "c"].

2020-11-16T19:55:50.326600Z

also, as a style concern, I'd usually use defn for a form that large, even if I only use it as a value in a hash map

2020-11-16T19:56:11.327400Z

@fadrian right, that's what that whole function looks like it would do if it compiled, but I was asking about that specific form, which is the source of your error

2020-11-16T19:56:56.328300Z

That's what the loop form does - it's supposed to return idPath once it's been loaded with the data.

2020-11-16T19:57:00.328500Z

the overall loop form, sure - but you can't just use loop as an identifier inside it

2020-11-16T19:58:11.329500Z

Oh crap. Thanks. It was supposed to be (count node). As usual, the error messages coming from Clojure are oh so helpful.

2020-11-16T19:58:39.329900Z

@fadrian loops is a macro, I think that error is pretty straightforward

2020-11-16T19:59:25.330600Z

see "can't take value of a macro: clojure.core/loop", look for places "loop" is in a non call position

2020-11-16T20:00:17.331500Z

generally that's what "can't take value" means - you used something that only works in a call position, in some other position in a form

2020-11-16T20:00:56.332Z

Thanks @noisesmith.

GGfpc 2020-11-16T21:50:45.334800Z

Really beginner question, but if I have a list of maps like this

'({:title "A" :count 1} {:title "B" :count 5} {:title "C" :count 2})
How can I add a new field :sum where the new field is the sum of all the previous (and current) :count fields?
'({:title "A" :count 1 :sum 1} {:title "B" :count 5 :sum 6} {:title "C" :count 2 :sum 8})

2020-11-16T22:18:15.338100Z

@ggfpc12495 that's a classic use case for reduce

dgb23 2020-11-16T22:21:10.338300Z

That’s a use-case for reduce I think. Generally, if you have a collection of X and want to do something that remembers previous results while generating a new thing, you use reduce. Something like this:

(reduce (fn [result item]
          (conj result (assoc item :sum (+ (or (:sum (last result)) 1) (:count item)))))
        '()
        '({:title "A" :count 1} {:title "B" :count 5} {:title "C" :count 2}))

dgb23 2020-11-16T22:21:36.338800Z

I don’t get your result though I didn’t figure out what :sum represents

2020-11-16T22:22:04.339200Z

conj gives the wrong order for list here

dgb23 2020-11-16T22:22:53.339600Z

also the 1 should be a 0

2020-11-16T22:23:31.339900Z

(def input                                                                     
  [{:title "A" :count 1}                                              
   {:title "B" :count 5}                        
   {:title "C" :count 2}])

(-&gt;&gt; input
     (reduce (fn [[updated total] element]   
               (let [total (+ total (:count element))]
                 [(conj updated (assoc element :sum total))           
                  total]))
             [[] 0])
     first) 
[{:title "A", :count 1, :sum 1}
 {:title "B", :count 5, :sum 6}
 {:title "C", :count 2, :sum 8}]

👍 1
2020-11-16T22:24:58.340700Z

it's possible to use the :sum from the prior element, but I think it's worth showing the pattern of using destructuring in order to track multiple values in a reduce

dgb23 2020-11-16T22:26:28.341Z

Oh I see this is way more elegant I agree

2020-11-16T22:27:03.341500Z

if the shape of computation is anything other than consuming a collection in order, you can use loop for this sort of thing

2020-11-16T22:27:19.341900Z

but reduce is helpful in that it abstracts the traversal for you

2020-11-16T22:27:33.342300Z

also reduced can be used for early exit of the reduce series

dgb23 2020-11-16T22:31:10.343Z

Oh I didn’t know [reduced](https://clojuredocs.org/clojure.core/reduced)!

dgb23 2020-11-16T22:37:22.344Z

Weird question: Are there libraries which consist of just EDN, just specs or even just namespaces? When would those be useful? Can you point me to any?

alexmiller 2020-11-16T22:41:40.344800Z

the cognitect aws api is basically an api + per-service libs for each aws service. each of the service libs is just edn data, edn docs, and specs

alexmiller 2020-11-16T22:42:27.345400Z

core.specs.alpha is a lib of specs for clojure core

alexmiller 2020-11-16T22:42:40.345600Z

https://github.com/clojure/core.specs.alpha

alexmiller 2020-11-16T22:42:54.346Z

there are some other libs of specs out there too

dgb23 2020-11-16T22:44:47.346200Z

thank you!

dpsutton 2020-11-16T22:46:04.347Z

Is cognitect anomalies just a namespace and some choice keywords?

👍 1
dpsutton 2020-11-16T22:46:22.347400Z

Not at a laptop so can’t look it up

alexmiller 2020-11-16T22:54:20.347600Z

yeah

alexmiller 2020-11-16T22:54:47.347800Z

https://github.com/cognitect-labs/anomalies

👍 1
dgb23 2020-11-16T22:58:10.348600Z

Ok this is kind of what I was looking for as an example to think about

alexmiller 2020-11-16T23:02:32.349300Z

the code .... is in your mind

dgb23 2020-11-16T23:05:45.349700Z

It’s more of a gut feeling at this point 😄

dgb23 2020-11-16T23:22:11.351300Z

would this be a good way to provide a doc string before putting a spec into the registry? It seems clunky: (defn message-string? "Documentation" [x] (string? x))

alexmiller 2020-11-16T23:24:32.352500Z

One whole point of putting specs I their own registry was to avoid creating vars for them, so that pains me :)

dgb23 2020-11-16T23:24:48.352900Z

i can see that

alexmiller 2020-11-16T23:25:33.353800Z

This is the highest voted issue in the Clojure issue system so I expect to address it in spec 2

dgb23 2020-11-16T23:26:26.354400Z

thank you that makes sense. It seemed to be a useful thing looking at https://github.com/cognitect-labs/anomalies