IDE Minutes 2008-04-17

From MemberWiki

Jump to: navigation, search

URL: http://www.openajax.org/member/wiki/IDE_Minutes_2008-04-15

Contents

Attendees

  • Jon Ferriaolo
  • Phil Berklund
  • Stew Niklas
  • Ingo Muschenetz
  • Bertrand Le Roy
  • Ted Thibadeaux

Minutes

mixins

Jon: Ingo and Bertrand were converging on the topic of mixins. Can one of you summarize where we are?

Bertrand: Dojo is using actual classes... there are two ways you can [delete?] things.. bag of members... Any top-level class could be a mixin, but we should also have a top-level item mixin.

Ingo: We need to figure out how to specify how one would mix in a mixin as opposed to a class.

Jon: So there will be a class element, an interface element, a mixin element, and a globals element?

Ingo: That's right. And there might be an enum element, but we'll get to that.

Bertrand: Why don't we have a namespace element? Describing the namespace of certain entities...

Jon: You mean you want to describe foo.bar in foo.bar.blue?

Bertrand: Yes, and foo.

Jon: Would any toolkits use it?

Bertrand: We would.

Jon: Toolkits segment into toolkits.whatever and toolkits.UI etc., so that makes sense?

Ingo: Is this constricting? Is this how people develop their JavaScript?

Jon: If we keept it as discussed above, and we had a namespace element which is optional -- it's just descriptive -- then it seems like it doesn't do any harm.

Ingo: It's just another top-level element that an IDE has to support.

Jon: Well, you don't HAVE to deal with it; if you don't implement anything for the namespace, you don't have to use it.

Ingo: Well we haven't needed it so far, but I can see how someone COULD use it.

Bertrand: We're using it today.

Jon: OK, I think we should put it in, and see how it works in the InterOperability event...

Ingo: When you're defining a namespace, it's a top-level tag... but you would still describe everything else using its fully namespaced name, right?

Bertrand: Yes.

Jon: ...you identify whether you're grabbing the static or the instance. So we've agreed to the from scope and the to scope?

Ingo: Right

Jon: So the thing we haven't agreed to is the syntax. mixins needed vs. mixins included. Included means that your class has an implementation of the thing that you're referring to, so you'd often do this with interface... but I've included this class that includes all the methods needed to implement A. But the needed means that at runtime, those mixins have to be attached to my class.

Ingo: Would you describe that as an ancestor, or would it be a mixin? In most cases you're applying a static.

Jon: Does ancestor mean that you're invoking the constructor? Or is that a non-issue?

Bertrand: I think that "ancestor" means that anything that's available on the ancestor is available in th econstructor.

Jon: Your constructor has to... I'm wondering how strict is...

Bertrand: I think what it means is you inherit from those guys. Maybe we should think of it more as an inheritance mechanism.

Ingo: There's some ambiguity right now is whether you could put something in your mixin section as opposed to ancestors; maybe we should just put it in ancestors.

Bertrand: Using ancestors seems to imply prototype inheritence, and that doesn't work for static.

Ingo: Rather than ancestors/ancestor, you could have multiple different tag. Maybe ancestors would be more general than just implying prototype inheritence.. but perhaps that's confusing.

Jon: What if we're just trying to grab properties and move them.

Ingo: There's an ancestors tag with ancestor(s) underneath it for classes and interfaces, and then there's a mixins tag that has mixin elements underneath it that are either mixins, classes, or interfaces. The decision is what the children tags are called so they don't conflict with the top-level tags.

Jon: mixes and mix...

Ingo: I like that. It's short.

Jon: OK, then mix would have a type attribute that could either refer to a mixin, a class, or an interface.

Bertrand: I don't know about interface, and this is about implementation.

Jon: Sometimes you can inherit an interface, in some languages, if it has an enum on it. Sometimes constants are.... So you're saying it doesn't make sense to do interface.

Bertrand: It doesn't make sense to me, but I guess there's no harm.

Jon: We need to think through whether interface makes sense.

fields and properties

Jon: OK, next topic: fields and properties.

Bertrand: [summarizes his e-mail of Thu 4/17/2008 1:59 PM EST]

[email]

Let me set-up the vocabulary first, with our own conventions, but please don't focus on that. The specs might use different vocabulary, which is fine. What's important here is that we agree on the concepts and their formalization.

