Fork me on GitHub
#clojure
<
2019-07-29
>
GC04:07:53

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

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

GC04:07:12

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

jjttjj14:07:05

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: ..."

ghadi14:07:39

Entities

✔️ 4
jjttjj14:07:36

thanks for the input

jjttjj14:07:47

wouldn't entities describe the instances better?

lukasz14:07:37

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

jjttjj14:07:11

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

jjttjj14:07:06

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 myapp.schema.company sounds right

lilactown14:07:32

I often think of “entity” as a definition

benoit14:07:46

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.

lilactown14:07:53

you could go with “model” but eh

jjttjj14:07:04

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

lilactown14:07:17

an instance of an entity is usually a map :P

jjttjj14:07:48

ok gotcha that makes sense when you put it that way

benoit14:07:03

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

jjttjj14:07:23

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

benoit14:07:44

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.

lilactown14:07:03

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

lilactown14:07:34

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

lilactown14:07:17

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

benoit14:07:12

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

lilactown15:07:03

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

dpsutton15:07:38

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 (java.io.RandomAccessFile. "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.

noisesmith16:07:05

interop is idiomatic

dpsutton16:07:12

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?

schmee16:07:26

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
  (:gen-class
    :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}
above

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

andy.fingerhut17:07:21

If I understand correctly what that is, Criterium is probably a Clojure equivalent: https://github.com/hugoduncan/criterium 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.

vlaaad20:07:19

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))))
usage:
(??? (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

vlaaad20:07:17

meta question: is this question a good fit for https://ask.clojure.org/ ?

Alex Miller (Clojure team)21:07:43

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

seancorfield20:07:39

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 [ ]...

vlaaad20:07:47

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

vlaaad20:07:19

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

seancorfield20:07:57

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

vlaaad20:07:20

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

seancorfield20:07:29

So maybe it's a runduction! :rolling_on_the_floor_laughing:

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

is this the same as run!?

ag21:07:08

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

ag21:07:44

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

lilactown21:07:08

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

ag21:07:29

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

lilactown21:07:46

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

noisesmith21:07:49

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

lilactown21:07:14

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 ""}}

noisesmith23:07:25

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

noisesmith23:07:30

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? https://github.com/bitcoin-s/bitcoin-s/tree/v0.1.0 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"}