dotnet / csharplang

The official repo for the design of the C# programming language
11.38k stars 1.02k forks source link

Proposal: File scoped namespaces #137

Open bomzj opened 7 years ago

bomzj commented 7 years ago

Spec: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/file-scoped-namespaces.md

How it looks now:

using System;

namespace Company.Project
{
    public class Product
    {        
        ...
    }
}

Why do we need to nest our class definition in namespace ? Why not to remove extra nesting ? Isn't that better ?

namespace Company.Project
using System;

public class Product
{ 
    ...
}

LDM history:

CyrusNajmabadi commented 6 years ago

I have never written switch blocks with cases that line up with the switch

That's because it's the default for VS. But it's an option that's there because it's something that was repeatedly asked for. That's why we've kept it. We even added more functionality here based on customer feedback to allow even finer control over indentation both of the cases, and of the cases contents themselves (including how they should behave whether or not either are blocks or not).

I personally don't write K&R style braces. But customers do. So we have support for it. I wouldn't have non-indented namespaces. But if enough people want that, i'm sure we can add an option to make that possible.

and I don't recall seeing code that does that.

BSD does it, as does linux. We have it because many c-style customers are used to it, and want it when they work in C#. For the same reasons that others here want to be able to write namespaces, but not have the contents indented.

Surely that is an odd convention.

Surely not indenting namespaces would be an 'odd convention' given the existing millions of lines of C# code out there that all indents namespaces. And yet, here we are, talking about a way to provide precisely that. :)

mikedn commented 6 years ago

I have never written switch blocks with cases that line up with the switch, and I don't recall seeing code that does that. Surely that is an odd convention. At best it is an exception to the rule rather than the rule.

I've seen and used this convention. Switch cases are pretty much like labels and labels do not need indenting because the code that follows is indented. This is the way things work for as long as I can remember in other "low level" languages that make use of labels (C, C++, assembly).

And speaking of C++ - this is exactly what some people do in C++ with namespaces, they do not intend the contents of the namespace block. In fact, I think this is the default in VC++. I see that it doesn't intend and I don't remember ever changing that VC++ formatting option.

Surely that is an odd convention.

There's nothing odd about not blindly doing things that do not need to be done. Quite the opposite.

aWeinzierl commented 6 years ago

I really like the idea of file scoped namespaces.

My favourite option is to only allow the following:

namespace Company.Project
using System;

public class Product
{ 
    ...
}
namespace Company;
using System;
using System.Collections;
namespace Project
{
    public class Product { }
}

which means the option for a declaration of the namespace for the whole file in the early beginning of the file - still supporting the old standards completely. Namespace scopes would just nest within the file scope.

This would not only minimize the effort, but also have the maximum of the effect which is desired:

I do not see a point in removing the indentation after a namespace scope. Like already meantioned, this breaks coding standards, and also does not appeal to me optically.

I also think the possible effort for implementing this feature would be fairly limited.

I must admit that I have not been very amazed by the namespace scopes since I have started programming in C#.

CyrusNajmabadi commented 6 years ago

I also think the possible effort for implementing this feature would be fairly limited.

To be clear: The cost of making a language feature over an IDE PR is roughly 3-4 orders of magnitude minimum. A language change has to go through the entire LDM process. It needs to be championed, completely spec'ed out (which means analyzing everything to ensure it is properly accounted for), implemented, tested, doc'ed. At that point you also have to update every IDE feature in all owned IDEs to understand this and do things properly. Then, this feature would also have to compete with all the other features trying to make it into the language (which actually bring functional, and not just stylistic improvements to things). This means that there is an indeterminate point that it will actually make it into the language. in other words, it could be years or more.

An IDE PR, on the the other hand, could be created in an hour, tested, and reviewed, and committed into the product in 24-48 hours (depending on how busy the team is). It would then be in the next release of VS.

In terms of effort, these are barely comparable. One is hugely expensive. One is about as cheap as it gets. :)

CyrusNajmabadi commented 6 years ago

maximum simplicity, since if there is such an namespace declaration it is in the beginning of the file

Just to check, but "usings/externs/etc." would still be allowed above just a single-line-namespace-decl right?

CyrusNajmabadi commented 6 years ago