I'll call field a simple attribute of an object (that is usually not a Function). Values for a field are got and set through simple dereferencing and equal operator.

Example: a.foo = "some value"; b.bar = 42; alert(b.bar);

I'll call property a value attached to an object, similar to a field, but where there is a convention to get and set the value. The get and set operations may have side effects because the getters and setters may contain code beyond getting and setting the actual value of the property. The value is usually stored in a private field.

I'll call getter (resp. setter) the method that gets (resp. sets) the value of the property.

And here's my proposal for formalizing properties in metadata:

Many (most?) libraries make a distinction between field and property in order to enable side-effects. For example, the setter of a property can publish an event so that subscribers can be notified of the change and update themselves accordingly. This enables live bindings, which plain fields can't do.

It is important for the metadata format to capture the semantics of properties, because otherwise it's impossible to build a good property grid or watch window.

There are many conventions and patterns to express properties in JavaScript. Here are a few, in no particular order, and without any claim for exhaustiveness):

1.    foo.prop.get(); foo.prop.set(value);
2.    foo.getValue("prop"); foo.setValue("prop", value);
3.    foo.get_prop(); foo.set_prop(value);
4.    foo.prop(); foo.prop(value);
5.    foo.prop; foo.prop = value; (this is ECMA 4, which supports real
properties)

The pattern for expressing properties is the same in any given library, but varies from library to library. Ideally, the metadata would specify the pattern on the api tag:

<api getterPattern="getterexpression" setterPattern="setterexpression">

where the expressions for the above examples would be:

1.    "{target}.{property}.get()" and "{target}.{property}.set({value})"
2.    "{target}.getValue("{property}")" and
"{target}.setValue("{property}", {value})"
3.    "{target}.get_{property}()" and "{target}.set_{property}({value}"
4.    "{target}.{property}()" and "{target}.{property}({value})"
5.    "{target}.{property}" and "{target}.{property} = {value}"

Despite the fact that there is usually a getter and a setter method, it's important to note that there is only one entity as far as the object model is concerned, and that is the property. Thus, the metadata for the object should show the property as a single entity instead of showing getter and setter as separate methods. For example:

   <class type="libraryname.ClassName" superclass="Object">
       <constructors>[...]</constructors>
       <properties> 
           <property name="foo" readonly="false" scope="instance"
type="String">
               <description>Property description</description>
           </property>
       </properties>
       <fields>
           <field name="bar" scope="instance" type="Number">
               <description>Field description</description>
           </field>
       </fields>
       <methods>[...]</methods>
   </class>

In this example, we're making the distinction between the field bar, which is got and set by just dereferencing or using equal, and property foo, which is accessed through the getter and setter as expressed in the api tag's patterns. For example, myInstance.get_foo() and myInstance.set_foo(value).

Also to consider, moving from fields attributes like readonly which really only make sense on a property.

[/email]

Jon: One thing I'll mention is that when you'rein the mashup space, you'll only be using the properties, not the fields. YOu have to use getters and setters.

Stew: Absolutely. Exactly what Bertrand said -- we're looking to kick off events to notify other elements of changes.

Jon: in the IDE world, does it make sense to distinguish between fields and properties.

Phil: I can see it making sense for the component level, but I'm not sure about the API metadata level. One of the main usages of the metadata in the IDE would be code completion, and how would you use this? I assume for completeness, these would also show up in th elist of methods?

Bertrand: Yes, especially in code completion case.

Ingo: It looks like a method, but the icon is actually a property, right?

Bertrand: Yes. In code completion, it shows you the getter and setter and the description of the properties. The case where it really shines is when you have a watch window.

Jon: Ingo and Phil, what do you feel about having this separation between fields and properties.

Phil: Well, what Bertrand just said about the watch window makes sense, except that... it will complicate things a bit. I have no hard objection.

Ingo: I think it makes sense. It means that we're post-processing the metadata and dynamically attaching them to... during code assist. We need to put the pattern on both the class and the API methods. The terminology of properties, fields, and methods might be confusing to JSers.

Phil: Substitution patterns... this isn't going to work for code completion unless it's something.something.

Bertrand: You could imagine a global function to get and set properties,

