Fork me on GitHub
#clojure
<
2019-04-01
>
potetm00:04:28

I see it in local scope for picking out options.

potetm00:04:19

(let [things ({:a [1 2 3], :b [4 5 6]} opt)] ...)

raaon01:04:19

newb here w/ an aot question. i'm compiling a (defrecord Foo ...) producing a jar containing the Foo.class then depending upon that jar from a java project i can successfully load Foo.class (ie, Class.forName("Foo")) dynamically from the java project but attempting to compile/`javac` statically against Foo (ie, import Foo from java), i get a compile error that the symbol can't be found

raaon01:04:03

javap Foo.class shows nothing suspicious. maybe something obvious, but i'm banging my head here..

potetm02:04:21

lotta variables there 🙂

potetm02:04:00

Is there a package? I can’t remember for sure, but I think Java disallows using the default package.

raaon02:04:08

ha, there is a package

Alex Miller (Clojure team)02:04:23

java doesn't disallow it, it's just discouraged

Alex Miller (Clojure team)02:04:41

maybe post the full compilation error?

raaon02:04:44

i used default package just to keep the question shorter 🙂

potetm02:04:07

next q: is the classpath properly set for the javac command?

raaon02:04:22

Error:(6, 30) java: cannot find symbol
  symbol:   class Foo
  location: class com.example

potetm02:04:28

it seems clear it’s properly set for the java command (since you’re able to access it via reflection), but it could be improperly set for the javac command

raaon02:04:31

yes the javac -cp ... is set

raaon02:04:44

i'm able to link against other .class files

raaon02:04:03

it makes me thing the .class generated by compiling the defrecord is special somehow

potetm02:04:45

to my knowledge, it is not

raaon02:04:29

this yields a successful compile/javac:

import com.example.*;
class Bar { public static void main(String[] args) throws Exception { System.out.println("hello"); } }
this doesn't:
import com.example.Foo;
class Bar { public static void main(String[] args) throws Exception { System.out.println("hello"); } }

raaon02:04:12

this compiles and runs w/o exception:

import com.example.*;
class Bar { public static void main(String[] args) throws Exception { System.out.println("hello"); Class.forName("com.example.Foo"); } }

potetm02:04:34

Are you overriding the classname? class Foo

raaon02:04:22

oh good question -no ..

raaon02:04:35

(i just edit my slack examples)

potetm02:04:20

Like I said, the last one is mostly irrelevant. It says nothing about the compilation.

raaon02:04:46

the one that succeeds of course doesn't if i get the javac -cp wrong

raaon02:04:53

and...

$ javap com/example/Foo.class 
Compiled from "model.clj"
public final class com.example.Foo implements clojure.lang.IRecord,clojure.lang.IHashEq...

potetm02:04:06

Yeah I dunno. Would probably need a full example.

potetm02:04:13

Good luck 😕

raaon02:04:19

hmm actually i might be on to something

raaon02:04:36

i think i have package and a class w/ the same name

raaon02:04:23

ok that seemed to be it

raaon02:04:45

however -- this seems like it'd be a common type of collision in clojure compiles ??

raaon02:04:34

...ie i (defrecord Foo... within (ns com.example)

raaon02:04:57

compiling yields a com/example.class and a com/example/Foo.class

raaon02:04:53

a javac / static compile finds import com.example.Foo and doesn't like it b/c com.example is a class ...this explains why the .forName("") worked and not the static compile

raaon02:04:21

but i guess i'm having trouble seeing why this wouldn't be a common thing

raaon02:04:15

...okay so i do have a (:gen-class) on the (ns com.example) so perhaps a slightly or much less common sitch?

raaon02:04:53

after many years of java coding i did not realize you couldn't safely have a package and class w/ the same name

...
com/example.class
com/example/Foo.class
...
^bad for javac apparently

raaon02:04:07

removing the (:gen-class) fixes the issue i guess the lesson is don't :gen-class ns's containing defrecord's?

raaon02:04:58

...revision: explicitly specify non-conflicting :name to gen-class will solve it too

Suren P04:04:40

Hey guys, I asked thi sin disc but none seems to know what's going on. I'm getting:

SEVERE: Error creating DB connection for {:classname "com.mysql.jdbc.Driver", :subprotocol "mysql", :subname "//<ip>:3306/proj_dev", :user "root", :password "A<censored>"}
java.sql.SQLException: No suitable driver found for jdbc:mysql://<ip>:3306/proj_dev
for migratus when running lein migratus migrate the db is completely empty, first time trying to migrate anything
With this in project.clj
  :migratus 
  {:store :database
    :migration-dir "migrations"
    :db {:classname "com.mysql.jdbc.Driver"
          :subprotocol "mysql"
          :subname "//<ip>:3306/proj_dev"
          :user "root"
          :password "*"}})
