Fork me on GitHub
#clojure
<
2023-09-19
>
Alexandre EL-KHOURY08:09:58

Hello quick question : Is there a specific way to import @ packages in clojurescript ? exemple : import { Web3Button } from '@web3modal/react' When I write this ["@web3modal/react" :refer (Web3Button)] I get an error :

--- node_modules/@web3modal/react/dist/index.js:78
Dynamic import expressions cannot be transpiled.

p-himik08:09:32

The error has nothing to do with the @ character. Also, this really belongs in #clojurescript.

p-himik08:09:54

And it's been asked before: https://clojurians.slack.com/archives/C03S1L9DN/p1689532330872299 tl;dr: You'll probably have to use webpack.

borkdude09:09:54

with shadow-cljs you can use ESM directly

p-himik10:09:53

ESM - yes, dynamic imports - no.

borkdude11:09:56

do you mean JS that contains dynamic imports? you can use dynamic imports from .cljs code using shadow-cljs as well

borkdude11:09:25

(as the link suggests, probably the first)

joshcho210:09:29

Is there a way to extend clojure maps so that they preserve semantics (like keyword access, destructuring), but make it so that accessing them via a key that doesn’t exist throws an error?

joshcho210:09:21

For instance, (def m (safe-map {:a 1})) (:a m) => 1 (:b m) => throws an error

joshcho210:09:00

And ditto for clojurescript

tatut10:09:08

something like

(let [m {:a 1}
      strict-m (reify clojure.lang.ILookup
                 (valAt [_ key]
                   (let [v (get m key ::not-found)]
                     (if (= ::not-found v)
                       (throw (ex-info "No such key" {:key key}))
                       v)))
                 (valAt [_ key not-found]
                   (get m key not-found)))]
  (:b strict-m))

❤️ 1
p-himik10:09:32

A custom map type can do that. I'm 80% certain there have already been a similar discussion and there's probably a library for it somewhere, or at least a gist. The code above doesn't cover all of the semantics of a regular map.

tatut10:09:33

not that I would recommend it necessarily, but ILookup is probably what you want

tatut10:09:53

but a reify output will look ugly and opaque in REPL, not like a regular map at all

practicalli-johnny11:09:45

Or wrap the hash-map access with the or function from Clojure and provide an expression to run should the key not be present

practicalli-johnny11:09:24

Or access the hash-map with get or get-in and provide a default value if a key is not present

practicalli-johnny11:09:05

I am afraid it's not clear from the question why a hash-map should be extended. Are the existing ways of accessing a hash-map relatively safely not suffice? There is always Clojure spec or Mali that define a specification, should it be beneficial to check the structure of a hash-map before accessing

tatut11:09:11

I too would recommend using spec or malli instead or do :pre conditions instead of custom map type

respatialized16:09:50

It sounds like you may be relying on error handling for control flow with this map type. While that's sometimes unavoidable, I think for such a simple use case it's considered an antipattern in Clojure. Idiomatic use of maps in Clojure generally assumes them to be "open", with data that may or may not be present. Why is a map that throws an error preferable to something like the following?

(get my-map :b default-val)
; alternatively 
(or (:b my-map) (do-something-else))

joshcho18:09:20

(op here) i am creating a macro-based nested map for state management like re-frame’s db. so one might have central state like (def db {:var1 3 :var2 “hello”}) (do-something (:var1 db)) the issue here is that during refactoring, i’d like to catch any errors/mismatch that may occur. if the automatic throw occurs, then i can change the :var1 to :variable1, and fix all the places where incorrect access is being made. just a guarantee that the maps are being used in the correct manner

joshcho18:09:06

also, curious how this would look like in cljs

respatialized19:09:08

I think you can do that with fspec: https://cljs.github.io/api/cljs.spec.alpha/fspec (I've never used spec from cljs so I can't speak to the dev/refactoring experience, however)

❤️ 1
joshcho01:09:04

@U2FRKM4TW i am trying to search if such a library exists, with no luck. searching sth like "strict map". any pointers?

joshcho01:09:53

also, i probably need to reach into java, javascript internals for this; where is a good place to start?

marcofiset15:09:18

It's been stated already, but throwing such an error is not idiomatic in Clojure. You want to use a spec library to enforce map keys, like clojure.spec or malli. That would allow you to spec some critical code paths and instrument them in dev to catch eventual errors.

đź‘Ť 1
joshcho22:09:24

@U07SWUQTH Agreed. It's just the use case I have is very specific (a state managment library). I think such techniques will be used for library authors more often (like with Pathom).

timvisher13:09:19

Are there any Clojure goodies for 'optional chaining' so that I can just descend into a Java API via Getters and not constantly have to check whether I've gotten null back by hand?

ghadi13:09:11

some->

đź’Ż 3
1
Alexander Bird13:09:30

get-in I think does optional chaining in ways too.

user=> (get-in {:a {:b 4}} [:a])
{:b 4}
user=> (get-in {:a {:b 4}} [:a :b])
4
user=> (get-in {:a {:b 4}} [:c :b])
nil
user=> 

timvisher13:09:35

@U03E1FSM4NM Right. Many of the Clojure native APIs do nil-punning quite nicely (as you'd expect). But get-in, unless I'm missing something, can't descend via Java getters.

đź‘Ť 1
Alexander Bird13:09:46

ah, yes. I missed that part of the question. I don’t know if it helps with that

Carsten Behring18:09:18

some-> works with interop as well

(def m (java.util.HashMap.))
(some-> m (.get "not-here") (.get "not there"))
-> nil

timvisher19:10:36

some-> was such a good solution to this! :D

kennytilton15:09:48

Are you using shadow-cljs? The answer varies depending. btw, you might try the #C03S1L9DN channel.

Ingy döt Net17:09:45

What order does clojure.test/run-tests run tests in? Can I control the order?

jpmonettas17:09:23

looks like it calls ns-interns, so that is the order, but it also looks like it checks for a hook to customize that : https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L737-L762

Alex Miller (Clojure team)17:09:40

I don't think ns-interns returns mappings in any particular order (not definition or sorted by name at least), so I believe it's arbitrary

Alex Miller (Clojure team)17:09:02

test-ns-hook really relies on you listing every test so it's generally impractical

Alex Miller (Clojure team)17:09:29

it's better to fold any important ordering into a single test var

Ingy döt Net17:09:32

I should note that I am not using deftest but am generating tests from a data file and interning them

hiredman17:09:40

a lot of testing libraries explicitly don't call run-tests, but instead do stuff to shuffle the order that tests are run

Alex Miller (Clojure team)17:09:42

oh, well then make test-ns-hook :)

Ingy döt Net17:09:43

I've used test-ns-hook to run a single test. How do I get it to return multiple tests?

Alex Miller (Clojure team)17:09:01

it's replacing test-all-vars so it needs to do what that does ,so invoke every test

Alex Miller (Clojure team)17:09:23

or rather I guess call test-vars with a collection of test vars

Ingy döt Net17:09:36

If I'm generating a sequence of tests, and using test-ns-hook to run them, do I even need to intern them?

Alex Miller (Clojure team)18:09:26

I mean, depends how much of clojure.test you want to use :) test-vars relies on vars so if your'e using that then yes I think

oyakushev19:09:56

@U05H8N9V0HZ Rather than ensuring the order of tests, it is better to make them independent if possible. For example, if you need some state set up for the test, take a look at clojure.test/use-fixtures.

Ingy döt Net19:09:05

These tests are independent but I have a verbose mode in my test runner and I found it disconcerting that the tests were not run in the order that I added them. That's why I asked the question here.

đź‘Ť 1