This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-22
Channels
- # babashka (36)
- # beginners (42)
- # calva (6)
- # chlorine-clover (25)
- # cider (31)
- # clara (5)
- # clj-kondo (55)
- # cljdoc (3)
- # cljs-dev (7)
- # cljsrn (3)
- # clojure (73)
- # clojure-brasil (6)
- # clojure-europe (8)
- # clojure-italy (2)
- # clojure-nl (3)
- # clojure-norway (1)
- # clojure-spec (3)
- # clojure-sweden (4)
- # clojure-switzerland (2)
- # clojure-uk (29)
- # clojurescript (93)
- # conjure (21)
- # data-science (14)
- # datomic (19)
- # emacs (4)
- # exercism (3)
- # figwheel-main (38)
- # fulcro (38)
- # graalvm (42)
- # graphql (5)
- # jackdaw (3)
- # jobs (1)
- # joker (2)
- # lambdaisland (1)
- # leiningen (31)
- # malli (8)
- # meander (5)
- # off-topic (27)
- # pathom (2)
- # pedestal (28)
- # re-frame (25)
- # reagent (2)
- # reitit (11)
- # releases (3)
- # remote-jobs (1)
- # rum (1)
- # shadow-cljs (63)
- # spacemacs (17)
- # sql (1)
Hi. I would like to use advanced optimization on my code, but, I want to protect a select number of function names from being modified. These are function names in my code, not in 3rd party libraries. Is this possible?
Use case: I am writing a bunch of apps script ( https://developers.google.com/apps-script/ ) and want to start doing it in clojurescript. I have everything working from end to end but due to advanced optimization I have spreadsheet functions like =C()
instead of =MYEASIERTOREMEMBERNAME()
. There is an approach here that uses an extern javascript file for the interface https://lambdaisland.com/blog/2016-10-01-clojurescript-and-google-apps-script - I could do that, but it would be completely sidestepped if I could mark some functions for no renaming.
I am using Shadow CLJS right now but I am happy to use any approach.
( and, I have tried to use the externs/<your-build>.txt
approach in Shadow to declare externs but it doesn't have the results I was expecting - perhaps I am missing something there https://shadow-cljs.github.io/docs/UsersGuide.html#_simplified_externs )
Any pointers appreciated.
Like in that LambdaIsland article:
(defn ^:export create-menu []
...)
The article itself talks about "the ^:externs
metadata" - that's probably a typo.https://shadow-cljs.github.io/docs/UsersGuide.html#_working_with_optimizations from shadow users guide but not finding anything on the cljs side
Here it is: https://clojurescript.org/reference/advanced-compilation#access-from-javascript
thanks @U2FRKM4TW
@U3HP1K63A what is your function named? there is munging still going on
export AFAIK puts a name on a global object like window['original-name'] = munged-name
That does not work in an apps script context.
Apps script needs to see function definitions like function original-name {}
Ah, in this case the approach with an extra JS file outlined in the LambdaIsland article seems like the only solution. That's how I would do it. But I'm not an expert in compilation, so I may be wrong.
yeah it seems the output will always look like the following:
foo.foo_with_export = (function foo$foo_with_export(){
return null;
});
goog.exportSymbol('foo.foo_with_export', foo.foo_with_export);
i am getting this error, can anyone help me with this
@vjdomadia google suggests its a disk error? google the "cyclic redunancy check" error
Hi. My name is Gunar. I'd like to contribute with the ecosystem. Do you know of some impactful projects that are in need of a hand or two? Thanks in advance!
Hey all! I want to get all checkboxes by Name "checkbox", I'm using the cljs-js interop for that :
def all-checkboxes (. js/document getElementsByName "checkbox")
; I see it returns a NodeList. How do I iterate through this and get only those checkboxes that are checked? A for-loop doesn't seem to work here. Also, I came across clojure-interop/cljs-web-api
How to use this in my cljs file? Thanks in advance!
for already implicitly calls seq
Yes I did try (array-seq all-checkboxes)
. When I gave (nth all-checkboxes 0)
, it gives the element as in <input type="checkbox" id=.. value=..>
.
prim-seq
explicitly says it supports NodeList https://cljs.github.io/api/cljs.core/prim-seq
I get an IndexedSeq now. But giving (`nth .. 0)` still gives <input type="checkbox" id=.. value=..>
once you have a seq, you can use filter
or equivalently use a :when
clause in a for
comprehension
for isn't a loop and only works on inputs that are seqable?
is there an official clojurescript version of resolve? I am trying to resolve keywords like :my.namespace/my-function to the function .. for clojure i can do this
(-> my-keyword-fn symbol resolve)
but can't get away with that in cljs
eww .. ok .. thanks Thomas
is there a way to have a similar effect as import-vars from potemkin in clojurescript?
there are no vars at runtime
there are while expanding macros afaik, but import-vars is mostly about keeping two vars in sync
you can use def otherwise
import-vars fixes problems with that def that cljs ensures you won't see
(mostly... I guess there's the issue of hot-loading the target ns...)
yeah, hot-loads will cramp your style with that
by default CLJS tooling will at least reload immediate dependents. so if you are importing defs from bar
into foo
, then changes to bar
will trigger a reload of foo
oh good
however, it will probably hit the cache for the compilation of foo since it hasn’t changed
which is why (def foo bar/foo)
will reload fine, but if you have a macro like:
(ns foo
(:require [bar]))
(import-defs 'bar)
and you add a new def to bar
, it probably won’t pick it up because foo
won’t have changes -> won’t re-compile and re-run the macroI have a massive data structure in an atom, and have a map containing that atom as a value, and am passing that map to a number of functions. This seems to slow things down considerably, even if none of the functions actually use that value in the map. Does this make sense?
that seems very odd. are any of the functions doing some sort of memoization?
One of them is resetting the value of a seperate atom to contain that map, I guess that might be doing it?
can you confirm that the atom isn't being used somehow by instead passing:
(reify IDeref
(-deref [_] (throw (js/Error. "not supposed to happen")))
that doesn't cover all ways an atom could be used, but might catch some
the only other thing I could think to do is have function that loops while calling the functions you're interested in and running the profiler to see what turns up
ok yeah I was accidentally rendering the whole printed map somewhere, woops!, thanks for the help though
no problem!
Hey all, I'm using the CLI tool for my current project and I'm trying to install and include a npm library I've read it's possible to do via :npm-deps but i'm not entirely sure where that needs to go. Would it go in the deps.edn or maybe in the prod and dev.clj files when I do the api/build? Would this be a question for tools-deps channel?
Use case is I'm developing an application that has to run in a QtWebkit browser that dosen't support ES6 so I'm wanting to use core-js to polyfill ES6 in order to use react/reagent. Am I going about this the wrong way?
I have a bunch of different components which can be rendered as dom objects. When designing a system for these to interact, is there a clear winner between these two approaches: 1. Renderability as a protocol
(defn codemirror-element
"Given a codemirror object, return a codemirror element"
[codemirror-object]
(.-parentElement (.getScrollerElement codemirror-object)))
(defprotocol IRender
(render [this]))
(specify! (CodeMirror.)
IRender
(render [this] (codemirror-element this)))
2. a "renderable" thing as an attribute in a map:
{::cm codemirror-object
::dom/node (codemirror-element codemirror-object)}
I realize this probably depends on a lot of other factors in the system. But with no further info is there a clear winner between these two?just between these two, there is a difference of timing. not for this specific example, but in a general sense, 1) renders when the caller decides based on the data at that time 2) the render happens ahead of time. this can make a difference even for the case of a non mutable renderable thing
i'm also working on some ui design stuff. currently, all elements are pure data, but there are some cases where I'd like to eventually allow the embedding of mutable ui components (eg. code mirror, video, webviews, etc). Ideally, I'd like a design that can turn these mutable embedded components into values, but I haven't quite figured out all the details yet.
how does option 2 handle equality?
it seems like having a map with mutable stuff inside could break equality semantics in a subtle way
for that reason, option 1 might avoid some of those issues?
My thinking was sort of that the mutable node would be controlled through the ::cm
key
right, so when the state of code mirror changes, you can't use =
to find out if the value has changed
and you can't do any caching using that ui component as part of the key
Oh yeah, true. I was think of, as I add features to associate other keys in the map, such as ::clean-save-state?
that could be an atom keeping a boolean, which would be set by a wrapping process, and I could build up features this way by just adding things to the map
yea, the two approaches seem pretty similar. I guess some of the differences are:
;; implies computation is being done here
;; can delay computation of dom nodes until they're actually needed
(render elem)
;; computed ahead of time
;; requires all views to precompute dom nodes,
;; even if this element isn't always attached to the DOM
(::dom/node elem)
so to me, approach 2 feels like it belongs in the part of the code that is only modifying the DOM. approach 1 feels like it's a protocol that a user could extend to provide a way for their data to be visualized
does clojurescript allow extend via metadata? https://clojure.org/reference/protocols#_extend_via_metadata
fwiw, I think approach 2 is becoming more popular, but I haven't tried it in any real application, so I'm not sure what benefits I might be missing there
Yeah I guess that's really what I'm trying to think about: does ::dom/node
make sense in the context of the rising emphases on "gloablly namespaced attributes", ie with specs. But I'm starting to think it doesn't because ::dom/node
doesn't really make sense globally as something that can be provided without context
Like once I start to want to compose the things,I think render
looks better:
(defn editor [{:keys [modebar?]}]
(let [cm (codemirror m)]
(reify IRender
(render [this]
(if modebar?
(div
(render cm)
(render (modebar cm)))
(render cm))))))
(defn editor [{:keys [modebar?]}]
(let [cm (codemirror m)]
(if modebar?
{::dom/node
(div
(::dom/node cm)
(::dom/node (modebar cm)))}
cm)))
is there any way to achieve:
(defn editor [{:keys [modebar?]}]
(let [cm (codemirror m)]
(reify IRender
(render [this]
(if modebar?
(div
cm
(modebar cm))
cm)))))
allowing div
to receive any renderable
further simplifying:
(defn editor [{:keys [modebar?]}]
(let [cm (codemirror m)]
(if modebar?
(div
cm
(modebar cm))
cm)))
cm)))))
I think I will want other data/methods associated with the editor though and will probably keep it a map with render
set via specify or a metadata protocol
I have a monolith Clojure server-rendered app with multiple unrelated sections that I want to add some JavaScript to (re-frame/reagent). How do I go about the compilation of such setup? I am using Leiningen and prefer to keep the JS of every section separate.