dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
288 stars 66 forks source link

What's syntax or feature you would like to create for VB or .net ? #587

Open RevensofT opened 3 years ago

RevensofT commented 3 years ago

Pointer

One of syntax I don't think it going to be apply to VB.net by MS is pointer , I half agree and half disagree with this decision because it's hard to guarantee its safety but it also give you a lot of performance if you use it right.

This is latest version I created and use. https://github.com/RevensofT/STD

ref(Of T) type

A new type for unsafe pointer, it's value of reference type aka it's value type but invoke by method as reference type.

Constructor via extension method

ref(Of T)(ByRef Input As T) As ref(Of T)

Create pointer from target, field of class and element of array are most safe pointer you can create without any concern, pointer of local var and value type should be use within their life cycle.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base(0).ref

Property

value As T

Get and set value via pointer, simply ldobj and stobj.

A.value = 8

Default Readonly index(Offset As Int64) As ref(Of T)

Move current pointer to other index offset of T unit.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base(1).ref
Dim B = A(1)

'A.value is 2
'B.value is 3

Readonly range(Destination As ref(Of T)) As Int64

Measure distance between this pointer and Destination pointer in T unit.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base(1).ref
Dim B = Base(4).ref

'B.range(A) is 4

Shared size As UInt64

Get size of T unit.

'ref(Of Int64).size is 8
'ref(Of Int32).size is 4

Method

Sub copy(Destination As ref(Of T), Length As UInt64)

Copy data from this pointer to Destination pointer.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base(0).ref
Dim B = Base(3).ref

A.copy(B, 2)
'Base is {1, 2, 3, 1, 2}

Function change(Of V)() As ref(Of V)

Get new pointer of V type point at the same address as this pointer.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base(0).ref
Dim B = A.change(Of Int64)

B.value = 0
'Base is {0, 0, 3, 4, 5}

Unsafe cast type

Other thing I'm would love to have but hate to live with is unsafe cast , DirectCast and CType do a good job to keep a code safe but also give me no other way to cast some type I know it fine like cast base type to inherit that only add method without touch field.

as(Of T, V)(Input As T) As V

Unsafe cast type on .net, you can cast object to any type, doesn't matter if it ref type or val type, highly cause an error if you don't know what are you doing.

Dim Base = {1, 2, 3, 4, 5}
Dim A = Base.as(Of ref(Of Intptr))

'A(1).change(UInt64) is 5, aka Base.Length
'A(2).change(Int32) is Base(0).ref

Stack frame allocate memory

Only 2 way I can think to create it until now is create a local var of structure and reference it via pointer to simulate is like stack alloc and other way is localloc aka stack alloc via method and use it on other argument method delegate, first one is uneasy to create a large alloc and second one request 2 extra stack frame to do it, cost over performance.

rskar-git commented 3 years ago

@RevensofT The moment you begin to make use of pointers is the moment you bring a world of hellish trouble. They are a necessary evil for very specific situations, but 99% of the time you don't need them and are better off without them.

Of course, behind the scenes, inevitably the compiler will generate code that makes use of pointers. That is perfectly fine, because any given compiler will be designed and tested against a very specific architecture; it will be up to the compiler designers to get everything critical done correctly. It can be a hellish landscape to properly navigate: padding, caching, byte-order, thread safety, etc.

But with pointers, one must be super-mindful and disciplined to do it right, and not for much gain versus the alternatives of properly designed language constructs and libraries. Actually, performance with pointers can be worse - see https://stackoverflow.com/questions/5374815/true-unsafe-code-performance.

Have a look at https://gitter.im/VB-NET/HowTo - it is possible to do ref types and pointers in VB.NET via MemoryMarshal. It is, of course, somewhat risky to do so, since the VB.NET compiler wasn't designed with these possibilities in mind. But it can be done.

So the one thing that would be nice is if the With statement could be safely used with a ref type (as maybe returned by a function).

rskar-git commented 3 years ago

Note that the With statement, even in VBA/VB6, essentiallly sets up a situation equivalent to a C# ref struct. I think we should extend this capability, so how about: With ByRef? An extension to the With statement block which allows for a list of one or more named references. E.g.:

Dim Base = {1, 2, 3, 4, 5}
With ByRef A = Base(1), B = Base(4)
    A.copy(B, 2)
End With
Echo-8-ERA commented 3 years ago

Weren't pointers/unsafe code one of the things that was specifically mentioned that MS was opposed to adding to VB.Net?

I personally would love to have pointers, as it would make interop with unmanaged libraries easier without resorting to ungainly workarounds or writing wrappers in another language.

rskar-git commented 3 years ago

@Echo-8-ERA

...pointers...would make interop with unmanaged libraries easier...

No, not necessarily, because a pointer is an architecture dependent thing (and part of a grander scheme known as a memory model). Of course, most of the time we're looking to interop with C/C++ libraries, so it's usually a matter of coming from other languages and contorting the code as needed to seem as C/C++ like as possible. (See https://stackoverflow.com/questions/6319146/c11-introduced-a-standardized-memory-model-what-does-it-mean-and-how-is-it-g)

The other major interop issue is calling conventions, which can't be helped without direct access to the stack and/or CPU registers (so it must be a language feature). Pointers offer nothing here. (See https://stackoverflow.com/questions/949862/what-are-the-different-calling-conventions-in-c-c-and-what-do-each-mean)

Anything else that a pointer might seem particularly handy for, such as stepping through arrays or naive type casting from raw, can be done well enough via API or language constructs.

RevensofT commented 3 years ago

@rskar-git
I believe in choice, instead force to do or not to do I believe give a choice for user to use it or not is much better, if they deem it going to be more trouble then help then they can choose not to use it but if they deem it more help then they have a choice to use it.

About custom statement, I'm not touch on this subject after I saw someone try to create new language on VS on Youtube and they have to fall back to use System.Reflect.Emit.DynamicMethod so I stop invest my time on this subject, anyway I don't agree with unsafe statement on C# so even if I can I'm not going to bring it to VB, it's much better to safety check when interactive with pointer like DirectCast then make a sandbox scope to contain it.

By the way, your issue #231 , if it can be a new VB keyword, it would be nice; this is what's I use (it's a lot easier to read for me then full code it).

    '''<summary>Update var.</summary>
    <Extension>
    Public Function be(Of T)(ByRef Input As T, Value As T) As T
        Input = Value
        Return Input
    End Function

    '''<summary>Set input var to this value.</summary>
    <Extension>
    Public Function via(Of T)(Value As T, ByRef Input As T) As T
        Input = Value
        Return Value
    End Function

    '''<summary>Update var after using it.</summary>
    <Extension>
    Public Function [then](Of T)(ByRef Input As T, Update As T) As T
        Dim Out = Input
        Input = Update
        Return Out
    End Function

@Echo-8-ERA Yes, it was, that why I and other coder create it, some maybe fork VB.net to add more feature; by the way, do you have anything you frequency use on other language and you think it would be nice to have it on VB.net ?

rskar-git commented 3 years ago

@RevensofT

I believe in choice...

Don't we all!! :)

Just look at all the fun choices programmers have made over the years!:

  1. https://blog.codinghorror.com/new-programming-jargon/

  2. https://www.reddit.com/r/programminghorror/

  3. https://www.cs.cmu.edu/~charlie/courses/17-214/2019-fall/slides/20191203-anti-patterns.pdf

  4. https://softwareengineering.stackexchange.com/questions/56935/why-are-pointers-not-recommended-when-coding-with-c

etc. etc. etc.

RevensofT commented 3 years ago

@rskar-git It's normally, isn't it ? When people has a freedom, some might do something stupid, some might do something harm themselves but it's also a beautiful of freedom, isn't it ?

By the way, I don't see you talk about unsafe cast type , can I assume you agree with it ? :) And have you had any feature or syntax you want to create for VB or .net ?

zspitz commented 3 years ago

(I hadn't realized this was a general question; I thought it was devoted to pointers etc.).

My wishlist of features for VB.NET (from easier/more likely to harder/less likely):

paul1956 commented 3 years ago

If I had one vote it would be for changing the TypeOf Is SomeType Syntax to allow a definition of a local variable of SomeType as part of the test. Not a fan of #172 as a solution to the issue. #337 might be a superset. It seems there are may open issues related to this one concept with different names. If #277 is a bug and not a new feature it should be fixed, if its not it should be closed.

zspitz commented 3 years ago

@paul1956

Not a fan of #172 as a solution to the issue.

Could you elaborate on this? Of the list I've mentioned, it's the only one which doesn't require any new syntax, but simply gives the compiler some new information. But it sounds as though you have some objection in principle.

I feel that if I've checked the type of the local variable against a derived type, I shouldn't need to create a new variable of the derived type in order to use members of the derived type. To my mind, that is the issue which #72 solves.

337 might be a superset.

Personally, I think pattern matching stands on its own merits, beyond multiple type checks -- instead of multiple If ... Then ... Else If blocks, I present one or more cases, and the first matching one executes the corresponding block. It's a more declarative form.

If #277 is a bug and not a new feature it should be fixed, if its not it should be closed.

It's not a bug in the sense of "the compiler/runtime is behaving oddly". But VB.NET is English-like in syntax, and even though some parts range from the sensible (If Foo.HasValue Then) to nonsensical (ParamArray), this particular syntax is actively misleading.

Imagine if Foo Implements Bar meant "Foo inherits from Bar" and Foo Inherits IBar meant "Foo implements the IBar interface". Would that be considered a bug or a new feature?

paul1956 commented 3 years ago

@zspitz #172 is confusing when you read the code, the examples are close to the TypeOf but if they are further away it is easy to get confused. Also is the Obj still a string, if somewhere below I set it to an integer? I like the C# model to create a new variable. How would intellisense work?

I agree pattern matching stands alone, but to me the compelling use case to me is to solve above. VB already has some pattern matching, and how would this new one work with what exists.

I don't think #277 is going to change, but the issue should be addressed or closed.

zspitz commented 3 years ago

@paul1956

the examples are close to the TypeOf but if they are further away it is easy to get confused

I think this is an occupational hazard of any long code where variable usage is far from the declaration. This is mitigated somewhat when working in the IDE -- I usually hover over the variable to display the type in a tooltip, or press F12 to jump to the declaration. Both of these could be modified for typecheck inferred types -- the tooltip could display something like String (Object), and F12 could go to the typecheck where a second F12 would go to the declaration.

is the Obj still a string, if somewhere below I set it to an integer

At that point, no; at least the way Anthony suggests it, the type of Obj will revert to the original Object. (I don't entirely understand why the Integer assignment couldn't alter the type to Integer (Object), but it seems as though there are technical difficulties in doing so.

How would intellisense work?

As if the variable under question was of type String. And for multiple typechecks, such as two interfaces or a class and an interface, as Anthony notes in that issue, there's already precedence in generic constraints to allow members from multiple types.

rskar-git commented 3 years ago

@RevensofT

When people has a freedom, some might do something stupid...

...where the harm isn't limited to themselves, and ends up doing great harm to many others. Buffer overruns, for starters...

I don't see you talk about unsafe cast type...

I most certainly did, although I used the phrase "naive type casting from raw". They are fine by me, generally, and can be done well enough via API or language constructs (pointers not required).

have you had any feature or syntax...

Yep, suggested above, With ByRef. (https://github.com/dotnet/vblang/issues/587#issuecomment-753683040)

BTW, I cannot see any code at RevensofT/STD, only README.md and LICENSE.

RevensofT commented 3 years ago

@rskar-git An employer/corporation already has power to decide how to code, their reputation are link with finish program so I believe only those code for fun are fit your worry which they already warn people before use their code.

About RevensofT/STD code, I write it in IL directly so if anyone want to look at code just iladsm release dll, I write template in VB.net and compile it then iladsm for source.il, write method code in MSIL/CIL then ilasm back to dll; however somehow it missing those remark and summary I write on template code even I already include/res=source.res .