Fork me on GitHub

@haiyuan.vinurs If you say :req-un, then :<anything>/id means :id as an unqualified key in the map you are spec'ing. If you want :goods_id, your spec key must be :<something>/goods_id.


(so, the answer to your question is "no")


is there a library out there that provides signal processing stuff (such as moving average, ema ...) as transducers?


my suspicion is that people that would be qualified to implement that stuff got scared away by how hard it can be to write performant numerics in Clojure


hmmm interesting thought, i would think the opposite

👍 8
Vesa Norilo14:07:04

DSP is my main area, while I love Clojure, I wouldn’t use it for compute kernels. My field is latency sensitive though, if it’s more about throughput I don’t see why Clojure couldn’t stand in for matlab etc


kixi is the closest thing to what I want. I still think clojure is underappreciated, there is a lot of potential but not a large enough community. perhaps i'm missing something.


writing numeric code in clojure that doesn't reflect or box is an art, and you don't get much feedback about it (until you see the symptom that your code is slow)

✔️ 4

I could easily imagine that scaring away people who are trying to do anything numerically interesting


@seancorfield I think your homepage needs updating, it's referencing next-jdbc 1.0.0 rc1 🙂


@dharrigan I need to write a long blog post about 1.0.0 and the journey to that point.

👍 4

Could a function like take have been written using transients instead of volatile? I'm guessing the latter was more performant for some reason? When should I use the former vs the latter?


transients were not allowed to be accessed across threads volatile's purpose is cross-thread publishing


can transducers execute across threads?


when to use transients: transients need to be contained in a "birthing process" for a persistent data structure


transients (intentionally) do not support all the operations of persistent maps/vectors


don't volatiles have an issue with multiple writer threads? i would think that would present an issue for using a transducer in multiple threads


you should not let transients escape a "birthing process" (function or handful of functions) or use transients for long-lived data


also, what's an example of a transducer that is parallizable?

Alex Miller (Clojure team)15:07:13

there are no parallel transducer contexts

Alex Miller (Clojure team)15:07:30

volatile is there to allow a transducer to migrate across threads (can happen with a channel transducer and go blocks which are multiplexed over a thread group), but there is only ever one thread at a time

🙏 4

I guess also that transient only applies to a collection type, not e.g. the case of take, a number


Quite different beasts


am I missing something about duratom on s3 or is not really an atom, in the sense that maybe writes are atomic (I mean, it's still a function operating on some data, so I guess it's atomic if writes to s3 never fail) but there's no actual mutex


so two things can read from s3 simultaneously, and last write wins aka some write loses


i think it could work correctly if it used dynamodb, because dynamodb does have locking semantics


s3 does not guarantee read-your-writes in the case of anything but the initial write that creates an object


if you overwrite an extant object (not sure what duratom is doing underneath the hood) you might not see the last write


and you're totally right about dynamo


if you want CAS / conditional PUT, that's your horse


sure yep, that's another way it's not like an atom


ok looks like I'm writing a duratom backend


I mean really I don't need one because all my data is WORO


is the O 'once' or 'only'


^:keyword is short for ^{:keyword true}


You are always welcome to ask here, of course, but FYI there is a section of the Clojure cheatsheet dedicated to listing syntax characters. Feel free to suggest additions to it if you run across anything it doesn't explain. It is the "Special Characters" section near the bottom left of the sheet, and it has a "guide" link near the top to a longer article with fairly detailed explanations of each one:


I guess one could make a good argument it would be better nearer the top.


It doesn't help for searching for special characters, only names, but if you click on the "Source repo" link near the top of the page, you will get to a few other variants of that page that have a text search box at the top


I am intimately familiar with its contents, or at least I have been at various times in the past 🙂

Sam Ferrell20:07:12

It's hidden by the text-overflow CSS property


I haven't used Component or any of the other 'system management' libraries for Clojure yet, but I have the impression that sometimes developers create big maps of application configuration data, and sometimes the associated values (but probably not the keys) are mutable Java objects, e.g. perhaps thinks like connections to databases. Is that correct?


that is correct for component, but not for mount. component builds an object that is your system which has the type SystemMap, and as an object you can build more then one, pass it around to functions, etc. mount does does not build an objec that is the system, it builds an implicit system based on vars


I was mainly curious because such a map isn't an immutable value the way a Clojure map is if it restricts all of its parts to immutable values, and yet, they seem fairly "safe" for many purposes, even to put such a map inside of an atom.


those are, I guess kind of the two poles of that kind of library, and others exist somewhere around them, duct is like component for examplel


You probably shouldn't use something where any part of it is a mutable value within a hash-based set or as a map key, but as map values, they seem a little less problematic.


typically, in production, I think the ideal situation with component is something like you construct the system, set it running, and then don't need to keep a reference to it around


so I might stick it in an atom or something to keep a reference to it for debugging purposes


the main place where I use the system as a reified object is in tests


e.g. spinning up two systems and having them talk to each other


but component is also pretty malleable in its usage, so there are kind of two camps in how it is used: something that very strictly passes things around and nothing gets access to the whole system vs. using component to build up a lot of stateful stuff and everything is passed the whole system and just pulls out what it needs


in the later case you might mechanically need to stash a reference to the systemmap somewhere in order to turn around and pass it to all your web request handers for example


My 2c: we store the "production" system in an atom, but are very strict about not passing it around - all application parts have dependency lists. I don't think that outside of scripts and nrepl-based debugging we ever reference the whole system


and tests, where we assemble a system of mocked components (if possible/appropriate)


which is to say, re: system maps and atoms, I think having the whole system as a value is great, but typically you use that in particular contexts such as debugging or testing, and I wouldn't expect a program to stick a system in an atom in some random place and do whatever with it


there are often global resources that are being used by the system map (server ports, tmp file directories, etc) so care has to be taken spinning up multiple systems for tests anyway


how do you determine tagged elements in a map. e.g. I have a map:

{:started-at #inst "2019-06-26T22:46:51.419-00:00"
 :ended-at #inst "2019-06-27T22:46:51.419-00:00"
 :foo "nothing"
how do I filter only the values that of #inst?


wouldn't (filter #(inst? (val %)) m) do the trick?

Alex Miller (Clojure team)21:07:25

or (->> m vals (filter inst?))

Alex Miller (Clojure team)21:07:48

depending no whether you want the vals or the entries


Oh cool, thank you!


note this doesn't have anything to do with the fact that these values are tagged though


(binding [*data-readers* {'foo str}]
        (read-string "{:a #foo [1 2 3] :b \"bob\"}"))
{:a "[1 2 3]", :b "bob"}
there's nothing "tagged" about this value. Its just a string.


(->> {:a #inst "2019" :b (java.util.Date. 119 0 0)} vals (filter inst?))

Alex Miller (Clojure team)22:07:25

well that's not entirely true, it's really up to the printer what value is placed after the tag

Alex Miller (Clojure team)22:07:14

tagged literals are a tag/value pair where the reader understands how to use the tag to look up a reader function that can "read" the value and produce an object

Alex Miller (Clojure team)22:07:25

nothing about the contract requires a string

Alex Miller (Clojure team)22:07:01

on the printing side, you can install a printer for a type of object that prints it as a tag and value

Alex Miller (Clojure team)22:07:44

both the tagged literal readers and the printers are extensible parts of Clojure

Alex Miller (Clojure team)22:07:02

so you could change your example above to expect a vector

Alex Miller (Clojure team)22:07:22

(binding [*data-readers* {'foo identity}]
  (read-string "{:a #foo [1 2 3] :b \"bob\"}"))
;;=> {:a [1 2 3], :b "bob"}

Alex Miller (Clojure team)22:07:27

since you're getting the values after they are read, there's no notion of "all the tagged values", as there are no tagged values after it's read, just objects as returned by the tagged reader fns