Short answer to "can produce more performant code":
yes, it can, following compiler theory, common expression elimination, applied to the left hand side of the cascade.
For example calling
a b c method1; method2
evaluates b and c once to determine the receiver of method1 and method2 where as
a b c method1.
a b c method2
obviously has to evaluate a b c twice with additional cost.
That leads to your argument that an optimization compiler should detect that and eliminate this redundancy for you.
But here you also have to ask if the optimization has the same effect.
Unfortunately, the answer here is no, not always.
I dare to say that such a proof is impossible in general, as this would imply a thorough investigation of the effects of calling a b c once or twice.
An example is e.g. seaside with its protocol to render:
html heading level: 1; with: 'Hello world'.
html heading level: 1; with: 'Hello world'.
has different effect than
html
heading level: 1; with: 'Hello world'.
;
level: 1; with: 'Hello world'.
so in such cases (protocols with side effects in general) you have to write precisely what you mean.
So lint and any other similar tool will give you only a hint that cascading may gain performance, but it is up to you to decide if that would be also correct to do so.
The same applies vice versa, to exand a cascade to series of individual cases.
How to test that performance gain: a simple mean is to bench repeated execution of such a code fragment (using Envy/Stats).
Another way is to investigate the emitted byte code, for insiders:
For example
html heading
level: 1;
with: 'Hello world'.
html heading
level: 1;
with: 'Hello world'
yields
0000 00 temps = 0
0001 01 args = 1
0002 00 prim = 0 VMprSendNoTempsNoBlock
0003 00 stackFrame = 0
0004 7F BCpushTemp0 - (sp) push temp 0 (html)
0005 87 BCsendUnary0 - (sp) send unary 0 (#heading), args = 0
0006 0F BCdupTOS - dup TOS
0007 41 03 BCpushMagicB - (b ) push magic 3 (SmallInteger 1)
0009 66 20 BCsendDropArgs1 - (sp) send/drop literal 1 (#level:), args = 1
0011 25 24 BCpushLiteralB - (b ) push literal 2 ('Hello world')
0013 66 28 BCsendDropArgs1 - (sp) send/drop literal 3 (#with:), args = 1
0015 7F BCpushTemp0 - (sp) push temp 0 (html)
0016 87 BCsendUnary0 - (sp) send unary 0 (#heading), args = 0
0017 0F BCdupTOS - dup TOS
0018 41 03 BCpushMagicB - (b ) push magic 3 (SmallInteger 1)
0020 66 20 BCsendDropArgs1 - (sp) send/drop literal 1 (#level:), args = 1
0022 25 24 BCpushLiteralB - (b ) push literal 2 ('Hello world')
0024 66 28 BCsendDropArgs1 - (sp) send/drop literal 3 (#with:), args = 1
0026 44 BCreturnTOS - return TOS
where as
html
level: 1;
with: 'Hello world';
level: 1;
with: 'Hello world'
will give a more compact code
0000 00 temps = 0
0001 01 args = 1
0002 00 prim = 0 VMprSendNoTempsNoBlock
0003 00 stackFrame = 0
0004 7F BCpushTemp0 - (sp) push temp 0 (html)
0005 0F BCdupTOS - dup TOS
0006 41 03 BCpushMagicB - (b ) push magic 3 (SmallInteger 1)
0008 5C 1C 01 BCsendDropDupLiteralB - (b ) send/drop/dup literal 0 (#level:), args = 1
0011 25 20 BCpushLiteralB - (b ) push literal 1 ('Hello world')
0013 5C 24 01 BCsendDropDupLiteralB - (b ) send/drop/dup literal 2 (#with:), args = 1
0016 41 03 BCpushMagicB - (b ) push magic 3 (SmallInteger 1)
0018 66 1C BCsendDropArgs1 - (sp) send/drop literal 0 (#level:), args = 1
0020 25 20 BCpushLiteralB - (b ) push literal 1 ('Hello world')
0022 66 24 BCsendDropArgs1 - (sp) send/drop literal 2 (#with:), args = 1
0024 44 BCreturnTOS - return TOS
Two byte codes less, indicating a potentially slight performance gain.
However, as I explained, in seaside the compact code will not have the same effect.
Summary: be careful. Converting of cascades is complex in respect of side effects.
Remember: protocols like
a ifNil: [:b ]
a and: [b]
vs.
a isNil ifTrue: [a]
a & b
also deal with this topic "common expression elimination"
It is up to you to choose what you want, not being left to an optimizing compiler.
Kind regard
Marcus