Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
49 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Chris Muller-3
Well, the new is taller and slimmer, with a consistent application of
Rectangular Block, a "best practice" formatting pattern.  I've never
found short and squat (and inconsistent!) to be easier to read than
tall & slim, but I guess we all have our visual acuity developed the
way it is developed.
method.

That's why I'd suggest to simply use pretty print when coming across a
method you find hard-to-read.

Also, if I make a small, one-line change to a method, I won't reformat
it out of respect for the prior author's format.  But if changes are
significant, it becomes "my" code and time is too scarce anyway to
spend time manually formatting code.  A Shift+Command+S just prior to
saving converts it to RB for me, which is easiest for most people to
read because, according to the pattern, people see things in
rectangles.



On Fri, Oct 4, 2013 at 6:06 AM, Bert Freudenberg <[hidden email]> wrote:

> On 2013-10-03, at 23:02, Chris Muller <[hidden email]> wrote:
>
>> The reformatting caused almost all lines to be dif'd.  The only change
>> is handling AttemptToWriteReadOnlyGlobal on the at:put:.
>
> I find the compact form the code had before a lot more readable.
>
> - Bert -
>
>>
>> On Thu, Oct 3, 2013 at 2:35 PM,  <[hidden email]> wrote:
>>> Chris Muller uploaded a new version of Compiler to project The Trunk:
>>> http://source.squeak.org/trunk/Compiler-cmm.275.mcz
>>>
>>> ==================== Summary ====================
>>>
>>> Name: Compiler-cmm.275
>>> Author: cmm
>>> Time: 3 October 2013, 2:34:56.409 pm
>>> UUID: 9d002330-e75e-436f-8699-b29413e98e81
>>> Ancestors: Compiler-nice.274
>>>
>>> When loading code, don't blow up just because of an undeclared ref.
>>>
>>> =============== Diff against Compiler-nice.274 ===============
>>>
>>> Item was changed:
>>>  ----- Method: Encoder>>undeclared: (in category 'encoding') -----
>>> + undeclared: name
>>> - undeclared: name
>>>        | sym |
>>>        requestor interactive ifTrue:
>>> +               [ requestor requestor == #error: ifTrue: [ requestor error: 'Undeclared' ].
>>> +               ^ self notify: 'Undeclared' ].
>>> -               [requestor requestor == #error: ifTrue:
>>> -                       [requestor error: 'Undeclared'].
>>> -                ^self notify: 'Undeclared'].
>>>        "Allow knowlegeable clients to squash the undeclared warning if they want (e.g.
>>>         Diffing pretty printers that are simply formatting text).  As this breaks
>>>         compilation it should only be used by clients that want to discard the result
>>>         of the compilation.  To squash the warning use e.g.
>>>                [Compiler format: code in: class notifying: nil decorated: false]
>>>                        on: UndeclaredVariableWarning
>>>                        do: [:ex| ex resume: false]"
>>>        sym := name asSymbol.
>>> +       ^ (UndeclaredVariableWarning new
>>> +               name: name
>>> +               selector: selector
>>> +               class: cue getClass) signal
>>> -       ^(UndeclaredVariableWarning new name: name selector: selector class: cue getClass) signal
>>>                ifTrue:
>>> +                       [ | undeclared |
>>> -                       [| undeclared |
>>>                        undeclared := cue environment undeclared.
>>> +                       [ undeclared
>>> +                               at: sym
>>> +                               put: nil ]
>>> +                               on: AttemptToWriteReadOnlyGlobal
>>> +                               do: [ : noti | noti resume: true ].
>>> +                       self
>>> +                               global: (undeclared associationAt: sym)
>>> +                               name: sym ]
>>> -                       undeclared at: sym put: nil.
>>> -                       self global: (undeclared associationAt: sym) name: sym]
>>>                ifFalse:
>>> +                       [ self
>>> +                               global: (Association key: sym)
>>> +                               name: sym ]!
>>> -                       [self global: (Association key: sym) name: sym]!
>>>
>>>
>>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Bert Freudenberg
On 2013-10-04, at 16:58, Chris Muller <[hidden email]> wrote:

> Well, the new is taller and slimmer, with a consistent application of
> Rectangular Block, a "best practice" formatting pattern.  I've never
> found short and squat (and inconsistent!) to be easier to read than
> tall & slim, but I guess we all have our visual acuity developed the
> way it is developed.
> method.
>
> That's why I'd suggest to simply use pretty print when coming across a
> method you find hard-to-read.
>
> Also, if I make a small, one-line change to a method, I won't reformat
> it out of respect for the prior author's format.  But if changes are
> significant, it becomes "my" code and time is too scarce anyway to
> spend time manually formatting code.  A Shift+Command+S just prior to
> saving converts it to RB for me, which is easiest for most people to
> read because, according to the pattern, people see things in
> rectangles.


Compare

        [ undeclared at: sym put: nil ]
                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

to:

        [ undeclared
                at: sym
                put: nil ]
                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