I do not see a point in removing the indentation after a namespace scope

The point is that you take a proposal, which may not ever happen, and which is expensive, and you turn it into a workable feature that can be shipped in a release quickly. It's similar to the discussion about regex-literals here: https://github.com/dotnet/csharplang/issues/371

Trying to get regex literals into the language will be hugely costly and will likely never happen (IMO). However, adding IDE support to make the regex experience better us much less costly and can be done with the involvement of far less people: https://github.com/dotnet/roslyn/pull/23984

Like already meantioned, this breaks coding standards,

The c# team gets to decide the coding standards around C# :) I've already been involved in this sort of thing in the past. For example, we already allow a lot of flexibility around indentation in switch-blocks. For example, if you want 'cases' indented. Or if you want code in teh cases indented. Or how you want to handle 'blocks' inside cases. Etc. Indeed, I wrote up that formatting option precisely because there was a desire by some to change how code was indented in switches, even though that wasn't part of any 'coding standard' we'd opted for in the past.

and also does not appeal to me optically.

Sure. But you have to ask yourself: is it better to be appealing optically, but never happen... or make it less appealing optically, but solve the actual problems you're complaining about (i.e. "It would let fit more code onto the screen and significantly improve side by side views (saves twice)"), right now.

Basically, are you letting perfect be the enemy of the good.

--

It's also worth noting that the formatting option in no way precludes changing the language in the future. But it means that instead of waiting 3+ years on something like this, you could instead have the feature in a few weeks as part of a normal VS update. The language could still add that syntactic feature in the future. But in the present, you'd actually solve all the cases you said you cared about :)

aWeinzierl commented 6 years ago

Just to check, but "usings/externs/etc." would still be allowed above just a single-line-namespace-decl right?

In my point of view I see no benefit at all of allowing using statements above the declaration, for several reasons:

The point is that you take a proposal, which may not ever happen

Thus, I show interest in that feature

is it better to be appealing optically, but never happen... or make it less appealing optically, but solve the actual problems you're complaining about

Imho problems should be solved in a proper manner. Workarounds are not a solution, especially if they break conventions which even may be enforced.

I do not avoid interfaces or use goto statements, just because it is a lot easier at certain moments. I use interfaces and avoid gotos because it is better in the long term. I think C# would do better with that feature than without, so I hope it is going to be implemented. I know it will take some effort, but so did every feature till now.

In my point of view, it is not comparable to the regex issue: Only a minority of the users would profit from that (I did not read the entire issue). However, everybody would have a benefit from this feature, which could (they need not use it) affect their whole programming experience with C#.

The language could still add that syntactic feature in the future.

True, but I am not what this proposal is about: It indeed is about the future of the language and of the users of it.

CyrusNajmabadi commented 6 years ago

In my point of view I see no benefit at all of allowing using statements above the declaration, for several reasons:

This will certainly kill such a proposal. A huge swath of code is written today with using-above-namespace. Forcing people to change to using-below-namespace will mean changing the semantics of their code.

there is no benefit of allowing it below, since there is only one such statement possible anyway

There's a very big benefit: preserving semantics of existing code. If you move your usings into the namespace, they take on a new meaning and affect lookup of symbol names.

CyrusNajmabadi commented 6 years ago

However, everybody would have a benefit from this feature, which could (they need not use it) affect their whole programming experience with C#.

The same could be said of the IDE feature. Again, you've mentioned the reasons you want this feature. Namely:

it would enable the removal of the additional unnecessary indentation layer. It would let fit more code onto the screen and significantly improve side by side views (saves twice) or any scenarios where one has multiple code files next to each other. Finally, it would enable a better comprehension of the indentation layers, especially while scoping within functions.

None of this needs a language change. These are all complaints about indentation. Which is a function of tooling and convention. Both of which can be changed far more easily than actually changing the language.

aWeinzierl commented 6 years ago

You misunderstood me: IF one is going to use the file scoped namespace declaration, he would have to place it above the code.

He still could leave everything as is and not use the feature.

Maybe there are legal reasons to allow such a declaration below using statement, but none has come to my mind yet.

CyrusNajmabadi commented 6 years ago

In my point of view, it is not comparable to the regex issue:

