Fork me on GitHub
#clojure
<
2017-09-25
>
cjhowe01:09:42

anyone still doing android development with clojure? i'm not really a fan of react-native

cjhowe02:09:31

it basically sounds like java interop at this point... and i'm not really sure i'd rather write java over clojure java interop

zerocooljs02:09:37

Hi everybody maybe someone can help me with this question (https://stackoverflow.com/questions/46396717/axis-2-client-support-multiple-certificates-for-the-same-webservice-enpoint) is not Clojure thing but I’m desperate, almost stuck 2 weeks on the error. 😕

qqq08:09:02

only slightly joking: in lisps, why don't people measure 'lines of code' by number of (), [], {} }

qqq08:09:25

it seems like this is a simple measure of complexity

noisesmith08:09:05

(-> x f g h i j) is as complex as (j (i (h (g (f x)))))

noisesmith08:09:17

similar issues with comp and partial

timrichardt09:09:46

you could count the nodes in the code after macroexpansion

noisesmith09:09:43

then for / doseq would look extremely complex

noisesmith09:09:21

user=> (pprint (macroexpand-1 '(for [x {:a [1 2 3] :b [4 5 6]} [y z] x] [x z])))
(clojure.core/let
 [iter__7307__auto__
  (clojure.core/fn
   iter__23
   [s__24]
   (clojure.core/lazy-seq
    (clojure.core/loop
     [s__24 s__24]
     (clojure.core/when-first
      [x s__24]
      (clojure.core/let
       [iterys__7303__auto__
        (clojure.core/fn
         iter__25
         [s__26]
         (clojure.core/lazy-seq
          (clojure.core/loop
           [s__26 s__26]
           (clojure.core/when-let
            [s__26 (clojure.core/seq s__26)]
            (if
             (clojure.core/chunked-seq? s__26)
             (clojure.core/let
              [c__7305__auto__
               (clojure.core/chunk-first s__26)
               size__7306__auto__
               (clojure.core/int (clojure.core/count c__7305__auto__))
               b__28
               (clojure.core/chunk-buffer size__7306__auto__)]
              (if
               (clojure.core/loop
                [i__27 (clojure.core/int 0)]
                (if
                 (clojure.core/< i__27 size__7306__auto__)
                 (clojure.core/let
                  [[y z] (.nth c__7305__auto__ i__27)]
                  (do
                   (clojure.core/chunk-append b__28 [x z])
                   (recur (clojure.core/unchecked-inc i__27))))
                 true))
               (clojure.core/chunk-cons
                (clojure.core/chunk b__28)
                (iter__25 (clojure.core/chunk-rest s__26)))
               (clojure.core/chunk-cons
                (clojure.core/chunk b__28)
                nil)))
             (clojure.core/let
              [[y z] (clojure.core/first s__26)]
              (clojure.core/cons
               [x z]
               (iter__25 (clojure.core/rest s__26)))))))))
        fs__7304__auto__
        (clojure.core/seq (iterys__7303__auto__ x))]
       (if
        fs__7304__auto__
        (clojure.core/concat
         fs__7304__auto__
         (iter__23 (clojure.core/rest s__24)))
        (recur (clojure.core/rest s__24))))))))]
 (iter__7307__auto__ {:a [1 2 3], :b [4 5 6]}))
nil

timrichardt09:09:59

true, some macros maybe should be masked 🙂

timrichardt09:09:22

=> (clojure.pprint/pprint (macroexpand '(->> 2 inc dec inc)))
(inc (dec (inc 2)))

hlolli09:09:14

wow, so many core functions in this expansion I've never seen, clojure.core/when-first nice!

djebbz10:09:25

Hello, I'm trying to create a custom generator for string of fixed size. I found gen/string-alphanumeric but didn't find a way enforce the size. Help ?

mpenet10:09:07

I guess you can do something like:

djebbz10:09:09

(gen/generate generator size) returns a value of that size, not a generator

mpenet10:09:20

(gen/fmap #(apply str %)  (gen/vector gen/char-alphanumeric 2 10))

djebbz10:09:19

not a bad idea, but string will still be of random size

mpenet10:09:25

I wouldn't be surprised if there's a better way

djebbz10:09:37

me too 🙂

djebbz10:09:43

Thanks anyway

mpenet10:09:55

(gen/sample (gen/fmap #(apply str %) (gen/vector gen/char-alphanumeric 10)))

mpenet10:09:11

1 arg of vec is fixed size

mpenet10:09:34

-> ("W6gz7Z339v" "CnLv6KSfSv" "viHShHZ44P" "2CZxxAIP6r" "IvN0zum2MR" "3lEx60c3bH" "D0oNW9ZZPU" "Z8FQ0mytW6" "3KH8uV08hA" "b05J5U7l4d")

mpenet10:09:39

seems to work

binora10:09:24

how do i pass command line tasks to lein aliases ?

:aliases {"bump-version"  ["do"
                             ["change" "version" "leiningen.release/bump-version"]
                             ["vcs" "commit"]]}

noisesmith10:09:20

I use the lein-shell plugin for that

binora10:09:46

i would like to mention :patch, :major, :minor with bump-verson like

lein bump-version :patch

noisesmith10:09:27

oh, I misunderstood - you don't mean shell tasks, you mean shell arguments applied to lein tasks

noisesmith10:09:26

I don't see anything for this in the lein help sample output, it might be easier to do something like

~(System/getenv "BUMP_LEVEL")
and then invoke with
BUMP_LEVEL=:patch lein bump-version

binora10:09:28

that's nice. Maybe i can then set this BUMP_LEVEL using lein-shell and then invoke the change version command and put them in the same alias. i guess that should work

binora10:09:32

no it wont. my bad.

noisesmith10:09:06

I thought it had to be set from the command line

noisesmith10:09:21

if you can set it elsewhere in project.clj, you can reference the project's own keys in the map

noisesmith10:09:04

eg :project/version gets replaced with the contents of :version

noisesmith10:09:33

you could add a :patch-level key and access it with :project/patch-level if you can set it inside the project file itself

binora10:09:29

no, i need to set it from command line. what i suggested wont work.

noisesmith10:09:07

yeah- in that case I see no documentation of accessing lein args inside the project map, so it might be simpler to work with and set env vars

binora10:09:48

okay. thanks for the quick response @noisesmith

djebbz11:09:41

@mpenet Exactly what I was thinking while having lunch. Thanks !

beoliver13:09:12

is there a way to create java objects from clojure maps?

beoliver13:09:50

something where the following would hold - (= my-map (bean (convert-to-object my-map)))

beoliver13:09:05

perhaps with or (= my-map (-> my-map convert-to-object bean (dissoc :class)))

Alex Miller (Clojure team)13:09:59

I’ve written some macros to do it on a non-recursive scale, but just as a one-off kind of thing

genec14:09:40

that's cool

Alex Miller (Clojure team)13:09:59

actually I guess that’s the other way for non-bean getters

beoliver15:09:18

easiest way to test seqable? prior to 1.9?

beoliver15:09:50

(try (seq x) (catch Exceception e false))

beoliver15:09:19

but then it has been converted...

noisesmith15:09:16

(try (seq x) true (catch Exception _ false))) ; still not quite

beoliver15:09:51

what about instance?

noisesmith15:09:36

this doesn't work because there's no single Interface that is seqable - even a string can be seq'd

leontalbot16:09:11

Trying to use google-apps-clj library

leontalbot16:09:38

is it normal I must import all java classes to make this library works?

leontalbot16:09:44

I tought I would have only to :require clojure lib ns but it seems it only works when I some :import s present in the library source

bfabry16:09:44

I have not actually used that library, but as someone who writes clojure code against various google cloud project applications every day I feel compelled to warn you not to use it and just write clojure agains the google Java API's directly

bfabry16:09:18

they move way too fast and are too all-encompassing (and are to a significant extent auto generated) for any wrapper that hasn't been updated since january to be a good bet

bfabry16:09:24

although this seems to be more the client applications side (Drive, Sheets, Calendar) than enterprise apps side. but it still seems likely to be true to me

leontalbot16:09:57

still, I wonder if the library imports java classes, why do I need to import them again myself when I use the library

bfabry16:09:08

not sure what you mean, but if you want to refer to a java class in a clojure namespace without fully specifying its package then you have to import it, otherwise how will the compiler know which namespace the class is in?

bfabry16:09:42

(and even if it could figure that how how would any poor programmer reading your code know? :-))

uwo16:09:31

Question: I’ve got an auto-resolved keyword inside a cljs reader conditional and I get “Invalid token” when I attempt to compile, even though the namespace alias is required for cljs. Any ideas?

(ns some.namespace
  #?(:cljs
     (:require [some.other.namespace :as abbr])))

#?(:cljs ...  ::abbr/read-only?  ...)

Alex Miller (Clojure team)16:09:00

Those are independent expressions

uwo17:09:03

@alexmiller forgive me. I don’t follow. Is it not possible to use auto-resolved namespace aliases in cljc? or have I not written the ns correctly?

Alex Miller (Clojure team)17:09:15

It is tricky (maybe impossible) to use auto-resolved namespaces in tandem with reader conditionals

Alex Miller (Clojure team)17:09:36

Off the top of my head, I don't have a good summary of what will and won't work

uwo17:09:11

ah! good to know. thx!

noisesmith17:09:20

@leontalbot import just aliases a class name, it isn't the mechanism that loads the class from the jar

noisesmith17:09:39

the jvm itself auto-loads classes when it finds them, we don't have to worry about it

leontalbot17:09:09

something like

(:import
 (com.google.api.services.drive.model
      File
      FileList
      ParentReference
      Permission
      PermissionList))

noisesmith17:09:19

a similar related issue is that you should require a namespace from each ns that uses it (and preferably alias it to a shorter name) - this avoids a bunch of gotchas you would otherwise hit if the order of loading namespaces changes, or another ns changes implementation and doesn't require what it did before

noisesmith17:09:45

@leontalbot something like that, you can stick to importing the specific classes you need short names for

noisesmith17:09:31

and if you were also using java.io.File you'd have to decide which one (if any) should be File and which needs to use its full name

leontalbot17:09:31

@noisesmith Much thanks! I was not using :require :as aliases but full path when call some library fns

leontalbot17:09:41

This is great!!!

leontalbot17:09:17

no more :import for a ton a java classes

plins18:09:36

Hello everyone, is there an easy way to “merge” match clauses? I’m about to write a macro but id like to know if there is a standart way

dpsutton18:09:24

type hints of return types go after function name and before arg list right? (defn name ^type [args ...]

dpsutton18:09:40

thanks. just wanted to confirm.

ghadi18:09:28

easy way to remember is that the meta always goes on the arglist

bostonaholic19:09:41

for anyone that uses hombrew to manage your java installation, homebrew just upgraded java to 1.9,181 which does not seem compatible with clojure

bostonaholic19:09:46

~ java -version java version “9” Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) ~ lein repl Exception in thread “main” java.lang.ExceptionInInitializerError at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:375) at clojure.lang.RT.classForName(RT.java:2168) at clojure.lang.RT.classForName(RT.java:2177) at clojure.lang.RT.loadClassForName(RT.java:2196) at clojure.lang.RT.load(RT.java:443) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core__init.load(Unknown Source) at clojure.core__init.<clinit>(Unknown Source) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:375) at clojure.lang.RT.classForName(RT.java:2168) at clojure.lang.RT.classForName(RT.java:2177) at clojure.lang.RT.loadClassForName(RT.java:2196) at clojure.lang.RT.load(RT.java:443) at clojure.lang.RT.load(RT.java:419) at clojure.lang.RT.doInit(RT.java:461) at clojure.lang.RT.<clinit>(RT.java:331) at clojure.main.<clinit>(main.java:20) Caused by: java.lang.ClassNotFoundException: java/sql/Timestamp at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:375) at clojure.lang.RT.classForName(RT.java:2168) at clojure.lang.RT.classForNameNonLoading(RT.java:2181) at clojure.instant$loading__5569__auto____6869.invoke(instant.clj:9) at clojure.instant__init.load(Unknown Source) at clojure.instant__init.<clinit>(Unknown Source) ... 23 more `

noisesmith19:09:20

that's a leiningen issue, addressed in the master branch but not released, last I heard

jumar19:09:18

And there are probably still more issues - and least when I tried to workaround this using latest lein RC which doesn't use boot classpath but still fails (I think some dynapath issue)

bostonaholic19:09:36

I hadn’t spent the time to look it up. facepalm

bfabry19:09:34

so I decided to move a couple of type hints based on the comments above from (defn ^Hint foo [args] to (defn foo ^Hint [args] and now I get eastwood errors like wrong-tag: Tag: Connection for return type of function on arg vector: [p__8116] should be fully qualified Java class name, or else it may cause exception if used from another namespace

bfabry19:09:04

is that eastwood being silly, or is it a legit problem? why doesn't it apply to how it was before?

bronsa19:09:53

it's eastwood warning about an issue that's been fixed in clojure 1.8

bronsa19:09:07

so if you're using clojure pre 1.8, eastwood is correct

bronsa19:09:09

otherwise ignore it

bfabry19:09:23

ah, ok I'll try and disable that check.ta

sophiago20:09:54

Is there a way to have a sorted-set using collections (currently just small vectors, but I may change them) as keys? This works: (sorted-set-by (fn [a b] (> (reduce +' (next a)) (reduce +' (next b)))) [3 1 0] [5 0 1] [7 0 0] [2 1 1]), but this does not: (sorted-set-by (fn [a b] (> (reduce +' a) (reduce +' b))) [1 0] 3 [0 1] 5 [0 0] 7 [1 1] 2). Am I just not writing the comparator correctly or is this not possible?

sophiago20:09:36

I also assume sorted-map-by has the same semantics with regards to this. I may need to switch between the two in order to preserve duplicate elements before I apply relational algebra functions from clojure.core/set to handle them.

bfabry20:09:10

ugh, well you can't disable that test, which makes eastwood false +ve error on any function tagged that way, making eastwood useless

bfabry20:09:15

just going to switch back to the wrong way

dpsutton20:09:51

the wrong way means just decoration for the programmer, right? ie, not performance benefit?

bfabry20:09:40

shrug well it makes the cursive warning go away so I'm guessing it avoids the reflection somehow

noisesmith20:09:09

@sophiago I'd assume the second one breaks because you put things in the set that you can't reduce - collection functions for sorting is fine, as long as all things in the insertions are collections

sophiago20:09:26

Can you please clarify? Obviously the keys in that case can be reduced.

noisesmith20:09:10

keys? that's a set

noisesmith20:09:25

the number 7 is being put in a set, and 7 can't be reduced

sophiago20:09:54

Oh, I feel foolish. I've hardly used sets before this. One second...

sophiago20:09:46

Actually, wait (I was just going to provide an example where I nest the vectors with the scalars and only reduce the vectors) the documentation does refer to "keys."

sophiago20:09:03

"Returns a new sorted set with supplied keys, using the supplied comparator. Any equal keys are handled as if by repeated uses of conj."

noisesmith20:09:27

right - but in a set they are all keys

sophiago20:09:55

Yeah, that language is confusing. I understand it's correct in terms of what keys are in Clojure colls, it's just odd to think of them without corresponding values.

sophiago20:09:29

This example makes it pretty clear:

user=> (set {:one 1 :two 2 :three 3})
#{[:two 2] [:three 3] [:one 1]}

noisesmith20:09:52

that's very unclear, as it's using the implicit sequentialization of a hash-map to provide a sequence that is then made a set - the set function and the sorted-set function are not analogs, the analog to sorted-set is hash-set

sophiago20:09:59

It makes clear to me that sets don't have kv pairs and how they handle them in conversion.

sophiago20:09:50

It seems I probably want to use sorted-map-by and then convert to a regular set in order to use relational algebra functions.

noisesmith20:09:31

but that's not what that example demonstrates at all

noisesmith20:09:21

maybe I'm looking at this wrong

sophiago20:09:02

I think we're just referring to different things. I didn't realize converting a map to a set places the k-v pairs in vectors rather than preserving them. That's all.

noisesmith20:09:24

I don't know what "preserving" them means - in clojure when a hash-map is treated as a sequence, it is a sequence of key-value pairs, and set is a function on sequences

sophiago20:09:44

It's that last part: set is a function on sequences. I was under the mistaken assumption it worked on associative.

sophiago20:09:06

Unfortunately, this seems to kill my idea to use relational algebra functions on just the keys.

sophiago20:09:09

Fwiw, I was massively overthinking this. sorted-map alone preserves ordering of these colls in line with at least one of the two ordering schemes I'm deciding between. And (merge-with + ...) on two sorted-maps handles one of my uses cases entirely 😛

cfleming20:09:08

@bfabry @dpsutton Annotating the var instead of the arg vector does work correctly, although IIRC it was sort of by accident.

dpsutton20:09:48

type annotations have got to be one of the most murky things in clojure. thanks for the heads up @cfleming

cfleming20:09:56

One disadvantage is that if you have multiple arities, you can’t type hint them independently, but I hope you’re not relying on that anyway 🙂

cfleming20:09:10

@bfabry FWIW I always type hint the var, even though it’s not “correct”, because of the issue about having to fully qualify hints on the arg vector.

cfleming20:09:28

I’m on Clojure 1.7 still so it’s a problem for me.

bronsa20:09:52

yes, that is a problem, but since 1.8 fixed it, I would not reccomend type hinting the var. it doesn't work as intended for primitive type hints

bronsa20:09:34

so my suggestion is if you're using >=1.8.0, forget that type hinting on the var exists and always hint on the argvec

cfleming20:09:46

True, but I never use primitive type hints anyway, they’re just too quirky.

cfleming20:09:06

But I should add an inspection for that.

bronsa20:09:17

what's quirky about them?

cfleming20:09:38

Well, the var hinting issue, only allowing 4 params etc

cfleming20:09:50

@bronsa Actually I had a question for you about type hinting. I’d like to be able to mark type hints as unused when they’re not required. Is it the case that they’re not required (for local bindings, params etc) unless a) the local is used as the target of an interop call b) the local is used as a param of an interop call and is required to disambiguate overloads, or c) the binding is bound directly to another binding (and thus transfers its hint) and the other binding is used as in a) or b)?

cfleming20:09:58

Are there other cases to take into account?

noisesmith20:09:08

beyond marking unused hints, it would be nice to mention when they can statically be shown as wrong as well

bronsa20:09:03

@cfleming yes + also unless the type hint is a primitive one and used in an unboxed context

bronsa20:09:04

and return type hints are always potentially useful because they're non-local so unless you can controll all the callsites you can't know

cfleming20:09:57

Right, I’m just thinking about marking them as unused on locals.

cfleming20:09:23

I hadn’t thought of the boxing part, thanks - currently I’m not tracking that although it should be straightforward.

bronsa20:09:58

@cfleming are you doing this analysis pre macroexpansion?

bronsa20:09:31

thinking of the case of inlineable functions that expand to static calls

cfleming21:09:57

@bronsa Yes. What are the implications there - that the type hints need to be propagated from the parameters?

cfleming21:09:15

Do you mean inlineable or the intrinsics?

bronsa21:09:55

no, i mean like

(defn bc {:inline (fn [x] `(Long/bitCount ~x))} [x] (Long/bitCount x))
(defn foo [^long x] (bc x))