I'm not sure what I'm doing wrong I have connected to the server with MySQL Workbench

Suren P04:04:58

I'm trying to connect to a Google Cloud MySQL instance...

Suren P04:04:09

any ideas?

mourjo06:04:37

Hi every one, I wrote this utility as an alternative to with-redefs such that the redefinition is done only on that thread and not others (ie, the global definition remains the same and redefinitions are per-thread). This is a fork from @gfredericks’s original solution https://gist.github.com/gfredericks/7143494. Would appreciate if you could check it out to suggest improvements/corrections: https://gist.github.com/mourjo/c7fc03e59eb96f8a342dfcabd350a927 cc @h0bbit

Empperi06:04:05

Hmm. Has anyone else noticed a really slow startup times with lein repl when using JDK12?

Empperi06:04:33

My REPL timeouts almost always with JDK12, maybe 1 out of 10 succeeds to connect. With JDK10 it works normally

vlaaad07:04:58

try clojure 1.10.1-beta1

vlaaad07:04:31

there was a performance regression regaring user.clj that 1.10.1-beta1 addressed: https://dev.clojure.org/jira/browse/CLJ-2484

Empperi07:04:15

Oh, that has to be it! Cheers

Empperi07:04:56

Yeah, I can confirm that after changing to 1.10.1-beta1 REPL starts up normally

dmaiocchi10:04:04

hi all, i'm looking for a good API client HTTP project for reading the source code and design as muster

dmaiocchi10:04:47

do you have any example in the clojure ecosystem and lib in the opensource word? like it could be dunno, any library with rest-client

danielstockton11:04:14

Anyone using nginx-clojure and got it running with openjdk 10+? Project doesn't really seem maintained anymore.

rutledgepaulv14:04:39

I use nginx-clojure but i think it doesn’t handle java versions above 8 right now. I don’t think there’s much active development happening but it’s been stable for us.

👍 4
danielstockton11:04:37

Or perhaps someone can advise a better deployment method these days, with high performance?

mpenet11:04:37

define high performance? what's the use case

danielstockton11:04:43

Real time bidding, just want to squeeze out as much performance as possible, and nginx-clojure had decent benchmarks.

mpenet11:04:45

most of the time aleph or jetty is good enough. Not sure nginx-clojure performs better at all

Jephthah11:04:47

Hey guys, I just downloaded clojure via the installer for windows (it downloaded as powershell module). I need help getting it started.

Alex Miller (Clojure team)12:04:56

Please ask in #clj-on-windows for help...

mpenet11:04:11

aleph also scores better than openresty (same models as nginx-clojure I think) on other benchmarks, anyway I bet the kind of platform you're building will likely not have a bottleneck at this level

👍 4
sparkofreason14:04:08

Anybody have experiences to share using Akka with Clojure? I found a couple of small wrapper projects which look inactive. My main concern would be around the requirement that actor classes be serializable, so I'd think you would have to be cautious about typical Clojurisms like grabbing state in a closure.

deep-symmetry16:04:00

I was trying to point some of my users at the Clojure documentation to show all the options for spit, and hit a brick wall. The spit doc string does not list them, https://clojuredocs.org/clojure.core/spit and even if they are resourceful enough to look up the entry for writer that does not list them. I basically would need to teach them how to bring up a REPL and spelunk through the source code in order to get a definitive list. And they are mostly not software developers. This seems… unfortunate?

Alex Miller (Clojure team)16:04:14

jira welcome, I don't think there is one I'm aware of

deep-symmetry18:04:24

