bwrap

Functional Processing


License
EPL-1.0

Documentation

Brute Wrap

Brute force wrapping of Java methods with Clojure functions.

Install

Bwrap is available in Clojars, add [bwrap "0.1.0"] to your Leiningen dependencies to pull it in to your project.

Usage

In a namespace,

(ns wrapper.string
    (:require [bwrap.wrapper :refer [defclassfns]]))

(defclassfns java.lang.String)

In the REPL,

user> (ns wrapper.string)
nil
wrapper.string> (use 'bwrap.wrapper)
nil
wrapper.string> (defclassfns java.lang.String)
WARNING: concat already refers to: #'clojure.core/concat in namespace: wrapper.string, being replaced by: #'wrapper.string/concat
WARNING: intern already refers to: #'clojure.core/intern in namespace: wrapper.string, being replaced by: #'wrapper.string/intern
WARNING: replace already refers to: #'clojure.core/replace in namespace: wrapper.string, being replaced by: #'wrapper.string/replace
#'wrapper.string/starts-with
wrapper.string> (keys (ns-publics *ns*))
(hash-code to-string trim get-chars split code-point-at sub-sequence concat starts-with ends-with offset-by-code-points content-equals intern compare-to-ignore-case char-at to-upper-case to-char-array last-index-of to-lower-case replace get-bytes compare-to replace-all length code-point-before equals-ignore-case region-matches matches code-point-count equals index-of hash32 is-empty replace-first substring contains)
It's a wise move to run this in a dedicated namespace. It will happily blat over existing function definitions.

The created functions have a first argument of self, this is the instance that the function should operate on. The remaining arguments will be passed into the function call.

wrapper.string> (length "123")
3
wrapper.string> (equals "aaa" "bbb")
false
wrapper.string> (equals "aaa" "aaa")
true

Function documentation

There is nothing useful. The function parameter names are constructed based on the type and the parameter index. Without a programmatic way to acquire sensible names of documentation there is not much that can be done here.

user> (doc length)
-------------------------
user/length
([self])
  nil

user> (doc equals)
-------------------------
user/equals
([self object0])
  nil

user> (doc index-of)
-------------------------
user/index-of
([self string0] [self int0 int1])
  nil

Overloaded methods and multiple arity functions

Bwrap handles overloaded methods and will create multi arity functions. However, it does this in a fairly crude way.

Clojure cannot have multiple function definitions with the same number of arguments* so all overloaded Java methods with the same number of arguments will be rolled into a single Clojure function definition.

For example, something like String#indexOf has four implementations, two with one argument and two with two arguments.

int  indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
int  indexOf(int ch, int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
int  indexOf(String str)
Returns the index within this string of the first occurrence of the specified substring.
int  indexOf(String str, int fromIndex)
Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

Bwrap cannot differentiate based on type* and create four different functions, so only two come into existence,

user> (doc index-of)
-------------------------
user/index-of
([self string0] [self int0 int1])
  nil

The argument names are picked from the first implementation that bwrap finds.

Fortunately, (or not) we can still dispatch on reflection. Here's an example of reflection dispatch on the single argument methods.

user> (index-of "abcdefg" 100)
3
user> (index-of "abcdefg" "d")
3

*actually, with multimethods it can. But I'll ignore that for now.

TODO

  • Replace reflection dispatch with multimethods and type hints
  • Investigate creating macros instead of functions
  • Add question mark suffix to boolean functions
  • Return self on void functions (or, perhaps create a return self alternative of each function)

License

Copyright © 2014 Dan Midwood

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.