Isn't the first one much more "rectangular" and easier to read? I find the indentation in the second one irritating.

- Bert -

>
> On Fri, Oct 4, 2013 at 6:06 AM, Bert Freudenberg <[hidden email]> wrote:
>> On 2013-10-03, at 23:02, Chris Muller <[hidden email]> wrote:
>>
>>> The reformatting caused almost all lines to be dif'd.  The only change
>>> is handling AttemptToWriteReadOnlyGlobal on the at:put:.
>>
>> I find the compact form the code had before a lot more readable.
>>
>> - Bert -
>>
>>>
>>> On Thu, Oct 3, 2013 at 2:35 PM,  <[hidden email]> wrote:
>>>> Chris Muller uploaded a new version of Compiler to project The Trunk:
>>>> http://source.squeak.org/trunk/Compiler-cmm.275.mcz
>>>>
>>>> ==================== Summary ====================
>>>>
>>>> Name: Compiler-cmm.275
>>>> Author: cmm
>>>> Time: 3 October 2013, 2:34:56.409 pm
>>>> UUID: 9d002330-e75e-436f-8699-b29413e98e81
>>>> Ancestors: Compiler-nice.274
>>>>
>>>> When loading code, don't blow up just because of an undeclared ref.
>>>>
>>>> =============== Diff against Compiler-nice.274 ===============
>>>>
>>>> Item was changed:
>>>> ----- Method: Encoder>>undeclared: (in category 'encoding') -----
>>>> + undeclared: name
>>>> - undeclared: name
>>>>       | sym |
>>>>       requestor interactive ifTrue:
>>>> +               [ requestor requestor == #error: ifTrue: [ requestor error: 'Undeclared' ].
>>>> +               ^ self notify: 'Undeclared' ].
>>>> -               [requestor requestor == #error: ifTrue:
>>>> -                       [requestor error: 'Undeclared'].
>>>> -                ^self notify: 'Undeclared'].
>>>>       "Allow knowlegeable clients to squash the undeclared warning if they want (e.g.
>>>>        Diffing pretty printers that are simply formatting text).  As this breaks
>>>>        compilation it should only be used by clients that want to discard the result
>>>>        of the compilation.  To squash the warning use e.g.
>>>>               [Compiler format: code in: class notifying: nil decorated: false]
>>>>                       on: UndeclaredVariableWarning
>>>>                       do: [:ex| ex resume: false]"
>>>>       sym := name asSymbol.
>>>> +       ^ (UndeclaredVariableWarning new
>>>> +               name: name
>>>> +               selector: selector
>>>> +               class: cue getClass) signal
>>>> -       ^(UndeclaredVariableWarning new name: name selector: selector class: cue getClass) signal
>>>>               ifTrue:
>>>> +                       [ | undeclared |
>>>> -                       [| undeclared |
>>>>                       undeclared := cue environment undeclared.
>>>> +                       [ undeclared
>>>> +                               at: sym
>>>> +                               put: nil ]
>>>> +                               on: AttemptToWriteReadOnlyGlobal
>>>> +                               do: [ : noti | noti resume: true ].
>>>> +                       self
>>>> +                               global: (undeclared associationAt: sym)
>>>> +                               name: sym ]
>>>> -                       undeclared at: sym put: nil.
>>>> -                       self global: (undeclared associationAt: sym) name: sym]
>>>>               ifFalse:
>>>> +                       [ self
>>>> +                               global: (Association key: sym)
>>>> +                               name: sym ]!
>>>> -                       [self global: (Association key: sym) name: sym]!
>>>>
>>>>
>>>
>>
>>
>>
>>


Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Eliot Miranda-2



On Fri, Oct 4, 2013 at 8:07 AM, Bert Freudenberg <[hidden email]> wrote:
On 2013-10-04, at 16:58, Chris Muller <[hidden email]> wrote:

> Well, the new is taller and slimmer, with a consistent application of
> Rectangular Block, a "best practice" formatting pattern.  I've never
> found short and squat (and inconsistent!) to be easier to read than
> tall & slim, but I guess we all have our visual acuity developed the
> way it is developed.
> method.
>
> That's why I'd suggest to simply use pretty print when coming across a
> method you find hard-to-read.
>
> Also, if I make a small, one-line change to a method, I won't reformat
> it out of respect for the prior author's format.  But if changes are
> significant, it becomes "my" code and time is too scarce anyway to
> spend time manually formatting code.  A Shift+Command+S just prior to
> saving converts it to RB for me, which is easiest for most people to
> read because, according to the pattern, people see things in
> rectangles.


Compare

        [ undeclared at: sym put: nil ]
                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

to:

        [ undeclared
                at: sym
                put: nil ]
                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

Isn't the first one much more "rectangular" and easier to read? I find the indentation in the second one irritating.

+1
 

- Bert -