Phil: Yeah, during code completion, if you had object.something, it wouldn't really apply at that point. If it's a pattern that uses a global function, then this doesn't work so well.

Bertrand: I don't know if that pattern is really used in the industry, tho.

...

Bertrand: You would have code completion on that global function, so maybe it's not that bad.

Jon: So do we agree that we're going to have different elements for properties and fields -- except that the terminology might change -- but are we in agreement on the general approach?

[no dissent]

Jon: So let's talk about the names.

Something about public fields and constructing getters and setters for them from Phil.

Jon: Are there any better names than properties and fields?

Ingo: Is there any special way we have to handle read-only fields?

Bertrand: It just means there's no setter in the implementation.

Ingo: How would you express that in the XML?

Bertrand: It's in the mail; read-only="true".

Jon: Back to the names... properties and fields.

Bertrand: I understand that "fields" is a common term in .NET, but may not be so familiar to JS.

Jon: "properties" meaning using getters/setters for is something that's common in the industry now, so I'd like to keep that. My inclination is that properties vs. fields is fine with me. It matches at least one thing we have in the industry: the Microsoft stuff.

Bertrand: How is it done in Java?

Jon: Java doesn't have fields.

Phil: Yes it does; Java has a convention for getters and setters. Properties is fine with me, attributes is too.

Ted: I'd vote for properties over attributes; fields is fine too.

Ingo: Aren't they called properties in the ECMA standard?

Bertrand: Oh yeah, we already have a standard!

Jon: What you're saying is that the element that you called 'fields' is called 'properties' in ECMA?

Ingo: They're both called properties.

Ted: The things that you're getting and setting are called attributes in data access.

Bertrand: In Java, attributes mean something different.

Jon: I think alignining with JavaScript in everything we do is good. Putting an attribute on the property element seems attractive to me.

Bertrand: Like managed="true". The language must be making the distinction somehow.

Jon: For now, we're going to combine fields and properties into properties, and have an attribute for managed properties.

Ingo: it looks like they make the distinction between 'virtual' properties and regular properties.

enumerations

Jon: Let's move on to enumeration.

Bertrand: This will be much simpler: Two types of enumerations, those that you can combine, like flags, and those that are mutually exclusive. In the case where you just want to restrict the values of some parameter, we could integrate those into the type attribute, but I don't like that approach. Type is overloaded anyway. The better approach is to have a values tag under parameter. Additionally, under values, we could have a tag indicating whether it's a flag or not.

[email]

Here's a simple proposal to handle enums in meta-data.

In recent discussions, we've identified two main uses for enumerated values. One was a one-time set of possible values for a parameter, and the other was a reusable set of values that is identifiable at runtime using names and also usable as a constraint on parameter values.

In both cases, we want to enable exclusive uses of values (one value at a time) or combinations of values.

To express one-time possible values, we could use

type="'foo'^'bar'^'baz'" or type="1^2^3" 

for exclusive values, and

type="0|1|2|4" 

for combinable values. Alternatively, we could use a more verbose syntax such as

<parameter type="Number" name="foo">
  <values flags="true|false">
    <value>0</value>
    <value>1</value>
    <value>2</value>
    <value>4</value>
  </values>
  <description>Parameter description</description>
</parameter>

For enumerations that are reusable, we could have another top-level enum tag (under api, as a peer to class, interface, mixin, namespace, etc.):

<api>
  <enum type="MyNamespace.AccessEnum" flags="true|false">
    <values>
      <value name="None">0</value>
      <value name="Read">1</value>
      <value name="Write">2</value>
      <value name="ChangeRights">4</value>
      <value name="FullControl">7</value>
    </values>
  </enum>
</api>

Then, a parameter that takes one of these values can just use the enum as its type:

<parameter type="MyNamespace.AccessEnum" name="foo">

[/email]

Jon: Google Gadgets has a tag called enumValues, and there's a display value and an actual value.

Bertrand: We also need room for a description. So the value should move to an attribute (but then you'd have <value value="foo" description="foo description">).

Jon: And wherever description exists, you can have example and remarks. Oh, and we had an unconstrained attribute that we talked about during the datatypes discussion for user-supplied values [to allow for editable drop-down in the UI].

Ingo: We solved that by having * as a value, but unconstrained makes sense.

Personal tools