It's comparable in the sense of how much work is involved. In both of these cases, there are requests to change the language to make the tooling experience better. But, in both cases, it's possible (and soooo much cheaper) to just make the tooling experience better without needing to change the language.

--

Another way to think about this. In the amount of time people have spent debating this, that same effort could have already gone into just solving the indentation problem in the tools and you could have hte benefits you asked for earlier :)

We're going on almost a year now since this was opened. How many years do people want to wait for better indentation? Such an improvement could have shipped back in march last year had anyone just submitted the IDE pr. But if you want on this going through the language, how many more years will you have to wait?

CyrusNajmabadi commented 6 years ago

You misunderstood me: IF one is going to use the file scoped namespace declaration, he would have to place it above the code.

I understood you. I'm telling you that that approach is almost certainly not going to fly as you'd be making a namespace proposal that could not handle one of the most common and important namespace cases that are handled today with existing namespace declarations.

Maybe there are legal reasons to allow such a declaration below using statement, but none has come to my mind yet.

I listed the reason above. It affects name lookup. Look at teh roslyn codebase itself. 99% of usings are above the namespace declaration. This has been the pattern found in the majority of C# codebases out there. Some people place usings inside the namespace (and there are good reasons to do so some of the time). But the default pattern (since literally C# 1.0) was for code to have usings above the namespace.

CyrusNajmabadi commented 6 years ago

probably easier to implement

IMO, it would be harder to implement this way. For one thing, the IDE would almost certainly have to provide a feature to allow people to specify which style they preferred (and to convert code between the styles). If you required the namespace decl as teh first line, we'd have to figure out how to fix up code that currently has usings above the existing namespace declaration. This would means a whole ton of extra analysis (and potential bugs) figuring out if moving the usings to inside the namespace now had changed any semantics of your code at all. This is very tricky to do, and could easily cause something to be missed.

For example, in Roslyn itself someone moved a using one time and it made it so one extension method was called over another. This extension method was much less efficient (an IEnumerable extension vs an ImmutableArray extension), and caused a perf issue. Note that nothing broke (the source still compiled, and all behavior was hte same). It was just that things became less efficient at runtime because of boxing/allocations/algorithmic complexity.

Writing all the code to prevent that from happening is non trivial, but necessary if we wanted to have the tooling to work with these styles (which people would certainly expect).

aWeinzierl commented 6 years ago

Okay, that makes sense. I have not been conscious about that. Thanks for the objection.

CyrusNajmabadi commented 6 years ago

Any time! Note: i at least think allowing "namespace X.Y.Z;" as a shorthand for "namespace X.Y.Z { }" (with all following statements assumed to be nested in the namespace) would be the most feasible language change to make. I still think it's unlikely to happen for many years. But it at least slots in the most sanely with how the language is defined today.

The important bit here is, from the syntactic model perspective, nesting would be maintained. (As opposed to a model where the new namespace was just a sibling of the usings/members at the same level as it in the file.)

From an impl perspective, we would be cute and do something like the following:

Take the existing namespace declaration syntax, which is:

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?

namespace_body
    : '{' extern_alias_directive* using_directive* namespace_member_declaration* '}'

And change this into:

namespace_declaration
    : 'namespace' qualified_identifier namespace_body 

namespace_body
    : '{' extern_alias_directive* using_directive* namespace_member_declaration* '}' ';'?
    : ';' extern_alias_directive* using_directive* namespace_member_declaration*

Then, in the impl, we'd take NamespaceDeclarationSyntax and break it into the following:

BaseNamespaceDeclarationSyntax
    Name: NameSyntax
    Externs: SyntaxList<ExternAliasDirectiveSyntax>
    Usings: SyntaxList<UsingDirectiveSyntax>
    Members: SyntaxList<MemberDeclarationSyntax>

NamespaceDeclarationSyntax : BaseNamespaceDeclarationSyntax
     OpenBraceToken: SyntaxToken
     CloseBraceToken: SyntaxToken
     SemicolonToken: SyntaxToken (opt)

SingleLineNamespaceDeclarationSyntax: BaseNamespaceDeclarationSyntax
    SemicolonToken: SyntaxToken

So, if you wrote:

namespace A.B.C;
using X;
class C { }

Then the using+class would actually be children of the SingleLineNamespaceDeclaration.

