redplanetlabs / proxy-plus Goto Github PK
View Code? Open in Web Editor NEWA replacement for Clojure's proxy that's 10x faster and more usable
License: Apache License 2.0
A replacement for Clojure's proxy that's 10x faster and more usable
License: Apache License 2.0
Would be nice to have an equivalent to Clojure's proxy-super. May or may not be possible to do efficiently. One idea is to wrap the call to super
in a lambda and make the lambda available to the clojure body code via a binding.
Awesome project!
There is a issue though, only when the class was generated from AOT, when I try to use it I get a exception
(ns foo)
(proxy+ Foo
[]
java.util.Date
(toString [_] "foo"))
(.toString (com.github.clojure_lsp.intellij.extension.formatting.Foo.)) ;; throws exception only when class was generated from AOT
java.lang.NullPointerException: Cannot invoke "clojure.lang.IFn.invoke(Object)" because "this.toString13132" is null
at foo.Foo.toString (:-1)
Hello,
ASM has eveloved, the current release is from 2013.
New versions support newer JDK releases. See https://asm.ow2.io/versions.html .
I did upgrade locally and it builds and the tests pass - but did not try any code against other jvm's .
Perhaps an automated build to test against multiple JVM might be a good option.
(⎈ |libris-k2-admin:prod)ieugen@daos-495:~/.../clojure/proxy-plus$ lein test
Retrieving org/ow2/asm/asm/9.2/asm-9.2.pom from central
Retrieving org/ow2/asm/asm-commons/9.2/asm-commons-9.2.pom from central
Retrieving org/ow2/asm/asm-tree/9.2/asm-tree-9.2.pom from central
Retrieving org/ow2/asm/asm-analysis/9.2/asm-analysis-9.2.pom from central
Retrieving org/ow2/asm/asm-util/9.2/asm-util-9.2.pom from central
Retrieving org/ow2/asm/asm-commons/9.2/asm-commons-9.2.jar from central
Retrieving org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar from central
Retrieving org/ow2/asm/asm-util/9.2/asm-util-9.2.jar from central
Retrieving org/ow2/asm/asm/9.2/asm-9.2.jar from central
Retrieving org/ow2/asm/asm-analysis/9.2/asm-analysis-9.2.jar from central
lein test com.rpl.proxy-plus-test
Ran 13 tests containing 52 assertions.
0 failures, 0 errors.
It can be frustrating to work out what type signatures are available. It'd be helpful to include a list of options on errors (demo: https://github.com/owenRiddy/proxy-plus-minus/blob/main/src/proxy_plus_minus/core.clj#L122).
What this looks like using the proposed custom hinting from Issue #20 :
(proxy+ [] TestBaseClass3
(trickyCase [this a b] [char java.lang.String :=> int] 8))
=>
Caused by: clojure.lang.ExceptionInfo: No matching methods {:base testclasses.TestBaseClass3,
:name "trickyCase",
:param-type [char java.lang.String :=> int],
:param-type-options (["finalize" [:=> void]] ["clone" [:=> java.lang.Object]]
["getInt" [:=> java.lang.Integer]] ["getDouble" [int double java.lang.String java.lang.Integer boolean :=> double]]
["getString" [java.lang.String :=> java.lang.String]] ["getOtherInt" [:=> int]]
["trickyCase" [int java.lang.String :=> int]] ["trickyCase" [java.lang.Integer java.lang.String :=> int]]
["wait" [long int :=> void]]
["wait" [:=> void]] ["wait" [long :=> void]] ["equals" [java.lang.Object :=> boolean]]
["toString" [:=> java.lang.String]] ["hashCode" [:=> int]] ["getClass" [:=> java.lang.Class]]
["notify" [:=> void]]
["notifyAll" [:=> void]])}
;; Programmer thinks: 'Aha! I want ["trickyCase" [int java.lang.String :=> int]]
;; so I should use [int java.lang.String :=> int]'
I'm not sure if this is supported but just not documented, but I was wondering how to do something like proxy-super
e.g. java.io.Writer
's write(String str, int off, int len)
and write(char[] cbuf, int off, int len)
Here's a (silly) example:
user=> (import java.io.File)
java.io.File
user=> (defn mkfile [^String pathname] (proxy+ [pathname] File))
Reflection warning, NO_SOURCE_PATH:1:33 - call to user.proxy_plus6169 ctor can't be resolved.
#'user/mkfile
The problem only occurs when multiple constructors have the same arity. I think the problem goes away if you type hint (as java.util.Map) the function map which is passed when invoking the constructor.
This doesn't work with deps.edn
if you just add the dependency as is:
Error building classpath. Could not find artifact com.rpl:rama-shaded-asm:jar:4.2 in central (https://repo1.maven.org/maven2/)
unless you add a :mvn/repos
entry like
{:mvn/repos {"rpl" {:url "https://nexus.redplanetlabs.com/repository/maven-public-releases"}}}
but this has downsides, since adding the extra maven repo has to be done for anything upstream that might be using something using this library.
Any chance you can add the dependency to Clojars as well? If not, it's probably worth calling this out in the README so other people don't get tripped up on it
Hi again. I have detected a tricky edge case. I'm don't know Java very well, so bear with me if I get something wrong here:
public class TestBaseClass3{
public int trickyCase(int a, String b) {
return 6;
}
public int trickyCase(java.lang.Integer a, String b) {
return 7;
}
}
It is trickey to override the trickyCase that returns 6.
(proxy+ [] TestBaseClass3
;; Impossible: "Only long and double primitives are supported"
(trickyCase [this ^int a b] 8))
I propose that there should be an option to explicitly declare the type signatures independent of hints. I found something like (trickyCase [this a b] [int java.lang.String :=> int] ...) ergonomic (example: https://github.com/owenRiddy/proxy-plus-minus/blob/main/test/clj/proxy_plus_minus/core_test.clj#L276).
If you like the idea I can put together a PR for proxy-plus
.
Hello,
I am trying to extend an abstract class and also implement custom methods (not belonging to an interface / abstract class).
Is this possible?
I tried but it failed with error.
I also tried defining a protocol:
(defprotocol ICsvTable
"Some extra CSV table methods"
(isStream [this] "Return true if table is stream")
(getFieldTypes [this type-factory] "Returns the field types of this CSV table."))
(defn csv-table
[^Source source ^RelProtoDataType proto-row-type]
(let [field-types (ArrayList.)])
(proxy+ []
AbstractTable
(getRowType
[this type-factory]
(get-row-type this source type-factory proto-row-type row-type proto-row-type))
ICsvTable
(isStream [this] false)
(getFieldTypes
[this type-factory]
(when (.isEmpty field-types)
(CsvEnumerator/deduceRowType type-factory source field-types (.isStream this))))))
and I got this (cryptic) error message:
; Evaluating file: calcite_csv.clj
; Syntax error macroexpanding proxy+ at (src/ro/ieugen/calcite_csv.clj:76:3).
; No implementation of method: :asm-type of protocol: #'com.rpl.asm/ASMType found for class: clojure.lang.Var
; Evaluation of file calcite_csv.clj failed: class clojure.lang.Compiler$CompilerException
I imported this library in my ocde and while working on it from Calva I noticed it does not have support for clj-kondo.
To my knowledge, macro support needs to be added for this to work.
Perhaps of help:
https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md#unrecognized-macros
The class files needlessly increase the size of the jar file and polute the namespace.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.