Fork me on GitHub
#clojure
<
2019-07-03
>
seancorfield00:07:13

@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.

seancorfield00:07:26

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

quadron10:07:55

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

noisesmith11:07:21

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

4
jeroenvandijk11:07:09

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

quadron20:07:12

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.

noisesmith20:07:03

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
noisesmith20:07:24

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

dharrigan12:07:41

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

seancorfield14:07:02

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

👍 4
csd15:07:21

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?

ghadi15:07:20

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

csd15:07:05

can transducers execute across threads?

ghadi15:07:49

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

ghadi15:07:11

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

csd15:07:43

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

ghadi15:07:45

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

csd15:07:10

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

alexmiller15:07:51

there are none

alexmiller15:07:13

there are no parallel transducer contexts

alexmiller15: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
csd15:07:22

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

mpenet15:07:23

Quite different beasts

lvh17:07:53

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

lvh17:07:13

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

lvh17:07:29

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

ghadi17:07:21

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

ghadi17:07:04

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

ghadi17:07:17

and you're totally right about dynamo

ghadi17:07:35

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

lvh17:07:41

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

lvh17:07:51

ok looks like I'm writing a duratom backend

lvh17:07:14

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

ghadi17:07:11

is the O 'once' or 'only'

Cora (she/her)20:07:26

what's the name for the ^:dynamic thing you can put on vars? are there others?

Cora (she/her)20:07:43

wait is that meta data?

ghadi20:07:55

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

andy.fingerhut20:07:35

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: https://clojure.org/api/cheatsheet

Cora (she/her)20:07:58

I honestly have never scrolled down this far in it 🙂

andy.fingerhut20:07:32

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

Cora (she/her)20:07:10

it depends on what you're optimizing for, I suppose

Cora (she/her)20:07:33

they're probably more useful for newcomers, but the vast majority of users would benefit from the other stuff

andy.fingerhut20:07:34

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

Cora (she/her)20:07:21

seems to be your github

andy.fingerhut20:07:54

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

Cora (she/her)20:07:01

it bugs me that there's apparently hidden text on https://clojuredocs.org/clojure.core or something that is found by searching the page and you have to keep going through matches to get past them

Cora (she/her)20:07:17

like the 4th match of "map" is hidden as far as I can tell

Cora (she/her)20:07:39

I know this isn't anyone here's site (I think?) I'm just complaining

Sam Ferrell20:07:12

It's hidden by the text-overflow CSS property

Cora (she/her)20:07:49

oh, it's on github, I'll make an issue

andy.fingerhut20:07:22

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?

hiredman20:07:13

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

andy.fingerhut20:07:27

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.

hiredman20:07:27

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

andy.fingerhut20:07:30

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.

hiredman20:07:57

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

hiredman20:07:38

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

hiredman20:07:08

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

hiredman20:07:25

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

hiredman20:07:18

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

hiredman20:07:18

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

lukasz20:07:25

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

lukasz20:07:10

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

hiredman21:07:23

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

hiredman21:07:58

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

ag21:07:03

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?

zugnush21:07:05

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

alexmiller21:07:25

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

alexmiller21:07:48

depending no whether you want the vals or the entries

ag22:07:48

Oh cool, thank you!

dpsutton22:07:07

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

dpsutton22:07:23

(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.

dpsutton22:07:28

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

alexmiller22:07:25

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

alexmiller22: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

alexmiller22:07:25

nothing about the contract requires a string

alexmiller22:07:01

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

alexmiller22:07:44

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

alexmiller22:07:02

so you could change your example above to expect a vector

alexmiller22:07:22

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

alexmiller22: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