Roslyn: C# structure isn't DRY

Created on 21 May 2015  Â·  68Comments  Â·  Source: dotnet/roslyn

In C#, the curly braces and indentation provide redundant ways to express the structure of namespaces, types, statement blocks, etc. Only the braces are normative, but if the indentation doesn't match, it confuses people. To compensate for the need to repeat ourselves, we use coding guidelines and tools to enforce the pairing.

Of course the redundancy intentional, going way back to C. It allows unusual whitespace patterns for the rare circumstances where they are useful. Perhaps a whitespace-ignorant parser was simpler to write on the memory constrained computers of the 1960s.

In any case, the lack of DRYness is a design hole that - while consciously carried forward - is fixable. A great solution would be to take page out of F#'s book and retain the existing curly-brace syntax as the verbose syntax and introduce a new whitespace-based lightweight syntax.

Area-Language Design Discussion

Most helpful comment

So we repeat the C# structure with whitespace

I don't do that. I type the syntax specified by the language, and the editor places it in a logical layout that matches what I typed. Indentation-based layout still requires the programming to type characters when changing scope, but relocates these scope-identifying characters from { and } to Tab and Backspace. This represents a reduction in ergonomic efficiency even if you assume (as I have) that the editor is smart enough to never require an explicit Enter.

If you are typing more characters in a curly-brace language just to maintain visual clarity, perhaps it means you need to either improve (or request improvements to) the editor's handling of format-while-you-type, or get a better editor. But making it more difficult to manage (in terms of number of characters typed and/or distance your fingers need to travel to type it) is obviously not a desirable answer when measured on the principles you seem to be advocating for.

All 68 comments

Razor has a big benefit from the fact that C# doesn't care about whitespace.

How is whitespace scoping more DRY? You are repeating yourself on every single line by re-affirming what scope you want to be in!

And what happens when you copy and paste a bit of code in a language where whitespace has semantic meaning? You can silently give that code different meaning than what you think it has.

Whitespace scoping is the part I dislike the most about both F# and Python and am strongly against bringing it to C#.

It's especially fun when working on a project where people are mixing spaces and tabs.

No, white space scoping has no place in C# or any C-derived language, and we're better off for it. There is no lack of CLR languages, including those with white space scoping. I suggest using them.

This is where Roslyn's static analysis could come in handy. It probably wouldn't be too hard to write an analyzer that errors at what you consider to be bad whitespacing, but please don't make this a language-level feature, because other people will have different opinions on whitespacing (like tabs vs. spaces, as @HaloFour mentioned).

I'm very much of the mindset that "white space is not code". Style is, and should be in my opinion, a distinctly separate thing from code / logic. I see useful constructs all the time like the following

if (foo == bar) DoSomething();

if (foo == bar)
    DoSomething();

if (foo == bar)
{
    DoSomething();
}

if (foo == bar) {
    DoSomething();
}

if (foo == bar)
{ DoSomething(); }

These are completely legitimate styles and project use what suites them. Enforcing a style isn't going to help the language, but it will break a lot of existing code.

@breyed You appear to be proposing something but you stop short of telling us what your proposal is. Can you please give an example of the syntax you propose would be supported (in addition to what is already supported, presumably).

I disagree with the premise. If C# mandated that indentation match the braces, then you would certainly violate DRY. This is not the case. Only the braces determine scope, and only one set of braces is required for each scope.

Since C# ignores whitespace when determining structure, it is DRY in its normative definition, as @sharwell points out. However, if you write code without repeating yourself you will have unindented and unmaintainable code. So we repeat the C# structure with whitespace, in a variety of styles, as @whoisj shared. Eliminating the redundancy and stylistic differences would both be a productivity boost to development teams.

I don't have a specific syntax to solve the DRYness problem in mind (@gafter). Some principles are clear, however. Since indentation is important to programmers, it's is a natural choice to specify scope (not reaffirm scope @MgSam suggested, which implies a succeeding line by default keeps the same scope as its previous line). There needs to be clear rules about the type of whitespace, per @HaloFour's point on tabs vs. spaces. F# deals with this by mandating spaces only, though perhaps a more creative solution allowing tabs along with good editor support to stick with a common style would be even better.

