none
Subs without params? No automatic idention? RRS feed

  • General discussion

  • I'm just beginning to use SmallBasic. It's fun! And it's a very promising begin.
    I like the simplicity of the editor: it has only the absolute necessary options to deal with code.
    Intellisense works good too! I haven't miss a reference manual... yet.

    But I think it has some drawbacks:

    For example, honestly, I cannot understand why subs are paramless. If you want params, you have to use global vars or the Stack.PushValue/PopValue method. I don't know what approach is worse.

    Every procedural language handles params transparently to the user. No one has to worry about pushing params to the stack and popping from it, as if it were assembly language.

    Think about LOGO: it has procedures with params, and it handles them in a very straighforward way. The user hasn't to deal with variable types as he has to do in C or PASCAL. You can extend the language by writting your own procedures, and they are used the same way you use the bult-in primitives.

    If this is a platform for the absolute beginner to start writting programs, things like the Stack object to implement parameter passing contributes to code illegibility, and makes the coder to worry about details that he shoudn't.

    Another issue, related to legibility: it would be great if the editor would implement an auto-indent feature. So, after typing a line as "For i=1 to 10", the cursor would move a few characters to the right on the next line, to perform identation. When you type "EndFor", the editor would match this EndFor with the previous For, to start both lines at the same column.

    Thanks!
    Tuesday, October 28, 2008 5:23 AM

All replies

  • Thanks for the feedback, Mcleod. 

    It was a language design choice we took to make Subs parameterless.  This follows closely on the decision to make all variables dynamic and global.  If we had subs take parameters, we'd have to introduce scopes for where these arguments are visible and valid, which we wanted to avoid. 

    The Auto-Indent feature is a great suggestion.  We'll definitely have it in the future versions.

     

    Tuesday, October 28, 2008 5:35 PM
    Moderator
  • OK, I understand. Having to deal with scopes is a headache for beginners. To avoid that, the language could force the user to name a variable using some kind of "mangled" notation.

    I mean: when you use a local variable in C, say, "myvar", inside a function called "myfunction", a compiler may choose an internal name as "myfunction$myvar" as the internal name for that variable, so avoiding name colission with a global variable called "myvar" too.

    In SmallBasic, one could name variables in a analogous way: for example: MySub.MyVar

    Combine it with an object named "Parameter", which would be created automatically when the sub starts execution. That object would keep the parameters for that sub, and would expose a GetValue method to retrieve values by index.

    So, a typical recursive program, the factorial, could be written as this:

    Sub Factorial
      Factorial.n=Parameter.GetValue(1)  '1 referes to the first parameter, use 2 for the second parameter, etc.
      If Factorial.n=0 then
        result=1       'global var to hold the final value
      else
        Factorial (Factorial.n -1)
        result=Factorial.n*result
      EndIf
    EndSub

    One could simply call Factorial, and get the calculated value in the global variable "result"

    Factorial(7)
    TextWindow.WriteLine(result)


    You may even extend this method to allow a sub to return a value, using the same convention as in PASCAL, so "Factorial.Factorial", or "Factorial.Self" could refer to the value being returned by the Factorial sub, as in this:

    Sub Factorial
      Factorial.n=Parameter.GetValue(1)
      If Factorial.n=0 then
        Factorial.Self=1   'the value being returned
      else
        Factorial.Self = Factorial (Factorial.n -1)*Factorial.n   'now, we can use factorial within an expression
      EndIf
    EndSub

    And use as this:

    TextWindow.WriteLine(Factorial(7))


    This extensions don't collide with current language specifications (as far as I know) so all programs written for SmallBasic, as it is defined now, would continue to run without modifications, and you would add a powerfull subroutine construction tool, by allowing parameters and value returning: such concepts would not be "new" when the newbie laern and moves to C#, JAVA, etc. Take into account that I'm not thinking just about kids, as the only users for this language, but a high school student, which could have some background in maths or physics, but no prior knowledge of programming, and would just use SmallBasic to practice with graph plotting, or to use sprites to simulate the dynamics of a particle.

    Well... it's only an idea... :)
    Tuesday, October 28, 2008 9:53 PM
  • I agree compleatly and wish subs were not paramless.
    Sunday, November 9, 2008 1:48 AM
  • Thanks Mcleod.  

    Sub Factorial
      Factorial.n=Parameter.GetValue(1)
      If Factorial.n=0 then
        Factorial.Self=1   'the value being returned
      else
        Factorial.Self = Factorial (Factorial.n -1)*Factorial.n   'now, we can use factorial within an expression
      EndIf
    EndSub


    That is a very well thought-out idea.  We'll definitely consider adding this to the language.
    Sunday, November 9, 2008 2:03 AM
    Moderator
  • You can simulate locals using an Array, and parameters using the Stack.  Here's what the Fib() function would look like:

    ' What it looks like in VB
    '
     Print fib(13)

    Function fib(ByVal n)
        If n < 2 Then
            Return n
        Else
            Return fib(n - 1) + fib(n - 2)
        End If
    End Function


    ' What it looks like in Microsoft Small Basic
    '

    ' Call Fib( 13 )
    Stack.PushValue( "p", 13 )
    Fib()
    TextWindow.WriteLine( Stack.PopValue( "p" ) )

    Sub Fib ' n
      Fib_Locals = Fib_Locals + 1
     
      'Set up params:
      Array.SetValue( Fib_Locals, "n", Stack.PopValue( "p" ) )

      If Array.GetValue(Fib_Locals, "n") < 2 Then
        ' Return n
        Stack.PushValue( "p", Array.GetValue(Fib_Locals, "n") )
        Goto Fib_Exit
      Else
        'n1 = Fib( n - 1 )
        Stack.PushValue( "p", Array.GetValue(Fib_Locals, "n") - 1 )
        Fib()
        Array.SetValue( Fib_Locals, "n1", Stack.PopValue( "p" ) )
       
        'n2 = Fib( n - 2 )
        Stack.PushValue( "p", Array.GetValue(Fib_Locals, "n") - 2 )
        Fib()
        Array.SetValue( Fib_Locals, "n2", Stack.PopValue( "p" ) )
       
        'Return n1 + n2
        Stack.PushValue( "p", Array.GetValue(Fib_Locals, "n1") + Array.GetValue(Fib_Locals, "n2") )
        Goto Fib_Exit
      EndIf
     
    Fib_Exit:
      Fib_Locals = Fib_Locals - 1
    EndSub
     

    Tuesday, December 23, 2008 5:07 AM
  • I second that and I hope you will add it to Small Basic.

    I agree that you should avoid the concept of variable scoping, but there certainly is a need for local variables.

    My son uses variables x and y to store coordinates. He has a hard time understanding that his variables are overwritten by sub routines or even event handlers.

    The <subroutinename>.<variablename> syntax is an elegant solution to this problem.
    • Edited by Marc_Derksen Tuesday, December 23, 2008 10:44 AM Typos
    Tuesday, December 23, 2008 10:40 AM
  • I don't have any problems keeping track of variables in my Basic programs so as it is, it works for me.
    I know that if I use a variable for one thing, it can't be used for something else.
    I guess I don't miss what I don't know.

    ...but if passing params is an important part of the real programing world, then maybe it should be added so there is less acclimation required.
    Like including "event based" programming.


    Then again, learning the hard way might make you apprecaite the easy way, as well as having more experince just by knowing the hard way.


    In Kenny's example, it looks to like the VB way will print 23.

    If that is all it is doing then why all the Stack commands in the Small Basic example?
    Won't the following do the same thing?

    n = 13
    Gosub Fib
    TextWindow.WriteLine (FibResults)

    Program.End()

    Sub Fib
        If n < 2 Then
            FibResults = n
        Else
            FibResults = (n - 1) + (n - 2)
        EndIf
    EndSub

    (You could even replace FibResults with n as the variable unless you need to use n, with value of 13, later on in the program.)

    ...or am I totally off base here?
        
    Tuesday, December 23, 2008 9:33 PM
  • Not 23, but 233

    I think you missed a subtle point.  In the VB way:

    Function fib(ByVal n)
        If n < 2 Then
            Return n
        Else
            Return fib(n - 1) + fib(n - 2)
        End If
    End Function


    The second "Return" actually calls the fib() function again, recursively.  In order for that to work, you need "n" to be a stack-based parameter.

    I would, however, would like to make one correction to my example.  The arrayName used for the local variables needs to be qualified by the name of the function so it's unique.

    So the full code should look like this:

    ' Call Fib( 13 )
    Stack.PushValue( "p", 13 )
    Fib()
    TextWindow.WriteLine( Stack.PopValue( "p" ) )

    Sub Fib ' n
      Fib_Locals = Fib_Locals + 1
     
      'Set up params:
      Array.SetValue( Text.Append( "Fib", Fib_Locals), "n", Stack.PopValue( "p" ) )

      If Array.GetValue( Text.Append( "Fib", Fib_Locals), "n") < 2 Then
        ' Return n
        Stack.PushValue( "p", Array.GetValue( Text.Append( "Fib", Fib_Locals), "n") )
        Goto Fib_Exit
      Else
        'n1 = Fib( n - 1 )
        Stack.PushValue( "p", Array.GetValue( Text.Append( "Fib", Fib_Locals), "n") - 1 )
        Fib()
        Array.SetValue( Text.Append( "Fib", Fib_Locals), "n1", Stack.PopValue( "p" ) )
       
        'n2 = Fib( n - 2 )
        Stack.PushValue( "p", Array.GetValue( Text.Append( "Fib", Fib_Locals), "n") - 2 )
        Fib()
        Array.SetValue( Text.Append( "Fib", Fib_Locals), "n2", Stack.PopValue( "p" ) )
       
        'Return n1 + n2
        Stack.PushValue( "p", Array.GetValue( Text.Append( "Fib", Fib_Locals), "n1") + Array.GetValue( Text.Append( "Fib", Fib_Locals), "n2") )
        Goto Fib_Exit
      EndIf
     
    Fib_Exit:
      Fib_Locals = Fib_Locals - 1
    EndSub

    I posted this on the wiki: http://smallbasic.com/smallbasic.com/wiki/Edit.aspx?Page=Fibonacci

    I also posted the explanation of how parameters and local variables can be simulated:
    How to Simulate Local Variables: 
    http://smallbasic.com/smallbasic.com/wiki/Simulating Local Variables.ashx
    How to Simulate Parameters: http://smallbasic.com/smallbasic.com/wiki/Simulating Parameters.ashx

    Wednesday, December 24, 2008 11:20 PM
  • Why do you use this complex algorithm for the Fibonacci's series

    I do so...

    For i=1 To 20
      n = Math.Ceiling((1 / Math.SquareRoot(5)) * (Math.Power(1.618,i) - Math.Power(-0.618,i))) 'Fibonacci function
      TextWindow.WriteLine("Fib("+i+")="+n)
    EndFor

    and I have the first 20 terms

    ... or view this solution (http://smallbasic.com/program/?BPB749). I hope you like that

    Bye

    Wednesday, October 14, 2009 10:16 PM