Giter Club home page Giter Club logo

Comments (14)

gilfusion avatar gilfusion commented on June 8, 2024 1

I think most of those questions could each almost be a big repo-wide design issue on its own.

Microsoft.VisualBasic doesn't, as I recall, contain any extension methods, so these don't have to be extension methods, either. Also, it's easier and less breaking to add <Extension> later if we decide we want it than it is to remove it if we add it now and regret it. (Fun fact: I believe you sort of can create extension methods on Object or on a unrestricted generic T, and if you do, they will work for every data type--except for Object itself, due to the reason you found.)

As for where to put it, if these methods are meant for general use, we could put increment and decrement in the existing VBMath module, and assignment might fit in the existing Interaction module (Why? Because IIf and Switch are in there.) If these methods are mainly for converting C# code to VB, we could take a page from the Microsoft.VisualBasic.Compatibility.VB6 namespace and create a Community.VisualBasic.Compatibility.CSharp namespace and put an Inline module in there.

As for naming, while I suspect x++ is more common than ++x in general, I don't know which is more common when they are being used inline. Also, Interlocked.Increment is equivalent to ++x, so that would be a precedent to drop the word Before and leave After. I think it would be best to keep both somehow--if you're relying on the return value of this function, it would be best if you knew for certain what it was to avoid off-by-one errors. Again, it depends on if these are intended to be for general use or for converting C# code.

Also, I really don't have a strong opinion on Inc vs Incr vs Increment. There are a lot of three-letter functions in Microsoft.VisualBasic (Rnd, Fix, Int, Val, Str, Hex, Oct, and so on), so Inc and Dec would fit in with that, but any prefix/suffix we add ruins that anyway. Incr and Decr are a little more descriptive while still being short, but the full word is, of course, the least ambiguous. Once again, it depends on if these are intended to be for general use or for converting C# code.

from community.visualbasic.

gilfusion avatar gilfusion commented on June 8, 2024

Sounds like a great place to start. Here's a couple of questions:

First, how important is thread safety? That's a big difference between x+=1 and using Threading.Interlocked.Increment. Without thread safety, it would be easy enough to implement for all the built-in numeric types. With thread safety, we can use Threading.Interlocked.Increment/Decrement for Integer, Long, UInteger, and ULong; we can write our own thread-safe code using Threading.Interlocked.CompareExchange for Single and Double; and I don't know about the rest.

Second (and this might go into bikeshedding territory), why one function instead of two? (Although, honestly, I would almost suggest three: a Sub Inc/Dec, a pre-applying Function PreInc/PreDec, and a post-applying Function PostInc/PostDec.)

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

Wanted to leave a quick comment here letting you know that I'm currently digesting these thoughts and goingt o explore CompareExchange further...

With that, I do have a quick follow-up question... Three? Wouldn't Inc/Dec be the same as PostInc/PostDec - or am I missing a set of scenarios?

from community.visualbasic.

gilfusion avatar gilfusion commented on June 8, 2024

Really, we don't need the Inc/Dec I suggested. I just like it because it separates "I need the old value", "I need the new value", and "I don't care because I'm just using this as a statement"; and it doesn't force the "I don't care" users to pick PreX or PostX. For the translation from C# scenario, it's probably unnecessary, but I thought I'd toss it in for completeness' sake.

from community.visualbasic.

gilfusion avatar gilfusion commented on June 8, 2024

Did a little code tinkering today, and here's a couple of methods. (I picked different names again, because naming is hard, and I kept forgetting which is which when it comes to prefix and postfix ++, let alone the method names I just posted a couple of days ago.)

    <Extension> Public Function IncAndGet(ByRef value As Integer) As Integer
        value += 1
        Return value
    End Function

    <Extension> Public Function IncAndGet_ThreadSafe(ByRef value As Integer) As Integer
        Return Interlocked.Increment(value)
    End Function

    <Extension> Public Function IncAndGet(ByRef value As Single) As Single
        value += 1
        Return value
    End Function

    <Extension> Public Function IncAndGet_ThreadSafe(ByRef value As Single) As Single
        'Get local copy of value
        Dim oldValue = value

        'Get incremented value
        Dim newValue = oldValue + 1

        'Try to update value (fails if another thread changed it since we got oldValue)
        Do Until Interlocked.CompareExchange(value, newValue, oldValue) = oldValue
            'Get local copy of value again
            oldValue = value

            'Get incremented value again
            newValue = oldValue + 1
        Loop

        Return newValue
    End Function