Indent-based structure introduces an ambiguity when pasting (per @MgSam). In the C# sequential structure, subsequent text is at the same scope as the previous text, and editors auto-format to put it there. It is explicit because block ends are explicit. With indent-based structure, it is ambiguous as to whether a new line is a continuation of the previous block or a new block. Here's an example:

// Verbose syntax
if (a) {
    foo();
}
bar(); // This line pasted in - unambiguous destination

// Lightweight syntax
if (a):
    foo()
bar() // This line pasted in - should it be aligned with "if" or "foo"?

Despite the ambiguity, there are good choices for an editor to provide the developer a good experience. One choice would be to ask where "bar()" should be placed. Better, however, would be to place the pasted block at the same indent level as the previous line and let the developer move it if desired. Either way, a lightweight syntax would not pose a problem for pasting code from unrelated sources.

Moreover, it would be a straightforward editor feature to take pasted code in verbose syntax (e.g. from StackOverflow) and transform it automatically to lightweight syntax, since the language remains otherwise the same. This is an advantage of adding a lightweight syntax to C#, versus @HaloFour's suggestion of using an alternative language.

So we repeat the C# structure with whitespace

I don't do that. I type the syntax specified by the language, and the editor places it in a logical layout that matches what I typed. Indentation-based layout still requires the programming to type characters when changing scope, but relocates these scope-identifying characters from { and } to Tab and Backspace. This represents a reduction in ergonomic efficiency even if you assume (as I have) that the editor is smart enough to never require an explicit Enter.

If you are typing more characters in a curly-brace language just to maintain visual clarity, perhaps it means you need to either improve (or request improvements to) the editor's handling of format-while-you-type, or get a better editor. But making it more difficult to manage (in terms of number of characters typed and/or distance your fingers need to travel to type it) is obviously not a desirable answer when measured on the principles you seem to be advocating for.

Note that braces do not indicate scope. They indicate blocks. The scoping applies to a single statement, and a block qualifies as a statement.

As whitespace is entirely optional as is indentation. Yes, there are various common styles used to indicate scope, but there are also many instances where one may want to deviate from a style where it makes the syntax visually clearer. If whitespace dictated scope or blocks that would no longer be an option. You'd be left to follow the rigid whitespace rules despite what would actually look appropriate.

No, this doens't belong in C#. It doesn't belong anywhere near C#. It to you braces make for a "heavy" language I don't want to know what you consider to be a light language. I've programmed COBOL (there goes the history claim), CoffeeScript and Python and it is obnoxious to me to be so constrained as to how you're permitted to lay out your code because someone decided to bake their coding conventions into the syntax.

Note that braces do not indicate scope. They indicate blocks.

@HaloFour I'm using the term in a more abstract sense to refer to lexical scope. Even in C#, however, the term "blocks" can be confusing because that's not a standard way to refer to the braces of a namespace declaration.

@HaloFour I've written a fair amount of Python and F# and have yet to encounter a case where I've wanted to indent in a way contrary to the language's rules. Can you provide an example where indent-defined structure would be overly constraining?

It's a good thing my socks are DRY then, ... oh wait.

@breyed in my examples, there's nothing "unproductive" about any of them. Simple tools like Astyle and complex IDEs like Visual Studio can be set to automatically format your code. Give the ease by which each developer can format code (so long as whitespace is a non-issue), I completely do not understand your logic.

If whitespace were difficult to manage or a requirement for doing work, I'd agree about your DRY concern. At no point do I feel that I am repeating myself when I code C# in Visual Studio. The IDE closes braces, formats indention and whitespace for me, and generally checks that code is compliant. I focus on the logic and flow while retaining a layout (whitespace, indention, etc) that is pleasing to me, requires minimal brain power to parse, and makes me more productive. YMMV

Can you provide an example where indent-defined structure would be overly constraining?

LINQ method chaining?

db.Posts.Where(p => p.User == user)
        .OrderByDescending(p => p.Date)
        .Take(10)
        .Select(p => new {
           //...
        })
        .ToList();

If I wasn't allowed to line up the dots because "it's contrary to the language's indentation rules", then it wouldn't be visually pleasing in the slightest.

@Joe4evr An intent-defined structure can support multi-line fluent APIs. A lightweight C# can use more than just indents to indicate expression continuation (a "." in this case). F# does this. For example, the following is valid F# lightweight syntax:

db.Posts.Where(fun p -> p.User = user)
        .OrderByDescending(fun p -> p.Date)
        .Take(10)
        .Select(fun p -> (
            // ...
        ))
        .ToList();

_You keep using this word [lightweight]. I don't think it means what you think it means._

What does the following mean in CoffeeScript?

x.foo 1
 .bar 2

Answer: completely depends on the version of the transpiler.

And for fun, in order to override the stupidity of the whitespace-sensitivity you had to know two different syntaxes and know when to apply which in order to override the behavior.

Do not want. If I wanted F# or Python I'd use F# or Python. The immeasurable effort necessary to bring a completely different form of parsing to C# would provide absolutely no real benefit and would likely provide only much more confusion. All just to avoid curly braces?

C# is becoming more DRY in general. The proposals in C# 6.0 and 7.0 for import of static type members into namespace, auto property initializers, default values for getter-only properties, and declaration expressions, all remove redundancy without adding any new functionality. Depending on your choice of editor and plug-ins, your tooling will generate much of this redundant code for you (as is the case with indenting, as @sharwell noted). So why all these new features? Because code generation is good, but code elimination is better.

For example, ever get confused by code accidentally checked in with incorrect indentation? As @whoisj alluded to, inconsistencies should be rare, since the code can be formatted automatically, but they still happen. We normalize our database schemas to avoid the pitfalls of data inconsistencies. Those benefits apply to code, too.

As with the other proposals to lean out C#, removing unnecessary code lets you focus on your logic and gets more of your logic on the screen. A closing brace generally ties up a whole line just to offer a single piece of information that your indentation, if sane, has already told you.

C# has a history of learning from the strengths and pitfalls of the languages that go before it. It is inconceivable that the flaws @HaloFour exposed in CoffeeScript would make their way into a lightweight C# syntax. Simply borrowing F#'s approach to specifying which syntax would be sufficient to avoid pitfalls. (BTW, I am borrowing the term _lightweight_ from F# as a technical term, not for purposes of persuasion (the latter would also be inconceivable :)).

I personally prefer C# syntax over F# syntax, deriving from OCAML was a mistake. More concise != more readable. Besides, there is already a lot of arguing about the best way to format code in current C#. Adding an extra option will make it only worse.

PS: @breyed - I noticed you are using punctuation in your English, those commas and round brackets are non-DRY too, but they do improve readability :-).

Please forgive, @dsaf, in advance, but I just can't resist: punctuation in English is more normative than I think you realize. For example, the commas around your username in this comment indicate its use as an appositive (rather than a direct object as it would be without surrounding commas). The punctuation changes the meaning entirely. Your postscript is a comma splice (a type of run-on sentence). Your comma (which should be semicolon) after _English_ makes _commas_ and _brackets_ modifiers of either _punctuation_ or _English_. The clause "are non-DRY too" then introduces a parsing error, not due to repetition, but by violating a constraint on verb usage. Fortunately, humans come with excellent algorithms for automatically correcting invalid syntax (reminds me of web browsers). :-)

@breyed Speaking of syntaxes that have evolved over time. If you rigorously apply what is taught in academia today to English texts written a century ago it wouldn't make much sense.

