This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-11
Channels
- # adventofcode (8)
- # announcements (1)
- # arachne (23)
- # beginners (146)
- # boot (4)
- # calva (2)
- # cider (48)
- # cljs-dev (17)
- # clojure (214)
- # clojure-austin (2)
- # clojure-berlin (1)
- # clojure-europe (9)
- # clojure-italy (5)
- # clojure-nl (2)
- # clojure-sanfrancisco (2)
- # clojure-spec (124)
- # clojure-uk (67)
- # clojured (3)
- # clojurescript (95)
- # community-development (7)
- # cursive (68)
- # data-science (1)
- # datomic (80)
- # emacs (19)
- # figwheel (3)
- # figwheel-main (5)
- # fulcro (61)
- # javascript (2)
- # kaocha (1)
- # off-topic (25)
- # pathom (21)
- # pedestal (1)
- # perun (4)
- # reitit (11)
- # ring-swagger (2)
- # shadow-cljs (55)
- # spacemacs (4)
- # sql (8)
- # test-check (16)
- # tools-deps (2)
- # vim (13)
- # yada (4)
I have a text file I want to use as input. I can't open this file in Javascript without getting cross origin request errors. Is there an easy way I can get the contents of this text file into a variable, so I can continue rapid development, without having to wory about the cross origin request errors?
So I’d assume we are talking clojurescript now. I think your best bet is either by serving it from your computer OR adding a file field to your page
If you are serving it from your computer, you must correctly set the cross origin request headers
So I've setup a webserver with http-kit
which serves my html file. This html file also includes my clojurescript code which I compile using lein-cljsbuild
. How would I go about adding a javascript library which doesn't have a clojurescript wrapper to my project so that I can use it in my clojurescript file?
@nicholas.jaunsen there's lots of ways to skin that cat. A main one is the "foreign libs" route.(https://clojurescript.org/reference/packaging-foreign-deps) There's various mechanisms to try to integrate with npm too - some ship with core and some tools, like shadow-cljs is well known for wrangling npm deps for cljs.
But the old school "add a script tag to your html file" works too. You just have to make sure that you're taking care of externs: https://clojurescript.org/guides/externs
You may want to hunt down a larger example project that uses http-kit
, to see how things are put together. If you have most experience with a traditional LAMP stack, then yogthos's luminus framework (collection of libs) is a great jump off point: http://www.luminusweb.net/docs/clojurescript.md
here's an "http-kit adapter" for luminus, for pointers on how http-kit would fit into the luminus framework https://github.com/luminus-framework/luminus-http-kit
Well, I was hoping luminus docs had more examples of leveraging foreign js libs. Looks like the main docs are using mostly packaged things, per http://www.luminusweb.net/docs#the_project_file (see the webjars stuff)
But in any case, if you're leveraging server side framework like luminus over something like http-kit, you'll often be defining the delivery of your 3rd party js assets in the server-side logic, using script tags in your hiccup forms or something like that. Whereas, if you're going the mostly SPA route (which you can still serve up from http-kit) then folks usually stick to wrapping js libs as cljs packages so that deps are available to code via native cljs :require
dep resolution (rather than via interop calls).
I think I posted this to the wrong channel (it’s just vanilla compjure, not compojure-api), so I am cross-posting here (I hope that is okay)
I'm trying to commit to Running with Scissors.... I am curious how people structure their projects to bring in repl tools they always use, repl tools that are project specific, and/or preserving repl explorations
right now I have a src
dir and a siderail
dir with a user.clj
in it, but that file is getting kind of wild and unruly
for repl explorations, I like having multiple forms in a file like #_(fire-missiles)
- that can be in the actual source, or a test, or a dedicated file for repl explorations
bonus, having a multi line version
#_
(fire-missiles)
makes it easier to use with editor integrations or even copy/pasteI think i've heard @hiredman keeps around a lot of history. I'd be interested to hear his approach if he has time
also if you use the nrepl terminal UI, all your history is in a file in the top level of the project .nrepl_history
you can copy paste from that
if CIDER / fireplace etc. don't have that, it would be a trivial feature to implement...
yeah, not surprised at all :D
my personal ~/src/scratch.clj is 9kloc right now, and I have another for work related odds and ends
I have the same for every project. It‘s in the project root and is something like „my repl history - the good parts“
yeah, and a good scratch file is very stream of consciousness, not much going back and editing, lots of duplicaction
a single scratch file seems much more of a better idea than my hundreds of randomly named, randomly placed snippet files I can never find
For users of reagent, a question, assuming @name
becomes a primitive JS string, how does Reagent know that a component used an atom? Does it measure/snapshot check which atom has been deref on first render?
@raymond.w.ko the r/atom code checks for surrounding context when you deref, and registers itself with the template if it finds one
Wow, thanks 🙂
lol. although i'm starting to think that's not the most relevant line of code ... maybe the add watchers part. either way it just tracks who is watching it
I was wondering that since [f]
(a vector consisting of 1 function) doesn't change between renders, how does it "know" it has to re-render...
if you look at the IReset protocol underneath that, when the value is changed it notifies watches
so its a bit of bookkeeping of writing down who is watching and when the value changes let those watchers know
and if you chase that around a bit you end up in
(defn- rea-enqueue [r]
(when (nil? rea-queue)
(set! rea-queue (array))
(batch/schedule))
(.push rea-queue r))
which is what ultimately runs on every watching component. it gets scheduled to rerenderthe other thing to remember: every reagent component instance gets converted to a React component instance with it's own state and lifecycle
s [f]
looks like a vector with a function that doesn't change, but when it gets rendered, it gets converted to a stateful thing. so when the ratom inside it changes, it triggers a re-render inside the React component instance
the vector is a template that the driver function uses to create the component right?
Like Reagent sort of maps [f] to a React component and the deref marks this React component dirty?
and that component then gets registered for watching the ratom
the deref marks the component as something to update if the ratom is dirty
correct @raymond.w.ko
In my mental model, a swap!
triggers it, rather than a deref... Then the diff happens on the React side and any dependent components get updated. Right @lilactown?
swap!
causes the ratom to look up any components that have registered them selves, and then the ratom tells them to eventually forceUpdate
@john that seems to make more sense.
yeah sorry, I misread your message wrong @raymond.w.ko
reset!
/ swap!
tells the ratom to look up any associated components and start triggering updates.
Okay, thanks all, I think I understand enough to use it confidently. I was worried that it wouldn't get updates.
This still seems like magic to me 😣
no more magical than React is 😛 but perhaps with some idioms that are not as common
The lifecycle stuff is where the magic turns into debt, imo. But perhaps the new hooks stuff will smooth that stuff over.
if there was a way to do componentDidCatch, I'd never have to use React classes again I think
how do you print a large data structure? seems like at some point (around 100 elements or so) I just get [el el el ...]
@nickstares0 clojure.pprint/pprint and clojure.pprint/print-table both work great, depending on context
Howdy! I get errors when i run "lein cljsbuild auto" and not sure how to troubleshoot
user=> (clojure.pprint/print-table (map #(zipmap [:a :b :c :d] (repeat %)) (range 10)))
| :a | :b | :c | :d |
|----+----+----+----|
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 |
| 6 | 6 | 6 | 6 |
| 7 | 7 | 7 | 7 |
| 8 | 8 | 8 | 8 |
| 9 | 9 | 9 | 9 |
nil
wow thats pretty neat!
doesn't work for the vector i'm using! I still get ... at the end
slack won't let me post the whole thing but the end is
(with-out-str (clojure.pprint/pprint (converge 200 2)))
[
{:state-counts {:a 80, :b 120}, :period 85}\n {:state-counts {:a 69, :b 131}, :period 86}\n {:state-counts {:a 73, :b 127}, :period 87}\n {:state-counts {:a 77, :b 123}, :period 88}\n {:state-counts {:a 89, :b 111}, :period 89}\n {:state-counts {:a 78, :b 122}, :period 90}\n {:state-counts {:a 72, :b 128}, :period 91}\n {:state-counts {:a 73, :b 127}, :period 92}\n {:state-counts {:a 73, :b 127}, :period 93}\n {:state-counts {:a 73, :b 127}, :period 94}\n {:state-counts {:a 74, :b 126}, :period 95}\n {:state-counts {:a 64, :b 136}, :period 96}\n {:state-counts {:a 63, :b 137}, :period 97}\n {:state-counts {:a 78, :b 122}, :period 98}\n ...]\n"
oh! the ...
is the problem? that's caused by *print-length*
iirc (there's some other related vars you can rebind). I misinterpreted your question
Yes! I'm trying to write a large vector to a file and all of the tutorials say to use pprint or pt-str
(with-open [w ( "values.edn")]
(binding [*out* w]
(pr-str (converge 100 2))))
user=> (apropos #"^\*print.*")
(clojure.core/*print-dup* clojure.core/*print-length* clojure.core/*print-level* clojure.core/*print-meta* clojure.core/*print-namespace-maps* clojure.core/*print-readably* clojure.pprint/*print-base* clojure.pprint/*print-miser-width* clojure.pprint/*print-pprint-dispatch* clojure.pprint/*print-pretty* clojure.pprint/*print-radix* clojure.pprint/*print-right-margin* clojure.pprint/*print-suppress-namespaces*)
- *print-length*
is the main one, but there's some others that have effect tooyou can set it to nil to allow arbitrary depth
awesome, so like this?
(def ^:dynamic *print-length* nil)
Or should I write over the one in clojure.core
?
with dynamic vars, you can use set!
or binding
(ins)user=> (set! *print-length* 5)
5
(ins)user=> (range)
(0 1 2 3 4 ...)
(ins)user=> (binding [*print-length* nil] (pr-str (range 20)))
"(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)"
binding is better in general, as it avoids the spooky action of global settings
great, i'll use the binding
yeah, for your usage (binding [...] (with-out-str ...))
is likely ideal
just be sure anything lazy is forced before leaving the with-out-str block
Yeah, I think the laziness is my problem. I read that doall
will force strict evaluation but that's not doing the trick
doall works on a single level only
but println / prn / pprint will all force the whole input
but they also obey *print-length*
, which isn't about laziness, it's about how printing is done (which interacts with laziness but is distinct)
I think I understand the distinction
(with-out-str (binding [*print-length* nil] (clojure.pprint/pprint (doall (converge 200 2)))))
but I would expect that to work
(defn converge [n s]
"Creates a population of n agents with s possible states and runs a period of interaction
on that population until all agents have the same state. Returns a
vector of maps, where each map contains the count of agents after
each period, e.g. [{:state-counts {:a 1 :b 19} :period 0}
{:state-counts {:a 0 :b 20} :period 1}]"
(loop [period 0
population (population n s)
results (vector (-> (run-period population s)
(assoc :period period)))]
(if (some #(= % (count population)) (vals (:state-counts (peek results))))
results
(recur (inc period) population (conj results (-> (run-period population s)
(assoc :period period)))))))
you don't need doall inside pprint - pprint will eagerly realize the inside as long as *print-length*
is nil; if *print-length*
isn't nil, it will only force the top level, and no children
and converge itself is not lazy, so there's no point in doall over that - it's the children of converge that might be lazy
Ok, 3 steps of indirection down the children of converge
use a fn that returns a lazy sequence via repeatedly
you could do a tree operation to recursively force the input, but the printing code will already force the input up to the limits of *print-length*
- hope I'm not repeating myself too much here, want to make sure my point is communicated properly
Yeah, I think I just need to force the input at the bottom leaf of the tree since there is only one lazy seq
Or rather only one place where lazy seqs are introduced
(defn population [n s]
"Creates a population of n agents that can each have s possible states"
(repeatedly n (partial new-agent s)))
Thank you so much for helping with all of this as I chase down a rabbit hole...
Is there a better way to put n elements into a collection besides repeatedly
? seems like I am not using that fn as intended
you can use (vec (repeatedly ...))
if laziness isn't desirable, also you might consider replacing (partial f arg)
with #(f arg)
for conciseness / readability
Awesome, that did the trick. Thank you so much!!
and thanks for the readability tip, seems obvious in retrospect 😛
I wish we had one or two character versions of identity
, comp
, partial
apply
etc. - so useful, but if they are more than two characters they add some noise...
(of course any of us can define our own aliases for all those functions...)
oh and complement
too
ooh, complement
is a good one that I forget to use
partial
and compliment
are on the long side
especially when you can ‘fake’ partial by #(fun arg1 arg2 %1 %2 ...)
and complement
is (comp not f)
few characters saving!
@kbosompem I've found it useful to stop the auto run, run lein clean
then lein cljsbuild once
if I discover a nontrivial error
@noisesmith my lein clean reports no errors and only empties the resource folder but not the target
C:\Sources\moose>lein cljsbuild once Compiling ClojureScript... Compiling ["resources/public/js/app.js"] from ["src/cljs"]... Compiling ["resources/public/js/app.js"] failed. clojure.lang.ExceptionInfo: failed compiling file:resources\public\js\out\cljs\core.cljs {:file #object[java.io.File 0x2bfb583b "resources\\public\\js\\out\\cljs\\core.cljs"]} at cljs.compiler$compile_file$fn__3702.invoke(compiler.cljc:1562)
then you might want to update your clean-targets - if you customize where the targets go, clean needs to be updated to stay in sync
in the mean time you can manually remove your target file(s), the point of running clean is that continuous auto-compiles can easily lead to inconsistent state reflecting a transient situation or a bug you already fixed
@noisesmith what i really need is a simple example of a re-frame app with a clojure backend
I'm not sure what's most up to date / recommended today, but iirc luminus has a lot of good examples and docs http://www.luminusweb.net/
chestnut is also a pretty solid template https://github.com/plexus/chestnut
@noisesmith luminus was overwhelming. base template's project.clj had 70 lines
how can I compare keys from a list of maps if the entire list of maps, the maps has the same keys?
reduce-kv maybe?
what kind of comparison? clojure.data/diff
is great for comparing any two maps with the same keys
I'm testing if every map in a list of maps has the same keys of a comparison map
(apply = (map #(select-keys % [:my :keys]) inputs))
same keys or same contents?
same keys
`(apply = (map keys inputs))`
oh - good call about using set
before comparing
thanks
> you want to assert that the set of keys from each map in a list are the same right?
(map (comp set keys))
falls out right there. and then you assert that everything in a list is the same
yeah it worked
I'm new to tests, trying to make some tests