Compound data type

From Rosetta Code
Revision as of 18:29, 23 April 2014 by rosettacode>AndiPersti (Omit from bc and dc)
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.

Create a compound data type Point(x,y).

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

See also

ACL2

<lang Lisp>(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</lang>

Output:

((:X . 1) (:Y . 2))
1
((:X . 3) (:Y . 2))
3
T

ActionScript

<lang actionscript>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;
       }
   }

}</lang>

Ada

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. <lang ada>type Point is tagged record

  X : Integer := 0;
  Y : Integer := 0;

end record;</lang>

Record Type

Ada record types are not extensible through inheritance. Without the reserved word tagged the record does not belong to an inheritance hierarchy. <lang ada>type Point is record

  X : Integer := 0;
  Y : Integer := 0;

end record;</lang>

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. <lang ada>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;</lang> 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

Tagged Type

ALGOL 68 has only tagged-union/discriminants. And the tagging was strictly done by the type (MODE) of the members. <lang algol68>MODE UNIONX = UNION(

  STRUCT(REAL r, INT i),
  INT,
  REAL,
  STRUCT(INT ii),
  STRUCT(REAL rr),
  STRUCT([]REAL r)

);</lang> To extract the apropriate member of a UNION a conformity-clause has to be used. <lang algol68>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;</lang> 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

ALGOL 68 record types are not extensible through inheritance but they may be part of a larger STRUCT composition. <lang algol68>MODE POINT = STRUCT(

  INT x,
  INT y

);</lang>

Parameterized Types

An ALGOL 68 record type can contain a tagged-union/discriminant. The tagged-union/discriminant is used to choose between internal structural representations. <lang algol68>MODE PERSON = STRUCT(

  STRING name,
  REAL age,
  REAL weight,
  UNION (
     STRUCT (REAL beard length),
     VOID
  ) gender details

);</lang> 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

<lang amigae>OBJECT point

 x, y

ENDOBJECT

PROC main()

 DEF pt:PTR TO point,
 NEW pt
 pt.x := 10.4
 pt.y := 3.14
 END pt

ENDPROC</lang>

AutoHotkey

Works with: AutoHotkey_L

monkeypatched example.

<lang AutoHotkey>point := Object() point.x := 1 point.y := 0 </lang>

AWK

As usual, arrays are the only data type more complex than a number or a string. Having to use quotes around constant strings as element selectors: <lang awk>p["x"]=10 p["y"]=42</lang>

BASIC

Works with: QBasic
Works with: PowerBASIC

<lang qb>TYPE Point

  x AS INTEGER
  y AS INTEGER
END TYPE</lang>

BBC BASIC

<lang bbcbasic> DIM Point{x%, y%}</lang>

Bracmat

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. <lang Bracmat>( ( 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)) );</lang> Output:

3 4
7 4

Brlcad

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

<lang c>typedef struct Point {

 int x;
 int y;

} Point;</lang>

C++

<lang cpp>struct Point {

 int x;
 int y;

};</lang>

It is also possible to add a constructor (this allows the use of Point(x, y) in expressions): <lang cpp>struct Point {

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

};</lang>

Point can also be parametrized on the coordinate type: <lang cpp>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 };</lang> Of course, a constructor can be added in this case as well.

C#

<lang csharp>struct Point {

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

}</lang>

Clean

Record type

<lang clean>:: Point = { x :: Int, y :: Int }</lang>

Parameterized Algebraic type

<lang clean>:: Point a = Point a a // usage: (Point Int)</lang>

Synonym type

<lang clean>:: Point :== (Int, Int)</lang>

Clojure

<lang clojure>(defrecord Point [x y])</lang> This defines a datatype with constructor Point. and accessors :x and :y : <lang clojure>(def p (Point. 0 1)) (assert (= 0 (:x p))) (assert (= 1 (:y p)))</lang>

CoffeeScript

<lang coffeescript>

  1. Lightweight JS objects (with CS sugar).

point =

 x: 5
 y: 3

console.log point.x, point.y # 5 3

  1. 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 </lang>


Common Lisp

<lang lisp>CL-USER> (defstruct point (x 0) (y 0)) ;If not provided, x or y default to 0 POINT</lang> In addition to defining the point data type, the defstruct macro also created constructor and accessor functions: <lang lisp>CL-USER> (setf a (make-point)) ;The default constructor using the default values for x and y

  1. S(POINT :X 0 :Y 0)

CL-USER> (setf b (make-point :x 5.5 :y #C(0 1))) ;Dynamic datatypes are the default

  1. 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)

  1. C(0 1)

CL-USER> (setf (point-y b) 3) ;The accessor is setfable 3 CL-USER> (point-y b) 3</lang>

D

<lang d>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);

}</lang>

Delphi

As defined in Types.pas:

<lang Delphi> TPoint = record

   X: Longint;
   Y: Longint;
 end;

</lang>

E

<lang e>def makePoint(x, y) {

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

}</lang>

Ela

Ela supports algebraic types:

<lang ela>type Maybe = None | Some a</lang>

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

<lang ela>opentype Several = One | Two | Three

//Add new constructor to an existing type data Several = Four</lang>

Erlang

<lang erlang> -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]).

</lang>

Factor

<lang factor>TUPLE: point x y ;</lang>

Fantom

<lang fantom> // 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 + ")")
 }

} </lang>

Output:

Point 1 = (0, 0)
Point 2 = (1, 2)

Forth

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

<lang forth>: 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</lang>

Works with: GNU Forth version 0.6.2

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

<lang forth>struct

 cell% field pt>x
 cell% field pt>y

end-struct point%</lang>

Fortran

In ISO Fortran 90 or later, use a TYPE declaration, "constructor" syntax, and field delimiter syntax: <lang fortran>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</lang>

F#

See the OCaml section as well. Here we create a list of points and print them out. <lang fsharp>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</lang>

Go

<lang go>package main

import "fmt"

type point struct {

   x, y float64

}

func main() {

   fmt.Println(point{3, 4})

}</lang>

Groovy

Declaration

<lang groovy>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}}" } 

}</lang>

Instantiation

Direct

<lang groovy>// 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</lang>

List-to-argument Substitution

There are several ways that a List can be substituted for constructor arguments via "type coercion" (casting). <lang groovy>// 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</lang>

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. <lang groovy>// 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</lang>

Haskell

Algebraic Data Type

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

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

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

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

<lang haskell>p = (2,3)</lang>

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

Discriminated Type

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

<lang icon>record Point(x,y)</lang>

IDL

<lang idl>point = {x: 6 , y: 0 } point.y = 7 print, point

=> { 6 7}</lang>


J

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:

<lang j> 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</lang>

Java

We use a class: <lang java>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 );
 }

}</lang>

JavaScript

<lang javascript>var point = {x : 1, y : 2};</lang>

JSON

<lang json>{"x":1,"y":2}</lang>

KonsolScript

<lang KonsolScript>Var:Create(

 Point,
   Number x,
   Number y

)</lang>