Then, we'd basically just have to go through the entire codebase and change usages of NamespaceDeclarationSyntax to BaseNamespaceDeclarationSyntax. Then, we'd only have to change a few features to have to know about the new SingleLineNamespaceDeclaration kind. Specifically, of the top of my head, we'd just need to update:

  1. indentation.
  2. formatting.
  3. completion (it looks syntactically at what's around it to decide what to offer).
  4. core add-using helpers (as these would need to know how to specifically update the syntax for either of these constructs).

Because we'd be producing the same hierarchical tree format, pretty much everything would work without much effort (as long as we ensured switching away from NamespaceDeclarationSyntax to BaseNamespaceDeclarationSyntax everywhere). As this could be done basically with just a Find/Replace, i think this would be much easier and cheaper than other approaches.

jnm2 commented 6 years ago

I still think it's unlikely to happen for many years.

If it takes many years to spec and implement namespace X;, I shudder to think how long it'll take to get more pattern matching features, default interface methods, or shapes. 😜

CyrusNajmabadi commented 6 years ago

I know you're being tongue-in-cheek, but i wanted to address this:

These types of feature are not comparable. A feature like single-line-namespaces would very likely get pushed out as it just addresses an indentation request from customers. That won't be felt to be as valuable as things like "pattern matching" and whatnot which genuinely enable entirely different ways of tackling coding problems.

The LDM will take on some ergonomic issues, but they're def less of a concern than larger and more impactful constructs that have very deep impact on how people code, how libraries are constructed, etc.

jnm2 commented 6 years ago

I know, just don't go overboard with the "4 orders of magnitude more work, therefore years and years" thing. It's really about priorities. xD

alrz commented 6 years ago

Then, in the impl, we'd take NamespaceDeclarationSyntax and break it into the following

could be an optional node of the CompilationUnitSyntax, so just an additive change.

NamespaceDirectiveSyntax
    NamespaceKeyword: SyntaxToken
    Name: NameSyntax
    SemicolonToken: SyntaxToken

CompilationUnitSyntax
    NamespaceDirective: NamespaceDirectiveSyntax
    Externs
    Usings
    AttributeLists
    Members
    EndOfFileToken
CyrusNajmabadi commented 6 years ago

could be an optional node of the CompilationUnitSyntax, so just an additive change.

My point is that that sort of approach would then make the impl much more complex. All code today that deals with namespaces would then have to know about this directive. Instead of an impl approach where we could be much more mechanical (i.e. just convert all usages of NamespaceDeclarationSnytax to BaseNamespaceDeclarationSyntax).

MgSam commented 6 years ago

Glade to see this was finally discussed in a LDM. Think of the billions of spaces/tabs you guys will save when you finally implement this!

AustinBryan commented 6 years ago

@MgSam That's awesome! I've tended to prefer not using namespaces because of the indention it causes (and in Unity it can't find the code if you do use a namespace)

sirgru commented 6 years ago

AustinBryan namespaces in Unity work just fine, they have for a while. However, you know how when you add the namespace the whole file is marked as changed in source control because of the added indentation? Well, yeah. With this proposal that would be solved. The indentation is completely superfluous, as long as we ensure it goes before any class definition and after usings.

CyrusNajmabadi commented 4 years ago

@MadsTorgersen I'd like to champion this.

ufcpp commented 4 years ago

Having tried the source generator, I wanted this feature.

https://github.com/ufcpp/StringLiteralGenerator/issues/1

Branches for {} and indentation are too noisy.

ssg commented 4 years ago

I believe the overwhelmingly positive reception of top-level "Main" code to C# 9.0 supports the relation between unnecessary indentation and developer pain. Namespace blocks are useful but noisy.

I had written a bit about why file-scoped namespaces are important here: https://medium.com/@ssg/a-pledge-for-namespace-directives-in-c-15a322504a15

Let me reiterate my main point here:

Namespace blocks are almost never used more than once in a file, and almost never nested. StyleCop already suggests one type per file, let alone multiple namespaces. The indentation that the namespace block adds provides no useful information to a regular developer. It just occupies space. It's a harmful default.

Is an extra indent bad? It may not be so as it forces you to have shorter code lines. Extra indent can make your code even more readable thanks to that. That's why Linux kernel insists on 8-space indents because they want less nesting and therefore less complexity in the code.

So, the problem of extra space isn't screen real-estate, it's developer psychology and semantics. It's the assuring warmth of the left margin versus the cold uncertainity of floating in space. The leftmost margin has great readability because the scope is unambiguous, you are at the top level of the file. It's assuring. You can't make a mistake if you are at the top level. One or two indents in, you can still maintain your semantic location mentally. But after the third indent you begin floating in space. You can be in a function, a loop, an else statement, or anything. That's where readability starts to fade. You need to maintain the distance between the left margin and the first chracter on the line in your mind while reading code and every indent it gets harder. Even if your IDE marks every indent separately, would you count them every time? No.

The extra indent in the scope of a class is useful. It conveys information. A namespace block doesn't. It's a useless default. Yes, it was there to support the breakthrough of multiple types per file in early C# days but we quickly learned that although multiple types per file can be nice occasionally, it shouldn't be the default. Multiple namespaces per file introduces even more complexity unnecessarily.

My case for file-scoped namespaces is: simpler defaults, less typing, less mental burden of trying to figure out your mental coordinates in the code. It's quite similar to @MadsTorgersen's rationale for top-level code support in C# 9.0.

Simpler defaults and less typing will attract more beginners and will expand the ecosystem. Less mental burden will make reading C# code more enjoyable.

CyrusNajmabadi commented 4 years ago

@ssg See https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-07-13.md#file-scoped-namespaces

CyrusNajmabadi commented 4 years ago

We have triaged this into C# 10.

CyrusNajmabadi commented 4 years ago

You can't make a mistake if you are at the top level. One or two indents in, you can still maintain your semantic location mentally. But after the third indent you begin floating in space. You can be in a function, a loop, an else statement, or anything.

I find that argument entirely uncompelling. First, removing the namespace indent doesn't help with these cases, as your floating code will still be floating. Second, all of the above effectively signifies that your code is so far removed from teh 'header' (be that the statement, method, etc.) level that it can't be made out as to how is is structured. This means the code is far too complex and needs to be seriously adjusted to be maintainable. Simply removing the first 4 spaces isnt' going to help there as your deeply nested code remains deeply nested.

ssg commented 4 years ago

@CyrusNajmabadi does traging mean it's approved for C# 10, or does it mean it will be re-evaluated in C# 10 timeframe?

333fred commented 4 years ago

CyrusNajmabadi does traging mean it's approved for C# 10, or does it mean it will be re-evaluated in C# 10 timeframe?

We'll be looking at exactly what we want to do in the C# 10 timeframe. I can't say that it's definitely guaranteed for any particular release, but the intention is that we'd like to do something here. There's near-universal support in the LDM for something.

ssg commented 4 years ago

I find that argument entirely uncompelling. First, removing the namespace indent doesn't help with these cases, as your floating code will still be floating.

The closer you get to the left margin the better assurance you have about your mental scope. Every less indent would help, especially a completely unnecessary one. I think the easiest to read code is a top-level code. Every indent adds a layer of ambiguity.

Second, all of the above effectively signifies that your code is so far removed from teh 'header' (be that the statement, method, etc.) level that it can't be made out as to how is is structured.

That's true but large, aka taller than the screen, functions are common in the wild, even the .NET code itself. If they are that unavoidable despite the drawbacks associated with them, we are stuck with them, regardless how knowledgeable we are about the problems they bring. They are part of our reality.

Also, you can browse the code (by navigating through IDE or by scrolling pageup/pagedown or by step by step debugging) and end up with partial visibility of the function you have due to the scroll position where you don't see the rest of the code even if it's a small function.

I'm not sure if there is enough literature to associate developer psychology on style issues like this and its impact on productivity. I've found Psychology of Programming goes over productivity issues related to indentation but I haven't read it yet. Perhaps, I can come back with some concrete academic research :)

CyrusNajmabadi commented 4 years ago

Every less indent would help,

I disagree. At the levels you're talking about, reducing one indent would still be firmly unclear. One less indent helps on hte left side. But those aren't the entities that are hard to reason about.

That's true but large, aka taller than the screen, functions are common in the wild

These function will not be helped by this proposal. They will still be taller than the screen, and if htey are deeply nested, then N-1 levels of deep nesting will be effectively as bad as N.

ssg commented 4 years ago

@CyrusNajmabadi I understand that what I say doesn't mean much without supporting data. Let me expand the scope of my argument a little bit:

Implicitly scoped using statements added with C# 8.0 saves you exactly one indent/block per each using statement. StyleCop recommends this over blocks, even if there are no nested using statements (and it's been possible to avoid extra indents for nested using blocks anyway). If one less indent doesn't make a difference, why do we have this? (As I see from the proposal, you were against that change too :))

Top-level code in C# 9.0. I know top-level code aims to reduce developer friction about blocks/classes/functions in general, not necessarily indentation or namespace blocks per se. But less indentation means less noise. Less braces mean less noise. Less blocks mean less cognitive overhead. Top-level code works partly because it eliminated namespace blocks.

So, by looking at C#'s recent changes to the language, it's apparent to me that C# is evolving towards a future with less noise and finds an indisputable value in it, especially in the light of the competition. Swift, a language that was heavily influenced by C#, has no explicit namespace declarations or no semicolons for that matter. Go, a modern competitor to C#, even eliminated additional syntactic noise like colons between variable type and names. F# already does away with file-scoped namespace statements, and it even allows nesting with that syntax in the same file. Modern languages try to reduce friction.

If it's possible to eliminate one level of noise without disrupting any backwards compatibility and annoying any developers at all, I say this is a no brainer change to C# language. Such a change doesn't cause ambiguity like removing semicolons (which I would love C# to get rid of). The semantics stay the same too.

CyrusNajmabadi commented 4 years ago

As I see from the proposal, you were against that change too

I'm not against this change. I'm the champion for it. I'm stating that your argument on why to do it is not compelling to me. I'm still pushing for this to be done in C# 10. and i got it through teh triage process in the last week to be accepted for that release :)

CyrusNajmabadi commented 4 years ago

If it's possible to eliminate one level of noise without disrupting any backwards compatibility and annoying any developers at all, I say this is a no brainer change to C# language. Such a change doesn't cause ambiguity like removing semicolons (which I would love C# to get rid of). The semantics stay the same too.

You don't need to convince me of the value of this feature. :) I very much want it.

My point was that your (earlier) justification for why we should do this feature didn't have enough merit in my eyes. So it was not part of my calculus on the decision. Note that your later arguments (which are different) do have much more alignment with my thinking :)

Pzixel commented 4 years ago

It would really help to copy-paste snippets in/out of the editor since you don't need to add/remove indentation. I can foresee a tremendous speedup due to better StackoverflowDD support

ssg commented 4 years ago

My point was that your (earlier) justification for why we should do this feature didn't have enough merit in my eyes.

I totally understand. I don't have any data to back my claims up so far, that could as well be how I feel personally. I wish it would be straightforward to measure the impact of these things. Is the triage timeline specified? Maybe I can do some research to back this up before it goes into evaluation.

CyrusNajmabadi commented 4 years ago

Is the triage timeline specified? Maybe I can do some research to back this up before it goes into evaluation.

Note really. But we discussed this week and basically there was strong support for this. So it's highly likely it will happen. It's more going to be a matter of spec'ing and implementing.

Eli-Black-Work commented 3 years ago

We have triaged this into C# 10.

Just to be clear, is the version that got triaged for C# 10 the version where one can add one using statement at the very top of the file and then it acts as though that using statement wraps the entirety of the file?

i.e.

namespace My.Namespace;

using System.Text;

public class A {

}

which is equivalent to


namespace {
  using System.Text;

  public class A {
  }
}
333fred commented 3 years ago

Just to be clear, is the version that got triaged for C# 10 the version where one can add one using statement at the very top of the file and then it acts as though that using statement wraps the entirety of the file?

Possibly. We haven't discussed the design yet, so I can't say for certain that that is the final design.

cenksener commented 3 years ago

Please don't add a lot of language features to C#. There are already so many features. This is not JavaScript. If you want to see a new framework or feature every week, you can use JavaScript. When any language has got so many keyword and features, readability is becaming low. We dont want to see unnecessary features in C# more.

wanton7 commented 3 years ago

@cenksener This is not unnecessary feature at all. This removes one level unnecessary indentation in almost every C# source file. I've been waiting this since C# 1.2.

HaloFour commented 3 years ago

One person's "unnecessary" is another person's "gotta have". It's up to the team to determine which features are worth the effort and increased complexity.

public const bool CHANGE = true;
ssg commented 3 years ago

@cenksener A better way to approach this would be to explain how this specific feature would hurt the language. For example: "having two different syntax for namespace declarations would be confusing for beginners" etc, so it can be discussed. Or, you can explain how this feature is unnecessary by refuting the arguments that has claimed its usefulness in the thread. Otherwise, we could comment "this is unnecessary, don't add please" under each new feature proposal, and it wouldn't mean much, right?

If you're concerned about the general direction of the language, I reckon that's beyond the scope of this ticket.

As a final note, none of the new C# features are essential. You can still write in C# 1.0 syntax without any trouble whatsoever if you're concerned about having to learn the new features.

cenksener commented 3 years ago

@ssg in fact i already wrote in my message "readability". But i can explain more.

*) If there are many methods/syntax to do same thing, programmers use these different methods. Also some programmers dont use new features or syntax immediately. They need time to get used to these features. And therefore Simplicity and readability in different codes will decrease.

*) C# and Java are created for productivity. Simplicity is main idea. In some cases, adding a new feature or syntax can broke simplicity.

*) Sometimes we are writing multiple C# Classes in an one file. And we are using multiple namespaces. (I am not saying that is good idea. But we are doing this sometimes.) This proposal doesnt look like effective for this scenario.

*) When i select to use a programming language, i look indentation, curly braces and other punctuation points. i like syntax of C, C#, Java, Php, JavaScript. i dont like syntax of Python, Ruby, Visual Basic etc... You can be sure that there are a lot of developer who care curly braces.

