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

Proposal: XML literals and embedded expressions in C# #1746

Closed
weitzhandler opened this issue Apr 1, 2015 · 33 comments
Closed

Proposal: XML literals and embedded expressions in C# #1746

weitzhandler opened this issue Apr 1, 2015 · 33 comments

Comments

@weitzhandler
Copy link
Contributor

Hi,

I am a born VB dev. Currently I develop only C# because I prefer the terse syntax over VB's verbose words, but I do miss some awesome features we had in VB.
One of the most notable and very compelling features I do miss very much, is the awesome XML literals and Embedded Expressions paradise going on in VB.
As soon as you get used to these features, separating out really feels like going hardcoded back again.
When I'm to develop a project that involves a lot of XML I'll prefer VB, eventho I don't like it's verbose syntax, and won't be able to link to other source files of my C# code base.

Anyway for those of you unfamiliar with VB, get a taste. Notice how all the XML literals are recognized as XML by the compiler (they're not wrapped with double-quotes).

'infered as XElement
Dim contact1 =
    <contact>
      <name>Patrick Hines</name>
      <phone type="home">206-555-0144</phone>
      <phone type="work">425-555-0145</phone>
    </contact>

 'infered as XDocument
Dim contactDoc =
    <?xml version="1.0"?>
    <contact>
      <name>Patrick Hines</name>
      <phone type="home">206-555-0144</phone>
      <phone type="work">425-555-0145</phone>
    </contact>

Manipulating objects with strings (embedded expressions):

Public Class XmlSamples

  Public Sub Main()
    ' Initialize the objects.  

    Dim phoneNumbers2 As Phone() = { 
        New Phone("home", "206-555-0144"), 
        New Phone("work", "425-555-0145")}

    ' Convert the data contained in phoneNumbers2 to XML.  

    Dim contact2 = 
        <contact>
          <name>Patrick Hines</name>
          <%= From p In phoneNumbers2 
            Select <phone type=<%= p.Type %>><%= p.Number %></phone> 
          %>
        </contact>

    Console.WriteLine(contact2)
  End Sub 

End Class 

Class Phone
  Public Type As String 
  Public Number As String 
  Public Sub New(ByVal t As String, ByVal n As String)
    Type = t
    Number = n
  End Sub 
End Class
@AdamSpeight2008
Copy link
Contributor

What's preventing you from using both languages in a Solution?

@weitzhandler
Copy link
Contributor Author

@AdamSpeight2008 First of all, as I mentioned, when I have a code base in C# and I want to link out several classes in a different platform.
But you missed the point, I wasn't complaining or asking for workarounds, I was merely suggesting a feature. Sorry if I sounded different, feel free to edit my post if you're a contributor.

@AdamSpeight2008
Copy link
Contributor

@weitzhandler
Put the XML processing part in seperate DLL so it can can be referenced in a C# Project (or any other .net language).

@weitzhandler
Copy link
Contributor Author

Again Adam thanks for trying to help, I know how to work around that, but this post is not about how to workaround the lack of this feature, but a request and discussion on how to implement this language feature in the C# language.

@AdamSpeight2008
Copy link
Contributor

I think it would be hard or require a rewrite of the C# lexer and parser, to be statful like VB.net, As the grammar rules for XML are different to VB's. For example '<' has ~18 different meaning in vb.net depending on where it is used.

@weitzhandler
Copy link
Contributor Author

But AFAIK C# has no < as an expression beginning token.

@weitzhandler
Copy link
Contributor Author

There is the leftshift operator which is a double << - invalid as XML literal anyway

@gafter gafter added this to the When Heck Freezes Over milestone Apr 2, 2015
@gafter gafter changed the title Time for XML literals and embedded expressions in C#?? Proposal: XML literals and embedded expressions in C# Apr 2, 2015
@Przemyslaw-W
Copy link

AFAIK c# paradigm is to stay away from technology specific features. So I
doubt we'll ever see xml literals or json literals built into the language
itself. I think this is also a reason we don't have close to the metal
support for INotifyPropertyChanged.

2015-04-02 2:19 GMT+02:00 Shimmy [email protected]:

There is the leftshift operator which is a double << - invalid as XML
literal anyway


Reply to this email directly or view it on GitHub
#1746 (comment).

@weitzhandler
Copy link
Contributor Author

Although I understand that, I wouldn't say XML is as tech-specific as INPC, INPC is widely used in XAML apps, but not used in ASP.NET at all. Same applies to JSON, which is only web-specific.
ITOH, XML is a general means to store and retrieve tree data, and is widely used in every single platform that's built on top of C#.
So I still vote YESSSSS.

@weitzhandler
Copy link
Contributor Author

OH that OverOurDeadBodies label LMAO! Right on fools day night! HAHA!

@weitzhandler
Copy link
Contributor Author

when heck freezes wtf hahahaha

@davepermen
Copy link

Hmm I use json outside of webdev all the time. I never use XML anymore. So no, it makes no sense to support one specific tech over the other.

@davepermen
Copy link

Instead, transpilers like jsx (XML inside JavaScript) or razor (c# inside html) would be more flexible off the main language projects.. Something like csx (XML inside c#) as an own project instead?

@dsaf
Copy link

dsaf commented Apr 2, 2015

How about this:

var contactDoc = XML(@"
    <?xml version=""1.0""?>
    <contact>
      <name>Patrick Hines</name>
      <phone type=""home"">206-555-0144</phone>
      <phone type=""work"">425-555-0145</phone>
    </contact>");

Where XML is your custom imported static method:

public static class XmlExtension
{
    public static XmlDocument XML([XmlString] string xml) { /*Logic*/ }
}

...and XmlStringAttribute is used by Roslyn to highlight and process the string the way ReSharper handles custom string formatters?

http://www.jetbrains.com/resharper/webhelp80/Code_Analysis__String_Formatting_Methods.html

image

@MgSam
Copy link

MgSam commented Apr 2, 2015

@gafter I love the "Over Our Dead Bodies" label and "When Heck Freezes Over" milestone. Responding entirely through metadata.

@weitzhandler
Copy link
Contributor Author

Yeah my wife woke up from my laughter this morning...

Anyway @dsaf I believe you never actually saw how XML literals works and
feels in VB.
Wrapping it in quotes is missing the whole point.
Am I the only over around heavily using XML? Am I the only one who got to
taste VB literals?

Sent from my Android
On Apr 2, 2015 4:23 PM, "MgSam" [email protected] wrote:

@gafter https://github.com/gafter I love the "Over Our Dead Bodies"
label and "When Heck Freezes Over" milestone. Responding entirely through
metadata.

Reply to this email directly or view it on GitHub
#1746 (comment).

@MgSam
Copy link

MgSam commented Apr 2, 2015

I think there's a few reasons this wouldn't happen:
a) XML is out of favor now in favor of lighter protocols like JSON.
b) Adding embedded DSLs into a language has a really high bar to get over. LINQ query comprehension syntax is the only case where anything has passed this bar for the C# team.
c) There are other, more general features which probably mostly satisfy this need. I've proposed before adding block quotes, which would allow you to paste in XML (or anything else) without the need to escape any characters at all. Others have suggested having user-defined string delimiters to achieve a similar outcome.

