David,
The reason Parenscript doesn't ship with macros for this kind of thing
is, I suppose, that they're so easy to write and everyone's preferences
are slightly different. Since we have
(@ addr 'zipcode) => addr.zipcode
you could imagine something like this to add in the null check:
(? addr 'zipcode) => (address != null) ? address.zipcode : null
The trickiest part really is figuring out what notation you
want to use. I don't know if ? is a good notation or not, it's
just the first that occurred to me.
That being said, there is a structural issue with s-expressions not
being so good for chaining such expressions together, since each
accessor introduces a new level of nesting. This isn't readable
when you have more than two or three properties in the chain:
(@ (@ (@ lottery 'winner) 'address) 'zipcode)
=> lottery.winner.address.zipcode
Parenscript gets around that by allowing (@ lottery 'winner 'address 'zipcode)
as shorthand for (@ (@ (@ lottery 'winner) 'address) 'zipcode). By
analogy, you could have (? lottery 'winner 'address 'zipcode) as
shorthand for (? (? (? lottery 'winner) 'address) 'zipcode), which
would add a null check before each access. But I don't see any way
to represent the equivalent of lottery.drawWinner?().address?.zipcode
in a flat way in s-expressions, since it's not using the same access
operator all the way through.
Arguably the best solution would be to extend the PS reader with
syntax for the dot operator, so lottery.winner.address.zipcode would
be syntax for (@ (@ (@ lottery 'winner) 'address) 'zipcode). Then, PS
being a Lisp, it would presumably not be very hard to add one's own
extensions like ? for null-checking. So far, though, no one has
undertaken such work on the PS reader. (Early versions of PS
actually had dot syntax for property access, but not at the
reader level. This wasn't convenient for many purposes, especially
macro writing, since an expression like lottery.winner.address.zipcode
was just one big lump of a symbol and you had to parse it yourself.)
Daniel