dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.05k stars 4.04k forks source link

JSON-like syntax for dictionary/array initialization and operation #6673

Closed comdiv closed 6 years ago

comdiv commented 9 years ago

Now :

var dict = new Dictionary<string,object>{
    ["key1"]  = 1,
    ["key2"] = new Dictionary<string,object>{
       ....
    }
}

this syntax is very ugly while JSON based integration is very usefull for now (ElasticSearch, MongoDB, numerous REST-based services) it will be good idea provide more native way to use JSON notation in C# Additionally it could be usefull provide lightweight JSON notation closer to JS / anonymous class declaration. What is my dream:

int z= 3;
var query = {
   z,
   x : 1,
   "b" : {
          c : [ 1, 2, 3]
   } ,
   a = 2
};

where {...} after assign operator treats as JSON-like ctor for Dictionary<string,object> with following notation : JCTOR -> { PROP[, PROP]* } PROP -> NAME ASSIGN VALUE | SCOPE_NAME (as in anonymous classes) ASSIGN -> = | : (both assign operators should be valid) NAME -> STRING | LITERAL (both JSON and JS/anon class methods of name definition) VALUE -> ANY (nested JCTOR, ARRAYS, terminal values, expressions)

Example above should internally translated to:

int z= 3;
var query = new Dictionary<string,object> {
   ["z"] = z,
   ["x"] = 1,
   ["b"] = new Dictionary<string,object> {
          ["c"] = new [] { 1, 2, 3 }
   } ,
   ["a"] = 2
};

So we can use json/js syntax without using any external classes at runtime.

More live example

var id = "xxx";
// we setup it even simpler that with JSON (no quotes)
var es_query = {
    query : {
        query_string : {
            query : $"_id:{id} AND other:true"
        }
    }
};
//but while it's just usual Dictionary we can work with it
if( size != -1){
    es_query[nameof(size)] = size; 
}
...
gafter commented 9 years ago

A prototype of this idea was presented last week at Microsoft's MVP summit by @AnthonyDGreen .

BreyerW commented 9 years ago

i support simplyfying arrays. ATM writing nested arrays/dicts is really ugly even after introducing new syntax for arrays. However i think keys still should use "key" otherwise "dynamic" key will be impossible (?). i mean something like this:

var id = "xxx";
string dynKey="our dynamic key";
var es_query = {
    "query" : {
        dynKey : {
            "query" : $"_id:{id} AND other:true"
        }
    }
};
//but while it's just usual Dictionary we can work with it
if( size != -1){
    es_query[nameof(size)] = size; 
}
...

btw maybe instead using {} we could use [] for even simpler/faster to type syntax? this would look like this:

var id = "xxx";
string dynKey="our dynamic key";
var es_query = [
    "query" : [
        dynKey : [
            "query" : $"_id:{id} AND other:true"
       ]
    ]
];
//but while it's just usual Dictionary we can work with it
if( size != -1){
    es_query[nameof(size)] = size; 
}
...
gafter commented 9 years ago

@BreyerW I think the point is to support json literals.

gafter commented 9 years ago

/cc @ljw1004

comdiv commented 9 years ago

Not exactly JSON - JSON is not very usefull too: 1) quotes around all names required 2) trail commas not allowed 3) no verbatim strings I think that point is to simplify dynamic object creation with C-related syntax that is forward compatible with JSON, JS, GROOVY and C# anonyms.

Array simplification is an option too.

alrz commented 9 years ago

Funny, I was going to propose this as well #3910 (comment) :smile:

dict-expression:{ dict-elements ,opt }

dict-elements:dict-elementdict-elements , dict-element

dict-element:constant-expression : expression

list-expression:[ list-elementsopt ]

list-elements:expression-list , opt

This would play nice with #3555, and can cover the #4100 easily. Also, the dictionary syntax is very close to anonymous types. What about use cases mentioned in #3910 "Wire formats"?

[Json]
interface IFoo { string name; double price; }

