Fork me on GitHub
#clojurescript
<
2018-03-28
>
john00:03:21

right and your garden/css compiler can just use configs from garden.edn and figwheel would run it when set to watch a css dir. Where as a cljs build tool could just use garden.edn and ignore figwheel.edn while doing an advanced compile. That way their configs aren't necessarily coupled together by a common project.clj.

zentrope00:03:51

Ok, but that starts to seem like the same thing. Instead of a map with keys, you have a directory with files, the “path” being the key and the “file” being the value.

zentrope00:03:03

(Not that I don’t kinda like it.)

john00:03:39

the later is composable at invocation time

john00:03:56

I don't know, we'll see. It's all pretty early

justinlee00:03:09

I just don’t get it. It seems to me that the new tool does 10% of what a build tool does and splits off a bunch of important stuff into a new configuration file. If you don’t have any complicated build rules, then this is awesome. But if you do, then you’re going to end up using a build tool anyway, like, say, lein, but now you’ve got an extra tool and an extra configuration file. In clojurescript you need something running all the time so that your repl works and so hot reloading is instant and any resource processing is watching changes. I get that it adds functionality like git integration etc., but I do not see how this really changes the way builds work.

zentrope00:03:36

I might have missed something, but I think it’s definitely there for simple projects and isn’t meant to be more than that.

zentrope00:03:41

I think it’s mainly for the use case of running something simple that also requires deps (but isn’t bundled into an uberjar).

zentrope00:03:38

Nice. A makefile. ;)

noonian00:03:42

I think with the shift towards reloaded workflows using e.g., component or integrant, people are increasingly running their build processes (and auto-build watchers) from a Clojure namespace. This is what I’ve been doing for a while now (started with figwheel-sidecar). So if you’re already doing that it plays nicely with deps.edn since you can just make dev aliases that call out to your own code to invoke builds. It does put the onus of integrating everything on the developer but I don’t think it will be too bad once some patterns emerge, build tools start supporting deps.edn, and people write new templates

athomasoriginal00:03:07

Its still simple and repeatable.

justinlee00:03:18

@zentrope I was really referencing dnolan’s comments about build tools being “busted” from earlier today

zentrope00:03:51

I’m not sure what he meant, exactly.

zentrope00:03:33

If he showed a project that doesn’t use lein/boot/maven, then I’d get it.

justinlee00:03:57

Yea me neither, which is why I asked for more reading material from john. But I still don’t get it. I’m just trying to formulate some guidance that isn’t so abstract. So far, if asked, I’d say that tools.deps is a reimplementation of dependency management and classpath construction (with added features for git and other mechanisms) that can be called from the command line.

zentrope00:03:25

That’s my understanding, too.

zentrope00:03:26

If all you have to do is produce a CLJS front-end (.js, .css, *.html), lein seems like overkill once you have some other way to pull in deps.

zentrope00:03:32

Maybe that’s what @dnolen meant?

lwhorton00:03:13

has anyone ever bumped into

ReactComponentTreeHook.purgeUnmountedComponents is not a function
when using reagent in a cljs project?

lwhorton00:03:42

i have no idea where this is coming from, and the only google foo results are talking about something like react native, which i’m not using.

john00:03:45

It's hard for tools to evolve when they have play nicely with everything else that might play nicely with a project.clj in the wild. A simple deps.edn is a lower common denominator for a lot of tools. It's hard to explain how things can work just as well without a project.clj, but if the community hates the decoupling of everything, we'll probably go back to lein or some similar monolithic config file

mfikes00:03:24

But, picking things apart to their atomic pieces is the Rich Hickey way 🙂

zentrope00:03:18

@john If you look at that ClojureBridge registration system link above, it uses a single deps.edn (with aliases) and a Makefile as a launcher. It’s not a lot different conceptually than Lein.

zentrope00:03:31

Probably faster.

john00:03:45

and I intend to use clojure tools for each of those tasks

zentrope00:03:05

And you could embed clj in a ./bin dir (and fix it so it doesn’t hard code its paths) to be self-contained.

noonian00:03:31

I’m using https://github.com/juxt/mach instead of Make and loving it

john00:03:01

make has the benefit of probably being on any given docker image you might use. But still, if i'm going to get turing complete, I want to do it in clojure 😉

