Fork me on GitHub
#clojure
<
2018-12-07
>
Andy01:12:36

quick question: what is a Clojure's name equivalent of Scheme's "atom"? I mean not nil and not a collection.

Andy01:12:06

_yes, I did homework but could not find anything meaningful, and <https://clojure.org/reference/data_structures> does not mention it, except "other types"_

noisesmith01:12:36

I don't think clojure has a name for that - consider that the underlying VM has an open set of potential objects you can define (and hundreds of existing ones) that would meet that criteria

seancorfield01:12:50

@happy.lisper In Scheme, you've only got a very limited number of things that are not atoms -- basically nil and cons pairs. In Clojure, you have a much richer set of collection types, as well as a lot of other things that wouldn't be considered "atomic" by most people. So it makes sense in Scheme to classify things as "atom" or "not atom" but no so much in Clojure.

seancorfield02:12:05

You might get close with (some-fn nil? string? number? symbol? keyword? boolean?) -- that returns a function that tests each of those, Maybe we'd call those scalars? Oh, and add char? to that list.

seancorfield02:12:10

inst? maybe? Although that's really a Java object but it's not a collection but it still has "parts" sort of...

seancorfield02:12:51

Heh, reading further in the Scheme forums and there's a school of thought that strings are not atomic...

dpsutton02:12:32

i guess so. be strange for an atom to be contained in another atom like string/contains?

Andy04:12:27

Thx for the suggestions. I think I like scalar the best.

slipset08:12:29

I was listening to @ericnormand on the way to work (https://lispcast.com/how-do-you-create-a-semantic-base-layer/), and he was talking about monoids. So we started discussing monoids at work. This ended up in talking about reduce, and how it feeds the two first values from the list to be reduced to the reducing function if no seed value is supplied.

slipset08:12:41

You can see that with / as in:

slipset08:12:37

user=> (reduce / [])
ArityException Wrong number of args (0) passed to: core//  clojure.lang.AFn.throwArity (AFn.java:429)

slipset08:12:19

This is all good (maybe). But the pusling thing is:

slipset08:12:46

user=> (/ 5)
1/5
user=> (reduce / [5])
5
user=>

slipset08:12:00

I would have expected these two to yield the same result?

slipset08:12:59

My colleague @mel.collins to the rescue! From the reduce docs:

If coll has only 1 item, it
is returned and f is not called.

dominicm08:12:46

The many arities of reduce confuse me. I pretty much never have an accumulator which is equal to my items, so I always provide a val. Things tend to be quite happy then. I probably have a lot of code which is broken if I'm passed a collection like [1]

madstap11:12:34

A heuristic: if the code uses the init value arity of reduce it might be ok, if it doesn't it is likely to be broken on [] and [1].

Marc O'Morain12:12:29

I’ve been upgrading some CircleCI services from 1.8 to 1.10, and I found an interesting change in behaviour between 1.8 and 1.9. We had a test failing, and there was a bug in the test: The test interacts with a database, and is was making assumption that (is (= (a) (b))) calls a before b.

peter hull12:12:34

After reading @seancorfield’s blog about datafy and nav I had a quick play around with writing a datafy for java.nio.file.Path just as a learning example. Results are here: https://github.com/pedro-w/nav-demo, if it helps anyone, or (more likely) anyone has comments on how to improve it, let me know.

vincentdm12:12:18

Quick quiz! Who can explain this test output? (expected and actual are both verifiable keywords and are seemingly identical)

expected: :subfolder/some-table.dbf
  actual: :subfolder/some-table.dbf
    diff: - :subfolder/some-table.dbf
          + :subfolder/some-table.dbf
(I just found the answer after wrecking my brain for half an hour)

mpenet12:12:04

tailing space?

vincentdm12:12:14

The solution:

(let [normal (keyword "subfolder" "some-table.dbf")
      deceitful (keyword nil "subfolder/some-table.dbf")]
  (println (pr-str normal))
  (println (pr-str deceitful))
  (println "(=" normal deceitful ") => " (= normal deceitful)))
Unfortunately both normal and deceitful are rendered as :subfolder/some-table.dbf.

mpenet12:12:49

I was thinking homoglyph next, but no it's simpler

ericnormand12:12:11

@slipset Rich Hickey regrets that behavior. He copied it from Common Lisp, but he wishes there was just one arity of reduce: [f init coll]

✔️ 2
1
mpenet12:12:23

garbage in garbage out as they say

mpenet12:12:29

oh slack (or chrome?) is better than I imagined

rickmoynihan13:12:51

Does anyone know of any good cloud hosted maven repository managers? Thinking it’d be nice to to step up from s3 wagon’s etc.

rickmoynihan13:12:04

Interesting… unfortunately it looks like they don’t support proxy repositories yet… which is the main feature I want

kulminaator13:12:40

Maybe ask @U051KLSJF if he can add it?

rickmoynihan13:12:20

it looks like it’s scheduled for the business plan and above… but they’re not available yet

shaun-mahood15:12:46

As a small data point, I've been relying on http://deps.co for about a year (Daniel helped me through a thorny problem ad set me up in the beta when I couldn't get what I needed working in s3-wagon) - it's been rock solid and much easier to deal with than s3-wagon.

