This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: use macros to generate java calls


On Dec 5, 2011, at 3:47 AM, Per Bothner wrote:

On 12/05/2011 12:30 AM, RÄzvan Rotaru wrote:
Hi,

I'm trying to use macros to generate java calls, and have been
strugling with this all weekend, but with no success. So, I'd like to
ask for some help from more experienced schemers:

The macro should work like this:

(create-object obj-type 'id1 arg1 'id2 arg2 ...)

=>

(obj-type) ;instantiation
(*:setId1 arg1)
(*:setId2 arg2)
...


Is this possible with kawa? Any hints how to achieve this? The biggest
challenge will probably be to transform 'id-foo in setIdFoo.

Rather than write your own macro, I suggest using the builtin facilities:
http://www.gnu.org/software/kawa/Allocating-objects.html


That makes use of keywords, changing your example to:

(obj-type id1: arg1 id2: arg2 ...)

RÄzvan, out of curiosity, what problems were you facing? Using the built-in
syntax is better in this case, but it might still be a good learning experience
for writing macros. As for the symbol transformations, instead of trying to
turn 'id-foo into "setIdFoo", I'd probably turn it into "*:set-id-foo" and
rely on Kawa's magic to convert that to CamelCase. (Note that the built-in
object creation syntax is more robust, since it'll turn "id1:" into either
setId1() or addId1() depending upon which method actually exists.)


Of course, there are times when the built-in facility isn't applicable, like
if you can't invoke a constructor (e.g. have to retrieve a singleton or call
a factory method) or if the methods you want to invoke on the object aren't
add/set or take more (or less) than one argument. For those cases, I wrote a
Kawa version of Clojure's doto macro
http://clojure.org/java_interop
which works pretty nicely:


(doto (java.util.HashMap) (*:put "a" 1) (*:put "b" 2))
=> {b=2, a=1}

(doto java.lang.System:out (*:println "Hello") (*:println "World"))
Hello
World
=> java.io.PrintStream@4e76fba0

The guts of it are fairly straightforward, so it makes for a decent macro
programming exercise. (And it doesn't require any symbol manipulation a la
id-foo -> *:set-id-foo, so it's probably an easier starting point than your
create-object.)


-Jamie

--
Jamison Hope
The PTR Group
www.theptrgroup.com




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]