@AdamSpeight2008
Copy link
Contributor

I think the tag should be Over Ander's Dead Body

@AdamSpeight2008
Copy link
Contributor

@dsaf VB.net has language support for XML-Literals.So for example if if rename a node, put forget to alter the closing node. It is a compile-time error. If you also import the schema you'll get intellisense support as well.

@HaloFour
Copy link

HaloFour commented Apr 2, 2015

Everything old is new again: 😄

Cω - Content Classes Tutorial

@AdamSpeight2008
Copy link
Contributor

@weitzhandler
<variable

Is that:-

  • a less than sign followed by an identifer;
  • an incomplete xml node?

You could always fork and implement it in your own flavour of C#, or use COmega.

@bondsbw
Copy link

bondsbw commented Apr 3, 2015

@dsaf So here's a thought... there has been some discussion about making the string interpolation mechanism extensible using prefixes, e.g.

var xml = XML$"<?xml version=""1.0""?>
    <contact>
      <name>Patrick Hines</name>
      <phone type=""home"">206-555-0144</phone>
      <phone type=""work"">425-555-0145</phone>
    </contact>";

A benefit of extensible string parsing is that XML$ could hook into the IDE and provide the syntax highlighting and intellisense that XML literals enjoy in VB.

Similar extensions such as JSON$ or YAML$ can also be created by the community.

@drake7707
Copy link

Just use the razor engine, that way you won't clutter your code with xml bloat and you still have the expressiveness that comes with model binding in an xml view.

Example: http://stackoverflow.com/questions/5943396/how-do-i-output-xml-with-asp-net-razor
And https://github.com/volkovku/RazorTemplates to use it without MVC or ASP

@gafter gafter removed this from the When Heck Freezes Over milestone Apr 5, 2015
@dsaf
Copy link

dsaf commented Apr 8, 2015

@AdamSpeight2008

...for example if if rename a node, put forget to alter the closing node. It is a compile-time error. If you also import the schema you'll get intellisense support as well.

As far as I understand Roslyn can tackle both without altering C# syntax.

@aluanhaddad
Copy link

If support for something like this is added I would very much prefer a generalizable approach like the one @bondsbw mentions. Also, I use JSON outside of web projects all the time.

@weitzhandler
Copy link
Contributor Author

XML literals, are recognized as part of VB.NET.
Giving language-level support for any tree-based technology would lead to an endless demand of support for various mechanisms like XML, JSON, and other blob architectures and mechanisms, that who knows how long those technologies are to last anyway.

And @davepermen regarding #1746 (comment) that XML is out of fashion, yeah I agree that XML might be too verbose, but don't forget that it has schema, attributes and other very important feature support that JSON lacks.