>
> On Fri, Oct 4, 2013 at 6:06 AM, Bert Freudenberg <[hidden email]> wrote:
>> On 2013-10-03, at 23:02, Chris Muller <[hidden email]> wrote:
>>
>>> The reformatting caused almost all lines to be dif'd.  The only change
>>> is handling AttemptToWriteReadOnlyGlobal on the at:put:.
>>
>> I find the compact form the code had before a lot more readable.
>>
>> - Bert -
>>
>>>
>>> On Thu, Oct 3, 2013 at 2:35 PM,  <[hidden email]> wrote:
>>>> Chris Muller uploaded a new version of Compiler to project The Trunk:
>>>> http://source.squeak.org/trunk/Compiler-cmm.275.mcz
>>>>
>>>> ==================== Summary ====================
>>>>
>>>> Name: Compiler-cmm.275
>>>> Author: cmm
>>>> Time: 3 October 2013, 2:34:56.409 pm
>>>> UUID: 9d002330-e75e-436f-8699-b29413e98e81
>>>> Ancestors: Compiler-nice.274
>>>>
>>>> When loading code, don't blow up just because of an undeclared ref.
>>>>
>>>> =============== Diff against Compiler-nice.274 ===============
>>>>
>>>> Item was changed:
>>>> ----- Method: Encoder>>undeclared: (in category 'encoding') -----
>>>> + undeclared: name
>>>> - undeclared: name
>>>>       | sym |
>>>>       requestor interactive ifTrue:
>>>> +               [ requestor requestor == #error: ifTrue: [ requestor error: 'Undeclared' ].
>>>> +               ^ self notify: 'Undeclared' ].
>>>> -               [requestor requestor == #error: ifTrue:
>>>> -                       [requestor error: 'Undeclared'].
>>>> -                ^self notify: 'Undeclared'].
>>>>       "Allow knowlegeable clients to squash the undeclared warning if they want (e.g.
>>>>        Diffing pretty printers that are simply formatting text).  As this breaks
>>>>        compilation it should only be used by clients that want to discard the result
>>>>        of the compilation.  To squash the warning use e.g.
>>>>               [Compiler format: code in: class notifying: nil decorated: false]
>>>>                       on: UndeclaredVariableWarning
>>>>                       do: [:ex| ex resume: false]"
>>>>       sym := name asSymbol.
>>>> +       ^ (UndeclaredVariableWarning new
>>>> +               name: name
>>>> +               selector: selector
>>>> +               class: cue getClass) signal
>>>> -       ^(UndeclaredVariableWarning new name: name selector: selector class: cue getClass) signal
>>>>               ifTrue:
>>>> +                       [ | undeclared |
>>>> -                       [| undeclared |
>>>>                       undeclared := cue environment undeclared.
>>>> +                       [ undeclared
>>>> +                               at: sym
>>>> +                               put: nil ]
>>>> +                               on: AttemptToWriteReadOnlyGlobal
>>>> +                               do: [ : noti | noti resume: true ].
>>>> +                       self
>>>> +                               global: (undeclared associationAt: sym)
>>>> +                               name: sym ]
>>>> -                       undeclared at: sym put: nil.
>>>> -                       self global: (undeclared associationAt: sym) name: sym]
>>>>               ifFalse:
>>>> +                       [ self
>>>> +                               global: (Association key: sym)
>>>> +                               name: sym ]!
>>>> -                       [self global: (Association key: sym) name: sym]!
>>>>
>>>>
>>>
>>
>>
>>
>>





--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Chris Muller-3
>> Compare
>>
>>         [ undeclared at: sym put: nil ]
>>                 on: AttemptToWriteReadOnlyGlobal
>>                 do: [ :noti | noti resume: true ]
>>
>> to:
>>
>>         [ undeclared
>>                 at: sym
>>                 put: nil ]
>>                 on: AttemptToWriteReadOnlyGlobal
>>                 do: [ :noti | noti resume: true ]
>>
>> Isn't the first one much more "rectangular" and easier to read? I find the
>> indentation in the second one irritating.

Yes, I agree with you for that one case.  RB, Indented Control Flow,
etc. do not specify how to handle keywords sent to Blocks.  One
suggestion is to add a blank line, as in:

         [ undeclared
                 at: sym
                 put: nil ]

                 on: AttemptToWriteReadOnlyGlobal
                 do: [ :noti | noti resume: true ]

Or, an extra indention:

         [ undeclared
                 at: sym
                 put: nil ]
                      on: AttemptToWriteReadOnlyGlobal
                      do: [ :noti | noti resume: true ]

The important thing to handle the _general_ case, so the computer can
do at least 97% of the formatting.  If we had a larger keyword
message, your rule would look like this:

           [ mySoundRecorder copyTo: resultBuf from: j to: (j + n - 1)
from: buf startingAt: firstInBuf normalize: nFactor dcOffset: dcOffset
]
                   on: AttemptToWriteReadOnlyGlobal
                   do: [ :noti | noti resume: true ]