OK, I created one. I forgot that I even had an account on the JIRA. Thanks! Hopefully it was formatted correctly and sufficiently informative.

Alex Miller (Clojure team)19:04:20

thx, I added a patch

🎉 4
deep-symmetry19:04:29

Wow, that was fast! 😄

Alex Miller (Clojure team)20:04:17

easier to do it now before I forget about it :)

Braden Shepherdson18:04:24

I'm looking for a way to manage state reactively, where the crucial thing is that invalidations are eager and computing the new value is lazy (ie. on deref)

Braden Shepherdson18:04:34

I was thinking an agent with for each chunk of state I care about, that eagerly invalidate their listeners. but how can I override the deref behavior?

noisesmith18:04:37

does this match the semantics of a cache at all? with core.cache you can easily get custom access / lookup behaviors

noisesmith18:04:57

(while storing the cache itself in an atom, agent, whatever's apropriate)

Braden Shepherdson18:04:04

hm, I wasn't thinking of it in terms of a cache at all. it's not a typical cache, but perhaps I could (ab)use hundreds of 1-element caches for this.

Braden Shepherdson18:04:36

the use case is a large reactive system, containing many hundreds of entities and links between them, but where only a handful of entities are "live" at any given time.

Braden Shepherdson18:04:16

if the invalidations are eager, the views for the few things that are live will know they need to rerender. meanwhile, the rest of the world might be invalid but that's harmless.

noisesmith18:04:39

hmm, sounds a lot like what react does under the hood actually

Braden Shepherdson18:04:16

not dissimilar in principle.

noisesmith18:04:21

what's the difference between "hundereds of 1-element caches" and "a cache with an index"

Braden Shepherdson18:04:02

depends on whether invalidation happens at the entry level or the cache level, I guess. I'm reading the core.cache docs now.

noisesmith18:04:07

I guess you'd need it loop it through - the cache forcing function would need to look up its data sources in the cache and invalidate it's descendents? now that I think about it you probably want a proper reactive system and not hacking it direclty out of cache / agent building blocks(?)

Braden Shepherdson18:04:20

well, I mentioned agents because that's what it felt like when I was vaguely thinking about it last night. but I think there's a bunch of extra bookkeeping to do that pushes me to use a default implementation. I'll probably end up building each reactive block out of a handful of refs I transact over, I guess.

noisesmith18:04:24

it uses rxjava iirc

noisesmith18:04:32

it uses rxjava, futures, and core.async in various examples

hiredman18:04:39

react, if I understand, doesn't actually use caches(so avoids figuring out cache invalidation), but diffs the virtual dom to determine what needs doing

noisesmith18:04:48

yeah, by extension you could use it to turn data dependency in a data flow app into smart invalidations, but that's still a stretch I think

Braden Shepherdson18:04:17

for my purposes, the wiring of dependencies is explicit, so I don't need to infer it. I just want to avoid having to unwire and rewire things as the user navigates.

Braden Shepherdson18:04:56

anyway, I'm just building a prototype, so I'll just hack something together and not sweat it too hard for this first POC.

yuhan19:04:23

Is there any way to dynamically un-extend a protocol?

noisesmith19:04:23

assign method implementations that all throw unimplementederror?

yuhan19:04:34

use-case: I have a default java.lang.Object implementation of a Foo protocol

yuhan19:04:55

then I extend it to clojure.lang.Seqable in the REPL

yuhan19:04:17

afterwards I realise I don't want that implementation to include hash maps, so I change that to a clojure.lang.Sequential

yuhan19:04:13

how do I disassociate Seqable so that calling a Foo method on a hash map falls back to the default Object implementation?

yuhan19:04:11

(without restarting the entire REPL)

noisesmith19:04:38

@qythium the extension of the method is stored with the protocol implementation (iirc in the var itself or its metadata) and can in theory be removed, I don't know if there's anything that would be portable though

noisesmith19:04:26

@qythium this should be enough info for a short term hack, but no promises it would work with the next clojure release

(ins)user=> IFoo
{:on user.IFoo, :on-interface user.IFoo, :sigs {:frob {:name frob, :arglists ([this]), :doc nil}}, :var #'user/IFoo, :method-map {:frob :frob}, :method-builders {#'user/frob #object[user$eval145$fn__146 0x42f33b5d "user$eval145$fn__146@42f33b5d"]}}
(ins)user=> (extend Object IFoo {:frob (fn [x] [:obj x])})
nil
(ins)user=> IFoo
{:on user.IFoo, :on-interface user.IFoo, :sigs {:frob {:name frob, :arglists ([this]), :doc nil}}, :var #'user/IFoo, :method-map {:frob :frob}, :method-builders {#'user/frob #object[user$eval145$fn__146 0x42f33b5d "user$eval145$fn__146@42f33b5d"]}, :impls {java.lang.Object {:frob #object[user$eval162$fn__163 0x3e14c16d "user$eval162$fn__163@3e14c16d"]}}}

noisesmith19:04:06

usually protocol / interface / multimethod changes are the one reason I do an unconditional repl restart, and I try to work on my design in such a way that those would change extremely rarely (which makes sense, as they are all meant to be top level entry points for other code)

yuhan19:04:22

tried doing (def Foo (update Foo :impls #(dissoc % clojure.lang.Seqable))), but that didn't work

yuhan19:04:35

guess I'll just have to restart the repl.. had lots of "testing data" state built up from evaluating commented forms which I didn't want to lose, but that's probably another sign of general sloppiness

noisesmith19:04:53

I'd suspect alter-var-root rather than def/update to be the right path, if anything worked

yuhan20:04:52

hmm, that doesn't do the trick either

Alex Miller (Clojure team)20:04:09

protocol choices get baked into per-call-site caches so it's probably difficult to do this fully without restarting your repl

4
orlandow22:04:09

Hello, I’m having some issues working with mutable Java arrays and can’t find what is going on. This code is supposed to return 5 but returns 0

(let [m (to-array [0 0 0])
      _ (for [i (range 3)]
          (aset m i 5))
      x (aget m 2)]
  x)
;; => 0
Now, when I eval it one form at a time it correctly returns 5
(def m (to-array [0 0 0]))
;; => #'user/m
(for [i (range 3)]
  (aset m i 5))
;; => (5 5 5)
(aget m 2)
;; => 5
Maybe I’m missing something obvious :thinking_face:

dpsutton22:04:57

classic laziness. for returns a lazy collection and is not a good choice for performing side effects like mutating an array. What you are seeing is that nothing is realizing the collection so no work is ever done. the result is that the original array contains 0s rather than 5s

orlandow22:04:32

right, of course, thanks!

dpsutton22:04:50

do you know the best way to fix it or want to ponder/work at it some more?

dpsutton22:04:56

(or already know the answer :)

orlandow22:04:54

I was going to try a doseq, is that enough? :thinking_face:

dpsutton22:04:35

that's what i would do

orlandow22:04:42

cool!, thanks 👍

metametadata22:04:50

> if the invalidations are eager, the views for the few things that are live will know they need to rerender. meanwhile, the rest of the world might be invalid but that's harmless. @braden.shepherdson isn't this how some CLJS view libs work? E.g see Reagent (`reaction` and ratom), Rum (reactive components and derived atoms), hoplon+javelin, etc.

yedi23:04:05

hey guys, whats the cleanest way to append something to the end of a vector within a thread last macro

yedi23:04:35

(->> v (conj e)) and (->> v (concat [e])) don't work for obvious reasons

yedi23:04:57

am i stuck having to create a let binding for this?

aryyya23:04:56

Are there any compelling reasons to prefer the loop and recur pattern over recursive function calls?

metametadata23:04:08

@yedicould be the case for as-> instead of ->>

jumpnbrownweasel23:04:56

@yedi I don't understand why you say your first example doesn't work, this works for me:

(let [c [1 2], v 3] (->> v (conj c)))
=> [1 2 3]

jumpnbrownweasel23:04:11

Oh, v is the vector not the value. Never mind.

noisesmith23:04:43

@yedi ->> and as-> are written so they can be nested inside ->

noisesmith23:04:17

you can use -> at the top level, and use ->> / as-> for parts of the pipeline inside that need to use the tread-last behavior

noisesmith23:04:01

user=> (-> [] (conj [:a 0]) (->> (into {})))
{:a 0}