Page 9 of 46 FirstFirst ... 678910111219 ... LastLast
Results 321 to 360 of 1810

Thread: TwinBasic

  1. #321
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Thumbs up Re: TwinBasic

    Quote Originally Posted by Krool View Post
    My proposal would be LetOrSet statement.
    Thus the statement tells already whats going on. Either a Let or Set statement. (Though Let is optional and seldom used)
    LetOrSet works for me!

  2. #322
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    Quote Originally Posted by wqweto View Post
    Is it possible to declare Private g_myField As T instead of Variant?
    You must have missed the comment in my code. I said that the TwinBASIC compiler complains about that:-


    I'm guessing that the TwinBASIC compiler expands generics into non-generic classes of each type based on what types you have defined in the application. In this case, when it expands into a String type, the compiler complains about Set being used to assign a String. It would be the same as doing this:-
    Code:
    Private Class OtherClass(Of T)
        
        'Same as using T since we have declared String versions of this class
        Private g_myField As String
        
        Public Sub SomeMethod(ByVal value As T)
                
            if isobject(value) then 
                set g_myfield=value
            else
                g_myfield=value                                   
            End If
            
        End Sub
        
    End Class
    It only works for all types if the field is a Variant.
    Last edited by Niya; Aug 17th, 2021 at 03:25 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  3. #323
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: TwinBasic

    Quote Originally Posted by Niya View Post
    It only works for all types if the field is a Variant.
    Yes, the if isobject(T) then part has to be executed at compile time and act like a preprocessor so that the invalid statements are not compiled at all.

    The idea is for LetOrSet to wrap this comptime logic but a more universal solution has to be researched/borrowed from .Net or C++ depending on which of these is closer as generics implementation (probably .Net).

    Btw, using As Variant instead of As T defeats the idea of generics. Currently built-in Collections use Variant as a way of duck-typing it. The idea of ListOf(T) is to not only expose strongly typed Item (indexed) property but to use an array of pointers to T internally for performance/storage reasons too.

    cheers,
    </wqw>

  4. #324
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,996

    Re: TwinBasic

    Quote Originally Posted by Krool View Post
    My proposal would be LetOrSet statement.
    Thus the statement tells already whats going on. Either a Let or Set statement. (Though Let is optional and seldom used)
    What about Assign?

  5. #325
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    I just figured out a way to avoid the TwinBASIC compiler and allow me to use type T as a field:-
    Code:
    Private Class OtherClass(Of T)
        
        Private g_myField As T
        
        Public Sub SomeMethod(ByVal value As T)
            
            If isobject(value) Then
                'We have to do a song and dance to avoid the TwinBASIC compiler
                '***********************************************************
                dim objPtr as longptr
                
                'Get object pointer
                CopyMemory(varptr(objptr),varptr(value),4)
                
                'Call AddRef on the object through its pointer
                AddRef(objPtr)
                
                'Dump the object pointer directly into the class
                'member field
                CopyMemory varptr(g_myfield),varptr(objptr),4
            Else
              g_myField = value
            End If
        End Sub
    
        private sub AddRef(byval objPtr as longptr)
            'Roundabout way of calling AddRef
            dim obj as object=PtrToObject(objptr)
            dim zero as long=0
            
            'Prevents TwinBASIC from decrementing the reference count
            'when this sub returns
            CopyMemory VarPtr(obj), VarPtr(zero), 4
        End Sub
        
    End Class
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  6. #326
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    Here's a version using wqweto's method from post 315:-
    Code:
    Private Class OtherClass(Of T)
        
        Private g_myField As T
        
        Public Sub SomeMethod(ByVal value As T)
            
            If isobject(value) Then
                'We have to do a song and dance to avoid the TwinBASIC compiler
                '***********************************************************
                dim objPtr as longptr
                
                'Get object pointer
                CopyMemory(varptr(objptr),varptr(value),4)
                
                'AddRef the object by it's pointer and dump that pointer
                'into the field
                vbaobjsetaddref(g_myfield,objptr)
            Else
              g_myField = value
            End If
        End Sub
    
        
    End Class
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  7. #327
    Member
    Join Date
    Nov 2018
    Posts
    56

    Re: TwinBasic

    Quote Originally Posted by Eduardo- View Post
    What about Assign?
    FWIW, I very much prefer Assign.

  8. #328
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    Quote Originally Posted by Krool View Post
    My proposal would be LetOrSet statement.
    Thus the statement tells already whats going on. Either a Let or Set statement. (Though Let is optional and seldom used)
    LetOrSet works for me!
    How about Let_Set or LetSet (I prefer LetSet)

    Edit:
    In addition, VBA occupies a very good keyword LSet. If VBA.LSet is not considered, we can merge Let and Set into LSet, and then replace VBA.LSet with other function. Of course, this is just an unrealistic idea.

    Edit2:
    If LSet cannot be used, maybe we can use SLet. It seems that LetSet is more intuitive.
    Last edited by SearchingDataOnly; Aug 17th, 2021 at 09:34 PM.

  9. #329
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    I'm really not feeling any of those to be honest. I mean all of it, not just the ones SD mentioned above. I really do not like the idea needing an extra construct for assigning Objects when a normal assignment expression would suffice.

    Now since it cannot be removed due to the quirk with Variant assignments mentioned here, I propose.....drum roll please.......Option Set Off

    I propose the introduction of a new member to the Option Explicit family. When used it will make Set implicit in the code file whenever an object assignment is performed. With this method we can effectively remove this abomination from TwinBASIC at our convenience while also maintaining full backward compatibility with VB6 since it will be on by default. VB6 projects obviously won't have this option set since it didn't exist in VB6. And as a bonus, we can still get all those fancy keywords you guys suggested above for those of you that actually want this. Personally though, I'd like the option to get rid of that garbage whenever I want. Seriously, using Set makes me want to drive molten nails into my skull. Just my opinion.
    Last edited by Niya; Aug 17th, 2021 at 10:50 PM. Reason: Clarification.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  10. #330
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: TwinBasic

    Quote Originally Posted by Niya View Post
    I'm really not feeling any of those to be honest. I mean all of it, not just the ones SD mentioned above. I really do not like the idea needing an extra construct for assigning Objects when a normal assignment expression would suffice.

    Now since it cannot be removed due to the quirk with Variant assignments mentioned here, I propose.....drum roll please.......Option Set Off

    I propose the introduction of a new member to the Option Explicit family. When used it will make Set implicit in the code file whenever an object assignment is performed. With this method we can effectively remove this abomination from TwinBASIC at our convenience while also maintaining full backward compatibility with VB6 since it will be on by default. VB6 projects obviously won't have this option set since it didn't exist in VB6. And as a bonus, we can still get all those fancy keywords you guys suggested above for those of you that actually want this. Personally though, I'd like the option to get rid of that garbage whenever I want. Seriously, using Set makes me want to drive molten nails into my skull. Just my opinion.
    Like you, I hate the Set keyword. But the question is, how do you deal with the default value of an object? Do you want to tell everyone not to use the default value?

    Quote Originally Posted by WaynePhillipsEA View Post
    We can't make Set optional since in classic VB it is valid to do things like
    Code:
    MyVariant = MyObject
    where the semantics are different to
    Code:
    Set MyVariant = MyObject
    . In the first version, the default member of MyObject is evaluated (DISPID_VALUE), and in the second version it is not. One of the reasons they were able to remove the Set keyword requirement in VB.NET is because they don't support default member evaluation in VB.NET like classic VB does.

  11. #331
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    How about a slightly different operator to control that behaviour instead of LetSet/Assign?

    Code:
    MyObject1 := MyObject2

  12. #332
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,375

    Re: TwinBasic

    Quote Originally Posted by SearchingDataOnly View Post
    How about Let_Set or LetSet (I prefer LetSet)

    Edit:
    In addition, VBA occupies a very good keyword LSet. If VBA.LSet is not considered, we can merge Let and Set into LSet, and then replace VBA.LSet with other function. Of course, this is just an unrealistic idea.

    Edit2:
    If LSet cannot be used, maybe we can use SLet. It seems that LetSet is more intuitive.
    LSet is not a shortcut for LetSet. There also exist RSet.
    So instead it means Left/Right. (for strings)

  13. #333
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    Quote Originally Posted by SearchingDataOnly View Post
    Like you, I hate the Set keyword. But the question is, how do you deal with the default value of an object? Do you want to tell everyone not to use the default value?
    This is why I said it should be a compiler option like Option Explicit, so you have the choice to opt in or not. You will never see me writing code like that. If I want a property value from an object, I will explicitly call the property. I have zero need for Set. It's just an extra mental burden that gives no extra value. Using Set is like paying your taxes and not getting your roads built and repaired.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  14. #334
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    How about a slightly different operator to control that behaviour instead of LetSet/Assign?

    Code:
    MyObject1 := MyObject2
    I like this option best. It makes a lot more sense and it's less verbose.

    EDIT:

    Also, what would be even better is if := behaves like a normal assignment when it's not assigning an Object. People like me could default to using it for most assignments. I like consistency. I don't like having to always think about how I'm performing an assignment.

    Also, I've been wondering. Is the Variant/Default property thing the only reason Set cannot be removed?
    Last edited by Niya; Aug 18th, 2021 at 01:20 AM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  15. #335
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Niya View Post
    I like this option best. It makes a lot more sense and it's less verbose.

    EDIT:

    Also, what would be even better is if := behaves like a normal assignment when it's not assigning an Object. People like me could default to using it for most assignments. I like consistency. I don't like having to always think about how I'm performing an assignment.

    Also, I've been wondering. Is the Variant/Default property thing the only reason Set cannot be removed?
    The proposed := assignment would behave as earlier discussed about the LetOrSet keyword (i.e. if either side is an explicit object, then Set-assignment is used, else defer to Let-assignment).

    Off the top of my head I can't think of anything other than default-member evaluation that prevents the removal of the Set keyword. By the way, it's not just the Variant example I gave earlier, there's lots of examples, e.g. 'MyObject1 = MyObject2' is valid in classic VB if there's a property-let default member on MyObject1 (or even a property-get default-member that returns an object that itself has a property-let default member)... it's a minefield, and it's heavily baked into the language.

  16. #336
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: TwinBasic

    Quote Originally Posted by Krool View Post
    LSet is not a shortcut for LetSet. There also exist RSet.
    So instead it means Left/Right. (for strings)
    Yes, I know this.

  17. #337
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    How about a slightly different operator to control that behaviour instead of LetSet/Assign?

    Code:
    MyObject1 := MyObject2
    Excellent. It is exactly the way I use it in my scripting language (my scripting language has removed the Set keyword)

    In my scripting language, ":=" has two uses:
    (1) Exempt variable declarations (similar to Golang), for example:
    var1 := getMyVaraible '--- var1 does not require variable declaration

    (2) Get the default value of an object
    myDefaultValue := myObject

    Note:
    If myDefaultValue is declared, then myDefaultValue is used to get the default value of myObject. If myDefaultValue is not declared, then myDefaultValue is the object reference of myObject.
    But this point is easy to cause ambiguity, so I'm considering whether my scripting language retains the feature of the default value of the object.
    Last edited by SearchingDataOnly; Aug 18th, 2021 at 02:17 AM.

  18. #338
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: TwinBasic

    How about augmenting the preprocessor to understand comptime expressions so this would compile

    Code:
            #If isobject(T) Then 
                set g_myfield=value
            #Else
                g_myfield=value                                   
            #End If
    . . . as a generic solution instead of introducing any (piecemeal) language constructs.

    Currently VBx preprocessor is able to understand *some* expressions containing arith operators and type conversion functions (CLng, etc.) so adding support for more functions/constructs here is not surprising, provided that generics source code is not expected to be round-tripped to VBx in first place.

    cheers,
    </wqw>

  19. #339
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by wqweto View Post
    How about augmenting the preprocessor to understand comptime expressions so this would compile

    Code:
            #If isobject(T) Then 
                set g_myfield=value
            #Else
                g_myfield=value                                   
            #End If
    . . . as a generic solution instead of introducing any (piecemeal) language constructs.

    Currently VBx preprocessor is able to understand *some* expressions containing arith operators and type conversion functions (CLng, etc.) so adding support for more functions/constructs here is not surprising, provided that generics source code is not expected to be round-tripped to VBx in first place.

    cheers,
    </wqw>
    Unfortunately we wouldn't be able to make that work. Generics work off the parse trees, but the preprocessor strips out code before it even gets parsed.

    We would literally need the equivalent to the C++ if-constexpr to make it work like that:
    Code:
            IfConst isobject(T) Then 
                set g_myfield=value
            Else
                g_myfield=value                                   
            End If

  20. #340
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    . . . but the preprocessor strips out code before it even gets parsed.
    How do you syntax highlight code inside branches of the preprocessor #If then?

    I see what the problem is but I always hated how C++/Zig implement IfConst like normal expressions with no clear marking what is evaluated at compile time and what not. Much worse than the way #If and the rest of the VB6 (and C/C++) preprocessor directives are obvious and human readable.

    cheers,
    </wqw>

  21. #341
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by wqweto View Post
    How do you syntax highlight code inside branches of the preprocessor #If then?
    In tB, we don't, we just grey-out the whole block. In VBx it is slightly different because they have a tokenizer stage that runs before the real parse run, which allows for highlighting of keywords and some syntax errors, but ultimately the code doesn't get to the fully parsed stage. You can see this if you enter illegal code in an #If block that isn't included; VBx will highlight some syntax errors in the tokenizer stage through the IDE (highlighted red), but the parser/resolver/compiler doesn't see them, and compilation can succeed regardless.

  22. #342
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: TwinBasic

    Since Niya brought up the "generics-example"...

    I've modified it a bit, to (primarily) point out a different "nice to have" feature
    (which would be great, if it was introduced).

    Code:
    Module modHelloRC6
      Public New_c As New cConstructor
     
      Sub Main()
        Dim Longs   As cArrayList = New_c.ArrayList(vbLong, 1, 2, 3)
        Dim Persons As cArrayList = New_c.ArrayList(vbObject, New cPerson("John"))
      
        Dim L As Long '<- tB does "For Each Auto-Coercing from Variant" already, also with simple types
        For Each L In Longs
            Debug.Print L
        Next
     
        Dim P As cPerson '<- this would work also in VBA/VB6, whereas the above "L As Long" wouldn't
        For Each P In Persons
            Debug.Print P.Name
        Next
      End Sub
    End Module
    
    Private Class cPerson
      Public Name As String
      Public Sub New(ByVal Name As String)
          Me.Name = Name
      End Sub
    End Class
    So, whilst the above Code will work "as it is" in tB already (when an RC6-reference is included) -
    I'd like to be able to have "LoopVar-TypeInitializers in For- and For-Each Loops, like below:
    Code:
    Module modHelloRC6
      Public New_c As New cConstructor
     
      Sub Main()
        Dim Longs   As cArrayList = New_c.ArrayList(vbLong, 1, 2, 3)
        Dim Persons As cArrayList = New_c.ArrayList(vbObject, New cPerson("John"))
      
        For Each L As Long In Longs
            Debug.Print L
        Next
     
        For Each P As cPerson In Persons
            Debug.Print P.Name
        Next
      End Sub
    End Module
    
    Private Class cPerson
      Public Name As String
      Public Sub New(ByVal Name As String)
          Me.Name = Name
      End Sub
    End Class
    Olaf

  23. #343
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,996

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    How about a slightly different operator to control that behaviour instead of LetSet/Assign?

    Code:
    MyObject1 := MyObject2
    FWIW, I strongly discourage to introduce not "BASICish" syntax like that.
    One of the main features and advantage of BASIC is that it can be understood almost "without studing", BASIC is almost English. It is intuitive.

    What does ":=" mean? (intuitively)
    "I don't know".

  24. #344
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: TwinBasic

    @WaynePhillipsEA,

    I'd like to know how twinBasic implements JavaScript-like inline-functions(Callback), for example:

    Code:
    //Basic forEach
    function forEach(array, action) {
        for (var i = 0; i < array.length; i++) {
    	action(array[i])
        }
    }
    
    // Test forEach
    forEach(["Pear", "Apple"], function(name) {
        console.log(name);
    });
    
    // Implement reduce
    function reduce(combine, base, array) {
        forEach(array, function(element) {
    	base = combine(base, element);
        });
        return base;
    }
    Another famous example is C++ qsort.
    Last edited by SearchingDataOnly; Aug 18th, 2021 at 09:47 AM.

  25. #345
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Eduardo- View Post
    FWIW, I strongly discourage to introduce not "BASICish" syntax like that.
    One of the main features and advantage of BASIC is that it can be understood almost "without studing", BASIC is almost English. It is intuitive.

    What does ":=" mean? (intuitively)
    "I don't know".
    Upon reflection, I think you're spot on, and I've rejected other proposed features for those exact reasons. I was purely trying to think of alternatives we hadn't considered, but you are right that this one is not BASIC-esque.

  26. #346
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Schmidt View Post
    Since Niya brought up the "generics-example"...

    I've modified it a bit, to (primarily) point out a different "nice to have" feature
    (which would be great, if it was introduced).

    Code:
    Module modHelloRC6
      Public New_c As New cConstructor
     
      Sub Main()
        Dim Longs   As cArrayList = New_c.ArrayList(vbLong, 1, 2, 3)
        Dim Persons As cArrayList = New_c.ArrayList(vbObject, New cPerson("John"))
      
        Dim L As Long '<- tB does "For Each Auto-Coercing from Variant" already, also with simple types
        For Each L In Longs
            Debug.Print L
        Next
     
        Dim P As cPerson '<- this would work also in VBA/VB6, whereas the above "L As Long" wouldn't
        For Each P In Persons
            Debug.Print P.Name
        Next
      End Sub
    End Module
    
    Private Class cPerson
      Public Name As String
      Public Sub New(ByVal Name As String)
          Me.Name = Name
      End Sub
    End Class
    So, whilst the above Code will work "as it is" in tB already (when an RC6-reference is included) -
    I'd like to be able to have "LoopVar-TypeInitializers in For- and For-Each Loops, like below:
    Code:
    Module modHelloRC6
      Public New_c As New cConstructor
     
      Sub Main()
        Dim Longs   As cArrayList = New_c.ArrayList(vbLong, 1, 2, 3)
        Dim Persons As cArrayList = New_c.ArrayList(vbObject, New cPerson("John"))
      
        For Each L As Long In Longs
            Debug.Print L
        Next
     
        For Each P As cPerson In Persons
            Debug.Print P.Name
        Next
      End Sub
    End Module
    
    Private Class cPerson
      Public Name As String
      Public Sub New(ByVal Name As String)
          Me.Name = Name
      End Sub
    End Class
    Olaf
    I like this idea Olaf, and I can't foresee it causing any clashes with existing syntax, so that's definitely a possibility.

    It would also be nice if the declared variable was scoped only to the For block, rather than the procedure-scope.
    Last edited by WaynePhillipsEA; Aug 18th, 2021 at 10:29 AM.

  27. #347
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by SearchingDataOnly View Post
    @WaynePhillipsEA,

    I'd like to know how twinBasic implements JavaScript-like inline-functions(Callback), for example:

    Code:
    //Basic forEach
    function forEach(array, action) {
        for (var i = 0; i < array.length; i++) {
    	action(array[i])
        }
    }
    
    // Test forEach
    forEach(["Pear", "Apple"], function(name) {
        console.log(name);
    });
    
    // Implement reduce
    function reduce(combine, base, array) {
        forEach(array, function(element) {
    	base = combine(base, element);
        });
        return base;
    }
    Another famous example is C++ qsort.
    Yes, Delegate-style function pointers are planned: https://github.com/WaynePhillipsEA/twinbasic/issues/79

  28. #348
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    This single thread is getting quite long already. Shame we can't get our own twinBASIC sub-forum here.

  29. #349
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    I like this idea Olaf, and I can't foresee it causing any clashes with existing syntax, so that's definitely a possibility.

    It would also be nice if the declared variable was scoped only to the For block, rather than the procedure-scope.
    I've thought about that ("For block-scoping") as well,
    but would rather the scoping remains at function-level, due to constructs like the one below:

    Code:
      'the construct here will only be possible, when P As Person would be scoped to Method-level
      For Each P As cPerson In Persons
        If P.Name = SomeNameToSearch Then Exit For
      Next
      
      If P Is Nothing Then 'P is re-initialized to Nothing, when the loop was "running its full course" (no match found)
        Debug.Print SomeNameToSearch & " was not found!"
      Else 'P is only different from Nothing, when the loop was exited early (via Exit For, because of a match)
        Debug.Print SomeNameToSearch & " was found!"
      End If
    Difficult decision to make (both "scopings" have advantages) - but the stuff shown above is quite common (at least in my code).

    Olaf

  30. #350
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Schmidt View Post
    I've thought about that ("For block-scoping") as well,
    but would rather the scoping remains at function-level, due to constructs like the one below:

    Code:
      'the construct here will only be possible, when P As Person would be scoped to Method-level
      For Each P As cPerson In Persons
        If P.Name = SomeNameToSearch Then Exit For
      Next
      
      If P Is Nothing Then 'P is re-initialized to Nothing, when the loop was "running its full course" (no match found)
        Debug.Print SomeNameToSearch & " was not found!"
      Else 'P is only different from Nothing, when the loop was exited early (via Exit For, because of a match)
        Debug.Print SomeNameToSearch & " was found!"
      End If
    Difficult decision to make (both "scopings" have advantages) - but the stuff shown above is quite common (at least in my code).

    Olaf
    That's true actually, and will save me from having to make any changes to the scoping

  31. #351
    Member
    Join Date
    Nov 2018
    Posts
    56

    Re: TwinBasic

    Quote Originally Posted by Schmidt View Post
    I've thought about that ("For block-scoping") as well,
    but would rather the scoping remains at function-level, due to constructs like the one below:

    Code:
      'the construct here will only be possible, when P As Person would be scoped to Method-level
      For Each P As cPerson In Persons
        If P.Name = SomeNameToSearch Then Exit For
      Next
      
      If P Is Nothing Then 'P is re-initialized to Nothing, when the loop was "running its full course" (no match found)
        Debug.Print SomeNameToSearch & " was not found!"
      Else 'P is only different from Nothing, when the loop was exited early (via Exit For, because of a match)
        Debug.Print SomeNameToSearch & " was found!"
      End If
    Difficult decision to make (both "scopings" have advantages) - but the stuff shown above is quite common (at least in my code).

    Olaf
    Counter-argument would be that .Net does scope inline declarations like this to the block, and it's occasionally quite nice to be able to reuse a name within the wider scope. For the times when you need the wider scope, you can just declare above the block as before.

    I'm ambivilant as to which is best for tB though.

  32. #352
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    GUYS I HAVE FINALLY SOLVED IT!!!

    Ok, to recap what I'm talking about for anyone just coming in. Yesterday I raised an issue with the Set keyword clashing with generics in TwinBASIC. Writing generic classes that perform assignments internally created situation where a generic class could not work for both classes and non-classes like Longs, Strings etc as the generic type. This was because assignment between class type variables needed to be performed with the Set keyword and assignment between non-class types must be performed without them. There was no way to perform an assignment that works with both types of assignment.

    After much discussion in this thread about it, Wayne Phillips pointed out that I could use IsObject to test whether a variable was an object or not and the program can use that information to decide how to perform the assignment. I tried it and it seemed to work in a little scratch pad application I wrote to specifically test it. I thought I had a workable solution. I went into what I was actually using this for which is a List(Of T) and HashTable(Of String,TValue) implementation I'm working on which is going to be 100% written in TwinBASIC code with no external dependencies. When I went back to the List(Of T) code to implement the IsObject solution, it failed. Turns out that for some reason it doesn't work when the assignments involved arrays of type T. Having already spent the better part of the day already on this, I was too burnt out to start this all over again in an attempt to figure out why arrays are now a problem.

    The overall problem was that the TwinBASIC compiler is determined not to allow assignments to be perform with the wrong statement, Let for non-objects variable and Set for object variables. If the compile even smells a possibility of this happening, it will complain. I did come up with a way around it by using a bunch on pointer tricks but they are just curiosities. These tricks are only good for showing off and not good for actual use. I went to bed last night defeated. I wrote it off generics as usable until this thing with Set could be sorted out.

    But for some reason when I got up today, I decided to give it one more try and I don't know if it was the sleep I needed or what but in 5 minutes, I came up with a way to solve this problem entirely by removing Set from the equation altogether and it didn't involve any fancy tricks with pointers or anything like this. Turns out you can bypass Set completely with a very easy method. Use a function like this:-
    Code:
        Private Sub SetVarValue(ByRef varToSet As Variant, ByVal value As Variant)
            varToSet = value
        End Sub
    I'm not even sure why that works as well as it does but it works. That function will allow you to perform an assignment to a variable regardless of if an Object is being assigned or not. Here is the full test program:-
    Code:
    Module MainModule
    
        ' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
        Public Sub Main()
            
            Dim objVal As TestClass = New TestClass
            Dim strVal As String = "BOO!"
            Dim lngVal As Long = 29
            
            Dim objVar As TestClass
            Dim strVar As String
            Dim lngVar As Long
            
            SetVarValue(objVar, objVal)
            SetVarValue(strVar, strVal)
            SetVarValue(lngVar, lngVal)
            
            Debug.Print objVar.Value
            Debug.Print strVar
            Debug.Print lngVar
            
        
        End Sub
    	
        Private Sub SetVarValue(ByRef varToSet As Variant, ByVal value As Variant)
            varToSet = value
        End Sub
    
        
    End Module
    
    Private Class TestClass
        
        Public Sub new()
            
        End Sub
        
        Public Property Get Value() As String
            Return "Class Property Value"
        End Property
        
    End Class
    I popped that into the List(Of T) class I'm writing and it works. The List(Of T) class can now work with both class and non-class types with no problem. And it has no problem working with arrays.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  33. #353
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Niya View Post
    GUYS I HAVE FINALLY SOLVED IT!!!

    Ok, to recap what I'm talking about for anyone just coming in. Yesterday I raised an issue with the Set keyword clashing with generics in TwinBASIC. Writing generic classes that perform assignments internally created situation where a generic class could not work for both classes and non-classes like Longs, Strings etc as the generic type. This was because assignment between class type variables needed to be performed with the Set keyword and assignment between non-class types must be performed without them. There was no way to perform an assignment that works with both types of assignment.

    After much discussion in this thread about it, Wayne Phillips pointed out that I could use IsObject to test whether a variable was an object or not and the program can use that information to decide how to perform the assignment. I tried it and it seemed to work in a little scratch pad application I wrote to specifically test it. I thought I had a workable solution. I went into what I was actually using this for which is a List(Of T) and HashTable(Of String,TValue) implementation I'm working on which is going to be 100% written in TwinBASIC code with no external dependencies. When I went back to the List(Of T) code to implement the IsObject solution, it failed. Turns out that for some reason it doesn't work when the assignments involved arrays of type T. Having already spent the better part of the day already on this, I was too burnt out to start this all over again in an attempt to figure out why arrays are now a problem.

    The overall problem was that the TwinBASIC compiler is determined not to allow assignments to be perform with the wrong statement, Let for non-objects variable and Set for object variables. If the compile even smells a possibility of this happening, it will complain. I did come up with a way around it by using a bunch on pointer tricks but they are just curiosities. These tricks are only good for showing off and not good for actual use. I went to bed last night defeated. I wrote it off generics as usable until this thing with Set could be sorted out.

    But for some reason when I got up today, I decided to give it one more try and I don't know if it was the sleep I needed or what but in 5 minutes, I came up with a way to solve this problem entirely by removing Set from the equation altogether and it didn't involve any fancy tricks with pointers or anything like this. Turns out you can bypass Set completely with a very easy method. Use a function like this:-
    Code:
        Private Sub SetVarValue(ByRef varToSet As Variant, ByVal value As Variant)
            varToSet = value
        End Sub
    I'm not even sure why that works as well as it does but it works. That function will allow you to perform an assignment to a variable regardless of if an Object is being assigned or not. Here is the full test program:-
    Code:
    Module MainModule
    
        ' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
        Public Sub Main()
            
            Dim objVal As TestClass = New TestClass
            Dim strVal As String = "BOO!"
            Dim lngVal As Long = 29
            
            Dim objVar As TestClass
            Dim strVar As String
            Dim lngVar As Long
            
            SetVarValue(objVar, objVal)
            SetVarValue(strVar, strVal)
            SetVarValue(lngVar, lngVal)
            
            Debug.Print objVar.Value
            Debug.Print strVar
            Debug.Print lngVar
            
        
        End Sub
    	
        Private Sub SetVarValue(ByRef varToSet As Variant, ByVal value As Variant)
            varToSet = value
        End Sub
    
        
    End Module
    
    Private Class TestClass
        
        Public Sub new()
            
        End Sub
        
        Public Property Get Value() As String
            Return "Class Property Value"
        End Property
        
    End Class
    I popped that into the List(Of T) class I'm writing and it works. The List(Of T) class can now work with both class and non-class types with no problem. And it has no problem working with arrays.
    Don't get too excited... that looks like a bug in tB, as it should be trying to call the default prop-let member in that assignment inside SetVarValue if the LHS is an object type. That will be fixed very soon, and then your code will break.

    You could put the IsObject check into the SetVarValue call to switch between the two types of assignments, and that should satisfy the compiler and be correct. Though of course you are passing the values through Variants for that to work, which as @wqweto mentioned earlier, goes against what you're trying to achieve by using generics.

    Code:
    Private Sub SetVarValue(ByRef varToSet As Variant, ByVal Value As Variant)
        If IsObject(varToSet) Then
            Set varToSet = Value
        Else
            varToSet = Value
        End If
    End Sub
    Last edited by WaynePhillipsEA; Aug 18th, 2021 at 03:44 PM.

  34. #354
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,996

    Re: TwinBasic

    BTW, this code:

    Code:
            SetVarValue(objVar, objVal)
            SetVarValue(strVar, strVal)
            SetVarValue(lngVar, lngVal)
    is also not allowed in VB6 (arguments in parentheses without the Call keyword).

  35. #355
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Eduardo- View Post
    BTW, this code:

    Code:
            SetVarValue(objVar, objVal)
            SetVarValue(strVar, strVal)
            SetVarValue(lngVar, lngVal)
    is also not allowed in VB6 (arguments in parentheses without the Call keyword).
    It is allowed in tB though, whilst retaining full backwards compatibility. See the discussion:

    https://github.com/WaynePhillipsEA/twinbasic/issues/262

  36. #356
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    This single thread is getting quite long already. Shame we can't get our own twinBASIC sub-forum here.
    It is fine to create multiple threads in Other Basic, then if/when a twinBASIC forum is created I (or other moderators) will move the threads across.

  37. #357
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,996

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    It is allowed in tB though, whilst retaining full backwards compatibility. See the discussion:

    https://github.com/WaynePhillipsEA/twinbasic/issues/262
    Ah, OK, then could we say that now the Call keyword is entirely optional/obsolete?

  38. #358
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by si_the_geek View Post
    It is fine to create multiple threads in Other Basic, then if/when a twinBASIC forum is created I (or other moderators) will move the threads across.
    Good to know, thanks!

  39. #359
    Addicted Member
    Join Date
    Dec 2020
    Posts
    203

    Re: TwinBasic

    Quote Originally Posted by Eduardo- View Post
    Ah, OK, then could we say that now the Call keyword is entirely optional/obsolete?
    I would say mostly optional/obsolete. There will be edge cases, e.g. if a procedure is named the same as a syntax keyword, then the call prefix can still help to disambiguate between the keyword and the procedure name. But in the majority of cases it should be considered obsolete/optional.

  40. #360
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: TwinBasic

    Quote Originally Posted by WaynePhillipsEA View Post
    Don't get too excited... that looks like a bug in tB, as it should be trying to call the default prop-let member in that assignment inside SetVarValue if the LHS is an object type. That will be fixed very soon, and then your code will break.

    You could put the IsObject check into the SetVarValue call to switch between the two types of assignments, and that should satisfy the compiler and be correct.
    I would be totally fine with that IsObject logic as long as it prevents the compiler from interfering with what I'm trying to do. The real value here is being able to use Variants on both sides so that the compiler doesn't try to tell me what I can and cannot do. With Variants involved on both sides of the assignment, the compiler cannot make any assumptions, it has to be evaluated at runtime for correctness, which is exactly what I want. The other big win here is that I don't have to refactor my class code, all I have to do is use the function where I'm performing assignments that involve type T. That's a very minor cost to pay in my opinion.

    Quote Originally Posted by WaynePhillipsEA View Post
    Though of course you are passing the values through Variants for that to work, which as @wqweto mentioned earlier, goes against what you're trying to achieve by using generics.
    This is true. However, I'm willing to live with that. Generics provide more value than just performance. I'd argue that the bigger pay off is type safety. I'm willing to sacrifice a bit of performance for the type safety that generics give you. If I have a list of Longs, I only want Longs in that list and I would like the compiler to stop me if I ever make this mistake of trying to put in a String. This is a big win for me that helps prevent all kinds of errors in code. If I have to lose a few clock cycles for it, so be it.

    This is the sole reason I hate JavaScript with its duck typing nonsense. It spoils an otherwise very beautiful language. It puts too much of a burden on you to always make sure you're using the right data types. There is a lot of value in a compiler that has ways of easing this burden so I can put my mental more towards what I'm actually doing rather than how I'm doing it. This is just my opinion though, there is no right or wrong here. It's just preferences.

    Quote Originally Posted by Eduardo- View Post
    BTW, this code:

    Code:
            SetVarValue(objVar, objVal)
            SetVarValue(strVar, strVal)
            SetVarValue(lngVar, lngVal)
    is also not allowed in VB6 (arguments in parentheses without the Call keyword).
    Oh boy. This is another big discussion. I really don't want to go down that path right now. I'll just say this, like Set, this is another one of those garbage things present in the VB6 language that makes zero sense and adds no value. No programming language I know of would allow something like that. I'm a huge fan of consistency in a programming language, and a function/sub call should always be in brackets. I'm only speculating here but I suspect that VB6 inherited that nonsense from QuickBasic to support Print and statements like it so you can do stuff like this:-
    Code:
        Debug.Print "This is ";
        Debug.Print "one line"
    Requiring brackets there would make the syntax look too cluttered. Of course I'm just speculating here. I really don't know why BASIC was the only mainstream language that allowed this. Suffice to say, it's confusing as hell when you start switching between writing code in BASIC and some other language such as C. Sometimes you bring back the habit of bracketing your function calls to BASIC and it can become annoying when the compiler stops you and demand that you fix it. I've experienced it and still do to this day when switching between VB6 and VB.Net which is consistent about function call syntax.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Page 9 of 46 FirstFirst ... 678910111219 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width