which, clearly, is a mess compared to:

           [ mySoundRecorder
                 copyTo: resultBuf
                 from: j
                 to: (j + n - 1)
                 from: buf
                 startingAt: firstInBuf
                 normalize: nFactor
                 dcOffset: dcOffset ]
                      on: AttemptToWriteReadOnlyGlobal
                      do: [ :noti | noti resume: true ]

I would LOVE to make pretty print use RB formatting in a way that's
acceptable to the wider community, so we can be developers and not
formatting slaves.

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Bert Freudenberg

On 2013-10-04, at 17:45, Chris Muller <[hidden email]> wrote:

>>> Compare
>>>
>>>        [ undeclared at: sym put: nil ]
>>>                on: AttemptToWriteReadOnlyGlobal
>>>                do: [ :noti | noti resume: true ]
>>>
>>> to:
>>>
>>>        [ undeclared
>>>                at: sym
>>>                put: nil ]
>>>                on: AttemptToWriteReadOnlyGlobal
>>>                do: [ :noti | noti resume: true ]
>>>
>>> Isn't the first one much more "rectangular" and easier to read? I find the
>>> indentation in the second one irritating.
>
> Yes, I agree with you for that one case.  RB, Indented Control Flow,
> etc. do not specify how to handle keywords sent to Blocks.  One
> suggestion is to add a blank line, as in:
>
>         [ undeclared
>                 at: sym
>                 put: nil ]
>
>                 on: AttemptToWriteReadOnlyGlobal
>                 do: [ :noti | noti resume: true ]
>
> Or, an extra indention:
>
>         [ undeclared
>                 at: sym
>                 put: nil ]
>                      on: AttemptToWriteReadOnlyGlobal
>                      do: [ :noti | noti resume: true ]
>
> The important thing to handle the _general_ case, so the computer can
> do at least 97% of the formatting.  If we had a larger keyword
> message, your rule would look like this:
>
>           [ mySoundRecorder copyTo: resultBuf from: j to: (j + n - 1)
> from: buf startingAt: firstInBuf normalize: nFactor dcOffset: dcOffset
> ]
>                   on: AttemptToWriteReadOnlyGlobal
>                   do: [ :noti | noti resume: true ]

You're misinterpreting my "rule" ;)

My rule is more like: If it clearly fits on one line then do not spread it over multiple lines. Otherwise, use your best judgement. :)

For your example I would probably end up with something like

        [ mySoundRecorder
                copyTo: resultBuf from: j to: (j + n - 1)
                from: buf startingAt: firstInBuf
                normalize: nFactor dcOffset: dcOffset
        ]
                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

even if it's not "agile". Source code is read way more often than written, so IMHO it is worth spending some time formatting it to make the meaning as obvious as possible.

That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.

> which, clearly, is a mess compared to:
>
>           [ mySoundRecorder
>                 copyTo: resultBuf
>                 from: j
>                 to: (j + n - 1)
>                 from: buf
>                 startingAt: firstInBuf
>                 normalize: nFactor
>                 dcOffset: dcOffset ]
>                      on: AttemptToWriteReadOnlyGlobal
>                      do: [ :noti | noti resume: true ]
>
> I would LOVE to make pretty print use RB formatting in a way that's
> acceptable to the wider community, so we can be developers and not
> formatting slaves.


- Bert -
Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

timrowledge

On 04-10-2013, at 9:23 AM, Bert Freudenberg <[hidden email]> wrote:
>
>
> That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.


We need a pragma to describe how a method's name is formatted by automagic formatters.
copyTo: resultBuf from: start to: stop) from: buf startingAt: firstInBuf normalize: nFactor dcOffset: offset
<pragma format: (3 5 7)>
        self wibble: buf….

The pragma says keep the first 3 keyword fragments together, then the next 2 and then the last 2, all as advisory input

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- Permanently out to lunch.



Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Bert Freudenberg

On 2013-10-04, at 18:31, tim Rowledge <[hidden email]> wrote:

>
> On 04-10-2013, at 9:23 AM, Bert Freudenberg <[hidden email]> wrote:
>>
>>
>> That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.
>
>
> We need a pragma to describe how a method's name is formatted by automagic formatters.
> copyTo: resultBuf from: start to: stop) from: buf startingAt: firstInBuf normalize: nFactor dcOffset: offset
> <pragma format: (3 5 7)>
> self wibble: buf….
>
> The pragma says keep the first 3 keyword fragments together, then the next 2 and then the last 2, all as advisory input


Well, or just use line breaks in the method pattern.

- Bert -


Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Chris Muller-3
This precise proposal is argued against by "Inline Message Pattern"
(pg. 172 of the book).  Method body's would be starting in all
different vertical places, your eyes have to "find" it.  And by
consuming more vertical space it will result in more required
scrolling.  Methods are often very short, would we really want to see
the message pattern take up more space than the body?

I don't like Tim's idea either, because it doesn't let each individual
define their own formatting preferences in case they have particularly
strong feelings about it (like us!).