Yes, i think some features in C# are unnecessary. For example; "Using declaration" in C# 8. i am not using new syntax. i am still using classic approach with curly braces. Because it is more readabilty for me. In future somebody can say that "we should remove curly braces from classes." What will we do this time? I like C# syntax and i dont want people to destroy C# syntax.

And finally, i want to say 2 things about your final note. 1-) We can not compare some perfect features in C# with this proposal. Generics (C# 2.0), Dynamic Features (C# 4.0), Linq (C# 3.0), Anonymous types (C# 3.0) etc... We can say objective reasons to implement these features. But there is no objective reason to remove curly braces.

2-) What i use which features in my personal project is not very important.Yes, maybe i can use only C# 2.0 features in my personal project. But it is very important what i read in other projects. When i look at other projects, i dont want to see a lot of minor features. Therefore i want C# to be simple and readabilty.

HaloFour commented 3 years ago

@cenksener

This feature isn't about removing all curly braces. It's about removing them when they're not necessary. If 99.9% of C# source files contain a single type within a single namespace requiring the entire source file to be enclosed within a block and indented is pointless. This feature would be equivalent to Java package directives syntactically speaking, and that has never been considered a problem in that language. Lots of directives in the languages you listed don't require blocks. If they did we'd all need much wider monitors.

As for the rest of the comments, everyone has wildly different ideas of what features are "perfect" or "necessary" or "pointless". There were people opposed to every single "perfect" feature you enumerated. If any feature required unanimous support then C# 1.0 would have never shipped, nor would any other language. This is why the language design group exists. They weigh the reward vs effort and evolve the language accordingly, and relatively conservatively.

CyrusNajmabadi commented 3 years ago

They need time to get used to these features.

This is certainly a concern we consider. However, my gut tells me the entirety of the c# user base will have no issue getting up to speed on this. Nor will it affect users learning the language.

ahmedilyasms commented 3 years ago

@MadsTorgersen Apologies if this was mentioned earlier but what if we go one step further: Why even declare it but use what is defined in the assembly by default and if defined in the file itself, that takes precedence?

I come from a background of declaring these in files etc... and I still like that but can see many benefits of this for other dev's, including myself too.

ssg commented 3 years ago

@ahmedilyasms Because it would be a breaking change. A missing namespace declaration currently implies "root namespace", and you'd be breaking any code that relies on that behavior by doing that.