This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-22
Channels
- # announcements (9)
- # beginners (96)
- # calva (14)
- # cider (49)
- # clj-kondo (29)
- # cljsrn (5)
- # clojure (55)
- # clojure-dev (37)
- # clojure-europe (4)
- # clojure-italy (4)
- # clojure-nl (5)
- # clojure-spec (5)
- # clojure-switzerland (3)
- # clojure-uk (5)
- # clojurescript (172)
- # cursive (14)
- # datomic (3)
- # duct (1)
- # emacs (6)
- # fulcro (17)
- # jobs (1)
- # leiningen (6)
- # nrepl (11)
- # off-topic (26)
- # pedestal (2)
- # re-frame (20)
- # reagent (9)
- # remote-jobs (3)
- # shadow-cljs (67)
- # spacemacs (24)
- # specter (6)
- # test-check (3)
- # tools-deps (18)
quick question guys,
im having trouble with the Calva repl & shadow-cljs
it seems like the console is hidden from me::
I can only get the result of evulations, ie 2
gives me back 2
, but (clojure.pprint/pprint 2)
, gives me back nil
, instead of 2
nil
is there a way to compile a cljs app into a standalone js file ?
@slack1224: it's a known issue. The output only goes to the console atm.
@slack1224 @pez well the return value will always be nil
since it prints to *out*
. if you want the actual result as a string you can use (with-out-str (cljs.pprint/pprint {:foo "bar"}))
[2:1]~cljs.user=> (require '[cljs.pprint :refer (pprint)])
nil
[2:1]~cljs.user=> (pprint 1)
1
nil
also works fine for me?Not in Calva. The out
nrepl message comes with a fixed (always the same) message id and not with the message id of the eval operation. Calva expects the latter and thus fails in showing the output.
Figwheel used to behave like that as well, I have been informed. Is it intentional in shadow-cljs, or should I file a change request? (This is a bit tricky to solve in Calva, because without the message id of the eval, I don't know where the output should go.)
why is everyone treating nrepl differently? and why do :out
messages need to be routed in the first place? it is just output that you should print?
I don't know enough about this to have an opinion on wether nrepl should be treated differently or not. 😃 As for why it needs to be routed, in Calva the user can evaluate things either inline in the editor, and that is ”mirrored” in an output log, where also any printing side effects show up. Or he can evaluate things in the REPL Window/prompt and then results and output are printed there. I might have wired things up incorrectly, but I do have the routing problem as it is.
well in JS we have the async problem. so I can capture all prints DURING evaluation easily but I cannot capture prints from async events that way
doesn't matter in the case of pprint
but it does matter as soon as anything async is done
If I can get the prints that happen during the evaluation in the eval response message, a lot would be won.
well isn't that any message you received after sending the eval request and before receiving the response?
I also have to fix the case you mention with any printing that happen after the evaluation.
I'm not saying that the out/err handling in shadow-cljs is great. just saying that we have to account for async since almost everything is in JS
I am planning to add a general output message handler. This driven by the case where some evaluation spawns of a thread where things are printed.
But I would like to be able to treat in-eval-printing such that I can print that at the same place where I print the results of the eval.
Now tried your example with (-> (js/fetch "/foo") (.then prn))
with Figwheel Main. It comes back with the same message id and session as the eval. This is what I get back:
{"id":"14","ns":"cljs.user","printed-value":1,"session":"eae3908b-0bdb-43a0-a883-5eb182d8b4f6","value":"#object[Promise [object Promise]]"}
{"id":"14","session":"eae3908b-0bdb-43a0-a883-5eb182d8b4f6","status":["done"]}
{"changed-namespaces":{},"id":"14","repl-type":"cljs","session":"eae3908b-0bdb-43a0-a883-5eb182d8b4f6","status":["state"]}
{"id":"14","out":"#object[Response [object Response]]\n","session":"eae3908b-0bdb-43a0-a883-5eb182d8b4f6"}
The Clojure REPL also sends back the out
messages with the same message id as the eval itself.
can you quickly test what happens in figwheel if you eval something else before the promise fires?
{"id":"14","ns":"cljs.user","printed-value":1,"session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","value":"#object[Promise [object Promise]]"}
{"id":"14","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","status":["done"]}
{"changed-namespaces":{},"id":"14","repl-type":"cljs","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","status":["state"]}{"id":"14","out":"#object[Response [object Response]]\n","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5"}
With (do (-> (js/fetch "/foo") (.then prn)) 1)
I get:
{"id":"20","ns":"cljs.user","printed-value":1,"session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","value":"1"}
{"id":"20","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","status":["done"]}
{"changed-namespaces":{},"id":"20","repl-type":"cljs","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5","status":["state"]}
{"id":"20","out":"#object[Response [object Response]]\n","session":"2e40e1e2-d1d3-4c2e-a212-4cf5d05c0ab5"}
is this correct interop? this.userOptions.plotOptions.pie.innerSize
-> (.. this -userOptions -plotOptions -pie -innerSize)
does anyone know any examples of well-known consumer facing clojurescript web applications?
I think CircleCI is written almost entirely in Clojure(script) https://github.com/circleci/frontend
is that just the landing page and portal or is there some kind of web tool / webapp also?
The landing page is not ClojureScript, but the web application is mostly ClojureScript
looks like precursor is also. It's actually a pretty cool app, too! https://precursorapp.com/
Whimsical is ClojureScript as well: https://whimsical.com/
Interesting... I wonder if these apps were developed with "hey what would be a natural choice for a product using clojurescript?" or more of a "we want to do this complex workflow app and the only thing that makes sense is clojurescript", or if it was something more organic
does anyone happen to know what lucidchart was written in?
Not sure about Lucidchart, but Precursor was developed by some ex-CircleCI employees who had acquired CLJS experience from working on the CircleCI frontend.
note that CircleCI has moved off ClojureScript as far as I know - from what I understand the team got significantly larger and they wanted to be able to just hire React devs
@goomba you can be effective with most modern tools for UI programming - claims otherwise are lies
ClojureScript / React simply show that functional techniques can be applied to UI programming at scale
there's no evidence that doing it one or another is going to make one bit of difference for any product
you're too modest @dnolen!! I think there's something very special about ClojureScript
sometimes there are legitimate technical reasons - but I've rarely found that to be true in narratives people tell
True. I just found myself in a similar boat to Mr. Hickey... if I had to write one more line of JavaScript I was going to quit and go back to potato farming
if you're sick of the programming language hodge-podge here Clojure(Script) provides an escape
While I agree that "anything can" be done with any client side language, I feel that the full stack synergy you mentioned hasn't been fully explored -- in fact I think we're barely scratching the surface. I'm sure you've checked out Tonsky's Web After Tomorrow blog entry?
I can't think of a single site that's doing that.
I've worked on Clojure(Script) + Datomic projects - lot of fun and sure IMO less complexity due to a unified programming model across all the bits of architecture
Well, the welcome-aboard kit with Clojure(Script) comes with enough rope to hang yourself, if that's the route you want to go, but I appreciate that 🙂
I think the killer missing piece right now is WebWorker-side VDOM diffing
After that it's game over
to be honest I don't really think all this super heavy client stuff is all that interesting
😮 😮 😮
What's up with all this modesty, wisdom, and pragmatism hahaha
yes/no... mm... that's a big problem with Clojure(Script) in general, and I think why teams eventually port their stuff to more accessible aka popular languages that are more copy/paste friendly and require less engineering discipline -- but I have the luxury of being incredibly biased
It's more of a LISP problem than a Clojure(Script) problem
Agreed, 100%
If you hire a Django dev or a Ruby on Rails dev you know what you're getting and everyone speaks the same language.
Kind of like why they went from archers to crossbows back in the middle ages. Doesn't take 20 years to train someone on the crossbow (edit: I have no idea if this is true or not but why let the facts get in the way of a good story...)
That impedance mismatch, weirdly enough, has been one of the awesomest things about cljs for me in doing full-stack work. It's been a survival tool in large inflexible organizations. Sometimes I can get more done client-side than is possible server-side just due to architectural or framework limitations.
Also oddly enough the nieche of cljs avoids a weird "bikeshedding" problem -- with popular frameworks/languages sometimes devs love to get into weirdly divisive arguments over minutia ... "is this function Pythonic enough?". With cljs in big organizations its, "I don't fully know how it works but darn you're doing a good job of delivering so keep it up"
Anybody else care to hear any more opinionated philosophy? 😛
but I think a wider success story probably needs to attack from a different direction - that's all I'm suggesting
I wonder if that wider success story is possible, or if it's closely tied to the so-far unsolvable riddle of "Quantitatively, what makes for a good developer?"
Probably more like a bhuddist koan though ... I'm not sure a good developer exists in isolation
Indeed. For what it's worth, you and your team have certainly made my life better.
cljs is the only reason i have fun doing side projects... maybe one day i will be able to sneak some into production
I have to say that CLJS makes UI learning an enjoyable experience.
The hot reloading makes the learning fun.
And also the repl.
Indeed. The first time you get that nrepl going and you see your code hot reload -- that's a unique experience to ClojureScript as far as I know.
Of course it took me about 3 years to get the nrepl going but I'm happy I finally got there!
Shadows-cljs made it much simpler
You can do it fully out of the box with deps.edn
now
Obviously, having experience in Emacs and coding in Clojure for fun for a few years helped that.
I dunno about deps.edn, but I know shadow-cljs helped me with all the major steps to understand the process to ship a UI.
The biggest issue is only the beginner’s curse of choice.
100% agree
@dnolen how do you see if there are too much work on client or server side? How does that situation arises?
on the server side you have stuff like the old Rails Turbolinks, on the client side you have people just trying to do everything in the client (no pages, etc.)
What does it mean no pages?
Is there a way to transform clojurescript forms (preferably fn
) to the most simple form of a javascript function so I could produce a javascript function in isolation?
I am asking this because pouchdb takes a simple javascript function as string for its map/reduce approach. I could just write the functions as javascript strings but it would be nicer to be able to have a simple transform (Without CLJ internals)
So SPA are bad?
I think the SPA is tempting because currently setting up a .js file per page like one might normally do in a typical full stack site carries with it a great deal of inertia, and creating reusable libraries while using advanced compilation has a higher barrier to entry than normal js projects
Not necessarily bad just harder to get right
When you have multiple pages you aren't bound by the decisions of other pages, it's just harder to get started
I'm talking about people writing SPAs with zero value - i.e. it's not a good fit for the problem
Ah ok.
means can I port a clojurescript function directly to JavaScript without all the clojurescript machinery
Just wants the "simple function" equivalent
As if mapped by hand
@alpox oh but you need to pass it as a string ... yeah probably simpler to just write the JS
I had to do this with Puppeteer recently - I just wrote those fns in a Closure namespace, ClojureScript makes it easy to load that kind of JS
Hmm I figured as much but I thought I better ask before ruling this possibility out fully. Thanks for the response 🙂
@alpox well issue would be you can't use anything from the ClojureScript std lib anyway - so even if we produce simpler output you would be effectively writing JS - you couldn't use any higher level anything
It's not impossible it just doesn't always make sense. You can advanced compile and specify that you don't want the compiler to munge the name and use the resulting artifact as a native JavaScript function, but to say it's overkill is an understatement
One of the "issues" with cljs is that it doesn't support copy/paste development
(it's not really an issue)
But you can't get away with just pasting in code, need to understand the workflow. Higher barrier to entry, but not so much more than webpack I think..?
With #fulcro and cljc
you can develop applications that work both with react/JS and fully SSR(JVM) with exact same code.
Or something like develop with react/JS (for hotreload) and deploy just with SSR (once SPA will not delivery any extra-value)
There is still some missing parts (routing/docs), but is possible.
Maybe share code between RN<>SSR There is a (broken) WIP about this here https://github.com/souenzzo/graph-demo
@goomba Webpack is a showstopper in many ways but most of the JS world uses Webpack only through wrappers like CRA now and have to touch it very rarely
Oh... Maybe I'm a masochist
hi! I'm finding hard to use from clojurescript js libraries where examples are written in ES6, are there any cljs abstractions or libraries for creating classes that extend from other classes, and deal with constructors, super, etc or is just working the prototype chain by hand the current way to go?
there's no sugar currently - though you have macros and can supply your own - perhaps there's a lib out there
I'm getting Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
with the following
[:span.ctx-Button.u-spaceInlineLeftSmall
(if attaching?
[:<> ;; if i replace this with a :span the error goes away
[cortex/icon-spinner]
[:span (or attaching-text "Attaching")]]
(if icon
[icons/icon :paperclip.fw (or button-text "Attach")]
(or button-text "Attach")))]
If i replace the react fragment with a span the error goes away and I can hotfix but I don't really understand why this is happening. Does anyone perhaps understand this situation a bit better?yes, if I had to guess you're using a component that gets replaced by SVG
the icons, specifically
in other words, the [cortext/icon-spinner]
probably starts out as an <i>...
and gets replaced by SVG+XML but this happens outside the control of React, and React is complaining during the teardown phase
so you have two or three options
first is use non-svg icons, second is find react-friendly svg icons, third is you can create a form-3 hiccup component that handles the teardown part of the lifecycle explicitly, and four is you might be able to bundle up those icons with webpack and it might go away (haven't tested the last one though, it's just a hypothesis)
i'm reverting the change back to i tags due to dropped click handlers so I'll get that there.
@dnolen you think that makes sense somethink like the Phoenix Liveview in Clojure world?
@dpsutton haha that error message is burnt into my mind... after hours of tearing my hair out with that problem once I won't soon forget it
@dnolen https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-real-time-apps-no-need-to-write-javascript
General question for some kind of React app -- if the application state is the result of the initial state + event1 + event2 + ... + eventN, what do we call that? Event driven? Event sourced? Data driven?
And also, what do we call it if we prefer sticking closer to core clojurescript (as opposed to framework heavy?)
"minimalist" doesn't seem right because sometimes it can be more verbose
Exactly @mkvlr @dnolen that is like a ELM architecture on the server, using websockets to send DOM diffing to browser
looks pretty interesting - perhaps some kind of happy mix possible here for Clojure(Script)
Someone is experimenting https://github.com/prepor/liveview-clj @prepor?
It is very interesting. I am curious how applications which are structured this way maintain sanity in the long rung... same problem I run into with a lot of distributed microservices, certain distributed and asyncronous work, and that I used to have with certain SPAs. i.e., imagine you have 10 go-loops
that wait for certain events to occur (maybe they're listening to an event log, maybe they get sent things from a pub/sub, who knows) and then take action based on those events. It's very easy to write apps like that... you write one of these processes and it's well defined and it does what it's supposed to. But later they can be hard to maintain because the behavior of the application gets more complex over time and sometimes it's hard to remember why the app is behaving the way it is.
i.e.,
(def proc1
(go-loop []
(when (some-event-happens)
(modify-app-state)
(recur))))
(def proc2
(go-loop []
(when (some-other-event-happens)
(modify-app-state-again)
(recur))))
easy to write, sometimes hard to remember what's going on lol
Yes, seems that they are experimented with this approach, so there is nothing in production yet, but seems very interesting. Follows the example that Bruce Tate twitted recently: https://twitter.com/redrapids/status/1164197019289882625