Kent Beck isn't my favorite guy, but his Best Practice patterns are
wholly worthwhile, IMO.  He provides very detailed reasons for his
patterns.

On Fri, Oct 4, 2013 at 11:42 AM, Bert Freudenberg <[hidden email]> wrote:

>
> On 2013-10-04, at 18:31, tim Rowledge <[hidden email]> wrote:
>
>>
>> On 04-10-2013, at 9:23 AM, Bert Freudenberg <[hidden email]> wrote:
>>>
>>>
>>> That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.
>>
>>
>> We need a pragma to describe how a method's name is formatted by automagic formatters.
>> copyTo: resultBuf from: start to: stop) from: buf startingAt: firstInBuf normalize: nFactor dcOffset: offset
>> <pragma format: (3 5 7)>
>>       self wibble: buf….
>>
>> The pragma says keep the first 3 keyword fragments together, then the next 2 and then the last 2, all as advisory input
>
>
> Well, or just use line breaks in the method pattern.
>
> - Bert -
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Bert Freudenberg
On 2013-10-04, at 20:02, Chris Muller <[hidden email]> wrote:

> This precise proposal is argued against by "Inline Message Pattern"
> (pg. 172 of the book).  Method body's would be starting in all
> different vertical places, your eyes have to "find" it.  And by
> consuming more vertical space it will result in more required
> scrolling.  Methods are often very short, would we really want to see
> the message pattern take up more space than the body?

You're putting up a straw man here. Nobody is proposing to always put a keyword on a new line. That would make no sense at all.

However, if you have a pattern with many and long keywords, then putting in explicit line breaks may be preferable to the automatic line wrapping. You would do that to group the keywords semantically.

- Bert -

>
> On Fri, Oct 4, 2013 at 11:42 AM, Bert Freudenberg <[hidden email]> wrote:
>>
>> On 2013-10-04, at 18:31, tim Rowledge <[hidden email]> wrote:
>>
>>>
>>> On 04-10-2013, at 9:23 AM, Bert Freudenberg <[hidden email]> wrote:
>>>>
>>>>
>>>> That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.
>>>
>>>
>>> We need a pragma to describe how a method's name is formatted by automagic formatters.
>>> copyTo: resultBuf from: start to: stop) from: buf startingAt: firstInBuf normalize: nFactor dcOffset: offset
>>> <pragma format: (3 5 7)>
>>>      self wibble: buf….
>>>
>>> The pragma says keep the first 3 keyword fragments together, then the next 2 and then the last 2, all as advisory input
>>
>>
>> Well, or just use line breaks in the method pattern.
>>
>> - Bert -
>>
>>
>




Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

marcel.taeumel (old)
In reply to this post by Bert Freudenberg
Where do those spaces before/after square brackets come from? I assume that is due to using a non-monospaced font by default? ^____^' I've never understood that.

But nevermind. ;)

Best,
Marcel
Reply | Threaded
Open this post in threaded view
|

Code formatting patterns (was: The Trunk: Compiler-cmm.275.mcz)

Louis LaBrunda
In reply to this post by Bert Freudenberg
On Fri, 4 Oct 2013 17:07:09 +0200, Bert Freudenberg <[hidden email]>
wrote:

>On 2013-10-04, at 16:58, Chris Muller <[hidden email]> wrote:
>
>> Well, the new is taller and slimmer, with a consistent application of
>> Rectangular Block, a "best practice" formatting pattern.  I've never
>> found short and squat (and inconsistent!) to be easier to read than
>> tall & slim, but I guess we all have our visual acuity developed the
>> way it is developed.
>> method.
>>
>> That's why I'd suggest to simply use pretty print when coming across a
>> method you find hard-to-read.
>>
>> Also, if I make a small, one-line change to a method, I won't reformat
>> it out of respect for the prior author's format.  But if changes are
>> significant, it becomes "my" code and time is too scarce anyway to
>> spend time manually formatting code.  A Shift+Command+S just prior to
>> saving converts it to RB for me, which is easiest for most people to
>> read because, according to the pattern, people see things in
>> rectangles.
>
>
>Compare
>
> [ undeclared at: sym put: nil ]
> on: AttemptToWriteReadOnlyGlobal
> do: [ :noti | noti resume: true ]
>
>to:
>
> [ undeclared
> at: sym
> put: nil ]
> on: AttemptToWriteReadOnlyGlobal
> do: [ :noti | noti resume: true ]
>
>Isn't the first one much more "rectangular" and easier to read? I find the indentation in the second one irritating.
>
>- Bert -

+1

Lou
-----------------------------------------------------------
Louis LaBrunda
Keystone Software Corp.
SkypeMe callto://PhotonDemon
mailto:[hidden email] http://www.Keystone-Software.com


Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Ben Coman
In reply to this post by Bert Freudenberg
Bert Freudenberg wrote:
On 2013-10-04, at 17:45, Chris Muller [hidden email] wrote:

  
Compare

       [ undeclared at: sym put: nil ]
               on: AttemptToWriteReadOnlyGlobal
               do: [ :noti | noti resume: true ]

