Fork me on GitHub

hi, can't find it anywhere, this errors out

(defn po [vol {:keyA [id name age] }])


but if i replace :keyA with :keys , it doesn't


Is there a term people use to describe the different "maps of expected shape" in their code? Ie, something which would be described by s/keys in spec. Clearly "type" isn't a great word to use, though this is how I think of them in my head. "keyspec"? hijack the word "struct"? As in "Here are the various <type-things> my app uses, and the possible keys in each of them: ..."



✔️ 4

thanks for the input


wouldn't entities describe the instances better?


Sorry, I misunderstood your question - so yes, entities would work better here (and they have to comply with a schema ;-))


no you were right I meant the way to describe the classification of the instance not the instance itself


schema might be good. Just trying to work out if i have precisely a spec.alpha2 schema here. And also if myapp.schema.person and sounds right


I often think of “entity” as a definition


The word "type" is the one I have encountered the most so it would make sense to me. But I find more helpful to think in terms of "set of keys" that entities can use or not, rather than type. So entities are not limited to one type.


you could go with “model” but eh


because also i have things in my app that would be described by a spec.alpha2 schema but are not one of these things


an instance of an entity is usually a map :P


ok gotcha that makes sense when you put it that way


I think "entity" has more to do with the idea of identity than schema or type: "a thing with distinct and independent existence."


Yeah that was my initial thought. "I am an entity. I am a person. Person is my <type/class/category>"


Yes, <type/class/category> are the most common terms for this idea so any of those would work. But you're not just a person, you can have many roles, so that's why it is more useful to think in terms of roles (or sets of keys) rather than types.


type/class/category sounds either too abstract, too closed or both ¯\(ツ)


“entity description” perhaps? but that’s rather long


I think a schema or spec that describes an entity is quite different than a type or class that describes some implementation detail, i think is where I get hung up


"type" is used a lot in data modeling to represent exactly this "class" is used in RDF schema and ontologies (OWL)


but we live next to Java/JS land, which have different meanings for those

Benny kach15:07:28

Hi, is there a non-blocking io (and specifically reading from file) in Clojure?

Benny kach15:07:57

i see that slurp is definitely blocking

Alex Miller (Clojure team)15:07:41

Java has a variety of blocking and nonblocking io apis, which are all usable from Clojure

Benny kach15:07:18

i would expect that Clojure will have a fn that reads from a file in a non-blocking way and return a channel. I can write one my self (in about 5 lines of code) but isnt there one?

Alex Miller (Clojure team)15:07:02

