Variables: Difference between revisions
(→{{header|AWK}}: real, no integer) |
(→{{header|AWK}}: foo() corrected, with example) |
||
Line 92: | Line 92: | ||
after the required arguments: |
after the required arguments: |
||
<lang awk> |
<lang awk> |
||
function foo( |
function foo(s, k) { |
||
# |
# s is an argument passed from caller |
||
# k is a dummy not passed by caller, but because it is |
# k is a dummy not passed by caller, but because it is |
||
# in the argument list, it will have a scope local to the function |
# in the argument list, it will have a scope local to the function |
||
k = length( |
k = length(s) |
||
print |
print "'" s "' contains", k, "characters" |
||
} |
|||
BEGIN { |
|||
k = 42 |
|||
s = "Test" |
|||
foo(s) |
|||
print "k is still", k |
|||
}</lang> |
}</lang> |
||
{{Out}} |
|||
<pre> |
|||
'Test' contains 4 characters |
|||
k is still 42 |
|||
</pre> |
|||
Numeric values are always real, there is no separate datatype for integer. |
Numeric values are always real, there is no separate datatype for integer. |
||
See also [[Arrays#AWK|Arrays]] |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
Revision as of 11:23, 25 November 2014
You are encouraged to solve this task according to the task description, using any language you may know.
Demonstrate the language's methods of variable declaration, initialization, assignment, datatypes, scope, referencing, and other variable related facilities.
Ada
<lang ada>declare
X : String := "Hello"; -- Create and initialize a local variable Y : Integer; -- Create an uninitialized variable Z : Integer renames Y: -- Rename Y (creates a view)
begin
Y := 1; -- Assign variable
end; -- End of the scope</lang>
ALGOL 68
Local variables are generally called local variables in ALGOL 68. Variables must be declared before use. In traditional ALGOL 68, variables must be declared before any labels: in a compound-clause. The declaration of a variable, without assigning a value takes the form: <typename> <variablename>; <lang algol68>int j;</lang> Some common types are: char, string, short int, int, long int, real, long real, bits and bytes .
Multiple variables may be defined in a single statement as follows: <lang algol68>LONG REAL double1, double2, double3;</lang> It is possible to initialize variables with expressions having known values when they are defined. The syntax follows the form <typename> <variablename> := <initializing expression>; <lang algol68>SHORT INT b1 := 2500; LONG INT elwood = 3*bsize, jake = bsize -2;</lang> The strings in ALGOL 68 are flex arrays of char. To declare initial space for a string of exactly to 20 characters, the following declaration is used. <lang algol68>FLEX[20]CHAR mystring;</lang> All arrays are structure that include both the lower lwb and upper upb of the array. Hence strings in ALGOL 68 may safely contain null characters and can be reassigned with longer or shorter strings.
To declare an initialized string that won't be changed the following declaration may be used: <lang algol68>[]CHAR mytext = "The ALGOL 68 Language";</lang> There are more rules regarding arrays, variables containing pointers, dynamic allocation, and initialization that are too extensive to cover here.
AppleScript
Variables are untyped in AppleScript, but they must be instantiated before use.
Example:<lang AppleScript>set x to 1</lang>
Scope may be explicitly defined before instantiation using either the global
or local
declarations.<lang AppleScript>global x
set x to 1
local y
set y to 2</lang>If undeclared, AppleScript will automatically set the scope based on the following rule: variables declared at the top level of any script will be (implicit) globals, variables declared anywhere else will be (implicit) locals. Scope cannot be changed after being explicitly or implicitly defined.
Where a variable has both local and global instances, it is possible to use the my
modifier to access the global (top-level) instantiation.
Example:<lang AppleScript>on localx()
set x to 0 -- implicit local
return x
end localx
on globalx() set x to 0 -- implicit local return my x end globalx
on run set x to 1 -- top-level implicit global return {localx(), globalx()} end run --> RETURNS: {0, 1}</lang>
Applescript also supports top-level entities known as properties
that are global to that script.
Example:<lang AppleScript>property x : 1</lang>Properties behave exactly as global variables except that they are persistent. Their most recent values are retained between script executions (or until the script is recompiled).
AutoHotkey
<lang autohotkey>x = hello ; assign verbatim as a string z := 3 + 4 ; assign an expression if !y ; uninitialized variables are assumed to be 0 or "" (blank string) Msgbox %x% ; variable dereferencing is done by surrounding '%' signs fx() { local x ; variable default scope in a function is local anyways global y ; static z=4 ; initialized once, then value is remembered between function calls }</lang>
AWK
In awk, variables are dynamically typecast, and do not need declaration prior to use. <lang awk> fruit = "banana" # create a variable, and fill it with a string a = 1 # create a variable, and fill it with a numeric value a = "apple" # re-use the above variable for a string </lang>
In awk multiple assignments are possible from within a single statement: <lang awk> x = y = z = 3 </lang>
Variables have global scope, and there is no way to make a variable local to a block.
However, function arguments are local,
so it is possible to make a variable local to a function
by listing the variable as an additional dummy function argument
after the required arguments:
<lang awk>
function foo(s, k) {
# s is an argument passed from caller # k is a dummy not passed by caller, but because it is # in the argument list, it will have a scope local to the function k = length(s) print "'" s "' contains", k, "characters"
} BEGIN {
k = 42 s = "Test" foo(s) print "k is still", k
}</lang>
- Output:
'Test' contains 4 characters k is still 42
Numeric values are always real, there is no separate datatype for integer.
See also Arrays
BASIC
In BASIC, variables are global and there is no scope. However, it is an error to reference a variable before it has been assigned.
<lang gwbasic>10 LET A=1.3 20 LET B%=1.3: REM The sigil indicates an integer, so this will be rounded down 30 LET C$="0121": REM The sigil indicates a string data type. the leading zero is not truncated 40 DIM D(10): REM Create an array of 10 digits 50 DIM E$(5.10): REM Create an array of 5 strings, with a maximum length of 10 characters 60 LET D(1)=1.3: REM Assign the first element of d 70 LET E$(3)="ROSE": REM Assign a value to the third string 80 PRINT D(3): REM Unassigned array elements have a default value of zero 90 PRINT E$(3): REM Ten spaces because string arrays are not dynamic 100 PRINT E$(3);"TTA CODE": REM There will be spaces between rose and etta 110 DIM F%(10): REM Integers use less space than floating point values 120 PRINT G: REM This is an error because f has not been defined 130 PRINT D(0): REM This is an error because elements are numbered from one 140 LET D(11)=6: REM This is an error because d only has 10 elements 150 PRINT F%: REM This is an error because we have not provided an element number 160 END</lang>
Applesoft BASIC
In Applesoft BASIC, variables are global and there is no scope. And, it is not an error to reference a variable before it has been assigned. The LET keyword is optional. Almost all math is done using floating point numbers by default. Using floating point variables is almost always faster than using integer variables which require extra conversion between floating point and integer. Integers use less space than floating point values. Applesoft BASIC array indexes start at zero.
<lang ApplesoftBasic> 10 A = 1.7: REM LET IS NOT REQUIRED
20 LET B% = 1.7: REM THE PERCENT SIGN INDICATES AN INTEGER; THIS GETS TRUNCATED DOWN 30 LET C$ = "0121": REM THE DOLLAR SIGN INDICATES A STRING DATA TYPE. THE LEADING ZERO IS NOT TRUNCATED 40 DIM D(20): REM CREATE AN ARRAY OF 21 FLOATING POINT NUMBERS 50 DIM E$(5,10): REM CREATE A TWO DIMENSIONAL ARRAY OF 66 STRINGS 60 LET D(1) = 1.3: REM ASSIGN THE SECOND ELEMENT OF D 70 Y$(3) = "ROSE": REM ASSIGN A VALUE TO THE FOURTH STRING 80 PRINT X: REM UNASSIGNED FLOATING POINT AND INTEGER VARIABLES HAVE A DEFAULT VALUE OF ZERO 90 PRINT Y$(2): REM UNASSIGNED STRING VARIABLES ARE EMPTY 100 PRINT Y$(3);"TTA CODE": REM THERE WON'T BE SPACES BETWEEN ROSE AND ETTA 110 F%(10) = 0: REM IF ARRAYS ARE NOT DECLARED THEY HAVE 11 ELEMENTS BY DEFAULT; IE. DIM F%(10) 120 PRINT G: REM THIS PRINTS 0 AND IS NOT AN ERROR EVEN THOUGH G HAS NOT BEEN DEFINED 130 PRINT D(0): REM THIS IS NOT AN ERROR BECAUSE ELEMENTS ARE NUMBERED FROM ZERO. 140 PRINT F%: REM THIS PRINTS 0 BECAUSE F% IS A DIFFERENT VARIABLE THAN THE ARRAY F%(10) 150 LET D(21) = 6: REM THIS IS AN ERROR BECAUSE D ONLY HAS 21 ELEMENTS INDEXED FROM 0 TO 20.</lang>
Batch File
Batch file variables are not limited to data types and they do not need to be initialized before use.
<lang dos> @echo off
- setting variables in defferent ways
set myInt1=5 set myString1=Rosetta Code set "myInt2=5" set "myString2=Rosetta Code"
- Arithmetic
set /a myInt1=%myInt1%+1 set /a myInt2+=1 set /a myInt3=myInt2+ 5
set myInt set myString pause>nul </lang>
BBC BASIC
<lang bbcbasic> REM BBC BASIC (for Windows) has the following scalar variable types;
REM the type is explicitly indicated by means of a suffix character. REM Variable names must start with A-Z, a-z, _ or `, and may contain REM any of those characters plus 0-9 and @; they are case-sensitive. A& = 123 : REM Unsigned 8-bit byte (0 to 255) A% = 12345678 : REM Signed 32-bit integer (-2147483648 to +2147483647) A = 123.45E6 : REM Variant 40-bit float or 32-bit integer (no suffix) A# = 123.45E6 : REM Variant 64-bit double or 32-bit integer A$ = "Abcdef" : REM String (0 to 65535 bytes) REM Scalar variables do not need to be declared but must be initialised REM before being read, otherwise a 'No such variable' error is reported REM The static integer variables A% to Z% are permanently defined. REM BBC BASIC also has indirection operators which allow variable-like REM entities to be created in memory: DIM addr 7 : REM Allocate 8 bytes of heap ?addr = 123 : REM Unsigned 8-bit byte (0 to 255) !addr = 12345 : REM Signed 32-bit integer (-2147483648 to +2147483647) |addr = 12.34 : REM Variant 40-bit or 64-bit float or 32-bit integer $addr = "Abc" : REM String terminated by CR (0 to 65535 bytes) $$addr = "Abc": REM String terminated by NUL (0 to 65535 bytes) REM The integer indirection operators may be used in a dyadic form: offset = 4 addr?offset = 12345678 : REM Unsigned 8-bit byte at addr+offset addr!offset = 12345678 : REM Signed 32-bit integer at addr+offset REM All variables in BBC BASIC have global scope unless they are used REM as a formal parameter of a function or procedure, or are declared REM as LOCAL or PRIVATE. This is different from most other BASICs.</lang>
Bracmat
Variable declaration.
Variables local to a function (i
and j
in the example below) can be declared just before the body of a function.
<lang bracmat>(myfunc=i j.!arg:(?i.?j)&!i+!j)</lang>
Global variables are created the first time they are assigned a value.
Initialization.
Local variables are initialised to 0
.
Assignment. There are two ways.
To assign unevaluated code to a variable, you normally would use the <variable>=<unevaluated expression>
syntax.
To assign an evaluated expression to a variable, you use pattern matching as in <evaluated expression>:?<variable>
Datatypes. There are no datatypes. The nature of an expression is observed by pattern matching.
Scope. Local variables have dynamic scope.
Referencing. Variables are referenced using the !<variable>
syntax.
Other variable related facilities.
Global variables (name as well as value) can be removed from memory with the built-in tbl
function.
The names of built-in functions such as put
and lst
can be used as variable names without adverse effects on the built-in function. It is not possible to redefine built-in functions to do something different.
C
Local variables are generally called auto variables in C. Variables must be declared before use. The declaration of a variable, without assigning a value takes the form <typename> <variablename>; <lang c>int j;</lang> Some common types are: char, short, int, long, float, double and unsigned.
Multiple variables may be defined in a single statement as follows: <lang c>double double1, double2, double3;</lang> It is possible to initialize variables with expressions having known values when they are defined. The syntax follows the form <typename> <variablename> = <initializing expression>; <lang c>short b1 = 2500; long elwood = 3*BSIZE, jake = BSIZE -2;</lang> Strings in C are arrays of char terminated by a 0 or NULL character. To declare space for a string of up to 20 characters, the following declaration is used. <lang c>char mystring[21];</lang> The extra length leaves room for the terminating 0.
To declare an initialized string that won't be changed the following declaration may be used: <lang c>const char * mytext = "The C Language";</lang> There are more rules regarding arrays, variables containing pointers, dynamic allocation, and initialization that are too extensive to cover here.
ChucK
Much like C or C++, declared but not initialized: <lang> int a; </lang> Multiple declaration: <lang>int b,c,d; </lang> Declared and initialized: <lang>0 => int e;</lang>
C++
Much like C, C++ variables are declared at the very start of the program after the headers are declared. To declare a as an integer you say: the type of variable; then the variable followed by a semicolon ";". <lang cpp>int a;</lang>
Template variables are specified with template parameters in angle brackets after the class name: <lang cpp>std::vector<int> intVec;</lang>
C#
Variables in C# are very dynamic, in the form that they can be declared practically anywhere, with any scope. As in other languages, often used variables are: int, string, double etc.
They are declared with the type first, as in C: <lang csharp>int j;</lang>
Multiple variables may be defined in a single line as follows: <lang csharp>int p, a, d;</lang>
It is also possible to assign variables, either while declaring or in the program logic: <lang csharp>int a = 4; int b; int c = Func(a);
b = 5;</lang>
COBOL
For example usage of array variables in COBOL, see Arrays#COBOL.
Assignment
Variables can be assigned values using either MOVE
or SET
. SET
is used for assigning values to indexes, pointers and object references, and MOVE
is used for everything else.
<lang cobol>MOVE 5 TO x
MOVE FUNCTION SOME-FUNC(x) TO y
MOVE "foo" TO z
MOVE "values 1234" TO group-item
SET some-index TO 5</lang>
One of COBOL's more well-known features is MOVE CORRESPONDING
, where variables subordinate to a group item are assigned the values of variables with the same names in a different group item. The snippet below uses this to reverse the date:
<lang cobol>01 normal-date.
03 year PIC 9(4). 03 FILLER PIC X VALUE "-". 03 month PIC 99. 03 FILLER PIC X VALUE "-". 03 dday PIC 99. *> Misspelling is intentional; day is a reserved word.
01 reversed-date.
03 dday PIC 99. 03 FILLER PIC X VALUE "-". 03 month PIC 99. 03 FILLER PIC X VALUE "-". 03 year PIC 9(4).
... PROCEDURE DIVISION.
MOVE "2012-11-10" TO normal-date MOVE CORR normal-date TO reversed-date DISPLAY reversed-date *> Shows '10-11-2012'</lang>
Declaration
Variables in COBOL are declared in the DATA DIVISION
. In standard COBOL, they can be declared within it in:
- the
FILE SECTION
, where sort-files/file records are defined and associated with their respective file/sort descriptions. - the
WORKING-STORAGE SECTION
, where static data is declared. - the
LOCAL-STORAGE SECTION
, where automatic data is declared. - the
LINKAGE SECTION
, where parameters are defined. - the
REPORT SECTION
, where reports are defined and associated with report descriptions. - the
SCREEN SECTION
, where the screens used for terminal I/O are described.
Variables are defined in the following format: level-number variable-name clauses.
Variable type is defined in a PICTURE
clause and/or a USAGE
clause. PICTURE
clauses can be used like so:
<lang cobol>01 a PIC X(20). *> a is a string of 20 characters.
01 b PIC 9(10). *> b is a 10-digit integer.
01 c PIC 9(10)V9(5). *> c is a decimal number with a 10-digit integral part and a 5-digit fractional part.
01 d PIC 99/99/99. *> d is an edited number, with a slash between each pair of digits in a 6-digit integer.</lang>
The USAGE
clause is used to define pointers, floating-point numbers, binary numbers, packed decimals and object references amongst others.
Each variable has a level-number, which is a number from 1 to 49, or 77, which goes before the variable name. Level-numbers indicate how data is grouped together.
Variables with higher level-numbers are subordinate to variables with lower level-numbers.
The 77 level-number indicates the variable has no subordinate data and is therefore not a group item. Group items can include FILLER
items which are parts of a group item which are not directly accessible.
<lang cobol>*> Group data items do not have a picture clause.
01 group-item.
03 sub-data PIC X(10). 03 more-sub-data PIC X(10).</lang>
Initialization
Initialization is done via the VALUE
clause in the DATA DIVISION
or via the INITIALIZE
statement in the PROCEDURE DIVISION
. The INITIALIZE
statement will set a variable back to either the value in its VALUE
clause (if INITIALIZE
has a VALUE
clause) or to the appropriate value out of NULL
, SPACES
or ZERO
.
<lang cobol>DATA DIVISION.
WORKING-STORAGE SECTION.
01 initialized-data PIC X(15) VALUE "Hello, World!".
01 other-data PIC X(15).
...
PROCEDURE DIVISION.
DISPLAY initialized-data *> Shows 'Hello, World!' DISPLAY other-data *> Will probably show 15 spaces.</lang>
Group items can be initialized, but they are initialized with a string like so: <lang cobol>01 group-item VALUE "Hello!12345".
03 a-string PIC X(6). *> Contains "Hello!" 03 a-number PIC 9(5). *> Contains '12345'.</lang>
Reference Modification
Reference modification allows a range of characters to be taken from a variable. <lang cobol>some-str (1:1) *> Gets the first character from the string some-num (1:3) *> Get the first three digits from the number another-string (5:) *> Get everything from the 5th character/digit onwards.
- > To reference modify an array element
some-table (1) (5:1) *> Get the 5th character from the 1st element in the table</lang>
Scope
Variables by default are local to the subprogram/class/etc. (source element) they are defined in. The GLOBAL
clause allows the variable to be accessed in any nested source units as well. To be accessed from those inner source elements, the variable must be redeclared exactly as it was in the outer one, complete with GLOBAL
clause, otherwise the variable in the inner one will shadow the global variable from the outer one.
Common Lisp
Declaration
Special variables are more or less like globals in other languages: http://www.lispworks.com/documentation/HyperSpec/Body/d_specia.htm
Special variables may be defined with defparameter.
<lang lisp>(defparameter *x* nil "nothing")</lang>
Here, the variable *x* is assigned the value nil. Special variables are wrapped with asterisks (called 'earmuffs'). The third argument is a docstring.
We may also use defvar, which works like defparameter except that defvar won't overwrite the value of the variable that has already been bound.
<lang lisp>(defvar *x* 42 "The answer.")</lang>
It does, however, overwrite the docstring, which you can verify:
<lang lisp>(documentation '*x* 'variable)</lang>
defconst works in the same way, but binds a constant. Constants are wrapped with '+' signs rather than earmuffs.
Common Lisp is case-insensitive, so saying (equal +MoBy-DicK+ +moby-dick+)
will return t no matter the combination of upper and lower-case letters used in the symbol names. Symbols are hyphenated and lower-case.
For non-special varibles, we use let:
<lang lisp>(let ((jenny (list 8 6 7 5 3 0 9))
hobo-joe) (apply #'+ jenny))</lang>
The symbols 'jenny' and 'hobo-joe' are lexically bound meaning that they are valid within the scope of the let block. If we move the apply form out of scope, the compiler will complain that 'jenny' is unbound.
The let macro binds an arbitrary number of variables: 'jenny' is bound to a list of numbers, whereas hobo-joe is bound to nil because we haven't provided a value. jenny and hobo-joe have the same scope.
Common Lisp prefers to use variables in lexical, rather than dynamic scope. If we've defined *x* as a special variable, then binding it lexically with let will create a new local value while leaving the dynamically scoped *x* untouched.
<lang lisp>(progn
(let ((*x* 43)) (print *x*) (print *x*))</lang>
If *x* has previously been bound to the value 42, then this example will output 43, then 42.
Mutation
We use setf to modify the value of one or more variables.
<lang lisp>(setf *x* 625)</lang>
Types
Common Lisp is dynamically typed, so we don't have to explicitly tell it what type of value a symbol holds. But we can if we want to:
<lang lisp>(declaim (ftype (function (fixnum) fixnum) frobnicate)) (defun frobnicate (x)
(declare (type fixnum x)) (the fixnum (+ x 128)))</lang>
A fixnum is like an unsigned integer in C. The size of a fixnum can vary by architecture, but because the Lisp virtual machine requires 2 bits for its own purposes, a fixnum can only represent 2^62 different values on a 64-bit platform.
The keyword the tells the compiler the type returned by an expression; frobnicate returns a fixnum.
The declare statement applies to the function in which the statement appears. In the example, we assert to the compiler that x is a fixnum.
Whereas declare describes a function, declaim is used to inform the compiler about the program globally. The usage above gives type information about one or more functions. The fixnum in parentheses tells the compiler that the function is of one argument, being is a fixnum, and that the function returns a fixnum. We can provide any number of function names.
Delphi
<lang Delphi>var
i: Integer; s: string; o: TObject;
begin
i := 123; s := 'abc'; o := TObject.Create; try // ... finally o.Free; end;
end;</lang>
D
<lang D> float bite = 36.321; ///_Defines a floating-point number (float), "bite", with a value of 36.321 float[3] bites; ///_Defines a static array of 3 floats float[] more_bites; ///_Defines a dynamic array of floats </lang>
DWScript
See Delphi for "classic" declaration. In DWScript, if variables have to be declared before use, but can be declared inline, and their type can also be inferred.
<lang Delphi> var i := 123; // inferred type of i is Integer var s := 'abc'; // inferred type of s is String var o := TObject.Create; // inferred type of o is TObject var s2 := o.ClassName; // inferred type of s2 is String as that's the type returned by ClassName </lang>
E
E is an impure, lexically scoped language. Variables must be defined before use (they are not created on assignment). Definition of variables is a special case of pattern matching.
An identifier occurring in a pattern is a simple non-assignable variable. The def
operator is usually used to define local variables:
<lang e>def x := 1 x + x # returns 2</lang>
Assignment
The pattern var x
makes x an assignable variable, and :=
is the assignment operator.
<lang e>def var x := 1 x := 2 x # returns 2</lang>
(As a shorthand, var x := ...
is equivalent to def var x := ...
.)
There are update versions of the assignment operator, in the traditional C style (+=
, -=
, |=
, etc.), but also permitting any verb (method name) to be used:
<lang e>def var x := 1 x += 1 # equivalent to x := x + 1, or x := x.add(1) x # returns 2
def var list := ["x"] list with= "y" # equivalent to list := list.with("y") list # returns ["x", "y"]</lang>
Patterns
Since variable definition is part of pattern matching, a list's elements may be distributed into a set of variables:
<lang e>def [hair, eyes, var shirt, var pants] := ["black", "brown", "plaid", "jeans"]</lang>
However, assignment to a list as in Perl or Python is not currently supported.
<lang e>[shirt, pants] := ["white", "black"] # This does not do anything useful.</lang>
Scoping
In E, a variable is visible from the point of its definition until the end of the enclosing block. Variables can even be defined inside expressions (actually, E has no statement/expression distinction):
<lang e>def list := [def x := timer.now(), x] # two copies of the current time list[0] == x # x is still visible here; returns true</lang>
Slots
The difference between assignable and non-assignable variables is defined in terms of primitive operations on non-primitive slot objects. Slots can also be employed by programmers for effects such as variables which have an effect when assigned (e.g. backgroundColor := red
) or automatically change their values over time, but that is beyond the scope of this task. For example, it is possible to transfer a variable between scopes by referring to its slot:
<lang e>def makeSum() {
var a := 0 var b := 0 return [&a, &b, fn { a + b }]
}
def [&x, &y, sum] := makeSum() x := 3 y := 4 sum() # returns 7</lang>
As suggested by the &
syntax, the use of slots is somewhat analogous in effect to C pointers or C++ references, allowing the passing of locations and not their values, and "pass-by-reference" or "out" parameters:
<lang e>def getUniqueId(&counter) {
counter += 1 return counter
}
var idc := 0 getUniqueId(&idc) # returns 1 getUniqueId(&idc) # returns 2</lang>
Ela
Strictly speaking Ela doesn't have variables. Instead Ela provides a support for a declaration of names that can be bound to values. Unlike variables names are immutable - it is not possible to change a value bound to a name.
Global declarations:
<lang ela>x = 42
sum x y = x + y</lang>
Local declarations:
<lang ela>sum x y = let z = x + y in z
sum x y = z
where z = x + y</lang>
Erlang
Variables spring into life upon assignment, which can only happen once (single assignment). Their scope is only the local function and they must start with a capital letter. <lang Erlang> two() -> A_variable = 1, A_variable + 1. </lang>
F#
Variables in F# bind a name to a value and are, by default, immutable. They can be declared nearly anywhere and are normally local to the block/assembly they are defined in. They are declared in the form: let name parameters = expression. <lang fsharp>let x = 5 // Int let mutable y = "mutable" // Mutable string let recordType = { foo : 6; bar : 6 } // Record let intWidget = new Widget<int>() // Generic class let add2 x = 2 + x // Function value</lang>
Types are normally inferred from the values they are initialised with. However, types can be explicitly specified using type annotations. <lang fsharp>let intEqual (x : int) (y : int) = x = y let genericEqual x y : 'a = x = y</lang>
Mutable variables are set using the <-
operator.
<lang fsharp>sum <- sum + 1</lang>
Factor
The SYMBOL bit defines a new symbol word which is used to identify variables. use-foo shows how one would modify and get the contents of the variable. named-param-example is an example of using :: to define a word with named inputs, similar to the way other languages do things. Last, but not least, local-example shows how to use [let to define a group of lexically scoped variables inside of a word definition. <lang factor>SYMBOL: foo
- use-foo ( -- )
1 foo set foo get 2 + foo set ! foo now = 3 foo get number>string print ;
- named-param-example ( a b -- )
a b + number>string print ;
- local-example ( -- str ) [let "a" :> b "c" :> a a " " b 3append ] ;</lang>
Forth
Historically, Forth has preferred open access to the parameter stack over named local variables. The 1994 standard however added a cell-sized local variable facility and syntax. The semantics are similar to VALUEs: locals are initialized from stack contents at declaration, the name retrieves the value, and TO sets the value of the local name parsed at compile time ("value TO name"). <lang forth>: hypot ( a b -- a^2 + b^2 )
LOCALS| b a | \ note: reverse order from the conventional stack comment b b * a a * + ;</lang>
Modern Forth implementations often extend this facility in several ways, both for more convenient declaration syntax and to be more compatible with foreign function interfaces. Curly braces are used to replace the conventional stack comment with a similar looking local variable declaration. <lang forth>: hypot { a b -- a^2 + b^2 } \ text between "--" and "}" remains commentary
a a * b b * + ;</lang>
Modern systems may also allow different local data types than just integer cells. <lang forth>: length { F: a F: b F: c -- len } \ floating point locals
a a F* b b F* F+ c c F* F+ FSQRT ;</lang>
Fortran
<lang fortran> program test
implicit none
integer :: i !scalar integer integer,dimension(10) :: ivec !integer vector real :: r !scalar real real,dimension(10) :: rvec !real vector character(len=:),allocatable :: char1, char2 !fortran 2003 allocatable strings
!assignments:
!-- scalars:
i = 1 r = 3.14
!-- vectors:
ivec = 1 !(all elements set to 1) ivec(1:5) = 2
rvec(1:9) = 0.0 rvec(10) = 1.0
!-- strings:
char1 = 'hello world!' char2 = char1 !copy from one string to another char2(1:1) = 'H' !change first character
end program test </lang>
GAP
<lang gap># At top level, global variables are declared when they are assigned, so one only writes global_var := 1;
- In a function, local variables are declared like this
func := function(n)
local a; a := n*n; return n + a;
end;
- One can test whether a variable is assigned
IsBound(global_var);
- true;
- And destroy a variable
Unbind(global_var);
- This works with list elements too
u := [11, 12, , 14]; IsBound(u[4]);
- true
IsBound(u[3]);
- false
Unbind(u[4]);</lang>
Go
Simplest and most common
While Go is statically typed, it provides a “short variable declaration” with no type explicitly stated, as in, <lang go>x := 3</lang> This is the equivalent of, <lang go>var x int // declaration x = 3 // assignment</lang> The technique of not stating the type is known as type inference, or duck typing. The right hand side can be any expression. Whatever type it represents is used as the type of the variable. More examples: <lang go>y := x+1 // y is int, assuming declaration above same := x == y // same declared as bool p := &same // type of p is pointer to bool pi := math.Floor(math.Pi) // math.Floor returns float64, so that is the type of pi</lang> Nothing goes uninitialized
Variables declared without initializer expressions are initialized to the zero value for the type. <lang go>var x, y int // two variables, initialized to zero. var p *int // initialized to nil</lang> Opposite C
While putting the variable before the type feels “backwards” to programmers familiar with certain other languages, it succinctly allows multiple variables to be declared with arbitrarily complex type expressions.
List syntax
Variables can be declared in a list with the keyword var used only once. The syntax visually groups variables and sets the declaration off from surrounding code. <lang go>var (
x, y int s string
)</lang> Multiple assignment
Multiple values can be assigned in a single assignment statement, with many uses. <lang go>x, y = y, x // swap x and y sinX, cosX = math.Sincos(x) // Sincos function returns two values // map lookup optionally returns a second value indicating if the key was found. value, ok = mapObject[key]</lang> Other kinds of local variables
Parameters and named return values of functions, methods, and function literals also represent assignable local variables, as in, <lang go>func increase (x int) (more int) {
x++ more = x+x return
}</lang> Parameter x and return value more both act as local variables within the scope of the function, and are both assignable. When the function returns, both go out of scope, although the value of more is then returned as the value of the function.
While assignment of return values is highly useful, assignment of function parameters is often an error. Novice programmers might think that modifying a parameter inside the function will affect a variable used as an argument to the function call. It does not.
Method receivers also represent assignable local variables, and as with function parameters, assigning them inside the method is often a mistake.
Other common errors
Short declarations can involve multiple assignment, as in <lang go>x, y := 3, 4</lang> But there are complications involving scope and variables already defined that confuse many programmers new to Go. A careful reading of the language specification is definitely in order, and a review of misconceptions as discussed on the mailing list is also highly recommended.
Programmers new to the concept of closures often fail to distinguish between assigning free and bound variables. Function literals in Go are closures, and a common novice error is to start multiple goroutines from function literals, and fail to understand that multiple goroutines are accessing the same free variables.
Haskell
You can define a variable at the top (module) level or in a where
, let
, or do
construct.
<lang haskell>foobar = 15
f x = x + foobar
where foobar = 15
f x = let foobar = 15
in x + foobar
f x = do
let foobar = 15 return $ x + foobar</lang>
One particular feature of do
notation looks like assignment, but actually, it's just syntactic sugar for the >>=
operator and a unary lambda.
<lang haskell>main = do
s <- getLine print (s, s)
-- The above is equivalent to:
main = getLine >>= \s -> print (s, s)</lang>
Pattern matching allows for multiple definitions of the same variable, in which case each call uses the first applicable definition.
<lang haskell>funkshun True x = x + 1 funkshun False x = x - 1
foobar = funkshun True 5 + funkshun False 5 -- 6 + 4</lang>
case
expressions let you do pattern-matching on an arbitrary expression, and hence provide yet another way to define a variable.
<lang haskell>funkshun m = case foo m of
[a, b] -> a - b a : b : c : rest -> a + b - c + sum rest a -> sum a</lang>
Guards are as a kind of syntactic sugar for if-else ladders.
<lang haskell>signum x | x > 0 = 1
| x < 0 = -1 | otherwise = 0</lang>
A defintion can be accompanied by a type signature, which can request a less general type than the compiler would've chosen on its own. (Because of the monomorphism restriction, there are also some cases where a type signature can request a more general type than the default.) Type signatures are also useful even when they make no changes, as a kind of documentation.
<lang haskell>dotProduct :: [Int] -> [Int] -> Int dotProduct ns ms = sum $ zipWith (+) ns ms -- Without the type signature, dotProduct would -- have a more general type.
foobar :: Num a => a foobar = 15 -- Without the type signature, the monomorphism -- restriction would cause foobar to have a less -- general type.</lang>
Since Haskell is purely functional, most variables are immutable. It's possible to create mutable variables in an appropriate monad. The exact semantics of such variables largely depend on the monad. For example, STRef
s must be explicitly initialized and passed between scopes, whereas the implicit state of a State
monad is always accessible via the get
function.
HicEst
<lang HicEst>! Strings and arrays must be declared. ! Everything else is 8-byte float, READ/WRITE converts
CHARACTER str="abcdef", str2*345, str3*1E6/"xyz"/ REAL, PARAMETER :: named_constant = 3.1415 REAL :: n=2, cols=4, vec(cols), mtx(n, cols) DATA vec/2,3,4,5/, mtx/1,2,3.1415,4, 5,6,7,8/
named = ALIAS(alpha, beta, gamma) ! gamma == named(3) ALIAS(vec,n, subvec,2) ! share subvec and vec(n...n+1) ALIAS(str,3, substr,n) ! share substr and str(3:3+n-1)
a = EXP(b + c) ! assign/initialze a=1, b=0, c=0 str = "blahblah" ! truncate/expand if needed beta = "blahblah" ! illegal
CALL noArguments_noUSE ! global scope SUBROUTINE CALL Arguments_or_USE(a) ! local scope SUBROUTINE t = func() ! local scope FUNCTION
SUBROUTINE noArguments_noUSE() ! all global
vec2 = $ ! 1,2,3,...
END
SUBROUTINE Arguments_or_USE(var) ! all local
USE : vec ! use global object var = SUM(vec) t = TIME() ! local, static, USEd by func()
END
FUNCTION func() ! all local
USE Arguments_or_USE : t ! use local object func = t
END</lang>
Icon and Unicon
Icon/Unicon data types are implemented as type safe self-descriptive values and as such do not require conventional type declarations. See Introduction to Unicon and Icon about declarations
Declarations are confined to scope and use and include local, static, global, procedure parameters, and record definitions. Additionally Unicon has class definitions. Undeclared variables are local by default. <lang Icon>global gvar # a global
procedure main(arglist) # arglist is a parameter of main local a,b,i,x # a, b, i, x are locals withing main static y # a static (silly in main)
x := arglist[1] a := 1.0 i := 10 b := [x,a,i,b]
- ... rest of program
end</lang>
Icon
Unicon
This Icon solution works in Unicon.
J
<lang j>val=. 0</lang>
J has two assignment operators. The =. operator declares, initializes, assigns, etc. a local variable. The =: operator does the same for a "global" variable.
<lang j>fun =: 3 :0
val1 =: 0 val1 =. 2 val2 =. 3 val1, val2
)
fun
2 3
val1
0
val2
|value error</lang>
Note that the language forbids assigning a "global" value in a context where the name has a local definition.
<lang j>fun1 =: 3 :0
val3=. 0 val3=: 0
)
fun1
|domain error</lang>
But the purpose of this rule is to help people catch mistakes. If you have reason to do this, you can easily set up another execution context.
<lang j>fun2 =: 3 :0
val4=. 0 3 :'val4=:y' y
)
fun2 </lang>
Variables are referred to by name, and exist in locales (which may be used as classes, closures or other stateful references).
FIXME (working on good illustrative examples that would make sense to someone used to different languages)
That said, it is possible and not uncommon to write an entire J application without using any variables (J has a functional, "point free" style of coding known as tacit). Names are optional (though often convenient). And, it can be possible to build code using names and then remove them using f.
-- this is somewhat analogous to compiling code though the implementation of f. does not have to compile anything.
Java
Variables in Java are declared before their use with explicit types: <lang java>int a; double b; AClassNameHere c;</lang> Several variables of the same type can be declared together: <lang java>int a, b, c;</lang> Variables can be assigned values on declaration or afterward: <lang java>int a = 5; double b; int c = 5, d = 6, e, f; String x = "test"; String y = x; b = 3.14;</lang> Variables can have scope modifiers, which are explained here.
final
variables can only be assigned once, but if they are Object
s or arrays, they can be modified through methods (for Object
s) or element assignment (for arrays):
<lang java>final String x = "blah";
final String y;
final double[] nums = new double[15];
y = "test";
x = "blahblah"; //not legal
nums[5] = 2.5; //legal
nums = new double[10]; //not legal
final Date now = new java.util.Date();
now.setTime(1234567890); //legal
now = new Date(1234567890); //not legal</lang>
JavaScript
Information lifted from Stack Overflow (credit to krosenvold and triptych)
Javascript uses scope chains to establish the scope for a given function. There is typically one global scope, and each function defined has its own nested scope. Any function defined within another function has a local scope which is linked to the outer function. It's always the position in the source that defines the scope.
An element in the scope chain is basically a Map with a pointer to it's parent scope.
When resolving a variable, javascript starts at the innermost scope and searches outwards.
var a=1;
// global scope function one(){
alert(a);
}
// local scope function two(a){
alert(a);
}
// local scope again function three(){
var a = 3; alert(a);
}
// Intermediate: no such thing as block scope in javascript function four(){
if(true){ var a=4; }
alert(a); // alerts '4', not the global value of '1'
}
// Intermediate: object properties
function Five(){
this.a = 5;
}
// Advanced: closure
var six = function(){
var foo = 6;
return function(){ // javascript "closure" means I have access to foo in here, // because it is defined in the function in which I was defined. alert(foo); }
}()
// Advanced: prototype-based scope resolution
function Seven(){
this.a = 7;
}
// [object].prototype.property loses to [object].property in the scope chain Seven.prototype.a = -1; // won't get reached, because 'a' is set in the constructor above. Seven.prototype.b = 8; // Will get reached, even though 'b' is NOT set in the constructor.
// These will print 1-8 one(); two(2); three(); four(); alert(new Five().a); six(); alert(new Seven().a);
alert(new Seven().b);</lang>Joy
JOY does not have variables. Variables essentially name locations in memory, where values are stored. JOY also uses memory to store values, but has no facility to name these locations. The memory that JOY uses is commonly referred to as "the stack".
Initializing
The JOY stack can be initialized: <lang joy>[] unstack</lang>
Assignment
Values can be pushed on the stack: <lang joy>42</lang> pushes the value 42 of type integer on top of the stack.
Stack
Calling the stack by name pushes a copy of the stack on the stack. To continue the previous example: <lang joy>stack</lang> pushes the list [42] on top of the stack. The stack now contains: [42] 42.
Liberty BASIC
<lang lb> 'In Liberty BASIC variables are either string or numeric. 'A variable name can start with any letter and it can contain both letters and numerals, as well as dots (for example: user.firstname). 'There is no practical limit to the length of a variable name... up to ~2M characters. 'The variable names are case sensitive.
'assignments: -numeric variables. LB assumes integers unless assigned or calculated otherwise. 'Because of its Smalltalk heritage, LB integers are of arbitrarily long precision. 'They lose this if a calculation yields a non-integer, switching to floating point.
i = 1 r = 3.14
'assignments -string variables. Any string-length, from zero to ~2M.
t$ ="21:12:45" flag$ ="TRUE"
'assignments -1D or 2D arrays 'A default array size of 10 is available. Larger arrays need pre-'DIM'ming.
height( 3) =1.87 dim height( 50) height( 23) =123.5 potential( 3, 5) =4.5 name$( 4) ="John"
'There are no Boolean /bit variables as such.
'Arrays in a main program are global. 'However variables used in the main program code are not visible inside functions and subroutines. 'They can be declared 'global' if such visibility is desired. 'Functions can receive variables by name or by reference. </lang>
Julia
Certain constructs in the language introduce scope blocks, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary set of source lines, but will always line up with one of these blocks. The constructs introducing such blocks are:
function bodies (either syntax) while loops for loops try blocks catch blocks let blocks type blocks. <lang julia>#declaration/assignment, declaration is optional x::Int32 = 1
- datatypes are inferred dynamically, but can also be set thru convert functions and datatype literals
x = 1 #x is inferred as Int, which is Int32 for 32-bit machines, Int64 for 64-bit machines
- variable reference
julia>x 1
x = int8(1) #x is of type Int8 x = 1.0 #x is Float64 x = y = 1 #assign both x and y to 1 global x = 1 #assigns 1 to global variable x (used inside scope blocks) local x = 1 #assigns 1 to local variable x (used inside scope blocks) x = 'a' #x is a 'Char' type, designated by single quotes x = "a" #x is a 1-element string, designated by double quotes</lang> A common use of variables is giving names to specific, unchanging values. Such variables are only assigned once. This intent can be conveyed to the compiler using the const keyword: <lang julia>const e = 2.71828182845904523536 const pi = 3.14159265358979323846</lang>
Lasso
<lang Lasso>// declare thread variable, default type null var(x) $x->type // null
// declare local variable, default type null local(x)
- x->type // null
// declare thread variable, initialize with a type, in this case integer var(x = integer)
// declare local variable, initialize with a type, in this case integer local(x = integer)
// assign a value to the thread var x $x = 12
// assign a value to the local var x $x = 177
// a var always has a data type, even if not declared - then it's null // a var can either be assigned a type using the name of the type, or a value that is by itself the type local(y = string) local(y = 'hello')
'\r' // demonstrating asCopyDeep and relationship between variables: local(original) = array('radish', 'carrot', 'cucumber', 'olive') local(originalaswell) = #original local(copy) = #original->asCopyDeep iterate(#original) => {
loop_value->uppercase
}
- original // modified
//array(RADISH, CARROT, CUCUMBER, OLIVE) '\r'
- originalaswell // modified as well as it was not a deep copy
//array(RADISH, CARROT, CUCUMBER, OLIVE) '\r'
- copy // unmodified as it used ascopydeep
//array(RADISH, CARROT, CUCUMBER, OLIVE)</lang>
Logo
Historically, Logo only had global variables, because they were easier to access when stepping through an algorithm. Modern variants have added dynamic scoped local variables.
<lang logo>make "g1 0 name 2 "g2 ; same as make with parameters reversed global "g3 ; no initial value to func :x
make "g4 4 ; still global localmake "L1 6 local ["L2 "L3] ; local variables, collection syntax func2 :g4 print :L2 ; 9, modified by func2 print :L3 ; L3 has no value, was not modified by func2
end to func2 :y
make "g3 :y make "L2 :L1 + 3 ; dynamic scope: can see variables of callers localmake "L3 5 ; locally override L3 from caller (print :y :L1 :L2 :L3) ; 4 6 9 5
end print :g4 ; 4 print :L1 ; L1 has no value print name? "L1 ; false, L1 is not bound in the current scope</lang>
LotusScript
<lang Lotusscript>Sub Click() 'a few declarations as example Dim s as New NotesSession ' declaring a New NotesSession actually returns the current, active NotesSession Dim i as Integer ' i = 0 Dim s as String ' s= "" Dim v as Variant ' v is nothing Dim l as Long ' l = 0 Dim doc as NotesDocument 'doc is EMTPY
'...
End Sub </lang>
Lua
In lua, variables are dynamically typecast, and do not need declaration prior to use.
<lang lua>a = 1 -- Here we declare a numeric variable fruit = "banana" -- Here we declare a string datatype needspeeling = True -- This is a boolean local b = 2 -- This variable declaration is prefixed with a scope modifier </lang>
The lua programming language supports multiple assignments from within a single statement:
<lang lua>A, B, C, D, E = 2, 4, 6, 8, "It's never too late"</lang>
Mathematica
x=value assign a value to the variable x x=y=value assign a value to both x and y x=. or Clear[x] remove any value assigned to x lhs=rhs (immediate assignment) rhs is evaluated when the assignment is made lhs:=rhs (delayed assignment) rhs is evaluated each time the value of lhs is requested
Atomic Objects
All expressions in Mathematica are ultimately made up from a small number of basic or atomic types of objects. Symbol / String / Integer / Real / Rational / Complex These objects have heads which are symbols that can be thought of as "tagging" their types. The objects contain "raw data", which can usually be accessed only by functions specific to the particular type of object. You can extract the head of the object using Head, but you cannot directly extract any of its other parts.
Symbols are the basic named objects in Mathematica
aaaaa user-defined symbol Aaaaa system-defined symbol $Aaaa global or internal system-defined symbol aaaa$ symbol renamed in a scoping construct aa$nn unique local symbol generated in a module
Contexts
aaaa`x is a symbol with short name x, and context aaaa. Contexts in Mathematica work somewhat like file directories in many operating systems. You can always specify a particular file by giving its complete name, including its directory. But at any given point, there is usually a current working directory, analogous to the current Mathematica context. Files that are in this directory can then be specified just by giving their short names.
Scoping Constructs
With[] evaluate with specified variables replaced by values Module[] localize names of variables (lexical scoping) Block[] localize values of variables (dynamic scoping) DynamicModule[] localize names of variables in dynamic interface constructs Other Forms of Scoping Begin, End localize symbol namespace Throw, Catch localize exceptions Quiet, Check localize messages BlockRandom localize pseudorandom variables
MATLAB / Octave
<lang Matlab> a = 4; % declare variable and initialize double value,
s = 'abc'; % string i8 = int8(5); % signed byte u8 = uint8(5); % unsigned byte i16 = int16(5); % signed 2 byte u16 = uint16(5); % unsigned 2 byte integer i32 = int32(5); % signed 4 byte integer u32 = uint32(5);% unsigned 4 byte integers i64 = int64(5); % signed 8 byte integer u64 = uint64(5);% unsigned 8 byte integer
f32 = float32(5); % single precission floating point number f64 = float64(5); % double precission floating point number , float 64 is the default data type.
c = 4+5i; % complex number
colvec = [1;2;4]; % column vector crowvec = [1,2,4]; % row vector m = [1,2,3;4,5,6]; % matrix with size 2x3</lang>
Variables within functions have local scope, except when they are declared as global
<lang Matlab> global b </lang>
Modula-3
<lang modula3>MODULE Foo EXPORTS Main;
IMPORT IO, Fmt;
VAR foo: INTEGER := 5; (* foo is global (to the module). *)
PROCEDURE Foo() =
VAR bar: INTEGER := 10; (* bar is local to the procedure Foo. *) BEGIN IO.Put("foo + bar = " & Fmt.Int(foo + bar) & "\n"); END Foo;
BEGIN
Foo();
END Foo.</lang>
For procedures, the formal parameters create local variables unless the actual parameter is prefixed by VAR: <lang modula3>PROCEDURE Foo(n: INTEGER) =</lang> Here, n will be local to the procedure Foo, but if we instead wrote: <lang modula3>PROCEDURE Foo(VAR n: INTEGER) =</lang> Then n is the global variable n (if it exists).
Nimrod
<lang nimrod>var x: int = 3
var y = 3 # type inferred to int
var z: int # initialized to 0
let a = 13 # immutable variable
var
b, c: int = 10 s = "foobar"</lang>
Objeck
Different ways to declare and initialize an integer. <lang objeck> a : Int; b : Int := 13; c := 7; </lang>
OCaml
The default handlers for values in OCaml are not variables strictly speaking, because as OCaml is a functional language these values can't vary (so are not variable). Strictly speaking these are bindings. An identifier is bound to a value in an immutable way.
The standard way to bind an identifier to a value is the let construct: <lang ocaml>let x = 28</lang>
This stated, ocaml programmers most often use the word variable when they refer to bindings, because in the programming world we usually use this word for the default values handlers.
Now to add confusion, real variables also exist in OCaml because it is an impure functional language. They are called references and are defined this way: <lang ocaml>let y = ref 28</lang> References can then be accessed and modified this way: <lang ocaml> !y (* access *)
y := 34 (* modification *)</lang>
An identifier can not be declared uninitialised, it is always defined with an initial value, and this initial value is used by the OCaml type inference to infer the type of the binding.
Inside an expression, bindings are defined with the let .. in construct, and we can also define multiple bindings with the let .. and .. in construct (here the expression can be the definition of a new identifier or the definition of a function): <lang ocaml>let sum = (* sum is bound to 181 *)
let a = 31 and b = 150 in (a + b)
let sum () = (* sum is a function which returns 181 *)
let a = 31 and b = 150 in (a + b)</lang>
Openscad
<lang openscad> mynumber=5+4; // This gives a value of nine </lang>
Oz
Variable names in Oz always start with an uppercase letter.
Oz variables are dataflow variables. A dataflow variable can basically be free (unbound) or determined (has a value). Once a value has been assigned, it can not be changed. If we assign the same value again, nothing happens. If we assign a different value to an already determined variable, an exception is raised: <lang oz>declare Var %% new variable Var, initially free {Show Var} Var = 42 %% now Var has the value 42 {Show Var} Var = 42 %% the same value is assigned again: ok Var = 43 %% a different value is assigned: exception</lang>
In the Emacs-based interactive environment, declare
creates a new open scope in which variables can be declared. The variables are visible for the entire rest of the session.
Most operations on free variables block until the variables have been bound (but not Show
as used above).
Assignment to dataflow variables is also called unification. It is actually a symmetric operation, e.g. the following binds B to 3: <lang oz>declare
A = 3 B
in
A = B {Show B}</lang>
However, variables can only be introduced at the left side of the =
operator. So this is a syntax error:
<lang oz>declare
A = 3 A = B %% Error: variable B not introduced
in
{Show B}</lang>
It is possible to introduce multiple variables in a single statement: <lang oz>declare
[A B C D] = [1 2 3 4] %% unification of two lists</lang>
In a module definition, toplevel variables can be introduced between the keywords define
and end
without the need for declare
. The range between these two keywords is also their scope. Toplevel variables can optionally be exported.
<lang oz>functor
export Function
define
ToplevelVariable = 42
fun {Function} 42 end
end</lang>
Function and class definitions introduce a new variable with the name of the function/class and assign the new function/class to this variable.
Most Oz statement introduce a new scope and it is possible to introduce local variables at the top of this scope with the in
keyword.
<lang oz>fun {Function Arg}
LocalVar1
in
LocalVar1 = if Arg == 42 then
LocalVar2 in LocalVar2 = yes LocalVar2 else LocalVar3 = no %% variables can be initialized when declared in LocalVar3 end
LocalVar1
end</lang>
Here, LocalVar1
is visible in the whole body of Function
while LocalVar2
is only visible in the then
branch and LocalVar3
is only visible in the else
branch.
Additionally, new local variables can be introduced everywhere using the keyword local
.
<lang oz>if {IsEven 42} then
{System.showInfo "Here, LocalVar is not visible."} local LocalVar = "Here, LocalVar IS visible" in {System.showInfo LocalVar} end
end</lang>
New variables are also introduced in pattern matching.
<lang oz>case "Rosetta code" of First|_ then {Show First} end %% prints "R"</lang>
_
creates a new nameless variable that is initially unbound. It is usually pronounced "don't care".
It is possible to create a read-only view of a variable with the !!
operator. This is called a "future". We can wait for such a variable to become bound by another thread and we can read its value, but we can never set it.
<lang oz>declare
A B = !!A %% B is a read-only view of A
in
thread B = 43 %% this blocks until A is known; then it fails because 43 \= 42 end A = 42</lang>
Additional operations on variables: <lang oz>declare
V = 42
in
{Wait V} %% explicitly wait for V to become determined
if {IsDet V} then %% check whether V is determined; not recommended {Show determined} elseif {IsFree V} then %% check whether V is free; not recommended {Show free} end</lang>
IsFree
and IsDet
are low-level functions. If you use them, you code is no longer declarative and prone to race conditions when used in a multi-threaded context.
To have mutable references like in imperative languages, use cells: <lang oz>declare
A = {NewCell 42} OldVal
in
{Show @A} %% read a cell with @ A := 43 %% change its value OldVal = A := 44 %% read and write at the same time (atomically)</lang>
A
is an immutable dataflow variable that is bound to a mutable reference.
PARI/GP
There are two types of local variables, local
(mostly deprecated) and my
. Variables can be used without declaration or initialization; if not previously used such a variable is a pure variable: technically, a monomial in a variable with name equal to the variable name. This behavior can be forced with the apostrophe operator: regardless of the value (if any) currently stored in x
,
<lang parigp>'x</lang>
displays as (and is treated internally as) x
. This is useful when you want to use it as a variable instead of a number (or other type of object). For example,
<lang parigp>'x^3+7</lang>
is a cubic polynomial, not the number 8, even if x is currently 1.
Pascal
See Delphi
Perl
In perl, variables are global by default and can be manipulated from anywhere in the program. Variables can be used without first being declared, providing that the strict pragmatic directive is not in effect:
<lang perl>sub dofruit {
$fruit='apple';
}
dofruit; print "The fruit is $fruit";</lang>
Variables can be declared prior to use and may be prefixed with scope modifiers our
, my
, or local
see scope modifiers for the differences. Variables which haven't been assigned to have the undefined value by default. The undefined value acts just like 0
(if used as a number) or the empty string (if used as a string), except it can be distinguished from either of these with the defined
function. If warnings are enabled, perl will print a message like "Use of uninitialized value $foo in addition (+)" whenever you use the undefined value as a number or string.
Initialization and assignment are the same thing in Perl: just use the =
operator. Note that the rvalue's context (scalar or list) is determined based on the lvalue.
<lang perl>my $x = @a; # Scalar assignment; $x is set to the
# number of elements in @a.
my ($x) = @a; # List assignment; $x is set to the first
# element of @a.
my @b = @a; # List assignment; @b becomes the same length
# as @a and each element becomes the same.
my ($x, $y, @b) = @a; # List assignment; $x and $y get the first
# two elements of @a, and @b the rest.
my ($x, $y, @b, @c, $z) = @a; # Same thing, and also @c becomes empty
# and $z undefined.</lang>
The kind of value a variable can hold depends on its sigil, "sigil" being a slang term for "funny character in front of a variable name". $dollarsigns
can hold scalars: the undefined value, numbers, strings, or references. @atsigns
can hold arrays of scalars, and %percentsigns
can hold hashes of scalars (associative arrays mapping strings to scalars); nested data structures are constructed by making arrays or hashes of references to arrays or hashes.
There are two other sigils, but they behave quite unlike the others. A token of the form &foo
refers to a subroutine named foo
. In older versions of Perl, ampersands were necessary for calling user-defined subroutines, but since they no longer are, they have only a handful of obscure uses, like making references to named subroutines. Note that you can't assign to an ampersand-marked name. But you can assign to a typeglob, a kind of object represented with the notation *var
. A typeglob *foo
represents the symbol-table entry for all of the otherwise independent variables $foo
, @foo
, %foo
, and &foo
. Assigning a string "bar"
to *foo
makes these variables aliases for $bar
, @bar
, %bar
, and &bar
respectively. Alternatively, you can assign a reference to a typeglob, which creates an alias only for the variable of the appropriate type. In particular, you can say *twiddle = sub {...}
to change the definition of the subroutine &twiddle
without affecting $twiddle
and friends.
The strict pragmatic directive
If the strict pragmatic directive is in effect, then variables need explicit scope declaration, so should be prefixed with a my or our keyword depending on the required level of scope:
<lang perl>use strict; our $fruit; # declare a variable as global our $veg = "carrot"; # declare a global variable and define its value</lang>
Local and global variables
The following example shows the use of local and global variables:
<lang perl>$fruit="apple"; # this will be global by default
sub dofruit {
print "My global fruit was $fruit,"; # use the global variable my $fruit="banana"; # declare a new local variable print "and the local fruit is $fruit.\n";
}
dofruit; print "The global fruit is still $fruit";</lang>
Perl 6
Much of what is true for Perl 5 is also true for Perl 6. Some exceptions:
There are no typeglobs in Perl 6.
Assigning an array to a scalar variable now makes that scalar variable a reference to the array:
<lang Perl6> my @y = <A B C D>; #Array of strings 'A', 'B', 'C', and 'D'
my $x = @y; # $x is now a reference for the array @y
say $x[1]; # prints 'B' follow by a newline character </lang>
Types and constraints can also be applied to variables in Perl 6:
<lang Perl6>
# $x can contain only Int objects my Int $x;
# $x can only contain native integers (not integer objects) my int $x;
#A variable may itself be bound to a container type that specifies how the container works, without specifying what kinds of things it contains. # $x is implemented by the MyScalar class my $x is MyScalar;
#Constraints and container types can be used together: # $x can contain only Int objects, # and is implemented by the MyScalar class my Int $x is MyScalar;
</lang>
(Includes code modified from http://perlcabal.org/syn/S02.html#Built-In_Data_Types. See this reference for more details.)
(Much more can and should be said here).
PL/I
<lang pli>/* The PROCEDURE block and BEGIN block are used to delimit scopes. */
declare i float; /* external, global variable, excluded from the */
/* local area (BEGIN block) below. */
begin;
declare (i, j) fixed binary; /* local variable */ get list (i, j); put list (i,j);
end;
/* Examples of initialization. */
declare p fixed initial (25); declare q(7) fixed initial (9, 3, 5, 1, 2, 8, 15);
/* sets all elements of array Q at run time, on block entry. */
declare r(7) fixed initial (9, 3, 5, 1, 2, 8, 15);
/* sets all elements of array R at compile time. */
p = 44; /* run-time assignment. */ q = 0; /* run-time initialization of all elements of Q to zero. */ q = r; /* run-time assignment of all elements of array R to */
/* corresponding elemets of S. */</lang>
PicoLisp
You can control the local bindings of symbols with functions like 'use' or 'let': <lang PicoLisp>(use (A B C)
(setq A 1 B 2 C 3) ... )</lang>
This is equivalent to <lang PicoLisp>(let (A 1 B 2 C 3)
... )</lang>
The parentheses can be omitted if there is only a single variable <lang PicoLisp>(use A
(setq A ..) ... )
(let A 1
...)</lang>
Other functions that handle local bindings are 'let?', 'bind', 'job', 'with' or 'for'.
PHP
<lang PHP><?php /**
* @author Elad Yosifon */
/*
* PHP is a weak typed language, * no separation between variable declaration, initialization and assignment. * * variable type is defined by the value that is assigned to it. * a variable name must start with a "$" sign (called "sigil", not a dollar sign). * variable naming rules: * + case-sensitive. * + first character after $ must not be a number. * + after the first character all alphanumeric chars and _(underscore) sign is allowed, e.g. $i_am_a_new_var_with_the_number_0 * */
- NULL typed variable
$null = NULL; var_dump($null); // output: null
- defining a boolean
$boolean = true; var_dump($boolean); // output: boolean true $boolean = false; var_dump($boolean); // output: boolean false
/*
* casting is made using (TYPE) as a prefix */
- bool and boolean is the same
$boolean = (bool)1; var_dump($boolean); // output: boolean true $boolean = (boolean)1; var_dump($boolean); // output: boolean true
$boolean = (bool)0; var_dump($boolean); // output: boolean false $boolean = (boolean)0; var_dump($boolean); // output: boolean false
- defining an integer
$int = 0; var_dump($int); // output: int 0
- defining a float,
$float = 0.01; var_dump($float); // output: float 0.01
- which is also identical to "real" and "double"
var_dump((double)$float); // output: float 0.01 var_dump((real)$float); // output: float 0.01
- casting back to int (auto flooring the value)
var_dump((int)$float); // output: int 0 var_dump((int)($float+1)); // output: int 1 var_dump((int)($float+1.9)); // output: int 1
- defining a string
$string = 'string'; var_dump($string); // output: string 'string' (length=6)
- referencing a variable (there are no pointers in PHP).
$another_string = &$string; var_dump($another_string); // output: string 'string' (length=6)
$string = "I'm the same string!"; var_dump($another_string); // output: string 'I'm the same string!' (length=20)
- "deleting" a variable from memory
unset($another_string);
$string = 'string'; /*
* a string can also be defined with double-quotes, HEREDOC and NOWDOC operators. * content inside double-quotes is being parsed before assignment. * concatenation operator is .= */
$parsed_string = "This is a $string"; var_dump($parsed_string); // output: string 'This is a string' (length=16) $parsed_string .= " with another {$string}"; var_dump($parsed_string); // output: string 'This is a string with another string' (length=36)
- with string parsing
$heredoc = <<<HEREDOC This is the content of \$string: {$string} HEREDOC; var_dump($heredoc); // output: string 'This is the content of $string: string' (length=38)
- without string parsing (notice the single quotes surrounding NOWDOC)
$nowdoc = <<<'NOWDOC' This is the content of \$string: {$string} NOWDOC; var_dump($nowdoc); // output: string 'This is the content of \$string: {$string}' (length=42)
- as of PHP5, defining an object typed stdClass => standard class
$stdObject = new stdClass(); var_dump($stdObject); // output: object(stdClass)[1]
- defining an object typed Foo
class Foo {} $foo = new Foo(); var_dump($foo); // output: object(Foo)[2]
- defining an empty array
$array = array(); var_dump($array); // output: array {empty}
/*
* an array with non-integer key is also considered as an associative array(i.e. hash table) * can contain mixed variable types, can contain integer based keys and non-integer keys */
$assoc = array( 0 => $int, 'integer' => $int, 1 => $float, 'float' => $float, 2 => $string, 'string' => $string, 3 => NULL, // <=== key 3 is NULL 3, // <=== this is a value, not a key (key is 4) 5 => $stdObject, 'Foo' => $foo, ); var_dump($assoc);
// output: // ======= // array // 0 => int 0 // 'integer' => int 0 // 1 => float 0.01 // 'float' => float 0.01 // 2 => string 'string' (length=6) // 'string' => string 'string' (length=6) // 3 => null // 4 => int 3 // 5 => // object(stdClass)[1] // 'Foo' => // object(Foo)[2]
/*
* all variables are "global" but not reachable inside functions(unless specifically "globalized" inside) */
function a_function() { # not reachable var_dump(isset($foo)); // output: boolean false
global $foo; # "global" (reachable) inside a_function()'s scope var_dump(isset($foo)); // output: boolean true }
a_function();
/**
* there is another special type of variable called (Resource). * for more info regarding Resources: * @url http://php.net/manual/en/language.types.resource.php * @url http://php.net/manual/en/resource.php */
</lang>
PureBasic
<lang PureBasic>; Variables are initialized when they appear in sourcecode with default value of 0 and type int Debug a
- or value "" for a string, they are not case sensitive
Debug b$
- This initializes a double precision float, if type is following the dot
Debug c.d
- They can be initialized with define (double precision float, string, integer)
Define d.d = 3.5, e$ = "Test", f.i = a + 2
- Define can have a default type (all bytes except j which is long)
Define.b g, h, j.l
- Define without following variables sets default type. In this case to single precision float
Define.f
- So this will be an single precision float and no integer
Debug k
- EnableExplicit forces declaration of used variables with define
EnableExplicit
- Will throw an error because L isn't initialized
Debug L DisableExplicit
- Global Variables are available in Procedures and Threads too
Global M = 3, N = 2 Procedure Dummy(parameter1, parameter2 = 20)
; Parameter contain values which where used when calling the function, ; their types have to be specified in the above Procedure header. ; The last ones can have default values which get applied if this parameter is not given.
; Variables in Procedures are separate from those outside, ; so d can be initialized again with another type ; which would otherwise lead to an error d.i ; Protected makes a variable local even if another one with same name is declared as global (see above) Protected M = 2 ; Shares a variable with main program like it was declared by global Shared a ; prevents a variable to be initialized with default value again when procedure is called a second time, ; could be used for example as a counter, which contains the number of times a function was called Static a ; N here also would have a value of 2, while for example ; f would, when named, initialize a new variable, and so have a value of 0
EndProcedure
- finally there are constants which are prefixed by an #
- Test = 1
- Their value cannot be changed while program is running
- String_Constant = "blubb"
- In constrast to variables, a constant has no types except an (optional) $ sign to mark it as string constant
- Float_Constant = 2.3
- Maps, LinkedLists , Arrays and Structures are not handled here, because they are no elemental variables</lang>
PowerShell
Variables in PowerShell start with a $ character, they are created on assignment and thus don't need to be declared: <lang powershell>$s = "abc" $i = 123</lang> Uninitialized variables expand to nothing. This may be interpreted for example as an empty string or 0, depending on context: <lang powershell>4 + $foo # yields 4 "abc" + $foo + "def" # yields "abcdef"</lang> Variables all show up in the Variable: drive and can be queried from there with the usual facilities: <lang powershell>Get-ChildItem Variable:</lang> Since Variables are provided via a flat filesystem, they can be manipulated using the common cmdlets for doing so. For example to delete a variable one can use <lang powershell>Remove-Item Variable:foo</lang> as if it were a file or a registry key. There are, however, several cmdlets dealing specifically with variables: <lang powershell>Get-Variable # retrieves the value of a variable New-Variable # creates a new variable Set-Variable # sets the value of a variable Clear-Variable # deletes the value of a variable, but not the variable itself Remove-Variable # deletes a variable completely</lang>
Python
Names in Python are not typed, although all the objects referred to by them, are. Names are lexically scoped by function/method/class definitions, and must be defined before use.
Names in global statements are looked up in the outermost context of the program or module. Names in a nonlocal statement are looked up in the order of closest enclosing scope outwards.
R
Variables are dynamically typed, so they do not need to be declared and instantiated separately. <- and = are both used as the assignment operator, though <- is preferred, for compatibility with S-Plus code. <lang R>foo <- 3.4 bar = "abc"</lang> It is possible to assign multiple variables with the same value, and to assign values from left to right. <lang R>baz <- quux <- 1:10 TRUE -> quuux</lang> There are also global assignment operators, <<- and ->>. From their help page:
The operators '<<-' and '->>' cause a search to made through the environment for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment.
In practice, this usually means that variables are assigned in the user workspace (global environment) rather than a function. <lang R>a <- 3
assignmentdemo <- function() {
message("assign 'a' locally, i.e. within the scope of the function") a <- 5 message(paste("inside assignmentdemo, a = ", a)) message(paste("in the global environment, a = ", get("a", envir=globalenv()))) message("assign 'a' globally") a <<- 7 message(paste("inside assignmentdemo, a = ", a)) message(paste("in the global environment, a = ", get("a", envir=globalenv())))
} assignmentdemo()</lang>
assign 'a' locally, i.e. within the scope of the function inside assignmentdemo, a = 5 in the global environment, a = 3 assign 'a' globally inside assignmentdemo, a = 5 in the global environment, a = 7
Finally, there is also the assign function, where you choose the environment to assign the variable. <lang R>assign("b", TRUE) #equivalent to b <- TRUE assign("c", runif(10), envir=globalenv()) #equivalent to c <<- runif(10)</lang>
Racket
<lang Racket>
- lang racket
- define a variable and initialize it
(define foo 0)
- increment it
(set! foo (add1 foo))
- Racket is lexically scoped, which makes local variables work
(define (bar)
(define foo 100) (set! foo (add1 foo)) foo)
(bar) ; -> 101
- and it also makes it possible to have variables with a global value
- that are accessible only in a specific local lexical scope
(define baz
(let () ; used to create a new scope (define foo 0) (define (bar) (set! foo (add1 foo)) foo) bar)) ; this is the value that gets bound to `baz'
(list (baz) (baz) (baz)) ; -> '(1 2 3)
- define a new type, and initialize a variable with an instance
(struct pos (x y)) (define p (pos 1 2)) (list (pos-x p) (pos-y p)) ; -> '(1 2)
- for a mutable reference, a struct (or some specific fields in a
- struct) can be declared mutable
(struct mpos (x y) #:mutable) (define mp (mpos 1 2)) (set-mpos-x! mp 11) (set-mpos-y! mp 22) (list (mpos-x mp) (mpos-y mp)) ; -> '(11 22)
- but for just a mutable value, we have boxes as a builtin type
(define b (box 10)) (set-box! b (add1 (unbox b))) (unbox b) ; -> 11
- (Racket has many more related features
- static typing in typed
- racket, structs that are extensions of other structs,
- pattern-matching on structs, classes, and much more)
</lang>
Rascal
The effect of a variable declaration is to introduce a new variable Name and to assign the value of expression Exp to Name. A variable declaration has the form <lang rascal> Type Name = Exp;</lang> A mention of Name later on in the same scope will be replaced by this value, provided that Name’s value has not been changed by an intermediate assignment. When a variable is declared, it has as scope the nearest enclosing block, or the module when declared at the module level.
There are two rules you have to take into account. Double declarations in the same scope are not allowed. Additionally, the type of Exp should be compatible with Type, i.e., it should be a subtype of Type.
As a convenience, also declarations without an initialization expression are permitted inside functions (but not at the module level) and have the form <lang rascal>Type Name;</lang> and only introduce the variable Name.
Rascal provides local type inference, which allows the implicit declaration of variables that are used locally in functions. There are four rules that apply when doing so. (1) An implicitly declared variable is declared at the level of the current scope, this may the whole function body or a block nested in it. (2) An implicitly declared variable gets as type the type of the first value that is assignment to it. (3) If a variable is implicitly declared in different execution path of a function, all these implicit declarations should result in the same type. (4) All uses of an implicitly declared variable must be compatible with its implicit type.
Examples
Two explicit variable declarations: <lang rascal>rascal>int max = 100; int: 100 rascal>min = 0; int: 0</lang>
An implicit variable declaration <lang rascal>rascal>day = {<"mon", 1>, <"tue", 2>, <"wed",3>, >>>>>>> <"thu", 4>, <"fri", 5>, <"sat",6>, <"sun",7>}; rel[str, int]: {
<"thu",4>, <"mon",1>, <"sat",6>, <"wed",3>, <"tue",2>, <"fri",5>, <"sun",7>
}</lang>
Variable declaration and assignment leading to type error <lang rascal>rascal>int month = 12; int: 12 rascal>month ="December"; |stdin:///|(7,10,<1,7>,<1,17>): Expected int, but got str</lang>
Pitfalls Local type inference for variables always uses the smallest possibe scope for a variable; this implies that a variable introduced in an inner scope is not available outside that scope. Here is how things can go wrong: <lang rascal>rascal>if( 4 > 3){ x = "abc"; } else { x = "def";} str: "abc" rascal>x; |stdin:///|(0,1,<1,0>,<1,1>): Undeclared variable, function or constructor: x</lang>
REXX
assignments via =
REXX has only one type of variable: a (character) string.
There is no need to declare anything (indeed, there is no way to declare anything at all).
All unassigned REXX variables have a default value of the variable name (in uppercase).
There is no way to initialize a variable except to assign it a value (by one of the methods below), however,
there is a way to "initialize" a (stemmed) array in REXX with a default value) ── see the 6th section below,
default value for an array.
To assign some data (value) to a variable, one method is to use the assignment operator, an equal sign (=):
<lang rexx>aa = 10 /*assigns chars 10 ───► AA */
bb = /*assigns a null value ───► BB */
cc = 2*10 /*assigns charser 20 ───► CC */
dd = 'Adam' /*assigns chars Adam ───► DD */
ee = "Adam" /*same as above ───► EE */
ff = 10. /*assigns chars 10. ───► FF */
gg='10.' /*same as above ───► GG */
hh = "+10" /*assigns chars +10 ───► hh */
ii = 1e1 /*assigns chars 1e1 ───► ii */
jj = +.1e+2 /*assigns chars +.1e+2 ───► jj */</lang>
Variables aa, ff, gg, hh, ii, and jj will all be considered numerically equal in REXX (but not exactly equal except for ff and gg).
assignments via PARSE
<lang rexx>kk = '123'x /*assigns hex 00000123 ───► KK */ kk = 'dead beaf'X /*assigns hex deadbeaf ───► KK */ ll = '0000 0010'b /*assigns blank ───► LL (ASCII) */ mm = '0000 0100'B /*assigns blank ───► MM (EBCDIC)*/
xxx = '11 2. 333 -5' parse var xxx nn oo pp qq rr
/*assigns 11 ───► NN */ /*assigns 2. ───► OO */ /*assigns 333 ───► PP */ /*assigns ─5 ───► QQ */ /*assigns "null" ───► RR */
/*a "null" is a string of length zero (0), */ /*and is not to be confused with a null char.*/
cat = 'A cat is a lion in a jungle of small bushes.'
/*assigns a literal ───► CAT */</lang>
assignments via VALUE
Assignments can be made via the value BIF [Built-In Function] (which also has other capabilities), the
capability used here is to create a variable name programmatically (normally using concatenation or abuttal).
<lang rexx>call value 'CAT', "When the cat's away, the mice will play."
/*assigns a literal ───► CAT */
yyy='CA' call value yyy'T', "Honest as the Cat when the meat's out of reach."
/*assigns a literal ───► CAT */
yyy = 'CA' call value yyy || 'T', "Honest as the Cat when the meat's out of reach."
/*assigns a literal ───► CAT */</lang>
unassigned variables
There are methods to catch unassigned variables in REXX. <lang REXX>/*REXX pgm to do a "bad" assignment (with an unassigned REXX variable).*/
signal on noValue /*usually, placed at pgm start. */
xxx=aaaaa /*tries to assign aaaaa ───► xxx */
say xxx 'or somesuch' exit
noValue: /*this can be dressed up better. */
badLine =sigl /*REXX line number that failed. */
badSource=sourceline(badLine) /*REXX source line ··· */
badVar =condition('D') /*REXX var name that's ¬ defined.*/
say
say '*** error! ***'
say 'undefined variable' badvar "at REXX line number" badLine
say
say badSource
say
exit 13</lang>
Note: the value (result) of the condition BIF can vary in different implementations of a REXX interpreter.
output using Regina (various versions), PC/REXX, and Personal REXX:
*** error! *** undefined variable AAAAA at REXX line number 5 xxx=aaaaa /*tries to assign aaaaa ───► xxx */
output using R4 REXX:
Error 46 : Invalid variable reference (NOVALUE) Information: Variable aaaaa does not have an assigned value Error occurred in statement# 5 Statement source: xxx= aaaaa Statement context: D:\variabl4.rex, procedure: variabl4
scope of variables
REXX subroutines/functions/routines/procedures can have their own "local" variables if the procedure statement is used.
Variables can be shared with the main program if the variables are named on the procedure statement with the expose keyword.
<lang rexx>/*REXX pgm shows different scopes of a variable: "global" and "local".*/
q = 55 ; say ' 1st q=' q /*assign a value ───► "main" Q.*/
call sub ; say ' 2nd q=' q /*call a procedure subroutine. */
call gyro ; say ' 3rd q=' q /*call a procedure with EXPOSE. */
call sand ; say ' 4th q=' q /*call a subroutine or function. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────SUB subroutine──────────────────────*/
sub: procedure /*use PROCEDURE to use local vars*/
q = -777 ; say ' sub q=' q /*assign a value ───► "local" Q. */
return
/*──────────────────────────────────GYRO subroutine─────────────────────*/
gyro: procedure expose q /*use EXPOSE to use global var Q.*/
q = "yuppers" ; say 'gyro q=' q /*assign a value ───► "exposed" Q*/
return
/*──────────────────────────────────SAND subroutine─────────────────────*/
sand: /*all REXX variables are exposed.*/
q = "Monty" ; say 'sand q=' q /*assign a value ───► "global" Q*/
return</lang>
output
1st q= 55 sub q= -777 2nd q= 55 gyro q= yuppers 3rd q= yuppers sand q= Monty 4th q= Monty
Programming note: there is also a method in REXX to expose a list of variables.
default value for an array
There is a way in REXX to assign a default value (or an initial value, if you will) to a (stemmed) array. <lang rexx>aaa. = '───────nope.' /*assign this string as a default*/ aaa.1=1 /*assign 1 to first element.*/ aaa.4=4. /* " 4 " fourth " */ aaa.7='lucky' /* " 7 " seventh " */
do j=0 to 8 /*go through a bunch of elements.*/ say 'aaa.'||j '=' aaa.j /*display element # and its value*/ end /*we could've started J at -100.*/</lang>
dropping a variable
In REXX, dropping a variable (this can be thought of as deallocating it or setting the value back to its "default").
Note that the storage used by the variable's (old) value is not truly deallocated, but its storage is returned to the
pool of storage available for allocation of other REXX variables (and their values). This action isn't mandatory
for the REXX language (or for that matter, not even specified), but it's apparently what all (Classic) REXX
interpreters do at the the time of this writing.
<lang rexx>radius=6.28 /*assign a value to a variable. */
say 'radius =' radius
drop radius /*now, "undefine" the variable. */
say 'radius =' radius</lang>
Note: The value of an undefined (or deallocated) REXX variable is the uppercased name of the REXX variable name.
output
radius = 6.28 radius = RADIUS
compound variables
In additions to the (simple) variables described above, REXX defines compound variables that consist of a stem (symbol.) followed by a list of period-separated simple variables and constants The compond variable's tail is computed by concatenating the variables' values (which can be any string) with the constants and the intervening periods. <lang>var.='something' /* sets all possible compound variables of stem var. */ x='3 ' var.x.x.4='something else' Do i=1 To 5
a=left(i,2) Say i var.a.a.4 "(tail is '"a||'.'||a||'.'||'4'"')" End</lang>
Output:
1 something (tail is '1 .1 .4') 2 something (tail is '2 .2 .4') 3 something else (tail is '3 .3 .4') 4 something (tail is '4 .4 .4') 5 something (tail is '5 .5 .4')
Ruby
Information taken from Variables page at the Ruby User's Guide
Ruby has three kinds of variables, one kind of constant and exactly two pseudo-variables. The variables and the constants have no type. While untyped variables have some drawbacks, they have many more advantages and fit well with ruby's quick and easy philosophy.
Variables must be declared in most languages in order to specify their type, modifiability (i.e., whether they are constants), and scope; since type is not an issue, and the rest is evident from the variable name as you are about to see, we do not need variable declarations in ruby.
The first character of an identifier categorizes it at a glance:
$ global variable @ instance variable [a-z] or _ local variable [A-Z] constant The only exceptions to the above are ruby's pseudo-variables:
self
, which always refers to the currently executing object, andnil
, which is the meaningless value assigned to uninitialized variables. Both are named as if they are local variables, butself
is a global variable maintained by the interpreter, andnil
is really a constant. As these are the only two exceptions, they don't confuse things too much.
Referencing an undefined global or instance variable returns nil
. Referencing an undefined local variable throws a NameError
exception.
<lang ruby>$a_global_var = 5 class Demo
@@a_class_var = 6 A_CONSTANT = 8 def initialize @an_instance_var = 7 end def incr(a_local_var) @an_instance_var += a_local_var end
end</lang>
Scala
Variables in Scala can have three different scopes depending on the place where they are being used. They can exist as fields, as method parameters and as local variables. Below are the details about each type of scope:
- Fields are variables that belong to an object. The fields are accessible from inside every method in the object. Fields can also be accessible outside the object depending on what access modifiers the field is declared with. Object fields can be both mutable or immutable types and can be defined using respectively var or val.
- Method parameters are variables, which are used to pass the value inside a method when the method is called. Method parameters are only accessible from inside the method but the objects passed in may be accessible from the outside, if you have a reference to the object from outside the method. Method parameters are always immutable and defined by val keyword. In algebraic datatypes (Scala's case classes), -think records- the parameters looks like method parameters. In this case they are fields.
- Local variables are variables declared inside a method. Local variables are only accessible from inside the method, but the objects you create may escape the method if you return them from the method. Local variables can be both mutable or immutable types and can be defined using respectively var or val.
Seed7
Seed7 variables must be defined with type and initialization value, before they are used. There are global variables and variables declared local to a function. <lang seed7>$ include "seed7_05.s7i";
var integer: foo is 5; # foo is global
const proc: aFunc is func
local var integer: bar is 10; # bar is local to aFunc begin writeln("foo + bar = " <& foo + bar); end func;
const proc: main is func
begin aFunc; end func;</lang>
SNOBOL4
Local variables in Snobol are declared in a function definition prototype string:
<lang SNOBOL4> define('foo(x,y)a,b,c') :(foo_end) foo a = 1; b = 2; c = 3
foo = a * ( x * x ) + b * y + c :(return)
foo_end</lang>
This defines a function foo( ) taking two arguments x,y and three localized variables a,b,c. Both the argument parameters and vars are dynamically scoped to the function body, and visible to any called functions within that scope. The function name also behaves as a local variable, and may be assigned to as the return value of the function. Any variable initialization or assignment is done explicitly within the function body. Unassigned variables have a null string value, which behaves as zero in numeric context.
Snobol does not support static or lexical scoping, or module level namespaces. Any variables not defined in a prototype are global to the program.
Tcl
Tcl's variables are local to procedures, lambdas and methods by default, and there is no initialization per se: only assignment when the variable previously did not exist.
Demonstrating: <lang tcl>namespace eval foo {
# Define a procedure with two formal arguments; they are local variables proc bar {callerVarName argumentVar} { ### Associate some non-local variables with the procedure global globalVar; # Variable in global namespace variable namespaceVar; # Variable in local (::foo) namespace # Access to variable in caller's context; may be local or global upvar 1 callerVarName callerVar
### Reading a variable uses the same syntax in all cases puts "caller's var has $callerVar" # But global and namespace vars can be accessed by using qualified names puts "global var has $globalVar which is $::globalVar"
### Writing a variable has no special syntax ### but [set] is by far the most common command for writing set namespaceVar $globalVar incr globalVar
### Destroying a variable is done like this unset argumentVar }
}</lang> The main thing to note about Tcl is that the "$" syntax is a language level operator for reading a variable and not just general syntax for referring to a variable.
TI-83 BASIC
Variables will remain global, even after the program is complete. Global variables persist until deleted (or reset or power loss, unless they are archived).
Variables may be assigned with the →
to a value.
<lang ti83b>
- 1→A
</lang>
TI-89 BASIC
A variable not declared local (to a program or function) is global. Global variables are grouped into folders of which one is current at any given time. Global variables persist until deleted (or reset or power loss, unless they are archived).
<lang ti89b>Local mynum, myfunc</lang>
Variables may be assigned with the →
or Define
statements, both of which assign a new value to a variable. →
is typically used interactively, but only Define
can assign programs or multi-statement functions.
<lang ti89b>Define mynum = 1 © Two ways to assign a number 1 → mynum
Define myfunc(x) = (sin(x))^2 © Two ways to assign a function (sin(x))^2 → myfunc(x)
Define myfunc(x) = Func © Multi-statement function
If x < 0 Then Return –x Else Return x EndIf
EndFunc</lang>
TUSCRIPT
<lang tuscript> $$ MODE TUSCRIPT,{} var1=1, var2="b" PRINT "var1=",var1 PRINT "var2=",var2
basket=* DATA apples DATA bananas DATA cherry
LOOP n,letter="a'b'c",fruit=basket var=CONCAT (letter,n) SET @var=VALUE(fruit) PRINT var,"=",@var ENDLOOP </lang> Output:
var1=1 var2=b a1=apples b2=bananas c3=cherry
TXR
Variables have a form of pervasive dynamic scope in TXR. Each statement ("directive") of the query inherits the binding environment of the previous, invoking, or surrounding directive, as the case may be. The initial contents of the binding environment may be initialized on the interpreter's command line. The environment isn't simply a global dictionary. Each directive which modifies the environment creates a new version of the environment. When a subquery fails and TXR backtracks to some earlier directive, the original binding environment of that directive is restored, and the binding environment versions generated by backtracked portions of the query turn to garbage.
Simple example: the cases
<lang txr>@(cases)
hey @a
how are you
@(or)
hey @b
long time no see
@(end)</lang>
This directive has two clauses, matching two possible input cases, which have a common first line. The semantics of cases is short-circuiting: the first successful clause causes it to succeed and stop processing subsequent clauses. Suppose that the input matches the second clause. This means that the first clause will also match the first line, thereby establishing a binding for the variable a
. However, the first clause fails to match on the second line, which means that it fails. The interpreter then moves to the second clause, which is tried at the original input position, under the original binding environment which is devoid of the a
variable. Whichever clause of the cases
is successful will pass both its environment modifications and input position increment to the next element of the query.
Under some other constructs, environments may be merged:
<lang txr>@(maybe) @a bar @(or) foo @b @(end)</lang>
The maybe
directive matches multiple clauses such that it succeeds no matter what, even if none of the clauses succeed. Clauses which fail have no effect, but the effects of all successful clauses are merged. This means that if the input which faces the above maybe
is the line "foo bar"
, the first clause will match and bind a
to foo, and the second clause will also match and bind b
to bar. The interpreter integrates these results together and the environment which emerges has both bindings.
UNIX Shell
<lang sh>
- !/bin/sh
- The unix shell uses typeless variables
apples=6
- pears=5+4 # Some shells cannot perform addition this way
pears = `expr 5+4` # We use the external expr to perform the calculation myfavourite="raspberries" </lang>
XPL0
There are only three variable types: 32-bit signed integers (in the 32-bit version), IEEE-754 64-bit reals, and characters which are actually 32-bit addresses of (or pointers to) strings. When a 'char' variable is subscripted, it accesses a single byte. All variable names must be declared before they are used, for example: int I, J, K; real X, Y, Array(10); char String(80); Variables (as well as all declared names, such as for procedures) must start with a capital letter or underline. Names may contain digits or underlines and be any length, but only the first 16 characters are significant. Names are case-insensitive by default, unless the /c switch is used when compiling. Variables are usually assigned values like this: X:= 3.14, but the first declared variables in a procedure can have argument values passed into them. Variables other than arguments are only initialized by explicit assignments in the body of the code. Local variables are encapsulated in the procedures that declare them and are not visible (are out of scope) outside those procedures. Procedures can be (statically) nested several levels deep. The deepest procedure can "see" all variables declared in the procedures in which it is nested. If two variables are declared with identical names, the most local one is used.
XSLT
Although called variables, XSLT "variable" elements are single-assignment, and so behave more like constants. They are valid in the node scope in which they are declared. <lang xml><xsl:variable name="foo" select="XPath expression" /> <xsl:if test="$foo = 4">... </xsl:if> </lang>
zkl
The are two variable type in zkl, register (auto in C) and var (instance variable). vars are global to class [instance], registers are visible to their scope and enclosed scopes. In addition, a function can have vars (static var in C), which are actually [hidden] instance data. vars have no type. <lang zkl>var v; // global to the class that encloses this file class C{ var v } // global to class C, each instance gets a new v class C{fcn f{var v=123;}} // v can only be seen by f, initialized when C is class C{fcn init{var [const] v=5;}} // init is part of the constructor,
so vars are promoted yo class scope. This allows const vars to be created at construction time
var v=123; v="hoho"; //not typed class C{var v} // C.v OK, but just v is not found class C{var[const]v=4} // C.v=3 illegal (compile or run time, depending) class C{var[mixin]v=4} // the compiler treats v as an int for type checking class C{var[proxy]v=f; fcn f{println("my name is ",self.fcn.name)} }
v acts like a property to run f so C.v is the same as C.f()
class C{reg r} // C.r is compile time error r:=5; // := syntax is same as "reg r=5", convenience</lang>
- Programming Tasks
- Basic language learning
- Simple
- Ada
- ALGOL 68
- AppleScript
- AutoHotkey
- AWK
- BASIC
- Applesoft BASIC
- Batch File
- BBC BASIC
- Bracmat
- C
- ChucK
- C++
- C sharp
- COBOL
- Common Lisp
- Delphi
- D
- DWScript
- E
- Ela
- Erlang
- F Sharp
- Factor
- Forth
- Fortran
- GAP
- Go
- Haskell
- HicEst
- Icon
- Unicon
- J
- Java
- JavaScript
- Joy
- Liberty BASIC
- Julia
- Lasso
- Logo
- LotusScript
- Lua
- Mathematica
- MATLAB
- Octave
- Modula-3
- Nimrod
- Objeck
- OCaml
- Openscad
- Oz
- PARI/GP
- Pascal
- Perl
- Perl 6
- PL/I
- PicoLisp
- PHP
- PureBasic
- PowerShell
- Python
- R
- Racket
- Rascal
- REXX
- Ruby
- Scala
- Seed7
- SNOBOL4
- Tcl
- TI-83 BASIC
- TI-89 BASIC
- TUSCRIPT
- TXR
- UNIX Shell
- XPL0
- XSLT
- Zkl
- GUISS/Omit
- Unlambda/Omit
- Retro/Omit
- Initialization
- Scope