mfikes00:03:25

One aspect David mentioned is the concept that you have minimally a -main to run things. I developed an appreciation for that model on a project recently where I eliminated all of the crufty Bash scripts and just wrote it all in Clojure, with a -main. With that it becomes trivial to drive such a project using clj

👍 4
mfikes00:03:33

On the fly, I can now point that stuff at the ClojureScript compiler sitting in a :local/root, for example.

noonian00:03:18

Interesting. I’ve been doing something similar but using multiple namespaces with simpler -mains and keeping common config in an edn file

mfikes00:03:54

Yeah, you can easily get at such config using io/resource 🙂

mfikes00:03:04

Or on disk if it is there

mfikes00:03:39

I guess the point is: If you decompose / decomplect, then you can re-compose in surprising ways sometimes.

💯 12
zentrope00:03:55

So I have a web-app (server + self-hosting web-app), and instead of the main file just starting the app, it would also run “test” tasks, and an “uberjar” task and so on?

zentrope00:03:14

The -main invokes figwheel?

justinlee00:03:25

Is this the idea: instead of drafting a project.clj and running lein you draft a clojure build program with a -main, presumably that uses a bunch of helpful composable libraries, and you know that will work because clj will ensure the libraries are there based on deps.edn?

noonian00:03:50

You can have multiple entrypoints, so -main in my-server.main runs the server and -main in my-server.build handles the build logic

mfikes00:03:50

Yeah, roughly.

justinlee00:03:50

yea what @zentrope said basically 🙂

justinlee00:03:27

now that is an interesting idea

noonian00:03:56

Don’t need lein at all if you are fine with running something like clojure -A:build test etc.

zentrope00:03:31

I would certainly trust myself to keep that sane…. ;)

mfikes00:03:14

Perhaps another example: I was interested in producing a tool to help with automating git bisect when a ClojureScript compiler breakage occurs. I'm truly happy that https://github.com/clojure/tools.gitlibs exists as a separate thing, perhaps making such a project doable.

mfikes00:03:55

I might get away with clj -Abisect or somesuch

john00:03:18

that's pretty awesome

mfikes00:03:29

But it happens if you don't have to fight with a monolith

john00:03:59

just in the last month or so, I've seen a ton of really cool examples of how to use clj. I'm sure there will be quite a bit of new stuff coming up over the next year.

mfikes00:03:25

Yeah, it is an enabler and we are only beginning to understand it 🙂

justinlee00:03:39

right the key here is that the libraries have to expose sane interfaces

justinlee00:03:16

the build order management of make was always more suited to the vagaries of the c compiler. you don’t really need that with clojure

john00:03:22

the ability to make simple repros has really made it a lot easier for me to contribute directly to clojurescript... I can just play with simple changes to git coordinates

zentrope00:03:44

Right. Make-as-a-launcher was the main value for me.

mfikes00:03:21

Right, and to fix something in ClojureScript for a non-trivial deps.edn based project, you just use :local/root, pointing it at your cloned ClojureScript tree containing some speculative fix.

zentrope00:03:47

Does that take relative paths, by chance?

john00:03:31

rich also teased something about being able to sanely do mono repos, but I haven't yet seen an example of how to do it.

justinlee00:03:17

how do people communicate with rich anyway. i’ve always found it intriguing. does he apparate or does he send an owl?

john00:03:49

7 virgins come out of a cave, from an under ground lake

mfikes00:03:50

@zentrope It appears so. This worked in a sibling project

clj -Sdeps '{:deps {org.clojure/clojurescript {:local/root "../clojurescript"}}}' -m cljs.main -re node

zentrope00:03:00

Ah, that’s nice.

athomasoriginal00:03:02

I would very much like to see how a monorepo is handled

john00:03:05

they pass messages for us 😉

richiardiandrea00:03:14

I actually do the above in a monorepo 😄

mfikes00:03:24

One does not simply talk to Rich

justinlee00:03:46

or perhaps you have to step into a go block and park your thread

richiardiandrea00:03:07

{:paths ["src"
         "../honeysql/src"
         "../honeysql-postgres/src"]
 :deps ...
 :aliases ...}
but I don't know how hacky that is 😄

mfikes00:03:32

Yeah, with the :paths stuff the ability to run stuff directly in Gists is a bizarre unexpected capability

noonian00:03:43

I think you could use the git support with a local file:// url (which git supports cloning from natively) for monorepos

noonian00:03:17

Ah nvm, guess being in the same repo messes that up

richiardiandrea00:03:36

I feel this will break in unexpected ways some day 😄

john00:03:38

do they scoop up parent deps.edn files?

john00:03:13

Well I have to check out your example

zentrope00:03:34

Wouldn’t each sub-project have its own deps file?

mfikes00:03:11

This is probably my favorite cljs.main-based gist example especially since it runs code on the classpath via @index.cljs https://gist.github.com/mfikes/e00202b2de7cc2352fedcf92b1fe60dc

zentrope00:03:16

I guess it depends on what “monorepo” actually means.

zentrope00:03:17

@mfikes Kinda reminds me of literate programming.

mfikes00:03:51

Another example I liked: I fixed something in the compiler for someone, pushed it to my own GitHub account, and had them use my coordinates to verify the fix.

zentrope01:03:16

Closest I’ve gotten to babel is create-react-app. So, too ignorant.

mfikes01:03:25

All on the fly, with no building or compiling, etc.

john01:03:42

yeah that's super powerful

mfikes01:03:56

It is the kind of unexpected stuff we are still discovering 🙂

john01:03:50

don't ever pull from a random gist if you haven't check it first. You could pull gists depending on gists, on other gists, etc 😉

mfikes01:03:45

Definitely, this is like discovering the fundamentals of nuclear physiccs

justinlee01:03:40

clj needs a “run this crap in a docker container” flag if we’re going to run random stuff from gists

john01:03:54

why, because quantum threads appear to be non-reentrant? 😉

john01:03:54

@lee.justin.m that would be cool

john01:03:07

a dockerizer

mfikes01:03:13

Or at least a clojail

😅 8
kucerm210:03:59

Hi, how i can call macro on collection?

kucerm210:03:15

I have for example (defroute "/about" [] (dispatch [::events/set-active-panel {:path [:about-panel]}]))

kucerm210:03:40

