Roslyn: Proposal: Inline Languages

Created on 12 Sep 2016  路  18Comments  路  Source: dotnet/roslyn

Proposal

I'd like to propose an idea for C# 8: inline languages. C and C++ have the __asm keyword which opens a new syntactical scope for inline assembly coding [1][2]. Proposed are such nested scopes in C# 8 for an open-ended set of languages.

Inline languages are envisioned as implemented by .NET components and interoperable with integrated development environments, compilers and debuggers.

Modes of Operation

Three modes of operation are compatible with inline languages:

  1. As per __asm, generates program logic
  2. Generates program logic which generates a runtime object
  3. Embeds a resource into an assembly and generates program logic to load it and to parse it into a runtime object

Advantages

  1. Software quality

    1. Maintainability - suitability for debugging (localization and correction of errors) and for modification and extension of functionality

    2. Readability

    3. Testability - suitability for allowing the programmer to follow program execution (runtime behavior under given conditions) and for debugging

  2. Optimization with MSIL
  3. Complexity reduction in use of nested languages

    1. data languages (XML, RDF, CSV, etc) with IDE features

    2. querying languages (SQL, SPARQL, etc) with IDE features

    3. programming languages (Prolog, etc) with IDE features

    4. special purpose languages (SRGS, SSML, grammars) with IDE features

      Examples


using language __msil = System.Runtime.MsilComponent;

class Example1
{
  void Function()
  {
    int x;

    __msil
    {
      ... x;
    }
  }
}
using language __xml = System.Xml.XmlComponent;

class Example2
{
  void Function()
  {
    System.Xml.XmlDocument x1 = __xml
    {
      <!-- -->
    }
    System.Xml.XmlDocumentFragment x2 = __xml
    {
      <!-- -->
    }
  }
}

Scenarios

Ideas for inline language scenarios include:

__msil,
__xml, __rdf, __n3,
__sql, __sparql,
__pls, __srgs, __ssml,
__antlr, __grammar,
__prolog

References

[1] https://msdn.microsoft.com/en-us/library/45yd4tzz.aspx
[2] https://msdn.microsoft.com/en-us/library/4ks26t93.aspx

Area-Language Design

Most helpful comment

F#:

public void PrintColor(Color color)
{
    return
    __fs
    {
        match color with
        | Color.Red -> printfn "Red"
        | Color.Green -> printfn "Green"
        | Color.Blue -> printfn "Blue"
        | _ -> ()
    };
}

All 18 comments

use PInvoke

@ufcpp related yes, but not quite the same. I am reading this as an idea for effectively a fancy string type which works with some sort of compile time transform as defined by the using language ... statement.

In this proposal it looks like

using language __msil = System.Runtime.MsilComponent;

the syntax using language identifier = type; produces an identifier which at compile time passes the string between { and } into some api pattern on the type specified, which in turn emits the result.

In the case of a hypothetical MsilComponent, there would be an msil parser and the msil instructions would be emitted. In the case of XmlComponent, various calls to other Xml namespace objects would be produced.


While I would very much like to see some way to embed other languages in the same assembly as the one produced by compiling my C# code (currently achievable by ILMerge and certain IL weaving bits), I'm not so enthusiastic about this particular proposal.

6972

@bbarry , @bondsbw , beyond text strings for parsing, IDE features are possible for inline languages, for example syntax highlighting, IntelliSense, linting and corrections, code navigation, debugging and refactoring.

Components like MsilComponent and XmlComponent could also be utilized to support .msil and .xml code editing in the IDE.

F#:

public void PrintColor(Color color)
{
    return
    __fs
    {
        match color with
        | Color.Red -> printfn "Red"
        | Color.Green -> printfn "Green"
        | Color.Blue -> printfn "Blue"
        | _ -> ()
    };
}

Cosmos X#:

public void Execute() {
    __x# 
         {
               ESI = 12345              // assign 12345 to ESI
               EDX = #constantForEDX    // assign #ConstantForEDX to EDX
               EAX = EBX                // move EBX to EAX              => mov ebx, eax
               EAX--                    // decrement EAX                => dec eax
               EAX++                    // increment EAX                => inc eax
               EAX + 2                  // add 2 to eax                 => add eax, 2
               EAX - $80                // subtract 0x80 from eax       => sub eax, 0x80
               BX * CX                  // multiply BX by CX            => mul cx      -- division, multiplication and modulo should preserve registers
               CX / BX                  // divide CX by BX              => div bx
               CX mod BX                // remainder of CX/BX to BX     => div bx
          }
}

The idea is to have intellisense too for the inlined languages?

While we're at it,

class HelloWorld
{
  static void Main()
  {
    __bf
    {
      ++++++++[>++++[>++>+++>+++>+<<<<-]>
      +>+>->>+[<]<-]>>.>---.+++++++..+++.
      >>.<-.<.+++.------.--------.>>+.>++.
    }
  }
}

+

Don't forget ook!

And don't forget about languages that have mismatched curly braces, like J. 馃榾

@fanoI : Wonderful idea! absolutely love it

Converge would be a nice example of a statically typed language with complex syntax (i.e. the exact opposite of Lisp) that nonetheless features both macros and internals DSLs in the style proposed here.

So what is the fate of this proposal?

For Cosmos will be really important to have the possibility to embed X# (x86 assembler) inside C# look what we have to do now:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.IL2CPU/Plugs/Assemblers/Array/ArrayGetLengthAsm.cs

while instead with this proposal we could "simply" do:

        using language __xs = Cosmos.XSCompiler;

        public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // $this   ebp+8
           __xs =  {
                    eax = epb + 8;
                    eax = *eax; // element count
                    push(eax);
        }

I think that to not put too much burden on this the language team should give us a mechanism to make easy to embed languages in C# and maybe the "demo" one that they could implement is MSIL as I suppose themselves could have the necessity to call IL directly in some place.

I add another language that could be interesting to embed in C#: IronPython actually to "compile" an IronPython fragment you have to pass it as string and as Python is so "boring" with the correct indentation having the possibility to write Python directly inside C# would be another plus of this proposal.

Another thing: maybe this issue should be re-opened in csharplang?

@fanoI I think this should definitely be re-opened in csharplang

@AdamSobieski as you are the one that opened the issue here is better that are you to re-open it in csharplang, what do you think?

This issue should be closed since you moved it to dotnet/csharplang#226.

This proposal is similar but with different syntax: #34821

Was this page helpful?
0 / 5 - 0 ratings