Enforced immutability: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(→‎{{header|Vlang}}: Rename "Vlang" in "V (Vlang)")
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(9 intermediate revisions by 5 users not shown)
Line 239:
Constants in COBOL are not stored in memory, but are closer to C's macros, by associating a literal with a name.
Prior to COBOL 2002, you could define figurative literals for characters only:
<syntaxhighlight lang="cobol"> ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
SYMBOLIC CHARACTERS NUL IS 0, TAB IS 9.</syntaxhighlight>
 
A new syntax was introduced in COBOL 2002 which allowed defining constants for other types.
<syntaxhighlight lang="cobol"> 01 Foo CONSTANT AS "Foo".</syntaxhighlight>
 
Prior to COBOL 2002, there were non-standard extensions available that also implemented constants. One extension was the the 78 level-number:
<syntaxhighlight lang="cobol"> 78 Foo VALUE "Foo".</syntaxhighlight>
Another was the <code>CONSTANT SECTION</code>:
<syntaxhighlight lang="cobol"> CONSTANT SECTION.
01 Foo VALUE "Foo".</syntaxhighlight>
 
=={{header|D}}==
Line 620:
{{works with|lua|5.4}}
<syntaxhighlight lang="lua">local pi <const> = 3.14159265359</syntaxhighlight>
 
=={{header|M2000 Interpreter}}==
====Four Examples for Constant/Final modifiers====
Modules and functions in M2000 can change definitions with another definition (excluded subs and simple functions which are written at the end of module/function). So except for variables to be immutable we have to do something with modules and functions, only for members of groups (the user defined object in M2000).
 
Here we have four big modules (in a module say A). The first show how to use final in class/group definition, and what happen if we use class inheritance. The second module show how we can produce group from merging two others (here using With operator), and what happen with final members. The third module show how we use a reference to global constant, and how we can check type. The last module show constant with lambda functions.
 
<syntaxhighlight lang="m2000 interpreter">
module inheritanceByClass {
class alfa {
// final x is an object with the value of x,
// and interpreter trait it as read only variable
final x=100
// module just marked as final
module final tryme {
Print "Can't change"
}
}
class delta as alfa {
x=500
// modules and functions can alter definitions
// by a new one, unless they have marked final
// only for modules/functions as member of groups.
module tryme {
print "I win or not ?"
}
}
z=delta()
print z.x =100
z.tryme ' can't change
}
inheritanceByClass
 
module inheritanceByInstance {
class alfa {
final x=100
module final tryme {
Print "Can't change"
}
}
class delta {
x=500
module tryme {
print "I win or not ?"
}
}
 
z1=delta() with alfa()
// x is final, because delta be on top of alfa
print z1.x=100
try {
z1.x++
}
print z1.x=100
// that didn't hold for module. The final on module, close it.
z1.tryme ' can't change
z2=alfa() with delta()
// the following statements show every public identifier we make, including those non on scope.
// use List to see what we have as variables here (including members of z1, z2)
// use List ! to render ouput using proportional character spacing
// constant values displayed inside square brackets like this [100]
list !
modules ? // use this to see what functions we have until here
// x isn't final, because alfa be on top of delta,
// because x exist as number, can't change to const object.
print z2.x=500
try {
z2.x++
}
print z2.x=501
// that didn't hold for module. The final on module, close it.
z2.tryme ' can't change
}
inheritanceByInstance
 
Module ConstantGlobal {
global const p2 as single=1.57096
module inner {
const p2 // raise error if no global const p2 exist
print p2, type$(p2)="Constant"
def type(x)=type$(x)
print type(p2)="Single" // true
}
Inner
}
ConstantGlobal
module checkLambdaConstant {
const a=lambda (x)->x**2
print a(3)=9
try {
a=lambda (x)->x*5
}
print a(3)=9 // we can't copy to a a new lambda
module checkhere (z) {
print z(3)=9
try {
z=lambda (x)->x*5
}
print z(3)=15
}
// pass by copy of a, but not as constant
checkhere a
// assign to z a copy of a, but not as constant
z=a
print z(3)=9
try {
z=lambda (x)->x*5
}
print z(3)=15 // true
// redefinition of checkhere
module checkhere {
const z=stackitem() ' get a copy of top of stack
drop ' drop top of stack
print z(3)=9
try {
z=lambda (x)->x*5
}
print z(3)=9 // z not changed now
}
// now we pass a copy, but internal we make a constant lambda
checkhere a
// using by ref pass we send the const object, not a copy of it
// actually we send a weak reference, and at Read &z,
// the Read statement (Interpreter insert it automatic), make the link.
module checkByRef(&z) {
print z(3)=9
try {
z=lambda (x)->x*5
}
print z(3)=9 // z not changed
}
checkByRef &a
}
checkLambdaConstant
</syntaxhighlight>
 
====Partial constants by using enumeration types====
The value of a enumeration type may change to those of the same type (not the value type, the variable type)
 
 
<syntaxhighlight lang="m2000 interpreter">
enum constA {
x=10
y=30
}
// constB get two members of constA to same list, but x and y are defined once as ConstB
enum constB {
constA, z="ok"
}
// m is a ConstB type. X value exist in ConstB
def m as ConstB=x
 
module inner (z as constB) {
print z=10
try {
z=500
}
print z=10, eval$(z)="x"
check(z)
z++
print z=30, eval$(z)="y"
check(z)
z++
print z="ok", eval$(z)="z"
check(z)
try {
z=30 // ok 30 exist in enum constB list
}
check(z) // z is y now
sub check(z as constB)
select enum z // like a select case but for enumeration type to check names
case x ' check name of enum
print "it is x", z
case y
print "it is y", z
case z
print "it is z", z
end select
end sub
}
inner m
</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Line 936 ⟶ 1,119:
TypeError: 'Immut' object does not support item assignment
>>></syntaxhighlight>
 
=={{header|Quackery}}==
 
Quackery does not enforce immutability. The majority of Quackery is immutable by design; operators and numbers are immutable, and nests are immutable insomuch as the words in the nest editing wordset treat them as immutable.
 
Certain objects; the ancillary stacks, the system dictionaries, and tables are mutable of necessity, and have a specific set of words, the ancillary stacks wordset, dedicated to handling them. The words in this wordset can also be applied to nests if the programmer chooses to disregard the guidelines for their use provided in The Book of Quackery. In short, enforcement is eschewed in favour of relying on the programmer's good sense.
 
=={{header|Racket}}==
Line 1,338 ⟶ 1,527:
 
Note though that if fields are reference types (lists, maps, user-defined classes etc.) even a 'getter' method may enable their internal state to be mutated unless you copy them first.
<syntaxhighlight lang="ecmascriptwren">class A {
construct new(f) {
_f = f // sets field _f to the argument f
Line 1,359 ⟶ 1,548:
6
8
</pre>
 
{{libheader|Wren-trait}}
Since the above entry was written, a ''Const'' class has been added to ''Wren-trait'' which simulates constants to some extent though the values used need themselves to be immutable for this to be water-tight.
<syntaxhighlight lang="wren">import "./trait" for Const
 
Const["six"] = 6
Const["eight"] = 8
Const["six"] = 7 // ignored, still 6
System.print(Const.entries)</syntaxhighlight>
 
{{out}}
<pre>
[eight:8, six:6]
</pre>
 
Line 1,379 ⟶ 1,582:
 
{{omit from|AWK| Does not support constants or readonly variables}}
{{omit from|EasyLang|No way to define constants}}
{{omit from|Lily}}
{{omit from|Maxima}}
9,476

edits