Pointers and references: Difference between revisions

Add Ecstasy example
m (syntax highlighting fixup automation)
(Add Ecstasy example)
 
(6 intermediate revisions by 3 users not shown)
Line 494:
===Pointers===
Pointers are declared like so, optionally with the type or program they will point to:
<syntaxhighlight lang="cobolcobolfree"> 01 ptr USAGE USAGEIS POINTER TO Some-Type.
01 prog-ptr USAGE USAGEIS PROGRAM-POINTER TO "some-program". *> TO is optional</syntaxhighlight>
 
<code>USAGE POINTER</code> data items are used in conjunction with <code>BASED</code> data items, with <code>ALLOCATE</code> optionally giving a pointer the address of the allocated memory. Pointers can also be used to free allocated memory, which will cause the pointer to be set to <code>NULL</code>.
<syntaxhighlight lang="cobolcobolfree">ALLOCATE01 heap-item RETURNINGPICTURE IS X, ptrBASED.
 
...
PROCEDURE DIVISION.
FREE ptr</syntaxhighlight>
ALLOCATE heap-item RETURNING ptr
*> ...
FREE ptr</syntaxhighlight>
 
<code>USAGE PROGRAM-POINTER</code> data items are used to point to programs and their entry points.
{{works with|OpenCOBOL}}
{{works with|Visual COBOL}}
<syntaxhighlight lang="cobolcobolfree">SET prog-ptr TO ENTRY "some-program"</syntaxhighlight>
 
Both types of pointer support basic pointer arithmetic.
<syntaxhighlight lang="cobolcobolfree">SET ptr1 UP BY 10
SET ptr2 DOWN BY LENGTH OF foo</syntaxhighlight>
 
Pointers can also be set to point to where other pointers are pointing or to other pointers themselves.
<syntaxhighlight lang="cobolcobolfree">SET ptr1 TO ptr2 *> ptr1 points to where ptr2 points
SET ptr2 TO ADDRESS OF ptr3 *> ptr2 points to ptr3</syntaxhighlight>
 
To alter the value pointed to by a pointer, the <code>SET</code> statement is needed once again and is used to set the address of <code>BASED</code> or <code>LINKAGE SECTION</code> data items, which can then be used to modify the data.
<syntaxhighlight lang="cobolcobolfree">SET ADDRESS OF foo TO ptr
MOVE "bar" TO foo</syntaxhighlight>
 
===References===
Object references are declared like so, optionally with the class/interface they will reference:
<syntaxhighlight lang="cobolcobolfree"> 01 obj USAGE USAGEIS OBJECT-REFERENCE "some-object".</syntaxhighlight>
 
They contain either a reference to an object or <code>NULL</code>.
 
They are initialised using by invoking a class constructor, and set using the <code>SET</code> statement.
<syntaxhighlight lang="cobolcobolfree">INVOKE SomeClass "new" RETURNING obj-ref
SET another-obj-ref TO obj-ref</syntaxhighlight>
 
Line 672 ⟶ 675:
→ 666
</syntaxhighlight>
 
=={{header|Ecstasy}}==
In Ecstasy, all values are references to objects. These references are like pointers in C, but address information is not accessible, and no arithmetic operations can be performed on them. Additionally, each reference is itself an object, providing reflective information about the reference.
 
Objects are always accessed and manipulated through references, using the <code>.</code> ("dot") operator.
 
Ecstasy uses call-by-value. When passing arguments, all arguments are references, passed by value.
 
<syntaxhighlight lang="ecstasy">
module test {
@Inject Console console;
 
public class Point(Int x, Int y) {
@Override String toString() = $"({x},{y})";
}
 
void run() {
Point p = new Point(0, 0);
p.x = 7;
p.y = p.x;
console.print($"{p=}");
 
// obtain the reference object itself
Ref<Point> r = &p;
console.print($"{r.actualType=}");
}
}
</syntaxhighlight>
 
{{out}}
<pre>
x$ xec test
p=(7,7)
r.actualType=Point
</pre>
 
=={{header|Forth}}==
Line 939 ⟶ 977:
 
Java is call-by-value. When passing arguments, you are either passing primitives by value or references by value. There is no such thing as "passing an object" as objects are not values in the language. As noted above, if the object that the reference is pointing to is mutable, then it is possible to modify that object's state through the reference. Then if the calling function has a reference to the same object, they will see that modification through the reference. So if you want to reflect changes in an argument back to the caller, one thing that you can do is wrap the argument as a field in an object, then modify the object through the reference.
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
'''Also works with fq, a Go implementation of a large subset of jq'''
 
In the context of JSON, "JSON Pointer" usually refers to RFC 6901,
which defines a string format for accessing values from a JSON document
in an analogous manner as XPath defines a mechanism for accessing values from an XML document.
 
jq has no built-in support for JSON Pointer as it already provides an analogous mechanism
based on paths expressed as arrays. Specifically, a JSON array of strings and integers can be used to specify
a path, $p, and jq provides a function `getpath($p)` for accessing the value at the given path, $p.
 
In this entry, we will use the term "JSON pointer" to refer to either a JSON Pointer string, or a jq array path.
 
Neither JSON nor jq provides a mechanism for handling embedded JSON pointers, but a common convention
is to use a JSON object with a key named "$ref" as a reference. We will adopt this convention here,
as illustrated by the following JSON document:
 
<pre>
[
{
"name": "John",
"birthplace": "London"
},
{
"name": "Jim",
"birthplace": "Paris",
"father": {
"$ref": "/0"
}
}
]
</pre>
 
In the following, we extend jq's support for array paths to JSON pointers, and
add functionality for dereferencing "$ref" values, whether expressed as
array paths or JSON Pointer values.
 
Thus we will be able to write expressions such as:
<pre>
deref([1, "father"])
deref( "/1/father" )
</pre>
to retrieve the details concerning Jim's father.
 
We shall also ensure that deref can be used with jq's native query capabilities:
<pre>
deref( .[1]["father"] )
deref( .[1] | .father )
</pre>
 
'''Library'''
<syntaxhighlight lang=jq>
# Convert a jq array path to a JSON Pointer
def jsonpointer:
def encode: gsub("~"; "~0") | gsub("/"; "~1");
reduce .[] as $x
("";
if ($x|type) == "string" then "\(.)/\($x|encode)"
else . + "/\($x)" end );
 
# Is the input syntactically a jq array path?
def isarraypath:
type == "array" and
all(.[]; type == "string" or (type == "number" and floor == .));
 
# The JSON Pointer spec allows 0 both for indexing an array and for retrieving a key named "0".
# disambiguate($k) accordingly disambiguates $k w.r.t. `.`.
# $k should be a string or integer.
# If $k is a string and . is an object then: if has($k) then $k else null end.
# If $k is an integer and . is an array, then emit $k.
# If $k is an integer-valued string and . is an array then exit $k|tonumber.
# Otherwise emit null
def disambiguate( $k ):
if ($k|type) == "string"
then if type == "object" then $k
elif type == "array" and ($k|test("^[0-9]+$"))
then ($k|tonumber)
else null
end
elif ($k|type) == "number" and type == "array"
then $k
else null
end;
 
# $array should be an array of strings and integers.
# Emit the disambiguated array, suitable for running getpath/1.
# Emit null if disambiguation fails at any point.
def disambiguatePath($array):
. as $in
| reduce $array[] as $x ([];
if . then . as $path
| ($in | getpath($path) | disambiguate($x)) as $y
| if $y then . + [ $y ]
else null
end
else .
end);
 
# getjsonpointer() is like getpath() but for jsonpointer pointers
def getjsonpointer($pointer):
if $pointer == "" then . # special case
else
# first decode ~1, then ~0
($pointer | split("/") | .[1:]
| map(gsub("~1"; "/") | gsub("~0"; "~"))) as $array
| disambiguatePath($array) as $apath
| if $apath then getpath($apath) else null end
end;
 
# like getpath() but allow $p to be a jsonpointer or an array
def getpointer($p):
if ($p|type) == "string" then getjsonpointer($p)
elif ($p|isarraypath) then getpath($p)
else $p
end;
# dereference $pointer, but not recursively.
# $pointer can be a jsonpointer pointer, or a jq array path,
# but one can also call deref(query) where `query` is a jq query yielding a $ref object.
def deref($pointer):
def resolve($x):
if ($x | type) == "object"
then $x["$ref"] as $ref
| if $ref then getpointer($ref)
else $x
end
else $x
end;
 
if ($pointer|type) == "string"
then resolve(getpointer($pointer))
elif ($pointer|isarraypath)
then resolve(getpath($pointer))
else resolve($pointer)
end;
</syntaxhighlight>
'''Examples'''
These examples correspond to the John/Jim JSON document shown above.
In each case, the result would be "John".
<pre>
getpointer("/0/name") # JSON Pointer
 
getpointer([0, "name"] ) # array path
 
deref("/1/father").name # JSON Pointer
 
deref([1,"father"] ).name # array path
 
deref(.[1]["father"] ).name # jq query
 
deref(.[1] | .father).name # jq query
 
deref(.[] | select(.name == "Jim").father ).name # jq query
</pre>
 
=={{header|Julia}}==
Line 2,007 ⟶ 2,203:
 
The following example illustrates the difference by passing both value and reference type parameters to a function. Note that in Wren parameters are always passed by value.
<syntaxhighlight lang="ecmascriptwren">// This function takes a string (behaves like a value type) and a list (reference type).
// The value and the reference are copied to their respective parameters.
var f = Fn.new { |s, l|
162

edits