This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-06
Channels
- # aleph (2)
- # arachne (4)
- # aws (3)
- # beginners (196)
- # cider (131)
- # cljs-dev (208)
- # clojure (193)
- # clojure-boston (1)
- # clojure-dev (26)
- # clojure-greece (4)
- # clojure-italy (26)
- # clojure-losangeles (1)
- # clojure-russia (11)
- # clojure-spec (40)
- # clojure-uk (78)
- # clojurescript (168)
- # cursive (25)
- # datascript (1)
- # datomic (31)
- # docker (8)
- # docs (1)
- # emacs (20)
- # fulcro (62)
- # hoplon (3)
- # jobs (1)
- # leiningen (3)
- # luminus (1)
- # nrepl (25)
- # off-topic (10)
- # other-languages (3)
- # parinfer (11)
- # planck (37)
- # portkey (54)
- # protorepl (11)
- # re-frame (2)
- # reagent (19)
- # remote-jobs (1)
- # ring (2)
- # rum (8)
- # shadow-cljs (23)
- # spacemacs (4)
- # uncomplicate (6)
- # unrepl (77)
- # vim (56)
- # yada (2)
looking at another library’s source code: what would be the motivation for defining a function in one namespace and then using set!
to put it another namespace like this (set! comp/as-element as-element)
?
you can't declare something in a different namespace
a third namespace, either used by both cyclic ns or using both, will usually resolve these things
or a first class function argument, or protocol or multimethod - the fact that there's so many answers is proof none of them are great
i’m sure i’m being silly here, but if you can use declare
to essentially tell the compiler to chill for a second on undefined functions, why doesn’t a refer
to another namespace do the same thing?
what does refer have to do with this? declare only creates vars in the current ns
i just don’t have a good enough grasp on the way clojurescript namespaces work to ask a smart question here. 🙂
oh, and require is depth-first - the rest of your ns is not loaded until all transitive requires namespaces successfully load
Poking around latest cljs.main goodness - is there a way to recompile compiled namespaces from the repl so that a ns :reload will get file edits?
require with :reload should recompile the source file and load the result in the repl
reviewing the pre-release quick start docs - if I “(require ’[hello-world.core :as hello] :reload)” (keep in mind this has some react code and was “pre-compiled” with cljs.main -c option. (i.e. clj --main cljs.main -c hello-world.core --repl)
oh, I misunderstood (since require always compiles, I lost the "precompile" destinction)
quickstart guide is looking amazing but i think some sort of lo-fi recompile instruction would cap it off
@boris Perhaps you are seeing https://dev.clojure.org/jira/browse/CLJS-2614
If you are on macOS or Linux, you can revise deps.edn
to instead specify a git dep on the latest ClojureScript master :sha
to see if it goes away.
@boris834 I think the fix for https://dev.clojure.org/jira/browse/CLJS-2611 also fixed https://dev.clojure.org/jira/browse/CLJS-2614
Revising deps.edn
to
{:deps {org.clojure/clojurescript {:git/url "" :sha "54b0486dbecc2ec9e6018b308f805d612bb302bb"}}}
instead of the one in the draft Quick Start would result in using the latest from master.@ben.borders yes, there's no restriction on that
use or require, either one, with the :reload argument
In summary @ben.borders
(in-ns 'blah)
(require 'blah :reload)
thanks @mfikes and @noisesmith
(You don't have to be in a namespace to reload it. But it often makes testing the vars in it easier.)
@boris834 Cool. To really perform a valid test, you would have to clone the ClojureScript repo, and script/build
and use the resulting version number as your :mvn/version
. (This is because using ClojureScript as a git dep disables the shared AOT cache logic that I believe was behind CLJS-2614,)
yeah i’m seeing possible cache issues (having to :reload ns twice to get expected behaviour)
and yet working fine now after a repl restart … i seem to dirty up /out easily at the moment and need to blast it
As an aside, for those interested, there is a tremendous amount of caching goodness that occurs when you use ClojureScript as a built maven dep (both at the Clojure level (AOT), and the ClojureScript level (shared AOT cache)), and you lose that when using ClojureScript as a git dep, but it a great fallback if you need a bug fix that is in master.
@boris834 Cool. If you happen to see any issues, by all means log one in JIRA. (ClojureScript 1.10.x is at a point now where the code is complete, and documentation is being polished, and bugs are being found and fixed.)
i’ll try to recreate issue and do the “valid test” you mentioned. Working as expected atm though.
Is there a reason why using records would make the generated code slower (with :optimizations :advanced)? I have some code where I keep data with points in sorted maps and changing all the containers to records made the code about 50% slower. This certainly wasn't my expectation.
@awerner32 sounds unlikely but it’s hard to say, you were using maps before?
yes, using maps it's a good 40-50% faster than switching it to all defrecord and using field accesses
more specifically, I was using maps with keywords :x
and :y
as points and changed that out for a Point record with direct field access.
Is there a way to prevent ClojureScript from inlining strings defined via (def)
(no :const
)? This is becoming a serious problem for me. I've just integrated Font Awesome 5 icons (SVG), and written a macro that references a global def
for a particular SVG path. This should in theory pull in only the paths I actually use. Well it does work, but including an icon multiple times includes the full SVG data multiple times, which doesn't make any sense.
I've heard it argued that duplicating strings doesn't matter, because compression "will take care of it" — I think this reasoning is fairly thin.
@jrychter There is a new @noinline
annotation coming in GCC (I dont think CLJS ships with it yet). But I'm not sure if works for normal JS vars, might only be for functions
Right now you could try a few tricks. Like exporting the var or calling a function on it (def the-big-str (identity "..."))
(to be tested)
Hmm... exporting could work (I'm auto-generating all the vars anyway). But it would bring back some of what I was trying to avoid (all full icon names listed).
That sounds very promising, any hints on how I can pass that annotation from ClojureScript?
This works for me with a recent CLJS:
(def fooooooooo "@noinline" "bar")
(defn ^:export foooooofn []
fooooooooo)
@rauh: Nice! This seems to work with ClojureScript 1.10.126, which I'm trying out right now. No inlining for SVG paths, and I've just saved 45kB in code size!
So, GCC in 1.10.126 does understand it, the one in 1.9.946 does not. Hopefully I'll be able to use 1.10.126 — I've been trying it out today and so far haven't seen any problems yet.
Has anyone tried the new figwheel with rebel repl feature?
Hey all. Stupid question. How would I write this in cljs:
people.map(function(person){
console.log("The person is", person);
});
also valid:
(doseq [person people]
(js/console.log "The person is" person))
(def gun (js/Gun.))
(def people (.. gun (get "people")))
(-> gun (.map (fn [person]
(prn (str "The person is " person)))))
does not give me what I expevted(map #( js/console.log (str "This person is " %)) ["Thomas" "Daniel"])
the above will only work with mapv
or wrapped in doall
// don't use map
for side effects
The above would be the exact translation of what you were going for. However, because you have a side effect...see @joelsanchez comment
hahaha you beat me to the punch 😉
sorry!
Just to be clear @petr the side effect is the console.log
statement
So I still feel like a fool. I'm trying to follow this: https://gun.eco/docs/Graph-Databases-101 This is what I have done so far:
(def gun (js/Gun.))
(def people (.. gun (get "people")))
(def alice (-> gun (.get "person/alice") (.put {:name "alice" :age "22"})))
(-> people (.set alice))
v------- app!{:conn 2} -------
#object[Gun [object Object]]
(doseq [person people]
(js/console.log "The person is" person))
=> #object[Error Error: [object Object] is not ISeqable]
cljs$core$seq (jar:file:/Users/peter/.m2/repository/org/clojure/clojurescript/1.9.946/clojurescript-1.9.946.jar!/cljs/core.cljs:1212:20)
^^ Suggests that I do need to use their map method?
gunmoo.core> (-> gun (.map (fn [person]
(prn (str "The person is " person)))))
v------- app!{:conn 2} -------
#object[Gun [object Object]]
I would js/console.log
people
directly to see what kind of value it is
you may need to convert people
to a seq
first
if people
is nil there is no hope imo
On line three, you need to pass in a javascript object, so {:name "alice" :age "22"}
becomes #js {:name "alice" :age "22"}
Ok, so pretty sure now it is closure-compiler-unshaded "v20180204"
miscompiling React 16 react-dom/index.js
(`:optimization :none`) from node_modules. Any suggestion how to put together a bare bones repro for the Closure people?
Thanks so much for the chat and for all the help, @mfikes!!! Keep up all the amazing work!
@deas there was at least one regression in v20180204. not sure if there are others. https://github.com/google/closure-compiler/issues/2822 if you see Cannot call a class as a function
that might be it.
there were a lot of changes to their rewriting code though so it may be other things
@thheller Perfect! Thanks a lot. Looks exactly like the kind of repro I am after. Will narrow down things tomorrow and let you know.
Is there proper documentation for the clojurescript compiler somewhere? I can't make heads or tails of a lot of its behavior.
Why would cljs.repl/repl
auto-rebuild when I haven't specified :watch "src"
?
What is the connection between the initial build to an output directory and then a repl to the same directory? Does it keep the settings? Doesn't repl accept all the same arguments are build?
Does my (require 'namespace :reload) do the building then?
additionally because ClojureScript was/is browser-first oriented this means we write to disk
But it shouldn't have the updated code from source changes?
Ok, I think I'm following. So it is the :reload
that's causing the rebuild.
How is that different than from :watch
on a repl?
Would :watch
only make sense for e.g. a browser that can be refreshed? (I'm using a node repl)
you can still push new code via websocket when files change
@noisesmith Ok, but that would require additional code/an additional library to do that. It's not a component of the compiler itself?
right - that's something figwheel does for example
Alright, I'll need to look into figwheel more. It works with node?
I don't actually know that for sure, I know it's possible in theory, I bet someone else here or in #figwheel knows though
Thanks
I guess I'm not seeing the use of the :watch
option for repl.
@borkdude: cljs truthiness isn't like js truthiness - see also (if 0 ...)
Since code isn't actually hot-reloaded. It's just written to disk, and the repl would have to be restarted to actually get the changes.
and I always found (number? NaN) funny, but it's technically apropriate
@borkdude: yeah, that seems like the right plan
@ghopper if you write your code to be reloadable, you don't need a restart, just a trigger telling you to load new definitions
what figwheel does iirc is send new code over the websocket for cljs to load, but you could also get a signal telling you to reload the files in npm
@ghopper :watch
just autobuilds so when you refresh the browser you see the right thing
@noisesmith So with :watch
I don't actually need the :reload
to (require)
to get new code?
you still need that
require just says "load this if it doesn't exist yet"
@dnolen That makes sense. So :watch
really only makes sense for browsers and not node? (Unless I'm perhaps using nodemon?)
Alright, I think I'm following now.
Another question; if repl is just a superset of build, should I be able to skip the initial build and just run repl with all the build configuration? How would the first argument to build (the src paths) be set for repl?
Or does repl keep all the same settings (when watching and building) from the initial build?
@dnolen Do you mind taking a look at this and letting me know how badly I'm bastardizing this poor compiler?
(deftask launch-server []
(comp
(with-pass-thru _
(let [dir (.getAbsolutePath (tmp-dir!))]
(cljs/build "dev"
{:main 'server.core
:target :nodejs
:output-dir dir
:output-to (str dir "/main.js")})
(future
(let [env (cljs-node-repl/repl-env)]
(cljs-repl/repl env
:read (fn [_ _] @(promise))
:prompt #()
:quit-prompt #()
:output-dir dir
:repl-requires '[[server.core]]
:inits [{:type :eval-forms
:forms ['(server.core/main)]}])))))
(wait)))
Anyone know if it's possible to load source from e.g. clojars at runtime so I can use it in cljs.js/eval? I'm basically trying to load libraries in the browser to do dynamic code eval
.jar files are essentially zip files (you can extract with tar -xf
and unzip
)
I’m sure there must be a way to extract zip files in javascript.
So I think would be possible to load from clojars inside the browser if you wanted to
@ghopper well I’m assuming you have a good reason to try to and do all the plumbing yourself but I woudn’t bother myself 🙂
it is basically a compilation server in boot it seems, very nice 😄
@dnolen The only real reason is that I wanted this to be a boot task, so I didn't want it actually taking over the repl. Basically I'm trying to use repl without it actually being a repl now that I think about it...
Anyways, now to get figwheel to hot-reload my code.
@ghopper just curious ( because I maintain it 😄) . Isn't boot-figreload
working for you for that particular task?
@richiardiandrea I'll have to look into that. 🙂 This was mostly just me trying to learn the cljs compiler. I was starting to feel like it might be cleaner to do away with the wrappers around it I was using. (boot-cljs, etc.)
always good to learn, don't get me wrong 😄
@ghopper if you want to learn more and possibly contribute #cljs-dev is a good place to lurk
@dnolen Thanks for the tip
@richiardiandrea Do you know of anyone successfully using boot-figreload for a nodejs target?
I remember someone mentioned it to me yes, as you were saying, it is a wrapper so the main work is done by boot-cljs
Well, I think the problem is it expects the process to start and connect to the weasel server. (When it's loaded in a browser) However, with node it makes sense to just start the process.
keep in mind that figwheel
is the one receiving the payloads so boot-figreload
is basically just the postman 😄
doesn't figwheel handle node the same as browser?
Apparently not. I think it might if I manually run node on the resulting package.
yeah, look you are right: https://github.com/bhauman/lein-figwheel/wiki/Node.js-development-with-figwheel
unfortunately the node side of cljs is not as advanced as the browser (I guess less people working with it). I have switched to this workflow: lumo
for the REPL and CLJS jvm for compilation and creation of the final artifact (in my case lambda functions)
@richiardiandrea Alright, I had to npm install ws
for it to work, but this works with live reloading:
(deftask dev []
(comp
(watch)
(reload)
(cljs-repl)
(cljs)
(target)))
All I have to do is go to /target
and node main.js
. It then connects and starts reloading.Maybe the only tricky bit is to move to target
and run node main.js
from there
I haven't ported to 0.5.15
yet...sorry about that ...