It is very clear how setters would work, but I am not clear on
getters. What is the return type of any "compound/cascaded" method
invocation for that matter? A tuple of each of the return values?
void? (I can't seem to open the google doc you link to to possibly
find the answer myself, sorry).
Still, the syntax seems and semantics of your proposal appear
extremely desirable.
On Nov 21, 8:48 pm, Bob Nystrom <rnyst...@google.com> wrote:
> Jacob Richman, one of the people feverishly working on our new DOM library
> has a language proposal to share with you. You can see it in Google doc
> form here:https://docs.google.com/document/d/1U0PeHtVQHMQ8usy7xI5Luo01W5LuWR1ac...
> *FAQ: *
Haven't seen the doc too, but from the presented code it seems that 'style' is already a getter. That means, you use getters by further calling methods on their result.
In the end the whole cascading seems not to be meant to return some value but to declare a call chain (manipulation chain). After finishing, the document is modified.
document.query('#myTable').{queryAll('.firstColumn').{style.{background = 'red',border = '2px solid black'},text = 'first column'},queryAll('.lastColumn').{style.background = 'blue',text = 'last column'}};
+1
It is very clear how setters would work, but I am not clear on
getters. What is the return type of any "compound/cascaded" method
invocation for that matter?
A tuple of each of the return values?
void? (I can't seem to open the google doc you link to to possibly
find the answer myself, sorry).
Still, the syntax seems and semantics of your proposal appear
extremely desirable.
Why use comma instead of semicolon as a separator?
Is it because the separated things are expressions and not statements? Semicolon would be more natural I guess, it's already used as statement separator in Dart... well, not as a separator, it's an end-mark. Comma as a separator is a nice distinction, but maybe using end-marks and semicolons would be more consistent with rest of the language.How about allowing return rExpr as a last expression, meaning that the value of the expression wouldn't be the receiver, but rExpr? It might allow some nice simplifications, but I need to think about it some more.
Oh, and one nice observation. Let's imagineclass C {m1() {...}m2() {...}noSuchMethod() {...}}I think that thisc = new C();c.{m1(),m2(),m3(),m4()}would result in calls c.m1(), c.m2(), c.noSuchMethod(...'m3'...) and finally c.noSuchMethod(...'m4'...), which allows for some nice Groovy-style builders, yay!
Why use comma instead of semicolon as a separator? Is it because the separated things are expressions and not statements? Semicolon would be more natural I guess, it's already used as statement separator in Dart... well, not as a separator, it's an end-mark. Comma as a separator is a nice distinction, but maybe using end-marks and semicolons would be more consistent with rest of the language.
How about allowing return rExpr as a last expression, meaning that the value of the expression wouldn't be the receiver, but rExpr? It might allow some nice simplifications, but I need to think about it some more.
Oh, and one nice observation. Let's imagineclass C {m1() {...}m2() {...}noSuchMethod() {...}}I think that thisc = new C();c.{m1(),m2(),m3(),m4()}would result in calls c.m1(), c.m2(), c.noSuchMethod(...'m3'...) and finally c.noSuchMethod(...'m4'...), which allows for some nice Groovy-style builders, yay!
LT
I hope I can suggest a small change. What if there's code that has
side effects that needs to come between the chain.
Consider this code:
var firstCol = $("#myTable")
.find('.firstColumn')
.text('First Column');
var color = this.getColorForFirstColumn();
// Let's assume this function has some side effects, so it's very
important to call it right after the text is set.
firstCol.css('background', color);
Even the syntactical sugar of method cascading will require us to
break for code coming between the chain. What if there's some way to
let a piece of code execute as-is while desugaring. like this
document.query("#myTable").{
queryAll('.firstColumn').{
text = "First Column",
{ var newBgColor = getColorForFirstColumn(); },
style.background.color = newBgColor
}
}
Thanks,
Anirudh
On Nov 22, 6:48 am, Bob Nystrom <rnyst...@google.com> wrote:
> Jacob Richman, one of the people feverishly working on our new DOM library
> has a language proposal to share with you. You can see it in Google doc
> form here:https://docs.google.com/document/d/1U0PeHtVQHMQ8usy7xI5Luo01W5LuWR1ac...
> *FAQ: *
Am 23.11.2011 11:12 schrieb "skyronic":
> document.query("#myTable").{
> queryAll('.firstColumn').{
> text = "First Column",
> { var newBgColor = getColorForFirstColumn(); },
> style.background.color = newBgColor
> }
> }
>
First, this specific example could simply avoid the variable newBgColor and call the getter directly instead.
Second, yes, you are right. In general this shows why cascading is only an insufficient analogue to Groovy's builder syntax, which is based on the concept of closures and delegate, not cascades.
To be honest, I don't like your syntax proposal, as the braces around the var decl suggest another scope, so the var wouldn't be visible in the following line.
KR
Det
Second, yes, you are right. In general this shows why cascading is only an insufficient analogue to Groovy's builder syntax, which is based on the concept of closures and delegate, not cascades.
On Wed, Nov 23, 2011 at 5:01 PM, Dirk Detering <mail...@googlemail.com> wrote:
>
> Am 23.11.2011 11:12 schrieb "skyronic":
>> document.query("#myTable").{
>> queryAll('.firstColumn').{
>> text = "First Column",
>> { var newBgColor = getColorForFirstColumn(); },
>> style.background.color = newBgColor
>> }
>> }
>>
>
> First, this specific example could simply avoid the variable newBgColor and
> call the getter directly instead.
Yes, it's a poor example. A better example would have been a function
to Hide a loading div
document.query("#myTable").{
queryAll(.firstColumn).{
text = "First Column",
{ document.query("#loading").hide() },
style.background.color = "red"
}
}
> To be honest, I don't like your syntax proposal, as the braces around the
> var decl suggest another scope, so the var wouldn't be visible in the
> following line.
Yes. I knew there would obviously some issues with scoping when I
suggested it. I'm sure there are also some other subtle side-effects
that will come in.
That said, I feel that method cascading would be a fantastic feature
in the current proposed form, and maybe my proposal won't fit into the
simplicity and elegance of the existing proposal.
Thanks,
Anirudh
I would advocate support for what .net has implemented along these
lines: extension methods.
If dart supported extension methods, then chaining would be naturally
supported.
John
On Nov 21, 7:48 pm, Bob Nystrom <rnyst...@google.com> wrote:
> Jacob Richman, one of the people feverishly working on our new DOM library
> has a language proposal to share with you. You can see it in Google doc
> form here:https://docs.google.com/document/d/1U0PeHtVQHMQ8usy7xI5Luo01W5LuWR1ac...
> *FAQ: *
Sorry, can't follow you here.
Could you please elaborate a bit more how EMs would solve this use case?
Sorry Michal, again I cannot follow.
The main point in your code is:
var p = casc(new Point()).call((p){
p.log('start');
p.x = x;
p.scale(10);
p.log('scaled');
p.x++;
p.y = x + p.x + p.y; // Note: p need not bind to outer scope on rhs here!
}).release();
But where is this any different from:
var p = new Point();
p.log('start');
p.x = x;
p.scale(10);
p.log('scaled');
p.x++;
p.y = x + p.x + p.y; // Note: p need not bind to outer scope on rhs here!
??
The point is, that you are not cascading method calls, like the original proposal suggests, as you always have to put the receiver in front anyway.
The cascading indeed is about to get free from the repeated ‘p.’
For your example:
var p = new Point();
p. { log('start'),
x = x, // ??
scale(10),
log('scaled'),
x++,
y = x + p.x + p.y
}
KR
Det
Feed: General Dart Discussion Google Group
Posted on: Wednesday, November 23, 2011 5:16 PM
Author: mmo...@google.com (Michal Mocny)
Subject: Re: [misc] Re: New Dart feature proposal: method cascades
So I had a little brainstorm here this morning and realized you can easily
emulate this feature using current Dart features. Here it is:
[link]
This emulation could be made more syntactically pleasant with:
(a) extension method for type Object, negating the need to use the wrapper
Artikel anzeigen...
--
BITMARCK SOFTWARE GMBH
Firmensitz: Paul-Klinger-Strasse 15, 45127 Essen
Geschaeftsfuehrer: Reiner Kuhn
Registergericht: Amtsgericht Essen HRB 20680
***********************************************************************
Die Information in dieser E-Mail ist vertraulich und ist ausschliesslich
fuer den/die benannten Adressaten bestimmt. Ein Zugriff auf diese
E-Mail durch andere Personen als den/die benannten Adressaten ist
nicht gestattet. Sollten Sie nicht der benannte Adressat sein, loeschen
Sie bitte diese E-Mail.
Second, yes, you are right. In general this shows why cascading is only an insufficient analogue to Groovy's builder syntax, which is based on the concept of closures and delegate, not cascades.
True. Cascade is a special case of a closure with delegate set to the receiver object and resolving set to "delegate only" (or delegate first?).
A small syntax addition would make this style of API much easier for immutable classes. I propose the addition of the following clause to the production 'compoundAssignmentOperator':
| '.='
That is, just as the statement 'foo += bar' is shorthand for 'foo = foo + bar', the statement 'foo.bar(baz)' would be shorthand for 'foo = foo.bar(baz)'.
With immutable classes, one implements "mutator" methods by returning a new object instance. When using such a class, one often wants to replace the reference to the original instance with the result from the method call. Imagining an immutable queue, for example, one might enqueue like so:
foo = foo.enqueue( 42 )
This naturally supports the chaining style, since the result of each method call is an object:
foo = foo.enqueue( 42 ).enqueue( 101 )
The new operator I suggest would allow you to write this chain like so:
foo.=enqueue(42)
.enqueue(101)
Immutability is a very useful concept, particularly in a concurrent world, and I would love to see Dart open up to that style of class design.
-Mars
True. Cascade is a special case of a closure with delegate set to the receiver object and resolving set to "delegate only" (or delegate first?).It's more restricted than that. It's not just that the implicit receiver is being rebound. It's that top-level expressions in a cascade, and only top-level expressions have an implicit receiver that must be the LHS of the ".{".
This makes it a good bit more limited than Groovy-style DSLs but it also avoids the complexity and very painful performance charactersistics of the dynamic scoping that those (and JavaScript's "with") lead to.
> Kinda tedious. jQuery would give you:
>
> $('#myTable')
> .find('.firstColumn')
> .css({'background': 'red',
> ‘border’: ‘2px solid black’})
> .text(‘first column’)
> .end()
> .find('.lastColumn')
> .css('background','blue')
> .text(‘last column’);
>
This, on the other hand, looks like a confusing mess of out-of-place
and nested braces:
Am 24.11.2011 12:01 schrieb "Andrew" <thef...@ozemail.com.au>:
>
>
> The jQuery below looks very pretty.
>
> > Kinda tedious. jQuery would give you:
> >
> > $('#myTable')
> > .find('.firstColumn')
> > .css({'background': 'red',
> > ‘border’: ‘2px solid black’})
> > .text(‘first column’)
> > .end()
> > .find('.lastColumn')
> > .css('background','blue')
> > .text(‘last column’);
> >
>
> This, on the other hand, looks like a confusing mess of out-of-place
> and nested braces:
Hmmm. Interesting... It is right the opposite to me.
While the jquery looks like the nasty fluent interface in Java, where it is kind of a wannabe DSL, the proposal seems
very symmetric and clearly structured.
Parens are only for query params and not for query and setters alike.
Curlies are only for cascading and not for param grouping,
so no place where parens and braces are directly nested.
Properties are always set with equal expressions, not a mix of
property , arg and property : arg
All in all the optical pattern is:
XXXXX. {
yyyyyyy
yyyyyyy
}
Which is almost identical to If or Loop constructs.
//CASCADES
foo.{
a = 42,
b(foo.a),
c.d = 7,
e.{a = b, c = d}
};
//WITH STATEMENT
with (foo){
.a = 42;
.b(.a);
.c.d = 7;
with (.e){
.a = a;
.c = d;
}
}
//CASCADE
class Node {
String key;
Node(this.key);
Node left;
Node right;
}
void main() {
Node right = new Node('e');
Node root = new Node('root').{
left = new Node('a').{
left = new Node('b').{
left = new Node('c')
},
right = new Node(‘d')
},
right = right
};
print(root);
}
//WITH STATEMENT
void main(){
Node right = new Node('e');
Node root = new Node('root');
with (root) {
.left = new Node('a');
with (.left){
.left = new Node('b');
with (.left) {
.left = new Node('c');
}
.right = new Node('d');
}
.right = right;
}
print(root);
}
root // Someone have mistake here either me or author of original
paper.
/ \
a e
/ \
b d
|
c
In my opinion this is more readable and familiar: no commas, just
semicolons and no semilocolons after brackets. It reduces confusion
(and probably mistakes) if we do not have some new rules when we have
to use commas instead of semicolons. (Notice that there are no
semicolons after with block.)
I should mention that with statement would not resolve open questions
mentioned in original paper.
So I would make an extension method like so:
static int countWords(this String anyString, [String delimeter = " "])
{
...
return wordCount;
}
Then I have
String x = "now is the time";
x
.countWords()
.isEven(); //or whatever. any extension that operates on bool could
then continue this chain.
On Nov 23, 8:19 am, John <pruj...@gmail.com> wrote:
> +1
>
> I would advocate support for what .net has implemented along these
> lines: extensionmethods.
>
> If dart supportedextensionmethods, then chaining would be naturally
> supported.
>
> John
>
> On Nov 21, 7:48 pm, Bob Nystrom <rnyst...@google.com> wrote:
>
>
>
>
>
>
>
> > Jacob Richman, one of the people feverishly working on our new DOM library
> > has a language proposal to share with you. You can see it in Google doc
> > form here:https://docs.google.com/document/d/1U0PeHtVQHMQ8usy7xI5Luo01W5LuWR1ac...
> > .
>
> > One of the questions that's come up a few times with our DOM API is whether
> > or not it supports jQuery-style chaining. This proposal is answer to that.
>
> > jQuery is one of the most well-known examples of APIs designed around a
> > fluent interface. StringBuffer is another. EaselJS (http://easeljs.com/)
> > tries to make HTML Canvases easier to use by wrapping them in this style.
>
> > But note that all of those APIs had to be designed to specifically work
> > with that pattern. Also note that they work withmethods, but not getters
Support for extension methods means inherently supports method
chaining.
I do concede that EMs are not suitable for the specific case where you
want to move back up through the chain to get to a previous "state" of
the chain itself.
My case for EM's is probably better put in a dedicated thread, so I'll
spend some time later doing that.
On Nov 25, 2:44 am, Dirk Detering <mailto...@googlemail.com> wrote:
> Hello John,
>
> 2011/11/24 John <pruj...@gmail.com>
Porfirio, this exact matter has been discussed before in this thread. Please read it completely before trying to answer.
http://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/611c04100ac17142/6832dc5c4425c363?lnk=raot#6832dc5c4425c363