Sheerpower Logo

Routines and Variable Scoping


Sheerpower: Routines and Variable Scoping

As projects grow, it becomes essential to break code into smaller, reusable building blocks. In Sheerpower, these are called routines. They not only organize your code, but also control how variables are shared, isolated, or reset between calls.

Routine names: Routine names may contain only letters, numbers, and underscores (A—Z, 0—9, _). They must begin with a letter and include at least one underscore. For example, do_taxes is valid, but taxes is not. Routine names are case-insensitive. By design, Sheerpower never uses underscores in its own keywords, so your routine names will never collide with language features.

Types of Routines in Sheerpower

Global Routines: The default type. All global variables are accessible inside them.

Private Routines: Use their own variable namespace. By default, variables declared inside are local to that routine. If you need to access a global variable, prefix it with main$.

Note: The main$ prefix allows private, scoped, or local routines to access global variables directly.

Scoped Routines: Similar to private routines, but all non-static variables are cleared on entry and again on exit. Prefix any variable with static to preserve it across calls.

Local Routines: Defined inside another routine. They share the parent's scope and can only be called from that parent. This makes them ideal for breaking down complex logic into smaller steps without parameter-passing or scoping overhead.

Note: The compiler ensures local routines cannot be called from outside their parent, preventing accidental coupling or misuse.

Invoking Routines with Named Parameters

Routines always use named parameters. Do not prefix the call with call. Instead, write the routine name directly, followed by with (input) and returning (output) parameter assignments. Named parameters eliminate positional errors and make refactoring safer when parameter lists change.

Input parameters in the with clause are read-only — the compiler prevents any modifications. They are passed by reference for efficiency, but cannot be changed within the routine. A routine may accept up to 16 input parameters using the with clause.

Output values are specified using the returning clause. Up to 16 values may be returned, and each returned variable must be explicitly named in the call. Together, the with and returning clauses allow a maximum of 32 parameters per routine.


The 16-parameter limits are intended to keep routine interfaces readable and maintainable. If a routine requires more than 16 inputs or outputs, consider passing a cluster instead (structured collections of related values covered in the Data Structures tutorial).
routine calculate_area with length, width, returning area area = length * width end routine calculate_area with length = 10, width = 5, returning area room_area print "The area is: "; room_area

Output:

The area is: 50

Basic Return Example

routine calculate_area with length, width, returning area area = length * width end routine calculate_area with length = 10, width = 5, returning area room_area print "The area is: "; room_area

Returning Multiple Values

routine split_name with full_name$, returning first$, last$ first$ = element$(full_name$, 1, " ") last$ = element$(full_name$, 2, " ") end routine split_name with full_name$ = "Anna Rivera", returning first$ fname$, last$ lname$ print "First: "; fname$ print "Last: "; lname$

Overall Benefits

Sheerpower routines combine clarity, safety, and flexibility. Strong scoping rules reduce accidental variable misuse, while named parameters make code self-documenting and maintainable.

The next tutorial covers parameter passing in much more detail.

Flow Control Within a Routine

Sheerpower provides explicit flow-control statements for managing routine execution without relying on exceptions, flags, or deeply nested conditionals.

  • exit routine — Exit the routine immediately, returning control to the caller before reaching the routine’s normal end.
  • repeat routine — Restart execution of the routine from the beginning without resetting parameters or variables.
  • guard condition — Enforce a required condition; if it is not met, the routine exits immediately.

Example 1: exit routine — Early, Intentional Exit

Use exit routine when continuing execution no longer makes sense, but the situation is not exceptional.

routine print_discount with price, returning discounted if price <= 0 then // Invalid input -- nothing to do discounted = 0 exit routine end if discounted = price * 0.9 end routine print_discount with price = -50, returning discounted d print "Discounted price: "; d

Example 2: guard condition — Enforcing Preconditions

Use guard to make required conditions explicit and self-documenting.

routine process_payment with amount guard amount > 0 print "Processing payment of "; amount // ... payment logic ... end routine process_payment with amount = -20

Example 3: repeat routine — Controlled Retry Without Reset

