Fork me on GitHub
#beginners
<
2020-08-26
>
theron.bair01:08:48

extreme beginner Q: getting this from "lein figwheel":

[[email protected] ~/clojure/jobwatch]$ lein figwheel
Figwheel: Cutting some fruit, just a sec ...
2020-08-25 17:26:53,238 [main] WARN  clj-antlr.common - multi-hinted-let is deprecated and will be removed in a future clj-antlr release. Migrate to char-stream functionality. 
Exception in thread "main" Syntax error compiling at (luminus/http_server.clj:20:26).
	at clojure.lang.Compiler.analyze(Compiler.java:6808)
	at clojure.lang.Compiler.analyze(Compiler.java:6745)
	at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3820)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7109)
	at clojure.lang.Compiler.analyze(Compiler.java:6789)
...
	at clojure.main.main(main.java:38)
Caused by: java.lang.RuntimeException: No such var: http-kit/server-stop!
	at clojure.lang.Util.runtimeException(Util.java:221)
	at clojure.lang.Compiler.resolveIn(Compiler.java:7388)
	at clojure.lang.Compiler.resolve(Compiler.java:7358)
	at clojure.lang.Compiler.analyzeSymbol(Compiler.java:7319)
	at clojure.lang.Compiler.analyze(Compiler.java:6768)
	... 103 more                                                                                                                              │
... any idea what the deal is? brand-new Luminus project ("+reagent +http-kit +postgres +cljs +graphql +auth")

theron.bair01:08:06

I imagine there's something useful in that stack trace, but I don't see how to enable greater verbosity.

dpsutton01:08:40

I think the important bit is “no such var http-kit/server-stop”

seancorfield02:08:54

I can repro @theron.bair...

seancorfield02:08:14

...It seems to be a version compatibility issue that is somehow triggered when you try to start things via Figwheel. If I do lein repl and (require 'luminus.http-server) it loads just fine.

seancorfield02:08:40

There's so much in that template that it's hard for me to tell what's causing the problem (this is why I don't recommend Luminus for beginners: when things go wrong, there are far too many moving parts for them to stand any chance at debugging the problem).

theron.bair08:08:38

Well... when I say "beginner", I mean mostly "with Clojure's peculiarities". But yes, there are certainly a lot of moving parts.

seancorfield02:08:53

http-kit/server-stop! is new in http-kit 2.4.0, which is what luminus-http-kit 0.1.8 is bringing in. I think lein figwheel is causing an earlier version of http-kit to be loaded but I cannot figure out how (since I don't use Figwheel).

theron.bair09:08:33

Hmm. OK. Any suggestions for what to do with it? Skip http-kit?

seancorfield15:08:57

Jetty is fine so, yeah, skip http-kit. We use Jetty in production, to power 40+ online dating sites in a dozen languages worldwide -- it's solid for high-traffic stuff.

seancorfield15:08:08

Early on we saw random "thread death" errors with an earlier version of Jetty so we switched to http-kit, which was reliable but not supported by New Relic for monitoring, so we switched back to (a later version of) Jetty to get better monitoring and it's been rock solid since then @theron.bair

marcus.akre08:08:36

Hi! What would be the most effective way of finding if :done is set to true in ANY of the maps the following vector? [ [{:done true}{:done false}] [{:done false}] ]

michael.e.loughlin09:08:07

I think (some :done your-seq) would do it

michael.e.loughlin09:08:53

it will return true or nil if no :done true is in there

michael.e.loughlin09:08:35

there's also not-any?

marcus.akre10:08:04

@michael.e.loughlin so some will traverse all dimensions of the vector?

marcus.akre10:08:30

it works well on one dimension but not on more it seems

marcus.akre10:08:53

Maybe I just should flatten the vector first..

michael.e.loughlin11:08:13

Flatten is lazy so the performance hit might not be so bad

marcus.akre10:08:04

then some works

emilien10:08:54

if you have no more than 2 dimensions in your sequence this works: (some (fn [xs] (some :done xs)) your-seq)

michael.e.loughlin10:08:19

oh sorry, do you want arbitrary nesting like a tree?

michael.e.loughlin10:08:03

otherwise @emilien has it

marcus.akre11:08:16

thank you both @michael.e.loughlin @emilien there are always some elegant solutions in clojure.. just need to internalize them. 🙂

sb13:08:49

Any idea how to rewrite this CSS config

input[type="time"]::-webkit-calendar-picker-indicator {
    background: none;
}
in Garden/CSS?

sb13:08:49

Any idea how to rewrite this CSS config

input[type="time"]::-webkit-calendar-picker-indicator {
    background: none;
}
in Garden/CSS?

sb13:08:58

I solved: [“input::-webkit-calendar-picker-indicator” {:background “none”}] ..

endrebak8518:08:51

I found the line ;;ignore println statements in prod (set! *print-fn* (fn [& _])) I understand print-fn is, but I would like to see docs for it and all such global variables (or whatever they are called). Are they listed anywhere? I am guessing it is specific to Clojure since it is not defined anywhere in the Luminus-project I am reading.

dpsutton18:08:01

(doc print-fn)

dpsutton18:08:14

(But with earmuffs and not bold :)

endrebak8519:08:02

Thanks! I had the wrong repl open XD

alexmiller18:08:15

I don't think that's a clojure thing

endrebak8519:08:36

You are right, it is only in cljs-core it seems 🙂

endrebak8518:08:02

I'll ask in the luminus channel then 🙂 It was hard to google.

alexmiller19:08:03

if you want a list of all in-scope dynvars: (->> *ns* ns-name ns-refers vals (map symbol) (filter #(clojure.string/starts-with? (name %) "*")) sort pprint)

endrebak8519:08:39

Thanks! I'll play around with it 🙂

alexmiller19:08:26

presumably print-fn will be in there somewhere :)

alexmiller19:08:52

not sure that will work in cljs

edwintriana21:08:05

Hello all!, I’m a beginner and I’m trying to implement a SPA. I used a https://github.com/reagent-project/reagent-template template. I want to include an authentication/authorization schema. I have seen https://github.com/cemerick/friend and https://github.com/funcool/buddy-auth/. What do you recommend? Do you have good recommendations to read about web application development in clojure/clojurescript?

mruzekw21:08:30

For full-stack Luminus is a good start https://luminusweb.com/

mruzekw21:08:15

SPA you have a variety of options most common ones based on React. React wrappers: Reagent, rum, helix, uix Frameworks: Fulcro (relay-like), re-frame (redux-like)

edwintriana21:08:00

Excellent, I’m gonna check Thanks a lot!

mruzekw21:08:51

Luminus is based on ring so both Friend and Buddy should work with it

mruzekw21:08:19

For SPA, there’s also Keechma, though I don’t know much about it

seancorfield21:08:19

I would just caution that there are a lot of moving parts in Luminus and most folks new-to-Clojure tend to struggle with it. There is a book to go with it, Web Development in Clojure (in Beta for the Third Edition, so you buy the ebook and get updates as work on the book progresses). https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/

mruzekw21:08:04

Nice! Didn’t know that

seancorfield21:08:50

Without the book, making sense of the generated Luminus project, is really pretty tough for beginners. And Fulcro is equally bewildering for beginners.

seancorfield21:08:08

Web development with Clojure -- especially an SPA using ClojureScript on the front end and Clojure on the backend -- tends to be a lot harder for beginners than web development in a lot of other languages...

edwintriana21:08:55

Yes it is hard!, I think I’m gonna start with Luminus, then move to SPA when I master the basics.

seancorfield21:08:00

You might want to start with just Ring + Compojure to get the basics mastered. Then perhaps look at https://github.com/seancorfield/usermanager-example which uses Ring, Compojure, Component, Selmer, and next.jdbc. And then look at Luminus.

kaxaw7583621:08:05

Any reason you picked component/selmer over integrant/hiccup ?

seancorfield21:08:04

@kaxaw75836 I think Component is easier for beginners to understand (and I prefer it in production code over Integrant). The same goes for Selmer -- since it's like Django templates.

nfedyashev17:08:15

Sorry, I'm a bit late. @seancorfield would you mind explaining what's your opinion on tolitius/mount? At first sight, stuartsierra.component looks like much more boilerplate with no clear benefits.. but I must be missing something in component.

seancorfield17:08:58

mount relies on global state which is a bad idea, IMO.

nfedyashev17:08:05

Thanks! I'll spend more time exploring the component then. That's good I noticed your message in #beginners

seancorfield17:08:23

component makes it very easy to swap out components for testing and allows you to apply the start/`stop` lifecycle via metadata to Clojure objects. For example next.jdbc.connection/component uses that approach on a function to provide a minimal component-compatible approach to building connection pools.

seancorfield17:08:48

Integrant has both good and bad aspects, IMO. I like the data-centric approach in theory but I dislike the fragmented code that tends to appear when you implement the various hooks the Integrant provides.

seancorfield17:08:39

For example https://github.com/dharrigan/nextjdbc-integrant/tree/master/src/simple has Integrant-specific defmethod's all over the code base so trying to form a mental model of the "system" is much harder (for me, at least) and it looks much harder to swap out "components" / lifecycles when stubbing for testing.

seancorfield21:08:44

Also, we have UI folks on our team who do HTML/CSS/JS and they can edit our Selmer templates but would not be able to edit Hiccup data 🙂

kaxaw7583622:08:59

ah designers, true

kaxaw7583622:08:30

have you found any tangible benefits for data routing libraries over compojure?

admin05522:08:54

@kaxaw75836 For learning purpose, I redo the great usermanager eg. and decide to move some libraries to learn them too. - Compojure -> Reitit - Component -> Integrant Maybe it can help : https://github.com/PrestanceDesign/usermanager-reitit-integrant-example

admin05522:08:49

Thx so much for your useful repo and helping @seancorfield

seancorfield22:08:32

@kaxaw75836 We're using Bidi in one app at work, instead of Compojure. I suspect if we were starting over, we might use Reitit everywhere.

seancorfield22:08:39

I like how Reitit looks, based on @jacek.schae’s new course https://www.jacekschae.com/learn-reitit-pro/pfec2 for which I reviewed all the next.jdbc code.

seancorfield22:08:14

@admin055 That's nice. I'll update my readme to link to that as well.

admin05522:08:02

Perfect, thx! I'll put tomorrow an README too with backlink to your repo and usage to run the app.

hiredman22:08:41

the place where we use bidi the reverse routing was really nice in the beginning as our urls shifted around, but the urls have been fairly stable for sometime now

kaxaw7583622:08:22

seems like a really helpful feature when starting then

hiredman22:08:26

the big difference in my mind between compojure and most other routing libraries is in compojure finding the route and executing the handler are a single operation

hiredman22:08:07

you can't ask a compojure route what handler a url would hit without invoking that handler

hiredman22:08:40

splitting that up allows for some nice integrations with things like component, bidi can return a keyword (instead of a ring handler like most of the examples show), which you can use to lookup the handler component by name

hiredman22:08:01

I haven't used reitit, and have only been vaguely keeping an eye on it, but it seems to want to bake(maybe that is just the docs) in the idea that routing is a function of urls -> handlers, not urls -> whatever data I want, which is not a decision I am a big fan of

seancorfield23:08:51

Looks like it can use names instead of handlers in the routes https://cljdoc.org/d/metosin/reitit/0.5.5/doc/basics/path-based-routing

hiredman23:08:25

cool, something to keep in the back pocket