Fork me on GitHub
#beginners
<
2020-04-20
>
i04:04:10

when you want to find the index of an element in a vector, do you use .indexOf method ?

didibus05:04:03

If that works go for it

hindol.adhya05:04:57

I collected these two from the web,

(defn positions
  [pred coll]
  (keep-indexed (fn [idx x]
                  (when (pred x)
                    idx))
                coll))

(defn position
  [pred coll]
  (first (positions pred coll)))

jaihindhreddy04:04:13

(keep-indexed #(when (= x %2) %) coll) will give you all such indices.

vishal.gautam05:04:46

Has anyone used Cypress with Reagent + Shadow-cljs app for end to end testing ?

tkjone20:04:02

Do you mean writing the cypress tests in CLJS? Or just testing CLJS app with cypress?

vishal.gautam21:04:14

I meant writing tests in CLJS. The latter is very trivial

neo255106:04:37

I am trying to remove the eval of the following macros, can anyone help me? I have been trying a lot haha.

(defmacro reg-fn+path
    [fname p]
    `(defn ~(symbol fname)
       ([] ~p)
       ([m#] (get-in m# ~p))
       ([m# v-or-fn#] (assoc-in m# ~p v-or-fn#))
       ([m# f# & args#] (apply update-in m# ~p f# args#))))

  (defmacro reg-fns+paths [fns+paths]
    `(for [[f# p#] ~fns+paths]
       (eval `(reg-fn+path ~f# ~p#)))) ;; fns+paths is a map of symbol to vectors of keywords

neo255106:04:05

(sorry for the variable naming)

ashnur07:04:39

can I install cljs dependencies from github?

david.perrenoud07:04:54

I don’t know the answer of your question but I would advise on copying the files locally, to avoid a dependency on Git when deploying

ashnur08:04:12

• deploying doesn't depend on third party servers in any case, I find it worrying, but also somewhat amusing that lots of people trust long running and heavily used services for deployment. • we already depend on git • but this question in particular luckily is just about sharing development code, the master branch on github has a bug fixed that's not yet deployed to clojars • it's a clojurescript dependency

gchewie01:04:17

Is this an infrastructure management question? If you're concerned about maintaining upstream artifacts for production deployments, rely upon package-lock.json to lock in your versions and then mirror those to a local repository somewhere. Running local-npm somewhere might be a quick solution for you. Otherwise you can look to Nexus or Artifactory servers for a more commercially supported solution.

gchewie01:04:33

A hackier way is to rely upon git clones of upstream packages, but only refer to them in your package.json by your clone references.

ashnur07:04:37

no, this is just a convenience question so it is less effort for my colleagues to check my code without me having to bundle dependencies with it (which is what the original suggestion - to copy it manually - amounts to)

ashnur07:04:45

or to clone it

ashnur07:04:08

in javascript/npm I can just install stuff from github normally, but I am guessing clojurescript is different.

endrebak8508:04:30

Are there helper print libraries that can show stuff like where a call to the print function was made and what the names of the variables were?

rakyi10:04:05

there is https://github.com/weavejester/hashp and few other similar solutions

jimka.issy09:04:33

Is it possible to have a lazy sequence such that reading an element causes a side effect? I am asking because I have an function I want to document with a warning. In my function, I usually iterate through the sequence. But in some cases, I abort the iteration early. Thus if the caller is expecting side effects, they may not happen.

hindol.adhya09:04:02

Do you want to know if a side-effecting lazy sequence can be created? It is definitely possible, the simplest being (map println (range 100)).

jimka.issy09:04:36

Yes, that's want I wanted to know. Thanks.

hindol.adhya09:04:48

Using lazy-seq, you can suspend any operation, side-effecting or not.

(realized?
 (lazy-seq
  (println "Hello, world"))) ;; => false

hindol.adhya09:04:31

And lazy-seq is used extensively throughout Clojure, basically all functions that return a lazy sequence will be using lazy-seq.

hindol.adhya09:04:59

And that is why, side-effecting lazy seq is discouraged in Clojure. All Clojurists shall already expect this. So a short note in the docstring should be enough.

orlandomr2711:04:21

Hi, is there a something like Flask WTForms in Clojure? I’m using Selmer to render my html files

jimka.issy12:04:10

What is the correct way/philosophy to emit a warning in clojure? In Common Lisp a warning is an instance of a special sub-type of condition. Consequently a warning may be handled or ignored by any function in the call chain. The default handler it to print it to the output stream. I don't find a warn function

timur05813:04:31

Would using logging libraries help you achieve what you want? You can flexibly specify where you want the message to go, and also set up custom handlers

jimka.issy13:04:37

hmm. my issue is that I, the library implementor, do now know where the output should go. In Common Lisp, I can leave that decision up to whoever calls into my library, and it works that way by design.

jimka.issy13:04:12

What is common in clojure?

jimka.issy13:04:17

potentially I can write a *warn* function bound to a dynamic variable, thus allowing the caller to rebind it. That's a pretty easy solution.

timur05811:04:55

I really might be mistaken here, but as far as I understand, https://github.com/clojure/tools.logging this standard library's aim is to be this abstract "common" point in all logging, and applications makers get to decide what goes where based on their preference (a lot of logging backend options are available). But it's in no way an answer, I really don't know the details — but rather I think this is the direction to research.

jimka.issy13:04:23

Is reduce /`reduced` the only loop in clojure which provides an early exit capability? I have an ugly piece of code, which I know I'll regret later, but I don't know how else to do it. I'm iterating over an input sequence to compute a Boolean value. In some situations I can compute the result without finishing consuming the sequence, but in other cases I need to wait until the sequence is finished. I'm piggy-backing off reduce/reduced to allow me to escape early.

(defn rte-execute [dfa items]
  (letfn [(consume [state-index item]
            (let [state-obj (dfa state-index)]
              (cl-cond
               ((:sync-state state-obj)
                (reduced (:accepting state-obj)))
               ((some (fn [[type next-state-index]]
                        (if (ty/typep item type)
                          next-state-index
                          false))
                      (:transitions state-obj)))
               (:else (reduced false)))))]
    (let [final-state (reduce consume 0 items)]
      (case final-state 
        (true) true
        (false) false
        (:accepting (dfa final-state))))))

skuttleman13:04:58

loop/recur is a general purpose, low level looping structure that can terminate whenever you want it to. https://clojuredocs.org/clojure.core/loop

jimka.issy13:04:17

Yes, I was originally using loop, but for that I need to deconstruct the sequence every time into head and tail. I refactored it into reduce to avoid this destructuring step. reduce also takes care of the empty sequence, which loop with destructuring doesn't do.

jimka.issy13:04:57

It looks like reduced does not work lexically. If reduce is being called from with the body of another reduce, then a call to reduced exists the inner loop, even if it is sitting lexically outside of it.

clojure-rte.core> (reduce (fn [acc1 items]
                            (println [:items items])
                            (letfn [(abort [x]
                                      (println (format "aborting with value %s" x))
                                      (reduced x))]
                              (reduce (fn [acc2 item]
                                        (println [:item item])
                                        (when (even? item)
                                          (abort [:aborting item]))) :init-val-2 items)))
                          :init-val-1
                          [[1 3 5 7 9]
                           [11 13 15 17 21]
                           [101 103 12 107 201 311]
                           [201 203 23 2072 301 411]
])
[:items [1 3 5 7 9]]
[:item 1]
[:item 3]
[:item 5]
[:item 7]
[:item 9]
[:items [11 13 15 17 21]]
[:item 11]
[:item 13]
[:item 15]
[:item 17]
[:item 21]
[:items [101 103 12 107 201 311]]
[:item 101]
[:item 103]
[:item 12]
aborting with value [:aborting 12]
[:items [201 203 23 2072 301 411]]
[:item 201]
[:item 203]
[:item 23]
[:item 2072]
aborting with value [:aborting 2072]
[:aborting 2072]

alexmiller13:04:19

reduced is just a function that wraps the return value, not syntax

jimka.issy13:04:20

I often accidentally swap the argv and the docstring like this:

(defn foo [a b d]
  "this is the argstring"
   ...)
And I don't see any warnings anywhere. Is there something that I should be doing so that the system reminds me? For example, I have a constant expression, the string, in a non-tail position so the compiler could warn me. right?

jimka.issy13:04:20

I often accidentally swap the argv and the docstring like this:

(defn foo [a b d]
  "this is the argstring"
   ...)
And I don't see any warnings anywhere. Is there something that I should be doing so that the system reminds me? For example, I have a constant expression, the string, in a non-tail position so the compiler could warn me. right?

doby16213:04:07

cl-kondo or lein eastwood would remind you, and they add a lot of value in other ways as well :+1:

teodorlu15:04:03

I was doing the exact same thing for a long time 😅 Clojure has no complaints at all if the first expression in your defn happens to be a string ... doc didn't work too well, though!́

jr0cket19:04:26

@ If your editor has code snippets, that is a simple way to ensure things are written the right way around. Or clj-kondo does catch the error if there is more code after the string. As the example works fine as clojure, except for the ... there is no error to report. If nothing else comes after the string, then it returns it as a value. If there is other code after the string, then clj-kondo will show a warning about the misplaed doc string.

jimka.issy07:04:12

@, are you using this with emacs/cider? I've tried to set this up as explained https://github.com/borkdude/flycheck-clj-kondo, but it doesn't simply work out of the box.

jr0cket07:04:47

I am indeed. I'm even writing a book about it https://practicalli.github.io/spacemacs/

jr0cket07:04:37

First check clj-kondo works on the command line. Then check the path is picked up by Emacs, e.g. getenv command in Emacs. There is a command to check if flycheck is picking up the backend (need to Google that).

jr0cket07:04:14

Make sure you restart Emacs if you just added a new path.

jimka.issy07:04:54

clj-kondo not found. Do I need to install it with brew or port? I didn't see any note about that in the https://github.com/borkdude/flycheck-clj-kondo.

jimka.issy08:04:41

got it, thanks.

jimka.issy08:04:43

now what's supposed to happen? It's not clear to me how to run it. Is it supposed to be something that runs autonomously or do I need to launch a command to check my code? which command?

ben.sless08:04:57

M-x flycheck-buffer I think, after you have set flycheck

jimka.issy08:04:07

apparently there is also M-x flycheck-mode

ben.sless08:04:18

yes, you need to turn it on, first. You can add a hook to clojure-mode to turn flycheck-mode on

jimka.issy08:04:36

OK, this is interesting. it complains about unused variables. Is there a convention for marking a variable as "yes I know I'm not using this one" ? for example, I must provide a binary function, but in my particular function I don't use both variables.

ben.sless08:04:53

yes, prepend _ to the variable name

ben.sless08:04:02

or just name it _, it's a legal name

jimka.issy08:04:24

is naming it _ the only way?

ben.sless08:04:36

you can name it _functions, too

ben.sless08:04:44

anything starting with _

jimka.issy08:04:31

ahh, cool, I can name it _functions. I used a lisp some years ago which had the same convention. it allows me to have descriptive unused variable names

jimka.issy08:04:08

sadly, if I name it with an _ and then use it, there is no warning 😞

ben.sless08:04:29

that's a feature suggestion for kondo right there ^

jimka.issy08:04:10

you mean I should file an enhancement issue? or that it is an outstanding known enhancement request?

ben.sless08:04:30

I mean you could file one. It's a good enhancement

jimka.issy08:04:12

that would be an enhancement of cjl-kondo right?

ben.sless08:04:45

wrt to configuring all the different tools for clojure in Emacs, Spacemacs works well in that regard. don't know how invested you are in your emacs configuration.

ben.sless08:04:45

I think you accidentally typed out the arg vectors in common-lisp style instead of clojure-style

ben.sless08:04:46

And gave the issue a thumbs-up, it's a good feature

jimka.issy09:04:53

I notice that eastwood created a .eastwood file. should I .gitignore it or will it be useful when I share the repository later?

jimka.issy14:04:16

is there a count cousin of some which counts the number of times a predicate is matched? Of course it is easy to write, but would rather use the one already defined.

hindol.adhya14:04:34

There isn't one. There are a few popular libraries that add such "missing pieces". I will link some.

shewitt14:04:51

(count (filter pred? coll))

dev.4openid15:04:38

noobie here (making progress :rolling_on_the_floor_laughing:) basic question: I am calling several APIs. I have created called AP I1 in the core.clj and have placed the second API 2 in a file zxc.clj. During development I want to evaluate the code written in zxc.clj but the repl will not operate as it seems to be bound to core.clj At present, there is no relationship between core.clj and zxc.clj as no code in core.clj calls anything in zxc.clj

dev.4openid15:04:09

So how do I evaluate the code? What technique is used?

kelveden15:04:05

It sounds like you need to read up on require - http://clojuredocs.org/clojure.core/require. Have a read of this as well: https://clojure.org/reference/libs.

dev.4openid15:04:46

So I treat the second file as a library file using :require? After reading the docs is seems that way - I mean the docs do not reflect user generated file but use http://java.io etc. Maybe it is that I have missed it? Thx

noisesmith15:04:46

after using require, you can use functions from the other namespace, or switch into the namespace

noisesmith15:04:59

user made files and the ones that come with clojure are not treated differently

dev.4openid15:04:45

OK I will experiment with this. Thx

dev.4openid15:04:20

Of course I could put everything in the same file but.....not best practice

mattias50415:04:12

So, for multi arity functions I still only get one doc string, right?

noisesmith15:04:18

right- there's only one doc string for any given var

noisesmith15:04:51

this is why, unlike other lisps, clojure doc strings go before the arg list instead of after

mattias50415:04:24

Yup, makes sense. I was itching to write specific strings. I’ll live 😅

vishal.gautam16:04:50

Hello, I have a quick question. I am trying to use the timeline feature of GSAP in cljs reagent project. The function below does this: https://greensock.com/docs/v3/GSAP/Timeline. What I am trying to achieve is I want to generalize the process. I wrote a version that uses recursion, but it doesnt work unfortunately. Any ideas

(defn animate
  []
  (-> (.timeline gsap)
      (.from ".targetA" (clj->js {:opacity 0
                                  :duration 0.6
                                  :y 10
                                  :ease :power1}))
      (.from ".targetB" (clj->js {:opacity 0
                                  :scale 0
                                  :ease :back}))
      (.from ".targetC" (clj->js {:opacity 0
                                  :ease :power}))
      (.from ".targetD" (clj->js {:opacity 0
                                  :xPercent -50
                                  :ease :power1
                                  :duration 0.5}) "<")
      (.from ".targetE" (clj->js {:opacity 0
                                  :xPercent 50
                                  :ease :power1
                                  :duration 0.5}) "<")))

hindol.adhya16:04:56

You will have better luck if you move this to either #clojurescript or #reagent

hindol.adhya16:04:54

Saying this because the Reagent author himself is active on #reagent :)

haywood16:04:06

how would you go about (slurp "src/project_name/core.clj") reading and modifying a clojure file?

mitchell_clojure18:04:50

how do you want to modify it? heavy duty usage might require an analyzer (tools.analyzer or the clj-kondo analyzer might be good places to start looking)

orlandomr2717:04:05

Hi, is there a something like Flask WTForms in Clojure? I’m using Selmer to render my html files

drewverlee03:04:32

I'm guessing you mostly want the csrf token handling right? I believe they're is a ring middle Ware for that, and from there you have to just include that token in the html.

orlandomr2710:04:46

Hi @ I would need to use that too. I found some examples using csrf token and the readme on ring. If you have something to shine a light for me I would appreciate it.

jtth22:04:36

anyone have any idea why, using the luminus template, something like the following would fail to send on the :session info? i just want to redirect people after logging in, and i’m just not understanding something somewhere. but the session info just goes away.

(defn login! [{:keys [params session]}]   
  "logs user in"
  (if-let [user-identity (authenticate
                           (get-in params [:email])
                           (get-in params [:pass]))]
    (-> (response/found "/authenticated-test")
        (assoc :session (assoc session :identity user-identity)))
    (response/unauthorized {:result  :unauthorized    
                            :message "login failure"})))

jtth22:04:02

I’ve tried asking in #luminus and #ring and got nothing, and every example I’ve looked up is so painfully simple that it’s trite. Is there some example application that shows how to do this right? That function returns the map to redirect, but for some reason that session information isn’t preserved, or I’m not accessing it right and it isn’t showing through the {% debug %} even though I thought it was being passed to the templates rendered through Selmer.

jtth22:04:10

I know everyone is hot and heavy over SPAs in ClojureScript but it’d be really helpful to have a good example of a classic server-rendered webapp somewhere as a reference.

seancorfield22:04:04

What session storage are you using?

seancorfield22:04:49

(I'm guessing the session access is keyed via cookies -- and it's not portable to set cookies on a redirect, so that might be a problem)

jtth22:04:11

Yeah, basic session stuff with buddy. And I think I’m realizing that, but every single example app does the same thing, and the login works (the cookie is set and the user is auth’d through buddy.auth), but I just don’t know how I’m supposed to persist the session info if I can’t redirect. Am I not supposed to do that, and if so, what am I supposed to do? I guess I figured this is a solved problem that I wouldn’t really have to deal with, but I’m used to rails + devise, so I don’t really know what’s going on.

seancorfield22:04:49

Yeah, I was just reading over Adam Bard's blog post about Buddy and redirect with assoc :session is exactly what he shows...

seancorfield22:04:13

We implemented OAuth2 and that process is to redirect after login with a short-lived code in the URL, that the application then presents to the Auth Server with its own credentials and gets back the actual access/refresh tokens to use with the API Server. It's a much more complicated process, but it never tries to redirect and set cookies in the same response.

jtth22:04:59

Yeah, it seems like there’s some breakdown happening here. Oh well. Thanks for your help (again!). Hopefully someone who has run across this will answer in one of the places I posted.

seancorfield22:04:24

Sorry. I've seen a few people run into this and I don't know what the "right" answer is, beyond the technically accurate but unhelpful one that cookies + redirects aren't universally supported 😕

codonnell22:04:31

Do you see the cookie getting set in your response header? Where are they disappearing?

seancorfield22:04:21

Oh, unrelated but important: you have the docstring in the wrong position in your login! function -- it should be between the function name and the argument list. As written, your function will "evaluate" the string "logs user in" as the first expression in the function body and then throw its value away.

jtth22:04:40

Woah, good catch! Thanks!

jtth22:04:29

@ cookie is there the whole time (in luminus it’s served immediately on loading any page with the session middleware, which is everything here), it’s the session info that’s not persisting, and it’s more that everyone seems to describe it as somehow being preserved after a redirect in guides and examples and posts.

smith.adriane22:04:06

does other session info persist successfully? or is it just this one redirect that’s not successfully persisting session info?

jtth22:04:05

@ that session info is the only stuff that’s being created for the redirect; csrf-token comes in through in the request through some middleware just fine

jtth22:04:56

I’m getting the feeling this is all from some reitit complexity or something.

jtth22:04:13

But thank you all, I gotta stop for today.

jumar04:04:06

Btw. here's a SO question related to Set-Cookie on redirects: https://stackoverflow.com/questions/4694089/sending-browser-cookies-during-a-302-redirect It seems that it's almost always supported.

jtth13:04:45

I don’t want to set a cookie. I want to forward session parameters. The cookie is set just fine. I want the session parameters to persist. That’s internal to the server. The cookie is just a UUID that maps to the session. It’s set just fine. Is it wrong to think that this should be a completely solved problem? I really want to just work on my app, not re-engineer user accounts and other basic web stuff. I’m going to try a little more today, but if I can’t figure this stuff out I’m gonna go back to rails for this project because I really don’t want to be dealing with stuff outside the business logic if I can help it. Is coast better for this?

seancorfield16:04:35

@ I had a quick look at a basic Luminus-generated project and it seems to override the default session setting (in-memory) to be via a cookie so, if it is working, I would expect to see session data encoded into a cookie. I didn't dig very deep. But this sort of stuff is why I tend to avoid framework-y templates and go for the basics (Ring, Compojure, Component, Selmer) so I don't have to worry about whatever "magic" the template is imposing on me.

jtth16:04:21

Yeah, I may try that one last time, but I really don’t want to set up a lot of that boilerplate stuff myself. FWIW the repo is here https://bitbucket.org/jtth/irbportal/src/bb8382ddc933842023f8bfba4353a5dcd7a5ace1/src/clj/irbportal/routes/auth.clj#lines-49

jtth17:04:12

I figured it out. The session is fine, there’s just no way of accessing it within luminus’s layouts. Which… what is the point of the template if not to provide such things? Anyway thank you for your help. Once again I find it dangerous to assume things.

sova23:04:42

@orlandomr27 What functionality do you get out of WTForms that you would like a library for? I don't know what Flask WTForms does.

orlandomr2710:04:29

Hi @ from flask wtforms I can declare a class with the structure of a html form. Type, validators, lenght:

password_confirm = PasswordField("Confirm Password", validators=[DataRequired(), Length(min=6, max=15), EqualTo('password')])
Then on the html template you can add the dinamic content
{{ form.email.label }}
{{ form.email.data }}
I prefer clojure and FP over python, but wtforms can save you a lot of work.

sova14:04:42

that looks super hlpful. i would also be interested in a solution for clojure(+script). i think you can do a lot of stuff with clojurescript and node these days, people import certain node libraries and use them outta the box with cljsjs but i'm not very experienced with that

orlandomr2715:04:46

It would be interesting to see something like flask wtforms in clojure, not with class but with a map. I wish I could have more exp to work on that myself