Fork me on GitHub
#clojure
<
2023-07-10
>
timo12:07:15

Anyone ever used hyperscript for frontend work? I am currently using htmx and am in need to add a hyperscript snippet to my button to create a modal https://htmx.org/examples/modal-bootstrap/.

[:button.button {:hx-get "/admin/address/new"
                 :hx-target #modal-div
                 :hx-trigger "click"
                 :_ "on htmx:afterOnLoad wait 10ms then add .show to #modal then add .show to #modal-backdrop"}
  "Button"]
With that clj-kondo already gives me a hint:
■ missing value for key "on htmx:afterOnLoad wait 10ms then add .show to #modal then add .show to #modal-backdrop"
and Clojure gives me
; (err) Syntax error reading source at (REPL:116:39).
; (err) No reader function for tag modal-div
I assume that the hash-signs are causing this. Anyone knows how to get around this?

timo12:07:54

ah damn, I see it now. The hx-target needs to be in quotes

👍 2
timo12:07:15

Sorry for the interruption

Rupert (Sevva/All Street)12:07:42

Yeah - htmx shouldn’t need any special treatment in hiccup.

👍 2
Alex Miller (Clojure team)17:07:12

This is a known issue - there was a bug in the indexer we use that has added some junk. Hope to have it fixed soon

👍 2
rolt08:07:22

great sorry for the noise then ! thanks

jasmin18:07:57

Is it important to add :else nil at the end of cond? In other words, is something like this ok:

(cond
  false :whatever)
which returns nil, or do I have to explicitly add :else nil or true nil ?
(cond
  false :whatever
  :else nil)

p-himik18:07:47

You don't have to add it. As the docstring says, you can even have (cond) which returns nil.

jasmin18:07:29

How about adding it as a message that the previous statements don't cover all the possibilities? In a sense, omitting :else nil indicates that nil cannot be returned as a result of that cond

p-himik18:07:01

Personally, I wouldn't do it and would remove it in any code that I own. It's just noise.

hiredman18:07:41

I very often do :else (assert nil) which is an extremely lazy way to signal that the conditions in the cond should be exhaustive

7
p-himik18:07:25

Ah, if you want to fail on a non-match, then yeah. I manage to force myself to use ex-info. :D

4
Noah Bogart18:07:56

I usually do (throw (ex-info ...)) but (assert nil) is very clever

jasmin19:07:45

Thank you for your help!

oyakushev19:07:08

@U0NCTKEV8 @UEENNMX0T I wrote this some eons ago, maybe it is useful to somebody: https://bytopia.org/2016/10/15/beware-of-assertions/ Basically, assert throws an Error, not an Exception, and this might be a problem sometimes.

hiredman19:07:16

Well aware, yes I always catch throwable

👍 2
didibus06:07:16

Aren't assert disabled sometimes as well?

vemv06:07:59

Alex' article doesn't acknowledge that you can simply

(try
  (catch Exception e
    ,,,)
  (catch AssertionError e
    ,,,))
One normally doesn't have to write this, because you'd have assertions disabled on production anyway (which perhaps some years ago was bit of a less-understood technique... now it's particularly easy to control with tools.build) I generally don't like to catch Throwable btw, because it also eats things like StackOverflowErrors. You could leave a machine stuck in a bad loop

vemv06:07:09

re OP, :else nil is defensible. It signals to maintainers that the author didn't forget to add an :else (which does happen)

2
Joshua Suskalo15:07:17

I have to say: it is very bad to catch Throwable everywhere, and you should carefully consider in each case whether to use an assertion or throw an ex-info. Use ex-info for situations that may arise as a result of user error, network failures, or other expected error conditions. Use assert for situations that indicate programmer error and which cannot come up otherwise (e.g. can only come up if an argument or return value doesn't match the spec it claims, a codepath is unreachable, etc).

Joshua Suskalo15:07:53

In cases where someone has made an incorrect decision about which to use and as a result assertion errors are being thrown in an expected error case, always catch AssertionError and never catch Throwable.

Joshua Suskalo15:07:50

The reasoning for this the generalization of what vemv was referring to: Error is noted by the JVM as specifically being for throwables which no sane program should attempt to catch. The only general-purpose exception to the rule that catching Throwable or Errors is a code smell is in task dispatch frameworks that need to keep the thread alive in case of a failure.

Joshua Suskalo15:07:29

Obviously there may be other exceptions to that general rule but they should be evaluated on a case-by-case basis and strongly favor being specific.

Joshua Suskalo15:07:56

(I'll also admit that I may be a bit more dogmatic about not catching Throwable than most, because I am the author of a library that relies on Error not being caught in random places to function correctly)

hiredman16:07:20

It's cool, I don't use your library

🤷 1
Joshua Suskalo16:07:44

It's not like my library is the only thing that uses errors. ThreadDeath, OutOfMemoryError, StackOverflowError, LinkageError, and others are all things that extend Error and are highly likely to produce undesirable behavior if you catch them.

Joshua Suskalo17:07:10

> An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. There's a reason this is the very first line of the Error javadoc.

hiredman17:07:27

sure, and your Error indicates a "serious problem that a reasonable that a reasonable application should not try to catch" right? you don't catch it right?

Joshua Suskalo17:07:57

Obviously my personal usecase is outside that domain, it's hijacking that property, and I see no issue with people avoiding my library because of it. It's simply the fact that making the library pushed me to research this topic more that has exposed me to these other issues that I believe anyone who wants to write reliable software on the JVM should care about, regardless of if they happen to use my library.

didibus07:07:02

I don't typically catch Throwable inside the code, but at the boundary, absolutely. Around APIs, or command inputs, etc. You don't want a throwable crashing your server for no good reason.

d._.b18:07:26

What is the library of choice for async http stuff in clojure?

borkdude18:07:19

babashka http-client supports it (any library built on java.net.http does I think like hato, etc), also http-kit supports it

oyakushev19:07:13

Speaking from experience, Aleph is the most mature solution, but learning to use it properly is a long journey.

kawas21:07:37

For client stuff, I have done a lot of https://github.com/dakrone/clj-http and it was complicated to use (async flavor) and painful (I just want a wall-clock timeout on my request 😞) thank to the clunky Apache Http API. These days, I just roll https://github.com/http-kit/http-kit it is easy to use and just works.

didibus06:07:20

httpkit is always the one I end up back too. The others always give me some issues here and there

hifumi12308:07:39

for async http handlers, ive been messing around with pedestal + jetty and its a breath of fresh air compared to ring-based solutions

borkdude09:07:57

are we talking http client or server?

d._.b15:07:29

clj-http's async flavor is... odd

d._.b15:07:46

normally i reach for http-kit for this kind of thing, but im also using datadog tracing and http-kit's client isn't included in their automatic instrumentation

d._.b15:07:50

as a result im now looking at hato

d._.b15:07:20

which relies on the java 11 httpclient, which is datadog supported

didibus07:07:41

I had an issue with the babashka http client, switched to http-kit, issue was gone, wished I had filed an issue, but now I can't remember

🤷 2