This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (6)
- # beginners (61)
- # boot (1)
- # chestnut (1)
- # cider (18)
- # cljs-dev (1)
- # cljsrn (3)
- # clojure (176)
- # clojure-android (8)
- # clojure-germany (12)
- # clojure-russia (4)
- # clojure-spec (7)
- # clojure-uk (5)
- # clojurescript (28)
- # css (10)
- # cursive (36)
- # datomic (7)
- # devcards (1)
- # docs (8)
- # emacs (17)
- # fulcro (29)
- # hoplon (28)
- # lein-figwheel (3)
- # leiningen (37)
- # lumo (1)
- # off-topic (54)
- # om (6)
- # re-frame (2)
- # reitit (7)
- # ring-swagger (23)
- # shadow-cljs (115)
- # sql (10)
- # uncomplicate (1)
- # unrepl (24)
Yeah I tested out my reader conditionals in a chestnut project and they worked in both runtimes.
I just never actually packaged a pure cljc project. Does the default lein template work fine for both runtimes?
https://github.com/stuartsierra/component looks like a minimal example of a (not quite pure) .cljc library
I should have looked at Sierra's components. It never clicked that I had them on the back and the front with the same namespace. It looks like this library has a project.clj a lot like mine as well. Thanks much!
hey, has anyone successfully used a go block in clojure >=1.7.0? i am having trouble with it not closing over its scope properly, so
(let [c (chan)] (go (prn (<! c)))) gets me
Unable to resolve var: c
the weird thing about that block of code is that core.async should treat it as a noop returning a channel that never delivers
i mean, there’s a more complicated version of that code, which also fails with the same issue, which actually does do a real hello world with the channels, in the tutorial
but i stripped it down to just that being enough for it to fail with the same issue
Clojure 1.9.0 +user=> (require '[clojure.core.async :as > :refer [go chan <!]]) nil +user=> (let [c (chan)] (go (prn (<! c)))) #object[clojure.core.async.impl.channels.ManyToManyChannel 0x1e5e2e06 "[email protected]"]
i accidentally had written a lot of actually working code before realizing this issue, because i had
defed a channel with the same name as i was using inside go blocks
this is straight up clojure + core.async running from a custom uberjar (project here https://github.com/noisesmith/bench - I just run lein uberjar then make the jar an executable)
option-bot.core> (require '[clojure.core.async :as > :refer [go chan <!]]) nil option-bot.core> (let [c (chan)] (go (prn (<! c)))) ExceptionInfo Could not resolve var: c clojure.core/ex-info (core.clj:4739)
sometimes things can get wonky with core.async and lein caches when versions of things change, in my experience
are you using any weird plugins? is there a chance that
lein deps :tree shows a version conflict that would give you the wrong version of core.async?
[clojure-complete "0.2.4" :exclusions [[org.clojure/clojure]]] [org.clojure/clojure "1.9.0"] [org.clojure/core.specs.alpha "0.1.24"] [org.clojure/spec.alpha "0.1.143"] [org.clojure/core.async "0.3.465"] [org.clojure/tools.analyzer.jvm "0.7.0"] [org.clojure/core.memoize "0.5.9"] [org.clojure/core.cache "0.6.5"] [org.clojure/data.priority-map "0.0.7"] [org.clojure/tools.analyzer "0.6.9"] [org.clojure/tools.reader "1.0.0-beta4"] [org.ow2.asm/asm-all "4.2"] [org.clojure/tools.nrepl "0.2.12" :exclusions [[org.clojure/clojure]]] [self/ib "9.73.01-SNAPSHOT"]
i mean, there is one custom java api library, but that shouldn’t do anything like this, i wouldn’t think
so I guess the answer to "are you using any weird plugins" is "we didn't realize how weird cider is"
Tooling, the cause of, and solution to, every problem we have when programming clojure.
and i thought every issue i had with it had been fixed now that cider could pass its plugin versions into lein
i was like “there’s no way this has actually been broken for the last three years, right?”
what’s a good way to represent a record that requires multiple api calls (and callbacks) to be fully realized?
but then also it kind of has a price, right? but to get the price, that’s the result of some other call
a good functional technique is to put the price and the time in there together, and make sure all price queries are explicit about time windows they accept
and sure, you can put a future in, you could also have a function that returns a future that returns a new instance of your record (with a newer time stamp) when realized
oh and then i’d have some fn
get-price (or maybe use
conform) and it’d get me the price that was cached if it was fresh enough
also, you could use a TTL cache (clojure core.cache provides this) and retrieve the price from the cache
the nice thing with core.cache is that it doesn't force a specific storage - it just takes a hash-map and returns a new one, and you can put this in a local that propagates via recur, or put it in a ref, or an atom, or even a proper db if you serialize it right - it should just work
https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readFully(byte) <-- where is this readFully contract definedd ?
i basically just hacked together some bullshit that worked for now with promises/futures
I'm trying to read 10k bytes from a file, and I don't wnat to loop; I want to make on3 call and have java read it for me
if you know it's always 10k bytes or less why not pass a 10k byte-array to the read method?
here's DataInput readFully https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readFully(byte)
it's saying "look at the method foo on class bar" - it's just phrasing it kind of weird
now i’m trying to go back and use core.async channels to model the continuous updates
the core.cache protocols do all the cache ttl logic, and transit handles the serialization, and mongo the storage
regarding mongo - I wouldn't necessarily recommend for a new project, it was inherited as part of the team expertise if that makes any sense
yeah, core.cache also does simple in-memory cache with ttl which is what I'm sure you actually want - for those mongo caches I'm measuring the ttl in days not minutes
like, price data, seconds, but the actual existence of the contracts i’m interested in
also the simplest solution would be to use an atom for your cache, but if you start to hit contention slowdowns you could use multiple refs instead of an atom with multiple keys in it
oh, instead of handing out refs like candy and then trying to update them in place
i guess i should make a function that is like
get-contract and then have that access the cache or synthesize a new contract info object
using lots of refs does work (and performs better under heavy write load) it's just a more complex design than a hash-map in an atom with a key for each "thing"
i have been thinking it would be kind of neat to have an agent for every contract i’m keeping track of
caching logic is notoriously tricky to get right, and core.cache helps a lot with that; I was surprised - I did a big cache with a lot of features built on core.cache and it worked without a hitch after the trivial data bugs were fixed
@anisoptera I'm trying to work out what this would require - it's a lot simpler to add keys on demand to an atom, but you could also hypothetically manage multiple refs but then you have the question of what tracks these on-demand refs and then I'm like "refs inside an atom" and no that is insanity
i guess for right now, it’s not a big deal, i can just have a single atom with a map
wow, that caching lib is great, just implementing a really naive caching layer in my calls was enough to massively reduce the number of API roundtrips
is there a way of writing call (.readInt ...) on this data-input-stream 10 times that is better than loop-recur ? (note that .readInt changes the 'pointer' in the file buffer, so we need to be careful with regards to laziness
Hi everyone. I’m using a
chestnut template and I have this simple route
whenever I try to post to this route from FE (cljs / re-frame), it sends
(defn home-routes [endpoint] (routes (POST "/api/get-name" _ get-name) (resources "/") (not-found "<h1>Page hello</h1>")))
OPTIONStype request first and it fails straight away with
404and then the
POSTis not being sent afterwards. When I manually add
it returns with
(OPTIONS "/api/get-name" _ get-name) (POST "/api/get-name" _ get-name)
POSTis not being sent afterwards
Your browser is sending OPTION request to make sure the planned POST request is acceptable. This may help you understand option request: https://developer.mozilla.org/de/docs/Web/HTTP/Methods/OPTIONS Check the network/console log of your browser to see which headers/methods/origins in the options request are asked for and then make sure your OPTIONS endpoint in your backend sends a valid option response. I think for most cases there are ring-middlewares to do this
Hi all. I have a spec question. I think I know the answer, but I want to confirm. If I'm spec'ing a map, and the keyword is :fooBar, then the spec must have the same name, correct? Actually, it would be namespaces, so ::fooBar, correct? I need to know if I can remap a keyword to a spec with a different name, or if that defeats the purpose of readability.
you can spec un-namespaced keys with :req-un and :opt-un https://clojure.org/guides/spec
Well, it’s not actually the namespacing. I’m fine with that part. I’m asking if I could have a
::foo-bar spec for the
Or, suppose you have 2 different API returns in the same domain, but that have the same keyword. Such as
:results but where the spec for each of those is different.
I'm looking for a few more folks to share their workflow in detail over at ClojureVerse: https://clojureverse.org/t/share-the-nitty-gritty-details-of-your-clojure-workflow/1208 Lots of great productivity hacks both big and small. Both Clojure beginners and experienced devs seem to be getting a lot out of it.
@taylor thanks for that answer. What would be the best way to spec data where the same keyword is used in different ways? For example, if I’m searching for books and music, both might return data with ‘results’ in it. But the shape of those results will be different.
::results actually need to point to 2 different specs, but the keywords still need to match the data they are based on.
@jmckitrick is there anything else in that map that indicates whether it’s a book or music? if so, maybe you could use
(s/def :my/result int?) (s/def :your/result pos-int?) (s/def ::test-spec-1 (s/keys :req-un [:my/result])) (s/def ::test-spec-2 (s/keys :req-un [:your/result]))
Well, I’m about to pitch my CTO on Clojure and spec, and we consume a lot of XML API’s. I’d like to know definitively how they relate, and if spec is an advantage here or not.
@jmckitrick I don't think there's much advantage, you could spec those XML APIs, and generate clojure.data.xml data structures automatically from them, to ensure that you have high coverage of the various data shapes that could be thrown at you from those APIs.
Spec is really "one layer down" from application APIs, and is more centered around function APIs.
I’m trying to talk a Scala CTO into allowing some Clojure pilot projects. A big part of the argument is what spec brings to the table.
When you say "consume a lot of XML APIs" do you mean you POST XML to them or you get XML responses back? In either case you could convert from/to a Clojure data structure and spec validate that Clojure data structure.
One of the reasons we initially tried Scala was that we had a problem that involved reading a SQL DB and generating XML to POST to a search engine -- and Scala has XML literals native in the language.
It will be a mix of both. I want to demo the worst-case scenario, even if we end up working with JSON.
When we switched to Clojure, we used Hiccup to generate XML and that just transforms Clojure data structures so those could, in theory, be spec'd.
Nice. I think we want to demo how we can consume changing API’s in Clojure more easily than in Scala.
@seancorfield Oh really? We've been using clojure.data.xml internally for docbook stuff & it's been fairly good.
clojure.data.xml in one place for a simple XML API response and also with
clojure.data.zip.xml in another place for parsing a complex XML document -- lots of manual code mapping from the XML structure to the Clojure data structure we want.
I didn't use it for xml, but https://github.com/halgari/odin/ had some nice helpers for xml, and might be a suitable XSLT-like tool.
recently I made a toy clojure program that plays the wikipedia philosophy game (as a demo of a debugging library I wrote) and tree-seq plus clojure.xml was good enough for the little dumb thing I was doing https://github.com/noisesmith/philoseek
We have lots of stuff like
(->boolean (or (zx/xml1-> node :required zx/text) false)) and
(->long (or (zx/attr node :minimum) 0)) and what is basically a custom recursive descent parser for the XML format 😞
well when you posted it initially it didnt have such a big picture, it’s just when flowthing posts it lol
Though in the spirit of full disclosure, I wouldn’t call that library exactly “battle-tested”… I just wanted to see whether you can write XSLT with parentheses instead of angle brackets, more or less. 😛
I could always turn off previews from http://github.com but the summary is often useful (even if the picture not so much)