Fork me on GitHub
#clojure
<
2021-08-18
>
vemv07:08:41

Say I have a file named config.edn representing a single map. Would you find a strong drawback to unwrapping the top-level map and letting each top-level form represent either a k or a v? Most times it would be obvious whether a form is a k or a v (keys are often a single keyword; values are often larger than keys). One could use commas after each k-v in case of doubt. This would remove a level of indentation and also make editing/formatting more isolated. I'm thinking of paredit navigation or map alignment... often those become global if everything belongs to one big map

rickmoynihan08:08:23

Well the main problem as I see it is that .edn is intended to be a data format; and therefore its interpretation will likely be shared and want to be unambiguous. If you do this anyone reading your .edn file will need to know to slurp the file and handle it specially with something like: (read-string (str "{" slurped-config "}")). Specifically the problem I see is that you’re removing the container from the serialisation, so users won’t know what the correct structure is. I would personally assume that such a file was a sequence of top-level forms that would need to be read one at a time with clojure.edn/read rather than clojure.edn/read-string. Using heuristics and hints like you suggest will be brittle (and also unlikely to be supported in any existing edn parser); commas in the edn spec are whitespace and not something most parsers represent as they have no homoiconic data representation. I see very little reason to opt out of the standard only to save two characters and a little bit of indentation. Also one other problem is that users may easily find yourself with an odd number of forms, which will no longer generate a parse error.

rickmoynihan08:08:49

If your data really is just a sequence of forms, then you can certainly use clojure.edn/read to read and represent it — but it sounds like it’s a hashmap.

vemv09:08:30

Good considerations thanks! A nuance which maybe I should have stated in advance is that only my app will read this file, prior to passing it elsewhere. (It's a fairly common thing to do) So other than editors/formatters/linters there wouldn't be arbitrary readers that could somehow choke on this file I'm aware that what I have in mind isn't exactly clean, however I'll entertain the idea unless there's a hard-and-fast flaw

rickmoynihan10:08:21

That’s entirely up to you — but I wouldn’t underestimate the communication power of having { } in the file itself.

👀 3
thheller07:08:04

I thought about doing that for shadow-cljs.edn a long time ago but decided against it. didn't feel right somehow. looked weird in practice IMHO.

👀 3
javahippie08:08:46

In an application I have defined Clojure functions with defn. These functions are called at runtime dynamically (from Java Code with Clojure.var), they are not referenced in the code itself. Everything works fine in the REPL, but in the compiled application, I am getting Attempting to call unbound fn when I try to call the function. My assumption is, that the functions are removed as dead code while compiling the Uberjar, would that be correct? Is there some kind of hint to prevent the removal?

vemv08:08:48

uberjarring does not perform dead code elimination I'd debug this by inspecting the uberjar. For each ns there should be N .class files denoting each defn (or fn) If there's nothing, there's something wrong in your uberjarring (I assume you perform AOT along with the uberjarring, but one does not imply the other)

rickmoynihan08:08:47

There’s no such thing as dead-code elimination in clj (on the standard jvm anyway — graalvm native-image does I believe do something like this though). I suspect you’ve just not required the namespaces or initialised the clojure environment properly… e.g. with:

IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("clojure.set"));

👍 6
javahippie08:08:29

You suspected correctly, I did not require the ns. Thanks a lot you two!

👍 3
rickmoynihan10:08:49

FWIW you may be interested in clojure.core/requiring-resolve (added in clojure 1.10)

javahippie11:08:55

Thanks again, I bookmarked it 👍

FiVo09:08:18

Are there any whitelabel app examples in Clojure(script)? Open source? Just to be clear, I am not talking about frameworks/templates where a developer fills in the details, but rather a users building their app with no-code/low-code tools. I admit that the line becomes blurry at some point.

vemv11:08:57

A no-code platform sounds like something that would be closed-source / commercial You might have luck by searching multitenancy (not the same thing, but might solve a % of your problem)

FiVo11:08:01

I was actually more interested in how a no-code app could look like on the cljs side.

vemv11:08:20

Yeah I get it but it would be quite the coincidence... it's like asking if there's an Uber clone in clojurescript I'd focus instead in the underlying APIs (like drag and drop) or components (e.g. https://github.com/day8/re-com)

sansarip15:08:07

It’s not quite what you’re asking for, but https://github.com/penpot/penpot is an open source design and prototyping platform written in clj/cljs. I’m sure there would be a lot of ideas you could draw :lower_left_paintbrush: inspiration from by looking through their codebase if you’re curious about creating a drag-n-drop UI builder simple_smile

👍 3
oly15:08:53

wonder if anyone can give me some suggestions, I have a stack trace Caused by: java.lang.Exception: No namespace further up the stack trace I have Exception in thread "main" Syntax error compiling at line 1:1 I know this is normally caused by - and _ but i have neither in the namespace or files, anything else i should be looking for ?

