How hard would it be to get namespaced keywords working with cherry? If it's not too hard, I might give it a try 🤔
We just need to keep track of the namespace name in the env argument and then pass that to edamame. Feel free to give it a try
Probably having a *cljs-ns* dynamic var or so which is set when the (ns <name> ...) is parsed will work and then this var is passed to the edamame opts like this:
https://github.com/borkdude/edamame#auto-resolve
I think I might have something working 🤔
partyparrot
I have :auto-resolve working for :current, but can't get it working for aliases
https://github.com/borkdude/cherry/pull/52/files - I tried adding a test with clojure.string but I'm guessing not all the core libs have been ported yet 👌
We should probably have a built-in cherry/cljs.string module
How would one go about doing that? Would it be available as clojure.string?
yeah, we should map the symbol clojure.string as an alias for ["cherry/cljs.string"] I think
or "cherry/clojure.string.js" rather (I don't think clojure.string is called cljs.string anywhere)
Ohh, that makes. Would shadow-cljs build "cherry/clojure.string.js" and have it link against cherry-cljs/cljs.core.js ?
yeah
I'm guessing I would start with a clojure.string.edn definition similar to cljs.core.edn?
yeah or just copy paste from the interwebs:
blank?
capitalize
ends-with?
escape
includes?
index-of
join
last-index-of
lower-case
replace
replace-first
reverse
split
split-lines
starts-with?
trim
trim-newline
triml
trimr
upper-case:-)
So I'll have shadow-extra-config slot in an extra module and then everything should work 👌
yes
I do wonder if going with cljs_string would be more consistent with cljs 🤔
I'm fine with that
I wonder if cherry could change something that's mentioned here: https://www.reddit.com/r/Clojure/comments/wmbbll/why_metabase_and_circle_are_not_using_cljs_mostly/ "We changed to JS because the CSS people could not make changes easily"
Another comment that stuck out to me in this thread: > My guess would be that it's because historically js interopt was harder. Shadow has really made it easier to just use the rest of the js ecosystem. That's been my feeling as well. For Clojure, Java interop has been solid and using Maven is relatively straightforward. For ClojureScript, JavaScript interop has been a huge pain. The pain of JS integration with CLJS sometimes outweighs the benefits of CLJS itself, which is unfortunate. Maybe this is less problematic today now that shadow-cljs has become more of a standard I started doing CLJS professionally in 2017 and since then it feels like interop has been a real bottleneck for growth within the companies I've worked for, especially since React came out with hooks. The work on cherry has been exciting to see since it gives us an opportunity to learn how to interop better with JS with a fresh perspective
Interesting thread here: https://clojureverse.org/t/the-further-adventures-of-starting-a-new-clojurescript-project-in-2022/9228/25 zcaudate says he has an experimental transpiler that transpiles to JS but without the immutable data structures. This is in fact how cherry started (as a fork of scripture). I still find the idea interesting, since JS devs are after all interested in small output (and it benefits performance a lot too). Maybe that should be a fork of cherry that's developed in parallel though.
or perhaps as a different output mode
being able to work with both would be interesting
or, like a macro: (js! (assoc {:a 1} :b 2)) would turn into JS mode ;)
like janet-lang has both mutable and immutable versions of its data structures
yeah, I thinking mixing mutable and immutable is easy enough (mutable would be just JS objects) but outputting minimal JS without any deps would be an interesting use case perhaps as well
Quick question about the generated js, why import {...} from 'lib' instead of import lib from 'lib' ?
My first guess is tree shaking but my understanding is they are both tree shakable
import lib from 'lib' means you are importing the default export from lib
Sorry, I meant import * as lib from 'lib'
yeah, I read somewhere that import * isn't as tree-shakable by some JS tools
but if you can verify this to not be true, we could probably change this
currently the output isn't tree-shakable anyway, it's an all or nothing thing right now due to how closure outputs things
I was experimenting with using cherry to compile clojure.string to see what happens and saw that its defn of replace was conflicting with clojure.core/replace
Was thinking an easy fix would be to use fully qualified names in the output
What if we do it like this? import { replace as str_replace } from ...?
The hard part is knowing you need to do that or not, then determining a symbol that wont conflict right?
We could use the alias as the prefix right?
hmm I see
you mean when you do :refer [ ] right? well, this should only be possible when you do :refer-clojure :exclude [replace]?
or I guess we can keep track of which symbol you referred and override the core one
and we could just use a gensym for each libname as the prefix
or a single letter
gensym seems safer
or the alias if one was given
I guess the quickest solution would get be to get :refer-clojure :exclude working 🤔
yeah, this would be another dynamic var I guess
I wonder if we should put those dyn vars in a mutable atom as part of the env instead
but this is an unrelated topic
Yeah, that would be nice 👍
Random though: would be nice have a reified ns environment like clj 🤔
@djblue I think we need this for the REPL anyway.. but it would also go against treeshaking right?
Here is the REPL issue: https://github.com/borkdude/cherry/issues/25 Especially the last comments contain the idea of a reified ns environment
At least, I think that's what you are getting at right?
I'll take a look 👍
Maybe we should support 2 output modes: one which can be tree-shaken and one with reified namespaces for REPL development.
Without reviewing the link, my thinking is that a cljs javascript module could export the reflection information, but that doesn't mean it needs to be consumed
So if you just load the entire file, it will be available. If the file is part of a build, the reflection info can be ignored
assuming it isn't being used for prod 😆
nice, yes! I think that was what Bruce was getting at too
Sounds like I need to review that link 👍
@djblue In #squint I just pushed a change which addresses this:
$ ./node_cli.js --show -e '(ns foo (:require [clava.string :as str])) (defn split [x] x) (prn (str/split "foo,bar" ","))'
import { prn } from 'clavascript/core.js'
import { split as str_split } from 'clavascript/string.js'
var split = function (x) {
return x;
};
prn(str_split("foo,bar", ","));
export { split }
["foo","bar"]