It's been years since I last tinkered with CompareExchange, so that code might not be the best, but I think it works and gets the basic principle across.

I wonder if making increment/decrement thread-safe here is overkill. As far as I can tell, in C#, ++ and -- aren't thread-safe; that's why the Interlocked class exists in the first place. We could do the same here: just implement the naïve version and push people to Interlocked if they need thread safety. On the other hand, Static locals do the work behind the scenes to be thread-safe, so maybe doing the work here is worthwhile.

Next, I may look to see what it would take to add an Object overload that looks for C# operator overloads for ++ and -- (besides reflection and the hidden method names op_Increment and op_Decrement). For that matter, I don't know any meaningful overloads for those operators even exist.

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

I'm not so sure that it's about "thread safety". Something about the Interlocked stuff manages to get things to work "like C#". Meaning that they provide the same behavior and result as the ++ and -- in C#.

Using an x++ in a loop uses the current value of x for the task at hand and upon completion of that task then increments it by 1.

Take the following code:

int value = 1;
System.Console.WriteLine($"({value}) value++ = {value++} ({value})");

The result is:

(1) value++ = 1 (2)

So you can see that value is 1 for the first printed result, is 1 for the second "result" and 2 for the final one. The value.ToString() occurs during the task at hand and is a 1 and after the task is completed, it is incremented to a 2 thus showing a 2 for the final task... all within the same line.

The Interlocked stuff is somehow allowing the same behavior (for a subset of types supported by it). So the goal is to have the "same" code (but in VB) produce the same output...

Dim value = 1
Console.WriteLine($"({value}) value++ = {value.Incr} ({value})")

The IncAndGet that you have above wouldn't produce the same output as the above (which uses the Interlocked stuff). As I said, there's some sort of Voodoo magic happening here...

If you utilize the IncAndGet the output would look like:

(1) value++ = 2 (2)

I was thinking along the same lines and ended up removing all of the overloads since they weren't working as I'd originally thought - but they were very similar to what you wrote.

So I'm wondering if the Interlocked.CompareExchange produces the same Voodoo results, will have to explore this more when I have time.

from community.visualbasic.

gilfusion avatar gilfusion commented on June 8, 2024

All of the methods in my last post, including the ones using Interlocked, were for ++value. (I figured putting all 8 of these methods in one post was overkill.)

Here are the ones I wrote for value++:

    <Extension> Public Function GetAndInc(ByRef value As Integer) As Integer
        GetAndInc = value
        value += 1
    End Function

    <Extension> Public Function GetAndInc(ByRef value As Single) As Single
        GetAndInc = value
        value += 1
    End Function

    <Extension> Public Function GetAndInc_ThreadSafe(ByRef value As Integer) As Integer
        GetAndInc_ThreadSafe = value
        Interlocked.Increment(value)
    End Function

    <Extension> Public Function GetAndInc_ThreadSafe(ByRef value As Single) As Single
        'Get local copy of value
        Dim oldValue = value

        'Get incremented value
        Dim newValue = oldValue + 1

        'Try to update value (if another thread hasn't just changed it)
        Do Until Interlocked.CompareExchange(value, newValue, oldValue) = oldValue
            'Get local copy of value again
            oldValue = value

            'Get incremented value again
            newValue = oldValue + 1
        Loop

        Return oldValue
    End Function

So,

int value = 1;
System.Console.WriteLine($"({value}) value++ = {value++} ({value})");

and

Dim value = 1
Console.WriteLine($"({value}) value++ = {value.GetAndInc} ({value})")

should both result in

(1) value++ = 1 (2)

while

int value = 1;
System.Console.WriteLine($"({value}) ++value = {++value} ({value})");

and

Dim value = 1
Console.WriteLine($"({value}) ++value = {value.IncAndGet} ({value})")

should both result in

(1) ++value = 2 (2)

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

This is awesome! I'll update what I've done to utilize this approach.

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

Just added all of this to my current implementation... so this concludes 80% of the "project". Now begins the last 20% of the project which will take 80% of the "effort". ;-)

Major questions:

  • Should these be extension methods? I think on the surface it sounds attractive; however, I think the (will have to review further) Framework Design Guidelines somewhat frown on extension methods for this particular problem space.
  • Where should this functionality exist in the context of the existing (or new) Community.VisualBasic namespace?
  • Naming (the most difficult of these questions).
  • Thread-safe an issue (or not)?

Any other potential questions that I'm not currently thinking of?

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

"AVOID frivolously defining extension methods, especially on types outside your library or framework.

If you do own source code of a type, consider using regular instance methods instead. If you don't own the type, but you want to add a method, be very careful. Liberal use of extension methods has the potential to clutter APIs with types that were not designed to have these methods.

Another thing to consider is that extension methods are a compile-time facility, and not all languages provide support for them. Callers using languages without extension method support will have to use the regular static method call syntax to call your extension methods.

There are, of course, scenarios in which extension methods should be employed. These are outlined in the guidelines that follow."

-- Framework Design Guidelines 3rd Edition Page 184.

The following recommendation seem to mainly be about interfaces, generics and/or functionality that would be in a separate assembly due to assembly dependencies. Finally, one of the big issues as I see regarding extension methods for this type of thing is:

"AVOID defining extension methods on System.Object.

VB users will not be able to call such methods on object references using the extension method syntax, because VB does not support calling such methods. In VB, declaring a reference as Object forces all method invocations on it to be late bound (the actual member called is determined at runtime), while bindings to extension methods are determined as compile-time (early bound). For example:

// C# declaration of the extension method
public static class SomeExtensions{
  static void SomeMethod(this object o){...}
}

' VB will fail to compile as VB.NET does not support calling extension
' methods on reference types as Object
Dim o as Object = ...
o.SomeMethod();

VB users will have to call the method using the regular static method call syntax.

SomeExtensions.SomeMethod(o)

Note that this guideline applies to other languages where the same binding behavior is present, or where extension methods are not supported." -- Page 188

There is another annotated comment from Anthony Moore that discusses how overusing of extension methods reminds him of a similar problem experienced in C++.

So it would appear to me that the recommendation is that these shouldn't be extension methods. Thoughts?

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

As for naming, I'm leaning to the following:

Dim value As UShort = 1
Console.WriteLine($"({value}) value=5 = {InlineAssign(value, 5US)} ({value})")
Console.WriteLine($"({value}) value++ = {InlineIncrAfter(value)} ({value})")
Console.WriteLine($"({value}) value-- = {InlineDecrAfter(value)} ({value})")
Console.WriteLine($"({value}) ++value = {InlineIncrBefore(value)} ({value})")
Console.WriteLine($"({value}) --value = {InlineDecrBefore(value)} ({value})")

Part of the logic behind this is that I'd like to keep the methods as small/concise as possible so that (hopefully) the code will be inlined when compiled.

The "Inline" portion may be something that we adjust depending on whether or not it is in it's own namespace ("???.Inline"). So we could have the following:

Imports Community.VisualBasic.???.Inline

...

Dim value As UShort = 1
Console.WriteLine($"({value}) value=5 = {Assign(value, 5US)} ({value})")
Console.WriteLine($"({value}) value++ = {IncrAfter(value)} ({value})")
Console.WriteLine($"({value}) value-- = {DecrAfter(value)} ({value})")
Console.WriteLine($"({value}) ++value = {IncrBefore(value)} ({value})")
Console.WriteLine($"({value}) --value = {DecrBefore(value)} ({value})")

I'm 50/50 on whether or not the Increment methods should have the word After or not. With that said, I think I'm leaning more to having them state After then not... but it's a very thin lean as I think that the most common behavior is value++ and/or value--.

from community.visualbasic.

Echo-8-ERA avatar Echo-8-ERA commented on June 8, 2024

What about types that overload op_Increment and op_Decrement?

from community.visualbasic.

DualBrain avatar DualBrain commented on June 8, 2024

@Echo-8-ERA Do you have an example?

from community.visualbasic.

Echo-8-ERA avatar Echo-8-ERA commented on June 8, 2024

I once wrote a fixed point math library which overloaded op_increment/decrement to add/subtract 1. Lost the code when I changed my OS.

from community.visualbasic.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.