This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-08
Channels
- # announcements (2)
- # beginners (75)
- # cider (2)
- # clj-kondo (8)
- # cljs-dev (4)
- # clojure (69)
- # clojure-europe (4)
- # clojure-nl (6)
- # clojure-uk (1)
- # clojurescript (17)
- # clojureverse-ops (1)
- # cursive (7)
- # lsp (7)
- # malli (10)
- # missionary (2)
- # off-topic (16)
- # pathom (4)
- # polylith (5)
- # portkey (1)
- # reitit (4)
- # rewrite-clj (1)
- # shadow-cljs (5)
- # spacemacs (3)
- # specter (3)
- # xtdb (14)
Yes, you can. The local-sym :some-key
pair is just another key/value pair in the overall destructuring.
Funnily enough, I just did exactly this in the next-gen version of clj-new
I'm writing...
See https://github.com/seancorfield/deps-new/blob/develop/src/org/corfield/new/impl.clj#L142
(because I want a :name
command-line arg but don't want to shadow name
in clojure.core
)
Nested destructuring is always a bit 👀
Of late, whenever I'm trying to go deeper (literally and metaphorically) with my destructing, I'm glad to have this link handy: https://danielgregoire.dev/posts/2021-06-13-code-observation-clojure-destructuring/
Hello all.
Do lazy sequences evaluate more items than you ask them to? For example:
(defn print-inc [num]
(println "Incrementing:" num)
(inc num))
(take 3 (map print-inc (range 1 10000)))
Yes they implement "chunking" which means it does batch, for performance reasons. That's why people suggest not to rely on lazy-seq for implementing lazy side effect behavior, because it can be tricky to know exactly when a side-effect will run, since many functions might realize a few more elements in the sequence then you might expect.
There is chunking, which has it realize 32 at a time, but there are other functions that if you use them over a sequence sometimes are not as lazy as you'd hope, and end up realizing a bit more than just the next element.
That prints Incrementing: 1
upto Incrementing: 32
although I've only asked for 3 items.
I'm curious if there is any batching involved by default.
I believe lazy seqs are chunked (in batches of 32) by default, see e.g. http://clojure-doc.org/articles/language/laziness.html
only some lazy types are chunked, but if the difference between realizing one item and realizing 32 items matters to you, don't use laziness
don't count on chunking or the lack of chunking
it is 20 not 21 https://github.com/clojure/clojure/blob/b1b88dd25373a86e41310a525a21b497799dbbf2/src/jvm/clojure/lang/Compiler.java#L140
although, 32 is not a magic number. There is a good article explaining why 32 - https://hypirion.com/musings/understanding-persistent-vector-pt-1
Although I'm still not sold on that explanation. I know of contiguous things being good and batching being good. But just as with CPUs having an odd number of cores, I'm not sure if any batch has to have a size that's a power of 2.
Now you're getting into things like how caches work, how CPUs load memory from RAM and move it between caches and cores, etc.
This is a very deep subject, so before a deep dive, I'll spoil the conclusion that small arrays might as well be in powers of two
First, memory is loaded in pages. Different operating systems have different page sizes, in my linux PC:
getconf PAGESIZE
4096
> fixed-length contiguous block of https://en.wikipedia.org/wiki/Virtual_memory, described by a single entry in the https://en.wikipedia.org/wiki/Page_table. It is the smallest unit of data for memory management in a virtual memory https://en.wikipedia.org/wiki/Operating_system
Cache line size usually is 64, see p. 10 https://www.aristeia.com/TalkNotes/ACCU2011_CPUCaches.pdf
L2 cache can be shared, sometimes between adjacent cores, depending on architecture and implementation, L3 cache is usually global
Just as a guess - a block size of 32 makes sense because it should take 64 bytes on x64?
The array itself is an object and has a header, but then you have the backing array in memory
Since these are dynamically allocated arrays, let's just pretend they're allocated with malloc
so you malloc them, then get back a pointer to the array, when the CPU issues a load op to get the array, you get an entire page
So if the array is aligned in cache and a load
will probably return the entire array, you're a happy clam
Here you can see backing by array to create a lazy seq:
private static final int CHUNK_SIZE = 32;
public static ISeq chunkIteratorSeq(final Iterator iter){
if(iter.hasNext()) {
return new LazySeq(new AFn() {
public Object invoke() {
Object[] arr = new Object[CHUNK_SIZE];
int n = 0;
while(iter.hasNext() && n < CHUNK_SIZE)
arr[n++] = iter.next();
return new ChunkedCons(new ArrayChunk(arr, 0, n), chunkIteratorSeq(iter));
}
});
}
return null;
}
Each time you load a pointer, it's a potential page load which invalidates your cache
And please someone from the core team or who knows Java/CPUs well correct me if I said nonsense
Having trouble sending multiple parameters in the body of a clj-http request. Is this the wrong syntax?
(defn text []
(try
(client/post ""
{:basic-auth ["#######" "######"]
:multipart [{:name "To" :content "+#######"}
{:name "From" :content "+########"}
{:name "Body" :content "test text"}]})
(catch Exception e {:error e} (println e))))
Gives me the following error:
<TwilioResponse><RestException><Code>21211</Code><Message>The 'To' number +####### is not a valid phone number.</Message><MoreInfo></MoreInfo><Status>400</Status></RestException></TwilioResponse>, :trace-redirects []}
Seems like it has nothing to do with multipart and instead has everything to do with the phone number itself.
Right - but it works in CURL,
Thought maybe it was an issue with the map
I use it in the same way, no issues on my end so far. You can try debugging it: https://github.com/dakrone/clj-http#debugging
Looks like a twilio issue - Thanks for confirming correct syntax 🙂
CURL requests are now failing, maybe sent too many reqs while testing
Hey everyone, how do I go about with interopt with a jar file? This isn't a java file, so I am not sure how to go about using the java classpaths in that jar.
Are you trying to use it as a library for other code, or are you trying to run something from the command line?
Are you trying to call the java classes from clojure?
I haven't tried to do that, would putting it on the local repo make it accessable?
I am using it as a library but it would be available locally. Not pulled off clojars. Would I have to do something in my project.clj
?@U07S8JGF7
@U0DJ4T5U1 Yep! That is what I am trying to do. Thing is I am unsure on where the jar should be located. src
? I am not getting namespace autocompletion either with Cursive so I suspect I am missing out a step here.
@U01V7GEU89J I don't know about lein
but you can do it easily with deps.edn
(see https://clojure.org/guides/deps_and_cli#local_jar)
@UHD67JRL4 Thanks! I was contemplating using polylith over lein for this project. This should work fine then.