Scope/Function names and labels: Difference between revisions

m
(Scope/Function names and labels in FreeBASIC)
m (→‎{{header|Wren}}: Minor tidy)
(3 intermediate revisions by 3 users not shown)
Line 19:
In addition, functions etc. declared between IF and THEN are in scope in the THEN and ELSE parts, but
declarations in the THEN part and not visible in the ELSE part (and vice versa), so the following is invalid:
<langsyntaxhighlight lang="algol68">IF PROC x = ...;
...
THEN
Line 30:
...
l1: ...
FI</langsyntaxhighlight>
Similarly, declarations between WHILE and DO are in scope between DO and OD and those declared between CASE and IN are visible in the IN and OUT parts of a CASE.
<br>
Line 41:
=={{header|AWK}}==
In awk, function names are always global and can be referenced in sections of code appearing before the definition:
<langsyntaxhighlight lang="awk"># This program outputs a greeting
BEGIN {
sayhello() # Call the function defined below
Line 49:
function sayhello {
print "Hello World!" # Outputs a message to the terminal
}</langsyntaxhighlight>
Note that the awk extraction and reporting language is data driven and does not support arbitary line labels.
 
Line 57:
=={{header|BASIC}}==
Line numbers are used instead of labels. These are also immediately accessible as soon as the line is entered, even if the program is not run:
<langsyntaxhighlight lang="basic">GOTO 50: REM THIS WILL WORK IMMEDIATELY</langsyntaxhighlight>
The visibility of functions depends on the implementation. Most versions of basic will allow a function to be referenced from a point in the code prior to its definition. However, other implementations may require the function definition to be run, before it can be used:
<langsyntaxhighlight lang="basic">10 DEF FN S(A)=A*A
20 PRINT FN S(2): REM THIS WILL WORK
30 PRINT FN C(2): REM CALLING A FUNCTION PRIOR TO DEFINITION MAY NOT WORK
Line 66:
60 END
9000 DEF FN C(A)=A*A*A
9999 RETURN</langsyntaxhighlight>
 
=={{header|bc}}==
Line 75:
There are no labels in bc.
 
<langsyntaxhighlight lang="bc">f(1) /* First output line */
define f(x) {
return(x)
Line 84:
return(x - 1)
}
f(3) /* Third output line */</langsyntaxhighlight>
 
{{Out}}
Line 94:
Demonstrating function scope as well as goto in a C program invariably leads to code like the one below. The [http://en.wikipedia.org/wiki/Scope_(computer_science)#C Wikipedia article] is a good starting point.
 
<syntaxhighlight lang="c">
<lang C>
#include <stdio.h>
 
Line 145:
printf("If you are trying to figure out what happened, you now understand goto.\n");
return 0;
}</langsyntaxhighlight>
 
{{out}} Example run:
Line 161:
If you are trying to figure out what happened, you now understand goto.
</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
1. Delphi is a one pass compiler, so the names of procedures, functions, variables, constants and types are only visible to code that comes after the item was declared. Procedure and functions can be "Forward" declared, which allows them to be declared before they are defined.
 
2. All items inside an object are visible throughout the object, no matter the order they are defined. Outside an object, the object and items inside it are only visible to code that comes after it was declared.
 
3. Delphi prodedures and functions can be nested. Varibles inside a procedure or function are only visible from inside the same procedures or functions. Variable, procedures and functions at higher levels of nesting are visible to lower levels of nesting.
 
4. Items inside objects have controlled visibility to the outside world. Objects are divided in specific sections that control the visibility of items inside the section. Here is a list of sections:
 
Private: Items contained within the "Private" section of an object are only visible inside the object.
 
Protected: Item contained within the "Protected" section of an object are only visible inside the object or inside object that inherit from the object.
 
Public: Item contained within the "Public" section of an object are completely visible to the outside world.
 
Published: Item contained within the "Published" section of an object are visible to the outside world and can be manipulated by the IDE.
 
 
<syntaxhighlight lang="Delphi">
 
// Test1 is visible to Test2, but not vice versa.
// The local variables A, B, and C invisible to the outside world.
 
procedure Test1;
var A,B,C: integer;
begin
end;
 
procedure Test2;
var A,B,C: integer;
begin
end;
 
 
// Test1 is visible to all code that follows it.
// Test2 is invisible to the ouside world
 
procedure Test1;
var A,B,C: integer;
 
procedure Test2;
var A,B,C: integer;
begin
end;
 
begin
end;
 
 
// Item1 and Test1 are only visible inside the object
// Item2 and Test2 are additional to inhered objects
// Item3 and Test3 are visible to the outside world
// Item4 is visible to the outside world and the IDE
 
 
type TMyObject = class(TObject)
private
Item1: integer
procedure Test1;
protected
Item2: integer
procedure Test2;
public
Item3: integer
procedure Test3;
published
property Item4: integer read FItem4 write FItem4;
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
 
</pre>
 
 
=={{header|Eiffel}}==
Line 167 ⟶ 247:
 
All features are assigned (at compile-time) to a particular scope defined by the most-recently preceding feature clause. Various feature clauses are given below, from least restrictive (most visible) to most restrictive (most hidden).
<langsyntaxhighlight Eiffellang="eiffel">--assume A, B and C to be valid classes
class X
feature -- alias for "feature {ANY}"
Line 187 ⟶ 267:
-- features following this clause are only visible to this particular instance of X
 
end</langsyntaxhighlight>
 
=={{header|Erlang}}==
Line 194 ⟶ 274:
There are no labels.
 
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( a_module ).
 
Line 202 ⟶ 282:
 
local_function() -> 2.
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
Each word belongs to a vocabulary. Vocabularies may be added to the vocabulary search path to put their words in scope. For example, to use the <code>+</code> word:
<langsyntaxhighlight lang="factor">USE: math
2 2 +</langsyntaxhighlight>
 
Words are visible in the vocabulary where they are defined. But only after the point where they have been defined.
<langsyntaxhighlight lang="factor">USE: io
IN: hello-vocab
 
hello ! error; hello hasn't been defined yet
: hello ( -- ) "Hello, world!" print ;
hello ! visible here</langsyntaxhighlight>
 
This restriction can be lifted through the use of <code>DEFER:</code>.
 
<langsyntaxhighlight lang="factor">USE: io
IN: hello-vocab
 
Line 225 ⟶ 305:
hello ! visible here
: hello ( -- ) "Hello, world!" print ;
hello ! visible here</langsyntaxhighlight>
 
 
Line 271 ⟶ 351:
A function definition, either a top-level declaration or a function literal, represents a function block.
 
<langsyntaxhighlight lang="go">package main
 
import (
Line 294 ⟶ 374:
 
// ex.x() non-exported function not visible here
}</langsyntaxhighlight>
<langsyntaxhighlight lang="go">package ex
 
import (
Line 311 ⟶ 391:
func x() { // not exported, x not upper case.
panic("top level x")
}</langsyntaxhighlight>
{{out}}
<pre>
Line 319 ⟶ 399:
 
Labels can only be declared in function blocks. The scope is the function block where the label is declared excluding any nested function blocks.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 347 ⟶ 427:
}
 
// end: // labels not allowed outside function blocks</langsyntaxhighlight>
{{out}}
<pre>
Line 356 ⟶ 436:
Functions are considered global in haskell and can be referenced in the sections of code appearing before the function definition. The following code illustrates the same. add2 was declared after add3 and used in add3. The variables x,y and z are local to the function.
 
<langsyntaxhighlight lang="haskell">
add3 :: Int -> Int-> Int-> Int
add3 x y z = add2 x y + z
Line 364 ⟶ 444:
 
main :: putStrLn(show (add3 5 6 5))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 373 ⟶ 453:
In the function below the functions g and h are local to the function getSquaredSum. They cannot be called from anywhere outside the function.
 
<langsyntaxhighlight lang="haskell">
getSquaredSum :: Int-> Int-> Int
getSquaredSum x y = g x + h y
Line 379 ⟶ 459:
g a = a*a
h b = b*b
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 407 ⟶ 487:
'''Local''' scope, names defined using =. will have local scope if a block scope exists.
 
<langsyntaxhighlight lang="j"> a=. 1</langsyntaxhighlight>
 
'''Locale''' scope, names defined using =: will have locale scope (and the '''base''' locale is used by default).
 
<langsyntaxhighlight lang="j"> b=: 2</langsyntaxhighlight>
 
Names may include a locale qualifier. A locative is a qualified name. Locale qualifiers contain two '''_''' characters, are a suffix on what would be the unqualified name. Locale qualifiers come in two forms: absolute and relative. Relative locale qualifiers use another name in the current locale to identify the target locale. Absolute locatives place the locale name between the two '''_''' characters, while relative locatives name the locale reference following the pair of '''_''' characters.
 
<langsyntaxhighlight lang="j"> c_thingy_=: 3
d=: <'test'
e__d=: 4
b + e_test_
6</langsyntaxhighlight>
 
If a local definition exists for a name, it is an error to use use =: to assign that name (use a locative instead of the unqualified name if you really need to do this).
 
<langsyntaxhighlight lang="j">verb define ''
f=. 6
g=: 7
Line 430 ⟶ 510:
)
|domain error
| g =:9</langsyntaxhighlight>
 
Meanwhile, there is a global current locale (default: '''base''') but each verb's definition is evaluated with the current locale being the locale where that verb was defined.
Line 444 ⟶ 524:
Labels are available in explicit definitions, and are names beginning with '''label_''' and ending with a '''.'''. You may use them with a goto which is a name beginning with '''goto_''' and ending with a '''.'''. Use of labels is restricted to the scope where they are defined, and they cannot be used to enter control structures (except in the sense of the normal entry point).
 
<langsyntaxhighlight lang="j">example=:3 :0
if. y do.
echo 0
Line 463 ⟶ 543:
example 0
2
5</langsyntaxhighlight>
 
=={{header|jq}}==
Line 482 ⟶ 562:
A similar rule applies to two inner functions defined within the same enclosing function. Otherwise, inner functions of the same
name can co-exist. In particular, a function named NAME may define an inner function of the same name. For example:
<langsyntaxhighlight lang="jq">def NAME:
def NAME: 2;
1, NAME; # this calls the inner function, not the outer function
 
NAME # => 1, 2</langsyntaxhighlight>
 
'''Mutually Defined Functions'''
The "declare-before-use" rule means that two top-level functions cannot be defined in terms of each other. Consider the following example:
<langsyntaxhighlight lang="jq">def F(x): if x == 0 then M(x) else 1 end; # NOT POSSIBLE
def M(x): if x == 1 then F(x) else 2 end;</langsyntaxhighlight>
There are several possible workarounds using inner functions. For example, if both F and M must be top-level functions, we could define them as follows:
<langsyntaxhighlight lang="jq">def F(x):
def M(x): if x == 1 then F(x) else 2 end;
if x == 0 then M(x) else 1 end;
 
