Fork me on GitHub

Hey y'all, gotta fresh toy here for ya: Kanaka's latest Mal over WASM, ported to ClojureScript and using tau.alpha for blocking reads, running in a browser REPL, producing a Mal REPL: Malhala


i'm looking for a presentation of figwheel and reagent where you could follow along as tetris was implemented. does anybody have the link? i can't find it anymore 😕


yeah, that one is amazing


Has anyone worked with Klipse as a library? I want to have some live-rendered snippets of reagent (as part of an interactive tutorial), but I want to call Klipse as a library from ClojureScript. Is this even possible?


if you find out, let me know, I’ve been meaning try this too


It’s tricky, because Klipse needs self-hosted CLJS, but I want the tutorial to be able to seamlessly reuse whatever lies around in my project which is compiled by shadow. I might have to look into actually using files…

Roman Tsopin13:01:33

Just watched the talk “functional programming in anger”, where David said that now you could require any npm lib, and there is no need to write externs manually. That’s cool. But I can’t figure out how to actually do this. Can someone please provide an example? Should you use foreign-libs, npm-deps, infer-externs etc? Also it would be awesome to include this into get started tutorial.

Roman Tsopin13:01:01

Thanks, I actually read those, but couldn’t figure out how to apply them in my case (empty cljs project and leftpad installed from npm)


lol, can someone help, I've been up for a thousand years. what's the best way to just get a pretty print formatted string in cljs


so I have some json, I want to edit it in a textarea in my browser, and I want it to be pretty printed


(with-out-str (clojure.pprint/pprint the-thing))


oh json, you could convert it to clj first with js->clj


if you want to edit it as json, I don’t know. you could look for some existing react lib for it, or use codemirror, I don’t know


still now what I'm going for


doing the pprint thing seems to just be adding escape slashes


@idiomancy if you just want pretty printed JSON and not EDN you can just use (js/JSON.stringify (clj->js {:some "data"}) nil 2)


no i mean its already json


but its like, I want it to look like this (I pasted it into an IDE and used the auto-reformat and pasted it back)


but instead, it looks like this:


(js/JSON.stringify the-json-obj nil 2)


look at that!


I never knew you could pass additional args to stringify to control the formatting


the magic words


How do you require namespaces in cljs REPL? I tried (require '[my.namespace :as x]), but x/.... doesn't work.


should work


have you changed anything after the first load? then you could try: (require '[my.namespace :as x] :reload)


so here’s a good one: how do you convince someone who doesn’t know what they don’t know (and is convinced they’re right) to look into clojurescript when “nah man i dont like abstractions over raw js” is their line of thinking? react/redux “is the best thing” and re-frame is just silliness.


what do they value?


for example, I came from the react/redux world into Clojure(Script) because I was exploring things that were already being talked about by the people I respected in those communities: - immutability - hot reloading - new syntax


when I started trying out Clojure, it was because I had tried and struggled with those 3 things and had heard that Clojure(Script) had them all by default 🙂


essentially it was easy to do the things I valued + had found hard


but those values didn’t come from Clojure… I already had them from listening to Dan Abramov, Jordan Walke, etc.


well, presumably immutability because they keep the mental overhead of using {... spread, a: 1} syntax everywhere. or they use immer/immutablejs. they have a lot to setup to get hot reloading, but admittedly you usually only have to do that once. it’s like im missing a piece to make it “click”.


for them things like javascripts object equality by reference instead of value isn’t a problem 😞


I mean, for most people it isn’t. you might think it is, but to them you’re just inventing problems 😛


maybe if you related that to componentDidUpdate and having to use immer/immutablejs. I can’t imagine someone using immutablejs in anger and not wanting to burn their project to the ground.


it sounds like this person is happy. are you trying to convince them for some reason?


yes, i want to use cljs + reframe when we have to build SPAs (not often, but often enough). the react/redux stack very often seems like pouring concrete and i know there’s better ways 😞


would you and he be developing together?


its a consultancy, so occasionally but not all the time. unfortunately we try to standardize on a stack for new projects. if there’s not agreement i think we’re going to default to some js framework simply because it’s least far from the familiar


well, maybe ya’ll could use it once for an experiment


I’ve been through this recently @lwhorton. I think it’s impossible, because the things ClojureScript brings to the table manifest over a longer period of time, and they also require a considerable up-front investment. So people who feel productive in their local maximum are reluctant to change.


that’s really depressing but i don’t disagree


One argument I had is that Clojure incorporates into the language many concepts that in JS you need to have a framework for. E.g. the succession model with atoms that can replace redux entirely. Also a standard library.


In the end, it feels like you’re in a Monty Python sketch arguing about what the romans ever did for us.

Braden Shepherdson18:01:24

one tactic I've used with a bit of success in that argument is to rebuild something - and not just a prototype, but a full reimplementation of some part of the app, real data and all - and then show (1) how much smaller and simpler the code is, and (2) how much more quickly I wrote it. the conclusions are either that these proposed tools are more powerful and allow us to do more with less code in less time, or that I'm way smarter and more productive than whoever wrote the original code, which seems unlikely.

Braden Shepherdson18:01:00

both arguments fall apart if there's even one footnote on the reimplementation; it needs to be real.

Braden Shepherdson18:01:25

because if there's even one tiny crack, it will become the explanation for everything, rather than the language.

Braden Shepherdson18:01:11

(even if it's completely impossible for the tiny crack to cause the four-fold code size reduction, etc. etc. you can probably hear how many frustrating and circular arguments we had about this.)

Braden Shepherdson18:01:52

(caveat, for honesty: I failed to ultimately persuade my team. there was an irredeemable "crack": Javascript is an officially supported language inside Google, and ClojureScript is not. never mind that both go through the Closure compiler and ultimately result in Javascript code for the user's browser to run.)


i actually did a complete rewrite of an existing client’s SPA. it was verbatim a copy-paste at 4.8x less code and it took me a week vs. 2 months. 😞


i’m sorry yours didn’t work out either

Braden Shepherdson17:01:30

I know that feeling. there's a bottomless well of frustrating counterarguments people use. "oh, we can use this library and reduce our code size by 20%." "yes, but I'm talking about a five-fold reduction in code size."

Braden Shepherdson17:01:14

I'm pitching a drop-in replacement thing at work right now unrelated to Clojure, it shrinks a block of generated JS by 20x, from 1.1MB to 70KB.

Braden Shepherdson17:01:55

my detractors propose changing the generation options to reduce the size by ~30%, and having to change all the call sites.

Braden Shepherdson18:01:16

but I had converts, which is something.


@lwhorton I typically express shock along with a disingenuous attempt at empathy for those using raw js. OMG you actually live without core.async?


i feel similarly. it’s hard not to be disingenuous, and sadly that makes us lispers often look pretty arrogant (i think). if you’re on the outside looking in, you don’t know what you don’t know.


> makes us lispers often look pretty arrogant… true, but I’m suggesting a response to arrogance + I tend to smile 🙂 it’s hard to be arrogant (at least for me) when you smile


Hi, I'm trying to compute a d3 pack layout from some cljs data. It works quite well, but when I convert the result back with js->clj, I just get #object[Node [object Object]]... Any idea how to turn that into useful data again, or do I have to recurse through it myself?


Ended up recursing through it myself feelsgood


json.stringify works on it, after I removed the parent field from it, which otherwise makes it circular -.-


define multimethods in runtime is a bad thing to cljs? example

(defmulti foo ...)
(defn main []
  (defmethod foo ... ))


@souenzzo any kind of runtime usage of def is discouraged


we certainly don't check for problems you might encounter doing that and don't have plans to


the one exception here is wrapping defs in some kind of conditional feature detection


but that's not def in def


defmethod is just sugar over (-add-method foo :val (fn [...] ...)) so you could use that directly instead too. defmethod doesn't actually def anything so I'd say its fine.


but imho its probably a code smell if you do that because you need access to extra state in the function definition. something that should probably be passed as an arg


well I would argue the problem here is unmanaged manipulation of global state - def and defmethod both do that - so I'd still argue probably not fine 🙂


unless you're doing something special that really calls for it anyway - I would avoid the pattern

Eccentric J21:01:57

Is there any guides on using ClojureScript’s browser events API? I found wrappers but haven’t been able to locate any API docs


@jayzawrotny that ns exist primarily for historical reasons


just use Closure Library directly, etc.

Eccentric J21:01:15

Ah ok, thanks!