Fork me on GitHub
#shadow-cljs
<
2017-10-25
>
Jon03:10:49

(ns respo.test.html
  (:require-macros [respo.macros :refer [html
                                         head
                                         title
                                         script
                                         style
                                         meta'
                                         div
                                         link
                                         body]])
  (:require [cljs.test :refer-macros [deftest is testing run-tests]]
            [respo.test.comp.todolist :refer [comp-todolist]]
            [respo.render.html :refer [make-string]]))

Jon03:10:02

just noticed in shadow-cljs :refer-macros works...

Jon03:10:30

I thought we have to use :require-macros always 😱

Jon03:10:53

it seems :refer-macros is actually more robust.

thheller07:10:32

you shouldn’t use this syntax at all

Jon14:10:44

did you mean I can use :refer directly?

thheller07:10:42

ALWAYS do this … it just makes things unnecessary complicated otherwise

mhuebert08:10:51

I’ve been looking at setting up an auto-generated changelog (from commit messages) for maria, to be performed on release. something like that might be nice for shadow-cljs too

thheller08:10:14

yeah … I’m not the greatest at maintaining that

thheller08:10:33

but not great at writing commit messages either 🙂

mhuebert11:10:52

yeah mine can be much improved too. but makes it feel more worthwhile when the format can produce a changelog without any extra work

mhuebert11:10:47

did you end up learning anything about thi.ng.math.macros namespace? i wonder if his libs may actually not be that useful unless they are modified to be supported by the self-host compiler directly. (but unsure if that is related to why that namespace can’t be found, seems like a different thing)

mhuebert11:10:12

the only problem i can see with thi.ng.geom.core.macros.vector is the :refer :all, that would be an easy PR if not for the org format

thheller11:10:14

afaict thatst he only issue

mhuebert11:10:40

is the math.macros error related to that? it seems like a resolution error

mhuebert11:10:21

maybe the :exclude option is actively excluding the transitive macro deps of the entry instead of just ignoring them? subtle difference..

mhuebert11:10:03

making a little test case to figure that one out.

mhuebert11:10:19

seems it may have nothing to do with :exclude

thheller11:10:10

what was the problem again?

mhuebert11:10:24

macros namespace a tries to require macros namespace b, should this work?

mhuebert11:10:11

[:bootstrap] Build failure:
The required namespace "shadow-eval.b" is not available, it was required by "shadow_eval/a$macros.cljc".

thheller11:10:23

it must be a .cljc file currently

thheller11:10:32

but that entire process is busted

thheller11:10:55

yeah transitive deps in macros are a problem

mhuebert11:10:37

renaming the dep to .cljc does work

thheller11:10:04

really? it does compile it as shadow-eval.b$macros?

thheller11:10:36

I assume it will be shadow-eval.b after which is incorrect I think

thheller11:10:44

I really couldn’t figure this out from reading the analyzer

mhuebert11:10:30

now i have a.clj and b.cljc and it builds

thheller11:10:55

I think that might be incorrect behaviour though, it should find the b.clj when compiling as a macro

thheller12:10:25

but really I couldn’t find any documentation on how this is supposed to be resolved

mhuebert12:10:33

it would make intuitive sense if the same resolution algo that was used to find a was used to find b

mhuebert12:10:40

since they are both macros lookups

thheller12:10:57

move a.clj to a.cljc 😉

mhuebert12:10:12

in my own code, sure 😉

thheller12:10:38

need to check how lumo or planck would handle such a case

thheller12:10:49

or cljs.core for that matter

mhuebert12:10:57

For bootstrapped ClojureScript you could have any of these arrangements:

Runtime Code   Macro Code
foo.cljs              foo.clj
foo.cljs              foo.cljc
foo.cljc              foo.clj

thheller12:10:07

thats not about transitive deps?

mhuebert12:10:40

i would guess it searches with [clj, cljc] preference order but not sure

thheller12:10:56

I do that for macros yes

thheller12:10:15

but not for things the macros themselves require

thheller12:10:32

the problem is if you say (:require [thing.b]) in a macro

thheller12:10:00

you might actually mean thing.b as in a normal namespaces that just contains functions and not macros

thheller12:10:15

so if you have a thing/b.cljs that would work

thheller12:10:42

but if you have include it as a macro it ends up as thing.b$macros

mhuebert12:10:43

i guess that would break compatibility with JVM clojurescript

mhuebert12:10:59

where things are divided by “compilation stage”

thheller12:10:00

I don’t know .. AFAICT this behaviour is undefined

mhuebert12:10:02

for the same reason we can’t intermix defmacro into cljs files without breaking compatibility, we also couldn’t use any other .cljs files in macro compilation stage

thheller12:10:08

if you can confirm that (:require [thing.b]) in a macro should cause thing/b.clj to be compiled as thing.b$macro I can add that

thheller12:10:27

but I’m not convinced that that would be correct behaviour?

thheller12:10:54

I never used any self hosted stuff

thheller12:10:02

can you maybe confirm in lumo or so?

thheller12:10:24

the shadow-bootstrap-example with b.clj

mhuebert12:10:44

you are right

mhuebert12:10:55

🙂. a.cljs :require-macros b.cljc requires c.clj, fail

mhuebert12:10:53

a.cljs requires b.clj requires c.clj, fail

thheller12:10:42

what did you try?

mhuebert12:10:06

from that dir, planck -i test/a.cljs

mhuebert12:10:16

and then mixing and matching b and c file extensions

thheller12:10:05

yeah the problem is that we can’t tell what is what

mhuebert12:10:30

IMO the moment it was decided to read macros written in ClojureScript (not Clojure) from .clj files, programming became a kind of spiritually elevated art form

mhuebert12:10:47

full of mystery and awe.

thheller12:10:07

hehe it totally makes sense though 🙂

mhuebert12:10:35

for compatibility reasons

mhuebert12:10:44

or other reasons?

thheller12:10:25

if I try to explain it I’ll butcher every correct lisp term for this

thheller12:10:52

by splitting it the compiled code does not itself depend on the compiler or the macros

thheller12:10:10

so the compiled code is drastically smaller by sacrificing runtime eval

mhuebert12:10:11

I think I get that part. but now in addition to using java-based clojure to write clojurescript macros, we also use JS-based clojure to write clojurescript macros with the same file extension… it would make more sense to me if tools like Planck did not support loading macros from .clj files at all, because planck does not support JVM clojure

mhuebert12:10:36

with planck you can write macros in .clj files that read from js/window or whatever

mhuebert12:10:50

well, planck doesn’t have js/window.

mhuebert12:10:55

but you can use js stuff.

thheller12:10:47

I can’t really say anything about self-hosted. I never use it and don’t know the particular details.

thheller12:10:50

but I do think its important to keep compatibility to the JVM compiler

thheller12:10:08

having self-host-only CLJS libs doesn’t help the community overall

thheller12:10:32

well … JVM only CLJS libs isn’t exactly great either

thheller12:10:54

but those could maybe be fixed to also work in self-host

thheller12:10:18

I really don’t know about the state of self-host and how “rushed” it was

thheller12:10:29

maybe it would actually be simple if just a few things were changed

mhuebert12:10:26

i think compilation passes got intertwined with language choice, and now we have a system where “.clj” and “.cljc” file extensions can no longer be taken at face value

mhuebert12:10:35

well, .cljc can

mhuebert12:10:51

i really don’t know how both concerns can be adequately handled

thheller12:10:31

the problem is that you need to split at every point

thheller12:10:18

you can just create .clj with a .cljc file that :require-macros itself

thheller12:10:42

that way there is no ambiguity whether you wanted to include a macro or just code

mhuebert12:10:56

from that thread > Why can’t bootstrapped load this file with “macros: false” and ignore all defmacro to load only functions and then load it with “macros: true” and take only defmacro into account?

thheller12:10:02

but that is annoying for the CLJ side

thheller12:10:35

good question

thheller12:10:44

I do not know

mhuebert12:10:44

would that make sense? we would still have the problem that functions could not use macros defined in the same namespace. but that seems like a reasonable limitation

thheller12:10:21

well technically you need the macros before the code

mhuebert12:10:21

oh, the rabbit hole 🙂. so for this library it looks like he needs to rename that file to .cljc, no real way around it

thheller12:10:59

(defmacro deffoo [& args])

(deffoo thing
  1 2 3)

thheller12:10:02

you cannot compile this

thheller12:10:44

actually that would work in clojure

thheller12:10:03

(defmacro deffoo [& args])

(deffoo thing
  (js/document.getElementById "foo"))

thheller12:10:13

you can’t compile this 🙂

thheller12:10:28

AFAICT the is just not self-host compatible

mhuebert12:10:40

exactly. but probably not a lot of changes required for it to be.

mhuebert12:10:00

i didn’t realize how this macro resolution worked

mhuebert12:10:08

*macro dependency resolution

thheller12:10:39

problem is I really cannot tell how easy the fix would be because of the org-mode

thheller12:10:48

I do not understand that at all 🙂

thheller12:10:19

also if the macros only exist because of some perf opts

mhuebert12:10:45

but from looking at the clj* source files (easy to follow with cursive) it doesn’t look complicated

thheller12:10:09

some of the perf opts might be solved a different way

mhuebert14:10:38

do you have a preference for whether i mention issues here vs. creating github issues?

Jon14:10:00

looks wonderful... is it valid syntax in shadow-cljs, or in ClojureScript itself?

thheller14:10:35

you can use :refer directly yes, valid in all CLJS

Jon15:10:26

when I was reading guide on clojurescript Wiki, I thought I should use :require-macros, didn't even noticed there was a :refer-macros.

thheller15:10:22

you should not use either ever

thheller15:10:48

the only place you should be using :require-macros is in a file of the same name basically requireing itself

thheller15:10:08

(ns app.lib
  (:require-macros [app.lib]))

thheller15:10:05

everything that uses app.lib then only uses :refer

Jon15:10:38

going to migrate many of my projects...