def M(x): if x == 1 then F(x) else 2 end;</langsyntaxhighlight>
If F and M are not required to be top-level functions, then both F and M could be defined as inner functions of the same enclosing function.
 
Line 552 ⟶ 632:
 
The following program illustrates some of these usages.
<langsyntaxhighlight lang="scala">// version 1.1.2
 
// top level function visible anywhere within the current module
Line 617 ⟶ 697:
l() // invokes lambda
println("Good-bye!") // will be executed
}</langsyntaxhighlight>
 
{{out}}
Line 636 ⟶ 716:
=={{header|Lua}}==
In Lua, variables are global by default, but can be modified to be local to the block in which they are declared.
<langsyntaxhighlight lang="lua">function foo() print("global") end -- global scope by default
foo()
local function foo() print("local module") end -- local to the current block (which is the module)
Line 655 ⟶ 735:
end -- close the block (and thus its scope)
foo() -- module-level local still exists
_G.foo() -- global still exists</langsyntaxhighlight>
{{out}}
<pre>global
Line 681 ⟶ 761:
There are statements Goto and Gosub as in Basic, including On Goto and On Gosub. We can make simple routines using Return to return from them.We can jump out from a block of code. We can't do the opposite, to enter in a block of code from outside. We can't jump out of Module or Function block, we can exit only using Exit or Break statements (Break exit on multiple blocks, Exit exit the current block). So Goto used to exit from a specific inner block to some block above it.
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Function Master {
Module Alfa {
Line 741 ⟶ 821:
\\ No variables exist after the return from Master()
Print Valid(M)=False
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Line 752 ⟶ 832:
Note that blocks are allowed anywhere where code is allowed, and so are labels. This is perfectly valid:
 
<langsyntaxhighlight Nimlang="nim"> const C = block useless: 3</langsyntaxhighlight>
 
=={{header|Objeck}}==
Line 763 ⟶ 843:
=={{header|Perl}}==
Perl allows various ways to futz with scope, but keeping it simple: Routines are package-scoped, and in each package the final definition of the routine is the one that is used throughout. Labels are generally also package-scoped, except when it comes to <code>goto</code>; let's don't even go there.
<langsyntaxhighlight lang="perl">no warnings 'redefine';
 
sub logger { print shift . ": Dicitur clamantis in deserto." }; # discarded
Line 785 ⟶ 865:
sub logger {
print shift . ": This thought intentionally left blank.\n" # routine for 'main' package
};</langsyntaxhighlight>
{{out}}
<pre>A: This thought intentionally left blank.
Line 801 ⟶ 881:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
Functions are normally internal to a program. If they are at the nesting level
immediately within the program, they are accessible from anywhere in the program.
Line 809 ⟶ 889:
Functions can be compiled separately, and then linked with a program
in which case they are globally accessible.
</syntaxhighlight>
</lang>
 
=={{header|PowerShell}}==
Line 817 ⟶ 897:
 
You can specify the scope of a function. For example, the function is added to the global scope in the following example:
<syntaxhighlight lang="powershell">
<lang PowerShell>
function global:Get-DependentService
{
Get-Service | Where-Object {$_.DependentServices}
}
</syntaxhighlight>
</lang>
When a function is in the global scope, you can use the function in scripts, in functions, and at the command line.
 
Line 828 ⟶ 908:
 
For more information about scope in Windows PowerShell, see about_Scopes
<syntaxhighlight lang="powershell">
<lang PowerShell>
Get-Help about_Scopes
</syntaxhighlight>
</lang>
 
=={{header|Python}}==
Line 847 ⟶ 927:
=={{header|Racket}}==
Racket inherits the strict lexical-scopedness of Scheme, so function bindings (like any other bindings) are visible only within their scope. For example
<langsyntaxhighlight lang="racket">
(define (foo x)
(define (bar y) (+ x y))
Line 853 ⟶ 933:
(foo 1) ; => 3
(bar 1) ; => error
</syntaxhighlight>
</lang>
but that applies only to the *bindings* -- the actual function values (like other values) can be passed around freely:
<langsyntaxhighlight lang="racket">
(define (foo x)
(define (bar y) (+ x y))
Line 861 ⟶ 941:
(foo 1) ; => #<procedure:bar>
((foo 1) 2) ; => 3
</syntaxhighlight>
</lang>
 
But it should be noted that Racket is flexible enough to make it possible to implement other kinds of scope.
Line 887 ⟶ 967:
</pre>
 
<syntaxhighlight lang="raku" perl6line># call a routine before it has been defined
say log(); # prints: outer
 
Line 939 ⟶ 1,019:
# call the original overridden CORE routine
say &CORE::log(e); # prints: 1 ( natural log of e )
}</langsyntaxhighlight>
 
Labels are less interesting and are typically useful only for control flow in looping constructs. They generally follow the same scoping rules as "my" variables. There is nearly always easier ways to do control flow though, so they aren't heavily used.
Line 966 ⟶ 1,046:
::::: (optional blanks)
::::::: ────(a repeat of the above as many times as is possible on a line of code)────
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates the use of labels and also a CALL statement. */
blarney = -0 /*just a blarney & balderdash statement*/
signal do_add /*transfer program control to a label.*/
Line 980 ⟶ 1,060:
add.2.args: procedure; parse arg x,y; return x+y /*first come, first served ···*/
add.2.args: say 'Whoa Nelly!! Has the universe run amok?' /*didactic, but never executed*/
add.2.args: return arg(1) + arg(2) /*concise, " " " */</langsyntaxhighlight>
'''output'''
<pre>
Line 988 ⟶ 1,068:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Scope/Function names and labels
 
Line 997 ⟶ 1,077:
func welcome(name)
see "hello " + name + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,007 ⟶ 1,087:
=={{header|Ruby}}==
'def' starts the definition of a method, and 'end' ends it - no cute little curly braces.
<langsyntaxhighlight lang="ruby">
def welcome(name)
puts "hello #{name}"
Line 1,014 ⟶ 1,094:
$name = STDIN.gets
welcome($name)
return </langsyntaxhighlight>
'''output'''
<pre>
Line 1,023 ⟶ 1,103:
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object ScopeFunction extends App {
val c = new C()
val d = new D()
Line 1,077 ⟶ 1,157:
println("Good-bye!") // will be executed
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
In Sidef, the same rule which is applied to variable scoping, is applied to functions and classes as well, which means that a function defined inside another function is not visible outside the current scope.
<langsyntaxhighlight lang="ruby"># Nested functions
func outer {
func inner {}; # not visible outside
Line 1,089 ⟶ 1,169:
class Outer {
class Inner {}; # not visisble outside
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
There are a number of different symbol types in Tcl, all of which are handled independently. Each namespace contains a mapping from (simple) command names to command implementations; when a command is looked up, the search is done by looking in the current namespace, then in the namespaces on that namespace's path (which is usually empty), and finally in the global namespace. There are ''no'' local commands (unlike with variables, though a lambda expression in a variable can act very similarly to a command). Commands only have a mapping after they have been created; the <code>proc</code> “declaration” is just a command that creates a procedure at the point where it is called.
<langsyntaxhighlight lang="tcl">doFoo 1 2 3; # Will produce an error
 
proc doFoo {a b c} {
puts [expr {$a + $b*$c}]
}
doFoo 1 2 3; # Will now print 7 (and will continue to do so until doFoo is renamed or deleted</langsyntaxhighlight>
Tcl does not support labels, either outside or inside procedures. (Other mechanisms are used for jumps and state machines.)
 
Line 1,105 ⟶ 1,185:
There is no lookahead in the shell, so functions cannot be called until their definition has been run:
 
<langsyntaxhighlight lang="sh">#!/bin/sh
multiply 3 4 # This will not work
echo $? # A bogus value was returned because multiply definition has not yet been run.
Line 1,114 ⟶ 1,194:
 
multiply 3 4 # Ok. It works now.
echo $? # This gives 12</langsyntaxhighlight>
 
The shell does not support the use of arbitrary line labels.
 
=={{header|V (Vlang)}}==
Vlang has both functions and labels.
 
A function definition, either a top level declaration or a function literal, represents a function block.
<syntaxhighlight lang="Vlang">
fn world() {
print("World!")
}
 
fn main() {
 
// anonymous function
f := fn() {
print("Hello ")
}
f() // "Hello
world() // World!"
 
// "Hello World!"
}
</syntaxhighlight>
Functions can be used before their declaration (below main), but can still be called from main.
 
This eliminates the need for header files or worrying about the order.
<syntaxhighlight lang="Vlang">
fn main() {
println(add(77, 33))
println(sub(100, 50))
}
 
fn add(x int, y int) int {
return x + y
}
 
fn sub(x int, y int) int {
return x - y
}
</syntaxhighlight>
Functions are private (not exported) by default. To allow other modules to use them, prepend pub
<syntaxhighlight lang="Vlang">
pub fn public_function() {
}
 
fn private_function() {
}
</syntaxhighlight>
Labelled break & continue:
 
You can also use break and continue followed by a label name to refer to an outer for loop.
<syntaxhighlight lang="Vlang">
outer: for i := 4; true; i++ {
println(i)
for {
if i < 7 {
continue outer
} else {
break outer
}
}
}
</syntaxhighlight>
Goto and labels:
 
1) The label name must be contained within the same function as the 'goto' statement.
 
2) Used only with 'unsafe' statements.
<syntaxhighlight lang="Vlang">
// Unsafe 'goto' pseudo example:
if x {
// ...
if y {
unsafe {
goto my_label
}
}
// ...
}
my_label:
</syntaxhighlight>
 
=={{header|Wren}}==
Line 1,126 ⟶ 1,286:
 
The following example illustrates these points.
<langsyntaxhighlight ecmascriptlang="wren">//func.call() /* invalid, can't call func before its declared */
 
var func = Fn.new { System.print("func has been called.") }
Line 1,139 ⟶ 1,299:
}
 
C.init() // fine</langsyntaxhighlight>
 
{{out}}
Line 1,148 ⟶ 1,308:
 
(with line 1 uncommented)
[./scope_function_namesScope_Function_names_and_labels line 3] Error at '}': Variable 'func' referenced before this definition (first use at line 1).
 
(with only line 7 uncommented)
func has been called.
Null does not implement 'init()'.
[./scope_function_namesScope_Function_names_and_labels line 7] in (script)
</pre>
 
Line 1,174 ⟶ 1,334:
 
Functions have two modifiers, public (the default) and private. Private is the same as public inside the compilation unit, outside that unit/file, a private function can only be accessed via reflection.
<langsyntaxhighlight lang="zkl">class C{ fcn [private] f{} }</langsyntaxhighlight>
 
=={{header|ZX Spectrum Basic}}==
Functions are visible as soon as they are entered, even if the program is not run. Line numbers are used instead of labels. These are also immediately accessible as soon as the line is entered, even if the program is not run:
<langsyntaxhighlight lang="zxbasic">9000 REM The function is immediately visible and usable
9010 DEF FN s(x)=x*x
 
PRINT FN s(5): REM This will work immediately
GO TO 50: REM This will work immediately</langsyntaxhighlight>
 
{{omit from|GUISS|does not have functions or labels}}
9,485

edits