Instanciate it with... <lang KonsolScript>function main() {

 Var:Point point;

}</lang>


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: <lang lasso>define Point => type {

   parent pair
   public onCreate(x,y) => {
       ..onCreate(#x=#y)
   }
   public x => .first
   public y => .second

}

local(point) = Point(33, 42)

  1. point->x
  2. point->y</lang>
Output:
33
43


In Logo, a point is represented by a list of two numbers. For example, this will draw a triangle: <lang logo>setpos [100 100] setpos [100 0] setpos [0 0] show pos  ; [0 0]</lang> 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: <lang logo>until [(first mousepos) < 0] [ifelse button? [pendown] [penup] setpos mousepos]</lang>

Lua

Simple Table

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

<lang lua> 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 </lang>

Prototype Object

Furthermore, Lua could create a prototype object (OOP class emulation) to represent a compound data type Point(x, y) as the following: <lang lua> 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 </lang>

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:

<lang 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 </lang>

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

<lang lua> 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 </lang>

Usage example:

<lang lua> 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 </lang>

Mathematica

Expressions like point[x, y] can be used without defining. <lang mathematica>In[1]:= a = point[2, 3]

Out[1]= point[2, 3]

In[2]:= a2

Out[2]= 3

In[3]:= a2 = 4; a

Out[3]= point[2, 4]</lang>

Or you can just define a function. <lang mathematica>p[x] = 2; p[y] = 3;</lang> Data will be stored as down values of the symbol p.

MATLAB / Octave

<lang MATLAB> point.x=3;

point.y=4;</lang>

Alternatively, coordinates can be also stored as vectors <lang MATLAB> point = [3,4];</lang>


Maxima

<lang maxima>defstruct(point(x, y))$

p: new(point)$

q: point(1, 2)$

p@x: 5$</lang>

MAXScript

Point is a built-in object type in MAX, so... <lang maxscript>struct myPoint (x, y) newPoint = myPoint x:3 y:4</lang> In practice however, you'd use MAX's built in Point2 type <lang maxscript>newPoint = Point2 3 4</lang>

Modula-2

<lang modula2>TYPE Point = RECORD

 x, y     : INTEGER

END;</lang>

Usage: <lang modula2>VAR point  : Point; ... point.x := 12; point.y := 7;</lang>

Modula-3

<lang modula3>TYPE Point = RECORD

 x, y: INTEGER;

END;</lang>

Usage:

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

or

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

NetRexx

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. <lang NetRexx>/* 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

</lang> Output:

X=2,Y=4

Objeck

Classes are used for compound data types. <lang objeck> 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; 
 }

} </lang>

OCaml

Algebraic Data Type

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.

<lang ocaml>type tree = Empty

         | Leaf of int
         | Node of tree * tree

let t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</lang>

Record Type

<lang ocaml>type point = { x : int; y : int }</lang>

How to construct a point:

<lang ocaml>let p = { x = 4; y = 5 }</lang>

You can use the dot (".") to access fields. <lang ocaml>p.x (* evaluates to 4 *)</lang>

Fields can be optionally declared to be mutable: <lang ocaml>type mutable_point = { mutable x2 : int; mutable y2 : int }</lang>

Then they can be assigned using the assignment operator "<-" <lang ocaml>let p2 = { x2 = 4; y2 = 5 } in

 p2.x2 <- 6;
 p2 (* evaluates to { x2 = 6; y2 = 5 } *)</lang>

Tuple Type

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

<lang ocaml>let p = (2,3)</lang>

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)

ooRexx

ooRexx uses class for compound data types. <lang ooRexx> 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

</lang>

OpenEdge/Progress

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.

<lang Progress (Openedge ABL)>def temp-table point

 field x as int
 field y as int
 .</lang>

Another option would be a simple class.

OxygenBasic

<lang oxygenbasic> 'SHORT FORM type point float x,y

'FULL FORM type point

 float x
 float y

end type </lang>

Oz

A point can be represented by using a record value: <lang oz>P = point(x:1 y:2)</lang>

Now we can access the components by name: P.x and P.y Often such values are deconstructed by pattern matching: <lang oz>case P of point(x:X y:Y) then

  {Show X}
  {Show Y}

end</lang>

PARI/GP

<lang parigp>point.x=1; point.y=2;</lang>

Pascal

<lang pascal>type point = record

             x, y: integer;
            end;</lang>

Perl

Array

<lang perl>my @point = (3, 8);</lang>

Hash

<lang perl>my %point = (

  x => 3,
  y => 8

);</lang>

Class instance

<lang perl>package Point;

use strict; use base 'Class::Struct'

   x => '$',
   y => '$',

my $point = Point->new(x => 3, y => 8);</lang>

Perl 6

Works with: Rakudo version #24 "Seoul"

Array

<lang perl6>my @point = 3, 8;</lang>

Hash

<lang perl6>my %point = x => 3, y => 8;</lang>

Class instance

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

PHP

<lang php># 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;</lang>

<lang php># Using array $point = array('x' => 1, 'y' => 2);

list($x, $y) = $point; echo $x, ' ', $y, "\n";

  1. or simply:

echo $point['x'], ' ', $point['y'], "\n";</lang>

<lang php># 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.</lang>

PicoLisp

<lang PicoLisp>(class +Point)

(dm T (X Y)

  (=: x X)
  (=: y Y) )

(setq P (new '(+Point) 3 4))

(show P)</lang> Output:

$52717735311266 (+Point)
   y 4
   x 3

PL/I

<lang PL/I> define structure

 1 point,
    2 x float,
    2 y float;


</lang>

Pop11

<lang pop11>uses objectclass; define :class Point;

  slot x = 0;
  slot y = 0;

enddefine;</lang>

PureBasic

Basic structuresare implemented as; <lang PureBasic>Structure MyPoint

 X.i
 Y.i

EndStructure</lang>


If needed StructureUnion can be used to optimize the structures <lang PureBasic>Structure MyFileDate

 name.s
 StructureUnion
   Date_as_txt.s
   Date_in_Ticks.l
 EndStructureUnion

EndStructure</lang>

Python

The simplest way it to use a tuple, or a list if it should be mutable: <lang python>X, Y = 0, 1 p = (3, 4) p = [3, 4]

print p[X]</lang>

If needed, you can use class:

<lang python>class Point:

   def __init__(self, x=0, y=0):
       self.x = x
       self.y = y

p = Point() print p.x</lang>

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

<lang python>class MyObject(object): pass point = MyObject() point.x, point.y = 0, 1

  1. objects directly instantiated from "object()" cannot be "monkey patched"
  2. however this can generally be done to it's subclasses</lang>

Dictionary

Mutable. Can add keys (attributes) <lang python>pseudo_object = {'x': 1, 'y': 2}</lang>


Named Tuples

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.

<lang python>>>> 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)

>>></lang>

R

R uses the list data type for compound data. <lang R>mypoint <- list(x=3.4, y=6.7)

  1. $x
  2. [1] 3.4
  3. $y
  4. [1] 6.7

mypoint$x # 3.4

list(a=1:10, b="abc", c=runif(10), d=list(e=1L, f=TRUE))

  1. $a
  2. [1] 1 2 3 4 5 6 7 8 9 10
  3. $b
  4. [1] "abc"
  5. $c
  6. [1] 0.64862897 0.73669435 0.11138945 0.10408015 0.46843836 0.32351247
  7. [7] 0.20528914 0.78512472 0.06139691 0.76937113
  8. $d
  9. $d$e
  10. [1] 1
  11. $d$f
  12. [1] TRUE</lang>

Racket

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

<lang racket>

  1. lang racket

(struct point (x y)) </lang>

Alternatively, you can define a class:

<lang racket>

  1. lang racket

(define point% ; classes are suffixed with % by convention

 (class object%
   (super-new)
   (init-field x y)))

</lang>

REXX

<lang rexx> x= -4.9 y= 1.7

point=x y </lang>

---or---

<lang rexx> x= -4.1 y= 1/4e21

point=x y

bpoint=point

gpoint=5.6 7.3e-12 </lang>

Ruby

<lang ruby>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>

  1. 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</lang>

Scala

<lang scala>case class Point(x:Int=0, y:Int=0)

val p=Point(1,2) println(p.y) //=> 2</lang>

Scheme

Using SRFI 9: <lang scheme>(define-record-type point

   (make-point x y)
   point?
   (x point-x)
   (y point-y))</lang>

Seed7

<lang seed7>const type: Point is new struct

   var integer: x is 0;
   var integer: y is 0;
 end struct;</lang>

SIMPOL

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

<lang simpol>type mypoint

 embed
 integer x
 integer y

end type</lang>

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.

<lang simpol>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</lang>

SNOBOL4

<lang snobol> 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</lang>

Standard ML

Algebraic Data Type

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.

<lang sml>datatype tree = Empty

             | Leaf of int
             | Node of tree * tree

val t1 = Node (Leaf 1, Node (Leaf 2, Leaf 3))</lang>

Tuple Type

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

<lang sml>val p = (2,3)</lang>

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

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:

<lang sml>val p = { x = 4, y = 5 }</lang>

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.

Tcl

This can be done using an associative array: <lang tcl>array set point {x 4 y 5} set point(y) 7 puts "Point is {$point(x),$point(y)}"

  1. => Point is {4,7}</lang>

Or a dictionary:

Works with: Tcl version 8.5

<lang tcl>set point [dict create x 4 y 5] dict set point y 7 puts "Point is {[dict get $point x],[dict get $point y]}"</lang> Or an object:

Works with: Tcl version 8.6

<lang tcl>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]"</lang>

TI-89 BASIC

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.

Ursala

A record type with two untyped fields named x and y can be declared like this. <lang Ursala>point :: x y</lang> A constant instance of the record can be declared like this. <lang Ursala>p = point[x: 'foo',y: 'bar']</lang> A function returning a value of this type can be defined like this, <lang Ursala>f = point$[x: g,y: h]</lang> 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. <lang Ursala>t = ~x p u = ~y p</lang> 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

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

<lang vim>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"</lang>

Output:
Point 1: x = 3, y = 2                                                           
Point 2: x = -1, y = -4

Visual Basic .NET

Simple Structures

This shows a structure in its simpest form.

<lang vbnet>Structure Simple_Point

  Public X, Y As Integer

End Structure</lang>

Immutable Structures

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.

<lang vbnet>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</lang>

XSLT

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

Attributes are often used for simple values. This is how a point might be represented in SVG, for example. <lang xml><point x="20" y="30"/>

<fo:block>Point = <xsl:value-of select="@x"/>, <xsl:value-of select="@y"/></fo:block></lang>

Children

More complex, multivariate, and nested data structures can be represented using child nodes. <lang xml><circle>

 <point>
   <x>20</x>
   <y>30</y>
 </point>
 <radius>10</radius>

</circle>

</lang>

<fo:block>Circle center = <xsl:value-of select="point/x"/>, <xsl:value-of select="point/y"/></fo:block>