This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-29
Channels
- # architecture (2)
- # bangalore-clj (2)
- # beginners (177)
- # boot (1)
- # cider (36)
- # clara (15)
- # cljs-dev (30)
- # cljs-experience (6)
- # cljsrn (7)
- # clojure (94)
- # clojure-argentina (2)
- # clojure-brasil (1)
- # clojure-dusseldorf (6)
- # clojure-greece (1)
- # clojure-italy (18)
- # clojure-norway (4)
- # clojure-quebec (1)
- # clojure-russia (28)
- # clojure-sg (3)
- # clojure-spec (12)
- # clojure-turkiye (1)
- # clojure-uk (12)
- # clojurescript (169)
- # code-reviews (4)
- # community-development (2)
- # core-async (6)
- # core-matrix (6)
- # cursive (35)
- # datomic (18)
- # devcards (4)
- # euroclojure (1)
- # hoplon (2)
- # keechma (4)
- # klipse (2)
- # leiningen (1)
- # luminus (16)
- # mount (1)
- # off-topic (34)
- # om (31)
- # pedestal (6)
- # re-frame (14)
- # reagent (33)
- # specter (4)
- # uncomplicate (8)
- # unrepl (15)
- # untangled (24)
- # yada (25)
ok, seems to be a hygiene issue. i did in fact need to append a gensym to the var in let
(probably would have been obvious if i used macros more than, well, hardly ever)
@mfikes the only problem remaining is a warning that cljs.core/eval
is undefined. that's using it like this: (quasiquote (let [img# (eval ~image)] ...))
image
is a function defined in your cljs namespace right? and you want to bind your gensym to the result of calling it (at run-time)? if so, i think you can delete the eval
and it will all work
what I had good luck with was using the fragment as my frontend dispatch, since without needing to use any trickery, changing the fragment never sends a new request to the server
and then encoding any data that would need to be repropagated into the fragment string so that bookmarks would be meaningful (and back / forward button for that matter)
then my router looks at the fragment string to find data to propagate, one piece of that being the handler to call to set up the next top level view
I use the callback in goog.history to call my dispatcher
Where I’ve gotten is: I can href to fragments together, and my handler will update the page and the route — everything looks fine
I didn't want an http style router - I just wanted each view to be a single named entity, no tree structure
But if I, say, open a new browser tab and link directly to something in the app, the whole thing borks
….which, come to think of it, makes me think the underlying webserver is probably swallowing the whole request
OK - there are two parts there - making sure that everything needed to recreate the view from scratch is in the fragment, and ensuring the view itself knows how to bootstrap when hit directly
the webserver should have nothing to do with this
anything that would be recreated based on the fragment should be an explicit ajax or websocket request
that is, if it relies on server data (of course)
what we have to look out for in our app is transitions that take for granted that a previous view was present. One way to avoid this is to explicitly erase all page specific data when the fragment navigation occurs, and make sure that every fragment change reconstructs view data (it doesn't have to be super slow if you have a separate non-view-specific data cache)
this can be hooked into eg. om-next very easily, but you can also do it with a reagent render atom or whatever other store you like - the fundamental concept is knowing a) where a piece of data would be in the store if you had it and b) knowing how to get it from server if it is not there
and the store is the canonical source of data, the view is constructed by pulling in parts of the store to various places in the dom
also - I found it useful to make the store an explicit arg to the view render
that way I could set up tests "if this data is in the store, this regex should match the html"
if you have a more concrete problem I'm sure many of us would be happy to help, but that's an overview of making bookmarks / forward button / back button work consistently in my app looked like
or even refresh for that matter
anyone any recommendations for (heuristic) optimization libraries in cljs? The use case is: I have a number of entities with many attributes and have to group them in pairs and, if it's not possible with pairs only, triples. A valid pair or triple depends on the attributes of both (and a pair or triple can be given a score - the exact function is an exercise for me). There can be multiple possibilities, so it would be nice to have like the top 5 solutions (or all solutions, ranked by 'total score'). I was thinking mainly to use methods like evolutionary algorithms and simulated annealing, but there may be others. I'm looking for a cljs lib that's doing this and people have good experiences with.
Oh yeah, the number of entities is less than 50, usually between 15 and 30, so this means around 10-15 pairs/triples.
The number of attributes/entity is about 20-30.
Anyone here writing their backend stuff in ClojureScript (on Node)? If so, do any of you have any experience to share ? I've only just started evaluating this path and I haven't (yet) fully decided to commit to it, so I am interested in hearing your experiences - especially in regards to REPL & macrowork, Cursive and the like
@pseud You should probably talk to @yogthos ad take a look at Macchiato https://macchiato-framework.github.io/
@roman01la - ah, sure 🙂 Wonder how I'll get a hold of him, though, but yes, he ought to have some thoughts. WRT to Macchiato itself though, that part I am not sure I follow. I've been experimenting with Express.js itself and aside form needing a small wrapper to make things more clojure-esque (to me, anyway), it's actually been really neat.
@pseud I think it’s fine to use Express, it’s just that Macchiato follows Ring philosophy which is more like idiomatic way of building web servers
Yea, I guess that depends on what you're after. My idea is to use ClojureScript exactly because the underlying environment (Node) is so attractive. To that end, I'm more concerned about making my bits fit with what an average piece of node middleware might expect than conform to the Ring/Clojure world. That said, it's a commendable undertaking
@pseud note that you can use Node middleware with Macchiato as well, here's an example https://github.com/facundoolano/cljsbin/blob/master/src/cljsbin/core.cljs#L23-L30
I actually started with the idea of wrapping express.js originally, but found that it really didn't add much
@yogthos So now that I've gotten your attention ... 😉 How's your experience been with using ClojureScript for the backend? I.e. have you noticed any issues using the ClojureScript node REPL (e.g. reloading macro definitions) or with tool integration or what have you.
it's generally been good, I'm using figwheel to do the compilation and it behaves pretty much same targeting node as the browser
Figwheel? Really now. Hmm, I might have to try that myself. Right now I'm using boot (& boot-cljs), which is nice. However, I'm reloading the app using nodemon which is a low-tech node-tool for basically restarting the process. It works, but it's not exactly glamerous
but thankfully node doesn't have a long startup time, so it hasn't been too much of an issue
I have figwheel configured to start cljs repl when it loads, so I just connect the editor to that
But aren't you then getting back into the clojurescript "issues" typically seen on the front-end ? That is, defining externs and such - or am I conflating using Figwheel with advanced optimisations in cljs
Yea, exactly. So long as you don't enable advanced optimizations. I guess I was conflating issues then 🙂
I setup macchiato to use simple optimizations for the release build, and that just packages everything into a single js file
Definitely (!). Maybe I just haven't found it, but you really should write an article on the nitty-gritty aspects of getting started with ClojureScript on the backend, that is, your thoughts on using figwheel with lein to get going. There's a dearth of good explanations and at least for me, that was a big stumbling block, so I'm guessing it'll make interesting reading. I'd do it myself, but my "hacked in anger" tooling "solution" is a little ugly 😛
I expected this to work in ClojureScript: (cljs.reader/read-string (pr-str {:foo/id "foo" :foo/bar "bar"}))
Why not?
@yogthos I’m in the very early stages of a new project, and I’m seriously considering AWS Lambda as a deployment platform. I’ve got the basics going on top of cljs-lambda (which is very nice), but I don’t really like the development experience - having to deploy to Lambda to test. I imagine that it should be possible to use Macchiato to run locally, but then deploy to Lambda? Is this something you have any experience with?
@borkdude I've seen others talk of this issue - unless or until read-string handles the prefixed map reader, it might be easier to use something like transit?
@noisesmith I could do that, but our state also has functions. I thought I could get away with this for now while I’m experimenting.
oh, right, pr-str preserves functions (sort of)
be careful of multi-arity btw
actually - you could tell transit to use pr-str with a #fn tag for functions - it's pretty easy to configure
but it's a yak for sure
alternatively you could have a pre/post transform that turns :foo/bar into [:namespaced :foo :bar] and visa/versa
which is a pain, but with the right keyword would be unambiguous
maybe the next cljs will read namespaced maps?
the keyword-namespaced-map reader tag is very new - but it was clearly only implemented as a writer for cljs, and not a reader
the printer is intended - not reading it is a bug
@paulbutcher that definitely sounds like it should be possible, but I don't have any experience using AWS Lambda myself
OK, cool. I might have a bit of a play and see how I get on.
@paulbutcher great, keep me posted if you get it working, I could an example for future reference here https://github.com/macchiato-framework/examples
Will do!
cool - I upvoted it
@borkdude see https://dev.clojure.org/jira/browse/CLJS-1706 and https://cljs.github.io/api/cljs.core/STARprint-namespace-mapsSTAR In particular, note the default setting for the REPL
I… feel like I’m losing my mind. This:
(defn page [title]
(let [page-chan (hit-api "page" title)]
(go
(let [new-page (async/<! page-chan)]
(swap! page-state (fn [_] new-page))))))
Throws <! used not in (go...) block
This, on the other hand, works fine, but feels ridiculous:
(defn page [title]
(let [page-chan (hit-api "page" title)]
(go-loop [new-page (async/<! page-chan)]
(swap! page-state (fn [_] new-page)))))
gastove, there are some notes on certain unsupported constructs, maybe that is one of them? https://github.com/clojure/core.async/wiki/Go-Block-Best-Practices#unsupported-constructs-and-other-limitations-in-go-blocks
Error must be coming from somewhere else, but I haven’t successfully gotten source maps working on this thing yet so I am not… sure from where.
from the notes, maybe try moving that swap
call outside the loop - possibly add a callback argument to the page
function that passes the new-page and calls swap there
I’ve just reloaded figwheel and things are… working again? Perhaps I just got in to a weird state w/r/t which code was actually being evaluated?
Trying Lumo out and want to read a file using 'fs'. I can get it to work in plain node, but not in Cljs. Anyone done this?
Lumo 1.5.0
ClojureScript 1.9.542
Node.js v7.10.0
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Exit: Control+D or :cljs/quit or exit
cljs.user=>
cljs.user=> (def fs (js/require "fs"))
#'cljs.user/fs
cljs.user=> (.readFile fs "foo.txt" "utf8" (fn [err data] (println data)))
nil
cljs.user=> Hi from Foo
@clj.max which version of Lumo are you using?
try upgrading to 1.5.0 I guess
are you doing it at the REPL?
yeah!
brew update && brew upgrade
yeah that’s fixed
@clj.max I’m sorry! https://github.com/anmonteiro/lumo/commit/09bc54061b4bf178eb97f4c1382baf2f30cf31b1
there was a regression in 1.4
when using (JSON/parse ..)
I get the warning No such namespace: JSON, could not locate JSON.cljs
. It still works though. Do I need to require JSON or silence the warning or something?
@clj.max Anything before /
implies a namespace. You can instead use the pseudo-namespace js
to cause equivalent JavaScript to be emitted: (js/JSON.parse ...)
by the way, I find the Lumo error messages pretty helpful. are they different from regular Clojure ones? I like the little arrow and the stack trace being succinct
achievement unlocked, I guess
inspiration was taken from Planck though, gotta give credit to @mfikes
@anmonteiro is there some kind of println flushing?
I'm doing a bunch of println in a ->>, and it doesn't print anything unless I put a "println" in the ->> afterwards
it might just be that you’re doing lazy evaluation?
are you using map
, etc
those are lazy 🙂
is there a better way to thread into doseq than creating a fn like this?
(defn print-lines [lines]
(doseq [l lines]
(println l)))
(run! println lines)
?
run!
is like map
but for side-effects
and returns nil
(the same way ^boolean foo
is: http://blog.fikesfarm.com/posts/2015-12-04-boolean-type-hints-in-clojurescript.html)