Branching message chain (was: Customizing Cascade)

So I touched React Native and got my hands on JSX for the first time. I hope it's not only me, but in many times before, I felt I need something in Amber to better specify tree hierarchies (thinking HTML). When doing Silk, the problem appeared again. So I began to fantasize, what if we allow (at least in Amber) a few changes additions to Smalltalk syntax? I will present one of them, which seems to prove useful in lots of cases.

You surely know methods that look like

new: aString at: anObject
    ^ super new
        name: aString;
        address: anObject;
        yourself

There is this cascade with yourself everywhere. I would even assume, shamelessly, that majority of cascades, done properly, now ends with mandatory yourself, unless you want the result of last message -- but that does not happen often.

What I always liked in Smalltalk is it wanted its statements look like an English sentence. So what about "A person set name: foo; set address: bar; the person itself." we told the (parentheses-using, but still) "A person (set name: foo; set address: bar)." sentence? It is frowned upon to overuse paretheses in written language; but they have their place, where "btw information" in injected not changing the contents of the main line.

Therefore, why not having this in Smalltalk:

new: aString at: anObject
    ^ super new (
        name: aString;
        address: anObject)

or, since we don't need yourself any more, it can be a one-liner

new: aString at: anObject
    ^ super new (name: aString; address: anObject)

The idea is, in any place I can send a message there is an expression, I could place a "BTW cascade message branch" in parentheses. The value returned would be the object before the parentheses itself (eg. as if nothing was there at all), but before returning it, a few messages are sent to it.

It can be used in lots of little situations like ^ foo (reset) instead of ^ foo reset; yourself or foo reset. ^ foo where, I claim, it this can be easily readable as we are used to this role or parentheses in natural language.

Now back to the JSX inspiration. In Silk is just too flexible, there were five example of how to write a piece of HTML in Silk, using different approaches. Compare any of them to:

"chaining and branched messages everywhere,
dynamic arrays only for more"
'#client-main' asSilk
  FORM
    TABLE
      TR (
        TD: 'Username:';
        TD (INPUT: 'name'->'name'));
      TR (
        TD: 'Password:';
        TD (INPUT: {'name'->'password'. 'type'->'password'}));
      TR (TD INPUT: {'type'->'submit'. 'value'->'Okay'})

Yes, it looks Lispy a bit, but it is the version that has the least boilerplate. Not to mention it allows other forms like

"chaining and branched messages everywhere
messages preferred over implicit 'assoc is attribute'"
'#client-main' asSilk
  FORM
    TABLE
      TR (
        TD: 'Username:';
        TD (INPUT attrAt: 'name' put: 'name'));
      TR (
        TD: 'Password:';
        TD (INPUT
            attrAt: 'name' put: 'password';
            attrAt: 'type' put: 'password'));
      TR (TD INPUT
            attrAt: 'type' put: 'submit';
            attrAt: 'value' put: 'Okay')

for those who do not like 'foo'->'bar' setting an attribute and prefer message send instead, or even

"chaining and branched messages everywhere
messages preferred over implicit 'assoc is attribute'
TAG: not used, explicit << instead"
'#client-main' asSilk
  FORM
    TABLE
      TR (
        TD (<< 'Username:');
        TD (INPUT attrAt: 'name' put: 'name'));
      TR (
        TD (<< 'Password:');
        TD (INPUT
            attrAt: 'name' put: 'password';
            attrAt: 'type' put: 'password'));
      TR (TD INPUT
            attrAt: 'type' put: 'submit';
            attrAt: 'value' put: 'Okay')

for those who want to see complete message tree directly. But those are only side-effects, I see the first example as the main win.

What do you think? Is it very crazy idea or could this be adopted by more Smalltalkers?

EDIT: OMG, it can get even Lispier... since customizing message chain does not alter the expression value, foo (bar; baz) can as well be foo (bar) (baz). The result in Silk example is then:

"chaining and branched cascadeless messages everywhere,
dynamic arrays only for more"
'#client-main' asSilk
  FORM
    TABLE
      (TR
        (TD: 'Username:')
        (TD INPUT: 'name'->'name'))
      (TR
        (TD: 'Password:')
        (TD INPUT: {'name'->'password'. 'type'->'password'}))
      (TR TD INPUT: {'type'->'submit'. 'value'->'Okay'})

I wonder what @NicolasPetton would say to this...

EDIT 2: Made less necessary parentheses -- instead of only allowing single message (or cascade) in parentheses, treat them as "branched" message chain with the same receiver. That allows more Smalltalkish foo (bar baz: 3) instead of previously mandatory foo (bar (baz: 3)) to implement tmp := foo. tmp bar baz: 3. tmp; with the caveat that foo (bar baz: 3; quux) means tmp := foo. tmp bar baz:3; quux. tmp. not tmp := foo. tmp bar baz: 3. tmp quux. tmp as naive reading may convey; OTOH this is consistent with how Smalltalk cascades work everywhere else.

EDIT 3: To not make things explode with nonreadable code, I decided to only allow simple message chain foo (bar baz: 3) or a cascade foo (bar; baz: 3). but not the more complicated pieces, like the aforementioned foo (bar baz: 3; quux). It can always be enabled later, if this syntax is actually adopted by the community and they won't deem it too dangerous.

EDIT 4: There is one hard-to-read ambiguity there. Consider these cascades 2 + 3 negated + 4; sin vs 2 + 3 negated sin; + 4. Not that any sane person would use that, but you see that receiver of the first one is 2 + 3 negated, which receiver of the second is 3 negated. With cascades, if this happens, you can decipher after a while, but with branching messages (you can have more of them one after another) thing is much more less clear (pretend that #+ and #sin have actually some side-effects, so it is important who is the reciever): 2 + 3 (+ 4; sin) (sin; + 4) (sin) (+ 4). So I am adding one more syntactical restriction: no branching message after binary message argument (fine for all the rest). Again, as with previous edit, it can be added later if there is consensus how to read it without confusion.

EDIT 5: Final decision, dispelling all confusion, bring up as little additional rules in: anything you can syntactically affix to the receiver until the end of the statement is allowed in a branching message chain. So if you can do (tmp = foo bar) baz quux; frob: 3 + 4. tmp asString you could as well do foo bar (baz quux; frob: 3 + 4) asString. This example is extreme, but it illustrates the "anything you can syntactically use without parens, you can put in parens" point.