You've still yet to propose an alternate syntax. You have one short example, but all you've done is replace a { with a :. You have no choice but to not be DRY given that the lack of anything already has specific scoping rules. All you could hope to eliminate is some form of block ending indicator.

And none of those other syntax changes drastically alter the basic forms through which C# is parsed. Anonymous delegates in C# 2.0 were probably the last time the basic structure had been altered, but even that kept to block scoping rules. C# does enjoy learning from the mistakes of others, and whitespace scoping is one big mistake you're not going to see adopted.

Good syntax is often a detailed and subtle endeavor, which is why I focused on just noting the issue. Prompted by @HaloFour's comment, I've given this some thought and would offer the following lightweight syntax. I'd have to dig through the C# spec to get the precise grammatical terminology, but this should give you the gist.

  • An indented line following a namespace, type, or controls block header means the indented lines are wrapped with implied braces.
  • A colon following a namespace, type, or controls block header on the same line means the text following the colon on its same line, along with any indented contents from subsequent lines, are wrapped with implied braces.
  • A statement or member definition whose next line is at the same or less indentation level has an implied semicolon at the end.

Examples:

Lightweight         Verbose
-----------         ------------
if (foo)            if (foo) {
  bar1()              bar1();
  bar2()              bar2();
                    }

if (foo):           if (foo)
  bar1()              bar1();

if (foo): bar1()    if (foo) {
  bar2()              bar1();
                      bar2();
                    }

if (foo): bar1()    if (foo)
bar2()                bar1();
                    bar2();

class A             class A {
  int f               int f;
  int P               int P {
    get: return 0       get { return 0; }
    set: f = value      set { f = value; }
                      }
                    }

BTW, I read _Treasure Island_ to my kids not too long ago. I didn't notice any differences in the English syntax of 132 years ago from that of today.

@breyed That's about what I expected. You _don't_ want C#. You want another language. Those languages already exist so I imagine that your problem is the inability to find jobs for those languages.

The semi-colon elimination proposal was already brought up. Again, C# was not designed for this, and the sheer volume of breaking changes and ambiguities (and the _massive_ effort that would be involved to even attempt to resolve that) make it a non-starter, primarily because there is _zero_ benefit to it. That bears repeating, this proposal provides ZERO benefit.

Barring that, your very first example already violates existing C# syntax. The rest of them just make it unreadable. And none of this is even remotely lightweight.

I can't comment on Treasure Island. I haven't read it in a long time. You should try the US Constitution, though. Entire court cases have revolved around the interpretation of different passages as written vs. modern English, commas in particular. Not to mention that the English alphabet had more letters then.

@HaloFour Recall that I suggest having two syntaxes, the existing syntax ("verbose") and a new syntax ("lightweight"). This would ensure no breaking changes. F# was successful with this approach. Ambiguity is another matter. Can you think of an example in which the proposed lightweight syntax would be ambiguous? And speaking examples, I'd love to see an example of a comma-based constitutional court case in which the date of the writing makes any difference, or an example of an additional English letter in the eighteenth century - although over here would be a better place.

@breyed I continue to contend that you suggest having two languages.

Try Googling "supreme court guns comma", the resulting articles/blogs/thesis/etc. are an interesting read. Makes you wonder what CongreĹż* was thinking.

* How "Congress" was spelled in 1789, as appears in the Bill of Rights.

Braces in Razor are a pain if you're trying to keep the newlines tidy in your output HTML. For example, the following leaves an extra blank line before the table close tag.

<table>
    @foreach (var item in list) {
        <tr>
            <td>item.Name</td>
            <td>item.Description</td>
        </tr>
    }
</table>

What if we could drop the braces?

<table>
    @foreach (var item in list)
        <tr>
            <td>item.Name</td>
            <td>item.Description</td>
        </tr>
</table>

@GeirGrusom, do you have an example in mind of the benefit to Razor of C# not caring about whitespace?

Razor can just convert everything between @( and ), @{ and } without caring about white space at all. The expressions inside, is verbatim valid C#. With a white space aware language it's not that simple any more.

I would also like to mention that mixing tabs and spaces, or getting the number of spaces wrong, either by copy-paste or poor merge conflict resolution, can introduce bugs in the code if C# cares about white space. And the benefit is non-existent in my opinion.

Python, OCaml and F# all care about white space, and I would say in F# it's an annoyance, and it's one of the least noticeable features of Python. So why bother implementing it in C#?

Also imagine if C cared about white space. We would never have had The International Obfuscated C Code Contest!

If you're obsessed with whitespace-clean HTML out of Razor your code is going to look awful regardless. Even in that "lightweight" example your table will be double-indented, and because you forced the indentation to mean something you can't even manually avoid that by reducing the indentation of the tags (something you _can_ do with braces).

Thankfully, HTML scope is not white-space sensitive. And neither should C#.

@HaloFour :+1:

Hey @breyed!

While I like a lot of the language constructions in F#, I still prefer the C#. I agree with you that could be a lightweight syntax mode, but we have to remind that C# inherits a lot from C, C++, Java and others and I don't think that it should change.

By the way, I'm not from a country of English language, so I am writing in poor English here! ;)

I still prefer the brackets in C#. It reminds me of that all things are in one scope, well defined by the brackets. I think that we could have other changes in the language and maybe a mode that force formatting and naming conventions as well, but not trying to transform the C# in F#. If you want F#, use F#.

There are so many cool ideas in languages like TypeScript, Scala, Kotlin, Ruby, Python and even few in Java too ( XD ), but indentation or brackets formatting are not one of then.

Also imagine if C cared about white space. We would never have had The International Obfuscated C Code Contest!

Or Code Golf.

Forget C, what about Whitespace itself?

I prefer moving the language forward such that braces become used less often, by introduction more functional constructs in the language.

This question of whether to avoid the repetition of braces isn't a question of parsing difficulty; it's about productivity and readability. Just as Razor can, as @GeirGrusom said, convert everything between @(/) and @{/} in C# verbose syntax without caring about whitespace (except in quotes and the newline following //), using a C# lightweight syntax, Razor can just as easy convert everything between @[^\(\{] and the next unindented line without caring about ) and }.

Razor will go on happily with either syntax, but if my C# code and the generated HTML output has less ceremony and more useful content per page, even if I'm not obsessed with whitespace-clean HTML (sorry @HaloFour), it's still an improvement. I'll happily take what I can get, and lightweight syntax seems to me like a small but valuable win. Just as lambdas and C# 6 auto-property initializers were nonessential but useful features to cause braces to be used less often (to @kasajian's point), a lightweight syntax would do likewise.

I believe C# shouldn't fall into the trap of "If you like a feature from language _x_, use language _x_." It has been successfully by borrowing from and iterating on features from other languages. We see the result today in features like type inference and LINQ.

I believe C# shouldn't fall into the trap of "If you like a feature from language x, use language x." It has been successfully by borrowing from and iterating on features from other languages. We see the result today in features like type inference and LINQ.

_Features_ yes, grammar no. You're not proposing any new features. All you're proposing is that C# become Python, or F#, or some other language simply because _you prefer_ that grammar. It provides NO benefit to the language or the developers. It doesn't make programming in C# any less verbose. All it will possibly do is make the C# language REALLY confusing because it is two languages smashed into one.

The goal of those other language changes isn't to eliminate braces. It is to make the language more consistent with itself by providing the same shorthand used elsewhere to define similar structures. And in every single one of those cases it remains whitespace insensitive.

The CLR was largely created specifically so that multiple languages could target it and retain their own features. You already have a bunch of whitespace sensitive CLR languages to choose from. They work just fine alongside C#.

A grammar contraction _is_ a feature. Auto-property initializers are an example of such a feature; it removes verbosity. An indent-based structure is similar in eliminating braces and lines of code at no cost to expressiveness. It differs in that it is alternative (not additional) syntax. That doesn't make it confusing, however. It's just a choice. F# offers this kind of choice and hasn't experienced problems. Of course, F# didn't have as long of a history before offering the second syntax. However, IDE auto-conversion for C# lightweight/verbose syntax election would smooth over old and new code quite nicely.

It's not a contraction. You can't possibly eliminate more than a single
printable character. It's an additional syntax for the sake of being an
additional syntax. It is useless, extraneous and would lead to only
confusion and error.
On May 31, 2015 8:41 AM, "Edward Brey" [email protected] wrote:

A grammar contraction _is_ a feature. Auto-property initializers are an
example of such a feature; it removes verbosity. An indent-based structure
is similar in eliminating braces and lines of code at no cost to
expressiveness. It differs in that it is alternative (not additional)
syntax. That doesn't make it confusing, however. It's just a choice. F#
offers this kind of choice and hasn't experienced problems. Of course, F#
didn't have as long of a history before offering the second syntax.
However, IDE auto-conversion for C# lightweight/verbose syntax election
would smooth over old and new code quite nicely.

—
Reply to this email directly or view it on GitHub
https://github.com/dotnet/roslyn/issues/2974#issuecomment-107172997.

@breyed You are conveniently ignoring my explanation that even if you ignore the difficulty of updating the specification, parser, and IDE functionality to handle the "lightweight" syntax, it is a net reduction in ergonomic efficiency compared to the current language. If Visual Studio did not provide auto-formatting capabilities of the form required for my claims to hold, then my statements would be theoretical. But this is not the case, which means from design to implementation to actual use, the only portion of your proposal which qualifies as lightweight is it occupies fewer lines of vertical screen real estate.

But C# is already moving in the direction of reducing that requirement:

  • Getter-only auto-properties
  • Expression-bodied members

@sharwell You are conflating Visual Studio (the IDE product) with C# (the programming language). I see that a lot, and it bothers me. We should consider them separate, especially now that C# is being made more portable.

@gafter I don't think _any_ language should be considered separately from the IDEs available for it in 2015. No one is writing C# in Notepad, so why should language design behave as if that is the case?

I would point out that while C# isn't being written in Notepad, it's increasingly being written in Atom, VS Code, Vim, and may others, especially thanks to the efforts of the OmniSharp team. VS may still be the premier editor for C#, but it's no longer the only by far.

@RichiCoder1 Totally true. However- any IDE worth anything should be providing some degree of auto-formatting of code.

I'd also point out that until and unless there is data that a large number of users are writing in other tools, VS should remain the overwhelming experience to consider when doing C# language design. It's nice that the language is now open-source, but that shouldn't mean that the needs of the many (the tens of thousands devs writing C# in VS) should be dictated by the small minority using other tools.

@gafter Yes and no. The specific functionality of Visual Studio required to support my argument is implemented in Roslyn components which are not strictly tied to Visual Studio. While I don't know of another editor implementing them in precisely the same way, the barrier to do so is not nearly as high as it once was.

I would say, as I understand it: C# is developed and compiled with Roysln, which comes with facilities to format code. Therefore any argument about various IDE is moot and off point. Since the compiler service itself supports code formatting, the existence of code formatting utilities is always available. Therefore code formatting should not be considered part of the equation for evaluating if C# is DRY enough.

Personally, I prefer my language a little moist :smirk: .

I agree, enough code editors with even basic support for C# have brace completion and auto-formatting.

But besides that, I think that altering the syntax in such a way doesn't make sense. It's in effect rewriting the language spec, and for no benefit other than to make it _feel_ like another language.

You're also stuck with two bad choices:

  1. Make this a compiler option, in which case the compiler becomes basically a compiler for two languages. The meaning of existing code can potentially change.
  2. Add some new syntax to permit this within the existing syntax. This is problematic because if the developer forgets to use the alternate syntax (e.g. appending ":") they are likely to make the assumption that the following indentation has meaning, which it won't. That will be a pit of failure.

I do feel a bit like this issue is like asking that English speakers stop conjugating "be". Doing so is technically wasteful of mental facilities, but not doing is makes communication significantly more difficult as people are forced to adapt; and there's a huge existing library of content using the old style.

@whoisj If you want to stop conjugating verbs you learn an Eastern language like Chinese, Japanese, Thai, Vietnamese, etc. You don't change English. :grinning:

From http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

In software engineering, don’t repeat yourself (DRY) is a principle of software development, aimed at reducing repetition of information of all kinds, especially useful in multi-tier architectures. The DRY principle is stated as “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” The principle has been formulated by Andy Hunt and Dave Thomas in their book _The Pragmatic Programmer_. They apply it quite broadly to include “database schemas, test plans, the build system, even documentation.” When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync. Besides using methods and subroutines in their code, Thomas and Hunt rely on code generators, automatic build systems, and scripting languages to observe the DRY principle across layers.

VS provides tools to C# programmers that are triggered by default at the end of every block when you type } to automate the association between the syntax and the indentation, thus satisfying this principle.

@gafter The cost of repetition depends on its form. From most to least expensive:

  1. Copy and pasted code that you have to manually change in many places when you change any one place
  2. Generated code where you manually initiate regeneration
  3. Generated code where regeneration is automatic, and the generated code gets checked in
  4. Generated code where regeneration is automatic, and the generated code doesn’t get checked in
  5. No generated code at all; the need for repetition is designed out of the system

C# auto-intending provides form 2 or 3, depending on your IDE. By way of comparison, Entity Framework Model First uses form 3 and Code First uses form 5. Granted, braces are much lighter than generating entire classes. However, it's nice to eliminate the experience of 4 or 5 cascading braces at the bottom of a C# file that you know has correct indentation but doesn’t yet have the braces right, and you play guess and check adding or removing braces until the compiler or IDE tell you the brace syntax is valid, i.e. you’ve succeeded at repeating your indentation logic.

The largest cost of using braces and semicolons to repeat indentation structure is the vertical whitespace. This cost is significant, which is why, as @sharwell commented, C# is working to reduce unnecessary vertical whitespace with getter-only auto-properties and expression-bodied members. If those features eliminate 10% of non-value add brace lines, why not go for the other 90%?Additionally, there is benefit to not fuddling with braces when the IDE doesn’t happen to do quite what you want. Coding isn’t a linear exercise.

Per @HaloFour’s comment, you can move the indicator of whether indent is significant from the project level to the block level by requiring a colon before blocks with significant indentation. This would let you integrate the two syntax styles in the same project and even file. An IDE could aggressively auto-format to mitigate the risk of confusion. However, I don’t see the value in mixing the two syntaxes. Because they map directly from one to another, an IDE can auto-convert an entire codebase when the project syntax mode changes. Similarly, it can auto-convert pasted code, which makes it easy to use old code samples from the web.

And if the person forgets the colon they will inadvertently screw up scope
with no indication of doing so. Pit of failure.

My comment is to further indicate why this is a horrifically terrible
idea. Thankfully every member of the compiler team to have commented thus
far agrees.
On Jun 7, 2015 8:58 AM, "Edward Brey" [email protected] wrote:

The largest cost of using braces and semicolons to repeat indentation
structure is the vertical whitespace. This cost is significant, which is
why, as @sharwell https://github.com/sharwell commented, C# is working
to reduce unnecessary vertical whitespace with getter-only auto-properties
and expression-bodied members. If those features eliminate 10% of non-value
add brace lines, why not go for the other 90%?Additionally, there is
benefit to not fuddling with braces when the IDE doesn’t happen to do quite
what you want. Coding isn’t a linear exercise.

Per @HaloFour https://github.com/HaloFour’s comment, you can move the
indicator of whether indent is significant from the project level to the
block level by requiring a colon before blocks with significant
indentation. This would let you integrate the two syntax styles in the same
project and even file. An IDE could aggressively auto-format to mitigate
the risk of confusion. However, I don’t see the value in mixing the two
syntaxes. Because they map directly from one to another, an IDE can
auto-convert an entire codebase when the project syntax mode changes.
Similarly, it can auto-convert pasted code, which makes it easy to use old
code samples from the web.

—
Reply to this email directly or view it on GitHub
https://github.com/dotnet/roslyn/issues/2974#issuecomment-109749215.

@HaloFour, I would suggest you check the comment history more carefully. Despite the fervor with which you have repeated (ironic, given the topic) your favored approach to this issue, the two compiler team members have wisely expressed neither agreement nor disagreement with it. Language feature selection and definition is successful after careful contemplation of the many facets of the issues and its design tradeoff. As you reread, you will also discover that your repeated concern about missed colons causing inadvertent scope are addressed by (a) not introducing colons and (b) even if you did, having IDEs autoformat so that the scope is clear. And if that’s not enough, I’d add a (c) that the compiler could issue a warning if the indentation is fishy – but really, you could just stop at (a).

@breyed Repetition is a form of emphasis.

If you can read the comments of the three collaborators who have been willing to post to this thread and find a positive (or even neutral) takeaway then I have to applaud your optimism.

You could also stop at (a) by using one of the several existing languages targeting the CLR which have whitespace-sensitive scoping, some of which having actually been written by Microsoft. (b) makes the entire discussion moot, the IDEs are already performing the indentation, YOU don't have to repeat anything. The fact that the language might, based on some optional conventions, is entirely irrelevant, when the tooling provides built-in mechanisms for avoiding this.

I read most of this thread and accept the premise that C# isn't DRY with regard to the assertion of the original poster. The severity of the issue isn't significant enough to have it be corrected by any of the existing proposals. It will just add yet another concept that one has to learn to understand the language.

The only acceptable way I think thus can be addressed in the future is some ingenuous way of introducing metaprogramming such that this and many other constructs can be adopted. That may never happen.

Kenneth Kasajian -- Mobile call or text: 949-288-3717, Skype: kkasajian

On Jun 7, 2015, at 6:42 AM, HaloFour [email protected] wrote:

And if the person forgets the colon they will inadvertently screw up scope
with no indication of doing so. Pit of failure.

My comment is to further indicate why this is a horrifically terrible
idea. Thankfully every member of the compiler team to have commented thus
far agrees.
On Jun 7, 2015 8:58 AM, "Edward Brey" [email protected] wrote:

The largest cost of using braces and semicolons to repeat indentation
structure is the vertical whitespace. This cost is significant, which is
why, as @sharwell https://github.com/sharwell commented, C# is working
to reduce unnecessary vertical whitespace with getter-only auto-properties
and expression-bodied members. If those features eliminate 10% of non-value
add brace lines, why not go for the other 90%?Additionally, there is
benefit to not fuddling with braces when the IDE doesn’t happen to do quite
what you want. Coding isn’t a linear exercise.

Per @HaloFour https://github.com/HaloFour’s comment, you can move the
indicator of whether indent is significant from the project level to the
block level by requiring a colon before blocks with significant
indentation. This would let you integrate the two syntax styles in the same
project and even file. An IDE could aggressively auto-format to mitigate
the risk of confusion. However, I don’t see the value in mixing the two
syntaxes. Because they map directly from one to another, an IDE can
auto-convert an entire codebase when the project syntax mode changes.
Similarly, it can auto-convert pasted code, which makes it easy to use old
code samples from the web.

—
Reply to this email directly or view it on GitHub
https://github.com/dotnet/roslyn/issues/2974#issuecomment-109749215.

—
Reply to this email directly or view it on GitHub.

One thing that I'd like to see is a lot more experimental forks of the language so people can actually see and play with these changes rather than just discussing it in the abstract.

Howe can we get more people to feel comfortable with and attempt to actually implement / prototype the language features they want? That'd be cool.

Significant whitespace for blocks is pretty much always wrong. Since text is the fundamental medium used to transmit the data to the tooling making tools depend so much on position in this way isn't a good idea. What happens if you have to past code into an email form for a mailing list or are reading an article and your browser doesn't pickup on the spacing used by an author? I have had this happen when trying to learn Haskell, seriously it isn't fun.

That we use fancy editors to write code is not in fact a justification for creating grammars that require specialized tools just to use without pulling your hair out. It isn't even good UX when you start thinking about what happens if someone uses large fonts and can't even see indentation levels.

@metatron-the-chronicler

It isn't even good UX when you start thinking about what happens if someone uses large fonts and can't even see indentation levels.

I know more than a couple of developers who also prefer using non-monospaced fonts. One insisted that anyone not using Tahoma as their font in Visual Studio was barbaric.

Proportional fonts are generally great for coding. You get more horizontal real estate and centuries of typography benefits. I personally prefer Calibri. A trade-off of using a proportional font is you can only align text based on indents, although with refactoring even with non-proportional fonts suffer if you rely on in-line alignment. Regardless of the font, space sizes are proportional to non-space sizes, so large fonts shouldn't pose a problem.

I'm actually thinking more of zooming rather than simply choosing a physically large font.

Just came across this discussion. I have to say that if an alternate syntax were added to C# I would have to abandon it wholesale. What a bad, bad idea.

I also find the idea that indentation/braces/whitespace falls under DRY to be just absurd.

Closing as this is not actionable... but you're welcome to continue commenting here

@breyed why not just pick up F#? It's quite easy to learn.

C# indentation and use of curly braces should not change, even if you could switch it on or off; it's not a good idea.

@panesofglass If I hadn't already learned languages like F# and Python, the repetition in curly braces languages may not have occurred to me. F# in particular is an excellent language; however, C# makes more business sense sometimes because of better tooling, framework integration, and developer familiarity. The advantages of C# were what prompted me to raise this issue to explore whether braces are inherent to the language or whether a indent scoping could make it even better.

In my opinion the indentation requirement in F# and Python are weak points rather than strengths.

Keep braces and semicolons. Close this discussion.

Already closed as not actionable in https://github.com/dotnet/roslyn/issues/2974#issuecomment-122975023 ... but anyone who wants to is welcome to discuss it. I'm unsubscribing now.

ruby

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MgSam picture MgSam  Â·  152Comments

mgravell picture mgravell  Â·  119Comments

MadsTorgersen picture MadsTorgersen  Â·  120Comments

Pilchie picture Pilchie  Â·  113Comments

mattwar picture mattwar  Â·  190Comments