-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
JSON-like syntax for dictionary/array initialization and operation #6673
Comments
A prototype of this idea was presented last week at Microsoft's MVP summit by @AnthonyDGreen . |
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;
}
... |
@BreyerW I think the point is to support json literals. |
/cc @ljw1004 |
Not exactly JSON - JSON is not very usefull too:
Array simplification is an option too. |
Funny, I was going to propose this as well #3910 (comment) 😄
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 |
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 I think that this would fit nicely along with #4100 which uses named-argument syntax for |
For the start - we must coordinate main goal what we want to accomplish.
It should not
For me it's ideology is close to GROOVY - we have JAVA in core but with very simple constructions. In way described above we can supply fully functional unified alternation for all thing in list:
Because it's not very strong part of C# for now |
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... |
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?
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?
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
is cool? it is C# dream? To make code unreadable and hard to write? In JS and Groovy it will be
Python: (even no tabs - all is with {} while Pyhon is not {} langauge by nature)
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" |
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. |
You are right, renamed |
@comdiv Based on your list above, here are my personal opinions for what they're worth:
1: Agreed, high priority.
2: Low priority, but I have nothing against it.
3: Agreed, high priority.
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: 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.
First 6: Seems handy but maybe that's a larger feature in general.
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).
First 1: Agreed, a library can be used to create JSON from these dictionaries.
Second 1: Agreed (assuming "something" is an existing collection). |
@gafter I see that this is removed from vnext milestone, it's because of "priority" concerns or something specific to this proposal? |
@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. |
Disagree. While it's just json-like but not JSON itself it SHOULD NOT provide quoting.
Think it's clear and significally same as in JS - so it would be understandable and not require special quoting; |
@comdiv that was my understanding of your proposal. |
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. |
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. |
In fact, what is the point of quotes at all. I don't understand. |
In fact, what is the point of quotes at all. I don't understand. Core syntax: C# current syntax:
9 symbols + it require new Dictionary<string,object> and so on JSON syntax:
7 symbols C# anonymous JS syntax: So JS is winner. var n = "name"; C# initializer
14 symbols + new DIctionary... Suggested JS-like syntax: So we just recomend
And it will be very pretty, close to JS and TypeScript map initialization support in our lovely C# |
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. |
My proposal to shorten the syntax is this: { "fred":expr,
identifier:expr,
<%= expr %>:expr
} The rule is that the key can be
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. |
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 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? |
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. |
@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? Who wants completly copy&paste language? We spoke about dictionary(map) definitions. I know that C# is very and very hybrid language.
The C# only features (that i don't see anywhere else close way) are:
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. 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#:
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. |
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 |
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. 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. |
You young'uns didn't program in CLU? |
No man I never program in CLU my start was with C and TurboPascal, is it my sin? |
Xen supported mapping and translating LINQ-like queries into SQL. When did jQuery ever become an ORM? |
@HaloFour it was just answer to you "use javascript if want deal with JSON" not more, my friend, enemy of JS. |
@comdiv No, my statement is, "use JavaScript if you want to copy&paste JavaScript and expect it to be compilable code." |
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 #1746 (comment). In the case of JSON, someone would create a var jsonString = JSON$"
{
""contact"":
{
""name"": ""Patrick Hines"",
""phones"":
[
{
""type"": ""home"",
""number"": ""206-555-0144""
},
{
""type"": ""work"",
""number"": ""425-555-0145""
}
]
}
}"; The EDIT: Added this as a separate proposal in #6972. And if you need an 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. |
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? |
To add to @gafter's comment, JSON is not dangerous. In every modern browser you can use |
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. |
@bondsbw I agree, one should never cut-and-paste arbitrary code into one's C# sources without examining it. |
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. |
@MgSam 👍 |
TurboPascal is not a language though but a Borland IDE. :) Anyway, I think that bringing JSON to C# would be a mistake so I'm all for loosen the syntax of object initializers to look like JSON but play by C# rules. |
Issue moved to dotnet/csharplang #1238 via ZenHub |
This proposal may make it introducing any script syntax to C# syntax: #34821 |
Now :
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:
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:
So we can use json/js syntax without using any external classes at runtime.
More live example
The text was updated successfully, but these errors were encountered: