Hi Dimitir,

Thanks for your questions, as you pointed me to deeper considerations and 
better description of idea.

> On 26 Dec 2015, at 16:20, Dmitri Gribenko <griboz...@gmail.com> wrote:
> 
> On Sat, Dec 26, 2015 at 3:59 PM, Radosław Smogura <rsmog...@icloud.com> wrote:
>> So,
>> 
>> What do you think about syntax like this:
>> 
>> // Declaration
>> @AttributeUsage(RUNTIME) //Can be SOURCE - attribute not emitted into binary
>> @AttributeTarget(PROPERTY) //Other CLASS, ENUM, METHOD, INIT
>> @attribute JSONProperty {
>> var name:String!;
>> var serializable:Bool? = true;
>> var deserializable:Bool? = true;
>> }
> 
> Is this a new declaration kind?  Do you think we could make it work
> with existing language constructs instead, like structs?  Any
> downsides to that?
It’s really good concern and I have to describe attribute concept in more 
details. The _implementation_ of attributes would and should use existing 
constructs like structs or classes - I prefer classes as it will allow 
attributes to subclass some common class (Attribute?), so in future new 
functionality can be added.

Let’s consider attributes, and marking struct with @Attrbute.

On runtime attributes will be passed as references or value objects (just to 
keep contract programming) and assignment to attribute properties should be 
prohibited:
- if attribute is bound to type, than attribute would be nothing more than 
extension of static context of that type,
- it’s error prone for developers, as someone could change i.e. JSON property 
name.

Attributes are metadata, and do not require methods (however methods could be 
interesting and innovative addition). So attribute’s properties should be 
declared with let, instead of var, to prevent modification of those, but from 
other hand we would like to set default values for some properties, I just 
think that declaration like this would be confusing:
@Attribute
struct JSONProperty {
/* … */
let deserializable:Bool? = true;
}

Additionally having attributes as a new construct will give us more flexibility 
on changing syntax and adding new features in future.

I think this implies that attribute can’t be considered as struct (on language 
level), and should be treated as new language construct.

>> // Usage
>> @JSONProperty(name=“id”)
>> var id:Int;
>> 
>> 
>> Attributes should be module aware (actual attributes should be redefined as 
>> Swift attribute, for beginning still can be hardcoded).
> 
> Sorry, I'm not sure what this means.
Attributes should be in module. So modules can define attributes with same 
name. Right now attributes are global.
> 
>> The attribute’s name have to be unique in module. It’s compile time error if 
>> attribute, class, enum, struct, etc has same name.
>> 
>> Attribute’s properties are read only and can’t be assigned - so during 
>> reflection no-one would change ‘shared’ values.
> 
> I think using structs and requiring that attributes are value types
> would solve both issues.
I think attributes should be treated as new language construct, regardless how 
those will be implemented on runtime - it can be struct or class.

>> Attribute’s properties can only support basic types: primitives, strings, 
>> types, and other attributes (optional).
> 
> Well, there is no such thing as "basic types" in Swift.  Strings,
> integers etc. are defined in the standard library and the compiler
> does not know anything special about them.
By basic type I meant a types which can be serialised to format which will not 
change in future. Numbers, strings, type names, arrays of those can be stored 
in binaries without risks of backward incompatibility, objects and structs are 
more fragile. I think next answer will clarify more.

>> When declaring attributes, properties can be set to constant values (static 
>> let) or enum values, however the final value is stored in binary, not a 
>> reference to it.
> 
> Again, given that strings are defined in the standard library, and
> that the language does not have a notion of a constant expression, I'm
> not sure how this would work.  I'm not saying it can't, I'm just
> saying you need to introduce a lot of new language concepts and
> compiler machinery.
It’s another good question. By const I mean virtual concept of static let 
declaration. My motivation is to keep attributes as static metadata.

Let’s consider three levels of attributes:
- source - those attributes are present only in source file and are not put in 
binary, such attributes can be used to mark pieces of code for external tools 
like visual UI designers, UMLs, etc
- compile - those attributes are present in output binary, but have not meaning 
on runtime - ie. @Deprecated,
- runtime - those attributes are present on runtime, and can be inspected by 
libraries to affect execution, ie.: @JSONProperty, @NSManaged

My other concern is related to attribute storage (let’s skip implementation of 
this). Suppose you want to centralise some values, ie. messages with following 
pice of code
CommonMessages {
        static var genericError = “Something went wrong :(“
}

And you want to bound a property to message when validation fails.
@ValidationMessage(message=CommonMessages.genericError)
var id:Int;

- For runtime referencing variables can be confusing, as some one seeing above 
notion can think that changing genericError will change message on runtime 
(annotations are static, so it will not work),
- For compilation level attributes compiler has limited possibilities to 
evaluate what genericMessage is, as there is no application runtime (it will be 
compiled), so only simple traversals through source can be performed. Even for 
const it can be hard right now.

The other question arises here, suppose CommonMessages are in external 
library,. What should happen if it changes, should a genericError be referenced 
or it’s value copied and stored in binary? Referencing could be quite 
interesting topic.

We can consider allowing simple or more complicated expressions in attribute 
properties
@Size(width=20+50+sqrt(12))
As long as those refer static context.

>> The compiler has build in support for core attributes, which can affect code 
>> generation. Compiler may perform additional checks on core attributes.
> 
> OK.
> 
> Another question is, how would you inspect attributes at runtime?
I would like to focus on syntax, semantic and parsing. This will require 
answering question how to store attributes (and I would like to move this to 
separate chain, as it will be long discussion). From the other hand, some 
questions still should be answered, ie.

How attribute should behave in such a case:
@ValidationMessage(message=CommonMessages.genericError)
var id:Int;

Should genericValue be copied or referenced (see above consideration), this 
implies what and how to store.

> Dmitri
> 
> -- 
> main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
> (j){printf("%d\n",i);}}} /*Dmitri Gribenko <griboz...@gmail.com>*/

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to