oly15:08:45

its strange in that the app runs, and the thing i change was to bring in the cognitext test runner and use clj -X:tests which then makes the error appear

oly15:08:01

the error is not in any of the test namespaces how ever

seancorfield16:08:31

@oliver.marks You'll need to provide a bit more info... in a thread, could you paste the stacktrace and provide some info about deps.edn and your project structure?

oly16:08:11

clj -X:dev:tests
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See  for further details.

Running tests in #{"test"}
Exception in thread "main" Syntax error compiling at (beanbag/schemas/pricesnagger/feeds/feeds.clj:1:1).
	at clojure.lang.Compiler.load(Compiler.java:7647)
	at clojure.lang.RT.loadResourceScript(RT.java:381)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.load(RT.java:463)
	at clojure.lang.RT.load(RT.java:428)
	at clojure.core$load$fn__6824.invoke(core.clj:6126)
	at clojure.core$load.invokeStatic(core.clj:6125)
	at clojure.core$load.doInvoke(core.clj:6109)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5908)
	at clojure.core$load_one.invoke(core.clj:5903)
	at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
	at clojure.core$load_lib.invokeStatic(core.clj:5947)
	at clojure.core$load_lib.doInvoke(core.clj:5928)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$load_libs.invokeStatic(core.clj:5985)
	at clojure.core$load_libs.doInvoke(core.clj:5969)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$require.invokeStatic(core.clj:6007)
	at clojure.core$require.doInvoke(core.clj:6007)
	at clojure.lang.RestFn.invoke(RestFn.java:482)
	at beanbag.views.v2.orders.invoice_generation$eval22174$loading__6706__auto____22175.invoke(invoice_generation.clj:1)
	at beanbag.views.v2.orders.invoice_generation$eval22174.invokeStatic(invoice_generation.clj:1)
	at beanbag.views.v2.orders.invoice_generation$eval22174.invoke(invoice_generation.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7176)
	at clojure.lang.Compiler.eval(Compiler.java:7165)
	at clojure.lang.Compiler.load(Compiler.java:7635)
	at clojure.lang.RT.loadResourceScript(RT.java:381)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.load(RT.java:463)
	at clojure.lang.RT.load(RT.java:428)
	at clojure.core$load$fn__6824.invoke(core.clj:6126)
	at clojure.core$load.invokeStatic(core.clj:6125)
	at clojure.core$load.doInvoke(core.clj:6109)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5908)
	at clojure.core$load_one.invoke(core.clj:5903)
	at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
	at clojure.core$load_lib.invokeStatic(core.clj:5947)
	at clojure.core$load_lib.doInvoke(core.clj:5928)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$load_libs.invokeStatic(core.clj:5985)
	at clojure.core$load_libs.doInvoke(core.clj:5969)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$require.invokeStatic(core.clj:6007)
	at clojure.core$require.doInvoke(core.clj:6007)
	at clojure.lang.RestFn.invoke(RestFn.java:551)
	at beanbag.v2.orders.invoice_generation_test$eval18746$loading__6706__auto____18747.invoke(invoice_generation_test.clj:1)
	at beanbag.v2.orders.invoice_generation_test$eval18746.invokeStatic(invoice_generation_test.clj:1)
	at beanbag.v2.orders.invoice_generation_test$eval18746.invoke(invoice_generation_test.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7176)
	at clojure.lang.Compiler.eval(Compiler.java:7165)
	at clojure.lang.Compiler.load(Compiler.java:7635)
	at clojure.lang.RT.loadResourceScript(RT.java:381)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.load(RT.java:463)
	at clojure.lang.RT.load(RT.java:428)
	at clojure.core$load$fn__6824.invoke(core.clj:6126)
	at clojure.core$load.invokeStatic(core.clj:6125)
	at clojure.core$load.doInvoke(core.clj:6109)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5908)
	at clojure.core$load_one.invoke(core.clj:5903)
	at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
	at clojure.core$load_lib.invokeStatic(core.clj:5947)
	at clojure.core$load_lib.doInvoke(core.clj:5928)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$load_libs.invokeStatic(core.clj:5985)
	at clojure.core$load_libs.doInvoke(core.clj:5969)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$require.invokeStatic(core.clj:6007)
	at clojure.core$require.doInvoke(core.clj:6007)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$map$fn__5851.invoke(core.clj:2755)
	at clojure.lang.LazySeq.sval(LazySeq.java:42)
	at clojure.lang.LazySeq.seq(LazySeq.java:51)
	at clojure.lang.RT.seq(RT.java:531)
	at clojure.core$seq__5387.invokeStatic(core.clj:137)
	at clojure.core$dorun.invokeStatic(core.clj:3133)
	at clojure.core$dorun.invoke(core.clj:3133)
	at cognitect.test_runner$test.invokeStatic(test_runner.clj:71)
	at cognitect.test_runner$test.invoke(test_runner.clj:62)
	at cognitect.test_runner.api$do_test.invokeStatic(api.clj:14)
	at cognitect.test_runner.api$do_test.invoke(api.clj:6)
	at cognitect.test_runner.api$test.invokeStatic(api.clj:30)
	at cognitect.test_runner.api$test.invoke(api.clj:16)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.core$apply.invokeStatic(core.clj:665)
	at clojure.core$apply.invoke(core.clj:660)
	at clojure.run.exec$exec.invokeStatic(exec.clj:39)
	at clojure.run.exec$exec.doInvoke(exec.clj:34)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.run.exec$_main.invokeStatic(exec.clj:163)
	at clojure.run.exec$_main.doInvoke(exec.clj:153)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.core$apply.invokeStatic(core.clj:665)
	at clojure.main$main_opt.invokeStatic(main.clj:491)
	at clojure.main$main_opt.invoke(main.clj:487)
	at clojure.main$main.invokeStatic(main.clj:598)
	at clojure.main$main.doInvoke(main.clj:561)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.main.main(main.java:37)