to:

       [ undeclared
               at: sym
               put: nil ]
               on: AttemptToWriteReadOnlyGlobal
               do: [ :noti | noti resume: true ]

Isn't the first one much more "rectangular" and easier to read? I find the
indentation in the second one irritating.
        
Yes, I agree with you for that one case.  RB, Indented Control Flow,
etc. do not specify how to handle keywords sent to Blocks.  One
suggestion is to add a blank line, as in:

        [ undeclared
                at: sym
                put: nil ]

                on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

Or, an extra indention:

        [ undeclared
                at: sym
                put: nil ]
                     on: AttemptToWriteReadOnlyGlobal
                     do: [ :noti | noti resume: true ]

The important thing to handle the _general_ case, so the computer can
do at least 97% of the formatting.  If we had a larger keyword
message, your rule would look like this:

          [ mySoundRecorder copyTo: resultBuf from: j to: (j + n - 1)
from: buf startingAt: firstInBuf normalize: nFactor dcOffset: dcOffset
]
                  on: AttemptToWriteReadOnlyGlobal
                  do: [ :noti | noti resume: true ]
    

You're misinterpreting my "rule" ;)

My rule is more like: If it clearly fits on one line then do not spread it over multiple lines. Otherwise, use your best judgement. :)

For your example I would probably end up with something like

	[ mySoundRecorder
                copyTo: resultBuf from: j to: (j + n - 1)
                from: buf startingAt: firstInBuf
                normalize: nFactor dcOffset: dcOffset
	]
		on: AttemptToWriteReadOnlyGlobal
                do: [ :noti | noti resume: true ]

even if it's not "agile". Source code is read way more often than written, so IMHO it is worth spending some time formatting it to make the meaning as obvious as possible. 

That said, I could live with your version below, in particular if it was automatically produced. It just doesn't feel as nice as the hand-formatted one which even takes into account the semantics of keywords to find suitable breaks.

  
which, clearly, is a mess compared to:

          [ mySoundRecorder
                copyTo: resultBuf
                from: j
                to: (j + n - 1)
                from: buf
                startingAt: firstInBuf
                normalize: nFactor
                dcOffset: dcOffset ]
                     on: AttemptToWriteReadOnlyGlobal
                     do: [ :noti | noti resume: true ]

I would LOVE to make pretty print use RB formatting in a way that's
acceptable to the wider community, so we can be developers and not
formatting slaves.
    


- Bert -

  
Bert, I like your vertical alignment of square braces for blocks.  For myself, this is my only absolute formatting rule, excepting only when opposing braces fit the same line.  Unfortunately most Smalltalk code puts the closing brace as soon as possible at the end of the last statement of the block.  Sometimes three or four closing braces pile up together at the end of a line, and it is slow to isolate the matching open braces. (Maybe that indicates other architectural issues with the code, but the reality is these situations occur.)  As a slight twist of my own to your last example, I indent the first statement one tabstop.

	[ 	mySoundRecorder
                	copyTo: resultBuf from: j to: (j + n - 1)
	                from: buf startingAt: firstInBuf
        	        normalize: nFactor dcOffset: dcOffset
	]	on: AttemptToWriteReadOnlyGlobal do: 
		[ 	:noti |
			noti someOtherMethod. 
			noti resume: true 
		]

cheers -ben



Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Stéphane Rollandin
In reply to this post by Bert Freudenberg
> Compare
>
> [ undeclared at: sym put: nil ]
> on: AttemptToWriteReadOnlyGlobal
> do: [ :noti | noti resume: true ]
>
> to:
>
> [ undeclared
> at: sym
> put: nil ]
> on: AttemptToWriteReadOnlyGlobal
> do: [ :noti | noti resume: true ]
>
> Isn't the first one much more "rectangular" and easier to read? I find the indentation in the second one irritating.

+1

Stef

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Stéphane Rollandin
In reply to this post by Chris Muller-3
> which, clearly, is a mess compared to:
>
>             [ mySoundRecorder
>                   copyTo: resultBuf
>                   from: j
>                   to: (j + n - 1)
>                   from: buf
>                   startingAt: firstInBuf
>                   normalize: nFactor
>                   dcOffset: dcOffset ]
>                        on: AttemptToWriteReadOnlyGlobal
>                        do: [ :noti | noti resume: true ]

I prefer

             [ mySoundRecorder
                   copyTo: resultBuf
                    from: j
                    to: (j + n - 1)
                    from: buf
                    startingAt: firstInBuf
                    normalize: nFactor
                    dcOffset: dcOffset
             ]
             on: AttemptToWriteReadOnlyGlobal
             do: [ :noti | noti resume: true ]


Stef

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Frank Shearar-3
In reply to this post by Ben Coman
On 5 October 2013 14:34, Ben Coman <[hidden email]> wrote:

> Bert Freudenberg wrote:
>
> On 2013-10-04, at 17:45, Chris Muller <[hidden email]> wrote:
>
>
>
> Compare
>
>        [ undeclared at: sym put: nil ]
>                on: AttemptToWriteReadOnlyGlobal
>                do: [ :noti | noti resume: true ]
>
> to:
>
>        [ undeclared
>                at: sym
>                put: nil ]
>                on: AttemptToWriteReadOnlyGlobal
>                do: [ :noti | noti resume: true ]
>
> Isn't the first one much more "rectangular" and easier to read? I find the
> indentation in the second one irritating.
>
>
> Yes, I agree with you for that one case.  RB, Indented Control Flow,
> etc. do not specify how to handle keywords sent to Blocks.  One
> suggestion is to add a blank line, as in:
>
>         [ undeclared
>                 at: sym
>                 put: nil ]
>
>                 on: AttemptToWriteReadOnlyGlobal
>                 do: [ :noti | noti resume: true ]
>
> Or, an extra indention:
>
>         [ undeclared
>                 at: sym
>                 put: nil ]
>                      on: AttemptToWriteReadOnlyGlobal
>                      do: [ :noti | noti resume: true ]
>
> The important thing to handle the _general_ case, so the computer can
> do at least 97% of the formatting.  If we had a larger keyword
> message, your rule would look like this:
>
>           [ mySoundRecorder copyTo: resultBuf from: j to: (j + n - 1)
> from: buf startingAt: firstInBuf normalize: nFactor dcOffset: dcOffset
> ]
>                   on: AttemptToWriteReadOnlyGlobal
>                   do: [ :noti | noti resume: true ]
>
>
> You're misinterpreting my "rule" ;)
>
> My rule is more like: If it clearly fits on one line then do not spread it
> over multiple lines. Otherwise, use your best judgement. :)
>
> For your example I would probably end up with something like
>
> [ mySoundRecorder
>                 copyTo: resultBuf from: j to: (j + n - 1)
>                 from: buf startingAt: firstInBuf
>                 normalize: nFactor dcOffset: dcOffset
> ]
> on: AttemptToWriteReadOnlyGlobal
>                 do: [ :noti | noti resume: true ]
>
> even if it's not "agile". Source code is read way more often than written,
> so IMHO it is worth spending some time formatting it to make the meaning as
> obvious as possible.
>
> That said, I could live with your version below, in particular if it was
> automatically produced. It just doesn't feel as nice as the hand-formatted
> one which even takes into account the semantics of keywords to find suitable
> breaks.
>
>
>
> which, clearly, is a mess compared to:
>
>           [ mySoundRecorder
>                 copyTo: resultBuf
>                 from: j
>                 to: (j + n - 1)
>                 from: buf
>                 startingAt: firstInBuf
>                 normalize: nFactor
>                 dcOffset: dcOffset ]
>                      on: AttemptToWriteReadOnlyGlobal
>                      do: [ :noti | noti resume: true ]
>
> I would LOVE to make pretty print use RB formatting in a way that's
> acceptable to the wider community, so we can be developers and not
> formatting slaves.
>
>
> - Bert -
>
>
>
> Bert, I like your vertical alignment of square braces for blocks.  For
> myself, this is my only absolute formatting rule, excepting only when
> opposing braces fit the same line.  Unfortunately most Smalltalk code puts
> the closing brace as soon as possible at the end of the last statement of
> the block.  Sometimes three or four closing braces pile up together at the
> end of a line, and it is slow to isolate the matching open braces. (Maybe
> that indicates other architectural issues with the code, but the reality is
> these situations occur.)  As a slight twist of my own to your last example,
> I indent the first statement one tabstop.

Ah, there's no war like a code formatting war. To throw my twig into
the fire, I far prefer piling up those ]]]s together, but hey, I write
Lisp in my spare time.

(]]]s belong together because (a) they're not terribly important and
(b) your code editor should make it easy to work with them. Lisp's
luckier than Smalltalk because the language, being even more regular
than Smalltalk, lets you use paredit-mode. Paredit-mode is fantastic
for manipulating s-expressions.)

frank

> cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Chris Muller-3
In reply to this post by Ben Coman
> Bert, I like your vertical alignment of square braces for blocks.  For
> myself, this is my only absolute formatting rule, excepting only when
> opposing braces fit the same line.  Unfortunately most Smalltalk code puts
> the closing brace as soon as possible at the end of the last statement of
> the block.  Sometimes three or four closing braces pile up together at the
> end of a line, and it is slow to isolate the matching open braces. (Maybe

Not if you use Shout.  Each level of parentheses and blocks specifies
its own color.

Nor if you simply click in the inner edge of the bracket.  Or Command+Space it.

Most Smalltlak code employs Rectangular Block because it's an
object-oriented format.  Like a text-version of Scratch tiles.

> that indicates other architectural issues with the code, but the reality is
> these situations occur.)  As a slight twist of my own to your last example,
> I indent the first statement one tabstop.
>
> [ mySoundRecorder
>                 copyTo: resultBuf from: j to: (j + n - 1)
>                from: buf startingAt: firstInBuf
>                normalize: nFactor dcOffset: dcOffset
> ] on: AttemptToWriteReadOnlyGlobal do:
> [ :noti |
> noti someOtherMethod.
> noti resume: true
> ]

