-
Notifications
You must be signed in to change notification settings - Fork 65
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
Discussion / proposal: usage of any installed programming language #211
Comments
I’m glad you like the idea, although it would be problematic to compile to separate assemblies, as you would lose access to the private members without using reflection (unless the compiler can sneak around that limitation) As nice as that syntax is, and how powerful it could be, now I think about it, I’m not sure how one could solve the issue of cyclic dependency if the VB code needs the c# code and the c# needs the vb code how would it be able to reconcile it. Maybe someone a lot smarter than me would know a way, but I am far from qualified for that, just the thought of it make my brain meltdown.. |
@TrendyTim |
AS I think of it, the out string vbVar would not work, bacause it updates the var after the call to MoreVBCode. So it should be implemented as "fieldInfo vbVar" and updated using reflection. |
When you consider compiler directives, imports/using statements, etc, partial classes and one language per partial class code file is probably more functional. |
@Bill-McC @TrendyTim VBCode:
The following CS code is generated:
The CS code in the VB file is converted to the following generated code:
A call to (new Test).Main() now shows a messagebox with the text "From C#" |
Separate code file in the same project, not separate projects.
|
@Bill-McC |
I don’t see how having the language separated by blocks is anyway easier than separate by file. For anything other than trivial, you really need the file structure, e.g. Imports vs Using.
You could also add compiler directives, either to the code file, or a project file (sub-project file)
.
|
Either way is acceptable for me, inline or language by code file (I would prefer the possibility to use both). The bottom line is that I think we should be able to mix the capability several languages, to be able to use the right language for the right job; for example using unsafe methods in C#, functional programming in F# and that all while building the bulk code in VB. |
I love the idea of mixing languages in a project, I don't need in a file. Virtually every real VB project I work on has a C# Project to handle some Unsafe Code. Maybe Span(Of T) someday will fix this. Today VSIX projects seem to be able to compile C++ code in the vsct file. One specific example is the Hash Class from Roslyn, which I need to use in one of my refactoring's and it is marked Friend. It is extremely difficult to if not impossible to implement in VB. So I had to create a project, rename the namespace and class to avoid conflicts, and track changes in the Roslyn version, all extra work. |
@tverweij Not bad, it probably comes at a little performance hit, but generally its probably not going to be a big deal, would still be nice if it could be in the same assembly for lower overhead/ and fewer files for deployment (perhaps if it did an IL merge or something). Its not quite as nice as just compiling each block to IL and having it render out one class in IL that came from two languages (if thats even remotely possible), but it gets the job done. @Bill-McC Both methods have their pros and cons the biggest pro of inline is you don't have to context switch, if it was in a separate file and we could do partials have to ensure case sensitivity of class names and translate the access modifiers correctly which may be a little tricky for people not well versed in both languages to keep them in sync, if partials weren't supported its another helper class that's required, and you lose easy access to private members. If you have C# files in the project you might end up with some confusing assumptions like folders in c# give you automatic namespaces (something i WISH vb .net did, the number of times i forget to add namespaces because of that (even though i do almost all my work in VB i suppose i live in denial that C# has a lazy programmer feature that VB doesn't). You also have the context switch of going to another file to work on the same class and you may also find yourself going back and forth a lot. Sometimes i want to have one method in C# because it offers features that for some reason VB doesnt (like dynamic types or unsafe code, but only wanted it in one method, other times a whole file might be useful to be in C# like back when webapi was almost impossible to use in vb) So long story short, both would be awesome, and technically if inline was done, separate files would be as well by association (just that it could allow for the default language from the file type). Though i image a new project type would be required to be able to configure language specific options (but hopefully most things can be unified, C# projects have some things that would be nice in VB projs and vice versa if i recall) Either way i would still be a happy camper, and all .Net languages could work together in perfect harmony. |
@tverweij There is an implicit assumption here that |
Actually how’s this, a combination of both methods, building off of what @tverweij did, what if when support for multiple language files in same project is added, the #Language directive region generates a language file of the same name but that language ext (either virtually, temporarily or as a “subordinate” file like the .designer files, perhaps as filename.generated.cs or filename.mixedlang.cs). If the language directive is inside a class it could automatically generate the partial class (and any needed namespace) as appropriate (also means to enable #Language inside a class you need to make it partial). If it’s outside a class it just “moves it” verbatim though ensuring the namespace (assuming one would want to support that modality). Any imports/using would need to get converted into the auto generated file as well and of course I don’t think supporting it inside a method is valid (nor modules because you can’t have partial modules as far as I know). That way we get best of both worlds, with little extra work. Edit: just to clarify that’s not to say that anyone can’t add te other language file themselves, this would just builds on that as an added ease of use. But as i said before it would be nice but not necessary for inline, I’d take what I can get. @AdamSpeight2008 not really, here #Language is assumingly talking about vb, it can of course be whatever the default language (ie file type) defines it to be, c# or f# may just want is as #lang VB |
Why do people hate managing two projects and two DLLs so badly? |
@TrendyTim |
@AnthonyDGreen I guess if you don’t hate already you won’t understand, seems overkill to add a new assembly for 30lines of code. @AdamSpeight2008 I’m not so sure that’s true, as the default language of the file (in this case VB) is what parses the directives and would extract the whole C# block and C# would never see that directive (start or end) |
This is more than just utility methods in another library. There's times you just need a bit of c# code but you want it in the same class, accessing all the private fields; There's times when you just want to paste in some code, but the sample is in c#; And there's times when major frameworks are available in c# only, so to modify or extend them you are forced to use c#, and we know of many folks who have gone there and have just given up trying to do the integration with vb.
Get Outlook for Android<https://aka.ms/ghei36>
From: Anthony D. Green
Sent: Sunday, 3 December, 7:11 am
Subject: Re: [dotnet/vblang] Discussion / proposal: usage of any installed programming language (#211)
To: dotnet/vblang
Cc: Bill-McC, Mention
Why do people hate managing two projects and two DLLs so badly?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#211 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AID_hMWE-FYCx_c3BeWKtNHM_HBCRH0Sks5s8a8BgaJpZM4QyRYj>.
|
@AnthonyDGreen try recreating Hash from Roslyn in VB and you will see the frustration. There are Namespace issues that I don't know how to solve, name conflicts, Unsafe Code, private functions.., The code is marked Friend so I can't access it directly from my project (why it isn't public is another question because it is called from all over Roslyn and many thing can't be easy implemented without it). It seems that VB integration keeps getting 99% of the way there and a minor issue breaks everything (and I am forced into C#) being able to do this at least gives an easy workaround. |
@AnthonyDGreen wrote;
It's all about manageability and readability. A complete project for one or two methods is overkill. |
Offtopic: @paul1956
Just use reflection for it - solves all those problems; I have standard CallMethod, SetProperty, GetProperty, SetField and Getfield methods to get around all unnecessary encapsulation (the .Net framework is full of it). |
Only if you don't care about performance.
Once this is implemented, yes, it might be an "easy" workaround. But actually implementing the ability to use multiple languages in one project is a long way from being simple. This would be an enormously complex feature that Roslyn doesn't really seem built to support. |
@reduckted |
I must have missed something. How is resorting to reflection, dealing with various security implications more productive than just having the code there in thge language it was written? |
@Bill-McC But all of this is off-topic. The topic is the wish of having multi- language support in one project. |
@AnthonyDGreen asks: "Why do people hate managing two projects and two DLLs so badly?" This is not about hating on multi-project solutions. It's about being forced into the use of a DLL as a work-around for what should be a trivial matter if only the language of choice was able to achieve the desired effect (efficiently) on its own. At that point where one is forced into another DLL, one must be resigned to making various somethings Public (so that your main assembly can make use of the now-necessary satellite DLL) that you otherwise would prefer not to, and the possibility of missing out on whatever optimizations the compiler might have done if all the desired functionality was in the same assembly. Probably the top two frustrations on this front are: (1) mixed use of checked and unchecked integer arithmetic; and (2) access/usage of C# libraries when there are issues of case-sensitivity and method signatures. I'd bet if these two items were (thoroughly) addressed, this idea of multi-language DLL-free mix-ins would be so less compelling. But, for the record, if there was a way found to knit another language into a VB project, the only one I'd care about would be F#. |
@rskar-git / @tverweij My point is this how do you work out which is the correct 'In VB project: MultiProgrammingLanguageTest
Public Class TestClass
Private vbVar as String = "From VB"
#Language CS
public void Main()
{
string CsString ="
#If foo_enable Them
#End Language
#EndIf
";
vbVar =CsString ;
MoreVBCode();
}
#End Language
Sub MoreVBCode()
Msgbox(vbVar)
End Sub
End Class Also what about |
@AdamSpeight2008 that’s the easy part, the same way #if and #region work the directives have to be at the start of the line. To prevent any cross language parsing issues I’d assume you can’t have nested #language directives, I think a .net terducken (turkey stuffed with a duck stuffed with a chicken) would be going too far anyway, 2 levels would be fine if you ask me. |
@TrendyTim Easy? Are you sure? I've updated the example. |
@AdamSpeight2008 Ok good point, frankly I’d be happy to concede that limitation that I can’t start a line with a #End Langauge as part of a multi line string in the foreign language as an inline block (need to use foreign language file for that if it’s that important) Maybe at some point the feature could advance enough to support it (like having the foreign parser communicating back to the host language parser) but that is an extreme corner case, and I can’t imagine many people complaining they can’t do that, so it really worth the effort, unless someone has a genius and yet simple idea) |
@TrendyTim how about we just get project to work first and then file then worry about nested, because I am sure I will be 100% retired before then and I think mixed projects solves 99% of the issues. I am surprised that with the new project system more wasn't done to enable mixed languages. |
@bandleader Speaking for myself: Yes. I use Telerik's converter quite often, because I want to use code samples or libraries documented solely in C#. An example is Quartz.NET, an excellent package. I used Telerik's site to convert their sample code into something I could work with in VB. There were some hiccups but it saved me a lot of frustration and time dealing with C#, which I am... fairly rusty at interpreting. Quartz.NET's Quick Start: https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html My savior: http://converter.telerik.com/ |
@ocdtrekkie I've found the problems with that translation approach are there are often bits that don't get translated properly, so a fair bit of time has to be spent testing the translation and fixing parts. It's not just plug in and go. And the second part is when the libraries get updated you have to go through step 1 all over again.. and that can add up to days of lost work really quickly. |
@ocdtrekkie @rskar-git It's very interesting to hear that some VB users use a C# translator on a regular basis! Hard for me to relate, but I guess we're not all the same after all! 😃
I had assumed so, unfortunately. (In my compiler design, this is done in one place.) However, instead of re-implementing everything, couldn't you just make the |
@Bill-McC I definitely usually have something to fix coming off the translator, but it's a lot better than starting from scratch. @bandleader Will give it a try next time! |
That is exactly what we did at the inception of the Roslyn project way back in 2009. We took this very question as one of the key design points that had to be decided right at the start of the Roslyn project, because it has an immense impact on the shape of the compiler internals. We thought about it over the course of a few weeks and discussed it in meetings for hours. In the end we decided not to do it because it would have added a large implementation cost (and uncertainty of success) to the project. The Roslyn code base was written under the assumption that we would not be mixing languages within a single project.
The |
@bandleader I've personally not made much use of translators; my C# knowlege is pretty good, and hand-coding C# examples into VB is something I consider as part of my own self-education. There are others who want to do things in VB, and don't know much C#, yet are eager to learn new things and get going with their own VB coding. Since so many .NET examples are done in C#, they make use of translators to get VB examples. This came to my attention via StackOverflow (e.g. https://stackoverflow.com/questions/45552216/bitcoin-blockchain-parser-c-sharp-snippet-to-vb/). My own hand-coding efforts involve maybe a few pages or less of code. However, if it were my job to regularly transform C# code into VB, you can be assured that I would be using a translator a lot then.
They probably wouldn't necessarily do the translations themselves, but a lot of these open source projects do welcome volunteers. I'd bet a VB'er who also knows C# could refactor the emitter issue; and utilizing a translator, quickly churn out VB templates. There are only two pain-points I can see here. The first (where they haven't a care or concern for the Common Language Specification) is employing some sort of case-sensitive naming scheme to their public and protected identifiers. But then that could be addressed by giving VB a way around that (perhaps with square brackets and @? e.g. C# protected foo and public Foo can be distinguished in VB as I don't know what to say about closed source and commercial projects, or the apparent wavering at MS. But I wouldn't hang hopes on MS embarking on this multi-language mix-in. |
This is a hard discussion. I believe the decisions made at the start of the Roslyn project were not only to help ensure the success of Roslyn, but also to ensure that VB could implement the things best for VB (and C#) in the future, because that was the language strategy of the day. It's easy to forget how amazing the Roslyn conversion was - they switched out our compiler and we barely noticed - from an incomprehensible one. We spent more time discussing mixed language in yesterday's VBLDM. We looked around the issue again - which has been looked at many times - and we have no reason to think the previous assessment (summarized by @gafter ) has or will change. I'm going to leave this open for now for clarification on this specific issue. But I would like to shift conversation to doable things that can provide value to VB developers - including some of the mitigating features discussed in this thread. Things blocking C# interop, wider understanding of "InternalsVisibleTo" and patterns to avoid circularity when projects are used to isolate languages are all discussions that may bear useful fruit. I anticipate closing it as "won't fix" in a few weeks. If something changes, we'll start over. Most are all of the folks on the language team, including myself, wish this were different, but it just isn't a feasible change. |
@rskar-git In the above Quartz.NET example, I did offer that if they added a tabbed code preview to their website, like Microsoft's docs, I'd be happy to contribute working VB sample code. |
@KathleenDollard That is bittersweet, its upsetting we will never get a nice unified language, but hopefully the fact that we want it so much will help drive VB to being more respected by the .net team. I know complete language parity will also never happen, but perhaps
|
@KathleenDollard ; @gafter . If the only issue is case sensitivity, would an option to make VB case sensitive address that hurdle? |
That is not the only issue, only the easiest to explain. |
Case Insensitive removes a lot of potential sources of bugs and errors. |
@AdamSpeight2008 Can you please elaborate on that? What class of program errors are removed by case insensitive? |
User-ability problems, I'm dyslexic, so spelling can be a bit a chore, add in case-sensibility into the mix that my productivity down the drain. Imagine an identifier with my username it us 15 characters, or 1 in 32768 chance of picking the right one with case sensitivity, each time I need to type it. Case Insensitivity make it virtually certain I get the write one. |
@AdamSpeight2008 @gafter More food-for-thought at https://blog.codinghorror.com/the-case-for-case-insensitivity/, http://lambda-the-ultimate.org/node/1114, https://softwareengineering.stackexchange.com/questions/9965/why-is-there-still-case-sensitivity-in-some-programming-languages. I'm OK with either, and can see the advantages and challenges to both. In VB, I'd like to see: (1) A compiler option to enable/disable case-sensitivity for the entire project. This would affect how references into libraries work too. (2) A syntax (particularly for when case-insensitivity is the mode) that indicates a case-sensitive match (I had suggested something like |
@gafter what are the other issues? |
@Bill-McC Even if I could locate them, I cannot share meeting notes from inside a private company (that were not undertaken as part of an open-source project at the time) without extensive review and legal clearance. I'm not motivated to devote a couple of months and lawyers to answering this question.
I cannot enumerate all of the other issues without doing the design work. But just to give you some idea: since we're writing a single compiler for both languages, we'd have to pick an implementation language, as we cannot implement it using mixed languages (if we did there would be no way for us to compile the new compiler). So we'd have to start by throwing away all of the VB code implementing the VB compiler. Also, all of the symbol table implementation code would have to be revised from scratch to have support for the semantics of both C# and VB. Instead of each type containing a single map from name to the members of that name, there would have to be two maps (one case-mapped, and one not). There are other things that are needed on one side or the other, but the result of this is that the symbol table would be significantly larger than it is today, even if you're only compiling one language. That means the compiler would consume more memory and be slower than it is today. Also, since the symbol table API is being overhauled, all of its implementation would need to be overhauled as well, as well as anything that uses it (i.e. most of the compiler). This could be done with a couple of years and the current compiler team devoted to the project. We'd have to stop adding any compiler or language features during this time because (a) we need the engineers doing this so it doesn't take longer, and (b) any new features would have to be added to both the existing Roslyn compiler and this new Roslyn2 compiler. So the question is: does this "feature" rise so high in value that we'd be willing to delay everything else by 2-3 years, and are we willing to slow down the compiler by 20% to accomplish it? Are we willing to have the VB compiler fully written in C# so that Roslyn2 can be compiled the first time by an existing compiler? Are we willing to have the compiler team less invested in VB by virtue of no longer using it in their day-to-day work? Those are some of the considerations, and on balance we decided it wasn't worth it. |
@gafter okay I give up. Looks like this isn't going anywhere even if it is feasible. Regards the symbol table being twice the size, does not make sense to me if one of the constraints was VB was to forgo case insensitivity. |
If indeed it requires a major rewrite and the 2-3 years you estimate -- of course not. But assuming we do find a more viable way to do this (which is the goal of this thread) please also make sure you consider the following.
Let me just be clear and say that I'm not trying to preach to the hardworking Roslyn team, nor demand PR explanations of "Explain why you can't do this!" I just want to make sure this idea is not abandoned for lack of thought or fleshing it out with the right amount of mindpower. (As a project leader, many a time I've thought "we could never implement feature X," and then after a comment by someone -- sometimes even a nontechnical client! -- I'd realize that it is not only possible but the right way to go.) I would be very glad if other members of the Roslyn team could chime in with their thoughts, and/or brainstorm other ways we could accomplish what we're looking to do. Thanks! @KathleenDollard |
We talked about this in last week's LDM (I know, I do not have a streamlined way to do notes, they aren't up, that's a problem, I get that). These folks have been thinking about these problems for years, and agree that if it was free, it might be desirable. I say might, because if it was suddenly free, we would then have a very long discussion of a few key issues. It isn't that case sensitivity is an issue in a few places, unless we have a third compiler, it's that every VB project would have to be considered. Symbols being evaluated differently in two scenarios would be bad, and worse in VB if Option Strict is off (runtime or logic errors, not compiler errors), Then, we'd come to the resulting Frankenstein. Whose overloads rules would win? Will VB have C# impact interfaces in that context? There are hundreds or thousands of small differences between the two, created via 2 decades of independent development. The result would either not really be VB or not really be C#. If we could do this, we could create translators. All the problems with translators would be happening in your compiler. I hope we can soon put our conversations into things that can improve VB itself. |
The dependencies between assemblies is one-way only. In the hypothetical two-language compiler, declaration binding has to handle declarations in two languages, which means binding a C# declaration has to perform binding of VB symbols as a subroutine (to bind types that we can then look up) and vice versa. It is problematic to organize code across assemblies in which recursion needs to happen in both directions between assemblies. Could we build firewalls between the language implementations using interfaces? Possibly, but at the expense of making a huge number of compiler-internal APIs public and paying a performance penalty. Could we hide those interfaces in a private assembly? Possibly, but we'd be shipping a fair number of separate assemblies to do this. Shims in cross-language scenarios don't work well because the symbol table is immutable and contains cycles. Even if we could do all these things, the symbol table (and all of its clients) would have to be overhauled, and that is a huge fraction of Roslyn. I'm not saying it cannot be done. I'm saying the price is high. I agree that the parsers can be kept in separate languages. Same thing for lowering and emit, and binding executable code. But they'd have to be overhauled because of symbol table API changes. I agree that we could reduce memory requirements in non-mixed-language environments by having C#-specific, VB-specific, and mixed language implementations. However, that would be a huge amount of duplicated code and a support nightmare. No, we cannot share common code through base classes because none of the .NET languages support multiple inheritance. Could we use the "default interface implementation" feature to get the effect of multiple-inheritance to make this easier? Sure, if and when that becomes widely available on .Net platforms, but we'd stiff pay the interface performance penalty. Case-insensitive is required for VB code for compatibility. We're not going to break compatibility, so it is a hard requirement, even for "VB code in a C# project". I don't see any reason to distinguish VB and C# projects in this hypothetical world. |
Found this (albeit a bit more general) in Roslyn: dotnet/roslyn#13735 |
I am reopening this because I do not want to end an active conversation because the original poster chose to exit and closed on their way out. While I am very skeptical that this could ever be done, the conversation should not be squashed. |
I can't find the reference (on GitHub) right now but the idea to use the C# scripting engine so VB can execute C# code inline is promising. It may not be fast but in the posted sample example it did work. I have not does extensive work on this solution but if it could be generalized I think it would address a large number of use cases and currently it is less than a page of code. Right now it looks to me like a new script would have to be generate for each usage and that is better suited to the compiler. That said it is more important to me for VB to get missing native functionality, and I will deal with a few modules of C# code to maintain. |
Solved in project Mercury |
@tverweij |
As @TrendyTim mentioned in #46:
I think this would be a very nice construct to use the language of choice (for us here VB) and still be able to use any installed language in the cases where another language better fits the job without resorting to different projects in different languages.
Syntax as proposed by @TrendyTim
#Language CS
#Language C
#Language C++
#Language F#
#Language IL
etc, any installed language should be usable.
Implementation: The #language/#End Language functions should be compiled into a separate assembly using the specific language compiler.
ADDED
In the example above, the call to MoreVBCode would cause a circular reference; The main VB assembly references the C# assembly where Main is defined, and this function needs a reference to the main VB assembly.
To fix this, the call to MoreVBCode should be implemented as a delegate,Invoke.
In the generated C# code, all references needed in the VB Assembly must be available in the generated function call.
The c# function above would get the following signature:
void TestClass_Main(Delegate MoreVBCode, out string vbVar);
The text was updated successfully, but these errors were encountered: