Open CeylonMigrationBot opened 11 years ago
[@FroMage] This Property
object may be something we want to merge with the current Value
metamodel. You also need to define the semantics of listeners wrt exceptions. I still think we should not introduce listeners to attributes without interceptors to methods, as I don't like the increasing difference between attributes and methods. I also don't quite like the third new model types that this would introduce: properties, metamodel and meta-declarations.
If you're convinced we must introduce listeners, we should address all this is one go. If all we need are attribute references, we should make them as close as possible to method references, minus the required extra syntax.
[@gavinking]
This
Property
object may be something we want to merge with the currentValue
metamodel.
Perhaps, but Value
seems to me something that is significantly more heavyweight. We distinguish between Callable
s and Method
s for the same reason.
I also don't quite like the third new model types that this would introduce: properties, metamodel and meta-declarations.
I'm not sure that this is a new layer. I think it conceptually lives in the same layer as Callable
.
I still think we should not introduce listeners to attributes without interceptors to methods
In principle I agree with you, but given the narrow bandwidth we have right now for new language features, I think we should focus attention on which of these features is more critical, and that, at least right now, is properties, not interception.
[@gavinking] By the way, @FroMage, I'm not even convinced that property notifications == interception. They might be distinct facilities. Interception to me would imply the ability to listen to attribute get operations as well as attribute set operations. Also, I had always envisaged that interception would be something at the metamodel level, and perhaps even be limited to static interception (i.e. class-level rather than instance-level interceptors).
Property notifications are:
So I'm not totally convinced that they're part of "interception".
[@FroMage]
I think it conceptually lives in the same layer as Callable.
Except Callable
has no methods, and we're now talking about a Property
with methods and adding the same to Callable
.
You're right that the metamodel is heavier, but this may be something we could fix with lazy(er) initialising.
So I'm not totally convinced that they're part of "interception".
I'm pretty sure they intersect a lot. Or will.
[@gavinking]
I'm pretty sure they intersect a lot. Or will.
Maybe. If we deicide that interception is an instance-level thing then yes, I suppose they will.
[@marvelous] What I would need is a static reference to a JavaBean property.
// Java
class Person {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
// Ceylon
Property<Person, String> prop = `Person.name`
A bit like the JPA metamodel really, but for the JavaBeans spec. http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html
With:
The spec is very old, but some parts are still used as-is.
I think the Property change pattern doesn't need language support.
[@vietj] @marvelous I have some kind of property in Cayla MVVM:
https://github.com/vietj/cayla-mvvm/blob/master/source/io/cayla/mvvm/Property.ceylon
[@gavinking] @vietj
property navigability (composition)
it is essential for proper addressing complex cases, specially for templates in which bind property > references and not instances. It looks like static property ref composition address this case.
Upon reflection it might be better to support something more like:
@Person.address.country
Than the much more verbose:
@Person.address.compose(@Address.country)
That is likely doable. We need to think it through.
multi valued properties
do you plan to address this case ? (list) or should it be handled by frameworks using collection wrappers.
I suppose you mean events when things are added/removed to/from a collection. Dunno, we need to discuss this. I can see a couple of different ways that it could work.
computed
need also something for creating computed observable properties :+1:
I think my proposal already covers that, doesn't it? The fake
examples.
[@gavinking] Note that the syntax for computed properties would be much nicer with #3627 and/or #3439. Consider:
@String fake = Property {
val=>”hello”;
assign val {}
};
[@EricSL] This can be combined with a pass-by-reference syntax.
So in C#, you can do:
void main() { int x = 2; addTwo(ref x); // x == 4; }
void addTwo(ref Integer x) { x += 2; }
So bringing this into the Ceylon world, I would suggest a new class Reference
So this syntax would enable pass-by-reference, but it would be much more powerful because you could provide a reference to a property on a class, you could store references, and so it would enable the features you're thinking about here as well.
[@gavinking] @EricSL Well that doesn't look that different to my proposal above, AFAICS.
[@EricSL] Yes it is quite similar.
Just a few things to clarify:
@String nameOfPerson = @person.name;
Is this a bug? Elsewhere you write things like "person.@name". Or does this create a reference that changes value when either person or person's name changes? This is hard to specify, as "@person" is a Property
shared @String @name = name.@fullName;
So when other code gets/sets name, does it get/set a String or a Property
I guess an advantage of "ref" is that you might want more kinds of references (e.g. "out" to just capture the setter), and another keyword if we add support for an observer. But the advantage of @ is that you can put it anywhere in a sequence of properties (@person.name or person.@name) whereas if those are different things with ref you would do "ref person.name" or "ref (person).name".
[@gavinking]
@String nameOfPerson = @person.name;
Is this a bug? Elsewhere you write things like "person.@name".
I think it's a misprint. I wrote that up a while ago.
shared @String @name = name.@fullName;
So when other code gets/sets name, does it get/set a String or a Property
?
What this syntax is doing, essentially, is creating an alias of name.fullName
.
It's saying that @name
is of type @String
, ∴ name
is of type String
. You see?
So writing:
name = "Gavin";
would set name.fullName
to "Gavin"
.
One could also have properties where you get/set
Property
s, and even references to such properties, so I would say it is different.
Yes, that would be:
shared variable @String nameProperty = name.@fullName;
Here nameProperty is of type @String
, not of type String
.
[@gavinking] We've discussed this many times before. Do we need a way to get a reference to an attribute that you can invoke to get/set it. This is very useful for UI code, where you would be able to just easily attach a textbox to a
String
attribute, for example.Proposed solution:
Thoughts?
P.S. Note if
name
were non-variable
, then the type of the function would be justString()
.[Migrated from ceylon/ceylon-spec#685]