Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Functions vs Procedures - Passing Arguments and which to use
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
np_123




PostPosted: Thu Jan 02, 2014 12:58 pm   Post subject: Functions vs Procedures - Passing Arguments and which to use

What is it you are trying to achieve?
Functions or Procedures - Which one to use


What is the problem you are having?
Deciding whether to keep passing variables arguments to procedure or somehow turn it into a function

I should mention that I did look through the Tutorial section - The Turing Walkthrough... - Functions and Procedures

Cervantes wrote:

I sincerely hope this has convinced you that functions are superior to procedures. I'm not saying that functions should be used exclusively. There are times when procedures are needed. Rather, I'm just saying that when you have a choice of using a function or using a procedure, choose the function. Nice functions are ones that compute a value based soley on the parameters they take. They don't rely on any global variables. These are functions that are easily documented. At the other extreme are procedures that use global variables inside their definition and also take in variables and modify them. These procedures are dangerous! and very hard to document.


After reading that, I am still unsure about whether my procedure is fine as it is or if I should find another way in order to avoid passing variables as arguments.
I am willing to put effort forward into any suggestion or critique - my primary concern is the way I SHOULD do it, rather than how I've already done it...
After all, I've rewritten the code for the entirety of the program at least 3 times already, using different methods and making it better each time.

My problem is that he values of the elements within the arrays bpcs, rpcs, bking, rking must be changed at some point because the pieces are being moved within the procedure, and the new positions must reevaluate to being true, and the old positions false


Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
This is what I currently have in one of my procedures...
The code may be more understandable if I mention that this is a complete procedure, and an excerpt from a working checkers game that I created
Oh, and the couple of commented lines are simply what I used for debugging

I've attached the main body of the program, the file from which it would actually be run from, to show where I initially declare the variables and the general path for the execution of the program. If necessary, I can upload other/the remainder of files required for one to run the program.

Turing:


proc redmove (var bpcs, rpcs, bking, rking : array - 2 .. 11, -2 .. 11 of boolean, center : array 1 .. 2, 1 .. 8, 1 .. 8 of int)

    const posx := 1
    const posy := 2
    const size := maxy div 10
    var X, Y, Btn, btnUpDown, sqx, sqy, sqx1, sqy1 : int
    var square1, square2 : array 1 .. 2 of int

    loop

        square1 := GetPieceRed (bpcs, rpcs, bking, rking)

        sqx := square1 (1)
        sqy := square1 (2)
        %locate (1, 1)
        %put "redx", sqx ..
        %put "redy", sqy ..
        redselect (rking, center, sqx, sqy)

        square2 := GetPieceRed1 (bpcs, rpcs, bking, rking, sqx, sqy)

        sqx1 := square2 (1)
        sqy1 := square2 (2)

        if sqx1 < 9 and sqx1 > 0 and sqy1 > 0 and sqy1 < 9
                and abs (sqx1 - sqx) = 1 and abs (sqy1 - sqy) = 1 and bpcs (sqx1, sqy1) = false
                and bking (sqx1, sqy1) = false and rpcs (sqx1, sqy1) = false and rking (sqx1, sqy1) = false
                and ((rpcs (sqx, sqy) = true and sqy1 > sqy) or rking (sqx, sqy) = true) then
            exit

        else

            Draw.FillOval (center (posx, sqx, sqy), center (posy, sqx, sqy), 25, 25, brightred)
            if rking (sqx, sqy) = true then
                Draw.FillOval (center (posx, sqx, sqy), center (posy, sqx, sqy), 5, 5, yellow)
            end if

        end if

    end loop


    Draw.FillBox (sqx * size + size, sqy * size, sqx * size + (size * 2), sqy * size + size, green)
    Draw.FillOval (center (posx, sqx1, sqy1), center (posy, sqx1, sqy1), 25, 25, red)
    if rking (sqx, sqy) = true then
        Draw.FillOval (center (posx, sqx1, sqy1), center (posy, sqx1, sqy1), 5, 5, yellow)
    end if

    if rpcs (sqx, sqy) = true then
        rpcs (sqx, sqy) := false
        rpcs (sqx1, sqy1) := true
    else
        rking (sqx, sqy) := false
        rking (sqx1, sqy1) := true
    end if

    %Input.Pause
    for count : 1 .. 8
        if rpcs (count, 8) = true then
            rpcs (count, 8) := false
            rking (count, 8) := true
            Draw.FillOval (center (posx, count, 8), center (posy, count, 8), 5, 5, yellow)
        end if
    end for
end redmove




Please specify what version of Turing you are using
4.1



0Main.t
 Description:
This file shows initialization of variables and the general path for the execution of the program

Download
 Filename:  0Main.t
 Filesize:  3.34 KB
 Downloaded:  53 Time(s)

Sponsor
Sponsor
Sponsor
sponsor
Raknarg




PostPosted: Thu Jan 02, 2014 1:22 pm   Post subject: RE:Functions vs Procedures - Passing Arguments and which to use

The reason functions should be used over procedures is that functions simply return a value for you. The value resulting from the function does not need to be tied to a variable

Take the randint function for example. In turing, you have randint (v, low, high) which puts a random value into v. There is also Rand.Int(low, high) which simply returns a value. It just makes more sense to use a function in this case, because the random value doesn not need to be tied to anything.

Turing:

var x : int := Rand.Int(1, 10)
var y : int
randint(y, 1, 10)

if Rand.Int(1, 2) = 1 then
    do_something()
end if

var rnd : int
randint (rnd, 1, 2)
if rnd = 1 then
    do_something()
end if


It's sloppier, and lot's of languages don't exactly support passing by reference (that's what it's called when you put var in front of a parameter), so it's better just to learn to use functions instead.

In any case, it makes your code cleaner and happier, easier to read. That's something you should always strive for

Also, I should mention, that you need to stop how you're doing variable names. Either write names that make more sense, or document it better, because if anyone has to read it(that includes you in the future, when you forget what everything does, because you WIL forget), they're going to shoot themselves in the head first
np_123




PostPosted: Thu Jan 02, 2014 1:58 pm   Post subject: Re: Functions vs Procedures - Passing Arguments and which to use

If I pass the value into the procedure like redmove (...) without using the var, can I call a function within that procedure to modify a variable that isn't declared in the procedure, if the right values are passed into it?

Because the way I see it, I need the arrays to updated in order to represent the piece locations, and to do that using functions, the function would then have to return a corresponding array, correct?
Except, then I wouldn't be able to do that from 'within' the procedure since I wouldn't be able to modify the value...
So, unless I return to the place where I declare the variables, I won't be able to change their values


I was told in my Gr11 ICS class, something along the lines of not using global variables - so ever since, when I write programs, I've tried to keep everything within procedures and functions, rather than declaring variables and whatnot outside - is that acceptable or should I be doing things differently???



And for the variable naming...for the most part I tried keeping it fairly straightforward (for me at least): sqx,sqy for coordinates of a square, rpcs for red pieces, etc. The main idea I tried following is that the variable was named, then I added r or b to represent the colour of the pieces...
(I originally started off using green as a piece colour, so I never actually changed the name for many variables or procedures/functions)

I'll take the critique as it's meant, and start trying to use more meaningful names
I probably should have learnt that lesson when I first tried making the program, like a year or so ago - then I stopped working on it - by the time I went back to it, the code was so much of a headache I started all over from scratch
np_123




PostPosted: Thu Jan 02, 2014 2:20 pm   Post subject: RE:Functions vs Procedures - Passing Arguments and which to use

I'm glad you mentioned that though, because I've actually applied to Software Eng, so all these pointers will be extremely helpful, cuz I have a lot of work to do before September

EDIT: I just headed back to The Turing Walkthrough in the Tutorials section - found Turing Style Guidelines by wtd, so I'll be going through that for sure
Raknarg




PostPosted: Thu Jan 02, 2014 3:55 pm   Post subject: RE:Functions vs Procedures - Passing Arguments and which to use

In general, the idea is if you're going to do something, try to do it in the way that makes the most sense, is easiest to understand, and be consistent. What I have up there are suggestions.

You would use var when you need to modify multiple variables or you need to modify an array, so if you're using var with an array, I would say that's fine.

Why do the arrays stretch from -2 to 11 though?
np_123




PostPosted: Thu Jan 02, 2014 4:25 pm   Post subject: Re: Functions vs Procedures - Passing Arguments and which to use

Hmm...I think that's something I had from when I first tried to make the program last year
I had it as such because to check if piece (x,y) can jump, I check if piece (x+2,y+2) is there or not, and a few other checks as well

I kept it above and below the 1-8 so it wouldn't crash when I check if an edge piece can jump
In that sense, it should actually be -1 to 10 for the arrays

I haven't been able to think of a way to get around that

Oh, and I set all the pieces outside the 1-8 range to True, so that moving off the board would not be a valid move
Dreadnought




PostPosted: Thu Jan 02, 2014 4:41 pm   Post subject: Re: Functions vs Procedures - Passing Arguments and which to use

np_123 wrote:

If I pass the value into the procedure like redmove (...) without using the var, can I call a function within that procedure to modify a variable that isn't declared in the procedure, if the right values are passed into it?

You mean, something like this?
Turing:

proc Add1 (var x:int)
    x += 1
end Add1

proc AddAndPrint(x : int)
    Add1(x)
    put x
end AddAndPrint

var a : int := 1
AddAndPrint(a)

This won't work since inside AddAndPrint there is no reference to a in fact in that procedure x is a constant.

np_123 wrote:

Because the way I see it, I need the arrays to updated in order to represent the piece locations, and to do that using functions, the function would then have to return a corresponding array, correct?
Except, then I wouldn't be able to do that from 'within' the procedure since I wouldn't be able to modify the value...
So, unless I return to the place where I declare the variables, I won't be able to change their values

