Fork me on GitHub
#clojure-dev
<
2019-11-09
>
seancorfield02:11:17

Interesting failure in Clojure's ability to find methods...

seanc@DESKTOP-QU2UJ1N:/mnt/c/Users/seanc/clojure$ clj -Sdeps '{:deps {org.ojalgo/ojalgo {:mvn/version "47.2.0"}}}'
Clojure 1.10.1
user=> (import '(org.ojalgo.matrix PrimitiveMatrix))
org.ojalgo.matrix.PrimitiveMatrix
user=> (set! *warn-on-reflection* true)
true
user=> (def m (.makeZero PrimitiveMatrix/FACTORY 2 2))
#'user/m
user=> m
#object[org.ojalgo.matrix.PrimitiveMatrix 0x62566842 "org.ojalgo.matrix.PrimitiveMatrix < 2 x 2 >\n{ { 0.0,\t0.0 },\n{ 0.0,\t0.0 } }"]
user=> (def m (.makeEye PrimitiveMatrix/FACTORY 2 2))
Reflection warning, NO_SOURCE_PATH:1:8 - call to method makeEye on org.ojalgo.matrix.PrimitiveMatrix$Factory can't be resolved (argument types: long, long).
Execution error (IllegalArgumentException) at clojure.main/main (main.java:40).
No matching method makeEye found taking 2 args for class org.ojalgo.matrix.PrimitiveMatrix$Factory
user=>
See http://generated.ojalgo.org/org/ojalgo/matrix/PrimitiveMatrix.html and http://generated.ojalgo.org/org/ojalgo/matrix/PrimitiveMatrix.Factory.html (repro'd on Java 8 and Java 10 so far -- so I don't think this is a Java 9+ change issue?).

seancorfield02:11:06

It looks like you can call any method that has just one declaration -- no overloads -- but cannot call any of the overloaded methods.

borkdude09:11:41

@lee and me are collection information on GraalVM / CLJ-1472 here: https://github.com/lread/clj-graal-docs/blob/master/CLJ-1472/README.md welcome to add / improve

đź‘Ť 8
dominicm18:11:18

Am I reading correctly that ns is additive? (based on macroexpansion) I'm thinking of writing a user.clj which will load other user.clj's if they are present.

dominicm18:11:55

The idea being to allow a developer a point where they can load some side-effects/namespaces automatically for developer conveniences (e.g. hooking in dot-slash https://github.com/gfredericks/dot-slash-2)

andy.fingerhut19:11:50

I'm not sure if I know what you mean by "additive" there, but there are probably some cases of changing the code of an ns form that would be odd to describe as additive, e.g. version 1 of an ns form contains (:refer-clojure :exclude [vector]), and after editing it you change it to (:refer-clojure :exclude [vector vec subvec])

andy.fingerhut19:11:57

Or version 1 of the ns form uses foo as an alias for namespace X, but after editing you instead use foo as an alias for a different namespace.

andy.fingerhut19:11:00

but maybe those examples are not relevant to your question.

ghadi19:11:17

@seancorfield turns out makeEye is a public method on a private class

ghadi19:11:38

You can’t call it from Java, according to my test in JShell

ghadi19:11:49

It is unrelated to overloading

ghadi19:11:39

Sigh, maybe it is... @seancorfield I’m clearly confused

dominicm19:11:19

By additive I mean that given there's an existing ns, does calling ns a second time delete requires, etc.

dominicm19:11:28

Refer clojure is a good one to check

andy.fingerhut19:11:27

Calling ns a second time on the same namespace does not undo any requires done before. It might repeat a require on one or more namespaces, which IIRC require will not re-load the code of an already-required namespace unless you use an option like :reload to force loading the code again.

đź‘Ť 4
seancorfield19:11:42

@ghadi well you can call any method that is not overloaded...

dominicm20:11:31

I'm gonna push on with my user idea then. I think the naming of user implies that it's for the user, not really for a project to set.

dominicm21:11:50

Is there any way to nest REPLs inside of prepl? In a "normal" REPL this works perfectly fine, but in a prepl you get everything coming over :out

cgrand18:11:29

For some value of perfect. Or of REPL. Plain REPLs nest perfectly well as long as they don’t mess with reading, eval or print.

dominicm21:11:57

❯ nc localhost 5678
(+ 1 1)
{:tag :ret, :val "2", :ns "user", :ms 1, :form "(+ 1 1)"}
(clojure.core.server/io-prepl)
(+ 1 1)
{:tag :out, :val "{:tag :ret, :val \"2\", :ns \"user\", :ms 1, :form \"(+ 1 1)\"}\n"}
Interesting really 🙂 But not useful

cfleming21:11:46

@dominicm I don’t think so - this is the fundamental difference between structured and streaming REPLs.

dominicm09:11:37

I think this could be worked around perhaps specifically for nesting the same type (prepl -> prepl). But cgrand is talking about a more general nesting solution.

cfleming21:11:53

Right, if the two repls have knowledge of each other and can interact, then it can be done, but it’s not arbitrary nesting.

dominicm23:11:10

User configurable is fine imo. The things I'm looking at subrepl for aren't controlling out, they're binding variables and pausing execution.

dominicm23:11:14

I understand it's not some for some things though.

dominicm21:11:25

Hmph. That's frustrating. I want to take over the original in/out I suppose.

sogaiu21:11:00

tangentially related, EwenG's replique provides some switching among programmatic and streaming repls, iiuc -- going through the overview demos this: https://github.com/EwenG/replique#overview

dominicm21:11:56

huh, how does replique load itself there oh, custom main, oops

dominicm21:11:47

replique is definitely in a similar space to me though, I'm looking at things like user-local init.clj and such

borkdude21:11:55

updated performance test of CLJ-1472. before there was probably lock eliding in play: https://github.com/lread/clj-graal-docs/tree/master/CLJ-1472#performance

cgrand18:11:29

For some value of perfect. Or of REPL. Plain REPLs nest perfectly well as long as they don’t mess with reading, eval or print.