Clojure in general does not provide wrappers around things that can be used directly via java interop in the jdk (so, no there isn't one)

Benny kach15:07:31

so why slurp is part of clojure ?

Alex Miller (Clojure team)15:07:21

slurp is a helper function that does a frequently used combination of actions


by channel do you mean core.async?

Alex Miller (Clojure team)15:07:49

I presume java.nio.channels.Channel

Alex Miller (Clojure team)16:07:43

you can get a channel with something like (.getChannel ( "afile.txt" "r"))

Benny kach16:07:14

this is fine, but I would like a more idiomatic Clojure solution for this - i.e., something that returns a core.async Channel. why not have something like async-slurp in core.async ? sounds like a common use case for io intensive apps.


interop is idiomatic


and async is a library

Tim Brown16:07:57

Hi... I think I'm compiling clojure with :direct-linking true in *compiler-options*; but looking at my byte code (disassembled in IntelliJ), I still seem to have a lot of Vars and indirection. Would that be expected?


yes, dynamic vars cannot be inlined and there are plenty of those

Alex Miller (Clojure team)16:07:00

Depends where you are seeing them

Tim Brown08:07:59

I would expect the following would be obviously “direct” for the compiler:

(ns net.timb.timmeh.tim
    :methods [[woo [] int]]

(defn- -woo [] 42)

Tim Brown08:07:38

But tim.class is decompiling as:

Tim Brown08:07:24

So there’s dereferencing right from the start, here.

Alex Miller (Clojure team)12:07:46

Oh, this is just how gen-class always works. It always uses vars as a point of indirection. Since these aren’t static methods on the generated class, there’s not really any choice

Alex Miller (Clojure team)12:07:09

Direct linking really affects normal function invocation call sites

Tim Brown12:07:26

It’s the woo, I’m really concerned about. Is there any way to get the declaration here closer to public int woo(){return (Integer)42;}

Tim Brown12:07:35

static is fine.

Alex Miller (Clojure team)12:07:23

Is there some reason you’re doing gen-class?

Tim Brown13:07:39

I’m experimenting with code generation macros… a bunch of classes generated of the back of a yaml file.

Tim Brown13:07:43

Currently I’m doing the code generation with scripts to produce .java source (mostly using jq).

Tim Brown13:07:54

Clojure’ll produce byte code… so I was hoping to do: ({k: v} map in yaml) -> {:k v} map in clojure -> macro with classes (named by :k, with v implementation) and gen-class -> .class byte code

Tim Brown13:07:12

kinda, so that woo here is generated from something along the lines of:

woo: 42
creating byte code for the
public static int woo() {return 42}

Tim Brown13:07:08

(although there’ll be more than one method per class, and it’s not just returning an int!)

Alex Miller (Clojure team)13:07:00

a more direct path would be to actually use asm to generate bytecode (like Clojure does)

Tim Brown13:07:00

I’m going to need quite a bit of language support in the macros… it’ll involve pattern matching and all sorts of other stuff I need a proper language for.

Alex Miller (Clojure team)13:07:16

oh, the v's are code, not data

Tim Brown13:07:08

int the yaml, they’re data (as literal values v)… once it’s in the generated class they’ll be some transformed value f(v) — but being spliced into a macro, they’re actually code. IYSWIM

Alex Miller (Clojure team)13:07:20

I don't think you're going to get what you want out of gen-class, probably better off with making normal vars and running compile on the namespace

Tim Brown13:07:32

The woo thing is an experiment… I’m keen not to be calling something that in principle is dereferenced through a Var — even though the promise of JIT magic might make that not a thing.

Tim Brown13:07:52

(I’m actually pretty new† to Clojure, but not to this kind of cross-language meta-programming)

Tim Brown13:07:10

† complete novice

Alex Miller (Clojure team)13:07:37

direct linking through compilation will remove the var indirection (but not with gen-class)

Tim Brown14:07:38

thanks… I think I have a direction now. Probably means dumping my generated code into a new source file to be compiled — I’m guessing there’s no

(compile '(namespace-contents...))

Alex Miller (Clojure team)14:07:28

no, compile rides on top of load, which is coming from a source file

Tim Brown14:07:00

I’ll see what mileage I get from this. I’m happy with this as a solution if it works; the intermediate source is a small price. Again thanks2


If I understand correctly what that is, Criterium is probably a Clojure equivalent: It has code that explicitly tries to first run some code enough times that the Java JIT compiler will likely kick in and create a native machine code version of your code before starting its measuerements.


question: I have a function that performs "transducing" over single element, how should I name it? code:

(defn ??? [xf f v]
  (let [rf (xf (completing #(f %2)))]
    (rf (rf nil v))))
(??? (map-indexed vector) str :a)
=> [0 :a]
(??? (map-indexed vector) println :a)
;; prints [0 :a]
=> nil
(??? (comp (filter int?) (map-indexed vector)) println :a)
;; does not print anything because :a is not an int
=> nil


meta question: is this question a good fit for ?

Alex Miller (Clojure team)21:07:43

it's a question, and it's about Clojure, so yes!


That sort of feels like it violates expectations around reduction/transduction to me... It's almost the same as transduce with the last arg wrapped in [ ]...


yeah, I now realized that it's not really a good ???duction, because it completely disregards accumulator


although it's exactly what is needed for my use case

seancorfield20:07:57 a way that (transduce xf f [v]) is not? Presumably in the (f) case to create the accumulator?


f will receive 2 args: accumulator and item, and in my case I don't care about accumulator, just performing side effects on each item


So maybe it's a runduction! :rolling_on_the_floor_laughing:

👍 8
parrot 4
Alex Miller (Clojure team)21:07:28

is this the same as run!?


is there a core equivalent of something like #(or % 0)?


I guess (fnil identity 0) - which is not much concise


I think fnil is correct, but I probably wouldn't use it on identity


so what’s the better way of doing something like this: (comp not zero? (fnil identity 0) util/parse-int)? parse-int return nil if can’t parse


(comp not (fnil zero? true) util/parse-int)


#({nil 0 false 0} % %) - returns arg if not nil or false, otherwise 0


but also not sure if I would use a hof like comp for this yeah

Janus Troelsen23:07:21

edn file trying to add sonatype and some dependencies that should be on there

Janus Troelsen23:07:11

when i use clj to run my project with these dependencies, it complains that it can't find them on Maven Central. how can i force a specific dependencey to be fetched from sonatype (which i am adding in that file) ?

John Collins23:07:19

I'm not sure what sonatype is but you can add external repos under the mvn/repos key. For example: :mvn/repos {"Sonatype" {:url ""}}


are you sure it's org.bitcoin-s and not org.bitcoins


that pom suggests the version string 0.1.0+45-91633375-SNAPSHOT which matches the date you specified, but doesn't include it in the version

Janus Troelsen23:07:55

aaah thanks! @noisesmith... i couldn't figure out how to browse sonatype, how did you do that? just manually adapt an URL from a different package? and remove elements from the end?

Alex Miller (Clojure team)23:07:38

is there some reason you're using a snapshot?

Alex Miller (Clojure team)23:07:45

there is a released 0.1.0

Alex Miller (Clojure team)23:07:27

the release should be newer than the snapshot

Janus Troelsen23:07:13

oh, i didn't realize. i wanted to use the snapshot because this is a one-off anyway and i don't know how stable that project is, and i would wanna report bugs based on master

Alex Miller (Clojure team)23:07:37

I'd just use {:mvn/version "0.1.0"}

Alex Miller (Clojure team)23:07:00

then you don't need the special repo either, central is included automatically

Janus Troelsen23:07:54

@alexmiller how can the release be newer than the snapshot? says the last commit is from may but the full version string of the snapshot says 201906, which should be june

Alex Miller (Clojure team)23:07:17

yeah, I was just looking at that. that's very weird.

Alex Miller (Clojure team)23:07:45

my guess would be a ci process continuing to build something off the snapshot version

Alex Miller (Clojure team)23:07:59

like the snapshot base version didn't get updated after the release build

Alex Miller (Clojure team)23:07:47

what I'm saying is, someone on the internet is wrong

Janus Troelsen23:07:03

aaaah yeah ok, i didn't even consider that a problem. i always thought if a version contains SNAPSHOT, you basically cannot trust its version number?

Alex Miller (Clojure team)23:07:14

but even if you were using a snapshot, you shouldn't pull in a specific timestamp version like that. The snapshot version is a "virtual" release and maven will map to the latest timestamp. So, you'd just want to use {:mvn/version "0.1.0-SNAPSHOT"}