Caused by: java.lang.Exception: No namespace: beanbag.schemas.pricesnagger.feeds.models
	at clojure.core$refer.invokeStatic(core.clj:4234)
	at clojure.core$refer.doInvoke(core.clj:4217)
	at clojure.lang.RestFn.applyTo(RestFn.java:139)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$load_lib.invokeStatic(core.clj:5966)
	at clojure.core$load_lib.doInvoke(core.clj:5928)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$load_libs.invokeStatic(core.clj:5985)
	at clojure.core$load_libs.doInvoke(core.clj:5969)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$require.invokeStatic(core.clj:6007)
	at clojure.core$require.doInvoke(core.clj:6007)
	at clojure.lang.RestFn.invoke(RestFn.java:805)
	at beanbag.schemas.pricesnagger.feeds.feeds$eval22202$loading__6706__auto____22203.invoke(feeds.clj:1)
	at beanbag.schemas.pricesnagger.feeds.feeds$eval22202.invokeStatic(feeds.clj:1)
	at beanbag.schemas.pricesnagger.feeds.feeds$eval22202.invoke(feeds.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7176)
	at clojure.lang.Compiler.eval(Compiler.java:7165)
	at clojure.lang.Compiler.load(Compiler.java:7635)
	... 111 more

oly16:08:43

:tests {:extra-paths ["test"]
                   :extra-deps {io.github.cognitect-labs/test-runner
                                {:git/url ""
                                 :sha "4e7e1c0dfd5291fa2134df052443dc29695d8cbe"}}
                   :main-opts ["-m" "cognitect.test-runner"]
                   :exec-fn cognitect.test-runner.api/test
                   }

oly16:08:31

:paths ["resources" "src" "libs"] the rest is basically just my deps

oly16:08:35

when i look in those files the linter does not pick up any syntax errors, and i can not spot any I have tried commenting out a load of stuff but still not traced down where the issue is to resolve it

oly16:08:24

would some kind of cyclic dependency cause this type of error ?

seancorfield16:08:40

Could be. The three namespaces of interest are beanbag.schemas.pricesnagger.feeds.feeds, beanbag.schemas.pricesnagger.feeds.models, beanbag.v2.orders.invoice-generation-test

seancorfield16:08:12

It looks like invoice-generation-test requires feeds and that requires models?

oly16:08:17

so invoice-generation-test does not require either of those namespaces though it likely includes other namespace that do use them

oly16:08:13

the stack trace feels very unhelpful in this case, not sure why its even flagging invoice-generation-test in the stacktrace, is it saying the error might be related to that

oly16:08:34

ah so that made me comment out the whole test file and the issue has gone

oly16:08:46

so i guess its related some how

oly16:08:33

I guess i can remove the comments one by one until it comes back

oly16:08:22

definitely related to required namespaces, two in particular so i will look in those see what i can discover

oly16:08:55

thanks for you assistance @U064X3EF3 helpful as always 🙂

seancorfield16:08:49

"not sure why its even flagging invoice-generation-test in the stacktrace" because that's the file Clojure was compiling when it ran into the error...

seancorfield16:08:09

Let us know what the solution ended up being!

oly16:08:49

sure it for tomorrow now anyway to finish fixing

oly07:08:48

seems it was a circular dependancy, there was a constant set in feeds.feed i have moved it under feeds.constants and now it works, I still 100% dont get why I get this in the tests but not in the running application as the requires are not that different

👍 3
3