This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-24
Channels
- # aleph (4)
- # beginners (93)
- # cider (7)
- # cljs-dev (16)
- # cljsrn (5)
- # clojure (192)
- # clojure-dusseldorf (3)
- # clojure-italy (14)
- # clojure-russia (16)
- # clojure-serbia (1)
- # clojure-spec (85)
- # clojure-taiwan (1)
- # clojure-uk (79)
- # clojurescript (188)
- # code-reviews (9)
- # core-async (2)
- # crypto (1)
- # cursive (26)
- # datomic (21)
- # heroku (1)
- # hoplon (3)
- # jobs (7)
- # jobs-discuss (20)
- # jobs-rus (13)
- # off-topic (77)
- # om (15)
- # onyx (23)
- # pedestal (94)
- # planck (11)
- # proton (10)
- # protorepl (1)
- # re-frame (16)
- # ring (22)
- # ring-swagger (9)
- # rum (2)
- # specter (18)
- # testing (2)
- # untangled (14)
- # vim (12)
- # yada (58)
be careful with that if the web worker can potentially be compiled against different cljs version
my point is even more subtle, assuming you compile both web worker code and main frame code under :advanced, but different sets of sources, the names of javascript functions will be renamed to different names
Yeah, we'll see if sending sources is sufficient. I could be that most of the functions people would want to send over will often have dependencies on functions that don't have source, nor exist on the worker agent side...
why do you need to send the sources? why don’t you let them compile their own js file for the web worker
(how do I apply compiled-fn to param1 and param2 on the worker side, if compiled fn is js and param1 and 2 are cljs datastructures?
It's probably something simple, but I couldn't figure it out. js* is a single parameter function
just sending the + function will send the js of that function, rather than the name or the var
and your code would do the marshalling and call js/some.fn.name
in the worker’s context
I understand that you can eval arbitrary js snippets in worker’s context. But that does not solve other code that the snippet might depend on.
so your saying the munged names of core fns referenced in one js snippet may not match the names in another worker? or something different? What if both the main thread and the worker are leveraging the same munged code base?
you can write a macro which will expand (dispatch-on-worker + 1 2)
to something like (dispatch-on-worker 'cljs.core/+ 1 2)
on worker side you would interpret that 'cljs.core/+
and invoke proper core function with de-serialized params
this is not sending code, this is just sending an identifier what to call on other side
Well, + would resolve to 'cljs.core/+ on the other side. But if there are any vars not defed on the other side, the sent code obviously won't run. So if you want the other side to have that function, you should send it the "(def code..." fn and then it's available there. right?
also I assume you would want to have multiple agents (workers), so each would have its own self-hosted compiler with own compiler/REPL state
The book Clojure Programming, by Chas Emerick, Brian Carper and Christophe Grand, has a pretty good example of using agents to implement a web crawler. So if you want a web crawler in your browser 🙂
anecdotally, last time when I needed to move some more serious clojurescript work off to a worker was reading/parsing jobs in my experimental ClojureScript editor[1], I ended up sending diffs of the data structures serialised as JSON, it was fun to write it, but ended up not very practical [1] https://github.com/darwin/plastic
hah I'm a huge fan of structural editors. I def think clojure and some structural editor will be the perfect combo one day.
I’m still tempted to restart the project, but next day I realise I would kill few years of my life this way 😉
just recently I discovered this: http://skew-lang.org, the author did amazing job, I think skew could be great language for low-level engine and cljs for high-level business-logic part (e.g. this example https://github.com/evanw/sky)
So I have a lot of this agent stuff implemented =>(def a (agent 1)) #'re-pl.repl/a => a #object [Agent 1] => (add-watch a :logger (fn [key atom old-state new-state] (println "old:" old-state) (println "new:" new-state))) #object [Agent 1] => (send-off a inc) #object [Agent 1] old: 1 new: 2 => @a 2
this is hard to read, why don’t you use gist or that “+” button in slack client? it syntax-highligts clojure
Though that inc won't actually work without a version that has source. I could make send-off a macro and have it quote the fn parameter if it's not a MetaFn... which would assume the symbol is bound somewhere on the worker side. hmm
Now that spec is around, how are people doing testing for clojurescript apps? I like the idea of generative testing, but I don’t know how to begin for testing a UI.
Generative testing (whatever that means in practice) is very interesting, but I don't think it's a replacement for manually written tests.
I'm inclined to think that the best approach for relatively small projects is to look at them, when it comes to testing what they look like.
But that's a very good reason to do as much as you can to decouple what things look like from what determines what they look like.
^^ this is why libraries like React/Om are great. Pure functions of data -> dom. Test the data. If there is branching in your UI code, that’s where bugs will live. So minimize that as much as possible.
Honestly, it's the sort of thing you would have a had a hard time convincing me of a while back, but..
I've stopped thinking of manually written tests as some sort of proof of correctness. I've started thinking of them more as a tripwire to tell me when I've really broken things.
different types of tests can be used for different reasons
e.g. driving a design vs. a regression suite
and others
it’s a good practice to get good at, it comes in handy every once in a while
but I don’t TDD every line of code that I write
but when I’m struggling for a design, maybe
For instance I wrote a computational geometry library in C a couple of years ago, and...
I imagine combining spec with something like https://github.com/tmarble/webica will have interesting results for UI testing
though something like this would probably run the tests much faster: https://saucelabs.com/blog/headless-browser-testing-with-casperjs
Yeah- the thing I guess I am getting at is that with a decent repl, and editor support for it...
I'm doing lots of node and JS for work these days and... the lack of an integrated Repl is making me nuts. It's enough to drive me to TDD 😉.
I am inclined to think that TDD, if purely practiced, leads to a lot of hill-climbing.
In fact, if I had to levy one real criticism against the code-bases I've written and had to work with, that were not obviously bad...
@tagore We do have quite a lot of automated tests, and these days I am trying to do generative testing (without success). We use reagent, and we have basically 3 types of tests: unit tests for usual functions, and for controllers which basically transform the state atom (a lot of async tests here). We also test the reagent components, in 2 ways: "in tests" which is when we pass some data, and it gets rendered on the screen so then we check whether what was supposed to be rendered is rendered, and "out tests" where we render the component and perform some action trying to see it it invokes the right functions with the right params.
I think we could use generative testing with the components, basically generating what goes in, just to see if it still renders on screen, even though speed might be an issue here.
Can anyone share a good way to load a configuration file into a clojurescript project?
runtime or compile time, @danielstockton ? if the former, it’d have to be on the page (as a <script> tag) or via XHR, if the latter, via a macro?
Compile time, macro could work yeah.
@danielstockton I recommend sticking to goog-define
and :closure-defines
to configure CLJS. this way the closure compiler can make intelligent use of the configuration and maybe even remove some code it otherwise could not.
also there is currently no way to tell CLJS to recompile a file if your config file changed
I looked at :closure-defines but it looked like they already had to be @defined by closure. goog-define looks like a macro to define my own defines? Do you know of an example of this being used anywhere?
Nvm, found this: http://cljs.github.io/api/cljs.core/goog-define, thanks!
The problem with closure-defines is that I have my project.clj checked into git. This config should be outside of git so that my fellow developers can change some settings for their local environment.
You're right, thanks.
trying to get started with leiningen following: https://clojurescript.org/reference/dependencies#using-leiningen
however lein cljsbuild auto
just results in Compiling ClojureScript.
- it never completes
It is waiting for changes?
Change a file.
Hmmm, strange...
now I'm not familiar with clojure etc but these dependencies seem old?
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/clojurescript "0.0-3149"]
[cljs-ajax "0.3.10"]]
That's a good question. You can certainly have more recent versions than those.
dbackeus there’s a very nice plugin called lein ancient
that answers these sorts of questions automatically
if you let it, it can even upgrade all your deps automatically
Recent versions of lein-ancient probably won't even clobber your project.clj while automatically upgrading
and yes, those are all very old deps
bja if my project.clj wasn’t in git any consequences of that are my own fault anyway 😄
ok first run was similar to old versions where the last message would be "Retrieving xxx from clojars" and it would be stuck forever
I was just commenting that it actually works now. The first few times I tried it, it got confused and made me git checkout project.clj
again
I just created the core.cljs
in the root of the project but I guess that needs to live under src
?
I was only interested in Leiningen so I assumed I didn't have to go through the entire beginning of the tutorial
a bit surprised at the ajax lib adding 110KB to the bundle, I'm assuming it has some more dependencies, is there a command I can see to understand the current deps tree?
dbackeus a pedantic point - “core.cljs” is just a convention, and it was arrived at because there isn’t a generic way to know what to call a project’s primary namespace. The one who institutionalized the convention is on record as suggesting that people should use other names if possible.
@dbackeus lein deps :tree
is cljs-ajax
the idiomatic library for ajax communication or is there some newer thing around? (just thought it fair to ask since the tutorial seemed to use ancient versions of everything to begin with)
cljs-ajax is fine, but using js/AJAX directly is also cromulent
oh, sorry, it’s a joke
@dbackeus Many people will also use goog.net.XhrIo
directly and avoid pulling in a library. My remote
namespace is 2-3 functions that use XhrIo
.
and cljs-ajax is popular. as is https://github.com/r0man/cljs-http
https://github.com/ptaoussanis/sente and https://github.com/ptaoussanis/sente are my preferred options
both of those provide both server and client side implementations, making shoveling data back and forth super easy.
oops, sente and https://github.com/jarohen/chord, rather