👍 2
danielcompton17:12:35

raises hand. I run http://deps.co which is a hosted Maven repo service, as Shaun mentioned :)

alexmiller13:12:39

I’ve had a lot of success with Nexus in corporate envs. I think Artifactory is the other big one.

alexmiller13:12:00

but depends whether your goals are primarily internal or external facing

dazld14:12:26

hey, maybe a silly question, but hoping someone can save me from porting something: does anyone know of an RNG in clojure-land that can take a string as a seed?

NoahTheDuke14:12:03

Could you take the string and convert it to a number?

NoahTheDuke14:12:43

Convert to Unicode/ascii code point, use that as your base number?

dazld14:12:03

doesn’t produce longs

dazld14:12:07

well, consistently

dazld14:12:13

and the number it produces isn’t very diverse

alexmiller14:12:00

hash it

👆 1
dazld15:12:42

exactly, but was hoping someone had wrapped that up already for me 😉

dazld15:12:26

I guess I can port to clojure for fun too 🙂

dazld15:12:01

seeded randoms are so handy

dazld15:12:07

(i’m doing some UI work..)

alexmiller15:12:26

hash is a thing

alexmiller15:12:46

that’s a murmur hash, not the Java hash, so it’s much better at spreading the bits than Java’s

dazld15:12:59

thanks alex, that works fine

alexmiller15:12:50

well, I guess I should mention that those produce ints

dazld15:12:13

java.util.Random takes ints as a seed, so that works for me

alexmiller15:12:21

