A Detailed Understanding of Routine Parameters
Sheerpower routines can handle up to 32 parameters in total,
split into two categories:
- Up to 16 parameters can be passed into routines.
- Up to 16 parameters can be returned from routines.
The with clause names the parameters passed into the routine,
and the returning clause names the parameters returned from it.
Design Rationale: Why dynamic-then-fixed
parameters?
- Low ceremony to start: You can call
routines without predeclaring types, which speeds up
prototyping and keeps call sites simple.
- Early, clear failures: After first use
establishes the type, mismatches become compile-time errors
(not runtime surprises).
- Optimizable paths: Once the type is known,
the runtime is able to treat it as static for faster code
paths.
- Business safety: Prevents subtle data drift
(e.g., strings replacing reals) in long-lived large apps.
- Escape hatch remains: If you need ongoing
flexibility, pass an argument explicitly declared as
dynamic
to keep it open.
Contrasting Methods
- Always dynamic (e.g., scripting): maximal
flexibility, but errors can surface later.
- Always static (e.g., classical compiled): maximal
safety, but verbose upfront.
- Sheerpower hybrid: start flexible, then lock for
safety and speed.
In short, Sheerpower parameters begin flexible but quickly
become disciplined — favoring both developer speed and business
safety.
Parameter Passing
Parameters Passed into a Routine
By default, all parameters in Sheerpower are passed into a routine by reference.
This means the routine works directly with the original data, rather than a copy.
As a result, parameter passing is highly efficient, no matter how large or complex
the data being passed.
Dynamic Parameter Types and Runtime Flexibility
Dynamic Parameters by Default
Routine parameters are initially dynamically typed.
This means a parameter can accept a STRING
, REAL
,
BOOLEAN
, INTEGER
, or even a custom type.
The first time the parameter is used establishes its data type for all
subsequent uses within the program. This determination does not occur if the
argument passed to the parameter was itself declared as dynamic
.
Important:
Once a parameter’s type has been determined, it cannot change.
If a different type is later passed to the same parameter,
Sheerpower will generate a compile-time error:
?? Inconsistent argument types were used. -- Argument "DO_TAXES$AMOUNT": Expected Real, got String
This prevents accidental misuse and ensures program consistency.
Example: Dynamic Parameters
routine display_value with input_data
print "Value: "; input_data
print "Type: "; typeof$(input_data)
print
end routine
! Calls with different data types
declare dynamic x
x = "Hello World"
display_value with input_data x ! STRING
x = 123.45
display_value with input_data x ! REAL
x = 42%
display_value with input_data x ! 42% is an INTEGER literal
Type Detection with typeof$()
routine format_output with data, returning formatted_result$
select case between$(typeof$(data), "Dtype:", " ")
case "String"
formatted_result$ = "Text: " + data
case "Real", "Integer"
formatted_result$ = "Number: " + str$(data)
case else
formatted_result$ = "Unknown type: " + typeof$(data)
end select
end routine
Returning Parameters
By default, values returned from a routine are copied into the named returning parameters.
Returning the same string multiple times is optimized internally, so performance remains fast.
Clusters as returning parameters are passed by reference. This lets routines add rows to cluster arrays
or update existing fields directly. Any changes made inside the routine are reflected
in the original cluster.
For Legacy Code:
Long ago, in older Sheerpower programs, routines sometimes modified with
parameters directly.
This was allowed back when the default calling method was by value.
To preserve this behavior, enable OPTION PERMISSIVE
at the top of your program.
With this option turned on, all with
parameters are passed by value
(copied), so they can be changed locally without affecting the caller’s original arguments.
Advantages of Named Parameters
- Clarity: Parameters clearly document their purpose.
- Order Independence: They can be passed in any order.
- Self-documenting Code: Inline documentation reduces comments.
- Maintainability: Explicit names make refactoring easier.
- Error Reduction: Reduces risk of mixing up parameters.
Tip: For clarity, use variable names that match the routine’s parameter names.
This allows you to call the routine with just the variables, in any order, and Sheerpower
will automatically match them.
Example of Named Parameter Usage
routine calculate_tax with income, tax_rate, returning tax_amount
tax_amount = income * tax_rate
end routine
calculate_tax with income=50_000, tax_rate=0.2,
returning tax_amount result
print "Tax Amount: "; result
! Using implied parameter values
income = 50_000
tax_rate = 0.2
calculate_tax with income, tax_rate, returning tax_amount
print "Tax Amount: "; tax_amount
Routines can also be called without any parameters.
This is typical for global routines.
Private and scoped routines almost always take parameters.
profit = 1234
tax_rate = 6.5/100
calculate_tax_due with amount profit, rate tax_rate,
returning due tax_due
print 'Tax due: '; tax_due
private routine calculate_tax_due with amount, rate,
returning due
due = amount * rate
end routine
There can be up to 16 parameters in the with clause
and up to another 16 in the returning clause.
For maintainability, keep the number of parameters small.
When large amounts of data must be exchanged, use cluster parameters (see next tutorial).
Performance Benefits of Pass-by-Reference
Research Insight:
Industry studies show 15–20% of code defects in languages like C++ are due to
parameter handling errors. Sheerpower’s design removes this risk by defaulting to
pass-by-reference with compile-time safety checks, eliminating the need to choose
between reference vs. value semantics.
Passing large data (like a 4 MB file or an entire Bible text) is as fast as passing
a single number, because only a reference is passed, not the data itself.
routine analyze_bible_text with bible_content$,
returning word_count
word_count = elements(bible_content$, " ")
end routine
Performance Summary
Sheerpower’s parameter model combines the speed of pass-by-reference
with compile-time safety, making it ideal for large-scale business
applications that demand both performance and reliability.
Simplifying Routine Calls
There are three increasingly concise ways to pass parameters:
! Full syntax
calculate_tax_due with amount=myamount, tax_rate=myrate,
returning due mydue
! Without "="
calculate_tax_due with amount myamount, tax_rate myrate,
returning due mydue
! Implied parameters
calculate_tax_due with amount, tax_rate, returning due
All three are equivalent—the last version being the simplest.
(Show/Hide Routine Parameters Takeaways)
Routine Parameters – Key Takeaways
-
Sheerpower routines support up to 32 parameters:
16 in the
with
clause (inputs) and 16 in the
returning
clause (outputs).
-
By default,
with
parameters are passed
by reference and treated as read-only,
providing both speed and compile-time safety.
-
Clusters are also passed by reference, so routines
can work directly with large data structures without copying.
-
Named parameters improve readability, allow order-independent
calls, and reduce errors; variable names can be used directly
for concise routine calls.
-
Parameters are dynamically typed and can accept
any type (STRING, REAL, INTEGER, BOOLEAN, etc.), with runtime type
detection available via
typeof$()
.
-
Passing large data (e.g., multi-MB text files) is as fast as passing
a single number because only references are passed.
-
There are three levels of syntax for routine calls:
full naming with
=
, explicit naming without =
,
and fully implied parameters — all equivalent, with the last being the simplest.