What is the best way to support completion? Opinions? Thanks!

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

What is the best way to support completion? Opinions? Thanks!

singmajesty

I am working with a Javascript framework that uses a factory model.

When you create a "definition," the object should be a simple object with  
only the properties you want to change. After this goes through the  
factory, you receive an object that has full functionality; methods,  
properties, inheritance, etc. However, most of the properties are only  
editable using getters and setters, so "caption" becomes editable using a  
"setCaption" method.

I would like to have as much accurate and complete code completion with  
Haxe as possible.

My current approach is to create my own classes for each "kind" in the  
framework. In order to provide code completion, I am defining each of the  
properties which are available for that object. In order to allow it to  
function properly through the factory, I am performing untyped JS calls to  
undefine each of these properties, so only the ones you explicitly change  
end up in the final object.

After the framework builds the objects, I am relying on the same class to  
provide completion. Now that it is an instance and not a definition,  
"caption" should really be a method, like "setCaption", but the other  
methods I exposed (like "show" or "hide") are now available.

Is there another way to provide code completion for "possible" properties,  
rather than defining them all through a class? Sort of like an "optional"  
interface?

Does this seem like the best approach, having single classes that help  
through both the definition and instance stages of each object, or should  
I create two separate classes, one for the definition, and one for the  
instance, so I can try and provide perfect code completion? The problem,  
then, is that you really do have to think of them as separate objects. In  
a traditional class-based application, a class and its instance are really  
the same thing. The weirdness here, from a completion perspective, is that  
your object transforms a bit before it becomes an instance.

If you have ideas for how I could support this better, or if you think  
I've taken the right approach, or have questions, comments, whatever, I'm  
grateful!

Thank you!

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: What is the best way to support completion? Opinions? Thanks!

Elsass Philippe
Joshua,

I think you should differentiate factory objects and created instances
- it's going to be less confusing eventually as it's obviously an
important aspect of the framework.

Actually the solution would be to improve this "factory" technique
because it's a widely used pattern and it has some real benefits:
- lets you build objects with many possible properties with lightweight code,
- lets you defer the creation of the real objects when they are needed,
- hides specific details on the objects creation.

Here's another example of factory usage, Appcelerator mobile:
var button = Titanium.UI.createButton({ title: 'Hello' }); // creates
a native button
button.addEventListener('click', button_click);

I believe the true solution would be to have code completion for that:
method({ prop1:"value", prop2:42 }); // maybe using a typedef?

Then haxe APIs for Titanium and Enyo could have some nice code
completion - if it's designed like Titanium's it could even leverage
"using" mixins.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: What is the best way to support completion? Opinions? Thanks!

singmajesty
Thanks, Philippe. This is very helpful.

I have been trying to find someone to talk to about code completion :)


If I can find a comfortable naming scheme, I agree that maintaining two  
sets of classes, one for definitions and one for instances, could be a  
very nice system. That messes things up a bit when a user creates their  
own class -- it would be a pain to instruct them to create two, but I  
suppose that is just how things are.


I tried typedefs, interfaces and classes. I think that the real problem is  
that all of these *require* each property to be present. There does not  
exist (as far as I can tell) a way to "suggest" available properties,  
without requiring that they are present on the object.

For example, I just created a new typedef, and tried to assign a generic  
object to that type:


Source/EnyoSample.hx:28: characters 2-33 : { salkdjf : String } should be  
Test
Source/EnyoSample.hx:28: characters 2-33 : { salkdjf : String } should be  
{ hi : String, hey : Int }
Source/EnyoSample.hx:28: characters 2-33 : { salkdjf : String } has no  
field hey


It also is not possible to use "new" in conjunction with a typedef, which  
feels nice from a syntax perspective:


var button = new Button ();

vs.

var button:Button = { kind: "Button" };


Even though it is a bit of a hack, the best way I have found to provide  
"optional" properties is to have a class that undefines its properties in  
the constructor.


If I go the route of providing two sets of classes, what do you think is a  
good convention for the definition and for the instance? Maybe...


enyo.Button
enyo.ButtonInstance

or

enyo.Button
enyo.instance.IButton

or...?



I have really enjoyed using Haxe for my latest application. When the code  
completion is set up properly, it reminds me of the change from AS1/AS2 to  
AS3, but in this case, Javascript.




On Mon, 15 Aug 2011 01:07:27 -0700, Elsass Philippe  
<[hidden email]> wrote:

> Joshua,
>
> I think you should differentiate factory objects and created instances
> - it's going to be less confusing eventually as it's obviously an
> important aspect of the framework.
>
> Actually the solution would be to improve this "factory" technique
> because it's a widely used pattern and it has some real benefits:
> - lets you build objects with many possible properties with lightweight  
> code,
> - lets you defer the creation of the real objects when they are needed,
> - hides specific details on the objects creation.
>
> Here's another example of factory usage, Appcelerator mobile:
> var button = Titanium.UI.createButton({ title: 'Hello' }); // creates
> a native button
> button.addEventListener('click', button_click);
>
> I believe the true solution would be to have code completion for that:
> method({ prop1:"value", prop2:42 }); // maybe using a typedef?
>
> Then haxe APIs for Titanium and Enyo could have some nice code
> completion - if it's designed like Titanium's it could even leverage
> "using" mixins.
>


--
Using Opera's revolutionary email client: http://www.opera.com/mail/

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Re: What is the best way to support completion? Opinions? Thanks!

Elsass Philippe
In reply to this post by singmajesty
For what is worth, here's a similar problem discussed a few years ago:
http://haxe.1354130.n2.nabble.com/Instancing-objects-with-lots-of-properties-td1657398.html

What about:
- constructor with most common properties as optional parameters,
- chainable setters.

Enyo.kind.button("hello world", "style1")
    .flex(1).height(20);

I feel like ButtonKind or KindButton for kind objects - using this
syntax and inference you don't care too much about their name.

--
haXe - an open source web programming language
http://haxe.org