This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: type declaration best practices?
- From: Per Bothner <per at bothner dot com>
- To: kawa at sourceware dot org, Jamison Hope <jrh at theptrgroup dot com>
- Date: Thu, 12 Nov 2009 15:57:45 -0800
- Subject: Re: type declaration best practices?
- References: <FF51B6B0-46D4-4C37-B521-831014EB4B73@theptrgroup.com>
On 11/12/2009 03:11 PM, Jamison Hope wrote:
Is there a definitive set of best practices for declaring types of
variables? I see mention here and there that using angle brackets is
out, but they're still all over the place in Kawa sources and the Kawa
homepage.
Angle brackets are semi-deprecated. I'm gradually fixing things
to remove angle-brackets - though I want to leave at least some, for
the sake of testing!
Similarly, there are still lots of older invoke and even the really
old primitive-virtual-method that should be replaced by colon-notation.
(invoke-static is still needed for some things.)
These appear to all be valid and equivalent:
(define (tagged-vector3f tag :: <symbol> x :: <float> y :: <float> z ::
<float>) :: <pair>
(cons tag (make <javax.vecmath.Vector3f> x y z)))
(define (tagged-vector3f tag :: symbol x :: float y :: float z :: float)
:: pair
(cons tag (make javax.vecmath.Vector3f x y z)))
I didn't realize this worked - it's not my preferred style, as it seems
non-obvious how things are grouped. However, it is consistent with
how things work in define and let - i.e. you can just add an optional
:: TYPE. See below.
(define (tagged-vector3f (tag symbol) (x :: float) (y :: float) (z ::
float)) :: pair
(cons tag (make javax.vecmath.Vector3f x y z)))
(define (tagged-vector3f (tag symbol) (x float) (y float) (z float)) ::
pair
(cons tag (make javax.vecmath.Vector3f x y z)))
Likewise not my preferred style - I think including the colons helps.
But this is something I've been pondering, and perhaps a question
for the list. In define and let you can just add the optional :: TYPE
without having to add extra parentheses. I'm thinking a slight change,
in removing a space, might make things more readable:
(define (tagged-vector3f tag ::symbol x ::float y ::float z ::float)
::pair
(cons tag (make javax.vecmath.Vector3f x y z)))
(define xxx ::integer 123)
Or perhaps allow leaving out the preceding space as well:
(define (tagged-vector3f tag::symbol x::float y::float z::float)
::pair
(cons tag (make javax.vecmath.Vector3f x y z)))
(define xxx::integer 123)
I think PLT allows something like that, except using a single colon
- but that would conflict with colon notation, alas.
Implementation becomes a little tricky: The easiest mechanism
is to just define that there is a "delimiter" before and after
double-colon - that would just be a reader change (which would
be disabled in strict-R6RS-mode, if/when we provide that).
Comments?
Likewise:
(define-alias Vector3f <javax.vecmath.Vector3f>)
(define-alias Vector3f javax.vecmath.Vector3f)
I recommend the latter these days.
[or s/alias/namespace/g in that]
Which of these are the preferred forms? Are there situations in which
angle brackets are still required?
There might be, but I believe only in forms which are deprecated anyway.
Also, I realize that there are differences between an alias and a
namespace:
(let ((x 3)) (define-namespace y x) (define-alias z x) (set! x 4) (list
x y z))
=> (4 3 4)
but it seems like when used with a class name as the second operand,
both define-namespace and define-alias are chiefly useful in order to
avoid having to repeatedly type a FQCN, like a Java import. So, which is
truly conceptually closer to a Java import statement?
define-alias is generally preferable, though the documentation
isn't very helpful. I need to update this.
http://sources.redhat.com/ml/kawa/2008-q1/msg00074.html
Which produces better code?
It should be the same.
When declaring a variable's type, or as the first argument
to the make procedure,
Btw - you know you can leave out the 'make' and use a
class as a "constructor function":
(java.lang.Integer "12")
or:
(java.lang.String[] "ab" "cd")
is there a performance difference when using (1)
a built-in type (an instance of gnu.bytecode.Type), (2) a
fully-qualified class name, (3) a namespace, or (4) an alias?
Nope, as long as the name/namespace/alias are all known
at compile-time. If the lookup needs to be done at
run-time and we need to use reflection - then I don't know.
--
--Per Bothner
per@bothner.com http://per.bothner.com/