Use repeat routine when a routine must retry its logic while retaining parameters and variable state.

routine read_until_valid with returning value static attempts attempts = attempts + 1 print "Attempt "; attempts input "Please enter a number between one and ten": value if value < 1 or value > 10 then print "Invalid number:"; value;" Please try again." repeat routine end if end routine read_until_valid returning value n print "Accepted value: "; n

Example 4: Combining guard and exit routine

This example demonstrates how guard enforces required inputs, while exit routine handles valid early-exit cases without error handling or deep nesting.

routine safe_divide with numer, denom, returning result result = 0 guard denom <> 0 if numer = 0 then exit routine end if result = numer / denom end routine safe_divide with numer = 10, denom = 0, returning result r print "Result: "; r

YIELD and CONTINUE — Generator-Style Routines

Sheerpower supports generator-style routines using yield and continue routine_name. This lets a routine suspend execution, return to the caller, and later resume exactly where it last yielded.

This is useful for incremental processing, streaming data, stateful iteration, and cooperative workflows where a routine produces results over time rather than all at once.

How yield Works

  • yield causes the current routine to return immediately to its caller.
  • The routine’s execution state is preserved — including local variables, static variables, and the current instruction position.
  • When resumed, execution continues at the statement immediately following the yield.

continue routine_name

To resume a previously yielded routine, use:

continue routine_name

The routine_name must be the name of a routine that has already executed a yield. Execution resumes from the last yield point inside that routine.

Example: Simple Generator Routines

generate_numbers with starting 1 do print counter continue generate_numbers if not _yield then exit do loop generate_numbers with starting 11 do print counter continue generate_numbers if not _yield then exit do loop read_file do print line$ continue read_file if not _yield then exit do loop stop // When a routine is called, execution starts at the beginning. // When YIELD is encountered, the routine returns and remembers where it // was. When CONTINUE is used, execution resumes from the last yield. routine generate_numbers with starting print "starting the count generator" counter = starting yield counter = counter + 1 yield counter = counter + 1 yield end routine routine read_file print "Opening the file to read" open file in_ch: name "@access.log" do line input #in_ch, eof eof?: line$ if eof? then exit do yield loop close #in_ch end routine

Key Characteristics

  • yield does not reset parameters or local variables.
  • Static variables naturally persist across yields.
  • Multiple yield statements may appear within the same routine.
  • Control flow remains explicit and easy to reason about.

When to Use yield

  • Streaming or incremental data processing
  • Stateful iteration without global variables
  • Breaking long computations into cooperative steps
  • Producing values over time instead of all at once

Unlike exception-based generators or hidden iterator objects in other languages, Sheerpower’s yield and continue statements keep control flow explicit, readable, and deterministic.

Yield Status: _yield

_yield is a built-in boolean status variable that indicates whether the most recent routine call or continue operation exited via a yield.

  • _yield is true if the routine executed a yield and can be continued.
  • _yield is false if the routine completed normally and cannot be continued.

_yield is set when a routine exits and reflects the outcome of the most recent routine call or continue operation.

This allows callers to determine whether a yielded routine is still active and decide whether further continue operations are valid.

continue routine_name is valid only if that routine has previously executed a yield and is currently suspended. If the routine is not in a yielded state, continue raises a runtime error.


Error Status & Routine Name: _error and _routine

_error is always false on routine entry and becomes true when you execute set error on; callers can check _error after the call. Also see the exception handling tutorial.

Inside a routine, _routine provides the routine's name as a string.

// Divide-by-zero guard using _error and exit routine routine safe_divide with numer, denom, returning quotient if denom = 0 then set error on exit routine end if quotient = numer / denom end routine // Caller: just check _error safe_divide with numer = 10, denom = 0, returning quotient q if _error then print "Error: divide by zero" else print "Quotient = "; q end if
// _routine returns the current routine name (string) routine reconcile_orders with date$, returning count print "I am in the routine called "; _routine // ... work ... count = 42 end routine

(Show/Hide Routine Syntax & Scoping Takeaways)

Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.