This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-05-22
Channels
- # announcements (1)
- # beginners (109)
- # boot (2)
- # calva (26)
- # cider (6)
- # circleci (6)
- # cljsrn (3)
- # clojure (77)
- # clojure-dev (5)
- # clojure-europe (28)
- # clojure-finland (1)
- # clojure-hamburg (1)
- # clojure-italy (21)
- # clojure-japan (13)
- # clojure-nl (36)
- # clojure-spec (22)
- # clojure-sweden (4)
- # clojure-uk (105)
- # clojurescript (91)
- # community-development (8)
- # cursive (60)
- # datascript (3)
- # datomic (4)
- # emacs (33)
- # fulcro (19)
- # graalvm (38)
- # hoplon (4)
- # instaparse (1)
- # jobs (1)
- # leiningen (22)
- # off-topic (14)
- # pathom (2)
- # perun (4)
- # planck (5)
- # re-frame (10)
- # reagent (1)
- # reitit (11)
- # rum (11)
- # shadow-cljs (97)
- # tools-deps (82)
- # vim (53)
I’ve just started looking at clojurescript/react frameworks. A hard requirement is that we have a clojure backend; and I’d like to do SSR with isomorphic components. I’ve got basic SSR going with a clojure backend in rum; and it seems to work as advertised — however rum seems to be locked on a very old react implementation. We also have a FE designer who is writing some components in js/react that we’d like to operate with… and he’d like to be using the latest and greatest react. Has anyone got SSR going with reagent/re-frame but with a clj backend? Am I asking too much?
Or are there other frameworks that will do this?
@rickmoynihan There’s no official way to render Reagent on JVM, but it’s still possible to achieve, see http://yogthos.net/posts/2015-11-24-Serverside-Reagent.html though I’m not aware of anyone going this way
why not? Does everyone just do SPAs?
@rickmoynihan Other option is the library that I’m developing https://github.com/roman01la/uix, it’s based on latest React APIs and supports SSR on JVM. But keep in mind that it’s very much a work in progress, even though I’m using it in a project.
thanks this looks interesting
yep, SSR is overrated IMO
Well I think it would be very useful if it also incorporated a pattern for re-hydrating state API’s via a component oriented backend.
i.e. if components exist both on the client and server… and components can effectively have their own API
I know graphql etc is seen as a solution to some of this
but graphql is kinda annoying if you want to share clojure(script) types on front and backend. As it leads to artificially deep schemas.
When I compile this code:
(ns cljc.core
#?(:cljs (:require-macros [cljc.core :refer [foo]])))
#?(:clj
(defmacro foo [x]
`(do (println ~x) (println ~x))))
(foo 1)
the output looks very clean:
$ cat out/cljc/core.js
// Compiled by ClojureScript 1.10.520 {:target :nodejs}
1
1
goog.provide('cljc.core');
goog.require('cljs.core');
cljs.core.println.call(null,(1));
cljs.core.println.call(null,(1));
However, when I remove the #?(:clj ...)
condition, which is typically not present around macros in .cljc files, I get this:
$ cat out/cljc/core.js
// Compiled by ClojureScript 1.10.520 {:target :nodejs}
1
1
goog.provide('cljc.core');
goog.require('cljs.core');
var ret__4776__auto___545 = cljc.core.foo = (function cljc$core$foo(_AMPERSAND_form,_AMPERSAND_env,x){
return cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,(new cljs.core.List(null,new cljs.core.Symbol(null,"do","do",1686842252,null),null,(1),null)),(new cljs.core.List(null,cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,(new cljs.core.List(null,new cljs.core.Symbol("cljs.core","println","cljs.core/println",-331834442,null),null,(1),null)),(new cljs.core.List(null,x,null,(1),null))))),null,(1),null)),(new cljs.core.List(null,cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,(new cljs.core.List(null,new cljs.core.Symbol("cljs.core","println","cljs.core/println",-331834442,null),null,(1),null)),(new cljs.core.List(null,x,null,(1),null))))),null,(1),null)))));
});
cljc.core.foo.cljs$lang$macro = true;
cljs.core.println.call(null,(1));
cljs.core.println.call(null,(1));
So that cljc.core.foo
function is the runtime macro, that’s probably only used for self-hosted CLJS?I’m trying to understand why, when you don’t have the #?(:clj ...)
condition, CLJS doesn’t see the defmacro
call in the CLJS interpretation/phase of the .cljc file as a re-definition. That has probably already been resolved and isn’t around anymore in that stage?
@borkdude In self-hosted ClojureScript, when you require a macros namespace, the Vars in that namespace get put into a synthetically derived namespace name suffixed with $macros
. (That's part of how you can have, for example, a macro and function with the same name without any collisions.)
@mfikes oh right. so what’s the use of var ret__4776__auto___545 = cljc.core.foo
in the generated code above?
@borkdude It is related to the code generated for https://github.com/clojure/clojurescript/commit/3c0c775b8c731806765d425781d0bfd16c0d7f51
@mfikes but this code isn’t self-hosted, maybe can be omitted from “normal” programs? I don’t have a $macros
namespace
@borkdude Yeah, perhaps CLJS-2015 could even be revised to generate less code under self-hosted
@borkdude Are you saying that defmacro
could generate different code for JVM ClojureScript in the case that it happens to be used in JVM ClojureScript?
I guess we have https://clojure.atlassian.net/browse/CLJS-2636
@mfikes let’s just say that I don’t understand at all why the code at var ret__4776__auto___545 = cljc.core.foo
is needed in the cljc.core
namespace when compiling with regular CLJS (non-self-hosted)
@borkdude Is the question related to the use of defmacro
in ClojureScript code when using JVM ClojureScript?
yes. with #?(:clj ...)
(first example) you don’t get that code. why do I get it when I omit that conditional, and does it ever get used somewhere
I suppose what happens when you use defmacro
in a runtime namespace in ClojureScript code is undefined.
@mfikes I was interested to see your work re: supporting macros from cljs (chivorcam). one thing I was thinking about awhile back for maria was whether it would make sense to (via some evil, for-REPL-only means) let these self-hosted macros read functions that are accessible from their “non-macro” namespace, rather than something like defmacfn
. eg if we (defmacro x ...)
in cljs.user
, we define it in cljs.user$macros
, but perhaps also walk defmacro
and resolve names in the context of cljs.user
.
Yeah. I introduced defmacfn
because I was actually exploring the general concept "why can't we intermix macros and functions in ClojureScript" (JVM-based).
I think many of the arguments you see against it are incorrect, and part of chivorcam was to just try it and see empirically where things go, and let it stand as a proof that you can have them intermixed, apart from some leftover issues.
defmacfn
gets to the core of the grey area right away.
But, you are right, if you start off assuming that you are in self-hosted ClojureScript, then the notion that you can have intermixed macros and function (just like Clojure) is completely feasible (IMHO), because self-hosted ClojureScript behaves like Clojure in important ways.
It would be nice to say, "Not only can you intermix defmacro
and defn
in your ClojureScript namespaces, you don't even need support from the compiler to do it. You can just use a library. How do you like them Lisp apples?"
it seems.. possible? I’ve been using macrovich quite a bit, sometimes in .cljc namespaces where I don’t do any host interop and just want to define macros that I use within the same namespace
By the way, Replete ships Chivorcam, so it is possible to play with it in the limited way it works. Replete prompts you before enabling it, because it is a non-standard thing 🙂
I think that Rich could have defined ClojureScript as mixing macros and functions for that limited subset.
I would love to see what Rich's take on the whole thing is. I wouldn't be surprised if he said "yeah, we definitely could have mixed macros and functions for certain scenarios, but at the time we were trying to cleanly separate compile time and runtime, and the solution we ended up with is the pragmatic one that we could pull off at the time"
It is definitely an evergreen subject. And you often see responses regarding why it can't be done. With chivorcam
we have a better feel for the specific areas where the "why" arguments hold water.
Yeah, it might be good to precisely define that term, but to me the informal notion is the normal CloureScript namespaces you have that define functions that live on into runtime.
Oh, yeah, if you use defmacro
in a ClojureScript runtime namespace, one thing that also helps is that the Var constructor is eliminated.
(Or simply set :def-emits-var
false
as a compiler option in your favorite ClojureScript REPL.)
I end up with some detritus left over that it doesn't seem to eliminate:
(function(){var a=cljs.b.a=function(){return null};cljs.b.a.c=!0;return a})()
I wanted to create an Desktop Application with Clojurescript And Reagent --and react-- with Descjop template. This template has really strange cljsbuild format. But I want to import external libraries with Webpack. I can build and import my Webpack bundle result. This result can be included. But. I know, Reagent depends on cljsjs.react. And I know that I also have to exclude this dependency from Reagent. But I have to tell the Google Clouse that I have already a React Library in my project. If I didn’t make a mistake; :foreign-libs key is meant to be used for this purpose. But. I didn’t make this work. I have a dead-line for a simple prototype. Can someone tell me what is my mistake ? Thank you all.
This is my Electron App’s Console prints:
`
index.html:8 Uncaught ReferenceError: process is not defined
at index.html:8
(anonymous) @ index.html:8
index.html:9 Uncaught ReferenceError: process is not defined
at index.html:9
(anonymous) @ index.html:9
invariant.js:24 Uncaught ReferenceError: process is not defined
at invariant.js:24
(anonymous) @ invariant.js:24
warning.js:7 Uncaught ReferenceError: process is not defined
at warning.js:7
(anonymous) @ warning.js:7
canDefineProperty.js:5 Uncaught ReferenceError: process is not defined
at canDefineProperty.js:5
(anonymous) @ canDefineProperty.js:5
emptyObject.js:5 Uncaught ReferenceError: process is not defined
at emptyObject.js:5
(anonymous) @ emptyObject.js:5
ReactComponent.js:36 Uncaught ReferenceError: process is not defined
at ReactComponent.js:36
(anonymous) @ ReactComponent.js:36
ReactPropTypeLocationNames.js:5 Uncaught ReferenceError: process is not defined
at ReactPropTypeLocationNames.js:5
(anonymous) @ ReactPropTypeLocationNames.js:5
ReactDOMFactories.js:10 Uncaught ReferenceError: process is not defined
at createDOMFactory$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactDOMFactories (ReactDOMFactories.js:10)
at module$Users$sckn$projects$business$qulak$desktopnew$node_modules$fbjs$lib$mapObject.default (mapObject.js:11)
at ReactDOMFactories.js:16
createDOMFactory$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactDOMFactories @ ReactDOMFactories.js:10
module$Users$sckn$projects$business$qulak$desktopnew$node_modules$fbjs$lib$mapObject.default @ mapObject.js:11
(anonymous) @ ReactDOMFactories.js:16
ReactPropTypes.js:29 Uncaught ReferenceError: process is not defined
at createChainableTypeChecker$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactPropTypes (ReactPropTypes.js:29)
at createPrimitiveTypeChecker$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactPropTypes (ReactPropTypes.js:69)
at ReactPropTypes.js:17
createChainableTypeChecker$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactPropTypes @ ReactPropTypes.js:29
createPrimitiveTypeChecker$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactPropTypes @ ReactPropTypes.js:69
(anonymous) @ ReactPropTypes.js:17
React.js:30 Uncaught ReferenceError: process is not defined
at React.js:30
(anonymous) @ React.js:30
DOMProperty.js:54 Uncaught ReferenceError: process is not defined
at DOMProperty.js:54
(anonymous) @ DOMProperty.js:54
ReactDOMComponentTree.js:12 Uncaught TypeError: Cannot read property 'ID_ATTRIBUTE_NAME' of undefined
at ReactDOMComponentTree.js:12
(anonymous) @ ReactDOMComponentTree.js:12
EventPluginRegistry.js:64 Uncaught ReferenceError: process is not defined
at EventPluginRegistry.js:64
(anonymous) @ EventPluginRegistry.js:64
ReactErrorUtils.js:22 Uncaught ReferenceError: process is not defined
at ReactErrorUtils.js:22
(anonymous) @ ReactErrorUtils.js:22
EventPluginUtils.js:38 Uncaught ReferenceError: process is not defined
at EventPluginUtils.js:38
(anonymous) @ EventPluginUtils.js:38
EventPluginHub.js:37 Uncaught TypeError: Cannot read property 'injectEventPluginOrder' of undefined
at EventPluginHub.js:37
(anonymous) @ EventPluginHub.js:37
EventPropagators.js:17 Uncaught TypeError: Cannot read property 'getListener' of undefined
at EventPropagators.js:17
(anonymous) @ EventPropagators.js:17
SyntheticEvent.js:99 Uncaught ReferenceError: process is not defined
at SyntheticEvent.js:99
(anonymous) @ SyntheticEvent.js:99
SyntheticCompositionEvent.js:10 Uncaught TypeError: module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$SyntheticEvent.default.augmentClass is not a function
at SyntheticCompositionEvent.js:10
index.html:8 Uncaught ReferenceError: process is not defined
at index.html:8
(anonymous) @ index.html:8
index.html:9 Uncaught ReferenceError: process is not defined
at index.html:9
(anonymous) @ index.html:9
invariant.js:24 Uncaught ReferenceError: process is not defined
at invariant.js:24
(anonymous) @ invariant.js:24
warning.js:7 Uncaught ReferenceError: process is not defined
at warning.js:7
(anonymous) @ warning.js:7
canDefineProperty.js:5 Uncaught ReferenceError: process is not defined
at canDefineProperty.js:5
(anonymous) @ canDefineProperty.js:5
emptyObject.js:5 Uncaught ReferenceError: process is not defined
at emptyObject.js:5
(anonymous) @ emptyObject.js:5
ReactComponent.js:36 Uncaught ReferenceError: process is not defined
at ReactComponent.js:36
(anonymous) @ ReactComponent.js:36
ReactPropTypeLocationNames.js:5 Uncaught ReferenceError: process is not defined
at ReactPropTypeLocationNames.js:5
(anonymous) @ ReactPropTypeLocationNames.js:5
ReactDOMFactories.js:10 Uncaught ReferenceError: process is not defined
at createDOMFactory$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactDOMFactories (ReactDOMFactories.js:10)
at module$Users$sckn$projects$business$qulak$desktopnew$node_modules$fbjs$lib$mapObject.default (mapObject.js:11)
at ReactDOMFactories.js:16
createDOMFactory$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactDOMFactories @ ReactDOMFactories.js:10
module$Users$sckn$projects$business$qulak$desktopnew$node_modules$fbjs$lib$mapObject.default @ mapObject.js:11
(anonymous) @ ReactDOMFactories.js:16
ReactPropTypes.js:29 Uncaught ReferenceError: process is not defined
at createChainableTypeChecker$$module$Users$sckn$projects$business$qulak$desktopnew$node_modules$react$lib$ReactPropTypes (ReactPropTypes.js:29)
at
If you can post the source I sure that will make it easier for people to be able to help you. But this seems related to the issue you are having. https://github.com/electron/electron/issues/18139
I think I have to done this with my win Object. I have changed it like this;
(reset! *win* (BrowserWindow. (clj->js {:width 800 :height 600 :webPreferences {:nodeIntegration true}})))
@U5K8NTHEZ here is the source. I haven’t change it much. https://github.com/LeaveNhA/ElectronProblem
I’m all alone with my LTE Connection. I’m sorry for the delay. It’s still uploading.
@U5K8NTHEZ it is alive.
Shutdown your app.
run lein descjop-once-dev
search app/dev/js/cljsbuild-main.js
and make sure it has "nodeIntegration" somewhere in it. Then rerun the app
It looks like you have a stale compile from before you added that flag.
Also *var*
is a convention for dynamic variables. You should remove the earmuffs there.
Hopefully that is helpful.
@U5K8NTHEZ, I’m living in Turkey. It is nice to meet you. Thank you. One day, if you come to Turkey. Write to me.
Hey everyone, I just watched "Expeditious Code via Inference" by Mike Fikes (https://www.youtube.com/watch?v=tPnCtXrwvIw), and immediately went to my project to try it out. I'm on the latest version of shadow-cljs (2.8.37), which uses cljs version 1.10.520, but I'm not seeing all the type warnings that I would expect. Of the following forms:
(+ "a" 1)
(let [x "a"] (+ x 1))
(+ (fn [] 1) "a")
(#(+ % 1) "a")
((fn [x] (+ x 1)) "a")
Only the first three give me warnings. Is there no checking across function signature boundaries? Is there something I need to do to turn checking on? Is there any documentation I can read about what to expect and rely on? Is this relevant: https://clojurescript.org/reference/compile-time-type-checking?But, you don't otherwise, as the compiler doesn't know the type of the function argument x
. (It's not looking that you are calling it with a literal string, right there inline.)
If you are curious:
cljs.user=> (defn foo [x] (+ x 1))
#'cljs.user/foo
cljs.user=> (foo "a")
WARNING: Type mismatch calling foo: expected [number], got [string] instead at line 1 <cljs repl>
"a1"
This is produced using https://gist.github.com/mfikes/1e2341b48b882587500547f6ba19279d
which is the parameter type inference experiment I mentioned in the talk.@mfikes thanks for that link, that clears things up a ton. I was wondering why the unsolved problems (changing function dependencies) were mentioned so casually! Any idea if/when this will land in clojurescript? Thanks for your work on it!
I didn't realize it was quite so bleeding edge, this article (https://blog.klipse.tech//clojure/2019/05/20/type-inference-in-clojurescript.html) made it sound like a new feature
@jstaab Function return type inference was shipped in November https://clojurescript.org/news/2018-11-02-release#_function_return_type_inference
But general type inference has been in the compiler since about a year after it was first released.
of course, I started using cljs in earnest about that time, so I wasn't aware of the change
Yeah, the numeric type check warnings you referred to above are from 2013. They've been around for a while 🙂
SPAs are overrated 😜