functions in fig

this is part 7 of an introductory series on fig programming. for part 6, go here.

 

part 7: functions in fig

 

in the previous chapter, we put together some code that asks for (and insists upon) a number.

if youve ever been to a website that rejected some input because it wasnt suitable, the code that does that is very similar. (its likely written in javascript or php though, because those are still very common languages for websites.)

we have learned several fig commands, and there are several more to learn in this chapter– but for the moment we are going to learn how to make new ones. first here is the code from before:

while
    x "please enter a number: " prints lineinput
    try
        y x val
        break
        except
        now "" print "thats not a number." print
        resume
    wend
now y print # this is the number we know is numeric

 

see the now y print at the bottom? the variable y is the one we get when things go right. keep that in mind.

to create a function (a new fig command) called thisthing which uses one parameter: x and converts it to the cosine of x radians, do this:

function  thisthing x
    now  x  cos  return now
    fig

 

ok, but thats not what we are doing. we are going to create a function called asknumeric with zero parameters.

we define our function using a function block:

function asknumeric
    # we really need the pass command here.
    fig

 

and the code inside the block will produce a variable called y, so lets ask the function to return that value (as the functions own value)

function asknumeric
    # our code will go here
    now return y
    fig

 

lets put the two together:

function asknumeric

while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        break
        except
        now ""  print  "thats not a number." print 
        resume
    wend
now y print # this is the number we know is numeric

    now return y
    fig

 

we can get rid of the “now y print” line:

function asknumeric
while
    x "please enter a number: "  prints  lineinput
    try
        y x  val
        break
        except
        now ""  print  "thats not a number." print 
        resume
    wend
    now return y
    fig

 

okay, run the program…

what? it doesnt do anything. congrats! its your first custom-made fig command.

youve defined it using function but you havent used it yet!

your new function is called asknumeric and always returns a number, so you can use it like this:

x  asknumeric  times 1000  print

 

any time you want to use your asknumeric command, just use it like you would any other fig command. (it will only be available in programs that contain the definition before you use it.)

you can even create a user-defined function that calls another user-defined function:

function doitagain
    x  asknumeric  times 1000  print
    fig
now doitagain

 

lets run this and see what happens…

please enter a number: okay

thats not a number.
please enter a number: yes it is!

thats not a number.
please enter a number: a number

thats not a number.
please enter a number: 5.78
5780

 

one of the more interesting things about writing programs is coming up with names for the different variables (and functions.)

if you pick a name that is too short or not very descriptive– x for example, is really only “descriptive” if youre describing a point on a horizontal axis– then you cause anyone reading your code to suffer a little.

if you pick a name that_is_too_absurdly_long then you cause anyone re-using (referencing) that name to suffer. people dont seem to mind this as much (i do, so i tend not to use very long names.)

if youre writing a manual, it matters somewhat less because people know “x” is always a variable.

but coming up with names is “work” sometimes.

whats more, is coming up with names can get in the way of more pressing or important matters; anything that helps reduce the amount of “overhead” in terms of organizing used and unused variable names is an idea worth considering.

one handy thing about functions is “scope.” if you are defining a function, the name you use to call (reference, refer to) the function– its name– is a thing you have to put some thought into. you want to give it a name that explains what it does, and preferably will also be easy to think of later.

everything inside the function is more or less isolated. this isolation is called “scope,” and it can be viewed as an inconvenience or an enormous help.

if youre writing a large, complicated program, organizing everything into functions is the best thing you can do. (you can also use objects, which are more complicated, and then “functions” will be called “methods” as far as terminology goes. but fig doesnt really get into objects.)

because of this “scope” isolating the stuff inside the function block, you (usually) need a way to get information from the program into the function.

in our first example, information gets into the function by way of the lineinput command. but if you refer to a program variable thats outside of a function youve created, the function will not know anything about it.

put another way: a variable called “cheese” outside the function block is going to have a totally different value / significance / relevance as a variable with the same name inside the function.

this is great because when youre creating a function, you dont have to know what variables are used in the program that calls it. for all you know, “x” is the most important variable in the whole program– so if you need a variable named “x” in your function, its completely separate; the two dont interfere. every function can have its very own “x” variable with its own value.

and every function does get its own variables. but what if you want to get some information from the program into the function? this is done with parameters.

lets name a couple of parameters thing1 and thing2. (you can have 0 or more parameters, even 20 of them. however the smaller the number, the better.) parameters dont need numbers by the way: we are using numbers in the name purely for fun.

function inthehat thing1 thing2
    pass
    fig

 

is a valid definition. lets have it print the number of characters in each parameter:

function inthehat thing1 thing2
    q 34  chr
    now q  plus thing1  plus q  plus " has " prints
    now thing1  len  str plus " characters." print

    now q  plus thing2  plus q  plus " has " prints
    now thing2  len  str plus " characters." print
    fig

 

and lets call the function, with two strings:

now  inthehat "hello" "mike"

 

outputs this:

“hello” has 5 characters.
“mike” has 4 characters.

 

one of the fun things about this code is it adds ascii 34 (a computer code for a double quote) to the string, so the output can display the string in quotes. that would be a useful function, actually:

function quote qstring
q 34  chr
withquotes q  plus  qstring  plus q  print
fig
now "this will be printed in quotes"  quote now

 

it works perfectly, but all it does is build the quotes into the string and print it. wouldnt it be cool if like other built-in functions, it could change the value of the main variable?

well, thats what return is for. lets change one line:

function quote qstring
q 34  chr
withquotes q plus qstring plus q  return withquotes
fig

 

now we have a function we can use anywhere in our program– so long as its after the function definition. lets fix up our other function with it. it does the same as before, with cleaner lines:

function quote qstring
q 34  chr
withquotes q plus qstring plus q  return withquotes
fig

function inthehat thing1 thing2
    now  quote thing1  plus " has " prints
    now thing1  len  str plus " characters." print

    now  quote thing2  plus " has " prints
    now thing2  len  str plus " characters." print
    fig

 

and call it:

now  inthehat "hello" "mike"

 

“hello” has 5 characters.
“mike” has 4 characters.

 

and it works! our function uses the len function (built in) to figure out how many characters the strings have– len will also find the length of an array, but not a numeric. so if you do this:

now  inthehat "hello" 5

 

your function will not work. you can fix this by putting the line that has len in a try / except / resume conditional block, and deciding what to say if it trips the except section.

you can also reword the ” characters.” string so that it says something like “ characters (or array elements).” thats up to your preference, obviously.

hopefully from these examples you can practice writing and editing functions. they are very powerful: half the job of creating your own programming language could be writing functions. fig has more functions built-in, so lets see them:

x  y  lcase  # copy y to x and make all-lowercase


x  y  ucase  # copy y to x and make all-uppercase


x  y  str  # copy y to x and convert num to string 


x  "dir"  shell  # run commands in bash/sh or dos 


x  "hello"  asc  # convert first character in a string to 
                 # numeric ascii code


x  "50.537"  val # convert string number to numeric


x  "hello there"  len  # length of string or array


x  52  not  # return -1 for zero and 0 for non-zero


x  "  space from left"  ltrim # cut lefthand space


x  "space from right  " rtrim # cut righthand space


x  10  chr  # convert integer to ascii / unicode
x  "dir"  arrshell  # load an array with command line output


x  arreverse  # reverse the order of an array


x  y  reverse  # copy string y to x and reverse


x  arrsort  # sort an array


x "hello"  left 2  # get leftmost 2 characters


x "hello"  right 2  # get rightmost 2 characters
    

x  arrget rr 5  # set x to 5th item of array rr


rr arrset 5 "hello" # set 5th item in rr to "hello"


x  y  mid 5 1  # copy y to x, and set x to a range/section of 1 
               # character(s) or item(s) starting with the 
               # 5th. (works on strings and arrays.)


p  string 12 104  # string of 12 x  ascii 104


p  string 12 "h"  # string of 12 x  "h"


x  instr "hello" "e"   # finds the first instance of "e” in 
                       # "hello” and returns the position; which 
                       # in this case is 2 (0 if not found.)


x  "/"  chdir  # changes the folder the program is working in.


now  end  # quits the program (closes files too)


now  system  # exactly the same as end


now  swap x y  # switches the values of x and y


now  get parametername  # earlier versions of fig required this 
                        # to copy parameters inside functions; 
                        # it is no longer required, but can still 
                        # be used to copy variables into the main
                        # variable.


x  split "hello" "e"  # split string by "e" into array ['h', 'llo']


e  join x "a"  # join array using "a" in between items

 

splitting by “e” and joining by “a” will change all instances of “e” to “a” in a string. you can create a function called replace like this:

function replace changewhat chfrom chto
    p  split changewhat chfrom  join p chto 
    now  return p     
    fig

 

then you can call it this way:

phrase "hello there"  replace phrase "he" "a"

 

here are a couple more functions you can use; basic and python (therefore fig) use radians for angles in trig functions. perhaps you would like to use degrees:

(all the code in this book is in the public domain / has its copyright waived under cc0, so feel free to use these functions in your programs)

function degrees2radians dg
    pi 1  atn  times 4   
    rd dg  times pi  divby 180  return rd    
    fig
function radians2degrees rd
    pi 1  atn  times 4   
    dg rd  times 180  divby pi  return dg    
    fig

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s