var foo = new as IFoo { "name": "name", "price": 12 };

foo.$name

Although, I have suggested new as syntax also for named anonymous types #3304 (comment)

HaloFour commented 9 years ago

The reason JSON spec requires the quotes is to avoid the keyword and type concerns that it would otherwise inherit from the JavaScript spec. I'd be fine if C# didn't require them for the keys where the name would be a valid identifier. Quotes or @ could be used where the key is not a valid identifier.

I think that this would fit nicely along with #4100 which uses named-argument syntax for params Dictionary<string, object>. I do hope that dictionary literals and array/list literals can be speced to stand on their own as well.

comdiv commented 9 years ago

For the start - we must coordinate main goal what we want to accomplish. For me it should 1) First goal is to add simplifyed JS - friendly syntax for task where JS is the best - tree-structure creation

var map = {x:1} //must be valid

2) it must be "from-JSON" compatible

var map = {"x":1} //must be valid

3) It should be used with existed classes at core


var map = {x:1,y:{a:"3"}};
//should be equal by default to
IDictionary<string,object> map = {x:1,y:{a:"3"}};
//but must support type control
IDictionary<string,int> intmap = {x:1,b:2}; //ok
IDictionary<string,int> intmap = {x:1,b:"2"}; //error
IDictionary<string,int> intmap = {x:1,b:2,c:{a:3}}; //error (nesting)

4) It should be able to use variables in names

var myname = "xxx";
var map = {$"{myname}" :4};

5) It should be used in anonymous context with stricts

var x = new {x:1,y:2,"z":3}; //should be valid
var y = new {x:1,"my val":2} //should fail - non literal name
var z = new {$"{somevar}": 4} // should fail if somevar is not compile-time constant with literal

6) It should be able to open road for inplace typed classes

public interface IMapReducer<TItem,TResult> {
     void Map(T item);
     void Merge(IMapReducer<TItem, TResult> other);
     TResult Reduce();
}
public abstract class MapReducer<TITem, TResult>{...}

//as interface implementation
IMapReducer<int,int> mapreducer1 = new as IMapReducer<int,int> { sum:0, cnt:0, Map : i=>{sum+=i,cnt++},...}
// as override of base class
IMapReducer<int,int> mapreducer = new as MapReducer<int,int> { sum:0, cnt:0, Map : i=>{base.Map(i);sum+=i,cnt+},...} 

6) It is not just about objects and maps but arrays to:

var x = [1,2,3]; //object[] {1,2,3} 
//think it shouldn't try to guess type

7) It would be cool add merge and operation overload

var arr = [1,2,3];
arr+=[4,5]; // -> [1,2,3,4,5];
IList<int>list = [1,2,3]; //new List<int>{1,2,3};
list+=[3,4]; //{1,2,3,3,4};
list~=[3,4]; //{1,2};
l...
var map = {x:1,y:2,a:{b:3}};
map+={z:3,u:2,a:{c:4}}; // {x:1,y:2,z:3,u:2,a:{b:3,c:4}};
...

8) Should be closer to short C++ ctor syntax (but may be it's not in C# ideology)

//why we should write
var x = new int[] {1,2,3};
// but not
int[] x[1,2,3]; // as example
//or even
var x[1,2,3];
var z{x:1,y:2}

It should not 1) It not should be JSON itself

//why it should be wrong?
var map = {x:1,}; //!!!! - it's clear why not?
//while if it is JSON we MUST
var map = {"x":1};

1) !!! IT SHOULD NOT BE more strictive than existed C# construction - it could REPLACE them completly - not be just ANOTHER-ONE

var str = "xxx";
var map = {x:1, toString: ()=>$"i am {str}" } //why not?
var map = {x:1, myArray: something.ToArray()} //why not?

For me it's ideology is close to GROOVY - we have JAVA in core but with very simple constructions. But while we have ROSLYN we can add such things in language C# itself on static/ dictionary way not with dynamics overheat.

In way described above we can supply fully functional unified alternation for all thing in list:

1) Anonymous classes 2) Object initialzers 3) Dictionary/arrays/list creation 4) Ugly manual merge/add/append and Array API operations

Because it's not very strong part of C# for now

ghord commented 9 years ago

I fail to see how this is different from XML literals feature which you were vehemently opposed to. I don't think adding features to C# that are tying it to any other language implementation such as JSON is a good idea. Did you consider more general syntax along the lines of this code: (With library provided coloring/compilation of snippets)

var item = json { "property" : "value" };
var query = sql select * from items;
var tree = xml <root><item>value</item></root>;

I would either do a feature that lets us work with any language or none at all...

comdiv commented 9 years ago

C# already is all-eating language that got much from others. And I don't suggest something new for C#. Me and some other guys just suggest replace ugly initializers that now are implemented in C# with construction that are in every-day in usage in JSON and where C# has lack. May be you think that generics, lambdas, object model, core {} syntax, namespaces are something C#-only?
In you humorous spample with SQL where's nothing more usable than

var query = "select * from items";

Xml construction from strings is not common way to do it while XML syntax itself is ugly and not comfortable.

So we DON'T want have Sql or Xml injectsions.

May be u forogot, but we ALREADY have SQL-Like syntax in C#, remember?

from i in new[]{1,2,3}
let x = i * 2
where ....

So your sarcasm is very strange.

But JS/JSON syntax is much close to C# and far more pretty - so it would be usable in C#.

May be u think that

// usual elastic search query creation
var dict = new Dictionary<string,object> {
   ["query"] = new Dictionary<string,object> {
        ["query_string"] = new Dictionary<string,object>{
        ["query"] = "[query string]"
        }
   }
}

is cool? it is C# dream? To make code unreadable and hard to write?

In JS and Groovy it will be

var query = {
    query :  {
        query_string : {
                query : "[query string]"
        }
        }
}

Python: (even no tabs - all is with {} while Pyhon is not {} langauge by nature)

q = {
  'query' : {
    'query_string' : {
                'query' : '[query string]'
        }
   }
}

So i think it's time to fix it not because "other languages has" but because "REST and ES and Mongo and other JSON/JS stuff is very popular and usable from C# and it's very uncomfortoble to deal with them with current syntax"

ufcpp commented 9 years ago

The title of this issue could be misleading. It should be like "JSON-like syntax for dictionaries and arrays". "JSON literal" sounds like a syntax for creating some kind of JSON class such as JObject or JArray.

comdiv commented 9 years ago

You are right, renamed

bondsbw commented 9 years ago

@comdiv Based on your list above, here are my personal opinions for what they're worth:

1) First goal is to add simplifyed JS - friendly syntax for task where JS is the best - tree-structure creation

1: Agreed, high priority.

2) it must be "from-JSON" compatible

2: Low priority, but I have nothing against it.

3) It should be used with existed classes at core

3: Agreed, high priority.

4) It should be able to use variables in names

4: Sure, although I'm not sure how this is different from, I assume nothing would prevent this as it is an existing part of the language.

5) It should be used in anonymous context with stricts

5: I'm not sure what I think on this. I believe this would depend on something like #1141, but I'm not sure the advantages of making the JSON components accessible via dot notation would outweigh the disadvantages.

6) It should be able to open road for inplace typed classes

First 6: Seems handy but maybe that's a larger feature in general.

6) It is not just about objects and maps but arrays to: ... 7) It would be cool add merge and operation overload ... 8) Should be closer to short C++ ctor syntax (but may be it's not in C# ideology)

Second 6 and 7 and 8: I like these concepts, they would be like F# lists. I think this should be filed as a separate proposal (if there's not already one for it).

It should not 1) It not should be JSON itself

First 1: Agreed, a library can be used to create JSON from these dictionaries.

1) !!! IT SHOULD NOT BE more strictive than existed C# construction - it could REPLACE them completly - not be just ANOTHER-ONE

Second 1: Agreed (assuming "something" is an existing collection).

alrz commented 8 years ago

@gafter I see that this is removed from vnext milestone, it's because of "priority" concerns or something specific to this proposal?

gafter commented 8 years ago

@alrz I don't think this proposal is quite right. We do want to support something like json literals. Actual json literals should work. But if you omit the quotes around a name that becomes an expression, like a variable reference or something. That is not what is envisioned by this issue.

comdiv commented 8 years ago

Disagree. While it's just json-like but not JSON itself it SHOULD NOT provide quoting. Only if it is at name part

var x =1;
var map = {
    x: x+1, //"x":2
   val1 : x, // "val1": 1
   $"val{x*10}" : x+2 //"val10": 3
};

Think it's clear and significally same as in JS - so it would be understandable and not require special quoting;

gafter commented 8 years ago

@comdiv that was my understanding of your proposal.

alrz commented 8 years ago

I think without quotes it's more JS objects than JSON, in any case, it wouldn't make sense for C# to create dictionaries like that, the syntax that I proposed is pretty clear on that matter.

@comdiv What you're proposing is more like an anonymous type than a dictionary. These should be clearly distinguishable from each other. By the way, it seems that #1141 is addressing this request.

comdiv commented 8 years ago

Of course it's JS/TypeScript/C# Anonymous/Python/Groovy like syntax because it's simple, less quotes and special symbols and don't require much more than C# already is.

alrz commented 8 years ago

less quotes and special symbols

In fact, what is the point of quotes at all. I don't understand.

comdiv commented 8 years ago

In fact, what is the point of quotes at all. I don't understand. my English issues...

Core syntax:

C# current syntax:

{ ["x"] = 1 } 

9 symbols + it require new Dictionary<string,object> and so on

JSON syntax:

{ "x" : 1 }

7 symbols

C# anonymous new { x = 1} 5 symbols + 3 (8) due to new keyword

JS syntax: { x : 1} 5 symbols

So JS is winner. If we require to use expressions in names and values. C# anonymous cannot accept expressions in names

var n = "name"; var ni = "1"; var v = "value"; // try to build {"name1":"value"}

C# initializer

{ [$"{n}{ni}"] = v}

14 symbols + new DIctionary...

Suggested JS-like syntax: { $"{n}{ni}" : v } 12 symbols

So we just recomend 1) remove ugly "new ..." for typical initialization (Dictionary<string,object> by default) 2) remove ugly ["xxx"] syntax and replace it with usual { "string": val} and {literal:val} 3) support both ":" and "=" as delimiter

And it will be very pretty, close to JS and TypeScript map initialization support in our lovely C#

gafter commented 8 years ago

All of the proposals to "shorten" the syntax assume we want the keys to be constant strings. I don't think we want to restrict the keys to be constant strings. We want them to be general expressions. Certainly literals will be the most common, but we want you to be able to use, for example, the value of a local variable for the key. We are not aiming to be JS or TypeScript - those are separate languages - but JSON is used as an interchange format so having a syntax for which that is a subset is a bonus. And JSON does indeed require quotes around the keys, so that is nicely compatible with the desire for the keys to be general expressions.

ljw1004 commented 8 years ago

My proposal to shorten the syntax is this:

{ "fred":expr,
   identifier:expr,
   <%= expr %>:expr
}

The rule is that the key can be

  1. a literal (in which case the value of this literal is used)
  2. a simple name (in which case the name is treated as a string)
  3. a hole (in which case the expression inside the hole is evaluated) The hole syntax might come from Razor, or from VB XML-literals.

The idea behind this is to (1) support JSON syntax, (2) support a convenient shorter syntax for the typical case like JavaScript does, (3) still have an escape-hatch for the more rare case.

Here's a comparison of other languages...

I have to say, based on what's in all the other languages, the JavaScript approach (my proposal) is pretty idiosyncratic, and probably not worth pursuing for a mainstream general purpose language.

tpetrina commented 8 years ago

Why not use string interpolation for expressions so this would be a valid syntax:

new
{
  name: "John",
  "age": GetAge(),
  $"payType{GetPayType()}": Employee.Regular 
}

So, either use a "property name", a string or a string interpolated expression.

gafter commented 8 years ago

@tpetrina Are you suggesting that this syntax would only be allowed to support strings as keys?

comdiv commented 8 years ago

Agree that if literal==strings in keys is ambigous idea - interpolations could be not bad

tpetrina commented 8 years ago

@gafter Well, JSON keys are strings so it makes sense that they are either valid C# names (for easier mapping to properties/fields) or general strings which may not be valid C# names (e.g. "data-type").

What did you have in mind if not using strings as keys?

gafter commented 8 years ago

I had in mind a syntax for dictionary initializers in which json just happened to be a special case. I also would like to avoid special rules for expressions in this context (I.e. Treating an identifier as a string)

alrz commented 8 years ago

You mean like this?

// is the "new" necessary?
var first = new { "name": (foo: "foo", bar: "bar" ) };
// int[] or List<int>?
var second = new [ 1, 2, 3 ]; 
// is this a Dictionary<string, object>?
var third = new { "id" : { "type": nameof(int) } , typeof(int).FullName: [ 1, 2, 3 ] };
// is this a Dictionary<string, Animal>?
var forth = new { "cat" : Cat() , "dog": Dog() };
// PS: can (string : Animal)  be considered as a shorthand for Dictionary<string,Animal>?
gafter commented 8 years ago

@alrz Maybe (I'm not sure exactly what you're asking). We probably need to give some hint as to what type of thing we're building, perhaps as part of what you've written as new. In any case that discussion probably belongs in #6949.

comdiv commented 8 years ago

To @alrz "You mean like this?" Js like means that it's for JS-like scenarios too. - It's support for dynamic-like behavior. And assume that i not agree that keys should be strings - my opinion that thay are NAME|STRING

var x = { cat : Cat(), dog : Dog() };  // is still Dictionary<stirng,object> while...
x["name"] = "Animals";

Have read all your posts on this thread and have impression that you don't really understand CORE motivation to bring JS like into C#. CORE motivation is not to supply "new universal C# syntax for any tasks". Core motivation is to give C# mechanics for better interop with JS/JSON (Edge, ElasticSearch, Mongo and so onb) and for better in/out serialization support fo REST (own and external web API's, Google and 9000+ of them). So with this case IDictionary<string,object>,object[], primitive types are best friends (already are best friends) along with it ((IEnumerable)e).OfType<object>.ToArray()) and e.GetType().GetProperties().ToDictionary(_=>_.Name, _.GetValue(e, Type.EmptyTypes)) and any?.ToString() are best friends too. So the main motivation is that iif in my ElasticSearch JSON i see:

{ "query" : {"query_string":{"query":"xxxx"}}}

I really want to write in C#:

var query_string = "xxxx";
var query_json = { query : { query_string : {query : query_string }}}; //that is JS-like syntax with NAME OR STRING at keys
var result_query = http.CallJson("/_search",query_json); //assume it returns IDictionary<string,object>
var full_info = { timestamp: DateTime.Now(), query : query_json, result : result_json };
File.WriteAllText( "...", full_info.ToJson());

It's real codestyle when you work with legacy API's - and you can tell that here we must to implement POCOs, implement EF extension and use it with EF, but it's not valid because most of API's (for ex ES) do not distinct object[] and object and map so {x:"a"} and {x:["a","b"]} and {x:{hint:"some hint",values:["a","b"]} could be all valid calls. It's true about both request parameters and return values.
So you cannot directly map in/out data to something "typed" with C# - you should use dynamic structures in intermediate. But it's not about dynamic keyword and DLR in .net (they are much slow and weighted for this task) - we just want to give IDictionary<string,object> and object[] and their best-known conversions second life as real intermediate structures fo JS/REST interop, as dynamic was created in motivation for COM interop (you can speak that noone use it but it's not true - developers who must to deal with Office and other COM based stuff really use it). So if С# will come with JS like syntax - 30% of my code will be rewritten with that syntax.

HaloFour commented 8 years ago

@comdiv Sounds like you'd be better served with #51. Yes, it wouldn't look like JavaScript, but as mentioned it is not a goal of C# to become or to look like JavaScript. Supporting JSON as a wire format and/or a general-purpose dictionary syntax would not likely treat identifiers as names.

comdiv commented 8 years ago

Yes it close to but i don't want to write IDictionary<string,object> explicitly, especially nesting (#51 don't sayd what about nested?) And i think #51 is close to this issue - because in #51 author said that it's just anonymous class syntax for dictionaries (he don't care if runtime classes would be generated for this anonyms because they never used on typed manner in examples of #51). So correctly would said that in #51 author said "oh gods of C# give me something (for ex anonymous) to make dicts simply!"..

And it's not goal to "C# look like JS" or vise versa but in real world it's very strange to copy paste JSON (that is really standard) to C# and then perform some replaces : to = and so on. And I don't understand why C# cannot have alternate ':' syntax for 'map-assign operator' along with '=' - for now it's only thing that distinct C# anonymous syntax from JS - THE ONLY. Can you say that such ability is very hard to implement in C# and require ideological synode to judje anyone who just want to use ':' to simplify REST interop?

HaloFour commented 8 years ago

@comdiv

You do know that C# is also a standardized language as well? It's ECMA standardized (same body that standardized JavaScript and JSON) as well as ISO standard. Nobody expects two completely different languages to be able to be copy&pasted to one another.

comdiv commented 8 years ago

@HaloFour: "You do know that C# is also a standardized language as well? It's ECMA standardized (same body that standardized JavaScript and JSON) as well as ISO standard. Nobody expects two completely different languages to be able to be copy&pasted to one another."

In which version it was standartized? In which year - how it match C# 5 and C# 6 man? You have mistaken about HEAD and TAIL. C# is HEAD and it's standard is TAIL. - C# changed and standard changed. It's true about all standards for languages. We have C++ 11 specification and then we have C++ 14 - nothing wrong while it has many things completly incompatible with C++ 11 and i even don't remember C++ 9 and older. And JSON is one of external standards that C# cannot ignore because one of it's main goal is to be language for REST servers and to be language for interoping with REST. And it's not same situation as with XML - XML is not about "objects" - it's just about "serialization structure" - and EVERYTHING is compatible with XML and back - it's just universal transport specification. It's not same about JSON - JSON is core and bone of OO interoping with very strict syntax and notation. While C# should not be FORWARD-COMPATIBLE with JSON (C# is significally rich than JSON) but it should be BACK-COMPATIBLE with JSON ( so any JSON should be valid C# but not any C# should be JSON) because for another hand C# is not compatible with most primitive C-like object notation. It's not valid situation.

Who wants completly copy&paste language? We spoke about dictionary(map) definitions. And JAVA walk invalid way - they just provide script languages (such Groovy and so on) to supply support for REST interop - while C# should go this way? We have Roslyn - why we still need external JSON things such Newthons, why we still need code generation for usual things?

I know that C# is very and very hybrid language. 1) It is Java/C++ based in it's core. 2) It has JQuery/SQL like LINQ operators (for ... in ... let) that are almost beside main language C-like syntax 3) It has lambdas, based on syntax of 9000+ functional languages 4) It has JS/C++ -inspired initializers 5) It has basic and strict support for JAVA anonymous classes 6) It has very ugly dynamic feature that make C# closer to VB for COM - and its good for some cases 7) We see yield operator that was not in C# 1, and was inspired by Python 2.2 that was firs language for all with this operator

The C# only features (that i don't see anywhere else close way) are: 1) Extensions - some kind of aspect/prototype support - may be something from dynamic languages - may be something in C++ macroses - but i think it's very C#-only 2) async/await - we can see such things in some speciall langs as Erlang, we can see simple 'fork' conception in POSIX - but in C# it's ultimate feature for high-level OO language 3) LINQ syntax (it's inspired by JQuery/SQL/HQL) but experimentally for C#/VB

So... when developers who works hard with REST and JS and use C# at server side fo 10 years speak about that thing that C# still not comfortable for it because it has not fully functioan anonymous support and not allow to use ':' operator (remember that this simpol for now used only in ternar operator - so it's significally free to use and doesn't cause ambiguity) - you speak about C# "clearance", "independance" and standartization. - Now woth Roslyn and open-source -it's especially strange.

The only ideology of C# - to be fastest, modern and comfortable for all propses language. When it was time of COM interop - dynamic was added When it was time to provide EF and better support for SQL/XML - LINQ syntax and Extensions was added When C# author sees that multthreading is still not much effective and clear - async was added When they see that Dictionary is used very intensive - C# 6 dict initializer was added.

But C# 6 initializers and C# 3.5 anounymouses are still not designed and implemented well. They don't match most tasks where they are appropriate - dynamic scenarios. And this issue just recomend simple way that not require to reqwrite and redesign whole C#:

1) Add ':' as alternate 'set' operator for inititlaizers ,both must be valid : {x:1}, {x=1} 2) Add 'to Dictionary<string,object>' translation for anonymous classes (where implicit or var conversion detected by compiler) and object[] translation for inline arrays {x:[1,2,"s"]} 3) Allow use strings in names in anonymous {"my best": 1} - if it's dictionary context (2) it must be used as-is - in anonymous class context it should be compiler erorr (if it's not constant and not name-compatible) 4) Allow names in existed dictionary initializers (C# 6)

It's really in C# ideology (and can be simple implemented with Roslyn) - it just need add one case to Tokenizer for (1), and replace "anonymous class defintion" with "new Dictionary<string,object>" with initializer (2). And for (3) and (4) it could be little more work.

HaloFour commented 8 years ago

@comdiv

So you can't feel comfortable with a language to write REST services unless you can copy and paste JSON as its source code? You have such a language. It's called JavaScript. Feel free to use it. Especially since you're explicitly asking for JavaScript syntax and not valid JSON.

The last version of C# to be ECMA standardized was 2.0. But most languages aren't standardized at all. Nor do they need to be. Nor is it relevant at all. When did it become possible to copy and paste JSON into C++ and have it compile?

I could rattle through the various inaccuracies of your comment, as if it bears any relevance to this discussion. I will point out that X#/Cω predates jQuery by 3 years. Python was also not the first language to support generators with a yield keyword, CLU was doing it in the mid 1970s.

comdiv commented 8 years ago

Oh cool. When i want to deal with MS SQL - deal with T-SQL and osql? About CLU you as me checkout from Wiki (is it good to bound it to discussion?). Python first language that popularize generators and make them known and welcome feature. Javascript is not .net language it's not compilable language and your' totally not right. Clear your mind - C# is Interop -oriented language from it's start. It has unsafe, dynamics, omega, and so on. Your C++ example is strange - C# was created to avoid C++ complexity and hardness - any things that make C# more universal and simple are welcome.

JS/C# convergantion is totally underscored with TypeScript project that is leading by same people as C#. So it's already close to each other languages and it's good ide to convergate them further.

gafter commented 8 years ago

You young'uns didn't program in CLU?

comdiv commented 8 years ago

No man I never program in CLU my start was with C and TurboPascal, is it my sin? Oh, forgot Basic for ZX Spectrum it was first )

HaloFour commented 8 years ago

@comdiv

Oh cool. When i want to deal with MS SQL - deal with T-SQL and osql?

Xen supported mapping and translating LINQ-like queries into SQL. When did jQuery ever become an ORM?

comdiv commented 8 years ago

@HaloFour it was just answer to you "use javascript if want deal with JSON" not more, my friend, enemy of JS.

HaloFour commented 8 years ago

@comdiv No, my statement is, "use JavaScript if you want to copy&paste JavaScript and expect it to be compilable code."

bondsbw commented 8 years ago

So you can't feel comfortable with a language to write REST services unless you can copy and paste JSON as its source code? You have such a language. It's called JavaScript.

Just wanted to point out that JSON isn't even a 100% subset of JavaScript (for example, U+2028 and U+2029 are valid in JSON but invalid in JavaScript).

Running eval() on arbitrary JSON input is never a good idea in JavaScript, so likewise it would never be a good idea to attempt to load arbitrary JSON input into C#.

So the only good reason I can think of is to copy/paste JSON into a C# file for easy reference (otherwise why not just put it in an embedded resource?). In that case, I would prefer something extensible like I mentioned at https://github.com/dotnet/roslyn/issues/1746#issuecomment-89088932. In the case of JSON, someone would create a JSON$ processor and it could be used like this:

var jsonString = JSON$"
    {
        ""contact"":
        {
            ""name"": ""Patrick Hines"",
            ""phones"": 
            [
                {
                    ""type"": ""home"",
                    ""number"": ""206-555-0144""
                },
                {
                    ""type"": ""work"",
                    ""number"": ""425-555-0145""
                }
            ]
        }
    }";

The JSON$ processor could provide full syntax highlighting, code formatting, syntax completion, and perhaps even have some form of intellisense.

EDIT: Added this as a separate proposal in #6972.

And if you need an IDictionary<> out of it, make that an extension method:

var jsonAsDictionary = JSON$"...".ToDictionary();

And this way, we're not tying C# to JSON. JSON might be outlived by C#; for all we know, a year from now YAML will be the big thing and JSON will feel like XML does now. And implementing JSON syntax now, forcing it as part of the language, may constraint future syntax design.

My vote is against making this JSON for the sake of JSON. JSON can be an extension to string interpolation, while the current proposal can focus on making array and dictionary initialization better.

gafter commented 8 years ago

Running eval() on arbitrary JSON input is never a good idea in JavaScript, so likewise it would never be a good idea to attempt to load arbitrary JSON input into C#.

I don't see why the former (Running eval() on arbitrary JSON input is never a good idea in JavaScript) implies the latter (it would never be a good idea to attempt to load arbitrary JSON input into C#). C# code loads all kinds of data all the time, why would JSON be particularly dangerous?

bbarry commented 8 years ago

To add to @gafter's comment, JSON is not dangerous. eval is.

In every modern browser you can use JSON.parse() on arbitrary data safely. You cannot ever assume eval is safe on arbitrary input. A similar vulnerability would exist in C# to eval if you were to copy an arbitrary byte array into the memory location that a delegate is using and then execute it blindly like this.

bondsbw commented 8 years ago

I don't see why the former (Running eval() on arbitrary JSON input is never a good idea in JavaScript) implies the latter (it would never be a good idea to attempt to load arbitrary JSON input into C#).

Because I misspoke. :)

I meant, I suggest never compiling arbitrary JSON input as C# and then loading (executing) it from C# code. In other words, don't do the C# equivalent of eval() in the hypothetical situation that JSON is now a subset of C#.

Loading JSON into memory as a string, or as an IDictionary, or as some JSON DOM is of course fine.

gafter commented 8 years ago

@bondsbw I agree, one should never cut-and-paste arbitrary code into one's C# sources without examining it.

MgSam commented 8 years ago

I'm strongly against adding JSON literals into the language. JSON is just one of many serialization formats. Yesterday it was XML, today it's JSON, maybe tomorrow it will be YAML or something else your kids will invent.

If anything we should be supporting custom string delimiters ala C++ as in #2239 or create some more generic capability to introduce user-defined DSLs.

Let's not pollute the language with the flavor of the day.

alrz commented 8 years ago

@MgSam check this out #6949.

aluanhaddad commented 8 years ago

@MgSam :+1: