Results 1 to 4 of 4

Thread: Concept: Context function

  1. #1
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Concept: Context function

    Before I try to demonstrate "how", have a look at this:
    if fileCreationDate > 1.Hour.Ago then
      ' do something
    end if
    
    Reads great, right? And it could be built in to language with support for "context functions". What would that mean?

    In case thinBasic would find construction like:
    variable.something, it would of course do the usual checks for UDT members, but if it would not find any member named something, it would also check, whether there is a function, which takes TypeOf(variable) as first parameter with name something, and it would pass that variable as the parameter then. And it would work in chained way.

    So for the example, all you would need to do to implement the above:
    Function Hour( nValue as Number ) As Number
      ' -- Converts nValue to amount of milliseconds
    End Function
    
    Function Ago( timeInMilliseconds as Number ) As Number
      ' -- Subtracts the timeInMilliseconds from Now and returns again timeInMilliseconds
    End Function
    
    ...you could call these directly:
    Number oneHourAgoInMilliseconds = Ago(Hour(1))
    
    ...but also via the syntax proposed - because the parameter would be propagated via the "dot pipeline", not via parenthesis.

    This is not needed within TYPEs usually, as we can define custom functions now (big THANKS to Eros), but with primitive types, such as Numbers and Strings, there is no way to "expand them".

    Do you like this idea? What do you think about it?

    As with all the great ideas - this is not something I invented, I saw the 1.hour.ago syntax in Ruby, and liked it very much.


    Petr
    Last edited by Petr Schreiber; 18-11-2015 at 18:08.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  2. #2
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    This would work only for functions that have 1. parameter passed ByRef...

    We also could stay on current syntax and do it like this:

    Function String.Unquoted([parameters]) As String
    
       Function = Remove$( $DQ, Me)
       
    End Function
    
    Function String.Uppercase() As String
      
      Function = UCase$(Me)
       
    End Function
    
    ' Function String.Length() As Long 
    
     '   Function = StrPtrLen(StrPtr(Me)) 
    
    ' End Function
    
    
    String s = $DQ & "hello this is a quoted string" & $DQ
    
    PrintL s
    PrintL s.Unquoted 
    PrintL s.UpperCase
    
    ' PrintL Str$(s.Length)
    
    ' now what if this:
    
    PrintL s.Unquoted.Uppercase
    PrintL Str$( s.Unquoted.Lenght )   ' thinkeable...??? 
    
    
    
    ' ---???---???---???---???---???---???---
    
    '        equals this:
    
    Function Unquoted(ByRef s As String[,Parameters]) As String
    
       Function = Remove$( $DQ, s)
        
    End Function
    
    Function UpperCase(ByRef s As String) As String
       
      Function = Ucase$(s)
    
    End Function
    
    String s = $DQ & "hello this is a quoted string" & $DQ
    
    PrintL s
    PrintL Unquoted(s) 
    PrintL Uppercase(s)
    
    ' PrintL  Uppercase(Unquoted(s)) ' ??? 
    '   ... nay ... not ByRef i think since we have to refer a variable
    
    ' ...   ...   ...   ...   ... maybe allows later:
    
    Type tFace
       X As Double
       Y As Double
       Z As Double
       col as TBGL_tRGBA  ' this is a MODULES TYPE !!!
    End Type
    
    
    Function TBGL_tRGBA.SetValue(Byval R As Byte, Byval G As Byte, Byval B As Byte, Byval A As Byte)
      Me.R = R
      Me.G = G
      Me.B = B
      Me.A = A
    End Function
    
    Function TBGL_tRGBA.UseToDraw()
    
      TBGL_Color Me.R, Me.G, Me.B, Me.A
    End Function
    
    Dim myFace As tFace
    
    myFace.col.SetValue(200, 255, 127, 0)
    '...
    myFace.col.UseToDraw()
    
    Last edited by ReneMiner; 18-11-2015 at 19:31.
    I think there are missing some Forum-sections as beta-testing and support

  3. #3
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Proposed syntax by Petr is an advantage of those programming languages born since he beginning as Object Oriented.
    Numbers are a primitive class that can be extended.
    Strings are a primitive class that can be extended.
    ... and so on.

    For programming languages born as procedural like thinBasic a syntax like 1.Hour.Ago is almost impossible unless we change the foundation of the core language.

    There are some possibilities we can adopt, maybe slowing down a bit source interpretation.
    I already have a hook in Core engine to scan for dotted notation almost for everything but then we need to adhere to some standards: how the language must behave?

    What does it mean a number (1) followed by a term (Hour), followed by a term (Ago), followed by ... and so on ?
    Is whatever meaning we can think always the same for the all similar situation?

    Is 1.Divided.2 something in which the language can behave like when it encounters 1.Hour.Ago?

    That's the problem I have to face when I thinBasic have to interpret a source code on the fly.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    The similar feature is "extension method" in C#. But I would not say it is necessarily OOP based, it is just syntactic sugar.

    Here is proof of concept demo:
    Uses "Console", "DT"
     
    Long timeLimit = 1    
    'String code = "timeLimit.hours.ago" ' -- Works too
    String code = "1.hours.ago" 
     
    PrintL "Now:      " + DT_GetTime()
    Number nValue = InterpretMe(code)
     
    PrintL "Hour ago: " + DT_MillisecToTime(nValue)
    WaitKey
     
    Function InterpretMe( pieceOfCode As String ) As Number
       
      String token = ConsumeToken(pieceOfCode)  
      String extension
      Number valueNow  = GetValue(token) 
       
      If IsExtendableNumeric(token) Then
         
        While Len(Assign$(GetExtension(pieceOfCode), extension))
                                
          If Len(extension) Then
            ' -- Here some validation for signature, not present...
             
            Call extension(valueNow) To valueNow
          Else
            Exit While 
          End If       
           
        Wend    
      End If
       
      Return valueNow
     
    End Function
     
    Function ConsumeToken(ByRef pieceOfCode As String) As String
      String token = IIf$(InStr(pieceOfCode, "."), Extract$(pieceOfCode, "."), pieceOfCode) ' -- This is really bad, but works for our case  
      pieceOfCode = Mid$(pieceOfCode, Len(token)+1)
           
      Return token
    End Function
     
    Function IsExtendableNumeric(token As String)
      Long isLiteral = token = "0" Or Val(token) <> 0  
      Long isVariable = VARIABLE_Exists(token) ' -- Here would be SMART test against list of numeric variables, this is too general
       
      Return isLiteral Or isVariable
    End Function           
     
    Function GetValue(token As String) As Number
       
      If token = "0" Or Val(token) <> 0 Then
        Return Val(token)
      Else             
        Return Val(Expand$("$"+token))
      End If                       
       
    End Function
     
    Function GetExtension(ByRef pieceOfCode As String) As String
      If Not StartsWith(pieceOfCode, ".") Then
        Return ""
      Else
        pieceOfCode = LTrim$(pieceOfCode, ".")
        Return ConsumeToken(pieceOfCode)
      End If
    End Function
     
    ' --
     
    Function Hours(ByVal x As Number) As Number
      Return DT_TimeToMillisec(x+":00:00.000")
    End Function                         
     
    Function Minutes(ByVal x As Number) As Number
      Return DT_TimeToMillisec("00:"+x+":00.000")
    End Function                         
     
    Function Seconds(ByVal x As Number) As Number
      Return DT_TimeToMillisec("00:00:"+x+".000")
    End Function                        
                       
    Function Ago(ByVal x As Number) As Number
      Return DT_TimeToMillisec(DT_GetTime) - x
    End Function
    

    Petr
    Last edited by Petr Schreiber; 18-11-2015 at 23:11.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

Similar Threads

  1. context menu (right-cklick) help
    By largo_winch in forum UI (User Interface)
    Replies: 5
    Last Post: 09-05-2011, 12:31
  2. Concept: Citys
    By Michael Hartlef in forum Media
    Replies: 45
    Last Post: 22-10-2008, 21:37
  3. Concept: Track tiles
    By Michael Hartlef in forum Media
    Replies: 17
    Last Post: 21-10-2008, 22:25
  4. Concept: Glider models
    By Michael Hartlef in forum Media
    Replies: 0
    Last Post: 13-10-2008, 08:25
  5. Concept drawings anyone?
    By Michael Hartlef in forum Media
    Replies: 0
    Last Post: 10-10-2008, 23:13

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

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