Compound data type: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) |
Thundergnat (talk | contribs) m (syntax ighlighting fixup automation) |
||
Line 18: | Line 18: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
< |
<syntaxhighlight lang="11l">T Point |
||
Int x, y |
Int x, y |
||
F (x, y) |
F (x, y) |
||
.x = x |
.x = x |
||
.y = y</ |
.y = y</syntaxhighlight> |
||
=={{header|ACL2}}== |
=={{header|ACL2}}== |
||
< |
<syntaxhighlight lang="lisp">(defstructure point |
||
(x (:assert (rationalp x))) |
(x (:assert (rationalp x))) |
||
(y (:assert (rationalp y)))) |
(y (:assert (rationalp y)))) |
||
Line 34: | Line 34: | ||
(assign p1 (update-point (@ p1) :x 3)) ; Update the x value |
(assign p1 (update-point (@ p1) :x 3)) ; Update the x value |
||
(point-x (@ p1)) |
(point-x (@ p1)) |
||
(point-p (@ p1)) ; Recognizer for points</ |
(point-p (@ p1)) ; Recognizer for points</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 47: | Line 47: | ||
NESASM3 syntax: |
NESASM3 syntax: |
||
< |
<syntaxhighlight lang="6502asm">MAX_POINT_OBJECTS = 64 ; define a constant |
||
.rsset $0400 ; reserve memory storage starting at address $0400 |
.rsset $0400 ; reserve memory storage starting at address $0400 |
||
point_x .rs MAX_POINT_OBJECTS ; reserve 64 bytes for x-coordinates |
point_x .rs MAX_POINT_OBJECTS ; reserve 64 bytes for x-coordinates |
||
point_y .rs MAX_POINT_OBJECTS ; reserve 64 bytes for y-coordinates</ |
point_y .rs MAX_POINT_OBJECTS ; reserve 64 bytes for y-coordinates</syntaxhighlight> |
||
VASM syntax: |
VASM syntax: |
||
< |
<syntaxhighlight lang="6502asm">MAX_POINT_OBJECTS equ 64 |
||
point_ram equ $0400 |
point_ram equ $0400 |
||
point_x equ point_ram |
point_x equ point_ram |
||
point_y equ point_ram+MAX_POINT_OBJECTS</ |
point_y equ point_ram+MAX_POINT_OBJECTS</syntaxhighlight> |
||
So, for example, let's say we want to load our third (zero-indexed) point variable and copy it to zero page RAM addresses $00 and $01. We would do the following: |
So, for example, let's say we want to load our third (zero-indexed) point variable and copy it to zero page RAM addresses $00 and $01. We would do the following: |
||
< |
<syntaxhighlight lang="6502asm">MAX_POINT_OBJECTS equ 64 |
||
point_ram equ $0400 |
point_ram equ $0400 |
||
Line 71: | Line 71: | ||
STA $00 |
STA $00 |
||
LDA point_y,x |
LDA point_y,x |
||
STA $01</ |
STA $01</syntaxhighlight> |
||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
{{libheader|Action! Tool Kit}} |
{{libheader|Action! Tool Kit}} |
||
< |
<syntaxhighlight lang="action!">INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit |
||
DEFINE REALPTR="CARD" |
DEFINE REALPTR="CARD" |
||
Line 101: | Line 101: | ||
PrintR(p2.rx) Print(",") |
PrintR(p2.rx) Print(",") |
||
PrintR(p2.ry) Print(")") |
PrintR(p2.ry) Print(")") |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Compound_data_type.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Compound_data_type.png Screenshot from Atari 8-bit computer] |
||
Line 110: | Line 110: | ||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
< |
<syntaxhighlight lang="actionscript">package |
||
{ |
{ |
||
public class Point |
public class Point |
||
Line 123: | Line 123: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
===Tagged Type=== |
===Tagged Type=== |
||
Ada tagged types are extensible through inheritance. The reserved word ''tagged'' causes the compiler to create a tag for the type. The tag identifies the position of the type in an inheritance hierarchy. |
Ada tagged types are extensible through inheritance. The reserved word ''tagged'' causes the compiler to create a tag for the type. The tag identifies the position of the type in an inheritance hierarchy. |
||
< |
<syntaxhighlight lang="ada">type Point is tagged record |
||
X : Integer := 0; |
X : Integer := 0; |
||
Y : Integer := 0; |
Y : Integer := 0; |
||
end record;</ |
end record;</syntaxhighlight> |
||
===Record Type=== |
===Record Type=== |
||
Ada record types are not extensible through inheritance. Without the reserved word ''tagged'' the record does not belong to an inheritance hierarchy. |
Ada record types are not extensible through inheritance. Without the reserved word ''tagged'' the record does not belong to an inheritance hierarchy. |
||
< |
<syntaxhighlight lang="ada">type Point is record |
||
X : Integer := 0; |
X : Integer := 0; |
||
Y : Integer := 0; |
Y : Integer := 0; |
||
end record;</ |
end record;</syntaxhighlight> |
||
====Parameterized Types==== |
====Parameterized Types==== |
||
An Ada record type can contain a discriminant. The discriminant is used to choose between internal structural representations. Parameterized types were introduced to Ada before tagged types. Inheritance is generally a cleaner solution to multiple representations than is a parameterized type. |
An Ada record type can contain a discriminant. The discriminant is used to choose between internal structural representations. Parameterized types were introduced to Ada before tagged types. Inheritance is generally a cleaner solution to multiple representations than is a parameterized type. |
||
< |
<syntaxhighlight lang="ada">type Person (Gender : Gender_Type) is record |
||
Name : Name_String; |
Name : Name_String; |
||
Age : Natural; |
Age : Natural; |
||
Line 152: | Line 152: | ||
null; |
null; |
||
end case; |
end case; |
||
end record;</ |
end record;</syntaxhighlight> |
||
In this case every person will have the attributes of gender, name, age, and weight. A person with a male gender will also have a beard length. |
In this case every person will have the attributes of gender, name, age, and weight. A person with a male gender will also have a beard length. |
||
Line 158: | Line 158: | ||
===Tagged Type=== |
===Tagged Type=== |
||
ALGOL 68 has only tagged-union/discriminants. And the tagging was strictly done by the ''type'' (MODE) of the members. |
ALGOL 68 has only tagged-union/discriminants. And the tagging was strictly done by the ''type'' (MODE) of the members. |
||
< |
<syntaxhighlight lang="algol68">MODE UNIONX = UNION( |
||
STRUCT(REAL r, INT i), |
STRUCT(REAL r, INT i), |
||
INT, |
INT, |
||
Line 165: | Line 165: | ||
STRUCT(REAL rr), |
STRUCT(REAL rr), |
||
STRUCT([]REAL r) |
STRUCT([]REAL r) |
||
);</ |
);</syntaxhighlight> |
||
To extract the apropriate member of a UNION a '''conformity-clause''' has to be used. |
To extract the apropriate member of a UNION a '''conformity-clause''' has to be used. |
||
< |
<syntaxhighlight lang="algol68">UNIONX data := 6.6; |
||
CASE data IN |
CASE data IN |
||
(INT i): printf(($"r: "gl$,i)), |
(INT i): printf(($"r: "gl$,i)), |
||
Line 175: | Line 175: | ||
OUT |
OUT |
||
printf($"Other cases"l$) |
printf($"Other cases"l$) |
||
ESAC;</ |
ESAC;</syntaxhighlight> |
||
The '''conformity-clause''' does mean that ALGOL 68 avoids the need for |
The '''conformity-clause''' does mean that ALGOL 68 avoids the need for |
||
[[duck typing]], but it also makes the tagged-union kinda tough to use, |
[[duck typing]], but it also makes the tagged-union kinda tough to use, |
||
Line 182: | Line 182: | ||
ALGOL 68 record types are not extensible through inheritance but they |
ALGOL 68 record types are not extensible through inheritance but they |
||
may be part of a larger STRUCT composition. |
may be part of a larger STRUCT composition. |
||
< |
<syntaxhighlight lang="algol68">MODE POINT = STRUCT( |
||
INT x, |
INT x, |
||
INT y |
INT y |
||
);</ |
);</syntaxhighlight> |
||
====Parameterized Types==== |
====Parameterized Types==== |
||
An ALGOL 68 record type can contain a tagged-union/discriminant. The |
An ALGOL 68 record type can contain a tagged-union/discriminant. The |
||
tagged-union/discriminant is used to choose between internal structural |
tagged-union/discriminant is used to choose between internal structural |
||
representations. |
representations. |
||
< |
<syntaxhighlight lang="algol68">MODE PERSON = STRUCT( |
||
STRING name, |
STRING name, |
||
REAL age, |
REAL age, |
||
Line 198: | Line 198: | ||
VOID |
VOID |
||
) gender details |
) gender details |
||
);</ |
);</syntaxhighlight> |
||
In this case every PERSON will have the attributes of gender details, name, age, |
In this case every PERSON will have the attributes of gender details, name, age, |
||
and weight. A PERSON may or may not have a beard. The sex is implied by the tagging. |
and weight. A PERSON may or may not have a beard. The sex is implied by the tagging. |
||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
< |
<syntaxhighlight lang="algolw">begin |
||
% create the compound data type % |
% create the compound data type % |
||
record Point( real x, y ); |
record Point( real x, y ); |
||
Line 212: | Line 212: | ||
% access the fields of p - note Algol W uses x(p) where many languages would use p.x % |
% access the fields of p - note Algol W uses x(p) where many languages would use p.x % |
||
write( x(p), y(p) ) |
write( x(p), y(p) ) |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|AmigaE}}== |
=={{header|AmigaE}}== |
||
< |
<syntaxhighlight lang="amigae">OBJECT point |
||
x, y |
x, y |
||
ENDOBJECT |
ENDOBJECT |
||
Line 228: | Line 228: | ||
pt.y := !3.14 |
pt.y := !3.14 |
||
END pt |
END pt |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
=={{header|ARM Assembly}}== |
=={{header|ARM Assembly}}== |
||
{{works with|as|Raspberry Pi}} |
{{works with|as|Raspberry Pi}} |
||
<syntaxhighlight lang="arm assembly"> |
|||
<lang ARM Assembly> |
|||
/* ARM assembly Raspberry PI */ |
/* ARM assembly Raspberry PI */ |
||
Line 375: | Line 375: | ||
iMagicNumber: .int 0xCCCCCCCD |
iMagicNumber: .int 0xCCCCCCCD |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang="arturo">point: #[ |
||
x: 10 |
x: 10 |
||
y: 20 |
y: 20 |
||
] |
] |
||
print point</ |
print point</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 394: | Line 394: | ||
There are numerous ways to do this. The simplest is to use an "unboxed" tuple type: |
There are numerous ways to do this. The simplest is to use an "unboxed" tuple type: |
||
< |
<syntaxhighlight lang="ats">typedef point (t : t@ype+) = @(t, t) |
||
val p : point double = (1.0, 3.0)</ |
val p : point double = (1.0, 3.0)</syntaxhighlight> |
||
If one insists both that the type be unique (as opposed to an alias for a tuple) and that the notation to create a point be '''Point (x, y)''', then the following works: |
If one insists both that the type be unique (as opposed to an alias for a tuple) and that the notation to create a point be '''Point (x, y)''', then the following works: |
||
< |
<syntaxhighlight lang="ats">datatype point (t : t@ype+) = |
||
| Point of (t, t) |
| Point of (t, t) |
||
val p : point double = Point (1.0, 3.0)</ |
val p : point double = Point (1.0, 3.0)</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Line 406: | Line 406: | ||
[[wp:Monkey_patch|monkeypatched]] example. |
[[wp:Monkey_patch|monkeypatched]] example. |
||
< |
<syntaxhighlight lang="autohotkey">point := Object() |
||
point.x := 1 |
point.x := 1 |
||
point.y := 0 |
point.y := 0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
As usual, arrays are the only data type more complex than a number or a string.<br> |
As usual, arrays are the only data type more complex than a number or a string.<br> |
||
Use quotes around constant strings as element selectors: |
Use quotes around constant strings as element selectors: |
||
< |
<syntaxhighlight lang="awk">BEGIN { |
||
p["x"]=10 |
p["x"]=10 |
||
p["y"]=42 |
p["y"]=42 |
||
Line 424: | Line 424: | ||
for (i in p) print( i, ":", p[i] ) |
for (i in p) print( i, ":", p[i] ) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 434: | Line 434: | ||
=={{header|Axe}}== |
=={{header|Axe}}== |
||
Axe does not have language support for custom data structures. However, they can be implemented from scratch using memory directly. |
Axe does not have language support for custom data structures. However, they can be implemented from scratch using memory directly. |
||
< |
<syntaxhighlight lang="axe">Lbl POINT |
||
r₂→{r₁}ʳ |
r₂→{r₁}ʳ |
||
r₃→{r₁+2}ʳ |
r₃→{r₁+2}ʳ |
||
r₁ |
r₁ |
||
Return</ |
Return</syntaxhighlight> |
||
To initialize a POINT at memory address L₁ with (x, y) = (5, 10): |
To initialize a POINT at memory address L₁ with (x, y) = (5, 10): |
||
<lang |
<syntaxhighlight lang="axe">POINT(L₁,5,10)</syntaxhighlight> |
||
The caller must ensure the buffer has enough free space to contain the object (in this case, 4 bytes). |
The caller must ensure the buffer has enough free space to contain the object (in this case, 4 bytes). |
||
Line 449: | Line 449: | ||
{{works with|PowerBASIC}} |
{{works with|PowerBASIC}} |
||
< |
<syntaxhighlight lang="qb">TYPE Point |
||
x AS INTEGER |
x AS INTEGER |
||
y AS INTEGER |
y AS INTEGER |
||
END TYPE</ |
END TYPE</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> DIM Point{x%, y%}</syntaxhighlight> |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
Line 463: | Line 463: | ||
So we go object oriented and create a 'type' Point. We show that <code>x</code> and <code>y</code> are independent by changing the value of <code>x</code> and checking that <code>y</code> didn't change. |
So we go object oriented and create a 'type' Point. We show that <code>x</code> and <code>y</code> are independent by changing the value of <code>x</code> and checking that <code>y</code> didn't change. |
||
Bracmat does not have other typing systems than duck typing. The variable <code>Point</code> is not a class, but an object in its own right. The <code>new$</code> function creates a copy of <code>Point</code>. |
Bracmat does not have other typing systems than duck typing. The variable <code>Point</code> is not a class, but an object in its own right. The <code>new$</code> function creates a copy of <code>Point</code>. |
||
< |
<syntaxhighlight lang="bracmat">( ( Point |
||
= (x=) |
= (x=) |
||
(y=) |
(y=) |
||
Line 473: | Line 473: | ||
& 7:?(pt..x) |
& 7:?(pt..x) |
||
& out$(!(pt..x) !(pt..y)) |
& out$(!(pt..x) !(pt..y)) |
||
);</ |
);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>3 4 |
<pre>3 4 |
||
Line 486: | Line 486: | ||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">typedef struct Point |
||
{ |
{ |
||
int x; |
int x; |
||
int y; |
int y; |
||
} Point;</ |
} Point;</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">struct Point |
||
{ |
{ |
||
public int x, y; |
public int x, y; |
||
Line 501: | Line 501: | ||
this.y = y; |
this.y = y; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">struct Point |
||
{ |
{ |
||
int x; |
int x; |
||
int y; |
int y; |
||
};</ |
};</syntaxhighlight> |
||
It is also possible to add a constructor (this allows the use of <tt>Point(x, y)</tt> in expressions): |
It is also possible to add a constructor (this allows the use of <tt>Point(x, y)</tt> in expressions): |
||
< |
<syntaxhighlight lang="cpp">struct Point |
||
{ |
{ |
||
int x; |
int x; |
||
int y; |
int y; |
||
Point(int ax, int ay): x(ax), y(ax) {} |
Point(int ax, int ay): x(ax), y(ax) {} |
||
};</ |
};</syntaxhighlight> |
||
Point can also be parametrized on the coordinate type: |
Point can also be parametrized on the coordinate type: |
||
< |
<syntaxhighlight lang="cpp">template<typename Coordinate> struct point |
||
{ |
{ |
||
Coordinate x, y; |
Coordinate x, y; |
||
Line 528: | Line 528: | ||
// a point with floating point coordinates |
// a point with floating point coordinates |
||
Point<float> point2 = { 1.7, 3.6 };</ |
Point<float> point2 = { 1.7, 3.6 };</syntaxhighlight> |
||
Of course, a constructor can be added in this case as well. |
Of course, a constructor can be added in this case as well. |
||
=={{header|Clean}}== |
=={{header|Clean}}== |
||
===Record type=== |
===Record type=== |
||
< |
<syntaxhighlight lang="clean">:: Point = { x :: Int, y :: Int }</syntaxhighlight> |
||
===Parameterized Algebraic type=== |
===Parameterized Algebraic type=== |
||
< |
<syntaxhighlight lang="clean">:: Point a = Point a a // usage: (Point Int)</syntaxhighlight> |
||
===Synonym type=== |
===Synonym type=== |
||
< |
<syntaxhighlight lang="clean">:: Point :== (Int, Int)</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure">(defrecord Point [x y])</syntaxhighlight> |
||
This defines a datatype with constructor ''Point.'' and accessors '':x'' and '':y'' : |
This defines a datatype with constructor ''Point.'' and accessors '':x'' and '':y'' : |
||
< |
<syntaxhighlight lang="clojure">(def p (Point. 0 1)) |
||
(assert (= 0 (:x p))) |
(assert (= 0 (:x p))) |
||
(assert (= 1 (:y p)))</ |
(assert (= 1 (:y p)))</syntaxhighlight> |
||
=={{header|CLU}}== |
=={{header|CLU}}== |
||
Line 550: | Line 550: | ||
Aside from this, they work the same way. |
Aside from this, they work the same way. |
||
< |
<syntaxhighlight lang="clu">% Definitions |
||
point = struct[x, y: int] |
point = struct[x, y: int] |
||
mutable_point = record[x, y: int] |
mutable_point = record[x, y: int] |
||
Line 556: | Line 556: | ||
% Initialization |
% Initialization |
||
p: point := point${x: 10, y: 20} |
p: point := point${x: 10, y: 20} |
||
mp: mutable_point := mutable_point${x: 10, y: 20}</ |
mp: mutable_point := mutable_point${x: 10, y: 20}</syntaxhighlight> |
||
The fields can be accessed using the <code>.</code> syntax: |
The fields can be accessed using the <code>.</code> syntax: |
||
< |
<syntaxhighlight lang="clu">foo := p.x |
||
bar := p.y</ |
bar := p.y</syntaxhighlight> |
||
''Record''s, but not ''struct''s, allow updating the fields in the same way. |
''Record''s, but not ''struct''s, allow updating the fields in the same way. |
||
< |
<syntaxhighlight lang="clu">mp.x := 30 |
||
mp.y := 40</ |
mp.y := 40</syntaxhighlight> |
||
It should be noted that the special forms <code>p.x</code> and <code>mp.x := value</code> |
It should be noted that the special forms <code>p.x</code> and <code>mp.x := value</code> |
||
are really only syntactic sugar, they are equivalent to the following method calls: |
are really only syntactic sugar, they are equivalent to the following method calls: |
||
< |
<syntaxhighlight lang="clu">foo := point$get_x(p) |
||
bar := point$get_y(p)</ |
bar := point$get_y(p)</syntaxhighlight> |
||
< |
<syntaxhighlight lang="clu">mutable_point$set_x(mp, 30) |
||
mutable_point$set_y(mp, 40)</ |
mutable_point$set_y(mp, 40)</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
< |
<syntaxhighlight lang="cobol"> |
||
01 Point. |
01 Point. |
||
05 x pic 9(3). |
05 x pic 9(3). |
||
05 y pic 9(3). |
05 y pic 9(3). |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
# Lightweight JS objects (with CS sugar). |
# Lightweight JS objects (with CS sugar). |
||
point = |
point = |
||
Line 603: | Line 603: | ||
console.log p1.distance_from # [Function] |
console.log p1.distance_from # [Function] |
||
console.log p1.distance_from p2 # 13 |
console.log p1.distance_from p2 # 13 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">CL-USER> (defstruct point (x 0) (y 0)) ;If not provided, x or y default to 0 |
||
POINT</ |
POINT</syntaxhighlight> |
||
In addition to defining the ''point'' data type, the defstruct macro also created constructor and accessor functions: |
In addition to defining the ''point'' data type, the defstruct macro also created constructor and accessor functions: |
||
< |
<syntaxhighlight lang="lisp">CL-USER> (setf a (make-point)) ;The default constructor using the default values for x and y |
||
#S(POINT :X 0 :Y 0) |
#S(POINT :X 0 :Y 0) |
||
CL-USER> (setf b (make-point :x 5.5 :y #C(0 1))) ;Dynamic datatypes are the default |
CL-USER> (setf b (make-point :x 5.5 :y #C(0 1))) ;Dynamic datatypes are the default |
||
Line 621: | Line 621: | ||
3 |
3 |
||
CL-USER> (point-y b) |
CL-USER> (point-y b) |
||
3</ |
3</syntaxhighlight> |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
Crystal's structs work very similarly to objects, but are allocated on the stack instead of the heap, and passed by value instead of by reference. More potential caveats are noted in the [https://crystal-lang.org/reference/syntax_and_semantics/structs.html language reference]. |
Crystal's structs work very similarly to objects, but are allocated on the stack instead of the heap, and passed by value instead of by reference. More potential caveats are noted in the [https://crystal-lang.org/reference/syntax_and_semantics/structs.html language reference]. |
||
< |
<syntaxhighlight lang="ruby">struct Point(T) |
||
getter x : T |
getter x : T |
||
getter y : T |
getter y : T |
||
Line 633: | Line 633: | ||
end |
end |
||
puts Point(Int32).new 13, 12 #=> Point(Int32)(@x=13, @y=12)</ |
puts Point(Int32).new 13, 12 #=> Point(Int32)(@x=13, @y=12)</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">void main() { |
||
// A normal POD struct |
// A normal POD struct |
||
// (if it's nested and it's not static then it has a hidden |
// (if it's nested and it's not static then it has a hidden |
||
Line 682: | Line 682: | ||
static assert(is(p6[0] == int)); |
static assert(is(p6[0] == int)); |
||
static assert(p6[1] == 5); |
static assert(p6[1] == 5); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
As defined in Types.pas: |
As defined in Types.pas: |
||
< |
<syntaxhighlight lang="delphi"> TPoint = record |
||
X: Longint; |
X: Longint; |
||
Y: Longint; |
Y: Longint; |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Diego}}== |
=={{header|Diego}}== |
||
< |
<syntaxhighlight lang="diego">use_namespace(rosettacode)_me(); |
||
add_struct(point)_arg(x,y); |
add_struct(point)_arg(x,y); |
||
Line 703: | Line 703: | ||
with_point(point2)_arg(0.033,👣); |
with_point(point2)_arg(0.033,👣); |
||
reset_namespace[];</ |
reset_namespace[];</syntaxhighlight> |
||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">def makePoint(x, y) { |
||
def point { |
def point { |
||
to getX() { return x } |
to getX() { return x } |
||
Line 713: | Line 713: | ||
} |
} |
||
return point |
return point |
||
}</ |
}</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(lib 'struct) |
(lib 'struct) |
||
(struct Point (x y)) |
(struct Point (x y)) |
||
Line 729: | Line 729: | ||
(Point 3 'albert) |
(Point 3 'albert) |
||
❌ error: #number? : type-check failure : albert → 'Point:y' |
❌ error: #number? : type-check failure : albert → 'Point:y' |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ela}}== |
=={{header|Ela}}== |
||
Line 735: | Line 735: | ||
Ela supports algebraic types: |
Ela supports algebraic types: |
||
< |
<syntaxhighlight lang="ela">type Maybe = None | Some a</syntaxhighlight> |
||
Except of regular algebraic types, Ela also provides a support for open algebraic types - which can be extended any time with new constructors: |
Except of regular algebraic types, Ela also provides a support for open algebraic types - which can be extended any time with new constructors: |
||
< |
<syntaxhighlight lang="ela">opentype Several = One | Two | Three |
||
//Add new constructor to an existing type |
//Add new constructor to an existing type |
||
data Several = Four</ |
data Several = Four</syntaxhighlight> |
||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
< |
<syntaxhighlight lang="elena">struct Point |
||
{ |
{ |
||
prop int X; |
prop int X; |
||
Line 756: | Line 756: | ||
Y := y |
Y := y |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
< |
<syntaxhighlight lang="elixir">iex(1)> defmodule Point do |
||
...(1)> defstruct x: 0, y: 0 |
...(1)> defstruct x: 0, y: 0 |
||
...(1)> end |
...(1)> end |
||
Line 776: | Line 776: | ||
10 |
10 |
||
iex(8)> py |
iex(8)> py |
||
20</ |
20</syntaxhighlight> |
||
=={{header|Elm}}== |
=={{header|Elm}}== |
||
< |
<syntaxhighlight lang="elm"> |
||
--Compound Data type can hold multiple independent values |
--Compound Data type can hold multiple independent values |
||
--In Elm data can be compounded using List, Tuple, Record |
--In Elm data can be compounded using List, Tuple, Record |
||
Line 807: | Line 807: | ||
--Each time a new record is generated |
--Each time a new record is generated |
||
--END |
--END |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang"> |
||
-module(records_test). |
-module(records_test). |
||
-compile(export_all). |
-compile(export_all). |
||
Line 821: | Line 821: | ||
P2 = P1#point{x=3.0}, % creates a new point record with x set to 3.0, y is copied from P1 |
P2 = P1#point{x=3.0}, % creates a new point record with x set to 3.0, y is copied from P1 |
||
io:fwrite("X: ~f, Y: ~f~n",[P2#point.x,P2#point.y]). |
io:fwrite("X: ~f, Y: ~f~n",[P2#point.x,P2#point.y]). |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Euphoria}}== |
=={{header|Euphoria}}== |
||
{{works with|OpenEuphoria}} |
{{works with|OpenEuphoria}} |
||
< |
<syntaxhighlight lang="euphoria"> |
||
enum x, y |
enum x, y |
||
Line 837: | Line 837: | ||
printf(1,"x = %d, y = %3.3f\n",point) |
printf(1,"x = %d, y = %3.3f\n",point) |
||
printf(1,"x = %s, y = %3.3f\n",point) |
printf(1,"x = %s, y = %3.3f\n",point) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 847: | Line 847: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
See the OCaml section as well. Here we create a list of points and print them out. |
See the OCaml section as well. Here we create a list of points and print them out. |
||
< |
<syntaxhighlight lang="fsharp">type Point = { x : int; y : int } |
||
let points = [ |
let points = [ |
||
Line 853: | Line 853: | ||
{x = 5; y = 5} ] |
{x = 5; y = 5} ] |
||
Seq.iter (fun p -> printfn "%d,%d" p.x p.y) points</ |
Seq.iter (fun p -> printfn "%d,%d" p.x p.y) points</syntaxhighlight> |
||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
<lang |
<syntaxhighlight lang="factor">TUPLE: point x y ;</syntaxhighlight> |
||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
< |
<syntaxhighlight lang="fantom"> |
||
// define a class to contain the two fields |
// define a class to contain the two fields |
||
// accessors to get/set the field values are automatically generated |
// accessors to get/set the field values are automatically generated |
||
Line 881: | Line 881: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 892: | Line 892: | ||
There is no standard structure syntax in Forth, but it is easy to define words for creating and accessing data structures. |
There is no standard structure syntax in Forth, but it is easy to define words for creating and accessing data structures. |
||
< |
<syntaxhighlight lang="forth">: pt>x ( point -- x ) ; |
||
: pt>y ( point -- y ) CELL+ ; |
: pt>y ( point -- y ) CELL+ ; |
||
: .pt ( point -- ) dup pt>x @ . pt>y @ . ; \ or for this simple structure, 2@ . . |
: .pt ( point -- ) dup pt>x @ . pt>y @ . ; \ or for this simple structure, 2@ . . |
||
Line 898: | Line 898: | ||
create point 6 , 0 , |
create point 6 , 0 , |
||
7 point pt>y ! |
7 point pt>y ! |
||
.pt \ 6 7</ |
.pt \ 6 7</syntaxhighlight> |
||
{{works with|GNU Forth|0.6.2}} |
{{works with|GNU Forth|0.6.2}} |
||
Some Forths have mechanisms for declaring complex structures. For example, GNU Forth uses this syntax: |
Some Forths have mechanisms for declaring complex structures. For example, GNU Forth uses this syntax: |
||
< |
<syntaxhighlight lang="forth">struct |
||
cell% field pt>x |
cell% field pt>x |
||
cell% field pt>y |
cell% field pt>y |
||
end-struct point%</ |
end-struct point%</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
In ISO Fortran 90 or later, use a TYPE declaration, "constructor" syntax, and field delimiter syntax: |
In ISO Fortran 90 or later, use a TYPE declaration, "constructor" syntax, and field delimiter syntax: |
||
< |
<syntaxhighlight lang="fortran">program typedemo |
||
type rational ! Type declaration |
type rational ! Type declaration |
||
integer :: numerator |
integer :: numerator |
||
Line 931: | Line 931: | ||
oon_denoms = one_over_n%denominator ! Access denominator field in every |
oon_denoms = one_over_n%denominator ! Access denominator field in every |
||
! rational array element & store |
! rational array element & store |
||
end program typedemo ! as integer array</ |
end program typedemo ! as integer array</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
||
Type Point |
Type Point |
||
Line 944: | Line 944: | ||
Print p.x, p.y |
Print p.x, p.y |
||
Print p2.x, p2.y |
Print p2.x, p2.y |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 953: | Line 953: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">type point struct { |
||
x, y float64 |
x, y float64 |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
===Declaration=== |
===Declaration=== |
||
< |
<syntaxhighlight lang="groovy">class Point { |
||
int x |
int x |
||
int y |
int y |
||
Line 968: | Line 968: | ||
Point(int x = 0, int y = 0) { this.x = x; this.y = y } |
Point(int x = 0, int y = 0) { this.x = x; this.y = y } |
||
String toString() { "{x:${x}, y:${y}}" } |
String toString() { "{x:${x}, y:${y}}" } |
||
}</ |
}</syntaxhighlight> |
||
===Instantiation=== |
===Instantiation=== |
||
=====Direct===== |
=====Direct===== |
||
< |
<syntaxhighlight lang="groovy">// Default Construction with explicit property setting: |
||
def p0 = new Point() |
def p0 = new Point() |
||
assert 0 == p0.x |
assert 0 == p0.x |
||
Line 988: | Line 988: | ||
def p2 = new Point(36) |
def p2 = new Point(36) |
||
assert 36 == p2.x |
assert 36 == p2.x |
||
assert 0 == p2.y</ |
assert 0 == p2.y</syntaxhighlight> |
||
=====List-to-argument Substitution===== |
=====List-to-argument Substitution===== |
||
There are several ways that a List can be substituted for constructor arguments via "type coercion" (casting). |
There are several ways that a List can be substituted for constructor arguments via "type coercion" (casting). |
||
< |
<syntaxhighlight lang="groovy">// Explicit coersion from list with "as" keyword |
||
def p4 = [36, -2] as Point |
def p4 = [36, -2] as Point |
||
assert 36 == p4.x |
assert 36 == p4.x |
||
Line 1,010: | Line 1,010: | ||
Point p8 = [36] |
Point p8 = [36] |
||
assert 36 == p8.x |
assert 36 == p8.x |
||
assert 0 == p8.y</ |
assert 0 == p8.y</syntaxhighlight> |
||
=====Map-to-property Substitution===== |
=====Map-to-property Substitution===== |
||
There are several ways to construct an object using a map (or a comma-separated list of map entries) that substitutes entries for class properties. The process is properly (A) instantiation, followed by (B) property mapping. Because the instantiation is not tied to the mapping, it requires the existence of a no-argument constructor. |
There are several ways to construct an object using a map (or a comma-separated list of map entries) that substitutes entries for class properties. The process is properly (A) instantiation, followed by (B) property mapping. Because the instantiation is not tied to the mapping, it requires the existence of a no-argument constructor. |
||
< |
<syntaxhighlight lang="groovy">// Direct map-based construction |
||
def p3 = new Point([x: 36, y: -2]) |
def p3 = new Point([x: 36, y: -2]) |
||
assert 36 == p3.x |
assert 36 == p3.x |
||
Line 1,044: | Line 1,044: | ||
Point p9 = [y:-2] |
Point p9 = [y:-2] |
||
assert 0 == p9.x |
assert 0 == p9.x |
||
assert -2 == p9.y</ |
assert -2 == p9.y</syntaxhighlight> |
||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Line 1,084: | Line 1,084: | ||
You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first: |
You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first: |
||
< |
<syntaxhighlight lang="haskell">p = (2,3)</syntaxhighlight> |
||
The type of <code>p</code> is <code>(Int, Int)</code>, using the same comma-delimited list syntax as the literal. |
The type of <code>p</code> is <code>(Int, Int)</code>, using the same comma-delimited list syntax as the literal. |
||
Line 1,099: | Line 1,099: | ||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
<lang |
<syntaxhighlight lang="icon">record Point(x,y)</syntaxhighlight> |
||
=={{header|IDL}}== |
=={{header|IDL}}== |
||
< |
<syntaxhighlight lang="idl">point = {x: 6 , y: 0 } |
||
point.y = 7 |
point.y = 7 |
||
print, point |
print, point |
||
;=> { 6 7}</ |
;=> { 6 7}</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,112: | Line 1,112: | ||
In a "real" J application, points would be represented by arrays of 2 (or N) numbers. None the less, sometimes objects (in the OO sense) are a better representation than arrays, so J supports them: |
In a "real" J application, points would be represented by arrays of 2 (or N) numbers. None the less, sometimes objects (in the OO sense) are a better representation than arrays, so J supports them: |
||
< |
<syntaxhighlight lang="j"> NB. Create a "Point" class |
||
coclass'Point' |
coclass'Point' |
||
Line 1,128: | Line 1,128: | ||
10 |
10 |
||
Y__P |
Y__P |
||
20</ |
20</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
We use a class: |
We use a class: |
||
< |
<syntaxhighlight lang="java">public class Point |
||
{ |
{ |
||
public int x, y; |
public int x, y; |
||
Line 1,145: | Line 1,145: | ||
System.out.println("y = " + point.y ); |
System.out.println("y = " + point.y ); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">//using object literal syntax |
||
var point = {x : 1, y : 2}; |
var point = {x : 1, y : 2}; |
||
Line 1,166: | Line 1,166: | ||
} |
} |
||
} |
} |
||
point = new Point(1, 2);</ |
point = new Point(1, 2);</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
< |
<syntaxhighlight lang="jq">{"x":1, "y":2}</syntaxhighlight> |
||
If the emphasis in the task description is on "type", then an alternative approach would be to include a "type" key, e.g. |
If the emphasis in the task description is on "type", then an alternative approach would be to include a "type" key, e.g. |
||
< |
<syntaxhighlight lang="jq">{"x":1, "y":2, type: "Point"}</syntaxhighlight> |
||
Using this approach, one can distinguish between objects of type "Point" and those that happen to have keys named "x" and "y". |
Using this approach, one can distinguish between objects of type "Point" and those that happen to have keys named "x" and "y". |
||
Line 1,178: | Line 1,178: | ||
=={{header|JSON}}== |
=={{header|JSON}}== |
||
< |
<syntaxhighlight lang="json">{"x":1,"y":2}</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
'''Define the type''': |
'''Define the type''': |
||
< |
<syntaxhighlight lang="julia">struct Point{T<:Real} |
||
x::T |
x::T |
||
y::T |
y::T |
||
end</ |
end</syntaxhighlight> |
||
The components of <code>Point</code> can be any sort of real number, though they do have to be of the same type. |
The components of <code>Point</code> can be any sort of real number, though they do have to be of the same type. |
||
'''Define a few simple operations for Point''': |
'''Define a few simple operations for Point''': |
||
< |
<syntaxhighlight lang="julia">Base.:(==)(u::Point, v::Point) = u.x == v.x && u.y == v.y |
||
Base.:-(u::Point) = Point(-u.x, -u.y) |
Base.:-(u::Point) = Point(-u.x, -u.y) |
||
Base.:+(u::Point, v::Point) = Point(u.x + v.x, u.y + v.y) |
Base.:+(u::Point, v::Point) = Point(u.x + v.x, u.y + v.y) |
||
Base.:-(u::Point, v::Point) = u + (-v)</ |
Base.:-(u::Point, v::Point) = u + (-v)</syntaxhighlight> |
||
'''Have fun''': |
'''Have fun''': |
||
< |
<syntaxhighlight lang="julia">a, b, c = Point(1, 2), Point(3, 7), Point(2, 4) |
||
@show a b c |
@show a b c |
||
@show a + b |
@show a + b |
||
Line 1,202: | Line 1,202: | ||
@show a + b + c |
@show a + b + c |
||
@show a == b |
@show a == b |
||
@show a + a == c</ |
@show a + a == c</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,216: | Line 1,216: | ||
=={{header|KonsolScript}}== |
=={{header|KonsolScript}}== |
||
< |
<syntaxhighlight lang="konsolscript">Var:Create( |
||
Point, |
Point, |
||
Number x, |
Number x, |
||
Number y |
Number y |
||
)</ |
)</syntaxhighlight> |
||
Instanciate it with... |
Instanciate it with... |
||
< |
<syntaxhighlight lang="konsolscript">function main() { |
||
Var:Point point; |
Var:Point point; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">data class Point(var x: Int, var y: Int) |
||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
Line 1,236: | Line 1,236: | ||
p.y = 4 |
p.y = 4 |
||
println(p) |
println(p) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,245: | Line 1,245: | ||
=={{header|Lambdatalk}}== |
=={{header|Lambdatalk}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
1) a pair |
1) a pair |
||
{def P {P.new 1 2}} |
{def P {P.new 1 2}} |
||
Line 1,269: | Line 1,269: | ||
{A.last {R}} |
{A.last {R}} |
||
-> 2 |
-> 2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
In Lasso, a point could just be stored in the pair type. However, assuming we want to be able to access the points using the member methods [Point->x] and [Point->y], let's just create a type that inherits from the pair type: |
In Lasso, a point could just be stored in the pair type. However, assuming we want to be able to access the points using the member methods [Point->x] and [Point->y], let's just create a type that inherits from the pair type: |
||
< |
<syntaxhighlight lang="lasso">define Point => type { |
||
parent pair |
parent pair |
||
Line 1,286: | Line 1,286: | ||
local(point) = Point(33, 42) |
local(point) = Point(33, 42) |
||
#point->x |
#point->x |
||
#point->y</ |
#point->y</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,296: | Line 1,296: | ||
Simply define a record in the LFE REPL (can also be used in include files, modules, etc.): |
Simply define a record in the LFE REPL (can also be used in include files, modules, etc.): |
||
< |
<syntaxhighlight lang="lisp"> |
||
(defrecord point |
(defrecord point |
||
x |
x |
||
y) |
y) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Creating points: |
Creating points: |
||
Line 1,342: | Line 1,342: | ||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Point and Vector types are built-in. A custom "MyPoint" type can be implemented like this: |
Point and Vector types are built-in. A custom "MyPoint" type can be implemented like this: |
||
< |
<syntaxhighlight lang="lingo">-- parent script "MyPoint" |
||
property x |
property x |
||
property y |
property y |
||
Line 1,349: | Line 1,349: | ||
me.y = py |
me.y = py |
||
return me |
return me |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="lingo">p = script("MyPoint").new(23, 42) |
||
put p.x, p.y |
put p.x, p.y |
||
-- 23 42</ |
-- 23 42</syntaxhighlight> |
||
Construction could also be simplified by using a global wrapper function: |
Construction could also be simplified by using a global wrapper function: |
||
< |
<syntaxhighlight lang="lingo">-- in some movie script |
||
on MyPoint (x, y) |
on MyPoint (x, y) |
||
return script("MyPoint").new(x, y) |
return script("MyPoint").new(x, y) |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="lingo">p = MyPoint(23, 42) |
||
put p.x, p.y |
put p.x, p.y |
||
-- 23 42</ |
-- 23 42</syntaxhighlight> |
||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
In Logo, a point is represented by a list of two numbers. For example, this will draw a triangle: |
In Logo, a point is represented by a list of two numbers. For example, this will draw a triangle: |
||
< |
<syntaxhighlight lang="logo">setpos [100 100] setpos [100 0] setpos [0 0] |
||
show pos ; [0 0]</ |
show pos ; [0 0]</syntaxhighlight> |
||
Access is via normal list operations like FIRST and BUTFIRST (BF). X is FIRST point, Y is LAST point. For example, a simple drawing program which exits if mouse X is negative: |
Access is via normal list operations like FIRST and BUTFIRST (BF). X is FIRST point, Y is LAST point. For example, a simple drawing program which exits if mouse X is negative: |
||
< |
<syntaxhighlight lang="logo">until [(first mousepos) < 0] [ifelse button? [pendown] [penup] setpos mousepos]</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Line 1,375: | Line 1,375: | ||
Lua could use a simple table to store a compound data type Point(x, y): |
Lua could use a simple table to store a compound data type Point(x, y): |
||
< |
<syntaxhighlight lang="lua"> |
||
a = {x = 1; y = 2} |
a = {x = 1; y = 2} |
||
b = {x = 3; y = 4} |
b = {x = 3; y = 4} |
||
Line 1,384: | Line 1,384: | ||
print(a.x, a.y) --> 1 2 |
print(a.x, a.y) --> 1 2 |
||
print(c.x, c.y) --> 4 6 |
print(c.x, c.y) --> 4 6 |
||
</syntaxhighlight> |
|||
</lang> |
|||
==== Prototype Object ==== |
==== Prototype Object ==== |
||
Furthermore, Lua could create a prototype object (OOP class emulation) to represent a compound data type Point(x, y) as the following: |
Furthermore, Lua could create a prototype object (OOP class emulation) to represent a compound data type Point(x, y) as the following: |
||
< |
<syntaxhighlight lang="lua"> |
||
cPoint = {} -- metatable (behaviour table) |
cPoint = {} -- metatable (behaviour table) |
||
function newPoint(x, y) -- constructor |
function newPoint(x, y) -- constructor |
||
Line 1,399: | Line 1,399: | ||
return setmetatable(pointPrototype, cPoint) -- set behaviour and return the pointPrototype |
return setmetatable(pointPrototype, cPoint) -- set behaviour and return the pointPrototype |
||
end--newPoint |
end--newPoint |
||
</syntaxhighlight> |
|||
</lang> |
|||
In the above example, the methods are declared inside the constructor so that they could access the closured values <code>x</code> and <code>y</code> (see usage example). The <code>pointPrototype:type</code> method could be used to extend the original <code>type</code> function available in Lua: |
In the above example, the methods are declared inside the constructor so that they could access the closured values <code>x</code> and <code>y</code> (see usage example). The <code>pointPrototype:type</code> method could be used to extend the original <code>type</code> function available in Lua: |
||
< |
<syntaxhighlight lang="lua"> |
||
local oldtype = type; -- store original type function |
local oldtype = type; -- store original type function |
||
function type(v) |
function type(v) |
||
Line 1,413: | Line 1,413: | ||
end--if vType=="table" |
end--if vType=="table" |
||
end--type |
end--type |
||
</syntaxhighlight> |
|||
</lang> |
|||
The usage of metatable <code>cPoint</code> which stores the behavior of the <code>pointPrototype</code> enables additional behaviour to be added to the data type, such as: |
The usage of metatable <code>cPoint</code> which stores the behavior of the <code>pointPrototype</code> enables additional behaviour to be added to the data type, such as: |
||
< |
<syntaxhighlight lang="lua"> |
||
function cPoint.__add(op1, op2) -- add the x and y components |
function cPoint.__add(op1, op2) -- add the x and y components |
||
if type(op1)=="point" and type(op2)=="point" then |
if type(op1)=="point" and type(op2)=="point" then |
||
Line 1,432: | Line 1,432: | ||
end--if type(op1) |
end--if type(op1) |
||
end--cPoint.__sub |
end--cPoint.__sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
Usage example: |
Usage example: |
||
< |
<syntaxhighlight lang="lua"> |
||
a = newPoint(1, 2) |
a = newPoint(1, 2) |
||
b = newPoint(3, 4) |
b = newPoint(3, 4) |
||
Line 1,444: | Line 1,444: | ||
print(c:getXY()) --> 4 6 |
print(c:getXY()) --> 4 6 |
||
print((a-b):getXY()) --> -2 -2 -- using __sub behaviour |
print((a-b):getXY()) --> -2 -2 -- using __sub behaviour |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">Point:= Record(x = 2,y = 4): |
||
Point:-x; |
Point:-x; |
||
Point:-y;</ |
Point:-y;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,459: | Line 1,459: | ||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
Expressions like point[x, y] can be used without defining. |
Expressions like point[x, y] can be used without defining. |
||
< |
<syntaxhighlight lang="mathematica">In[1]:= a = point[2, 3] |
||
Out[1]= point[2, 3] |
Out[1]= point[2, 3] |
||
Line 1,469: | Line 1,469: | ||
In[3]:= a[[2]] = 4; a |
In[3]:= a[[2]] = 4; a |
||
Out[3]= point[2, 4]</ |
Out[3]= point[2, 4]</syntaxhighlight> |
||
Or you can just define a function. |
Or you can just define a function. |
||
< |
<syntaxhighlight lang="mathematica">p[x] = 2; p[y] = 3;</syntaxhighlight> |
||
Data will be stored as down values of the symbol ''p''. |
Data will be stored as down values of the symbol ''p''. |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
< |
<syntaxhighlight lang="matlab"> point.x=3; |
||
point.y=4;</ |
point.y=4;</syntaxhighlight> |
||
Alternatively, coordinates can be also stored as vectors |
Alternatively, coordinates can be also stored as vectors |
||
< |
<syntaxhighlight lang="matlab"> point = [3,4];</syntaxhighlight> |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<syntaxhighlight lang="maxima">defstruct(point(x, y))$ |
||
p: new(point)$ |
p: new(point)$ |
||
Line 1,489: | Line 1,489: | ||
q: point(1, 2)$ |
q: point(1, 2)$ |
||
p@x: 5$</ |
p@x: 5$</syntaxhighlight> |
||
=={{header|MAXScript}}== |
=={{header|MAXScript}}== |
||
Point is a built-in object type in MAX, so... |
Point is a built-in object type in MAX, so... |
||
< |
<syntaxhighlight lang="maxscript">struct myPoint (x, y) |
||
newPoint = myPoint x:3 y:4</ |
newPoint = myPoint x:3 y:4</syntaxhighlight> |
||
In practice however, you'd use MAX's built in Point2 type |
In practice however, you'd use MAX's built in Point2 type |
||
< |
<syntaxhighlight lang="maxscript">newPoint = Point2 3 4</syntaxhighlight> |
||
=={{header|MiniScript}}== |
=={{header|MiniScript}}== |
||
< |
<syntaxhighlight lang="miniscript">Point = {} |
||
Point.x = 0 |
Point.x = 0 |
||
Point.y = 0</ |
Point.y = 0</syntaxhighlight> |
||
=={{header|Modula-2}}== |
=={{header|Modula-2}}== |
||
< |
<syntaxhighlight lang="modula2">TYPE Point = RECORD |
||
x, y : INTEGER |
x, y : INTEGER |
||
END;</ |
END;</syntaxhighlight> |
||
Usage: |
Usage: |
||
< |
<syntaxhighlight lang="modula2">VAR point : Point; |
||
... |
... |
||
point.x := 12; |
point.x := 12; |
||
point.y := 7;</ |
point.y := 7;</syntaxhighlight> |
||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
< |
<syntaxhighlight lang="modula3">TYPE Point = RECORD |
||
x, y: INTEGER; |
x, y: INTEGER; |
||
END;</ |
END;</syntaxhighlight> |
||
Usage: |
Usage: |
||
Line 1,534: | Line 1,534: | ||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
Like Java, NetRexx uses the <tt>class</tt> instruction to create compound types. Unlike Java; NetRexx provides keywords to automatically generate getters and setters for <tt>class</tt> properties and will automatically generate intermediate methods based on defaults provided in method prototypes. |
Like Java, NetRexx uses the <tt>class</tt> instruction to create compound types. Unlike Java; NetRexx provides keywords to automatically generate getters and setters for <tt>class</tt> properties and will automatically generate intermediate methods based on defaults provided in method prototypes. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols nobinary |
options replace format comments java crossref symbols nobinary |
||
Line 1,556: | Line 1,556: | ||
res = 'X='getX()',Y='getY() |
res = 'X='getX()',Y='getY() |
||
return res |
return res |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,563: | Line 1,563: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">type Point = tuple[x, y: int] |
||
var p: Point = (12, 13) |
var p: Point = (12, 13) |
||
var p2: Point = (x: 100, y: 200)</ |
var p2: Point = (x: 100, y: 200)</syntaxhighlight> |
||
=={{header|Oberon-2}}== |
=={{header|Oberon-2}}== |
||
< |
<syntaxhighlight lang="oberon2"> |
||
MODULE Point; |
MODULE Point; |
||
TYPE |
TYPE |
||
Line 1,590: | Line 1,590: | ||
END Point. |
END Point. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
Classes are used for compound data types. |
Classes are used for compound data types. |
||
< |
<syntaxhighlight lang="objeck"> |
||
class Point { |
class Point { |
||
@x : Int; |
@x : Int; |
||
Line 1,630: | Line 1,630: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 1,637: | Line 1,637: | ||
See [[wp:Algebraic_data_type|algebraic data type]]. The different options ("Empty", "Leaf", "Node") are called ''constructors'', and is associated with 0 or more arguments with the declared types; multiple arguments are declared with a syntax that looks like a tuple type, but it is not really a tuple. |
See [[wp:Algebraic_data_type|algebraic data type]]. The different options ("Empty", "Leaf", "Node") are called ''constructors'', and is associated with 0 or more arguments with the declared types; multiple arguments are declared with a syntax that looks like a tuple type, but it is not really a tuple. |
||
< |
<syntaxhighlight lang="ocaml">type tree = Empty |
||
| Leaf of int |
| Leaf of int |
||
| Node of tree * tree |
| Node of tree * tree |
||
let t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</ |
let t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</syntaxhighlight> |
||
===Record Type=== |
===Record Type=== |
||
< |
<syntaxhighlight lang="ocaml">type point = { x : int; y : int }</syntaxhighlight> |
||
How to construct a point: |
How to construct a point: |
||
< |
<syntaxhighlight lang="ocaml">let p = { x = 4; y = 5 }</syntaxhighlight> |
||
You can use the dot (".") to access fields. |
You can use the dot (".") to access fields. |
||
< |
<syntaxhighlight lang="ocaml">p.x (* evaluates to 4 *)</syntaxhighlight> |
||
Fields can be optionally declared to be mutable: |
Fields can be optionally declared to be mutable: |
||
< |
<syntaxhighlight lang="ocaml">type mutable_point = { mutable x2 : int; mutable y2 : int }</syntaxhighlight> |
||
Then they can be assigned using the assignment operator "<-" |
Then they can be assigned using the assignment operator "<-" |
||
< |
<syntaxhighlight lang="ocaml">let p2 = { x2 = 4; y2 = 5 } in |
||
p2.x2 <- 6; |
p2.x2 <- 6; |
||
p2 (* evaluates to { x2 = 6; y2 = 5 } *)</ |
p2 (* evaluates to { x2 = 6; y2 = 5 } *)</syntaxhighlight> |
||
===Tuple Type=== |
===Tuple Type=== |
||
Line 1,666: | Line 1,666: | ||
You can make a tuple literal by using a comma-delimited list, optionally surrounded by parentheses, without needing to declare the type first: |
You can make a tuple literal by using a comma-delimited list, optionally surrounded by parentheses, without needing to declare the type first: |
||
< |
<syntaxhighlight lang="ocaml">let p = (2,3)</syntaxhighlight> |
||
The type of <code>p</code> is a product (indicated by <code>*</code>) of the types of the components: |
The type of <code>p</code> is a product (indicated by <code>*</code>) of the types of the components: |
||
Line 1,676: | Line 1,676: | ||
Using a class : |
Using a class : |
||
< |
<syntaxhighlight lang="oforth">Object Class new: Point(x, y)</syntaxhighlight> |
||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
ooRexx uses class for compound data types. |
ooRexx uses class for compound data types. |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
p = .point~new(3,4) |
p = .point~new(3,4) |
||
say "x =" p~x |
say "x =" p~x |
||
Line 1,692: | Line 1,692: | ||
::attribute x |
::attribute x |
||
::attribute y |
::attribute y |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OpenEdge/Progress}}== |
=={{header|OpenEdge/Progress}}== |
||
Line 1,698: | Line 1,698: | ||
The temp-table is a in memory database table. So you can query sort and iterate it, but is the data structure that comes closest. |
The temp-table is a in memory database table. So you can query sort and iterate it, but is the data structure that comes closest. |
||
< |
<syntaxhighlight lang="progress (openedge abl)">def temp-table point |
||
field x as int |
field x as int |
||
field y as int |
field y as int |
||
.</ |
.</syntaxhighlight> |
||
Another option would be a simple class. |
Another option would be a simple class. |
||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
'SHORT FORM |
'SHORT FORM |
||
type point float x,y |
type point float x,y |
||
Line 1,728: | Line 1,728: | ||
print p.x " " p.y |
print p.x " " p.y |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
A point can be represented by using a record value: |
A point can be represented by using a record value: |
||
< |
<syntaxhighlight lang="oz">P = point(x:1 y:2)</syntaxhighlight> |
||
Now we can access the components by name: P.x and P.y |
Now we can access the components by name: P.x and P.y |
||
Often such values are deconstructed by pattern matching: |
Often such values are deconstructed by pattern matching: |
||
< |
<syntaxhighlight lang="oz">case P of point(x:X y:Y) then |
||
{Show X} |
{Show X} |
||
{Show Y} |
{Show Y} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
< |
<syntaxhighlight lang="parigp">point.x=1; |
||
point.y=2;</ |
point.y=2;</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
< |
<syntaxhighlight lang="pascal">type point = record |
||
x, y: integer; |
x, y: integer; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
===Array=== |
===Array=== |
||
< |
<syntaxhighlight lang="perl">my @point = (3, 8);</syntaxhighlight> |
||
===Hash=== |
===Hash=== |
||
< |
<syntaxhighlight lang="perl">my %point = ( |
||
x => 3, |
x => 3, |
||
y => 8 |
y => 8 |
||
);</ |
);</syntaxhighlight> |
||
===Class instance=== |
===Class instance=== |
||
< |
<syntaxhighlight lang="perl">package Point; |
||
use strict; |
use strict; |
||
Line 1,770: | Line 1,770: | ||
; |
; |
||
my $point = Point->new(x => 3, y => 8);</ |
my $point = Point->new(x => 3, y => 8);</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
===traditional user defined type=== |
===traditional user defined type=== |
||
The sequence is a natural compound data type. The following would be the same without the type point and declaring p as a sequence, apart from the run-time error. There would be no difficulty defining point to have a string and two atoms. |
The sequence is a natural compound data type. The following would be the same without the type point and declaring p as a sequence, apart from the run-time error. There would be no difficulty defining point to have a string and two atoms. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">enum</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span> |
<span style="color: #008080;">enum</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span> |
||
Line 1,789: | Line 1,789: | ||
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- fine</span> |
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- fine</span> |
||
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"string"</span> <span style="color: #000080;font-style:italic;">-- run-time error (not pwa/p2js)</span> |
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"string"</span> <span style="color: #000080;font-style:italic;">-- run-time error (not pwa/p2js)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,805: | Line 1,805: | ||
{{libheader|Phix/Class}} |
{{libheader|Phix/Class}} |
||
You could also use a class (not pwa/p2js) |
You could also use a class (not pwa/p2js) |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">class</span> <span style="color: #000000;">point</span> |
<span style="color: #008080;">class</span> <span style="color: #000000;">point</span> |
||
<span style="color: #008080;">public</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span> |
<span style="color: #008080;">public</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span> |
||
Line 1,815: | Line 1,815: | ||
<span style="color: #000000;">p</span><span style="color: #0000FF;">.</span><span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- fine</span> |
<span style="color: #000000;">p</span><span style="color: #0000FF;">.</span><span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- fine</span> |
||
<span style="color: #000000;">p</span><span style="color: #0000FF;">.</span><span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"string"</span> <span style="color: #000080;font-style:italic;">-- run-time error</span> |
<span style="color: #000000;">p</span><span style="color: #0000FF;">.</span><span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"string"</span> <span style="color: #000080;font-style:italic;">-- run-time error</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,829: | Line 1,829: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php"># Using pack/unpack |
||
$point = pack("ii", 1, 2); |
$point = pack("ii", 1, 2); |
||
Line 1,838: | Line 1,838: | ||
list($x,$y) = unpack("ii", $point); |
list($x,$y) = unpack("ii", $point); |
||
echo $x; |
echo $x; |
||
echo $y;</ |
echo $y;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="php"># Using array |
||
$point = array('x' => 1, 'y' => 2); |
$point = array('x' => 1, 'y' => 2); |
||
Line 1,847: | Line 1,847: | ||
# or simply: |
# or simply: |
||
echo $point['x'], ' ', $point['y'], "\n";</ |
echo $point['x'], ' ', $point['y'], "\n";</syntaxhighlight> |
||
< |
<syntaxhighlight lang="php"># Using class |
||
class Point { |
class Point { |
||
function __construct($x, $y) { $this->x = $x; $this->y = $y; } |
function __construct($x, $y) { $this->x = $x; $this->y = $y; } |
||
Line 1,855: | Line 1,855: | ||
} |
} |
||
$point = new Point(1, 2); |
$point = new Point(1, 2); |
||
echo $point; # will call __tostring() in later releases of PHP 5.2; before that, it won't work so good.</ |
echo $point; # will call __tostring() in later releases of PHP 5.2; before that, it won't work so good.</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(class +Point) |
||
(dm T (X Y) |
(dm T (X Y) |
||
Line 1,866: | Line 1,866: | ||
(setq P (new '(+Point) 3 4)) |
(setq P (new '(+Point) 3 4)) |
||
(show P)</ |
(show P)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>$52717735311266 (+Point) |
<pre>$52717735311266 (+Point) |
||
Line 1,873: | Line 1,873: | ||
=={{header|Pike}}== |
=={{header|Pike}}== |
||
<syntaxhighlight lang="pike"> |
|||
<lang Pike> |
|||
class Point { |
class Point { |
||
int x, y; |
int x, y; |
||
Line 1,888: | Line 1,888: | ||
write("%d %d\n", point->x, point->y); |
write("%d %d\n", point->x, point->y); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 1,895: | Line 1,895: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
define structure |
define structure |
||
1 point, |
1 point, |
||
Line 1,902: | Line 1,902: | ||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Plain English}}== |
=={{header|Plain English}}== |
||
< |
<syntaxhighlight lang="plainenglish">A cartesian point is a record with an x coord and a y coord.</syntaxhighlight> |
||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
< |
<syntaxhighlight lang="pop11">uses objectclass; |
||
define :class Point; |
define :class Point; |
||
slot x = 0; |
slot x = 0; |
||
slot y = 0; |
slot y = 0; |
||
enddefine;</ |
enddefine;</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{works with|PowerShell|5}} |
{{works with|PowerShell|5}} |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
class Point { |
class Point { |
||
[Int]$a |
[Int]$a |
||
Line 1,936: | Line 1,936: | ||
$p1.add() |
$p1.add() |
||
$p2.mul() |
$p2.mul() |
||
</syntaxhighlight> |
|||
</lang> |
|||
<b>Output:</b> |
<b>Output:</b> |
||
<pre> |
<pre> |
||
Line 1,946: | Line 1,946: | ||
Prolog terms ARE compound data types, there is no need to specifically define a type. |
Prolog terms ARE compound data types, there is no need to specifically define a type. |
||
for the purpose of this exercise you could define a rule like so: |
for the purpose of this exercise you could define a rule like so: |
||
<lang |
<syntaxhighlight lang="prolog">point(10, 20).</syntaxhighlight> |
||
This will create static point that can be called: |
This will create static point that can be called: |
||
< |
<syntaxhighlight lang="prolog">?- point(X,Y). |
||
X = 10, |
X = 10, |
||
Y = 20.</ |
Y = 20.</syntaxhighlight> |
||
terms can be passed around as values and can have a complex nested structure of any size, eg: |
terms can be passed around as values and can have a complex nested structure of any size, eg: |
||
< |
<syntaxhighlight lang="prolog">person_location(person(name(N), age(A)), point(X, Y)).</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
A basic [http://www.purebasic.com/documentation/reference/structures.html structure] is implemented as; |
A basic [http://www.purebasic.com/documentation/reference/structures.html structure] is implemented as; |
||
< |
<syntaxhighlight lang="purebasic">Structure MyPoint |
||
x.i |
x.i |
||
y.i |
y.i |
||
EndStructure</ |
EndStructure</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
The simplest way it to use a tuple, or a list if it should be mutable: |
The simplest way it to use a tuple, or a list if it should be mutable: |
||
< |
<syntaxhighlight lang="python">X, Y = 0, 1 |
||
p = (3, 4) |
p = (3, 4) |
||
p = [3, 4] |
p = [3, 4] |
||
print p[X]</ |
print p[X]</syntaxhighlight> |
||
If needed, you can use class: |
If needed, you can use class: |
||
< |
<syntaxhighlight lang="python">class Point: |
||
def __init__(self, x=0, y=0): |
def __init__(self, x=0, y=0): |
||
self.x = x |
self.x = x |
||
Line 1,979: | Line 1,979: | ||
p = Point() |
p = Point() |
||
print p.x</ |
print p.x</syntaxhighlight> |
||
One could also simply instantiate a generic object and "monkeypatch" it: |
One could also simply instantiate a generic object and "monkeypatch" it: |
||
< |
<syntaxhighlight lang="python">class MyObject(object): pass |
||
point = MyObject() |
point = MyObject() |
||
point.x, point.y = 0, 1 |
point.x, point.y = 0, 1 |
||
# objects directly instantiated from "object()" cannot be "monkey patched" |
# objects directly instantiated from "object()" cannot be "monkey patched" |
||
# however this can generally be done to it's subclasses</ |
# however this can generally be done to it's subclasses</syntaxhighlight> |
||
=== Dictionary === |
=== Dictionary === |
||
Mutable. Can add keys (attributes) |
Mutable. Can add keys (attributes) |
||
< |
<syntaxhighlight lang="python">pseudo_object = {'x': 1, 'y': 2}</syntaxhighlight> |
||
Line 1,998: | Line 1,998: | ||
As of Python 2.6 one can use the ''collections.namedtuple'' factory to create classes which associate field names with elements of a tuple. This allows one to perform all normal operations on the contained tuples (access by indices or slices, packing and unpacking) while also allowing elements to be accessed by name. |
As of Python 2.6 one can use the ''collections.namedtuple'' factory to create classes which associate field names with elements of a tuple. This allows one to perform all normal operations on the contained tuples (access by indices or slices, packing and unpacking) while also allowing elements to be accessed by name. |
||
< |
<syntaxhighlight lang="python">>>> from collections import namedtuple |
||
>>> help(namedtuple) |
>>> help(namedtuple) |
||
Help on function namedtuple in module collections: |
Help on function namedtuple in module collections: |
||
Line 2,024: | Line 2,024: | ||
Point(x=100, y=22) |
Point(x=100, y=22) |
||
>>></ |
>>></syntaxhighlight> |
||
=={{header|QB64}}== |
=={{header|QB64}}== |
||
< |
<syntaxhighlight lang="qb64">Type Point |
||
x As Double |
x As Double |
||
y As Double |
y As Double |
||
Line 2,036: | Line 2,036: | ||
p.y = 2.412 |
p.y = 2.412 |
||
Print p.x; p.y</ |
Print p.x; p.y</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 15.42 2.412</pre> |
<pre> 15.42 2.412</pre> |
||
Line 2,050: | Line 2,050: | ||
The word <code>point</code> creates an instance of a nest with two elements, both initialised to zero. The word <code>x</code> specifies the location of the zeroth element within the nest, and the word <code>y</code> specifies the location of the first element within the nest. <code>peek</code> returns the value stored in a specified location, and <code>poke</code> changes the value stored in a specified location, returning the modified nest. |
The word <code>point</code> creates an instance of a nest with two elements, both initialised to zero. The word <code>x</code> specifies the location of the zeroth element within the nest, and the word <code>y</code> specifies the location of the first element within the nest. <code>peek</code> returns the value stored in a specified location, and <code>poke</code> changes the value stored in a specified location, returning the modified nest. |
||
<syntaxhighlight lang="quackery"> |
|||
<lang Quackery> |
|||
[ ' [ 0 0 ] ] is point ( --> [ ) |
[ ' [ 0 0 ] ] is point ( --> [ ) |
||
Line 2,060: | Line 2,060: | ||
dup x peek echo cr |
dup x peek echo cr |
||
99 swap y poke |
99 swap y poke |
||
y peek echo cr</ |
y peek echo cr</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,071: | Line 2,071: | ||
The "overkill" solution automates the process of creating new structures with the word <code>struct{</code>, which extends the Quackery compiler to allow the definition of complex compound data structures as follows. |
The "overkill" solution automates the process of creating new structures with the word <code>struct{</code>, which extends the Quackery compiler to allow the definition of complex compound data structures as follows. |
||
< |
<syntaxhighlight lang="quackery"> struct{ |
||
item.0 |
item.0 |
||
{ item.1.0 |
{ item.1.0 |
||
Line 2,083: | Line 2,083: | ||
} item.1 |
} item.1 |
||
item.2 |
item.2 |
||
}struct mystruct</ |
}struct mystruct</syntaxhighlight> |
||
Once defined, the word <code>mystruct</code> will place a new instance of the described structure, with each item initialised to <code>null</code>, on the stack. (The behaviour of <code>null</code> is to place a reference to itself on the stack, as a convenience for debugging, and to allow code to identify elements within the structure that have not had a value assigned to them.) |
Once defined, the word <code>mystruct</code> will place a new instance of the described structure, with each item initialised to <code>null</code>, on the stack. (The behaviour of <code>null</code> is to place a reference to itself on the stack, as a convenience for debugging, and to allow code to identify elements within the structure that have not had a value assigned to them.) |
||
Line 2,091: | Line 2,091: | ||
Names following a <code>}</code> within the definition of a struct (e.g. <code>} item.1.2</code>) return a path to the compound data structure preceding it within the structure. In the example, <code>item.1.2</code> returns the path to <code>{ item.1.2.0 item.1.2.1 item.1.2.2 item.1.2.3 }</code> |
Names following a <code>}</code> within the definition of a struct (e.g. <code>} item.1.2</code>) return a path to the compound data structure preceding it within the structure. In the example, <code>item.1.2</code> returns the path to <code>{ item.1.2.0 item.1.2.1 item.1.2.2 item.1.2.3 }</code> |
||
< |
<syntaxhighlight lang="quackery"> mystruct ( create new instance of a mystruct ) |
||
dup echo cr ( this is what it looks like ) |
dup echo cr ( this is what it looks like ) |
||
789 swap item.1.3 {poke} ( change one of the items ) |
789 swap item.1.3 {poke} ( change one of the items ) |
||
dup echo cr ( this is what it looks like now ) |
dup echo cr ( this is what it looks like now ) |
||
item.1.3 {peek} echo cr ( retrieve the specified item ) |
item.1.3 {peek} echo cr ( retrieve the specified item ) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,106: | Line 2,106: | ||
The words <code>{peek}</code>, <code>{poke}</code>, <code>null</code>, and the building word (i.e. compiler extension) <code>struct{</code> defined: |
The words <code>{peek}</code>, <code>{poke}</code>, <code>null</code>, and the building word (i.e. compiler extension) <code>struct{</code> defined: |
||
<lang> [ witheach peek ] is {peek} ( { p --> x ) |
<syntaxhighlight lang="text"> [ witheach peek ] is {peek} ( { p --> x ) |
||
[ dip dup |
[ dip dup |
||
Line 2,213: | Line 2,213: | ||
{}.name again ] |
{}.name again ] |
||
{}.struct release |
{}.struct release |
||
{}.path release ] builds struct{ ( [ $ --> [ $ )</ |
{}.path release ] builds struct{ ( [ $ --> [ $ )</syntaxhighlight> |
||
Finally we use <code>struct{</code> etc. to fulfil the requirements go the task. |
Finally we use <code>struct{</code> etc. to fulfil the requirements go the task. |
||
< |
<syntaxhighlight lang="quackery"> struct{ x y }struct point |
||
point |
point |
||
dup x {peek} echo cr |
dup x {peek} echo cr |
||
99 swap y {poke} |
99 swap y {poke} |
||
y {peek} echo cr</ |
y {peek} echo cr</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,231: | Line 2,231: | ||
=={{header|R}}== |
=={{header|R}}== |
||
R uses the list data type for compound data. |
R uses the list data type for compound data. |
||
< |
<syntaxhighlight lang="r">mypoint <- list(x=3.4, y=6.7) |
||
# $x |
# $x |
||
# [1] 3.4 |
# [1] 3.4 |
||
Line 2,250: | Line 2,250: | ||
# [1] 1 |
# [1] 1 |
||
# $d$f |
# $d$f |
||
# [1] TRUE</ |
# [1] TRUE</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 2,256: | Line 2,256: | ||
The most common method uses structures (similar to records): |
The most common method uses structures (similar to records): |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(struct point (x y)) |
(struct point (x y)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Alternatively, you can define a class: |
Alternatively, you can define a class: |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(define point% ; classes are suffixed with % by convention |
(define point% ; classes are suffixed with % by convention |
||
Line 2,269: | Line 2,269: | ||
(super-new) |
(super-new) |
||
(init-field x y))) |
(init-field x y))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 2,276: | Line 2,276: | ||
===Array=== |
===Array=== |
||
<lang |
<syntaxhighlight lang="raku" line>my @point = 3, 8; |
||
my Int @point = 3, 8; # or constrain to integer elements</ |
my Int @point = 3, 8; # or constrain to integer elements</syntaxhighlight> |
||
===Hash=== |
===Hash=== |
||
<lang |
<syntaxhighlight lang="raku" line>my %point = x => 3, y => 8; |
||
my Int %point = x => 3, y => 8; # or constrain the hash to have integer values</ |
my Int %point = x => 3, y => 8; # or constrain the hash to have integer values</syntaxhighlight> |
||
===Class instance=== |
===Class instance=== |
||
<lang |
<syntaxhighlight lang="raku" line>class Point { has $.x is rw; has $.y is rw; } |
||
my Point $point .= new(x => 3, y => 8);</ |
my Point $point .= new(x => 3, y => 8);</syntaxhighlight> |
||
===[http://design.raku.org/S32/Containers.html#Set Set]=== |
===[http://design.raku.org/S32/Containers.html#Set Set]=== |
||
<lang |
<syntaxhighlight lang="raku" line>my $s1 = set <a b c d>; # order is not preserved |
||
my $s2 = set <c d e f>; |
my $s2 = set <c d e f>; |
||
say $s1 (&) $s2; # OUTPUT«set(c, e)» |
say $s1 (&) $s2; # OUTPUT«set(c, e)» |
||
say $s1 ∩ $s2; # we also do Unicode</ |
say $s1 ∩ $s2; # we also do Unicode</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang="rexx">x= -4.9 |
||
y= 1.7 |
y= 1.7 |
||
point=x y</ |
point=x y</syntaxhighlight> |
||
:: ---or--- |
:: ---or--- |
||
< |
<syntaxhighlight lang="rexx">x= -4.1 |
||
y= 1/4e21 |
y= 1/4e21 |
||
Line 2,308: | Line 2,308: | ||
bpoint=point |
bpoint=point |
||
gpoint=5.6 7.3e-12</ |
gpoint=5.6 7.3e-12</syntaxhighlight> |
||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
see new point {x=10 y=20} class point x y |
see new point {x=10 y=20} class point x y |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output |
Output |
||
< |
<syntaxhighlight lang="ring"> |
||
x: 10.000000 |
x: 10.000000 |
||
y: 20.000000 |
y: 20.000000 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">Point = Struct.new(:x,:y) |
||
pt = Point.new(6,7) |
pt = Point.new(6,7) |
||
puts pt.x #=> 6 |
puts pt.x #=> 6 |
||
Line 2,335: | Line 2,335: | ||
pt.each_pair{|member, value| puts "#{member} : #{value}"} |
pt.each_pair{|member, value| puts "#{member} : #{value}"} |
||
#=> x : 2 |
#=> x : 2 |
||
#=> y : 5</ |
#=> y : 5</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 2,342: | Line 2,342: | ||
====C-like struct==== |
====C-like struct==== |
||
< |
<syntaxhighlight lang="rust"> // Defines a generic struct where x and y can be of any type T |
||
struct Point<T> { |
struct Point<T> { |
||
x: T, |
x: T, |
||
Line 2,350: | Line 2,350: | ||
let p = Point { x: 1.0, y: 2.5 }; // p is of type Point<f64> |
let p = Point { x: 1.0, y: 2.5 }; // p is of type Point<f64> |
||
println!("{}, {}", p.x, p.y); |
println!("{}, {}", p.x, p.y); |
||
} </ |
} </syntaxhighlight> |
||
====Tuple struct==== |
====Tuple struct==== |
||
These are basically just named tuples. |
These are basically just named tuples. |
||
< |
<syntaxhighlight lang="rust">struct Point<T>(T, T); |
||
fn main() { |
fn main() { |
||
let p = Point(1.0, 2.5); |
let p = Point(1.0, 2.5); |
||
println!("{},{}", p.0, p.1); |
println!("{},{}", p.0, p.1); |
||
}</ |
}</syntaxhighlight> |
||
===Tuples=== |
===Tuples=== |
||
< |
<syntaxhighlight lang="rust"> fn main() { |
||
let p = (0.0, 2.4); |
let p = (0.0, 2.4); |
||
println!("{},{}", p.0, p.1); |
println!("{},{}", p.0, p.1); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">case class Point(x: Int = 0, y: Int = 0) |
||
val p = Point(1, 2) |
val p = Point(1, 2) |
||
println(p.y) //=> 2</ |
println(p.y) //=> 2</syntaxhighlight> |
||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
Using [http://srfi.schemers.org/srfi-9/srfi-9.html SRFI 9]: |
Using [http://srfi.schemers.org/srfi-9/srfi-9.html SRFI 9]: |
||
< |
<syntaxhighlight lang="scheme">(define-record-type point |
||
(make-point x y) |
(make-point x y) |
||
point? |
point? |
||
(x point-x) |
(x point-x) |
||
(y point-y))</ |
(y point-y))</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">const type: Point is new struct |
||
var integer: x is 0; |
var integer: x is 0; |
||
var integer: y is 0; |
var integer: y is 0; |
||
end struct;</ |
end struct;</syntaxhighlight> |
||
=={{header|Shen}}== |
=={{header|Shen}}== |
||
< |
<syntaxhighlight lang="shen">(datatype point |
||
X : number; Y : number; |
X : number; Y : number; |
||
==================== |
==================== |
||
[point X Y] : point;)</ |
[point X Y] : point;)</syntaxhighlight> |
||
Pairs (distinct from cons cells) are also supported, in which case a point would be denoted by (number * number): |
Pairs (distinct from cons cells) are also supported, in which case a point would be denoted by (number * number): |
||
< |
<syntaxhighlight lang="shen">(2+) (@p 1 2) |
||
(@p 1 2) : (number * number)</ |
(@p 1 2) : (number * number)</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">struct Point {x, y}; |
||
var point = Point(1, 2); |
var point = Point(1, 2); |
||
say point.y; #=> 2</ |
say point.y; #=> 2</syntaxhighlight> |
||
=={{header|SIMPOL}}== |
=={{header|SIMPOL}}== |
||
The <code>point</code> type is pre-defined in [SIMPOL], so we will call this mypoint. |
The <code>point</code> type is pre-defined in [SIMPOL], so we will call this mypoint. |
||
< |
<syntaxhighlight lang="simpol">type mypoint |
||
embed |
embed |
||
integer x |
integer x |
||
integer y |
integer y |
||
end type</ |
end type</syntaxhighlight> |
||
The <code>embed</code> keyword is used here as a toggle to indicate that all following properties are embedded in the type. The other toggle is <code>reference</code>, which only places a reference to an object in the type, but the reference assigned before the property can be used. These keywords can also be placed on the same line, but then they only apply to that line of the type definition. |
The <code>embed</code> keyword is used here as a toggle to indicate that all following properties are embedded in the type. The other toggle is <code>reference</code>, which only places a reference to an object in the type, but the reference assigned before the property can be used. These keywords can also be placed on the same line, but then they only apply to that line of the type definition. |
||
Line 2,412: | Line 2,412: | ||
A type in [SIMPOL] can be just a container of values and other structures, but it can also include methods. These are implemented outside the type definition, but must be part of the same compiled unit. |
A type in [SIMPOL] can be just a container of values and other structures, but it can also include methods. These are implemented outside the type definition, but must be part of the same compiled unit. |
||
< |
<syntaxhighlight lang="simpol">type mypoint |
||
embed |
embed |
||
integer x |
integer x |
||
Line 2,421: | Line 2,421: | ||
me.x = x |
me.x = x |
||
me.y = y |
me.y = y |
||
end function me</ |
end function me</syntaxhighlight> |
||
=={{header|SNOBOL4}}== |
=={{header|SNOBOL4}}== |
||
< |
<syntaxhighlight lang="snobol"> data('point(x,y)') |
||
p1 = point(10,20) |
p1 = point(10,20) |
||
p2 = point(10,40) |
p2 = point(10,40) |
||
output = "Point 1 (" x(p1) "," y(p1) ")" |
output = "Point 1 (" x(p1) "," y(p1) ")" |
||
output = "Point 2 (" x(p2) "," y(p2) ")" |
output = "Point 2 (" x(p2) "," y(p2) ")" |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
Line 2,437: | Line 2,437: | ||
See [[wp:Algebraic_data_type|algebraic data type]]. The different options ("Empty", "Leaf", "Node") are called ''constructors'', and is associated with 0 or 1 arguments with the declared types; multiple arguments are handled with tuples. |
See [[wp:Algebraic_data_type|algebraic data type]]. The different options ("Empty", "Leaf", "Node") are called ''constructors'', and is associated with 0 or 1 arguments with the declared types; multiple arguments are handled with tuples. |
||
< |
<syntaxhighlight lang="sml">datatype tree = Empty |
||
| Leaf of int |
| Leaf of int |
||
| Node of tree * tree |
| Node of tree * tree |
||
val t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</ |
val t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</syntaxhighlight> |
||
===Tuple Type=== |
===Tuple Type=== |
||
Line 2,447: | Line 2,447: | ||
You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first: |
You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first: |
||
< |
<syntaxhighlight lang="sml">val p = (2,3)</syntaxhighlight> |
||
The type of <code>p</code> is a product (indicated by <code>*</code>) of the types of the components: |
The type of <code>p</code> is a product (indicated by <code>*</code>) of the types of the components: |
||
Line 2,464: | Line 2,464: | ||
You can make a record literal by using a comma-delimited list of <code>key = value</code> pairs surrounded by curly braces, without needing to declare the type first: |
You can make a record literal by using a comma-delimited list of <code>key = value</code> pairs surrounded by curly braces, without needing to declare the type first: |
||
< |
<syntaxhighlight lang="sml">val p = { x = 4, y = 5 }</syntaxhighlight> |
||
The type of <code>p</code> is a comma-delimited list of <code>key:type</code> pairs of the types of the fields: |
The type of <code>p</code> is a comma-delimited list of <code>key:type</code> pairs of the types of the fields: |
||
Line 2,478: | Line 2,478: | ||
See '''[https://www.stata.com/help.cgi?m2_struct struct]''' in Stata help. |
See '''[https://www.stata.com/help.cgi?m2_struct struct]''' in Stata help. |
||
< |
<syntaxhighlight lang="stata">mata |
||
struct Point { |
struct Point { |
||
real scalar x, y |
real scalar x, y |
||
Line 2,493: | Line 2,493: | ||
test() |
test() |
||
30 |
30 |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">// Structure |
||
struct Point { |
struct Point { |
||
var x:Int |
var x:Int |
||
Line 2,514: | Line 2,514: | ||
self.y = y |
self.y = y |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
This can be done using an associative array: |
This can be done using an associative array: |
||
< |
<syntaxhighlight lang="tcl">array set point {x 4 y 5} |
||
set point(y) 7 |
set point(y) 7 |
||
puts "Point is {$point(x),$point(y)}" |
puts "Point is {$point(x),$point(y)}" |
||
# => Point is {4,7}</ |
# => Point is {4,7}</syntaxhighlight> |
||
Or a dictionary: |
Or a dictionary: |
||
{{works with|Tcl|8.5}} |
{{works with|Tcl|8.5}} |
||
< |
<syntaxhighlight lang="tcl">set point [dict create x 4 y 5] |
||
dict set point y 7 |
dict set point y 7 |
||
puts "Point is {[dict get $point x],[dict get $point y]}"</ |
puts "Point is {[dict get $point x],[dict get $point y]}"</syntaxhighlight> |
||
Or an object: |
Or an object: |
||
{{works with|Tcl|8.6}} |
{{works with|Tcl|8.6}} |
||
< |
<syntaxhighlight lang="tcl">oo::class create Point { |
||
variable x y |
variable x y |
||
constructor {X Y} {set x $X;set y $Y} |
constructor {X Y} {set x $X;set y $Y} |
||
Line 2,538: | Line 2,538: | ||
Point create point 4 5 |
Point create point 4 5 |
||
point y 7 |
point y 7 |
||
puts "Point is [point show]"</ |
puts "Point is [point show]"</syntaxhighlight> |
||
=={{header|TI-89 BASIC}}== |
=={{header|TI-89 BASIC}}== |
||
Line 2,548: | Line 2,548: | ||
In TXR Lisp, a structure type can be created: |
In TXR Lisp, a structure type can be created: |
||
< |
<syntaxhighlight lang="txrlisp">(defstruct point nil (x 0) (y 0))</syntaxhighlight> |
||
If it is okay for the coordinates to be initialized to <tt>nil</tt>, it can be condensed to: |
If it is okay for the coordinates to be initialized to <tt>nil</tt>, it can be condensed to: |
||
< |
<syntaxhighlight lang="txrlisp">(defstruct point nil x y)</syntaxhighlight> |
||
The <tt>nil</tt> denotes that a <tt>point</tt> has no supertype: it doesn't inherit from anything. |
The <tt>nil</tt> denotes that a <tt>point</tt> has no supertype: it doesn't inherit from anything. |
||
Line 2,558: | Line 2,558: | ||
This structure type can then be instantiated using the <tt>new</tt> macro (not the only way): |
This structure type can then be instantiated using the <tt>new</tt> macro (not the only way): |
||
< |
<syntaxhighlight lang="txrlisp">(new point) ;; -> #S(point x 0 y 0) |
||
(new point x 1) ;; -> #S(point x 1 y 0) |
(new point x 1) ;; -> #S(point x 1 y 0) |
||
(new point x 1 y 1) ;; -> #S(point x 1 y 1)</ |
(new point x 1 y 1) ;; -> #S(point x 1 y 1)</syntaxhighlight> |
||
A structure can support optional by-order-of-arguments ("boa") construction by providing a "boa constructor". The <tt>defstruct</tt> syntactic sugar does this if a function-like syntax is used in place of the structure name: |
A structure can support optional by-order-of-arguments ("boa") construction by providing a "boa constructor". The <tt>defstruct</tt> syntactic sugar does this if a function-like syntax is used in place of the structure name: |
||
< |
<syntaxhighlight lang="txrlisp">(defstruct (point x y) nil (x 0) (y 0))</syntaxhighlight> |
||
The existing construction methods continue to work, but in addition, this is now possible: |
The existing construction methods continue to work, but in addition, this is now possible: |
||
< |
<syntaxhighlight lang="txrlisp">(new (point 3 4)) -> #S(point x 3 y 4)</syntaxhighlight> |
||
Slot access syntax is supported. If variable <tt>p</tt> holds a point, then <tt>p.x</tt> designates the <tt>x</tt> slot, as a syntactic place which can be accessed and stored: |
Slot access syntax is supported. If variable <tt>p</tt> holds a point, then <tt>p.x</tt> designates the <tt>x</tt> slot, as a syntactic place which can be accessed and stored: |
||
< |
<syntaxhighlight lang="txrlisp">(defun displace-point-destructively (p delta) |
||
(inc p.x delta.x) |
(inc p.x delta.x) |
||
(inc p.y delta.y))</ |
(inc p.y delta.y))</syntaxhighlight> |
||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
{{works with|ksh93}} |
{{works with|ksh93}} |
||
ksh93 allows you to define new compound types with the <tt>typeset -T</tt> command. |
ksh93 allows you to define new compound types with the <tt>typeset -T</tt> command. |
||
< |
<syntaxhighlight lang="bash">typeset -T Point=( |
||
typeset x |
typeset x |
||
typeset y |
typeset y |
||
Line 2,589: | Line 2,589: | ||
echo ${p.x} ${p.y} |
echo ${p.x} ${p.y} |
||
Point q=(x=3 y=4) |
Point q=(x=3 y=4) |
||
echo ${q.x} ${q.y}</ |
echo ${q.x} ${q.y}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>( x=1 y=2 ) |
<pre>( x=1 y=2 ) |
||
Line 2,596: | Line 2,596: | ||
You can also declare compound variables "on the fly" without using a defined type: |
You can also declare compound variables "on the fly" without using a defined type: |
||
< |
<syntaxhighlight lang="bash">point=() |
||
point.x=5 |
point.x=5 |
||
point.y=6 |
point.y=6 |
||
echo $point |
echo $point |
||
echo ${point.x} ${point.y}</ |
echo ${point.x} ${point.y}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>( x=5 y=6 ) |
<pre>( x=5 y=6 ) |
||
Line 2,607: | Line 2,607: | ||
=={{header|Ursala}}== |
=={{header|Ursala}}== |
||
A record type with two untyped fields named <code>x</code> and <code>y</code> can be declared like this. |
A record type with two untyped fields named <code>x</code> and <code>y</code> can be declared like this. |
||
<lang |
<syntaxhighlight lang="ursala">point :: x y</syntaxhighlight> |
||
A constant instance of the record can be declared like this. |
A constant instance of the record can be declared like this. |
||
< |
<syntaxhighlight lang="ursala">p = point[x: 'foo',y: 'bar']</syntaxhighlight> |
||
A function returning a value of this type can be defined like this, |
A function returning a value of this type can be defined like this, |
||
< |
<syntaxhighlight lang="ursala">f = point$[x: g,y: h]</syntaxhighlight> |
||
where <code>g</code> and <code>h</code> are functions. Then <code>f(p)</code> would evaluate to |
where <code>g</code> and <code>h</code> are functions. Then <code>f(p)</code> would evaluate to |
||
<code>point[x: g(p),y: h(p)]</code> for a given argument <code>p</code>. Accessing the fields of |
<code>point[x: g(p),y: h(p)]</code> for a given argument <code>p</code>. Accessing the fields of |
||
a record can be done like this. |
a record can be done like this. |
||
< |
<syntaxhighlight lang="ursala">t = ~x p |
||
u = ~y p</ |
u = ~y p</syntaxhighlight> |
||
where <code>p</code> is any expression of the defined type. A real application wouldn't be written |
where <code>p</code> is any expression of the defined type. A real application wouldn't be written |
||
this way because pairs of values <code>(x,y)</code> are a common idiom. |
this way because pairs of values <code>(x,y)</code> are a common idiom. |
||
=={{header|Vala}}== |
=={{header|Vala}}== |
||
< |
<syntaxhighlight lang="vala">struct Point { |
||
int x; |
int x; |
||
int y; |
int y; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
< |
<syntaxhighlight lang="vb">Type point |
||
x As Integer |
x As Integer |
||
y As Integer |
y As Integer |
||
End Type</ |
End Type</syntaxhighlight> |
||
=={{header|Vim Script}}== |
=={{header|Vim Script}}== |
||
One cannot create new data types in Vim Script. A point could be represented by a dictionary: |
One cannot create new data types in Vim Script. A point could be represented by a dictionary: |
||
< |
<syntaxhighlight lang="vim">function MakePoint(x, y) " 'Constructor' |
||
return {"x": a:x, "y": a:y} |
return {"x": a:x, "y": a:y} |
||
endfunction |
endfunction |
||
Line 2,643: | Line 2,643: | ||
echon "Point 1: x = " p1.x ", y = " p1.y "\n" |
echon "Point 1: x = " p1.x ", y = " p1.y "\n" |
||
echon "Point 2: x = " p2.x ", y = " p2.y "\n"</ |
echon "Point 2: x = " p2.x ", y = " p2.y "\n"</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 2,654: | Line 2,654: | ||
A simple structure with two public, mutable fields: |
A simple structure with two public, mutable fields: |
||
< |
<syntaxhighlight lang="vbnet">Structure Point |
||
Public X, Y As Integer |
Public X, Y As Integer |
||
End Structure</ |
End Structure</syntaxhighlight> |
||
=== Immutable Structures === |
=== Immutable Structures === |
||
Line 2,668: | Line 2,668: | ||
Below is the same <code>Point</code> as above, except with an immutable API. |
Below is the same <code>Point</code> as above, except with an immutable API. |
||
< |
<syntaxhighlight lang="vbnet">Structure ImmutablePoint |
||
ReadOnly Property X As Integer |
ReadOnly Property X As Integer |
||
ReadOnly Property Y As Integer |
ReadOnly Property Y As Integer |
||
Line 2,676: | Line 2,676: | ||
Me.Y = y |
Me.Y = y |
||
End Sub |
End Sub |
||
End Structure</ |
End Structure</syntaxhighlight> |
||
=={{header|Vlang}}== |
=={{header|Vlang}}== |
||
Vlang also supports embedding structs into other structs and assigning methods to structs. |
Vlang also supports embedding structs into other structs and assigning methods to structs. |
||
< |
<syntaxhighlight lang="vlang">struct Point { |
||
x int |
x int |
||
y int |
y int |
||
Line 2,703: | Line 2,703: | ||
assert p.x == 30 |
assert p.x == 30 |
||
println("Show the struct again after change:\n $p") |
println("Show the struct again after change:\n $p") |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,720: | Line 2,720: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
< |
<syntaxhighlight lang="ecmascript">class Point { |
||
construct new(x, y) { |
construct new(x, y) { |
||
_x = x |
_x = x |
||
Line 2,742: | Line 2,742: | ||
p.y = 3 |
p.y = 3 |
||
// print without using the toString method |
// print without using the toString method |
||
System.printAll(["(", p.x, ", ", p.y, ")"])</ |
System.printAll(["(", p.x, ", ", p.y, ")"])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,755: | Line 2,755: | ||
===Attributes=== |
===Attributes=== |
||
Attributes are often used for simple values. This is how a point might be represented in SVG, for example. |
Attributes are often used for simple values. This is how a point might be represented in SVG, for example. |
||
< |
<syntaxhighlight lang="xml"><point x="20" y="30"/> |
||
<!-- context is a point node. The '@' prefix selects named attributes of the current node. --> |
<!-- context is a point node. The '@' prefix selects named attributes of the current node. --> |
||
<fo:block>Point = <xsl:value-of select="@x"/>, <xsl:value-of select="@y"/></fo:block></ |
<fo:block>Point = <xsl:value-of select="@x"/>, <xsl:value-of select="@y"/></fo:block></syntaxhighlight> |
||
===Children=== |
===Children=== |
||
More complex, multivariate, and nested data structures can be represented using child nodes. |
More complex, multivariate, and nested data structures can be represented using child nodes. |
||
< |
<syntaxhighlight lang="xml"><circle> |
||
<point> |
<point> |
||
<x>20</x> |
<x>20</x> |
||
Line 2,770: | Line 2,770: | ||
</circle> |
</circle> |
||
<!-- context is a circle node. Children are accessed using a path-like notation (hence the name "XPath"). --></ |
<!-- context is a circle node. Children are accessed using a path-like notation (hence the name "XPath"). --></syntaxhighlight> |
||
<fo:block>Circle center = <xsl:value-of select="point/x"/>, <xsl:value-of select="point/y"/></fo:block> |
<fo:block>Circle center = <xsl:value-of select="point/x"/>, <xsl:value-of select="point/y"/></fo:block> |
||
=={{header|Z80 Assembly}}== |
=={{header|Z80 Assembly}}== |
||
We'll declare the following C struct: |
We'll declare the following C struct: |
||
< |
<syntaxhighlight lang="c">struct Point{ |
||
char x; |
char x; |
||
char y; |
char y; |
||
}</ |
}</syntaxhighlight> |
||
and then execute the following C code as Z80 Assembly below. |
and then execute the following C code as Z80 Assembly below. |
||
< |
<syntaxhighlight lang="c">struct Point myPoint; |
||
myPoint.x = 3; |
myPoint.x = 3; |
||
myPoint.y = 5;</ |
myPoint.y = 5;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="z80">;I'm arbitrarily choosing &1100 as the memory location of our Point variable. |
||
ld hl,&1100 |
ld hl,&1100 |
||
ld (hl),3 |
ld (hl),3 |
||
inc hl |
inc hl |
||
ld (hl),5 |
ld (hl),5 |
||
ret</ |
ret</syntaxhighlight> |
||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
The OO solution: |
The OO solution: |
||
< |
<syntaxhighlight lang="zkl">class Point{ var x,y; |
||
fcn init(x,y){self.x=x.toFloat(); self.y=y.toFloat(); } |
fcn init(x,y){self.x=x.toFloat(); self.y=y.toFloat(); } |
||
fcn toString{ "P(%f,%f)".fmt(x,y) } |
fcn toString{ "P(%f,%f)".fmt(x,y) } |
||
Line 2,800: | Line 2,800: | ||
//... __opEQ == etc |
//... __opEQ == etc |
||
} |
} |
||
Point(1,2).println() //-->P(1.000000,2.000000)</ |
Point(1,2).println() //-->P(1.000000,2.000000)</syntaxhighlight> |
||
which can be pretty heavy weight. [read only] lists can work just as well: |
which can be pretty heavy weight. [read only] lists can work just as well: |
||
< |
<syntaxhighlight lang="zkl">point:=T(1,2); points:=T( T(1,2), L(3,4) )</syntaxhighlight> |
||
{{omit from|bc}} |
{{omit from|bc}} |
||
Line 2,808: | Line 2,808: | ||
=={{header|zonnon}}== |
=={{header|zonnon}}== |
||
< |
<syntaxhighlight lang="zonnon"> |
||
{ref,public} (* class *) |
{ref,public} (* class *) |
||
Point = object(ord,abs: integer) |
Point = object(ord,abs: integer) |
||
Line 2,832: | Line 2,832: | ||
self.y := abs; |
self.y := abs; |
||
end Point; |
end Point; |
||
</syntaxhighlight> |
|||
</lang> |