The above, by contrast, looks and feels procedural, with the brackets
"delimiting" the starts and ends of code segments.

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns (was: [squeak-dev] The Trunk: Compiler-cmm.275.mcz)

Chris Muller-3
In reply to this post by Bert Freudenberg
>> This precise proposal is argued against by "Inline Message Pattern"
>> (pg. 172 of the book).  Method body's would be starting in all
>> different vertical places, your eyes have to "find" it.  And by
>> consuming more vertical space it will result in more required
>> scrolling.  Methods are often very short, would we really want to see
>> the message pattern take up more space than the body?
>
> You're putting up a straw man here. Nobody is proposing to always put a keyword on a new line. That would make no sense at all.

Oh, I thought that's what you were proposing as an alternative to
Tim's pragma idea.  I guess I misunderstood.

> However, if you have a pattern with many and long keywords, then putting in explicit line breaks may be preferable to the automatic line wrapping. You would do that to group the keywords semantically.

I think it's better to format the language syntax elements
consistently, perhaps with a couple of exceptions like to:do: for the
sake of vertical space.  I think this gives the reader a
more-immediate awareness of the messages being sent, rather than
"reading prose".  It's a program, not a poem.  :)

Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Ben Coman
In reply to this post by Chris Muller-3
Chris Muller wrote:
Bert, I like your vertical alignment of square braces for blocks.  For
myself, this is my only absolute formatting rule, excepting only when
opposing braces fit the same line.  Unfortunately most Smalltalk code puts
the closing brace as soon as possible at the end of the last statement of
the block.  Sometimes three or four closing braces pile up together at the
end of a line, and it is slow to isolate the matching open braces. (Maybe
    

Not if you use Shout.  Each level of parentheses and blocks specifies
its own color.
  
Sure. Color helps.  I do use Shout. But your still have to "search" for the color of the opposing bracket.  It is not "immediately" obvious like vertical alignment.
Nor if you simply click in the inner edge of the bracket.  Or Command+Space it.
  
That also helps.  But it requires interaction. It is not as immediately obvious as vertical alignment.
Also you cannot view two of these simultaneously.  With vertical alignment multiple levels are visible simultaneously.

Most Smalltlak code employs Rectangular Block because it's an
object-oriented format.  Like a text-version of Scratch tiles.
  
Maybe I miss something, but I don't see how that form is particularly 'object-oriented' - except that it is common to Smalltalk and Smalltalk is object-oriented.  I haven't used Scratch, but reviewing [1] step 8 I see 'forever', 'repeat', 'if' all have strong visible vertical alignment of their left hand edge, and an empty blank line beneath.

[1] http://nebomusic.net/scratchlesson1/scratchexercise1.html

  
that indicates other architectural issues with the code, but the reality is
these situations occur.)  As a slight twist of my own to your last example,
I indent the first statement one tabstop.

[ mySoundRecorder
                copyTo: resultBuf from: j to: (j + n - 1)
               from: buf startingAt: firstInBuf
               normalize: nFactor dcOffset: dcOffset
] on: AttemptToWriteReadOnlyGlobal do:
[ :noti |
noti someOtherMethod.
noti resume: true
]
    

The above, by contrast, looks and feels procedural, with the brackets
"delimiting" the starts and ends of code segments.


  

But a block is a code segment, is it not? which IS in fact delimited by brackets. I understand that it might 'feel' procedural since Smalltalk (which happens to be OO) has typically formatted it one way, and a lot of other languages (which happen to be procedural) have formatted it another, but I don't understand there is a causal link between the formatting whether it is actually more procedural or object-oriented. 

My unsubstantiated belief is in the very early days, screen real-estate was more of a premium, and it made sense to avoid wasting lines dedicated to only a closing brace.  This was the same situation with early procedural languages, but good practice with those have moved on.  It is probably more important for procedural languages since code segments tend to be longer and more nested, but Smalltalk commonly having shorter methods shouldn't preclude the practice being applied to Smalltalk. Of course, cultural norms are much harder to address than technical merits.

cheers -ben


Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Bob Arning-2
In reply to this post by Frank Shearar-3
My only twig will be this - that strong concern about formatting may correlate with having too much code in the first place.

Cheers,
Bob

On 10/5/13 4:05 PM, Frank Shearar wrote:
Ah, there's no war like a code formatting war. To throw my twig into
the fire, 



Reply | Threaded
Open this post in threaded view
|

Re: Code formatting patterns

Tobias Pape
Am 06.10.2013 um 11:50 schrieb Bob Arning <[hidden email]>:

> My only twig will be this - that strong concern about formatting may correlate with having too much code in the first place.

this.



signature.asc (210 bytes) Download Attachment
123