Compound data type

From Rosetta Code
(Redirected from Compound Data Type)
Task
Compound data type
You are encouraged to solve this task according to the task description, using any language you may know.

Data Structure
This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.


Task

Create a compound data type:

  Point(x,y) 


A compound data type is one that holds multiple independent values.


Related task


See also



Contents

ACL2[edit]

(defstructure point
(x (:assert (rationalp x)))
(y (:assert (rationalp y))))
 
(assign p1 (make-point :x 1 :y 2))
(point-x (@ p1)) ; Access the x value of the point
(assign p1 (update-point (@ p1) :x 3)) ; Update the x value
(point-x (@ p1))
(point-p (@ p1)) ; Recognizer for points
Output:
((:X . 1) (:Y . 2))
1
((:X . 3) (:Y . 2))
3
T

ActionScript[edit]

package
{
public class Point
{
public var x:Number;
public var y:Number;
 
public function Point(x:Number, y:Number)
{
this.x = x;
this.y = y;
}
}
}

Ada[edit]

Tagged Type[edit]

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.

type Point is tagged record
X : Integer := 0;
Y : Integer := 0;
end record;

Record Type[edit]

Ada record types are not extensible through inheritance. Without the reserved word tagged the record does not belong to an inheritance hierarchy.

type Point is record
X : Integer := 0;
Y : Integer := 0;
end record;

Parameterized Types[edit]

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.

type Person (Gender : Gender_Type) is record
Name  : Name_String;
Age  : Natural;
Weight : Float;
Case Gender is
when Male =>
Beard_Length : Float;
when Female =>
null;
end case;
end record;

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.

ALGOL 68[edit]

Tagged Type[edit]

ALGOL 68 has only tagged-union/discriminants. And the tagging was strictly done by the type (MODE) of the members.

MODE UNIONX = UNION(
STRUCT(REAL r, INT i),
INT,
REAL,
STRUCT(INT ii),
STRUCT(REAL rr),
STRUCT([]REAL r)
);

To extract the apropriate member of a UNION a conformity-clause has to be used.

UNIONX data := 6.6;
CASE data IN
(INT i): printf(($"r: "gl$,i)),
(REAL r): printf(($"r: "gl$,r)),
(STRUCT(REAL r, INT i) s): printf(($"r&i: "2(g)l$,s)),
(STRUCT([]REAL r) s): printf(($"r: "n(UPB r OF s)(g)l$,s))
OUT
printf($"Other cases"l$)
ESAC;

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, except maybe in certain special cases.

Record Type[edit]

ALGOL 68 record types are not extensible through inheritance but they may be part of a larger STRUCT composition.

MODE POINT = STRUCT(
INT x,
INT y
);

Parameterized Types[edit]

An ALGOL 68 record type can contain a tagged-union/discriminant. The tagged-union/discriminant is used to choose between internal structural representations.

MODE PERSON = STRUCT(
STRING name,
REAL age,
REAL weight,
UNION (
STRUCT (REAL beard length),
VOID
) gender details
);

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.

AmigaE[edit]

OBJECT point
x, y
ENDOBJECT
 
PROC main()
DEF pt:PTR TO point,
 
NEW pt
-> Floats are also stored as integer types making
-> the float conversion operator necessary.
pt.x := !10.4
pt.y := !3.14
END pt
ENDPROC

AutoHotkey[edit]

Works with: AutoHotkey_L

monkeypatched example.

point := Object()
point.x := 1
point.y := 0
 

AWK[edit]

As usual, arrays are the only data type more complex than a number or a string.
Use quotes around constant strings as element selectors:

BEGIN {
p["x"]=10
p["y"]=42
 
z = "ZZ"
p[ z ]=999
 
p[ 4 ]=5
 
for (i in p) print( i, ":", p[i] )
}
Output:
4 : 5
x : 10
y : 42
ZZ : 999

Axe[edit]

Axe does not have language support for custom data structures. However, they can be implemented from scratch using memory directly.

Lbl POINT
r₂→{r₁}ʳ
r₃→{r₁+2}ʳ
r₁
Return

To initialize a POINT at memory address L₁ with (x, y) = (5, 10):

POINT(L₁,5,10)

The caller must ensure the buffer has enough free space to contain the object (in this case, 4 bytes).

BASIC[edit]

Works with: QBasic
Works with: PowerBASIC
TYPE Point
x AS INTEGER
y AS INTEGER
END TYPE

BBC BASIC[edit]

      DIM Point{x%, y%}

Bracmat[edit]

Normally, values are compounded by putting them in a tree structure. For examples, the values 3 and 4 can be put in a small tree (3.4). But since the task requires the values to be independent, the values must be changeable, which they are not in (3.4). So we go object oriented and create a 'type' Point. We show that x and y are independent by changing the value of x and checking that y didn't change. Bracmat does not have other typing systems than duck typing. The variable Point is not a class, but an object in its own right. The new$ function creates a copy of Point.

( ( Point
= (x=)
(y=)
(new=.!arg:(?(its.x).?(its.y)))
)
& new$(Point,(3.4)):?pt
& out$(!(pt..x) !(pt..y))
{ Show independcy by changing x, but not y }
& 7:?(pt..x)
& out$(!(pt..x) !(pt..y))
);
Output:
3 4
7 4

Brlcad[edit]

In brlcad, the datatypes are geometric primitives or combinations. Here we create a lamp using a combination of previously created components:

c lamp base stem bulb shade chord plug

C[edit]

typedef struct Point
{
int x;
int y;
} Point;

C#[edit]

struct Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}

C++[edit]

struct Point
{
int x;
int y;
};

It is also possible to add a constructor (this allows the use of Point(x, y) in expressions):

struct Point
{
int x;
int y;
Point(int ax, int ay): x(ax), y(ax) {}
};

Point can also be parametrized on the coordinate type:

template<typename Coordinate> struct point
{
Coordinate x, y;
};
 
// A point with integer coordinates
Point<int> point1 = { 3, 5 };
 
// a point with floating point coordinates
Point<float> point2 = { 1.7, 3.6 };

Of course, a constructor can be added in this case as well.

Clean[edit]

Record type[edit]

:: Point = { x :: Int, y :: Int }

Parameterized Algebraic type[edit]

:: Point a = Point a a  // usage: (Point Int)

Synonym type[edit]

:: Point :== (Int, Int)

Clojure[edit]

(defrecord Point [x y])

This defines a datatype with constructor Point. and accessors :x and :y :

(def p (Point. 0 1))
(assert (= 0 (:x p)))
(assert (= 1 (:y p)))

CoffeeScript[edit]

 
# Lightweight JS objects (with CS sugar).
point =
x: 5
y: 3
 
console.log point.x, point.y # 5 3
 
# Heavier OO style
class Point
constructor: (@x, @y) ->
distance_from: (p2) ->
dx = p2.x - @x
dy = p2.y - @y
Math.sqrt dx*dx + dy*dy
 
p1 = new Point(1, 6)
p2 = new Point(6, 18)
console.log p1 # { x: 1, y: 6 }
console.log p1.distance_from # [Function]
console.log p1.distance_from p2 # 13
 

Common Lisp[edit]

CL-USER> (defstruct point (x 0) (y 0))  ;If not provided, x or y default to 0
POINT

In addition to defining the point data type, the defstruct macro also created constructor and accessor functions:

CL-USER> (setf a (make-point))          ;The default constructor using the default values for x and y
#S(POINT :X 0 :Y 0)
CL-USER> (setf b (make-point :x 5.5 :y #C(0 1))) ;Dynamic datatypes are the default
#S(POINT :X 5.5 :Y #C(0 1)) ;y has been set to the imaginary number i (using the Common Lisp complex number data type)
CL-USER> (point-x b) ;The default name for the accessor functions is structname-slotname
5.5
CL-USER> (point-y b)
#C(0 1)
CL-USER> (setf (point-y b) 3) ;The accessor is setfable
3
CL-USER> (point-y b)
3

D[edit]

void main() {
// A normal POD struct
// (if it's nested and it's not static then it has a hidden
// field that points to the enclosing function):
static struct Point {
int x, y;
}
 
auto p1 = Point(10, 20);
 
// It can also be parametrized on the coordinate type:
static struct Pair(T) {
T x, y;
}
 
// A pair with integer coordinates:
auto p2 = Pair!int(3, 5);
 
// A pair with floating point coordinates:
auto p3 = Pair!double(3, 5);
 
// Classes (static inner):
static class PointClass {
int x, y;
this(int x_, int y_) {
this.x = x_;
this.y = y_;
}
}
 
auto p4 = new PointClass(1, 2);
 
// There are also library-defined tuples:
import std.typecons;
 
alias Tuple!(int,"x", int,"y") PointXY;
 
auto p5 = PointXY(3, 5);
 
// And even built-in "type tuples":
import std.typetuple;
 
alias TypeTuple!(int, 5) p6;
 
static assert(is(p6[0] == int));
static assert(p6[1] == 5);
}

Delphi[edit]

As defined in Types.pas:

  TPoint = record
X: Longint;
Y: Longint;
end;
 

E[edit]

def makePoint(x, y) {
def point {
to getX() { return x }
to getY() { return y }
}
return point
}

EchoLisp[edit]

 
(lib 'struct)
(struct Point (x y))
(Point 3 4)
→ #<Point> (3 4)
 
;; run-time type checking is possible
(lib 'types)
(struct Point (x y))
(struct-type Point Number Number)
(Point 3 4)
(Point 3 'albert)
❌ error: #number? : type-check failure : albert → 'Point:y'
 

Ela[edit]

Ela supports algebraic types:

type Maybe = None | Some a

Except of regular algebraic types, Ela also provides a support for open algebraic types - which can be extended any time with new constructors:

opentype Several = One | Two | Three
 
//Add new constructor to an existing type
data Several = Four

Elixir[edit]

iex(1)> defmodule Point do
...(1)> defstruct x: 0, y: 0
...(1)> end
{:module, Point, <<70, 79, 82, ...>>, %Point{x: 0, y: 0}}
iex(2)> origin = %Point{}
%Point{x: 0, y: 0}
iex(3)> pa = %Point{x: 10, y: 20}
%Point{x: 10, y: 20}
iex(4)> pa.x
10
iex(5)> %Point{pa | y: 30}
%Point{x: 10, y: 30}
iex(6)> %Point{x: px, y: py} = pa # pattern matching
%Point{x: 10, y: 20}
iex(7)> px
10
iex(8)> py
20

Erlang[edit]

 
-module(records_test).
-compile(export_all).
 
-record(point,{x,y}).
 
test() ->
P1 = #point{x=1.0,y=2.0}, % creates a new point record
io:fwrite("X: ~f, Y: ~f~n",[P1#point.x,P1#point.y]),
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]).
 

Euphoria[edit]

Works with: OpenEuphoria
 
enum x, y
 
sequence point = {0,0}
 
printf(1,"x = %d, y = %3.3f\n",point)
 
point[x] = 'A'
point[y] = 53.42
 
printf(1,"x = %d, y = %3.3f\n",point)
printf(1,"x = %s, y = %3.3f\n",point)
 
Output:
x = 0, y = 0.000
x = 65, y = 53.420
x = A, y = 53.420

F#[edit]

See the OCaml section as well. Here we create a list of points and print them out.

type Point = { x : int; y : int }
 
let points = [
{x = 1; y = 1};
{x = 5; y = 5} ]
 
Seq.iter (fun p -> printfn "%d,%d" p.x p.y) points

Factor[edit]

TUPLE: point x y ;

Fantom[edit]

 
// define a class to contain the two fields
// accessors to get/set the field values are automatically generated
class Point
{
Int x
Int y
}
 
class Main
{
public static Void main ()
{
// empty constructor, so x,y set to 0
point1 := Point()
// constructor uses with-block, to initialise values
point2 := Point { x = 1; y = 2}
echo ("Point 1 = (" + point1.x + ", " + point1.y + ")")
echo ("Point 2 = (" + point2.x + ", " + point2.y + ")")
}
}
 
Output:
Point 1 = (0, 0)
Point 2 = (1, 2)

Forth[edit]

There is no standard structure syntax in Forth, but it is easy to define words for creating and accessing data structures.

: pt>x ( point -- x ) ;
: pt>y ( point -- y ) CELL+ ;
: .pt ( point -- ) dup pt>x @ . pt>y @ . ; \ or for this simple structure, 2@ . .
 
create point 6 , 0 ,
7 point pt>y !
.pt \ 6 7
Works with: GNU Forth version 0.6.2

Some Forths have mechanisms for declaring complex structures. For example, GNU Forth uses this syntax:

struct
cell% field pt>x
cell% field pt>y
end-struct point%

Fortran[edit]

In ISO Fortran 90 or later, use a TYPE declaration, "constructor" syntax, and field delimiter syntax:

program typedemo
type rational ! Type declaration
integer :: numerator
integer :: denominator
end type rational
 
type( rational ), parameter :: zero = rational( 0, 1 ) ! Variables initialized
type( rational ), parameter :: one = rational( 1, 1 ) ! by constructor syntax
type( rational ), parameter :: half = rational( 1, 2 )
integer :: n, halfd, halfn
type( rational ) :: &
one_over_n(20) = (/ (rational( 1, n ), n = 1, 20) /) ! Array initialized with
! constructor inside
! implied-do array initializer
integer :: oon_denoms(20)
 
halfd = half%denominator ! field access with "%" delimiter
halfn = half%numerator
 
oon_denoms = one_over_n%denominator ! Access denominator field in every
! rational array element & store
end program typedemo ! as integer array

Go[edit]

package main
 
import "fmt"
 
type point struct {
x, y float64
}
 
func main() {
fmt.Println(point{3, 4})
}

Groovy[edit]

Declaration[edit]

class Point {
int x
int y
 
// Default values make this a 0-, 1-, and 2-argument constructor
Point(int x = 0, int y = 0) { this.x = x; this.y = y }
String toString() { "{x:${x}, y:${y}}" }
}

Instantiation[edit]

Direct[edit]
// Default Construction with explicit property setting:
def p0 = new Point()
assert 0 == p0.x
assert 0 == p0.y
p0.x = 36
p0.y = -2
assert 36 == p0.x
assert -2 == p0.y
 
// Direct Construction:
def p1 = new Point(36, -2)
assert 36 == p1.x
assert -2 == p1.y
 
def p2 = new Point(36)
assert 36 == p2.x
assert 0 == p2.y
List-to-argument Substitution[edit]

There are several ways that a List can be substituted for constructor arguments via "type coercion" (casting).

// Explicit coersion from list with "as" keyword
def p4 = [36, -2] as Point
assert 36 == p4.x
assert -2 == p4.y
 
// Explicit coersion from list with Java/C-style casting
p4 = (Point) [36, -2]
println p4
assert 36 == p4.x
assert -2 == p4.y
 
// Implicit coercion from list (by type of variable)
Point p6 = [36, -2]
assert 36 == p6.x
assert -2 == p6.y
 
Point p8 = [36]
assert 36 == p8.x
assert 0 == p8.y
Map-to-property Substitution[edit]

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.

// Direct map-based construction
def p3 = new Point([x: 36, y: -2])
assert 36 == p3.x
assert -2 == p3.y
 
// Direct map-entry-based construction
p3 = new Point(x: 36, y: -2)
assert 36 == p3.x
assert -2 == p3.y
 
p3 = new Point(x: 36)
assert 36 == p3.x
assert 0 == p3.y
 
p3 = new Point(y: -2)
assert 0 == p3.x
assert -2 == p3.y
 
// Explicit coercion from map with "as" keyword
def p5 = [x: 36, y: -2] as Point
assert 36 == p5.x
assert -2 == p5.y
 
// Implicit coercion from map (by type of variable)
Point p7 = [x: 36, y: -2]
assert 36 == p7.x
assert -2 == p7.y
 
Point p9 = [y:-2]
assert 0 == p9.x
assert -2 == p9.y

Haskell[edit]

Algebraic Data Type[edit]

See algebraic data type. The different options ("Empty", "Leaf", "Node") are called constructors, and is associated with 0 or more arguments with the declared types.

 data Tree = Empty
           | Leaf Int
           | Node Tree Tree
 deriving (Eq, Show)
 
 t1 = Node (Leaf 1) (Node (Leaf 2) (Leaf 3))

Tagged Type[edit]

This is a special case of the algebraic data type above with only one constructor.

 data Point = Point Integer Integer
 instance Show Point where
     show (Point x y) = "("++(show x)++","++(show y)++")"
 p = Point 6 7

Record Type[edit]

Entries in an algebraic data type constructor can be given field names.

data Point = Point { x :: Integer, y :: Integer } 
deriving (Eq, Show)

The deriving clause here provides default instances for equality and conversion to string.

Different equivalent ways of constructing a point:

p  = Point 2 3
p' = Point { x=4, y=5 }

The field name is also a function that extracts the field value out of the record

x p' -- evaluates to 4

Tuple Type[edit]

You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first:

p = (2,3)

The type of p is (Int, Int), using the same comma-delimited list syntax as the literal.

Discriminated Type[edit]

Just an algebraic data type with multiple constructors being records

data Person =
    Male   { name :: String, age :: Integer, weight :: Double, 
             beard_length :: Double }
  | Female { name :: String, age :: Integer, weight :: Double }
  deriving (Eq, Show)

Note that the field names may be identical in alternatives.

Icon and Unicon[edit]

record Point(x,y)

IDL[edit]

point = {x: 6 , y: 0 } 
point.y = 7
print, point
;=> { 6 7}


J[edit]

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:

   NB.  Create a "Point" class
coclass'Point'
 
NB. Define its constuctor
create =: 3 : 0
'X Y' =: y
)
 
NB. Instantiate an instance (i.e. an object)
cocurrent 'base'
P =: 10 20 conew 'Point'
 
NB. Interrogate its members
X__P
10
Y__P
20

Java[edit]

We use a class:

public class Point
{
public int x, y;
public Point() { this(0); }
public Point(int x0) { this(x0,0); }
public Point(int x0, int y0) { x = x0; y = y0; }
 
public static void main(String args[])
{
Point point = new Point(1,2);
System.out.println("x = " + point.x );
System.out.println("y = " + point.y );
}
}

JavaScript[edit]

//using object literal syntax
var point = {x : 1, y : 2};
 
//using constructor
var Point = function (x, y) {
this.x = x;
this.y = y;
};
point = new Point(1, 2);
 
//using ES6 class syntax
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
point = new Point(1, 2);

jq[edit]

{"x":1, "y":2}

If the emphasis in the task description is on "type", then an alternative approach would be to include a "type" key, e.g.

{"x":1, "y":2, type: "Point"}

Using this approach, one can distinguish between objects of type "Point" and those that happen to have keys named "x" and "y".

JSON[edit]

{"x":1,"y":2}

Julia[edit]

Define the type

 
type Point{T<:Real}
x::T
y::T
end
 

The components of Point can be any sort of real number, though they do have to be of the same type.

Define a few simple operations for Point

 
==(u::Point, v::Point) = (u.x == v.x) & (u.y == v.y)
-(u::Point) = Point(-u.x, -u.y)
+(u::Point, v::Point) = Point(u.x + v.x, u.y + v.y)
-(u::Point, v::Point) = Point(u.x - v.x, u.y - v.y)
 

Have fun

 
a = Point(1, 2)
b = Point(3, 7)
c = Point(2, 4)
 
println("a = ", a)
println("b = ", b)
println("c = ", c)
 
println("a + b = ", a+b)
println("-a + b = ", -a+b)
println("a - b = ", a-b)
println("a + b + c = ", a+b+c)
println("a == c ", a == c)
println("a + a == c ", a + a == c)
 
Output:
a = Point{Int64}(1,2)
b = Point{Int64}(3,7)
c = Point{Int64}(2,4)
a + b =     Point{Int64}(4,9)
-a + b =    Point{Int64}(2,5)
a - b =     Point{Int64}(-2,-5)
a + b + c = Point{Int64}(6,13)
a == c      false
a + a == c  true

KonsolScript[edit]

Var:Create(
Point,
Number x,
Number y
)

Instanciate it with...

function main() {
Var:Point point;
}

Lasso[edit]

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:

define Point => type {
parent pair
 
public onCreate(x,y) => {
..onCreate(#x=#y)
}
 
public x => .first
public y => .second
}
 
local(point) = Point(33, 42)
#point->x
#point->y
Output:
33
43

LFE[edit]

Simply define a record in the LFE REPL (can also be used in include files, modules, etc.):

 
(defrecord point
x
y)
 

Creating points:

> (make-point x 0 y 0)
#(point 0 0)
> (set p (make-point x 1.1 y -4.2))
#(point 1.1 -4.2)

Accessing:

> (point-x p)
1.1
> (point-y p)
-4.2

Updates (note that since LFE has no mutable data, persisted updates would need to rebind the new value to the old variable name):

> (set-point-x p 3.1)
#(point 3.1 -4.2)
> (set-point-y p 4.2)
#(point 1.1 4.2)

Metadata, etc.:

> (fields-point)
(x y)
> (is-point #(x y))
false
> (is-point p)
true

[edit]

In Logo, a point is represented by a list of two numbers. For example, this will draw a triangle:

setpos [100 100] setpos [100 0] setpos [0 0]
show pos  ; [0 0]

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:

until [(first mousepos) < 0] [ifelse button? [pendown] [penup]  setpos mousepos]

Lua[edit]

Simple Table[edit]

Lua could use a simple table to store a compound data type Point(x, y):

 
a = {x = 1; y = 2}
b = {x = 3; y = 4}
c = {
x = a.x + b.x;
y = a.y + b.y
}
print(a.x, a.y) --> 1 2
print(c.x, c.y) --> 4 6
 

Prototype Object[edit]

Furthermore, Lua could create a prototype object (OOP class emulation) to represent a compound data type Point(x, y) as the following:

 
cPoint = {} -- metatable (behaviour table)
function newPoint(x, y) -- constructor
local pointPrototype = {} -- prototype declaration
function pointPrototype:getX() return x end -- public method
function pointPrototype:getY() return y end -- public method
function pointPrototype:getXY() return x, y end -- public method
function pointPrototype:type() return "point" end -- public method
return setmetatable(pointPrototype, cPoint) -- set behaviour and return the pointPrototype
end--newPoint
 

In the above example, the methods are declared inside the constructor so that they could access the closured values x and y (see usage example). The pointPrototype:type method could be used to extend the original type function available in Lua:

 
local oldtype = type; -- store original type function
function type(v)
local vType = oldtype(v)
if (vType=="table" and v.type) then
return v:type() -- bypass original type function if possible
else
return vType
end--if vType=="table"
end--type
 

The usage of metatable cPoint which stores the behavior of the pointPrototype enables additional behaviour to be added to the data type, such as:

 
function cPoint.__add(op1, op2) -- add the x and y components
if type(op1)=="point" and type(op2)=="point" then
return newPoint(
op1:getX()+op2:getX(),
op1:getY()+op2:getY())
end--if type(op1)
end--cPoint.__add
function cPoint.__sub(op1, op2) -- subtract the x and y components
if (type(op1)=="point" and type(op2)=="point") then
return newPoint(
op1:getX()-op2:getX(),
op1:getY()-op2:getY())
end--if type(op1)
end--cPoint.__sub
 

Usage example:

 
a = newPoint(1, 2)
b = newPoint(3, 4)
c = a + b -- using __add behaviour
print(a:getXY()) --> 1 2
print(type(a)) --> point
print(c:getXY()) --> 4 6
print((a-b):getXY()) --> -2 -2 -- using __sub behaviour
 

Mathematica / Wolfram Language[edit]

Expressions like point[x, y] can be used without defining.

In[1]:= a = point[2, 3]
 
Out[1]= point[2, 3]
 
In[2]:= a[[2]]
 
Out[2]= 3
 
In[3]:= a[[2]] = 4; a
 
Out[3]= point[2, 4]

Or you can just define a function.

p[x] = 2; p[y] = 3;

Data will be stored as down values of the symbol p.

MATLAB / Octave[edit]

 point.x=3;
point.y=4;

Alternatively, coordinates can be also stored as vectors

 point = [3,4];


Maxima[edit]

defstruct(point(x, y))$
 
p: new(point)$
 
q: point(1, 2)$
 
[email protected]: 5$

MAXScript[edit]

Point is a built-in object type in MAX, so...

struct myPoint (x, y)
newPoint = myPoint x:3 y:4

In practice however, you'd use MAX's built in Point2 type

newPoint = Point2 3 4

Modula-2[edit]

TYPE Point = RECORD
x, y : INTEGER
END;

Usage:

VAR    point   : Point;
...
point.x := 12;
point.y := 7;

Modula-3[edit]

TYPE Point = RECORD
x, y: INTEGER;
END;

Usage:

VAR point: Point;
...
point := Point{3, 4};

or

point := Point{x := 3, y := 4};

NetRexx[edit]

Like Java, NetRexx uses the class instruction to create compound types. Unlike Java; NetRexx provides keywords to automatically generate getters and setters for class properties and will automatically generate intermediate methods based on defaults provided in method prototypes.

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
class RCompoundDataType
method main(args = String[]) public static
pp = Point(2, 4)
say pp
return
 
class RCompoundDataType.Point -- inner class "Point"
properties indirect -- have NetRexx create getters & setters
x = Integer
y = Integer
 
method Point(x_ = 0, y_ = 0) public -- providing default values for x_ & y_ lets NetRexx generate intermediate constructors Point() & Point(x_)
this.x = Integer(x_)
this.y = Integer(y_)
return
 
method toString() public returns String
res = 'X='getX()',Y='getY()
return res
 
Output:
X=2,Y=4

Nim[edit]

type Point = tuple[x, y: int]
 
var p: Point = (12, 13)
var p2: Point = (x: 100, y: 200)

Objeck[edit]

Classes are used for compound data types.

 
class Point {
@x : Int;
@y : Int;
 
New() {
@x := 0;
@y := 0;
}
 
New(x : Int, y : Int) {
@x := x;
@y := y;
}
 
New(p : Point) {
@x := p->GetX();
@y := p->GetY();
}
 
method : public : GetX() ~ Int {
return @x;
}
 
method : public : GetY() ~ Int {
return @y;
}
 
method : public : SetX(x : Int) ~ Nil {
@x := x;
}
 
method : public : SetY(y : Int) ~ Nil {
@y := y;
}
}
 

OCaml[edit]

Algebraic Data Type[edit]

See 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.

type tree = Empty
| Leaf of int
| Node of tree * tree
 
let t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))

Record Type[edit]

type point = { x : int; y : int }

How to construct a point:

let p = { x = 4; y = 5 }

You can use the dot (".") to access fields.

p.x (* evaluates to 4 *)

Fields can be optionally declared to be mutable:

type mutable_point = { mutable x2 : int; mutable y2 : int }

Then they can be assigned using the assignment operator "<-"

let p2 = { x2 = 4; y2 = 5 } in
p2.x2 <- 6;
p2 (* evaluates to { x2 = 6; y2 = 5 } *)

Tuple Type[edit]

You can make a tuple literal by using a comma-delimited list, optionally surrounded by parentheses, without needing to declare the type first:

let p = (2,3)

The type of p is a product (indicated by *) of the types of the components:

# let p = (2,3);;
val p : int * int = (2, 3)

Oforth[edit]

Using a class :

Object Class new: Point(x, y)

ooRexx[edit]

ooRexx uses class for compound data types.

 
p = .point~new(3,4)
say "x =" p~x
say "y =" p~y
 
::class point
::method init
expose x y
use strict arg x = 0, y = 0 -- defaults to 0 for any non-specified coordinates
 
::attribute x
::attribute y
 

OpenEdge/Progress[edit]

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.

DEF TEMP-TABLE point
FIELD X AS INT
FIELD Y AS INT
.

Another option would be a simple class.

OxygenBasic[edit]

 
'SHORT FORM
type point float x,y
 
'FULL FORM
type point
float x
float y
end type
 

Oz[edit]

A point can be represented by using a record value:

P = point(x:1 y:2)

Now we can access the components by name: P.x and P.y Often such values are deconstructed by pattern matching:

case P of point(x:X y:Y) then
{Show X}
{Show Y}
end

PARI/GP[edit]

point.x=1;
point.y=2;

Pascal[edit]

type point = record
x, y: integer;
end;

Perl[edit]

Array[edit]

my @point = (3, 8);

Hash[edit]

my %point = (
x => 3,
y => 8
);

Class instance[edit]

package Point;
 
use strict;
use base 'Class::Struct'
x => '$',
y => '$',
;
 
my $point = Point->new(x => 3, y => 8);

Perl 6[edit]

Works with: Rakudo version #24 "Seoul"

Array[edit]

my @point = 3, 8;

Hash[edit]

my %point = x => 3, y => 8;

Class instance[edit]

class Point { has $.x is rw; has $.y is rw; }
my Point $point .= new(x => 3, y => 8);

Set[edit]

my $s1 = set <a b c d>; # order is not preserved
my $s2 = set <c d e f>;
say $s1 (&) $s2; # OUTPUT«set(c, e)»
say $s1$s2; # we also do Unicode

Phix[edit]

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.

enum x,y
type point(object p)
return sequence(p) and length(p)=y and atom(p[x]) and atom(p[y])
end type
 
point p = {175,3.375}
 
p[x] -= p[y]*20
 
puts(1,"point p is ")
?p
printf(1,"p[x]:%g, p[y]:%g\n",{p[x],p[y]})
 
p[x] = 0 -- fine
p[y] = "string" -- run-time error
Output:
point p is {107.5,3.375}
p[x]:107.5, p[y]:3.375
C:\Program Files (x86)\Phix\test.exw:15
type check failure, p is {0,"string"}

PHP[edit]

# Using pack/unpack 
$point = pack("ii", 1, 2);
 
$u = unpack("ix/iy", $point);
echo $x;
echo $y;
 
list($x,$y) = unpack("ii", $point);
echo $x;
echo $y;
# Using array
$point = array('x' => 1, 'y' => 2);
 
list($x, $y) = $point;
echo $x, ' ', $y, "\n";
 
# or simply:
echo $point['x'], ' ', $point['y'], "\n";
# Using class
class Point {
function __construct($x, $y) { $this->x = $x; $this->y = $y; }
function __tostring() { return $this->x . ' ' . $this->y . "\n"; }
}
$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.

PicoLisp[edit]

(class +Point)
 
(dm T (X Y)
(=: x X)
(=: y Y) )
 
(setq P (new '(+Point) 3 4))
 
(show P)
Output:
$52717735311266 (+Point)
   y 4
   x 3

PL/I[edit]

 
define structure
1 point,
2 x float,
2 y float;
 
 
 

Pop11[edit]

uses objectclass;
define :class Point;
slot x = 0;
slot y = 0;
enddefine;

PowerShell[edit]

Works with: PowerShell version 5
 
class Point {
[Int]$a
[Int]$b
Point() {
$this.a = 0
$this.b = 0
}
Point([Int]$a, [Int]$b) {
$this.a = $a
$this.b = $b
}
[Int]add() {return $this.a + $this.b}
[Int]mul() {return $this.a * $this.b}
}
$p1 = [Point]::new()
$p2 = [Point]::new(3,2)
$p1.add()
$p2.mul()
 

Output:

0
6

PureBasic[edit]

A basic structure is implemented as;

Structure MyPoint
x.i
y.i
EndStructure

Python[edit]

The simplest way it to use a tuple, or a list if it should be mutable:

X, Y = 0, 1
p = (3, 4)
p = [3, 4]
 
print p[X]

If needed, you can use class:

class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
 
p = Point()
print p.x

One could also simply instantiate a generic object and "monkeypatch" it:

class MyObject(object): pass
point = MyObject()
point.x, point.y = 0, 1
# objects directly instantiated from "object()" cannot be "monkey patched"
# however this can generally be done to it's subclasses

Dictionary[edit]

Mutable. Can add keys (attributes)

pseudo_object = {'x': 1, 'y': 2}


Named Tuples[edit]

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.

>>> from collections import namedtuple
>>> help(namedtuple)
Help on function namedtuple in module collections:
 
namedtuple(typename, field_names, verbose=False)
Returns a new subclass of tuple with named fields.
 
>>> Point = namedtuple('Point', 'x y')
>>> Point.__doc__ # docstring for the new class
'Point(x, y)'
>>> p = Point(11, y=22) # instantiate with positional args or keywords
>>> p[0] + p[1] # indexable like a plain tuple
33
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessable by name
33
>>> d = p._asdict() # convert to a dictionary
>>> d['x']
11
>>> Point(**d) # convert from a dictionary
Point(x=11, y=22)
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Point(x=100, y=22)
 
>>>

R[edit]

R uses the list data type for compound data.

mypoint <- list(x=3.4, y=6.7)
# $x
# [1] 3.4
# $y
# [1] 6.7
mypoint$x # 3.4
 
list(a=1:10, b="abc", c=runif(10), d=list(e=1L, f=TRUE))
# $a
# [1] 1 2 3 4 5 6 7 8 9 10
# $b
# [1] "abc"
# $c
# [1] 0.64862897 0.73669435 0.11138945 0.10408015 0.46843836 0.32351247
# [7] 0.20528914 0.78512472 0.06139691 0.76937113
# $d
# $d$e
# [1] 1
# $d$f
# [1] TRUE

Racket[edit]

The most common method uses structures (similar to records):

 
#lang racket
(struct point (x y))
 

Alternatively, you can define a class:

 
#lang racket
(define point% ; classes are suffixed with % by convention
(class object%
(super-new)
(init-field x y)))
 

REXX[edit]

x= -4.9
y= 1.7
 
point=x y
---or---
x= -4.1
y= 1/4e21
 
point=x y
 
bpoint=point
 
gpoint=5.6 7.3e-12

Ring[edit]

 
see new point {x=10 y=20} class point x y
 

Output

 
x: 10.000000
y: 20.000000
 

Ruby[edit]

Point = Struct.new(:x,:y)
pt = Point.new(6,7)
puts pt.x #=> 6
pt.y = 3
puts pt #=> #<struct Point x=6, y=3>
 
# The other way of accessing
pt = Point[2,3]
puts pt[:x] #=> 2
pt['y'] = 5
puts pt #=> #<struct Point x=2, y=5>
 
pt.each_pair{|member, value| puts "#{member} : #{value}"}
#=> x : 2
#=> y : 5

Rust[edit]

Structs[edit]

There are three kinds of structs in Rust, two of which would be suitable to represent a point.

C-like struct[edit]

 // Defines a generic struct where x and y can be of any type T
struct Point<T> {
x: T,
y: T,
}
fn main() {
let p = Point { x: 1.0, y: 2.5 }; // p is of type Point<f64>
println!("{}, {}", p.x, p.y);
}

Tuple struct[edit]

These are basically just named tuples.

struct Point<T>(T, T);
fn main() {
let p = Point(1.0, 2.5);
println!("{},{}", p.0, p.1);
}

Tuples[edit]

 fn main() {
let p = (0.0, 2.4);
println!("{},{}", p.0, p.1);
}

Scala[edit]

case class Point(x:Int=0, y:Int=0)
 
val p=Point(1,2)
println(p.y) //=> 2

Scheme[edit]

Using SRFI 9:

(define-record-type point
(make-point x y)
point?
(x point-x)
(y point-y))

Seed7[edit]

const type: Point is new struct
var integer: x is 0;
var integer: y is 0;
end struct;

Shen[edit]

(datatype point
X : number; Y : number;
====================
[point X Y] : point;)

Pairs (distinct from cons cells) are also supported, in which case a point would be denoted by (number * number):

(2+) (@p 1 2)
(@p 1 2) : (number * number)

Sidef[edit]

struct Point {x, y};
var point = Point(1, 2);
say point.y; #=> 2

SIMPOL[edit]

The point type is pre-defined in [SIMPOL], so we will call this mypoint.

type mypoint
embed
integer x
integer y
end type

The embed keyword is used here as a toggle to indicate that all following properties are embedded in the type. The other toggle is reference, 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.

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.

type mypoint
embed
integer x
integer y
end type
 
function mypoint.new(mypoint me, integer x, integer y)
me.x = x
me.y = y
end function me

SNOBOL4[edit]

	data('point(x,y)')
p1 = point(10,20)
p2 = point(10,40)
output = "Point 1 (" x(p1) "," y(p1) ")"
output = "Point 2 (" x(p2) "," y(p2) ")"
end

Standard ML[edit]

Algebraic Data Type[edit]

See 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.

datatype tree = Empty
| Leaf of int
| Node of tree * tree
 
val t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))

Tuple Type[edit]

You can make a tuple literal by using a comma-delimited list surrounded by parentheses, without needing to declare the type first:

val p = (2,3)

The type of p is a product (indicated by *) of the types of the components:

- val p = (2,3);
val p = (2,3) : int * int

You can extract elements of the tuple using the #N syntax:

- #2 p;
val it = 3 : int

The #2 above extracts the second field of its argument.

Record Type[edit]

Records are like tuples but with field names.

You can make a record literal by using a comma-delimited list of key = value pairs surrounded by curly braces, without needing to declare the type first:

val p = { x = 4, y = 5 }

The type of p is a comma-delimited list of key:type pairs of the types of the fields:

- val p = { x = 4, y = 5 };
val p = {x=4,y=5} : {x:int, y:int}

You can extract elements of the tuple using the #name syntax:

- #y p;
val it = 5 : int

The #y above extracts the field named "y" of its argument.

Swift[edit]

// Structure
struct Point {
var x:Int
var y:Int
}
 
// Tuple
typealias PointTuple = (Int, Int)
 
// Class
class PointClass {
var x:Int!
var y:Int!
 
init(x:Int, y:Int) {
self.x = x
self.y = y
}
}

Tcl[edit]

This can be done using an associative array:

array set point {x 4 y 5}
set point(y) 7
puts "Point is {$point(x),$point(y)}"
# => Point is {4,7}

Or a dictionary:

Works with: Tcl version 8.5
set point [dict create x 4 y 5]
dict set point y 7
puts "Point is {[dict get $point x],[dict get $point y]}"

Or an object:

Works with: Tcl version 8.6
oo::class create Point {
variable x y
constructor {X Y} {set x $X;set y $Y}
method x {args} {set x {*}$args}
method y {args} {set y {*}$args}
method show {} {return "{$x,$y}"}
}
Point create point 4 5
point y 7
puts "Point is [point show]"

TI-89 BASIC[edit]

TI-89 BASIC does not have user-defined data structures. The specific example of a point is best handled by using the built-in vectors or complex numbers.

TXR[edit]

In TXR Lisp, a structure type can be created:

(defstruct point nil (x 0) (y 0))

If it is okay for the coordinates to be initialized to nil, it can be condensed to:

(defstruct point nil x y)

The nil denotes that a point has no supertype: it doesn't inherit from anything.

This structure type can then be instantiated using the new macro (not the only way):

(new point)         ;; -> #S(point x 0 y 0)
(new point x 1)  ;; -> #S(point x 1 y 0)
(new point x 1 y 1) ;; -> #S(point x 1 y 1)

A structure can support optional by-order-of-arguments ("boa") construction by providing a "boa constructor". The defstruct syntactic sugar does this if a function-like syntax is used in place of the structure name:

(defstruct (point x y) nil (x 0) (y 0))

The existing construction methods continue to work, but in addition, this is now possible:

(new (point 3 4)) -> #S(point x 3 y 4)

Slot access syntax is supported. If variable p holds a point, then p.x designates the x slot, as a syntactic place which can be accessed and stored:

(defun displace-point-destructively (p delta)
(inc p.x delta.x)
(inc p.y delta.y))

UNIX Shell[edit]

Works with: ksh93

ksh93 allows you to define new compound types with the typeset -T command.

typeset -T Point=(
typeset x
typeset y
)
Point p
p.x=1
p.y=2
echo $p
echo ${p.x} ${p.y}
Point q=(x=3 y=4)
echo ${q.x} ${q.y}
Output:
( x=1 y=2 )
1 2
3 4

You can also declare compound variables "on the fly" without using a defined type:

point=()
point.x=5
point.y=6
echo $point
echo ${point.x} ${point.y}
Output:
( x=5 y=6 )
5 6

Ursala[edit]

A record type with two untyped fields named x and y can be declared like this.

point :: x y

A constant instance of the record can be declared like this.

p = point[x: 'foo',y: 'bar']

A function returning a value of this type can be defined like this,

f = point$[x: g,y: h]

where g and h are functions. Then f(p) would evaluate to point[x: g(p),y: h(p)] for a given argument p. Accessing the fields of a record can be done like this.

t = ~x p
u = ~y p

where p is any expression of the defined type. A real application wouldn't be written this way because pairs of values (x,y) are a common idiom.

Vim Script[edit]

One cannot create new data types in Vim Script. A point could be represented by a dictionary:

function MakePoint(x, y)    " 'Constructor'
return {"x": a:x, "y": a:y}
endfunction
 
let p1 = MakePoint(3, 2)
let p2 = MakePoint(-1, -4)
 
echon "Point 1: x = " p1.x ", y = " p1.y "\n"
echon "Point 2: x = " p2.x ", y = " p2.y "\n"
Output:
Point 1: x = 3, y = 2                                                           
Point 2: x = -1, y = -4

Visual Basic .NET[edit]

Simple Structures[edit]

This shows a structure in its simpest form.

Structure Simple_Point
Public X, Y As Integer
End Structure

Immutable Structures[edit]

In Visual Basic, mutable strucutures are difficult to use properly and should only be used when performance measurements warrant it. The rest of the time, immutable structures should be used. Below is the same structure seen before, but in an immutable form.

Structure Immutable_Point
Private m_X As Integer
Private m_Y As Integer
 
Public Sub New(ByVal x As Integer, ByVal y As Integer)
m_X = x
m_Y = y
End Sub
 
Public ReadOnly Property X() As Integer
Get
Return m_X
End Get
End Property
 
Public ReadOnly Property Y() As Integer
Get
Return m_Y
End Get
End Property
 
End Structure

XSLT[edit]

Data types in XSLT are expressed as XML nodes. Members of a node can be either attributes or child nodes. Access to data is via XPath expressions.

Attributes[edit]

Attributes are often used for simple values. This is how a point might be represented in SVG, for example.

<point x="20" y="30"/>
 
<!-- 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>

Children[edit]

More complex, multivariate, and nested data structures can be represented using child nodes.

<circle>
<point>
<x>20</x>
<y>30</y>
</point>
<radius>10</radius>
</circle>
 
<!-- context is a circle node. Children are accessed using a path-like notation (hence the name "XPath"). -->
<fo:block>Circle center = <xsl:value-of select="point/x"/>, <xsl:value-of select="point/y"/></fo:block>

zkl[edit]

The OO solution:

class Point{ var x,y; 
fcn init(x,y){self.x=x.toFloat(); self.y=y.toFloat(); }
fcn toString{ "P(%f,%f)".fmt(x,y) }
fcn __opADD{} //+
//... __opEQ == etc
}
Point(1,2).println() //-->P(1.000000,2.000000)

which can be pretty heavy weight. [read only] lists can work just as well:

point:=T(1,2); points:=( T(1,2), L(3,4) )