[About accessing x.t without knowing the concrete type of x:]
On Apr 14, 4:09 am, Jeff Bezanson <
jeff.bezan...@gmail.com> wrote:
> We actually considered a rule like this at one point. But it never
> seemed worth it to go to lots of effort in the implementation just to
> disallow something:
>
>
http://en.wikipedia.org/wiki/Duck_typing
>
> It also somewhat alleviates the need for structure inheritance to be
> able to define multiple types with the same fields, and call the same
> functions on them.
I see your point. Maybe one should go in the opposite direction and
implement properties in Julia (which I think would be pretty useful).
I think it's only fair that if named fields could be part of the
interface of an object, it should be possibe to put in some custom
behavior, or provide a default implementation in an abstract
supertype.
I was able to get something of the kind by overloading getfield.
If I enter this at the Julia prompt:
global getfield
orig_getfield = getfield
getfield(x...) = orig_getfield(x...)
# create type T and add a property t2 == t^2
type T
t
end
getfield(self::T, sym::Symbol) = (sym == :t2 ? self.t^2 :
orig_getfield(self, sym))
Then T(3).t2 returns 9.
I wasn't able to overload assignment in the same way. (Looking at the
definition of setfield: "setfield(s, f, v) = (s.(f) = v)", I suppose
that's not so surprising :) No matter what, read only properties would
be a lot better than no properties.
Incidentally, if this kind of thing could work without too much
overhead, it could be nice to use it for the newly introduced Options
type, e g
getfield(opts::Options, sym::Symbol) = opts[sym]
At least to me, opts.size feels a lot more comfortable than
opts[:size].
I'd prefer to leave quoting to the more magic/meta parts of the code.
I suppose it would give the compiler an easier job to optimize the
resulting code if you could define a specific property using something
like
getfield(self::T, Type{:t2}) = (self.t^2)
(singleton types for symbols), and it would also decouple properties
for the same type with different names.
A nice thing with this kind of setup would be that you could define
properties for abstract types, with a default implementation or a an
error("abstract property!"), and subtypes could override it.
I suppose an actual field with the same name in a composite type
should override all property definitions, since it would be the most
specific, just like adding an actual property with the same name to
the concrete type.
Of course, if you want to introduce a specific property, you could get
similar results with plain getter and setter methods and avoid all the
nasty stuff (but not with code already written to use field access).
But dot notation would be a more compact way to express properties,
and also more clear I think. Properties would seemingly live in the
namespace of the object, which feels more comfortable to me than
pulling a getter method from a sea of functions (maybe I just haven't
written enough Julia code yet to get used to this :) )
I'm not sure this would be the best way to go about it, though.
I got lot of segfaults and hangs when playing around with redefining
getfield.
For instance, the above code works if you load it after starting
julia, but running it right after boot with
julia -L props.jl
gives a segfault.
If properties is a good idea, there should definitely be some macros
to take care of the unsafe stuff and boilerplate, like
@rwproperty T.t2 self->self.t^2 (self,t2)->(self.t = sqrt(t2))
or perhaps just
@rwproperty T.t2 self.t^2 self.t = sqrt(t2)
to define the property above (with assignment too), or maybe
@rproperty T.t2 = self.t^2
for a read only property.
What do people think? Would it be a good thing or a bad thing?