Fork me on GitHub
#clojure
<
2019-10-23
>
valerauko07:10:44

kibit is yelling at me for trying to map over a closure

(defn foo [tag ids]
  (map (fn [id] [tag id]) ids))
tells me
Consider using:
  tag
instead of:
  (fn [id] [tag id])
any idea how could i resolve this without disabling linting?

schmee07:10:27

what types are tag and id?

vlaaad07:10:54

kibit is wrong, it thinks it's (fn [id] (tag id)), which can be simplified to tag

Arto Kalishian07:10:01

Good morning! All of these solutions are working for me on the REPL, but they're not working on 4clojure. What's wrong?

Arto Kalishian07:10:36

Ok, sorry guys.. I forgot the exclamanation mark! 🙂

dominicm07:10:04

I've written a small clojure interpreter that takes edn code and runs it. Unfortunately I've hit a limitation on . forms, e.g. .close. I don't really know how to run such a thing in the JVM? Do I need to use reflection?

vlaaad07:10:51

do you run eval on edn?

dominicm08:10:35

Not at the moment, no. Eval couldn't handle things like futures as arguments

schmee08:10:26

@dominicm yes, that would require reflection, here’s where the Clojure compiler handles all that stuff: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java

dominicm08:10:25

ah, great, thanks

dominicm08:10:35

To check, is there no alternative to eval which can evaluate something like:

user=> (eval `(deref ~(delay 1)))

borkdude08:10:54

is it possible to specify a different named file than project.clj to lein?

borkdude08:10:04

@dominicm you want to pass in an already evaluated binding to the expression, right?

borkdude08:10:42

the way I handle that in sci is:

(sci/eval-string "(deref d)" {:bindings {'d (delay 1)}})
1

dominicm08:10:24

@borkdude that's great. Are you open to adding member access to sci?

borkdude08:10:05

yeah, I was considering it

borkdude08:10:34

in graalvm that might be tricky, but for JS/CLJS it would work

echavis14:10:02

Is there an existing library somewhere to transform Swagger models to specs? I see https://github.com/metosin/spec-tools for going spec -> swagger, but I haven't found anything going the other way.

danieroux14:10:38

How do I extract "src/clj/collection/sensordata_test.repl" 117 from the ex-info below?

#error{:cause "Transcript assertion failed! -- Spec failed --------------------

                 true

               should satisfy

                 false?

               -------------------------
               Detected 1 error
               ",
       :data #:clojure.spec.alpha{:problems [{:path [], :pred clojure.core/false?, :val true, :via [], :in []}],
                                  :spec #function[clojure.core/false?],
                                  :value true},
       :via [{:type clojure.lang.ExceptionInfo,
              :message "Transcript assertion failed! -- Spec failed --------------------

                          true

                        should satisfy

                          false?

                        -------------------------
                        Detected 1 error
                        ",
              :data #:clojure.spec.alpha{:problems [{:path [], :pred clojure.core/false?, :val true, :via [], :in []}],
                                         :spec #function[clojure.core/false?],
                                         :value true},
              :at [collection.sensordata_test$eval59578
                   invokeStatic
                   "src/clj/collection/sensordata_test.repl"
                   117]}],
       :trace [[collection.sensordata_test$eval59578
                invokeStatic
                "src/clj/collection/sensordata_test.repl"
                117]]]}

bfabry14:10:23

looks like (take-last 2 (get-in (ex-info e) [:trace 0])

danieroux15:10:03

Did you mean ex-data? Because that’s:

#:clojure.spec.alpha{:problems [{:path [], :pred clojure.core/false?, :val true, :via [], :in []}],
                     :spec #function[clojure.core/false?],
                     :value true}

bfabry15:10:36

I’m getting a little thrown by the presentation here. the ExceptionInfo presents like a map but is not one?

danieroux15:10:13

Yes, and I'm also quite thrown. Excuse the pun.

bfabry15:10:04

can you get-in on the exception itself that is being shown?

danieroux15:10:36

(and see the keys or vals)

bfabry15:10:19

which is what the repl is calling for its presentation

danieroux16:10:07

Thank you @U050MP39D! That was the fn I could not find 🙂

vlaaad15:10:39

hmm, 2 recent questions on http://ask.clojure.org are asked by @alexmiller, is this legit or a bug?

Alex Miller (Clojure team)15:10:17

op asked 3 questions in one question so I split into 3

vlaaad15:10:10

ah, okay, sorry

devn16:10:29

i'm looking for library to do haversine distance and handle conversion between units (km, miles, etc.)

devn16:10:59

im happy to do interop, but also wouldn't mind a clojure-y solution -- i've googled, but am wondering if anyone has a recommendation

devn17:10:22

(i'm allergic to dependencies, so something light in that area would be preferred)

devn17:10:12

i may just go ahead and implement it, but a small lib with some added convenience would be nice

yuhan17:10:31

not sure if this is the appropriate channel, but how do I make a JFrame "visible" to Mac OS? Such that it appears in the Dock / can be switched to via Cmd-Tab

yuhan18:10:05

got it, I just had to start the REPL with JVM option -Dapple.awt.UIElement=false

devn17:10:43

@lukaszkorecki yeah, was looking at that, sort of makes me just want to write the basic formula myself

(defn haversine-distance
  [start-lat start-long end-lat end-long]
  (let [earth-radius 6372.8
        haversin (fn [x] (Math/pow (Math/sin (/ (double x) 2)) 2))
        d-lat (Math/toRadians (- end-lat start-lat))
        d-long (Math/toRadians (- end-long start-long))
        start-lat (Math/toRadians start-lat)
        end-lat (Math/toRadians end-lat)
        a (+ (haversin d-lat)
             (* (Math/cos start-lat)
                (Math/cos end-lat)
                (haversin d-long)))
        c (* 2 (Math/atan2 (Math/sqrt a) (Math/sqrt (- 1 a))))]
    (* earth-radius c)))

devn17:10:34

however, i do wonder down the line if ill run into more of this kind of thing. I saw there's a clojure geo and geo-clj, gonna give those a peek next

chrisn17:10:31

The only one I have found aside from things like that so far is in apache lucene.

Eduardo Mata17:10:25

Hello, I am running integrant with a the capability to create processors. Processors have a handler that subscribes to a redis topic for subscribing and publishing. Such configuration is done reading a edn file with a vector of maps such as the following

[{:sub :telephone
  :handler myapp.processor/telephone
  :pub {:channel :fax}}]
anwyay, this work great. However, the processor for telephone call different functions and the function send data to a sse stream. I run the jar file such as java -jar target/myapp.jar` and I get an exception such as
Caused by: java.lang.IllegalAccessError: send-data-sse does not exist

More interesting, if a stop the jar file and run it again the exception is gone. IF i repeat the same process, It will be running with exception then without exception

noisesmith17:10:06

sounds like the kind of problem you get when using aot / gen-class and then having some part of your app reload the definition in the running process

noisesmith17:10:13

just a hunch though

hiredman17:10:14

the exception message doesn't seem to name the thing from the handler so possibly unrelated

hiredman17:10:10

you are some how creating an empty namespace that is supposed to contain send-data-sse, but doesn't, and trying to use send-data-sse then causes that error

hiredman17:10:52

the main integrant project doesn't mention processors, and googling didn't turn up any integrant based library with whatever those are, but I am kind of guessing, if your example configuration is just made up data, but the error shown is the real error, that would explain why they don't match, and likely whatever the code is that adds this processor feature it is broken

Eduardo Mata18:10:26

There is nothing about processors. It was a self implementation. It works great to receive data, processed it, and send it somewhere. one processor handler diverges the data to separate namespaces to process the data differently for an specific output and send that out to another redis channel. the namespaces all of them use sse-send-data and for some reason when the jar file is ran once it runs 100% good. The second or third time, will throw out the exception at the moment the jar file is run for some reason I can't explain

Eduardo Mata18:10:52

I do this with several micro services using the same integrant boilerplate. Only one service is throwing this out to me.

hiredman18:10:18

my guess is your processor code isn't correctly loading the namespace of the handler

hiredman18:10:10

and you have some kind of race condition where the namespace may be loaded normally before the process stuff gets to it

hiredman18:10:28

in fact, it seems a good bet that the difference between the cases where you get the error and not is based on if there is a message "in the queue", and what is happening is your handler code is being run before the namespace is loaded

hiredman18:10:17

e.g. 1st run, there is a message in queue, immediatly grabbed and is attempted to be processed before the namespace with the handler is loader, 2nd run that message has been removed from the queue, so no error

hiredman18:10:18

since processors are something you created, I would also strongly suggest that they should be other things in the integrant dependency graph, not functions in a var, so if they depend on anything else in that graph it is captured there. using a function in a var (a global) means if your "processor" needs any other functionality to only way to get it is via a global

practicalli-johnny19:10:11

Curious how this 4Clojure solution works, it seems that \c matches \( and I haven't found any explanation whilst searching

(comp {\# :set \{ :map \[ :vector \c :list} first str)
http://www.4clojure.com/problem/65 The code is a very simple parser that gets the first character of a collection and uses a dictionary (hash-map) to return the relevant keyword. Is the \c a peculiarity of 4Clojure and its version of Clojure or some interesting ascii code or character literal? Thanks.

Alex Miller (Clojure team)19:10:53

why do you think it matches?

practicalli-johnny19:10:45

I dont think it does, but it passed the 4Clojure tests

Alex Miller (Clojure team)19:10:49

afaik, there is nothing special about \c and it should not match \(

Alex Miller (Clojure team)19:10:35

one note is that 4clojure runs a very old version of clojure and potentially there is some difference or bug there, don't know

practicalli-johnny19:10:12

This is my fallback assumption if no one else knows of why this works 🙂

Alex Miller (Clojure team)19:10:35

I can actually repro that on Clojure 1.4

👍 4
Alex Miller (Clojure team)19:10:07

answer: "clojure.lang.LazySeq@db6f4287"

Alex Miller (Clojure team)19:10:39

user=> (str (range (rand-int 20)))
"clojure.lang.LazySeq@9ebadac6"

Alex Miller (Clojure team)19:10:19

lazy seqs used to toString like that (they now print the sequence) - this changed at some point

Derek19:10:37

that appears to be half right

Clojure 1.10.1
user=> (str (range (rand-int 20)))
"(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)"
user=> (str (map identity (range (rand-int 20))))
"clojure.lang.LazySeq@a0c74788"

Alex Miller (Clojure team)19:10:00

maybe it was the range re-impl in 1.7 that changed that

bfabry19:10:51

not to distract from the discussion too much but I’m laughing quite a lot at toString’ing the collection as an answer to that problem

Alex Miller (Clojure team)19:10:06

:) pr-str will do what you want here on any version btw

Derek19:10:13

it’s likely a code golf solution

Alex Miller (Clojure team)19:10:09

yeah, this was changed in the range re-impl

Alex Miller (Clojure team)19:10:39

range is now supported by two (well, actually 3) impls

Alex Miller (Clojure team)19:10:27

the 99% case is a range defined only by start/stop/step with longs in LongRange. These are always finite so there is no reason to protect against printing infinite lazy seqs. That's the case above.

Alex Miller (Clojure team)19:10:16

other finite ranges are in Range, those will also print all

Alex Miller (Clojure team)19:10:23

looks like infinite ranges also try to print as of 1.7, but you will wait a long time for that to fail :)

Alex Miller (Clojure team)19:10:27

but perhaps the better lesson is to not ever try to print potentially infinite sequences

Alex Miller (Clojure team)19:10:29

I'm not sure I understand the point of that 4clojure question given its restrictions (which excludes all the predicates that you would normally use for this)

bfabry19:10:27

I think it’s trying to point out adds to head vs tail

bfabry19:10:33

but it’s a roundabout way

Alex Miller (Clojure team)20:10:55

well that is a long way to go for that

practicalli-johnny19:10:53

Thanks for solving this little mystery Alex, much appreciate

emccue23:10:53

question about implementation i guess

emccue23:10:08

i know gen-class cannot redefine itself when loaded into a repl

emccue23:10:43

i thought the reason was that the JVM didn't support multiple classes with the same name

emccue23:10:54

but defrecord seems to handle this somehow

emccue23:10:17

just a bit confused

hiredman23:10:14

The jvm can be bent to all kinds of shapes

hiredman23:10:28

I think the actual rule is closer to you can only have one class with a given name per classloader, but you can have as many classloaders as you like

hiredman23:10:41

Way back, before 1.0, the way clojure namespaces are compiled changed, and before that clojure had a more flexible class generating macro, but that was removed and replaced with gen-class which is more restrictive and tied to aot compilation

seancorfield23:10:19

@emccue Those are two different A classes:

user=> (defrecord A [])
user.A
user=> (def a1 (A.))
#'user/a1
user=> (defrecord A [])
user.A
user=> (def a2 (A.))
#'user/a2
user=> (class a1)
user.A
user=> (class a2)
user.A
user=> (= (class a1) (class a2))
false

hiredman23:10:22

am not sure, but I believe the difference between records and gen-class there is intended use

hiredman23:10:10

because records are primarily intended to be used from clojure, having their behavior match clojure's more dynamic abilities is useful

emccue23:10:22

@seancorfield That makes perfect sense

emccue23:10:38

but i guess what im driving at is - why does that work when this doesn't

emccue23:10:44

(gen-class
  :name "some.package.Apple")
=> nil
some.package.Apple
Syntax error (ClassNotFoundException) compiling at (form-init15779309300631176008.clj:1:1127).
some.package.Apple

hiredman23:10:15

but gen-class is more for interop, for which aot with a stable classloader is better

emccue23:10:54

that argument doesn't make all that much sense to me - a usecase of definterface and co. is already to AOT and use from java as needed

emccue23:10:52

defrecord and defprotocol also work about the same under aot afaik

noisesmith23:10:56

gen-class is explicitly a no-op when not compiling from a file

hiredman23:10:08

when not aot compiling

seancorfield23:10:45

From the gen-class docstring: "When not compiling, does nothing."

emccue23:10:03

(gen-interface :name "some.package.Orange")
=> some.package.Orange
(import some.package.Orange)
=> some.package.Orange

emccue23:10:11

i understand that is what it does

emccue23:10:21

but im more stuck on the why

hiredman23:10:21

gen-class also predates records and protocols etc by fair amount

emccue23:10:43

ah okay so its at least not rejected out of hand

emccue23:10:11

The only reason why this wasn't also done for gen-class is that I forgot about it.

hiredman23:10:22

I forget what "triaged" means for approval

hiredman23:10:35

that is commentary from the person who opened the ticket

hiredman23:10:55

not commentary from someone with decision making power (as far as I know)

andy.fingerhut23:10:24

triaged means Alex Miller marked it that way, and thinks it is worth Rich considering it for vetting, meaning roughly "interested in a fix"

noisesmith23:10:26

IIRC a thing that is triaged is put aside for the sake of something more urgent, or placed before something less urgent, and you need more context to know which

noisesmith23:10:03

it literally means "assigned some degree of urgency"

hiredman23:10:17

it is a distinct state in the clojure jira

emccue23:10:21

nah it means that its a triangle

hiredman23:10:34

and I was referring to that, not generally what does the word mean

noisesmith23:10:06

yeah I was criticising this use of language, not being pedantic

noisesmith23:10:14

or - not trying to be

andy.fingerhut23:10:20

scroll down to "Workflow" section

hiredman23:10:46

yes, thanks

andy.fingerhut23:10:44

It seems reasonable to use a word like triaged for this, if you think the word has any meaning outside of a medical context at all. The triaged tickets have been examined by one professional (Alex) for their judgement, and put into the bin of "more urgent than the ones not so marked".

noisesmith23:10:26

the synonym "prioritized" not only shares the meaning, but also is unambigous (and has the here intended meaning) when used generically

emccue23:10:48

anywho i think i understand now - historical artifact, not ongoing technical blocker

emccue23:10:23

though i can understand why it might not be desired in the end

emccue23:10:42

definterface is basically just a wrapper on gen-interface

emccue23:10:19

and if gen-class worked the same way i could imagine a few creative ways to make defclass and annonymous-class

hiredman23:10:51

you could just do it

hiredman23:10:30

there are plenty of bytecode generation libraries

hiredman23:10:55

like, gen-class as a macro doesn't rely on special support from the compiler

emccue23:10:26

good point

emccue23:10:36

but also i have no pressing need