Fork me on GitHub
#beginners
<
2020-11-16
>
Iulian00:11:35

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?

gregg00:11:02

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

gregg00:11:07

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

Iulian00:11:36

[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

dpsutton01:11:39

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

dpsutton01:11:36

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

gibi11:11:53

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-Smith12:11:50

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-Smith12:11:06

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

gibi13:11:14

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

gibi13:11:38

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

gibi13:11:07

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

gibi13:11:46

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

Laurence Pakenham-Smith13:11:59

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

gibi14:11:30

this should work then, but it still seems to fail

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

Stuart14:11:40

Cant you just use dedupe ?

Stuart14:11:52

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

Stuart14:11:53

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

gibi14:11:52

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

gibi14:11:17

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

Stuart14:11:21

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

Stuart14:11:26

and you will see what is happening 🙂

Stuart14:11:57

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"

gibi14:11:26

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!

Michaël Salihi12:11:37

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

Remy15:11:42

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 <version> 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 ${_VERSION} in the pom directly, but the tool doesn't seem to parse these... so I figured i'd try here first.

Bob B16:11:26

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)

Remy16:11:59

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...

Bob B16:11:48

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 🙂

Remy18:11:54

thanks i'll look into those options 🙂

rickmoynihan16:11:39

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

rickmoynihan16:11:18

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.

Remy16:11:39

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.

Remy17:11:46

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

gibi16:11:53

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.

delaguardo16:11:45

correct

👍 3
adityaathalye17:11:57

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.

adityaathalye17:11:26

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

fadrian19:11:07

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 (< (count loop) idx)
                                                           (= "." (nth node (inc idx))))
                                                     (recur (conj idPath (nth node idx)) (+ idx 2))
                                                     idPath)))}

noisesmith19:11:45

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

noisesmith19:11:17

perhaps you want (count idPath)

noisesmith19:11:43

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

fadrian19:11:27

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

noisesmith19:11:50

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

noisesmith19:11:11

@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

fadrian19:11:56

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

noisesmith19:11:00

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

fadrian19:11:11

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

noisesmith19:11:39

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

noisesmith19:11:25

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

noisesmith20:11:17

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

GGfpc21:11:45

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

noisesmith22:11:15

@ggfpc12495 that's a classic use case for reduce

dgb2322:11:10

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

dgb2322:11:36

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

noisesmith22:11:04

conj gives the wrong order for list here

dgb2322:11:53

also the 1 should be a 0

noisesmith22:11:31

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

(->> 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}]

👍 3
noisesmith22:11:58

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

dgb2322:11:28

Oh I see this is way more elegant I agree

noisesmith22:11:03

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

noisesmith22:11:19

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

noisesmith22:11:33

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

dgb2322:11:22

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?

alexmiller22:11:40

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

alexmiller22:11:27

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

alexmiller22:11:54

there are some other libs of specs out there too

dgb2322:11:47

thank you!

dpsutton22:11:04

Is cognitect anomalies just a namespace and some choice keywords?

👍 3
dpsutton22:11:22

Not at a laptop so can’t look it up

dgb2322:11:10

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

alexmiller23:11:32

the code .... is in your mind

dgb2323:11:45

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

dgb2323:11:11

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

alexmiller23:11:32

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

dgb2323:11:48

i can see that

alexmiller23:11:33

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

dgb2323:11:26

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