That being said, I believe the solution should be agnostic, and there can be support for tree-data in a root/element/attribute way, bound to the language. There should maybe be support to map objects to a schema (see here how it's done in VB.NET)
Then, the support for serializing those trees to XML, JSON, Redis is already a matter of provider implementation. So this should be really be thought thru to be able to comply with the major tree based techniques already existing, namely XML, JSON, Redis and other NoSql .NET client capabilities etc.

Here's some pseudo prototyping out of my brains stack.

var people = new dynamic
//anything under dynamic can be either exsiting objects
//or gets interpreted as dynamic
{       
  LastAccessDate = DateTime.Now,
  People = new[] {
    new Person //Person isn't declared it's a pseudu dynamic object
    {
      FirstName = "John",
      LastName = "Doe",
      Children = new[] {
        new Person
        {
          FirstName = "Ed",                
          Address = 
          new Address
          { 
            City = "New York",
            //primitive types are always parsed as attributes,
            //unless explicitly specified
            [Element]
            Country = "USA"
          }
        },
        new Person
        {
          FirstName = "Beth",
          LastName = "Doe",
          BirthDate = DateTime.Now.AddYears(-20),
          Spouse = new Person
          {                                      
            MaidenName = "Washington"
          }
        }
      }
    },
    new Professor : Person //???
    {
      LastName = "Einstein",
      Phone = new Phone
      {
        Type = PhoneType.Home, //???
        Number = "911"
      }
    }          
  }
};                       

And here comes the most important part.
Please learn a bit about LINQ to XML in VB.NET, and XML manipulation in VB.NET.
Although XML is indeed very comprehensive I'm sure this pattern can be generalized. And I say most important part, because the searching capabilities in No-Sql is even more important than being able to define it on the fly.

var doeFamily = x.People...<Person>
                  .Where(p => p.@LastName == "Doe")
                  .OrderBy(p => p.@BirthDate);

foreach (var doeMember in doeFamily)
  Console.WriteLine("{0} {1}", doeMember.FirstName, doeMember.LastName);

var allPplWithPhones = x...<Phone>.Select(p => p.Parent());

So this could be great in C# having an in-language option to walk thru children of dynamic objects by property name/value etc. etc.
The precise standards could be different than VB.NET and unbound to XML or any other technology, but the mechanism is very useful and compelling.

This might open a whole new convenience in storing, accessing, and manipulating NoSql data. Giving options for implementation of Linq to NoSql for databases like Redis etc.

And I quote from the previous link on how VB.NET provides support for accessing XML:

Property description | Example                 | Description
------------------------------------------------------------------------------------------------
child axis           | contact.<phone>         | Gets all phone elements that are child elements
                     |                         | of the contact element.
attribute axis       | phone.@type             | Gets all type attributes of the phone element.
descendant axis      | contacts...<name>       | Gets all name elements of the contacts element,
                     |                         | regardless of how deep in the hierarchy they 
                     |                         | occur. 
extension indexer    | contacts...<name>(0)    | Gets the first name element from the sequence.
value                | contacts...<name>.Value | Gets the string representation of the first 
                     |                         | object in the sequence, or Nothing if the 
                     |                         | sequence is empty.

@MadsTorgersen
Copy link
Contributor

Per #3912 we are probably never going to do this. We aren't comfortable tying C# to a specific format like that.

@bjorn-ali-goransson
Copy link

@MadsTorgersen, I can't stop myself from wondering why we included an SQL-variant syntax for LINQ if we are not comfortable tying C# to a specific 3rd part language - in all cases, XML is more integral to C# than SQL...

To be constructive, what I'd like to see is the equivalent of NuGet packages enabling inlining of different languages, JSON, XML, HTML ...

@leppie
Copy link
Contributor

leppie commented Apr 8, 2016

@bjorn-ali-goransson Then it is not longer C#. XML (and the Xpath, XSLT family) is merely an different syntax of Lisp/Scheme.

@HaloFour
Copy link

HaloFour commented Apr 8, 2016

LINQ query syntax is only SQL-like, it's not SQL and it doesn't tie C# to any outside language/format specifications.

I think that when integrating logic with wire formats like XML, HTML or JSON that a templating engine like razor makes more sense.

@bjorn-ali-goransson
Copy link

If it's possible, then to interpolate C#-values in XML like we do in strings in C#6 would be nice and very time saving, especially if it could be done through some pluggable mechanism ... But then again, it would be quite far-fetched to hope for that the infrastructure would allow this without major changes.

@svick
Copy link
Contributor

svick commented Apr 8, 2016

@bjorn-ali-goransson I'm not quite sure what you're asking for, but maybe the FormattableString support that already exists in string interpolation could be helpful?

@VBAndCs
Copy link

VBAndCs commented Apr 7, 2019

This proposal may make it introducing any script syntax to C# syntax: #34821

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