This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-31
Channels
- # announcements (6)
- # babashka (40)
- # beginners (6)
- # calva (1)
- # cider (1)
- # clerk (43)
- # clj-kondo (3)
- # clojure (93)
- # clojure-denver (8)
- # clojure-europe (52)
- # clojure-norway (20)
- # clojure-sweden (7)
- # community-development (5)
- # datascript (15)
- # datomic (30)
- # emacs (24)
- # events (15)
- # fulcro (23)
- # graalvm (12)
- # gratitude (1)
- # helix (4)
- # honeysql (4)
- # hoplon (39)
- # hyperfiddle (7)
- # introduce-yourself (1)
- # jobs (1)
- # jobs-discuss (26)
- # lambdaisland (3)
- # lsp (6)
- # matcher-combinators (2)
- # matrix (5)
- # meander (39)
- # nrepl (4)
- # nyc (1)
- # off-topic (5)
- # portal (73)
- # practicalli (1)
- # re-frame (2)
- # reitit (22)
- # releases (1)
- # remote-jobs (4)
- # shadow-cljs (5)
- # sql (17)
- # testing (1)
- # tools-deps (15)
update: thanks to @djblue we are close to supporting all of the emmy viewers in portal, like this: this one should be dragging the plot around, and it will, soon! EDIT: it works great:
it should look like this:
Can't get the inequality bit working, probably have the wrong version of the code, but the atoms are working for this example if you wrap the code in an fn
Also default viewers can be specified at all levels so this viewer will compose will all the other viewers in portal
For example:
(->
[:<>
[:portal.viewer/code "(+ 1 2 3)"]
[:portal-present.viewer/mafs
'(fn []
(reagent.core/with-let
[G__68160 (reagent.core/atom [0 0])]
[:<>
[:pre (clojure.core/pr-str @G__68160)]
[mafs.core/Mafs
[mafs.coordinates/Cartesian {}]
(reagent.core/with-let
[G__68161
(js/Function.
"[y0001]"
"[p0002]"
" const _0006 = - p0002;\n const _0008 = _0006 + y0001;\n const _0013 = Math.sinh(_0008);\n const _0014 = Math.cosh(_0008);\n const _0015 = Math.pow(_0014, 4.0);\n return (- 6.0 * Math.pow(_0013, 4.0) + 8.0 * Math.pow(_0013, 2.0) * Math.pow(_0014, 2.0) - 2.0 * _0015) / _0015;")]
[mafs.plot/OfX
{:y
(let [G__68162 (mapv @G__68160 [0])] (fn [x] (G__68161 [x] G__68162)))}])
(reagent.core/with-let
[G__68163
(js/Function.
"[y0001]"
"[p0002]"
" const _0006 = - p0002;\n const _0008 = _0006 + y0001;\n const _0013 = Math.sinh(_0008);\n const _0014 = Math.cosh(_0008);\n const _0015 = Math.pow(_0014, 4.0);\n return (- 6.0 * Math.pow(_0013, 4.0) + 8.0 * Math.pow(_0013, 2.0) * Math.pow(_0014, 2.0) - 2.0 * _0015) / _0015;")
G__68165
(js/Function. "y0001" " return Math.cos(y0001);")]
#_[mafs.plot/Inequality
{:y
{:<=
(let [G__68164 (mapv @G__68160 [0])] (fn [x] (G__68163 [x] G__68164))),
:> G__68165},
:color :blue}])
[mafs.core/MovablePoint {:atom G__68160, :constrain "horizontal"}]]]))]]
(with-meta {:portal.viewer/default :portal.viewer/hiccup}))
In terms of downstream users resolving npm deps, not sure how you envisioned it, but the following might be a start:
In jvm land
(try
(portal.api/eval-str "(js/require \"mafs\")")
(catch Exception e <install deps for user or ask them to do so>))
If you wanted to vendor your npm deps, portal can resolve js files from the classpath 👍
@djblue I do specify deps.cljs
, could we pull them from there?
@djblue in clerk I have been building a custom JS bundle that includes everything, but this approach seems obviously easier to extend
(ev/with-let [!phase [0 0]]
(let [shifted (ev/with-params {:atom !phase :params [0]}
(fn [shift]
(((cube D) tanh) (- identity shift))))]
[:<>
[:pre `(pr-str @~!phase)]
(mafs/mafs
(mafs/cartesian)
(mafs/of-x shifted)
(mafs/inequality
{:y {:<= shifted :> cos} :color :blue})
(mafs/movable-point
{:atom !phase :constrain "horizontal"}))]))
the fn
trick worked great:
(p/register-viewer!
{:name ::mafs
:predicate (constantly true)
:component (fn [form]
(eval (list 'fn [] form)))})
Currently Portal doesn't look for deps.cljs, it could but I'm not sure how that would play with how shadow treats it
If you already have the code vendor'd:
;; in cljs land
(def mafs
(try
(js/require "./vendor.js")
(catch :default e (js/reauire "mafs"))))
my expectation was that any consumer of mafs.cljs will build a bundle with shadow, and that this file would trigger shadow into running npm install mafs
with the correct version;
https://github.com/mentat-collective/Mafs.cljs/blob/main/src/deps.cljs
and save the user from having to do it manually
same with mathbox.cljs, leva.cljs etc
Interesting, so with Portal you get the convenience of no bundles but the inconvenience of resolving npm deps 😆
(clicking to interact seems to also “begin filtering” always, not sure if that matters enough to figure out a way around! doesn’t seem to impact the animation at all)
Not sure if you are interested, but you have access to portal.ui.theme, which will automatically work with editor based themes
Also, would getting this working in calva notebooks be something you want? https://cljdoc.org/d/djblue/portal/0.40.0/doc/editors/vs-code/clojure-notebooks
yes, absolutely
that looks very powerful, and absolutely fits in with my goals here, of having these viewers come to the user wherever they are
It looks like it should be able to work as long as people have the portal.nrepl/wrap-notebook
nrepl middleware setup 🔥
https://github.com/djblue/portal/releases/tag/0.41.0 has all the changes so far to get things working 🎉
Also, not sure if this is important to you but Portal also works for the #C060SFCPR and it looks like emmy is a lot of cljc :thinking_face:
Tell me about this portal.nrepl/wrap-notebook
middleware?!?
By default, calva notebooks pass along edn from nrepl to the portal viewer so all the rich runtime data is gone (no datafy/nav, etc...). With this middleware, portal can detect if you are in a notebook, intercept the runtime value and pass along an id, then in the notebook viewer it can hookup portal to your runtime and everything works as a normal runtime connected portal.
The following bits are enabled with the middleware: • https://cljdoc.org/d/djblue/portal/0.40.0/doc/datafy-nav • First class object support • Runtime registered commands • Larger values which are harder for edn to serialize and parse • Better error rendering
I think once calva notebooks support clojure-lsp, they are gonna be a top tier development environment
(def ^:private theme-mapping
{:fg ::c/text
:bg ::background
:line-color ::c/border
:red ::c/exception
:orange ::c/uri
:green ::c/string
:blue ::c/namespace
:indigo ::c/boolean
:violet ::c/package
:pink ::c/number
:yellow ::c/tag})
(defn- ->style [theme]
(str
".MafsView {"
(str/join
";"
(reduce-kv
(fn [out mafs portal]
(conj out (str "--mafs-" (name mafs) ": " (get theme portal))))
[]
theme-mapping))
"}"))
I really love this
Added the wrap-notebook
middleware and I'm trying out the Clojure Notebook thing... very cool! Seems it selects Portal rendering by default? (good)
One downside seems to be that if you have RCFs -- (comment ...)
blocks -- in your file and you tell the Notebook to "Run All", it evaluates the contents of those RCFs as well as all the top-level forms... which is kinda dangerous (given some of the code I have in RCFs!). It doesn't look like there's even a way to visually distinguish regular top-level forms from the contents of RCFs?
Is the Notebook format just fundamentally incompatible with the RCF-based approach?
(and is there a better channel to ask about this?)
The Calva integration was mostly handled by @U02EMBDU2JU so he probably knows more about the details / limitations
I think the #CBE668G4R channel might be a good place to have this convo but I'm also cool if we continue it here 👌
Cool, thanks. I remember seeing some discussions about it but couldn't remember where...
I feel like https://github.com/BetterThanTomorrow/calva/blob/published/src/NotebookProvider.ts#L171-L173 could be updated to ignore forms from comments :thinking_face:
I think when the parser splits apart the comment form into multiple cells, it might be able to mark them as special to filter them out in this for loop. Then, the only method of evaluation would be eval'ing the cell alone.
I'm not at home right now so I can't link to it but there should be a github discussion
on this in the calva repo
https://github.com/BetterThanTomorrow/calva/discussions/1825 -- Thanks, @U02EMBDU2JU!
The parser already marks comment forms as special, so we can do the filtering. I’ll go ahead and do it, @U02EMBDU2JU. Holler if you see a reason not to do this.
Having refreshed my memory -- since I participated quite a bit in that thread -- it seems that the restrictions with RCFs are known about but unsolved, which certainly makes it dangerous for me to use at present 🙂 Issue 2210 needs to also skip RCFs in the run cells above and run cell & below commands. I'll add that note to the issue.
This VSIX should fix it https://output.circle-artifacts.com/output/job/7f57b12b-206f-444d-bbea-b622700cd2b4/artifacts/0/tmp/artifacts/calva-2.0.365-2210-rich-comment-notebook-run-all-9710d2c3.vsix Do you have time to test it, @U04V70XH6? Otherwise, I’ll just release it and we can fix any remaining issues later. The run cells above and below cases should be covered the way I did the filtering.
Sure, I can try it...
The bug was that evaluation of cells below a comment cell would not happen either. Now they do (unless they are comment cells).
I installed that but there still seems to be a bug in Cell and Below...
Trying to repro...
Ah, my bad, I had a defn-
inside a long RCF and couldn't tell in notebook view -- and it wasn't getting evaluated, but when I scrolled down I found real top-level forms were evaluated! So it does seem correct. Thank you!
I wish there was a way to visually tell that a cell is part of an RCF 😐
And ;; line comments
don't appear in notebook cells (which would have clued me into this being in an RCF).
It's got a ways to go... but it's certainly a lot safer to use now! 🙂
Calva’s feature for creating an RCF tucks an :rcf
at the closing bracket. That’s retained as a cell in the notebook.
Hmm, I don't see that:
Oh, @U0ETXRFEW You mean some specific feature in Calva that inserts an RCF actually inserts this?
(comment
:rcf)
I have never used that (since it's so easy to just type (comm
and tab-complete to accept the RCF suggestion)!Yeah, it’s a bit of a silly feature. More for people to discover RCFs as such. But it does work well if you’re inside some function and want to create (or jump to) an RCF below it.
For notebooks, it looks like https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts#L227https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts#L227 and I'm not seeing an official way to customize some of the styling :thinking_face:
Yeah I’d love to style them somehow. The best I’ve come up with is to show the (comment
and )
as cells but that seems weird as well 😞
And thanks @U0ETXRFEW for quickly implementing this. At some point, we might want to make run-all for RCF optional but off by default seems like a good safety feature.