Fork me on GitHub
#clojurescript
<
2018-09-11
>
john00:09:42

Niiiice!

john00:09:05

I dig the name too šŸ™‚

mfikes00:09:43

Itā€™s a emal eman

john00:09:33

Does defmacfn run in clj/jvm?

john00:09:43

the fn defined by it?

mfikes00:09:57

Yes, but it also works in self-hosted ClojureScript

john00:09:16

But the function body has to be cljs semantics?

mfikes00:09:18

defmacfn is just a macro that runs defn in your macros namespace

mfikes00:09:47

Actually, if you are in JVM ClojureScript the function should be able to call Java interop

john00:09:17

So you gotta be cognizant your stuff might not be portable between the two

mfikes00:09:55

Yeah, I wouldnā€™t take that library seriously. It is more of an experiment.

john00:09:00

Right. If the macro ns was defined in a cljc file, would the reader platform conditionals work in a defmacfn? (:cljs & :clj)

mfikes00:09:41

I think the :cljs branch would always be taken.

john00:09:59

k, I'm def going to play with it

mfikes00:09:03

(Because reading happens before macroexpansion.)

mfikes00:09:45

To be honest, I suspect when people want macros in ClojureScript, they may really want ā€œThe whole language always availableā€ concept spelled out by Paul Graham http://www.paulgraham.com/diff.html (item 9 there). The chivorcam approach doesnā€™t give you that. It gives you a much weaker concept that is close to what we have today, but is really just a little convenient in that you can define a macro right in your ClojureScript source, or right in the REPL.

john00:09:30

A lot of cljs is like that. It's deceptively dynamic at dev time while producing this static thing.

john00:09:02

I guess static is a relative idea though, sitting on top of js and js/eval

mfikes00:09:21

Yeah, stepping back and looking at things through a very long term lens: ClojureScript's entire approach is an optimization that caters to the way things are today. You can imagine that in the future, all of this stuff won't be necessary. It may not be that far off. I still recall being surprised seeing a photographic-quality image on a computer screen (25 years ago?), or a near perfect audio in a digital file (15 years ago?). I bet we will have fully dynamic Lisp everywhere ultimately.

wizard 8
john00:09:47

In terms of cljs being static as an optimization... Yeah, memory footprint might be less of a worry, more and more. The minification and tree shaking def facilitates runtime performance, so that may always be a boon. Reversible minification would be nice though. But not having a runtime repl... is that a memory optimization or a runtime performance one too?

john00:09:22

Well, minification is a runtime performance boost whenever you've gotta push serialized code between workers or clients. But most people don't do that in js

mfikes00:09:36

I'm just sayin' go to http://clojurescript.io and it works today. It isn't like you have to wait that long for it.

john00:09:49

Yeah, market forces aren't there yet. It's still too much of a cost to ship the runtime.

mfikes00:09:29

I agree. I'm wondering how long we will be in that mode šŸ™‚

john00:09:52

I'd like to make a mini static blog platform that has a self host repl in it though, that can save itself to github.

john00:09:29

And I can just program the site in the site, updating anything, with macros etc, and saving it back to GH

john00:09:30

Sorta like these things ~<https://github.com/iamdanfox/ghupdate~> I can't find what I was thinking off, nm

john00:09:09

But with a self-hosted cljs that just grows its semantics over time

john00:09:56

I've got a thing working based on this awesome shadow-cljs example by Matt Huebert here https://github.com/mhuebert/shadow-bootstrap-example

john00:09:43

I've got a version of the widget where you can pass in hiccup forms and it produces it in the right pane. So I'm thinking there can just be an edit mode, where you can expand the hiccup content of any given widget on the page. Pretty simple.

john00:09:11

It's similar to how https://maria.cloud is built. It's pretty awesome how seamlessly that works with github.

john00:09:48

Oh, and a neat perk would be that it still produces static pages, for the view of the website that is not in admin mode (while authed to GH), so viewers of your blog would still be getting a minimal set of artifacts, if any.

john01:09:05

Has anybody tried this with a self-hosted cljs compiler? https://github.com/google/closure-compiler-npm

john01:09:11

I guess producing minified artifacts in self-host mode has limited use cases

jaawerth01:09:21

@john that's kinda what lumo is using, except it's just directly google-closure-compiler-js

john01:09:41

Yeah, and that's a valid usecase... I suppose if I wanted a github hosted site, where I could generate minified artifacts and save them back to github, that'd be a valid usecase.

john01:09:44

Or if I wanted to serialize code between workers, there's an optimization there. But why else would you want to produce new minified artifacts at runtime?

mfikes01:09:30

@john Planck also uses it. (See Optimizations under http://planck-repl.org/performance.html)

jaawerth01:09:40

I think it's more about not needing additional runtimes beyond the one you're targeting

jaawerth01:09:48

which is to say, not needing the jvm

john01:09:09

But wrt in-browser usecases, rather than node. Maybe an in browser ide

jaawerth01:09:35

yeah, or a better sort of cljs-fiddle/repl/bin

john01:09:29

Yes, thanks for the lead

mfikes01:09:27

I suppose it is not that easy (https://github.com/planck-repl/planck/blob/master/planck-cljs/src/planck/closure.cljs), but you should feel comfortable knowing that it works from self-hosted ClojureScript.

jaawerth01:09:57

yeah, lumo still bundles itself with a full node runtime for.. reasons. and doesn't seem to have a requirable compilation API from the JS side. Which hopefully will change in the future. Though I haven't had a build script try compiling itself, from lumo

john01:09:59

Yea, I wasn't sure it would

john01:09:25

Yeah, it's optimized for the cli I guess

john01:09:25

TBH though, I think wasm is the future. I'm researching the semantics now to see how much of MAL can be implemented in raw wast

mfikes01:09:05

Maybe that's what Brandon Bloom has been doing, trying to read between the lines of his recent tweets.

john01:09:18

oh, well his github seems to agree šŸ™‚

john01:09:43

Yeah, so I think we may be able to decouple clojure from a particular memory management scheme/runtime by building persistent data structures backed by a fully memory managed (by clojure) pool of fressian objects living on SABs, via a lockfree allocation/reclamation protocol.

john01:09:27

Then we may be able to implement a clojure dsl in wasm that operates over SAB fressian pools, without needing a managed memory runtime

john01:09:31

We'd need to build character stream facilities and regexes though

john01:09:40

to get a repl up on it

john01:09:17

And, from what a lot of C++ conference speakers are saying about newer lockfree alloc/free schemes, they can be pretty good

jaawerth02:09:09

would that be worth the barrier to js interop? or am I missing something?

john02:09:41

Not for js interop. For the raw performance of wasm

jaawerth02:09:08

right, but there'd be a tradeoff, no?

john02:09:25

like, 20% compared to machine code

john02:09:37

What other trade offs where you thinking of?

john02:09:28

There's no GC there yet, but with self managed fressian pools, we wouldn't need any

john02:09:43

(theoretically)

john02:09:02

You're still in the JS sandbox, so there's those tradoffs. But pretty soon, there'll be tons of wasm interpreters for the cli for every platform

jaawerth02:09:16

I mean, wouldn't any interop from your compiled cljs to js and the dom apis only it has access to require going through a binding?

jaawerth02:09:57

maybe I'm misunderstanding something and this is just for isolated optimized routines

john02:09:27

From what I understand, they plan on exposing dom apis to wasm

john02:09:11

It's a hassle now. Rust is just finishing up something called bindgen that takes care of binding the dom stuff in for you

jaawerth02:09:14

I could be misremembering but I was under the impression some things needed to be restricted due to safety issues yo uget with a lower level language, but it's not a subject I keep up on super well so I could be conflating things

john02:09:34

yeah, I recall hearing that a while back too

john02:09:42

I think the mindset has changed around that

john02:09:55

Wasm threat model is = to js threat model

john02:09:23

There's no point in overly restricting access between the two, when the're both in the same js sandbox

john02:09:30

I think you'll be able to enforce more sandboxing over the wasm, but it's considered the same sandbox with the same threat model

jaawerth02:09:16

there's also the whole interop for using the host platform's ecosystem benefit to consider but I can see where the binding might be worth it in some applications because of how little you need to do that

jaawerth02:09:16

you could do some pretty cool things with a worker that was compiled to wasm from cljs, for example

jaawerth02:09:20

(or whatever)

john02:09:59

But don't be surprised if you end up seeing a "posix" wasm module and a bunch of unix utilities ported right into the browser

jaawerth02:09:34

I'm just hoping it won't lead to a boom of new adware and drm

john02:09:24

It'll be no different than the current situation, wrt js

john02:09:00

But yeah, way more powerful šŸ™‚

john02:09:28

Doom 9 adware running at 60 fps šŸ˜‰

john02:09:11

wrt browsix and your OS moving to the browser... one benefit is package management is already a solved problem by the browser cache.

john02:09:54

the browser cache does package management of js files pretty efficiently for users already

john02:09:35

wasm is now an official target of the unity engine. Most new games built on it will likely have a web port https://blogs.unity3d.com/2018/08/15/webassembly-is-here/

john02:09:48

Folks are trying to bring Volkan to wasm too

john03:09:19

And wasm seems to be the new hotness for the go and rust communities. I guess go shipped a gc in there, despite some difficulties.

samedhi03:09:54

I am having some trouble figuring out how to host some snippet code I wrote with klipse, seems that I do not see cljs.spec.test.alpha. http://samedhi.github.io/code/2018/09/08/clojure-macro-for-running-clojure-spec-test.html . Thanks you!

priornix13:09:28

Hi, any ways to load code from another cljs namespace? load only works in CLI

henrik13:09:44

@priornix Are you looking for

(ns my-app.thingie
  (:require [ā€¦

priornix13:09:21

No, just wish to expose the code from other namespaces in this one

priornix13:09:59

eg: (in-ns 'foobar.core)

priornix13:09:32

I'm trying to find the equivalent in cljs

henrik13:09:35

Typically you would use,

(ns my-app.thingie
  (:require [my-app.doodad :refer [my-function]]))

priornix13:09:34

Yes, but my-function won't be visible in (my-app.thingie/my-function)

priornix13:09:54

I'm trying to group functions in one namespace but keeping them in separate files

priornix13:09:55

In Clojure you can do things like in-ns or refer or load

henrik13:09:23

Oh I see, interesting. Iā€™ve never tried to do that.

priornix13:09:58

Yeah, apparently it's how Closure works with namespaces

priornix13:09:24

I'm not sure what's the status this now

thheller13:09:19

@priornix this is not possile in CLJS. namespaces are static due to the closure compiler. you can use require in the REPL dynamically but in files they must be static

priornix13:09:38

Yes, that's what the article mentioned

priornix13:09:51

Or somewhere else that I read

priornix13:09:32

Just trying to see how to organize the code

priornix13:09:42

Thanks @thheller for confirming

sveri13:09:29

Hi, how can I translate this theme.breakpoints.up('md') to clojurescript? I managed to access the up function: (-> theme .-breakpoints .-up) but I am clueless on how to provide the 'md' keyword to it?

thheller13:09:53

(-> theme .-breakpoints (.up "md"))

sveri13:09:03

@thheller Thanks, that did it

bmaddy19:09:50

Is anyone else using the Oops library? Do you know why I'd be seeing this error?

(oset! (js-obj) :mood "a happy camper")
clojure.lang.ExceptionInfo: Can't change/establish root binding of: *cljs-warnings* with set at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :root-source-info {:source-type :fragment, :source-form (oset! (js-obj) :mood "a happy camper")}, :tag :cljs/analysis-error}

darwin19:09:34

@bmaddy it looks like it cannot set! cljs.analyzer/*cljs-warnings* in your REPL

darwin19:09:40

not sure why it should not work in REPL, maybe someone else will have some insight: https://github.com/binaryage/cljs-oops/blob/master/src/lib/oops/compiler.clj#L43

bmaddy19:09:56

Hmm, strange. I'll look into that binding and see if I can figure out what's up. Thank you!!

darwin20:09:30

if I remember correctly, I needed that to add some new warnings into cljs compiler: https://github.com/binaryage/cljs-oops/blob/master/src/lib/oops/messages.clj#L40-L65

mfikes20:09:08

You can't set that binding in the REPL because it is a Clojure thing.

bmaddy20:09:48

Interestingly, this works (in the repl):

(set! cljs.analyzer/*cljs-warnings* (merge cljs.analyzer/*cljs-warnings* {:foo true}))

mfikes20:09:19

@bmaddy Are you in a self-hosted REPL?

bmaddy20:09:47

No, I initially started my project with lein new re-frame my-project +10x +cider +re-com +routes +test

mfikes20:09:29

Hrm. I suspect that you have the cljs.analyzer namespace visible in ClojureScript simply because the source ends with .cljc and it was accidentally compiled.

mfikes20:09:55

(For JVM-based ClojureScript, cljs.analyzer is a Clojure namespace.)

bmaddy20:09:26

come to think of it, I didnt' even require it, just tried using it.

mfikes20:09:26

(That means that, while you can set cljs.analyzer/*cljs-warnings*, it won't mean much.)

šŸ‘ 4
mfikes20:09:12

(Normally you need to set this from your build tooling while in Clojure.)

mfikes20:09:44

Or make a fancy macro that lets you do it from ClojureScript.

darwin20:09:57

cljs-oops does that in a macro

darwin20:09:27

oh, wait, maybe not

bmaddy20:09:28

Ah, so my testing of setting that binding wasn't doing what Oops is doing. That makes sense now. I should try from my clj repl.

bmaddy20:09:10

Yep, that did it:

(set! cljs.analyzer/*cljs-warnings* (merge cljs.analyzer/*cljs-warnings* {:foo true}))
java.lang.IllegalStateException: Can't change/establish root binding of: *cljs-warnings* with set

darwin20:09:59

actually, yes, it runs that code in context of a macro

darwin20:09:53

the idea is to augment *cljs-warnings* during oset! macro invocation: https://github.com/binaryage/cljs-oops/blob/master/src/lib/oops/core.clj#L19 with-compiler-context! is a clojure macro which conditionally generates some code including (set! cljs.analyzer/*cljs-warnings*...)

bmaddy20:09:17

Yeah, I saw that and it makes sense. I'm just confused as to why I get that error when trying to use oset! in the repl.

bmaddy20:09:09

Well, it seems to work in code when compiled, so it must just be a repl thing.

bmaddy20:09:06

Anyway, thanks for the help everyone! šŸ˜„

4
Mario C.20:09:59

I am using Spacemacs and want to start up a CLJS repl. How do I do that?

Mario C.20:09:13

I ran SPC - m - s - I

Mario C.20:09:46

This prompts me to choose between nashorn figwheel figwheel-main

Mario C.20:09:58

plus a few others

Mario C.20:09:13

but regardless it gives me an error that says piggieback not available

bmaddy20:09:01

I need to run, so can't really respond after this, but is piggieback possibly not in your project setup file (`project.clj` if using lein)?

šŸ‘ 4