As Raknarg said, modifying arrays with procedures is the correct approach.

np_123 wrote:

I was told in my Gr11 ICS class, something along the lines of not using global variables - so ever since, when I write programs, I've tried to keep everything within procedures and functions, rather than declaring variables and whatnot outside - is that acceptable or should I be doing things differently???

It is good practice to restrict the scope of variables as much as possible. In small projects there aren't really any consequences to not doing this, but in a big project it avoids variable names being already taken and clarifies the intent.


np_123 wrote:

And for the variable naming...for the most part I tried keeping it fairly straightforward (for me at least) sqx,sqy for coordinates of a square, rpcs for red pieces, etc. The main idea I tried following is that the variable was named, then I added r or b to represent the colour of the pieces...
(I originally started off using green as a piece colour, so I never actually changed the name for many variables or procedures/functions)

I'll take the critique as it's meant, and start trying to use more meaningful names
I probably should have learnt that lesson when I first tried making the program, like a year or so ago - then I stopped working on it - by the time I went back to it, the code was so much of a headache I started all over from scratch

The general guideline are that the more important a variable is the more descriptive its name should be. (when I say "important", I think of some vague measure of its scope and occurrence)

Overall, for coding style I think that what is really important (Raknarg mentioned this) is consistency. Pick a style (preferably one that promotes readability of your code) and stick to it. If you are modifying someone else's code, try to stick to their coding style to maintain consistency.

Also, for something like your array indices starting at -2, this is the kind of thing that looks odd when you look at it so placing a comment there clarifying whats going on might be nice (or you can try to think of a way of avoiding this oddity)
np_123




PostPosted: Thu Jan 02, 2014 8:03 pm   Post subject: Re: Functions vs Procedures - Passing Arguments and which to use

A fair amount of my procedures have very similar purposes, so naming them 'uniquely' was a bit tricky
So, the same procedure as I posted earlier...but would you consider this more readable?
(I added comment concerning the indices of the arrays when I first declared them)

Turing:


%Regular move Red
proc red_move (var blue_piece, red_piece, blue_king, red_king : array - 1 .. 10, -1 .. 10 of boolean, center : array 1 .. 2, 1 .. 8, 1 .. 8 of int)

    const X_POSITION := 1
    const Y_POSITION := 2
    const size := maxy div 10
    var X, Y, Btn, btnUpDown, x_location, y_location, x_location1, y_location1 : int
    var square1, square2 : array 1 .. 2 of int

    loop

        square1 := select_red_piece (blue_piece, red_piece, blue_king, red_king)

        x_location := square1 (1)
        y_location := square1 (2)

        redselect (red_king, center, x_location, y_location)

        square2 := select_second_red_piece (blue_piece, red_piece, blue_king, red_king, x_location, y_location)

        x_location1 := square2 (1)
        y_location1 := square2 (2)

        if x_location1 < 9 and x_location1 > 0 and y_location1 > 0 and y_location1 < 9
                and abs (x_location1 - x_location) = 1 and abs (y_location1 - y_location) = 1 and blue_piece (x_location1, y_location1) = false
                and blue_king (x_location1, y_location1) = false and red_piece (x_location1, y_location1) = false and red_king (x_location1, y_location1) = false
                and ((red_piece (x_location, y_location) = true and y_location1 > y_location) or red_king (x_location, y_location) = true) then
            exit

        else

            Draw.FillOval (center (X_POSITION, x_location, y_location), center (Y_POSITION, x_location, y_location), 25, 25, brightred)
            if red_king (x_location, y_location) = true then
                Draw.FillOval (center (X_POSITION, x_location, y_location), center (Y_POSITION, x_location, y_location), 5, 5, yellow)
            end if

        end if

    end loop


    Draw.FillBox (x_location * size + size, y_location * size, x_location * size + (size * 2), y_location * size + size, green)
    Draw.FillOval (center (X_POSITION, x_location1, y_location1), center (Y_POSITION, x_location1, y_location1), 25, 25, red)
    if red_king (x_location, y_location) = true then
        Draw.FillOval (center (X_POSITION, x_location1, y_location1), center (Y_POSITION, x_location1, y_location1), 5, 5, yellow)
    end if

    if red_piece (x_location, y_location) = true then
        red_piece (x_location, y_location) := false
        red_piece (x_location1, y_location1) := true
    else
        red_king (x_location, y_location) := false
        red_king (x_location1, y_location1) := true
    end if

    %Input.Pause
    for count : 1 .. 8
        if red_piece (count, 8) = true then
            red_piece (count, 8) := false
            red_king (count, 8) := true
            Draw.FillOval (center (X_POSITION, count, 8), center (Y_POSITION, count, 8), 5, 5, yellow)
        end if
    end for
end red_move

Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 8 Posts ]
Jump to:   


Style:  
Search: