This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-06
Channels
- # announcements (2)
- # babashka (22)
- # beginners (93)
- # calva (12)
- # cider (65)
- # clj-kondo (15)
- # cljdoc (5)
- # cljs-dev (4)
- # cljsrn (4)
- # clojure (65)
- # clojure-europe (2)
- # clojure-italy (1)
- # clojure-nl (1)
- # clojure-norway (1)
- # clojure-spec (40)
- # clojure-uk (7)
- # clojurescript (12)
- # conjure (1)
- # cursive (2)
- # data-science (13)
- # datomic (1)
- # dirac (12)
- # emacs (3)
- # figwheel-main (19)
- # ghostwheel (5)
- # helix (6)
- # kaocha (1)
- # leiningen (6)
- # news-and-articles (2)
- # off-topic (17)
- # pathom (5)
- # re-frame (59)
- # reitit (17)
- # restql (1)
- # shadow-cljs (31)
- # spacemacs (5)
- # spire (3)
- # sql (35)
@ray.stubbs @isak Within Clojure, the purpose of symbols is to provide bindings - names for values, often function values. Whereas, keywords provide identities. keywords evaluate to themselves, not something else (which, of course, symbols do). As a result, keywords are more data-like, which is exactly why they are in the language. And we want to use data as much as possible. This may help https://day8.github.io/re-frame/data-oriented-design/
Fundamentally, we want the code which dispatches an event, or subscribes to a query, to have no clue about the eventual implementation (no coupling) . keywords are pure data, and data is declarative by nature, which is a good thing.
it makes it harder to do things like code splitting tho if you have keywords used ad-hoc everywhere without requiring the ns that implements the event or sub you're using
I think it's fine to have a use a symbol that refers to an identity which is used throughout the system as data
> it makes it harder to do things like code splitting tho if you have keywords used ad-hoc everywhere without requiring the ns that implements the event or sub you're using I've never had this problem, probably because we don't need to code split. So, I'll have to take your word that its a problem. Having said that, we aren't very "adhoc" about the keywords we use. Doing anything "adhoc" is ultimately a problem when you later need more structure.
> I think it's fine to have a use a symbol that refers to an identity which is used throughout the system as data
I can't parse this sentence. Perhaps because I don't consider symbols as an identity. They are a name which is bound to something. When you evaluate them, you get the thing they are bound to. If they are good identities, why does Clojure have keywords? As I understand it, because keywords evaluate to themselves, making them the perfect identities, a bit like how 4
evaluates to 4
, except keywords are more descriptive. And, that, as I understand it, is why we have keywords in the language.
I think lilactown meant something like (def do-stuff-event-id :events/do-stuff)
so that later you could require the ns that contains do-stuff-event-id
.
Anyways, the good news is that all opinions work because re-frame
doesn't actually demand that you use keywords.
You can even do this if you want:
(reg-event-db
[:a 'vector "if you want"] ;; <-- not a keyword
(fn [db e]
...))
Does it work with sets as well? :) Making dispatch on sets or maps would be fun.
Then:
(dispatch [[:a 'vector "if you want"] <other>])
Each to their own, but I, personally, won't be doing that
And I won't be using symbols, because for me it creates an unnecessary, unwelcome coupling. But, hey, I've been wrong before.
Hi. I'm a beginner in re-frame. I tried to create a project using lein new re-frame
. When I ran the application using lein dev
, it gets rendered but "shadow-cljs connection closed" pops up as soon as the page gets loaded. None of the events work. I git cloned another re-frame project and ran it. It is working fine. I compared the project.clj files and there is no :cljsbuild key in my project. Is that the reason?
If you're using shadow-cljs, then you don't care what project.clj
contains since shadow-cljs doesn't use that file. That file will be used if you use shadow-cljs via lein, but then :cljsbuild
should not be present AFAIK because only shadow-cljs should build CLJS files.
Thanks. What should I do next? Even a button click doesn't work now. Shadow-cljs connection gets closed as soon as the page gets loaded.
it should be connecting to localhost:9630
which would be the shadow-cljs main server. did you maybe block that in your firewall or so?
IG that's the problem. It says Can't establish connection to the server at localhost:9630
what do you get when you open http://localhost:9630 in your browser?
you are accessing this all locally I presume? or is running in some of container/virtual machine?
yes, I'm accessing it locally. When I open http://localhost:9630, it is blank.
what does it say on startup? it should be logging something like shadow-cljs - server version: <version> running at
Just this:
The character encoding of the plain text document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the file needs to be declared in the transfer protocol or file needs to use a byte order mark as an encoding signature.
Now I get this error in the terminal:
ERROR: UT005071: Undertow request failed HttpServerExchange{ GET /ws/worker/app/550c2156-ce6d-45e8-bf19-f1cd4390a1ee/ca23dabe-004a-
4ae5-bc5c-60944bd623c5/browser}
Caused by: java.lang.OutOfMemoryError: Java heap space from the UncaughtExceptionHandler in thread "dev-http-file-watch"
which directory do you use as your :dev-http
? does that have like a billion files in it?
hmm that should be enough. how much is actually free though? the file-watch really shouldn't consume that much memory.
you can set :jvm-opts ["-Xmx512M"]
to constrain the memory use of shadow-cljs down to 512mb which is usually enough
hmm that should be fine. some older versions consumed more memory than they should but that has long been fixed.
I cloned another git repo that uses figwheel. None of these errors came with that. It is working fine. Is figwheel an alternate to shadow-cljs?
Cool. How do I create a re-frame app with figwheel and not shadow-cljs? The documentation says the base template comes with shadow-cljs.
@mikethompson So if I understand right what you're saying, you wouldn't recommend this:
;; a.cljs
(ns a)
(reg-event-db
::my-handler
(fn [db] ...))
;; b.cljs
(ns b
(:require [a]))
(dispatch [::a/my-handler ...])
...because this introduces a coupling between the two namespaces a and b, and the code in namespace b which dispatches the event should have no clue about the handler registered in namespace a. Did I understand right?
I'd be really interested to hear more why the coupling and the need to require the namespace is considered unwelcome. This is the pattern I've used in the app I've been building and it has been working very nicely for me.I've been using this pattern for about 3 years now. For me, it works better than manually assigning namespaces that don't correspond to any actual namespaces.
My read of his explanation is that that’s ok, but not required? I could be totally off base, but I’ve done that, and I’ve also done this:
(dispatch [:a/my-handler]) ;; <-- no double colon
I find it really useful that both of these patterns are supported…::a/x
- here ::a
is replaced with the namespace that you requried, it's an alias.
:a/x
- here a
is the namespace. It's not an alias.
Yep, I’m aware, but :a/my-handler
doesn’t need you to require the namespace in question, which is useful at times vs ::a/my-handler
which does…
Yep, but you'll have to also call (reg-event-db :a/my-handler ...)
instead of (reg-event-db ::my-handler ...)
. Different approaches, both work, each has pros and cons.
I think you need discipline when you refer to events from other namespace. Something like private/public or local/global events or some notions of events might be shared to other namespaces. The reason is you might be less strict on change for local events. I usually have 3 contexts in my apps: components (where events/subs are fully qualified and defined in the same file, and events only concerns the views defined on that file, components are meant to be shared across all panels), global events/subs (non qualified keywords probably shared by all panels), panels events (fully qualified keys as well).
The trick starts when you have to share events between panels, and I defaulted to global events for exchanging information.
I served me well for the last year and half, but maybe I am missing something.