bronsa21:09:11

that type hint is still useful even if bc is a normal funcntion invocation, because of the inline

bronsa21:09:45

(same in the case where bc took a primitive long as parameter, this is a bit of an artificial example, but i'm thinking about e.g. the array functions in core)

cfleming21:09:04

Perhaps I won’t mark it unused if the local is used as a param on an inlineable function, because I can’t really tell in that case.

beoliver21:09:12

how do I extend a java type to have interface clojure.lang.ILookup? I tried

(extend VPackSlice
  clojure.lang.ILookup
  {:valAt (fn
            ([this k] (.get this k))
            ([this k default] (.get this k default)))})
but I get interface clojure.lang.ILookup is not a protocol

noisesmith01:09:08

right, ILookup is an interface, and you can't extend other people's code to Interfaces, only protocols

noisesmith01:09:56

you could use proxy to make something that extends VPackSlice and also implements ILookup, just calling the super method for every method outside ILookup

bronsa21:09:17

yeah seems sensible

bronsa21:09:22

same if bc were a macro

cfleming21:09:58

Right, being a macro is more restrictive though.

cfleming21:09:16

Inline functions aren’t that common, but macros are.

cfleming21:09:58

BTW the boxing thing should only affect primitive hints, right? Or can that also be affected by hints like ^Integer?

bronsa21:09:54

can't think of a case with non primitives of the top of my head

lxsameer22:09:53

hye guys, any idea how to generate nested arrays of integers using spec ?

bfabry22:09:59

boot.user=> (s/exercise (s/coll-of (s/coll-of integer? :kind vector?) :kind vector?) 1)
([[[-1 0 -1 0 -1 0 0 -1 -1 -1 0 0 0 -1 0 -1 -1 0 -1 0] [-1 0 -1 0 0 0] [-1 0 -1 0 0 0 0 0 0 -1] [0 0 0 0 0 -1 0 0 -1 -1 0 -1 0 0 -1 0 0 -1 0]] [[-1 0 -1 0 -1 0 0 -1 -1 -1 0 0 0 -1 0 -1 -1 0 -1 0] [-1 0 -1 0 0 0] [-1 0 -1 0 0 0 0 0 0 -1] [0 0 0 0 0 -1 0 0 -1 -1 0 -1 0 0 -1 0 0 -1 0]]])

moogey22:09:05

Does anyone know anything about pdfboxing or PDFBox? I’m trying to set some checkbox fields readonly and it doesn’t seem to stick.