user=> (map #(Long/toBinaryString (hash %)) ["a" "b" "c"])
("1010110110000011100101111010001" "11110110001111111010010010110" "1001000101100010111110100111110")
user=> (map #(Long/toBinaryString (.hashCode %)) ["a" "b" "c"])
("1100001" "1100010" "1100011")

theeternalpulse16:12:09

are there any libraries that are good for creating less than trivial mathematical expressions?

dpsutton16:12:09

"less than trivial"?

theeternalpulse18:12:42

as an example this `

(-> (* pi x)
         (+ (/ (* 3 pi) 2))
         math/sin
         inc
         (/ 2))
is a bit harder to translate from what I'd write down. I'm looking for something that's closer to what would be a written math formula.

dpsutton18:12:16

Ah I think someone made an infix lib

theeternalpulse16:12:41

something that's not only a few sequential operations on a value. multiple operation son a numerator/denominator etc.

devn16:12:03

Getting this when running lein new luminus foo >Could not load template, failed with: java.lang.VerifyError: class com.fasterxml.jackson.dataformat.cbor.CBORGenerator overrides final method com.fasterxml.jackson.core.base.GeneratorBase.copyCurrentEvent(Lcom/fasterxml/jackson/core/JsonParser;)V, compiling:(cheshire/factory.clj:78:5)

devn16:12:54

Also, what are the other options in this space these days?

devn16:12:39

derp, not sure how openjdk11 got on this box, but assuming that's the culprit

alexmiller17:12:38

seems more likely it’s a weird set of mismatched jackson deps than jdk11

alexmiller17:12:10

approximately 100% of deps issues are related to jackson :)

😛 4
📊 2
bronsa17:12:28

that explains the collective PTSD symptoms this channel is now experiencing after reading that error message

mccraigmccraig17:12:14

huh, i feel left out - why have i never had a mismatched jackson deps problem ? perhaps because i favour {:pedantic? :abort} ?

schmee17:12:18

you need to add more enterprise Java libraries

3
not-sure-fry 1
mccraigmccraig17:12:12

silly me, i'll get right on it

phil17:12:33

Hey. When using the clojure command line, how do I pass in system props? Specifically, I need to set maven.repo.local.

alexmiller18:12:54

If you’re talking clj, -J-Dmaven.repo.local=foo

alexmiller18:12:18

but it sounds like what you’re trying to do is influence the maven local repo

alexmiller18:12:25

and that happens in a separate process

alexmiller18:12:32

but you can set that in your deps.edn

alexmiller18:12:43

with a :mvn/local-repo key at the root map

kulminaator18:12:16

my bread these days is writing a ton of java microservices and keeping jackson outside the gate is one of the most annoying tasks ... especially after the security issues they have had over the last year. it's too big (hell, jackson json + databind is bigger than my applications that include rabbitmq postgresql jdbc and gson) and it's trying too much to be everything ...

kulminaator18:12:30

and when i'm in my clojure bubble then data.json gives me just enough features 🙂

arohner19:12:04

@bronsa I’m trying to use tools.analyzer.jvm’s ability to inject locals into :env, but it appears the injected binding doesn’t share the atom with the ‘real’ local. Is that expected, or am I doing something wrong?

arohner19:12:29

i.e. I’m seeing {:op :local :form x :atom (atom 0x1234) :env {:locals {x {:op :binding :name x, :atom (atom 0x5678)}}}}

arohner19:12:12

i.e. there is an x in :env :locals, but the use of x points to a different atom

bronsa19:12:33

you're missing the :name field

bronsa19:12:49

that's how the pass discriminates whether to reuse the atom or make a new one

bronsa19:12:53

i should add an AST validation phase...

bronsa19:12:10

well, a stricter one

arohner19:12:21

here’s the whole output, for analyze (seq x): `

arohner19:12:37

{:args [{:children [], :name x, :op :local, :env {:context :ctx/expr, :locals {x {:op :binding, :name x, :form x, :env {}, :local :let}}, :ns spectrum.repl, :column 34, :line 9, :file "*cider-repl localhost*"}, :o-tag nil, :form x, :tag nil, :atom #atom[{} 0x5672bb33], :local :let, :assignable? false}], :children [:fn :args], :fn {:meta {:added "1.0", :ns #namespace[clojure.core], :name seq, :file "clojure/core.clj", :static true, :column 1, :line 126, :tag clojure.lang.ISeq, :arglists ([coll]), :doc "Returns a seq on the collection. If the collection is\n    empty, returns nil.  (seq nil) returns nil. seq also works on\n    Strings, native Java arrays (of reference types) and any objects\n    that implement Iterable. Note that seqs cache values, thus seq\n    should not be used on any Iterable whose iterator repeatedly\n    returns the same mutable object."}, :return-tag clojure.lang.ISeq, :op :var, :env {:context :ctx/expr, :locals {x {:op :binding, :name x, :form x, :env {}, :local :let}}, :ns spectrum.repl, :column 34, :line 9, :file "*cider-repl localhost*"}, :o-tag java.lang.Object, :var #'clojure.core/seq, :form seq, :tag clojure.lang.AFunction, :arglists ([coll]), :assignable? false}, :meta {:line 9, :column 34}, :op :invoke, :env {:context :ctx/expr, :locals {x {:op :binding, :name x, :form x, :env {}, :local :let}}, :ns spectrum.repl, :column 34, :line 9, :file "*cider-repl localhost*"}, :o-tag java.lang.Object, :top-level true, :form (seq x), :tag clojure.lang.ISeq}

arohner19:12:00

it looks like there is a :name there

arohner19:12:13

and should I be creating an atom for the injected binding?

bronsa19:12:13

@arohner oh -- if you're injecting a local fro an outer scope, so no matching :binding node, that would explain it

arohner19:12:29

right, I want to analyze (seq x), and inject a binding for x

bronsa19:12:44

ok -- give me 2 minutes to remember how to do this :)

arohner19:12:35

this is for writing tests for https://github.com/arohner/spectrum, so I can assert that e.g. (infer '(first x) {:x (coll-of int?)}) => (or int? nil?)

bronsa19:12:21

it looks like with the current implementation that is not possible, but this is a valid use-case

bronsa19:12:37

can you open a ticket and I'll work on it this weekend

danielcompton22:12:56

Is my understanding correct that if you AOT compiled this macro on Java 8 and tried to run the compiled JAR on Java 9 or later that it would fail? Java 9 wouldn't be able to resolve the java.xml.bind module? So you'd need to AOT compile on the same version of Java that you were running in production?

(defmacro base64-encode [bs]
  (if (try (import 'javax.xml.bind.DatatypeConverter)
           (catch ClassNotFoundException _))
    `(javax.xml.bind.DatatypeConverter/printBase64Binary ~bs)
    (do
      (import 'java.util.Base64)
      `(.encodeToString (java.util.Base64/getEncoder) ~bs))))
From https://github.com/http-kit/http-kit/commit/0cc921f0c2b62566f0884f0d8affa52516e30ac7#diff-42655ca9cd6f3874875b3d81c24966fbR3

hiredman22:12:26

it will fail if aot'ed when javax.xml.bind.DatatypeConverter is present, and then you attempt to load those class files when javax.xml.bind.DatatypeConverter is not present

hiredman23:12:42

reducers at one point had a similar macro compile-if, with if I recall, similar issues

hiredman23:12:37

https://dev.clojure.org/jira/browse/CLJ-1509 reducers.clj specifically was excluded from the aot compile that happens when the clojure jar is built to avoid this

danielcompton23:12:52

Yep, that's what I expected, just checking I was reading it right