(def routes '( ["/" [:home]] ["/servisni-udalosti/probihajici" [:servisni-udalosti :probihajici]] ["/servisni-udalosti/vyhledavani" [:servisni-udalosti :prehled]]))

kucerm210:03:50

and a need to call like this 🙂

kucerm211:03:24

(defn apply-routes [routes] (for [[path panels] routes] (defroute path [] [(dispatch [::events/set-active-panel panels])])))

kucerm211:03:38

(apply-routes routes)

kucerm211:03:56

is it possible?

darwin11:03:11

not easily, you must understand that calling a macro means “rewrite this piece of code at hand during compile-time”

kucerm211:03:01

so the easiest way is to write a macro that expands it?

bbss11:03:27

Is there some alternate syntax for namespaced map literals in ClojureScript than Clojure?

#:SC2APIProtocol.sc2api$RequestObservation{:observation {}} 
;;valid clj
#:SC2APIProtocol.sc2api$RequestObservation{:observation {}}
;; clojure.lang.ExceptionInfo: Reader tag must be a symbol {:type :reader-exception, :line 1, :column 43, :file "NO_SOURCE_FILE"}

darwin11:03:41

@kucerm2 you can easily write another macro, which given collection of routes rewrites it into a bunch of (defroute …) forms, which then later get further expanded, because defroute is a macro

👍 4
kucerm211:03:32

Thanx, i'm going to start learn write macros 🙂

darwin11:03:49

klidne se mi pak ozvi v privatnim chatu, kdyztak kouknu a pomuzu

kucerm211:03:32

Tak ja to tady lamu anglicky a on je to cech 😄 diky

darwin11:03:08

you would have to write (defroutes '([...] [...] ...)), so that the macro gets full list of routes as a param

kucerm211:03:33

I'm going to try it

darwin11:03:16

(def routes '(...)) and later (defroutes routes) would not work, because your macro would see only routes symbol

bbss11:03:42

I was able to solve my problem by using the keyword function.

(defn map->nsmap
  [m n]
  (reduce-kv (fn [acc k v]
               (let [new-kw (if (and (keyword? k)
                                     (not (qualified-keyword? k)))
                              (keyword (str n) (name k))
                              k) ]
                 (assoc acc new-kw v)))
             {} m))
from 

cljs.user> (map->nsmap {:observation {}} 'SC2APIProtocol.sc2api$RequestObservation)
#:SC2APIProtocol.sc2api$RequestObservation{:observation {}}

bbss11:03:59

pasting in the result is not valid according to the reader though. Not sure if that's intended behaviour.

mfikes11:03:13

@bbss Can't repro. Which version of ClojureScript are you using?

bbss11:03:17

@mfikes thanks for looking into it. I thought "1.9.946" would be high enough (as spec was quite a bit before it).

mfikes11:03:03

Yes, that version definitely has that feature. Perhaps you have a really old reader dependency?

bbss11:03:08

I do have [org.clojure/tools.reader "1.1.0"]. Does that influence cljs?

bbss11:03:12

Let me check my :tree.

mfikes11:03:14

Yes, that's what's reading the map

bbss11:03:55

Okay, I'll check it out later. Thanks 🙂

pyr12:03:17

Thanks for the much approachable recent release

pyr12:03:41

A co-worker is asking if shadow-cljs is the right tool when looking at producing libraries consumable from JS

pyr12:03:05

(and ideally, libraries which do not bring goog's closure into the mix)

pyr12:03:29

we only ever built spas in clojurescript so far, so this hasn't been an area of attention for us

pyr12:03:00

but for a few things it would make sense if we had a way to produce JS libraries for arbitrary consumers

pesterhazy12:03:21

wouldn't lein cljsbuild work for this?

pesterhazy12:03:21

might be work looking at how mori, a library commonly used outside of the CLJS ecosystem, does it: https://github.com/swannodette/mori

pyr12:03:04

ah thanks!

pesterhazy12:03:25

@pyr, here's the resulting JS bundle from the npm distribution: https://unpkg.com/[email protected]/mori.js

pyr13:03:14

Thanks a lot @pesterhazy that will be quite helpful

mfikes17:03:00

PSA: :closure-defines / goog-define are trivial to use. If you've never seen them before:

$ clj -m cljs.main -co '{:closure-defines {foo.core/bar 11}}' -r
ClojureScript 1.10.238
cljs.user=> (ns foo.core)

foo.core=> (goog-define bar 10)
nil
foo.core=> bar
11
They are great for "configuring" your code, and compatible with the new Shared AOT Cache feature.

edward18:03:33

I’m getting the following error:

Uncaught Error: No *print-fn* fn set for evaluation environment
How do I debug this? It was working fine a minute ago. From experience the line that fixes the problem is (enable-console-print!). However I’ve already got this is a dev.cljs file and my project.clj file has the following entries:
{:app
…
:source-paths ["cljs/src" "cljs/env/dev/cljs"]
…
:compiler {:main "myproject.dev" … }
…
}
I’m quite sure I can nuke the project and start over but I want to figure out how to actually debug this. Do I throw some print statements into dev.clj to see if it’s not being found? Is there a way to tell lein how to spit out the classpaths?

dnolen19:03:46

you should have a stacktrace, the stracktrace will tell you where you attempted to print

dnolen19:03:57

probably you are printing before you have enabled printing

edward19:03:11

Uncaught Error: No *print-fn* fn set for evaluation environment
    at Object.cljs$core$string_print [as string_print] (core.cljs:9612)
    at Object.cljs$core$pr_with_opts [as pr_with_opts] (core.cljs:9776)
    at Function.cljs.core.println.cljs$core$IFn$_invoke$arity$variadic (core.cljs:9819)
    at cljs$core$println (core.cljs:9816)
    at Function.myproject.core.fetch_webm.cljs$core$IFn$_invoke$arity$variadic (core.cljs?rel=1522263132980:18)
    at myproject$core$fetch_webm (core.cljs?rel=1522263132980:13)
    at myproject$core$init_BANG_ (core.cljs?rel=1522263132980:96)
    at core.cljs?rel=1522263132980:98

dnolen19:03:30

so it’s telling you

dnolen19:03:58

your code is in that trace

edward19:03:47

Wow yes I removed the print statement and it worked. Sorry about that. In all previous contexts where I saw that error it was a build-related issue. Thank you

dnolen19:03:00

stacktraces don’t lie 🙂

edward19:03:31

Apparently not haha