Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ":" symbol as alternate to "=" in initializers and anonymous class declaration #6963

Closed
comdiv opened this issue Nov 23, 2015 · 24 comments

Comments

@comdiv
Copy link

comdiv commented Nov 23, 2015

Due to #6673 became some case of holy war I split it to more localized issues.

In JS, JSON, Groovy we see usefull syntax to define mapping: {"key":value}
In C# we see:

  1. new { key = value} for anonymous
  2. new X{ key = value } for class initializer
  3. new Dictionary<stirng,object>{ { key, value} } old initializer syntax
  4. new Dictionary<string,object>{ [key] =valye ,} new initializer syntax

Suggest to allow both symbols : and = to be valid in initialzier.
So anonymous could be new {key: value} and class initalizer too `new X { key : value }

It will be greatly usefull for 2-language projects with JS and for readablity in REST contet.

":" symbol is not much overloaded in C# ( it used for 1) ternars 2) before base class list ) it's much more free than in C++ (where :: operator exists) so it will be not ambigous in initializer context.

For #6673 and similar issues it will be first step to do C# and JS initializers closer.

@HaloFour
Copy link

There is no reason to do this. The = operator works fine and is easy to understand. What value does adding a completely superfluous operator to the language have other than to make it smell more like JavaScript?

Also, REST has NOTHING to do with JSON, or any particular wire format. REST is the pattern of HTTP verbs and resource names. It's just as likely to return XML or plain/text or pictures. So that argument goes right out the window.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

@HaloFour i see that only reasone of your posting is trying to show you are passion warior of C# clearance.

The only thing that most people who really use C# over 10+ year asked about initializers - why they choose '=' to do things where ':' should be more preferable. If you are not comfort with it - continue use '=' what is problem?

"Smell like JavaScript" - you are so bad about JavaScript? We must ask why? - it's efficient, readable and very compact language... you don't lilke readability and compact code? - it's "smell" for you? Hejlsberg will be not your best frend. ))) May be you think that C# always "smell as dior"? No - it's not true, sometimes it smell as GC.

Man, don't try throll me with you great knowlege about REST - you speak as school teacher - mentored but without experience with dealling with real one.

@HaloFour
Copy link

@comdiv I'd suggest reading some Douglas Crockford if you don't know about the myriad of language absurdities with JavaScript. The language was slopped together over a three day weekend, and it shows. It is largely an awful language with awful syntax and awful idiosyncrasies.

C# chose to use = because = is the assignment operator in c/C++. There doesn't need to be any other reason.

I write REST services on a daily basis and have been doing so long before ASP.NET supported them and before JSON existed. REST was described in 1996. I'd suggest you learn a thing or two about the technologies that you demand be incorporated as syntax into the language.

@sharwell
Copy link
Member

There are already subtle differences between the { key, value } form and the [key] = value form. I don't want to expand on this syntax with no functional change for the following reasons:

  • It increases complexity of the language and therefore increases the difficulty of training new developers to use it (small items in this category add up to big problems over time).
  • There are no notable benefits offered by the new syntax. Specifically, it is not a shorter way to express any other piece of functionality provided by the language, and is not easier to read than the existing form.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

Man - it's not problem of my suggestion. It's problem of C# itself - starting as modern and clear language it get already two not good initializers - both {key,value} and [key]=value are not comfortable in tasks where dictionaries especially needed - create dynamic data for interop with systems as ElasticSearch and Google API.

It's ALREADY mistake of C# - try to close question with {key, value} - it's so ugly that [key] = value was necessary - 2 versions of C# contains 2 versions of initializers? - both ugly and very "original".

@sharwell As you see in links this query is in row with others that goal is to simplify JS/JSON interop You may be completly right, but just say - do you really thing that it's code on good language:

var esquery = new Dictionary<stirng,object>{
    ["query"] = new Dictionary<stirng,object>{
        ["query_string"] = new Dictionary<string,object>{
            ["query"] = "language"
        }
    }
}

May be you can tell that you can do it with anonymous:

object esquery = new {query= new {query_string = new {query ="language"}}}; //oh good C# is cool
//but what about - somewhere else
if (options.Sorted){
    esquery["sort"] = new  { timestamp = "desc" }; // oh - it's not map it's anonymous compiler ERROR
}

The only answer is that C# that support usual JS-like initializer for Dictionary<string,object> and it's default class for mapping is good for C#:

var  esquery = {query : {query_string :  {query : "language"}}}; //compiler substitute with  Dictionary<string,object> 
if (options.Sorted){
    esquery["sort"] = {timestamp:"desc"};
}

It's not just readable, not require anything except System.Collection.Generics, not require much work on Roslyn - it's highly compatible with JS - last code already is JS too. So if we need to supply both C# and JS(for nodejs) version of some logic it will be less work to accomplish.

May be you can say that I must say that existed situation is good?
May be you can tell that JS interop is not real task? Say it to people working with ES, Mongo, Google API and with GeoJSON.
May be i should use dynamic or i must use Newthon?

It's not new syntax - it's very old syntax - problem is that C# team ignores usefull expirience of JavaScript, forgot that Java world continue spam script wrappers over Java (as Groovy) just to compensate Java uncomfort zone.

Existed initializers are dark side of C# and you try (i work with C# since 1-st version and have millions lines of code in it myself and with my team) tell me that they are cool. We know existed initializers, both of them and every time we wander about it's design.

You can further think that it's all good but it's just sign that C# became older and it's community is not oriented to C# usage, but oriented to keep it "very special and original" even if it's not truth.

I'm not best Guru but work hard with C#, JavaScript and some other things. It's sad but C# community more and more is looks like Java community - every ugly thing in those language and every comparison with C# or something else - and they not try to think "why our Java developers not agree with our roadmap and look for C# and migrate to it" - they was just hated and speak that "Java really is beter and cooler forever and ever and it will never be close to C# because C# is bullshit and Java is GOD".

@HaloFour
Copy link

@comdiv It's no mistake, it's just different. I'm sorry that you don't like it, but that's no reason to arbitrarily change it to just use one special character in place of another. Your argument boils down to nothing more than, "I want C# to be JavaScript." C# isn't JavaScript and there is no reason for C# syntax to become JavaScript.

ElastiSearch uses JSON, not JavaScript. A dictionary initialization syntax which would potentially be a superset of JSON (but not JavaScript) is being considered. That syntax would include :.

@alrz
Copy link
Member

alrz commented Nov 23, 2015

Is there any chance to see a "C#: The Good Parts" book in the future? Because these are going to be the good parts.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

@HaloFour - i work with ElasticSearch - every day - i create dictionaries and serialize them to JSON - i know with what i work. Problem is Dictionary creation - not JS or JSON.
With JS we do so JSON.stringify(jsobj) to build JSON. What you want to say? Exactly?
@HaloFour say one thing - are you really think that current dictionary initializer is good?
You have post 100+ comments about "C# not JSON comdiv not know C#, C# is not JS, comdiv don't know REST, Elastic is JSON, REST is not JSON" - where are your POSTs about TOPIC and SUBJECT - better Dictionary initializer for C#.
I like JavaScript so I suggest do initializers this way. You can like JS, not like JS, you can say that REST is not about JSON but what you really can say about DICTIONARY INITIALIZERS.
If it's not required - why we have 2 already, why both of them {key,value} and ["key"] = value never control duplicates even with Warn and if constant are used - it's smart you think, why them not use existed anonymous syntax to parse names? - @HaloFour - after anti-JS holywar you not see problem of C# - invalid dict initializer design.

But I know cause - C# is not dynamic language by nature and when dynamic requirements occured - C# designers try to resolve it on typed-object maner - "you should supply POCO model, supply serializer"- or they supply something monstrous as DLR and dynamics - but it's not about realty of dynamic based API. This and close issues is just first blows of wind to make C# more smarter for dynamic and scripting tasks.

For following hollywar @HaloFour
What Is better:

using System;
namespace MyNamespace {
     public static class Program {
        public static int Main( string[] args) {
            Console.WriteLine("Hello HaloFour");
            return 900913;
        }
     }
}

or

System.Console.WriteLine("Hello HaloFour");
return 900913;

I think I know your answer "C# is object oriented, binding operators to functions and binding functions to classes - is main think you must pray about, namespaces are only ultimate way to avoid ambiguity!!!!"

But i know real answer - Roslyn already can parse method body on script manner and supply wrapping method and class dynamically with dynamic names. Why? Because it's really needed to use C# in short script developing too, especially due to new coming dnx realty.

Se further man. See to EDGE - their comunity hardly discuss common modules both for JS and C# - they think int terms of code generation from TypeScript definitions and similar, but I think they would very glad if they could write :

//my.cs
var a =  {x:1};

And get both JS and CS without overheat?

@whoisj
Copy link

whoisj commented Nov 23, 2015

@comdiv

var a = {x:1};

So basically - you want Roslyn to do you parsing because you do not want to write your own parser or consume an existing parser?

Am I understanding that correctly?

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

I think that it's not good idea write OWN Roslyn. I have not good expirience with Boo (meta) and good experience own parsers for some domain-oriented langs.
If Roslyn community will agree to add such literals to C# 7 but they would not write it themself - then i will ask gurus of Roslyn - where find places to fix - and prepare pull request myself.
But only in case that it will be in common release further.
I don't want to create special "Very.Guru.Comdiv.Roslyn" fork that will got breaked from Roslyn master branch after 2 weeks of domination )).

@HaloFour
Copy link

@comdiv You have yet to demonstrate why C#'s dictionary initialization syntax is "invalid" beyond the fact that it's not JavaScript.

@HaloFour
Copy link

@comdiv You're the one making the proposals. The burden of proof is on you to demonstrate why the effort needs to be expended.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

@HaloFour - you are just holywar throll
Comment this sample, why it's valid:

var esquery = new Dictionary<stirng,object>{
    ["query"] = new Dictionary<stirng,object>{
        ["query_string"] = new Dictionary<string,object>{
            ["query"] = "language"
        }
    }
}

I have post it more than 10 times as main motivation.
It's bad because it's bad.
It's ugly because it's ugly.
It's uncomfortable because it's uncomfortable
It's unreadable because it's unreadable
It's too long because it's more than 70% of syntax and repeats not mean part.

You still speak about JS - please talk about C#

@HaloFour
Copy link

@comdiv Your argument is with the explicit creation of the type, not the dictionary initialization syntax. Fine, a dictionary literal would solve that. But, as mentioned before, a dictionary literal syntax would not reuse identifiers as names nor would it be limited to keys of string.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

@HaloFour why anonymous classes reuse names and can use them even replacing values

var x = 1;
object a = new { x };

Oh, i know - "it's class and it's names - dictionary is not class - so no names", logically... nothing can said.

your last comment is even stranger than all things you write before, i translate:

"Ok, stupid and nooby Comdiv - take your shitty dictionary literals - BUT WE NEVER do them good - they will be not help for you - it will be inquisition - NO NAMES, NO KEYS, JUST STRINGS AND NOTHING MORE!"

What do you want to say exactly.

I give simple to reproduce sample of bad C# design. (I'm C# guy - i don't know another samples of bad design of C# and agree with most decisions in C# 2,4,5,6 )

I give simple to implement solution that is close to existed C# notation (far close than C-Omega syntax) and in another issue suggest parser/production rules for it.

But almost all discussion is with you and is about that C# is not JS. What is you goal in github and roslyn project? What do you develop with C# what kind of products? How it occured that you totally comfort with existed initializers and so angree about JS? So strange... so strange...

@HaloFour
Copy link

Anonymous classes don't have keys, they have properties. Properties are identifiers. Keys are not identifiers. Properties aren't expressions. Keys are expressions. Properties must be names that confirm to the rules of identifiers per the C# specification. Expressions can be of any type and of any value.

You're the one trying to force JavaScript into this conversation since you demand on JavaScript syntax and not JSON (despite the argument about REST/ElastiSearch/etc.).

@alrz
Copy link
Member

alrz commented Nov 23, 2015

var esquery = new Dictionary<stirng,object>{
    ["query"] = new Dictionary<stirng,object>{
        ["query_string"] = new Dictionary<string,object>{
            ["query"] = "language"
        }
    }
}

This has nothing special to do with dictionaries, These are just indexer initializers , and before that there was collection initializers which call Add overloads. so these are just general syntaxes for initializing that happen to be useful for Dictionary<,> as well. Until now there wasn't any effort to support "dictionaries" as a language feature and I think even #6949 is not intended to do that. By the way, opening three individual proposals for this seems silly because they don't make any sense on their own, #6673 was enough, If you just like opening new issues, then that's ok.

@sharwell
Copy link
Member

@comdiv The two initializer syntaxes do not do the same thing.

  • { key, value}: This form uses the Add(TKey, TValue) method for each item. And like Add, an exception will be thrown if you have the same key twice according to the equality comparer used by the container (not a requirement, but this is the most common implementation for Add). If the container does not have such an Add method, this form cannot be used.
  • [key] = value: This form uses the indexer property for the container. If two or more keys are equal, the last one defines the value for the key (not a requirement, but this is the most common implementation for indexers). If the container does not have an indexer with a set accessor, this form cannot be used.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

@sharwell I know what is initializers.
This issue was covered by next one: #6965
There is Add semantic (dictionary as collection) there is indexer semantic (dictionary as set).

But there is not normal dictionary tree semantic where we can define dictionary<string,object> as tree structure? As it can be defined in JS or Groovy or Python. It's kind of indexer semantic but without syntax overheat.
Of course this issue itself not cover this thing. But when I make complex issue - it became some kind of holywar #6673 - people prefer to speak about should or not should C# be closer to JS instead of thinking how to make dictionary usage more comfortable. If you are really interesting what is motivation and how it's suggested to implement #6965 is most detailed one.

@whoisj
Copy link

whoisj commented Nov 23, 2015

@comdiv why put together a working example on https://github.com/dotnet/corefxlab and see if the community adopts it?

@sharwell
Copy link
Member

But there is not normal dictionary tree semantic where we can define dictionary as tree structure?

That is unrelated to this proposal. This proposal only concerns the ability to use : instead of = in the indexer form of initializer expressions.

The comment where you replied to my first response contains the following:

It's ALREADY mistake of C# - try to close question with {key, value} - it's so ugly that [key] = value was necessary - 2 versions of C# contains 2 versions of initializers? - both ugly and very "original".

I was simply clarifying that C# contains two initializer expressions, but they do not behave in the same way. The proposal you are making here does not contain any new behavior. This proposal, unlike the introduction of indexer initializers, is a true duplication of an existing language feature.

📝 Note that I am not criticizing you for making this feature request. I am simply adding context to my reasoning for objecting to using it.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

It think that it can be pull request for roslyn repository - it cannot be created at corefxlab level, while it require to fix compiler at parser level and add rewrite tree filter. It would be pleased if someone from roslyn community can help to explore roslyn code and find minimal set of point to add required fixes in, while roslyn codebes is much complex - it's hard to explore it from zero.

@sharwell you are right and i make reference to #6965, it's not copy of existed feature - it's advanced version of feature. Where are many C# things that is no actually new features but are advanced old ones - for example lambda syntax for delegates - of course you can speack that lambdas are coupled with expression support - but in practice it's just shugar over existed delegate support. Same we can said about already existed short version of array initalizer - where's nothing new in it, but advanced existed one. But of course it's not discussion of this issue, suggest to close it and move discussion to #6965

@HaloFour
Copy link

@comdiv

There is absolutely nothing that makes : more "advanced" than = when it comes to anonymous type declaration, object initialization or indexer initialization. It is the replacement of a single character for another for no reason other than to fulfill this JavaScript obsession of yours. This proposal doesn't make any sense outside of the other two proposals which are literally just the repetition of #6673.

If you want to argue for dictionary literals, I'm all for that. You've already proposed your syntax on that subject and it has some comments by members of the C# team. Redefining existing initializer syntax just 'cause is silly when it provides absolutely no verbosity or functionality improvements over the existing syntax.

@comdiv
Copy link
Author

comdiv commented Nov 23, 2015

So it's better explanation is in #6965, i close this issue while it's not clear. Additionally after discussion of ambiguity with anonymous i review own opinion and think that ':' is not good for all proposes but for dictionary literals only. I close this issue.

@comdiv comdiv closed this as completed Nov 23, 2015
@gafter gafter removed the Discussion label Nov 23, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants