Projects/Ink

edit
revisions

what's new
search
help

kiwi


Projects.Ink History

Hide minor edits - Show changes to markup

June 08, 2004, at 09:46 AM by Sébastien -
Changed line 5 from:

See InkCodeScratchBook for my attempts to write interesting Ink code snippets, and InkSyntax for my attempts at writing a syntax reference and grammar for Ink.

to:

Related documents:

Added lines 7-10:
  • InkCodeScratchBook for my attempts to write interesting Ink code snippets
  • InkSyntax for my attempts at writing a syntax reference and grammar for Ink
  • MultiMethods, for a page collecting information on multi methods dispatching
April 30, 2004, at 08:36 AM by Sébastien -
Changed lines 304-308 from:
  • http://lambda.weblogs.com/discuss/msgReader$11988 UML and DSL a small comment by EhudLamm? on an article related to UML and DSL which I find close to the perspective I have in designing Ink.
to:
  • http://lambda.weblogs.com/discuss/msgReader$11988 UML and DSL a small comment by EhudLamm? on an article related to UML and DSL which I find close to the perspective I have in designing Ink.

Here is a very intersting library for Python which allows transparent access to C functions:

  • http://starship.python.net/crew/theller/ctypes/ CTypes, seems like a very straightforward way to use foreign libraries in a Python program. This could be adapted to Ink as well.
April 26, 2004, at 01:29 PM by Sébastien -
Added lines 302-304:

References

  • http://lambda.weblogs.com/discuss/msgReader$11988 UML and DSL a small comment by EhudLamm? on an article related to UML and DSL which I find close to the perspective I have in designing Ink.
April 20, 2004, at 03:13 PM by Sébastien -
Changed line 103 from:
 abstractExpr(1)
to:
 abstractExpr (1)
Changed line 106 from:
 abstractExpr(1,2)
to:
 abstractExpr (1,2)
Changed line 111 from:
 abstractExpr( _, 2 )
to:
 abstractExpr ( _, 2 )
Changed line 114 from:
 abstractExpr( b = 2 )
to:
 abstractExpr ( b = 2 )
April 20, 2004, at 02:31 PM by Sébastien -
Changed line 5 from:

See InkCodeScratchBook for my attemps to write interesting Ink code snippets.

to:

See InkCodeScratchBook for my attempts to write interesting Ink code snippets, and InkSyntax for my attempts at writing a syntax reference and grammar for Ink.

April 14, 2004, at 12:32 PM by Sébastien -
Changed line 5 from:

See ScratchBook? for my attemps to write interesting Ink code snippets.

to:

See InkCodeScratchBook for my attemps to write interesting Ink code snippets.

April 14, 2004, at 12:32 PM by Sébastien -
Added lines 5-6:

See ScratchBook? for my attemps to write interesting Ink code snippets.

April 14, 2004, at 12:31 PM by Sébastien -
Added line 119:

Specifying constraints

Changed line 121 from:

3. Object model

to:

For now, you may wonder what this mechanism is called a template system, as it does not seem to be more than a way to represent blocks of code as primitive types.

Changed line 123 from:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

to:

Ink template system is used to define arguments to any abstract expression, and more specifically for relations. In Ink paradigm, there can be multiple abstract expressions bound to the same relation name. For instance, we could consider the join relation as follows :

Changed lines 125-126 from:

For instance, looking back at our Point class, we could have declared the type as follows:

to:
 relation [a] join [b]:
   ...
Changed lines 128-140 from:
 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )
   relations are (
     add! [p:Point]:
      point := Point create
      point.x = .x
      point.y = .y
      [point]
   )
to:

which would evaluate this way

Changed lines 130-131 from:

Here we can notice two things:

to:
 1 join 2
 --> 12
Changed lines 133-134 from:
  • The left member of the relation add was omitted
  • The .x and .y expressions have an implicit left member, which a value of the current type.
to:
 "Hello" join "World"
  --> "Hello World"
Changed line 136 from:

This notation is stricly equivalent to the form we presented above, it is expanded by the Ink compiler in the same way.

to:

In this case, we see that the join relation is an abstract expression with two arguments, but the same relation produces different results with different concrete arguments.

Changed line 138 from:

2.1 Data encapsulation

to:

So the question is, how to declare a relation, or abstract expression to behave differently according to the given arguments ? This is the purpose of the template system : conditionnaly conretize abstract expression according to a specific logic. This what makes Ink template system a system.

Changed line 140 from:

One of the basic mechanisms required by object-oriented design is encapsulation. Encapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

to:

Abstract expression can be conditionnaly expanded according to constraints. The above cases could be defined as follows :

Changed lines 142-143 from:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

to:
 relation [a:as Number] join [b:as Number]:
   [a * 10 + b ]
Changed lines 145-146 from:

Here is an example of accessors for the upper-left attribute of the Rectangle type:

to:
 relation [a:as String] join [b:as String]:
   [a + " " + b ]
Changed lines 148-152 from:

type Rectangle:

  structure is (
    upper-left: type Point
    lower-right: type Point
  )
to:

The argument templates have now been expanded with a type constraint on every argument.

Changed lines 150-154 from:
  .upper-left access is:
    [.upper-left]

  .upper-left mutate! <p:Point> is:
    .upper-left = p
to:

We could go further and specify different relations depending on the values of certain arguments :

Changed lines 152-153 from:

Now, the data structure attributes can be simply accessed:

to:
  relation [a:as Number, < 10] join [b: as Number, <10]:
    [a * 10 + b]
Changed lines 155-158 from:
 r := Rectangle create
 r.upper-left  = Point create (1, 1)
 r.lower-right = Point create (2, 2)
 print r.lower-right.x
to:
  relation [a:as Number, < 10] join [b: as Number, <100]:
    [a * 100 + b]
Changed lines 158-159 from:
 --> 2
to:
  relation [a:as Number, < 10] join [b: as Number, <1000]:
    [a * 1000 + b]
Changed line 161 from:

2.2 Polymorphism

to:

you can note that it is not required to specify constraints such as b>10 for the second relation, as the relations are evaluated sequentially, in their reverse order of declaration, until one is matched.

Changed line 163 from:

A second important point of object-orientation is polymorphism.

to:

How to determine to order constraints ? Which are more generic, or less generic ?

Deleted line 164:

Polymorphism is handled in two different ways in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

Changed line 166 from:

Polymorphism is then easily realised by specifying constraints on the parameters of a relation. Consider the following examples:

to:
Changed lines 168-169 from:
 [p!:Point] add [p2:Point]:
  p : (.x, .y) = p2 : (.x, .y)
to:

3. Object model

Changed lines 170-171 from:
 [p!:.x Number, .y Number] add [p:.x Number, .y Number]
  p : (.x, .y) = p2 : (.x, .y)
to:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

Changed lines 172-173 from:
 [p!] add [p2]
  p : (.x, .y) = p2 : (.x, .y)
to:

For instance, looking back at our Point class, we could have declared the type as follows:

Changed lines 174-186 from:

The above declarations seem all similar, but only their process is similar: they apply to different types of values.

to:
 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )
   relations are (
     add! [p:Point]:
      point := Point create
      point.x = .x
      point.y = .y
      [point]
   )
Changed lines 188-190 from:
  • First expression only applies to Point values
  • Second expression applies to any value which as x and y attributes of type Number
  • Third expression applies to any values which have x and y attributes.
to:

Here we can notice two things:

Changed lines 190-191 from:

Actually, there is one more constraint for the two last constraints : there must exist a mutator for the x attribute of the left member that accepts the value of the x attribute of the right member, and this is the same for the y attribute.

to:
  • The left member of the relation add was omitted
  • The .x and .y expressions have an implicit left member, which a value of the current type.
Changed line 193 from:

Scoping rules

to:

This notation is stricly equivalent to the form we presented above, it is expanded by the Ink compiler in the same way.

Changed line 195 from:

Design patterns

to:

2.1 Data encapsulation

Changed line 197 from:

Concurrency

to:

One of the basic mechanisms required by object-oriented design is encapsulation. Encapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

Changed line 199 from:

Application operator and template system

to:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

Changed line 201 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Here is an example of accessors for the upper-left attribute of the Rectangle type:

Changed lines 203-207 from:

If we go back to our point addition relation, we see the following block of code:

to:

type Rectangle:

  structure is (
    upper-left: type Point
    lower-right: type Point
  )
Changed lines 209-210 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:
  .upper-left access is:
    [.upper-left]

  .upper-left mutate! <p:Point> is:
    .upper-left = p
Changed line 215 from:

Can be rewritten :

to:

Now, the data structure attributes can be simply accessed:

Changed lines 217-220 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:
 r := Rectangle create
 r.upper-left  = Point create (1, 1)
 r.lower-right = Point create (2, 2)
 print r.lower-right.x
Changed line 222 from:

The application operator is a bit like the shell | operator: you apply the right member of the | to the output of the evaluation of the left member.

to:
 --> 2
Changed line 224 from:

Pattern-Matching

to:

2.2 Polymorphism

Changed line 226 from:

The following examples adds any list that starts with two Number values to the point:

to:

A second important point of object-orientation is polymorphism.

Changed line 228 from:
 relation [p:Point] add ([x:Number], [y:Number], _ )
to:

Polymorphism is handled in two different ways in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

Changed line 230 from:

can also be written:

to:

Polymorphism is then easily realised by specifying constraints on the parameters of a relation. Consider the following examples:

Changed lines 232-233 from:
 relation [p:Point] add ([x,y:Number], _ )
to:
 [p!:Point] add [p2:Point]:
  p : (.x, .y) = p2 : (.x, .y)
Changed lines 235-236 from:

Syntax overview

to:
 [p!:.x Number, .y Number] add [p:.x Number, .y Number]
  p : (.x, .y) = p2 : (.x, .y)
Changed lines 238-239 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:
 [p!] add [p2]
  p : (.x, .y) = p2 : (.x, .y)
Changed line 241 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:

The above declarations seem all similar, but only their process is similar: they apply to different types of values.

Changed lines 243-245 from:

Relation naming convention

to:
  • First expression only applies to Point values
  • Second expression applies to any value which as x and y attributes of type Number
  • Third expression applies to any values which have x and y attributes.
Changed line 247 from:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

to:

Actually, there is one more constraint for the two last constraints : there must exist a mutator for the x attribute of the left member that accepts the value of the x attribute of the right member, and this is the same for the y attribute.

Changed line 249 from:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

to:

Scoping rules

Changed line 251 from:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

to:

Design patterns

Changed line 253 from:

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

to:

Concurrency

Changed line 255 from:

Parameters naming convention

to:

Application operator and template system

Changed line 257 from:

Formal parameters in relations must be suffixed by ! when the given parameter value is mutated. By default, parameters are immutable, unless they are indicated as mutable by the ! suffix.

to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Added lines 259-299:

If we go back to our point addition relation, we see the following block of code:

   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y

Can be rewritten :

   (x, y) : <a> point.a = p1.a + p2.a

The application operator is a bit like the shell | operator: you apply the right member of the | to the output of the evaluation of the left member.

Pattern-Matching

The following examples adds any list that starts with two Number values to the point:

 relation [p:Point] add ([x:Number], [y:Number], _ )

can also be written:

 relation [p:Point] add ([x,y:Number], _ )

Syntax overview

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Relation naming convention

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

Parameters naming convention

Formal parameters in relations must be suffixed by ! when the given parameter value is mutated. By default, parameters are immutable, unless they are indicated as mutable by the ! suffix.

April 14, 2004, at 11:59 AM by Sébastien -
Changed line 40 from:
   return clone
to:
   [clone]
Changed line 42 from:

2. Template system

to:

2. Templating system

Added line 44:

One of the particularities of Ink is to embed within the language itself a simple but effective templating system. In fact, any Ink expression or construct can be either concrete or abstract, which are defined as followed.

Changed line 46 from:

3. Object model

to:

A concrete expression is an expression which can be directly evaluated, without requiring anything else than an evaluation context.

Changed line 48 from:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

to:

An abstract expression cannot be evaluated until some information is given to obtain a concrete form of the abstract expression.

Changed line 50 from:

For instance, looking back at our Point class, we could have declared the type as follows:

to:

Abstract and concrete expressions

Changed lines 52-64 from:
 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )
   relations are (
     add [p:Point]:
      point := Point create
      point.x = .x
      point.y = .y
      [point]
   )
to:

For instance, look at the following expression

Changed line 54 from:

Here we can notice two things:

to:
  1 + 2
Changed lines 56-57 from:
  • The left member of the relation add was omitted
  • The .x and .y expressions have an implicit left member, which a value of the current type.
to:

this is a simple addition, which can be easily computed, here is another form of this expression :

Changed line 58 from:

This notation is stricly equivalent to the form we presented above, it is expanded by the Ink compiler in the same way.

to:
  a + b
Changed line 60 from:

2.1 Data encapsulation

to:

assuming that a = 1 and b = 2, and that both symbols are defined in the evaluation environment, this expression is equivalent to the preceding in this environment, and can be directly evaluated.

Changed line 62 from:

One of the basic mechanisms required by object-oriented design is encapsulation. Encapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

to:

Now, let's consider the following pseudo-code :

Changed line 64 from:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

to:
  f(x,y) = x + y
Changed lines 66-67 from:

Here is an example of accessors for the upper-left attribute of the Rectangle type:

to:

we have defined a function which can do the same operation as the two first expressions, provided it is given the proper arguments :

Changed lines 69-73 from:

type Rectangle:

  structure is (
    upper-left: type Point
    lower-right: type Point
  )
to:
  f(1,2)

this form can be evaluated to a concrete expression, which is 1+2. This was made possible because the function f, which is abstract, required two given values to become concrete.

Changed lines 73-77 from:
  .upper-left access is:
    [.upper-left]

  .upper-left mutate! <p:Point> is:
    .upper-left = p
to:

Consider the following expression

Changed line 75 from:

Now, the data structure attributes can be simply accessed:

to:
 f(1)
Changed lines 77-80 from:
 r := Rectangle create
 r.upper-left  = Point create (1, 1)
 r.lower-right = Point create (2, 2)
 print r.lower-right.x
to:

this expression cannot be evaluated because it is not concrete: we only know that f(1) = 1 + y, but we still lack information about what value the y symbol is bound to, thus f(1) is still an abstract expression.

Changed line 79 from:
 --> 2
to:

Abstract expressions in Ink

Changed line 81 from:

2.2 Polymorphism

to:

Just as we have shown it in the previous introduction, Ink allows to define abstract expression, not only for function declarations, but also for any other expression.

Changed line 83 from:

A second important point of object-orientation is polymorphism.

to:

For instance, the expression

Changed line 85 from:

Polymorphism is handled in two different ways in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

to:
 1 + 2
Changed line 87 from:

Polymorphism is then easily realised by specifying constraints on the parameters of a relation. Consider the following examples:

to:

can be abstracted as

Changed lines 89-90 from:
 [p!:Point] add [p2:Point]:
  p : (.x, .y) = p2 : (.x, .y)
to:
 [a, b]: a + b
Changed lines 91-92 from:
 [p!:.x Number, .y Number] add [p:.x Number, .y Number]
  p : (.x, .y) = p2 : (.x, .y)
to:

which can be useful when the expression grows a little bit bigger

Changed lines 93-94 from:
 [p!] add [p2]
  p : (.x, .y) = p2 : (.x, .y)
to:
 [a, b]: a + b , a + 10 * b
Changed line 95 from:

The above declarations seem all similar, but only their process is similar: they apply to different types of values.

to:

abstract expressions, as any other form of expressions can be assigned to slots:

Changed lines 97-99 from:
  • First expression only applies to Point values
  • Second expression applies to any value which as x and y attributes of type Number
  • Third expression applies to any values which have x and y attributes.
to:
 abstractExpr := [a,b] : a + b
Changed line 99 from:

Actually, there is one more constraint for the two last constraints : there must exist a mutator for the x attribute of the left member that accepts the value of the x attribute of the right member, and this is the same for the y attribute.

to:

abstract expression values can then be made less abstract, or conrete by applying arguments to them :

Changed lines 101-102 from:

Scoping rules

to:
 abstractExpr(1)
 --> [b] : 1 + b
Changed lines 104-105 from:

Design patterns

to:
 abstractExpr(1,2)
 --> 3
Changed line 107 from:

Concurrency

to:

You can also choose which arguments you would like to leave abstract, with the following forms :

Changed lines 109-110 from:

Application operator and template system

to:
 abstractExpr( _, 2 )
 --> [a] : a + 2
Changed lines 112-113 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:
 abstractExpr( b = 2 )
 --> [a] : a + 2
Changed line 115 from:

If we go back to our point addition relation, we see the following block of code:

to:

In the first form we used the _ (underscore) as the explicit declaration for an abstract argument, and specified the value for the second argument. In this case, we explicitely set a as abstract.

Changed lines 117-118 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:

In the second form, we used explicit naming to bind to the symbol b of the abstractExpr argument list the value 2. In this case, a was implicitely left as abstract.

Deleted line 118:

Can be rewritten :

Changed line 120 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:

3. Object model

Changed line 122 from:

The application operator is a bit like the shell | operator: you apply the right member of the | to the output of the evaluation of the left member.

to:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

Changed line 124 from:

Pattern-Matching

to:

For instance, looking back at our Point class, we could have declared the type as follows:

Changed lines 126-138 from:

The following examples adds any list that starts with two Number values to the point:

to:
 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )
   relations are (
     add! [p:Point]:
      point := Point create
      point.x = .x
      point.y = .y
      [point]
   )
Changed line 140 from:
 relation [p:Point] add ([x:Number], [y:Number], _ )
to:

Here we can notice two things:

Changed lines 142-143 from:

can also be written:

to:
  • The left member of the relation add was omitted
  • The .x and .y expressions have an implicit left member, which a value of the current type.
Changed line 145 from:
 relation [p:Point] add ([x,y:Number], _ )
to:

This notation is stricly equivalent to the form we presented above, it is expanded by the Ink compiler in the same way.

Changed line 147 from:

Syntax overview

to:

2.1 Data encapsulation

Changed line 149 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:

One of the basic mechanisms required by object-oriented design is encapsulation. Encapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

Changed line 151 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

Changed line 153 from:

Relation naming convention

to:

Here is an example of accessors for the upper-left attribute of the Rectangle type:

Changed lines 155-159 from:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

to:

type Rectangle:

  structure is (
    upper-left: type Point
    lower-right: type Point
  )
Changed lines 161-165 from:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

to:
  .upper-left access is:
    [.upper-left]

  .upper-left mutate! <p:Point> is:
    .upper-left = p
Changed line 167 from:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

to:

Now, the data structure attributes can be simply accessed:

Changed lines 169-172 from:

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

to:
 r := Rectangle create
 r.upper-left  = Point create (1, 1)
 r.lower-right = Point create (2, 2)
 print r.lower-right.x
Changed line 174 from:

Parameters naming convention

to:
 --> 2
Changed line 176 from:

Formal parameters in relations must be suffixed by ! when the given parameter value is mutated. By default, parameters are immutable, unless they are indicated as mutable by the ! suffix.

to:

2.2 Polymorphism

Added lines 178-251:

A second important point of object-orientation is polymorphism.

Polymorphism is handled in two different ways in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

Polymorphism is then easily realised by specifying constraints on the parameters of a relation. Consider the following examples:

 [p!:Point] add [p2:Point]:
  p : (.x, .y) = p2 : (.x, .y)

 [p!:.x Number, .y Number] add [p:.x Number, .y Number]
  p : (.x, .y) = p2 : (.x, .y)

 [p!] add [p2]
  p : (.x, .y) = p2 : (.x, .y)

The above declarations seem all similar, but only their process is similar: they apply to different types of values.

  • First expression only applies to Point values
  • Second expression applies to any value which as x and y attributes of type Number
  • Third expression applies to any values which have x and y attributes.

Actually, there is one more constraint for the two last constraints : there must exist a mutator for the x attribute of the left member that accepts the value of the x attribute of the right member, and this is the same for the y attribute.

Scoping rules

Design patterns

Concurrency

Application operator and template system

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

If we go back to our point addition relation, we see the following block of code:

   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y

Can be rewritten :

   (x, y) : <a> point.a = p1.a + p2.a

The application operator is a bit like the shell | operator: you apply the right member of the | to the output of the evaluation of the left member.

Pattern-Matching

The following examples adds any list that starts with two Number values to the point:

 relation [p:Point] add ([x:Number], [y:Number], _ )

can also be written:

 relation [p:Point] add ([x,y:Number], _ )

Syntax overview

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Relation naming convention

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

Parameters naming convention

Formal parameters in relations must be suffixed by ! when the given parameter value is mutated. By default, parameters are immutable, unless they are indicated as mutable by the ! suffix.

April 14, 2004, at 11:15 AM by Sébastien -
Changed line 24 from:
 relation <p1:type Point> add <p2:type Point>:
to:
 relation [p1:type Point] add [p2:type Point]:
Changed line 28 from:
   <-- point
to:
   [point]
Changed line 30 from:

This relation creates a new point which x and y values are the addition of the x and y value of both points. Note that the <-- symbol means return (or yield, as we will see later).

to:

This relation creates a new point which x and y values are the addition of the x and y value of both points. Note that the [point] symbol means return point (or yield point, as we will see later).

Changed line 36 from:
 directive <p:type Point> clone :
to:
 directive [p:type Point] clone :
Changed line 42 from:

2. Object model

to:

2. Template system

Deleted line 43:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

Changed line 45 from:

For instance, looking back at our Point class, we could have declared the type as follows:

to:

3. Object model

Added lines 47-50:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

For instance, looking back at our Point class, we could have declared the type as follows:

Changed line 58 from:
     add <p:Point>:
to:
     add [p:Point]:
Changed line 62 from:
      <-- point
to:
      [point]
Changed line 87 from:
    <-- .upper-left
to:
    [.upper-left]
Changed lines 109-110 from:
 <p:Point> add <p2:Point>:
  p : ( .x, .y ) = p2 : ( .x, .y )
to:
 [p!:Point] add [p2:Point]:
  p : (.x, .y) = p2 : (.x, .y)
Changed lines 112-113 from:
 <num?=.x type? Number, .y type? Number, p:num?> add <p2 num?>
  p : ( .x, .y ) = p2 : ( .x, .y )
to:
 [p!:.x Number, .y Number] add [p:.x Number, .y Number]
  p : (.x, .y) = p2 : (.x, .y)
Changed lines 115-116 from:
 <p> add <p2>
  p : ( .x, .y ) = p2 : ( .x, .y )
to:
 [p!] add [p2]
  p : (.x, .y) = p2 : (.x, .y)
Changed line 151 from:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
to:
 relation [p:Point] add ([x:Number], [y:Number], _ )
Deleted line 153:

relation <p:type? Point> add (<x,y:type? Number>, _ )

Added lines 155-156:
 relation [p:Point] add ([x,y:Number], _ )
Added lines 173-176:

Parameters naming convention

Formal parameters in relations must be suffixed by ! when the given parameter value is mutated. By default, parameters are immutable, unless they are indicated as mutable by the ! suffix.

April 14, 2004, at 10:58 AM by Sébastien -
Changed line 30 from:

This relation creates a new point which x and y values are the addition of the x and y value of both points. Note that the <-- symbol means return.

to:

This relation creates a new point which x and y values are the addition of the x and y value of both points. Note that the <-- symbol means return (or yield, as we will see later).

Changed line 36 from:
 directive <p:type Point> clone! :
to:
 directive <p:type Point> clone :
Changed line 71 from:

One of the basic mechanisms required by object-oriented design is encapsulation. Enapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

to:

One of the basic mechanisms required by object-oriented design is encapsulation. Encapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

Changed line 73 from:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

to:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

Changed line 75 from:

Here is an example of accessor with a Rectangle type:

to:

Here is an example of accessors for the upper-left attribute of the Rectangle type:

Changed line 102 from:

Polymorphism is handled in two different way in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

to:

Polymorphism is handled in two different ways in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

April 08, 2004, at 11:22 AM by Sébastien -
Changed line 5 from:

Types and relations

to:

1. Types and relations

Changed line 42 from:

Object-orientation

to:

2. Object model

Changed line 69 from:

Data encapsulation

to:

2.1 Data encapsulation

Changed line 98 from:

Polymorphism

to:

2.2 Polymorphism

Changed line 102 from:

Polymorphism is handled in two different way in Ink. The first one is by explicit typing: you simply express to which specific types a relation will applw. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

to:

Polymorphism is handled in two different way in Ink. The first one is by explicit typing: you simply express to which specific types a relation will apply. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

Changed line 104 from:

Polymorphism is then easily realised by specifying constraints to the parameters of a relation. Consider the following examples:

to:

Polymorphism is then easily realised by specifying constraints on the parameters of a relation. Consider the following examples:

Changed line 115 from:

The above declaration seem similar, but only their process is similar, but they apply to different values.

to:

The above declarations seem all similar, but only their process is similar: they apply to different types of values.

Added line 123:

Scoping rules

Added line 125:

Design patterns

Added line 127:

Concurrency

Changed line 129 from:

Scoping rules

to:

Application operator and template system

Changed line 131 from:

Design patterns

to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Changed line 133 from:

Concurrency

to:

If we go back to our point addition relation, we see the following block of code:

Changed lines 135-136 from:

Application operator and template system

to:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Changed line 138 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Can be rewritten :

Changed line 140 from:

If we go back to our point addition relation, we see the following block of code:

to:
   (x, y) : <a> point.a = p1.a + p2.a
Changed lines 142-143 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:

The application operator is a bit like the shell | operator: you apply the right member of the | to the output of the evaluation of the left member.

Changed line 144 from:

Can be rewritten :

to:

Pattern-Matching

Changed line 146 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:

The following examples adds any list that starts with two Number values to the point:

Changed line 148 from:

Pattern-Matching

to:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
Changed lines 150-151 from:

The following examples adds any list that starts with two Number values to the point:

to:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

Changed line 153 from:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
to:

Syntax overview

Changed lines 155-156 from:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

to:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Changed line 157 from:

Syntax overview

to:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Changed line 159 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:

Relation naming convention

Changed line 161 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

Changed line 163 from:

Relation naming convention

to:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

Changed line 165 from:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

to:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

Changed line 167 from:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

to:

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

Deleted lines 168-171:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

April 06, 2004, at 10:13 AM by Sébastien -
Added line 110:
  p : ( .x, .y ) = p2 : ( .x, .y )
Added lines 112-113:
 <p> add <p2>
  p : ( .x, .y ) = p2 : ( .x, .y )
Added line 115:

The above declaration seem similar, but only their process is similar, but they apply to different values.

Added lines 117-119:
  • First expression only applies to Point values
  • Second expression applies to any value which as x and y attributes of type Number
  • Third expression applies to any values which have x and y attributes.
Changed line 121 from:

Scoping rules

to:

Actually, there is one more constraint for the two last constraints : there must exist a mutator for the x attribute of the left member that accepts the value of the x attribute of the right member, and this is the same for the y attribute.

Deleted line 122:

Design patterns

Deleted line 123:

Concurrency

Deleted line 124:

Application operator and template system

Changed line 126 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Scoping rules

Changed line 128 from:

If we go back to our point addition relation, we see the following block of code:

to:

Design patterns

Changed lines 130-131 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:

Concurrency

Changed line 132 from:

Can be rewritten :

to:

Application operator and template system

Changed line 134 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Changed line 136 from:

Pattern-Matching

to:

If we go back to our point addition relation, we see the following block of code:

Changed lines 138-139 from:

The following examples adds any list that starts with two Number values to the point:

to:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Changed line 141 from:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
to:

Can be rewritten :

Changed lines 143-144 from:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

to:
   (x, y) : <a> point.a = p1.a + p2.a
Changed line 145 from:

Syntax overview

to:

Pattern-Matching

Changed line 147 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:

The following examples adds any list that starts with two Number values to the point:

Changed line 149 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
Changed lines 151-152 from:

Relation naming convention

to:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

Changed line 154 from:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

to:

Syntax overview

Changed line 156 from:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

to:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Changed line 158 from:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

to:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Changed line 160 from:

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

to:

Relation naming convention

Added lines 162-169:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

April 06, 2004, at 10:08 AM by Sébastien -
Changed line 25 from:
   point   := Point create!
to:
   point   := Point create
Changed line 32 from:

You can also note that there is something that looks like an invocation: Point create!. In fact, the create! symbol denotes a directive, which is a specific kind of relation. In our case, the create! directive is a primitive directive, which is note declared in Ink.

to:

You can also note that there is something that looks like an invocation: Point create. In fact, the create symbol denotes a directive, which is a specific kind of relation. In our case, the create directive is a primitive directive, which is note declared in Ink.

Changed line 37 from:
   clone := Point create!
to:
   clone := Point create
Changed line 56 from:
      point := Point create!
to:
      point := Point create
Changed line 83 from:
  .upper-left access! is:
to:
  .upper-left access is:
Added line 89:

Now, the data structure attributes can be simply accessed:

Changed lines 91-94 from:
to:
 r := Rectangle create
 r.upper-left  = Point create (1, 1)
 r.lower-right = Point create (2, 2)
 print r.lower-right.x
Changed line 96 from:

Scoping rules

to:
 --> 2
Changed line 98 from:

Design patterns

to:

Polymorphism

Changed line 100 from:

Concurrency

to:

A second important point of object-orientation is polymorphism.

Changed line 102 from:

Application operator and template system

to:

Polymorphism is handled in two different way in Ink. The first one is by explicit typing: you simply express to which specific types a relation will applw. The other way is by expressing constraints on a value: what structure it should have, which annotations its type should have, and so on.

Changed line 104 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Polymorphism is then easily realised by specifying constraints to the parameters of a relation. Consider the following examples:

Changed lines 106-107 from:

If we go back to our point addition relation, we see the following block of code:

to:
 <p:Point> add <p2:Point>:
  p : ( .x, .y ) = p2 : ( .x, .y )
Changed lines 109-110 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:
 <num?=.x type? Number, .y type? Number, p:num?> add <p2 num?>
Deleted line 110:

Can be rewritten :

Deleted line 111:
   (x, y) : <a> point.a = p1.a + p2.a
Deleted line 112:

Pattern-Matching

Changed line 114 from:

The following examples adds any list that starts with two Number values to the point:

to:

Scoping rules

Changed line 116 from:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
to:

Design patterns

Changed lines 118-119 from:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

to:

Concurrency

Changed line 120 from:

Syntax overview

to:

Application operator and template system

Changed line 122 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Changed line 124 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:

If we go back to our point addition relation, we see the following block of code:

Changed lines 126-127 from:

Relation naming convention

to:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Changed line 129 from:

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

to:

Can be rewritten :

Changed line 131 from:

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

to:
   (x, y) : <a> point.a = p1.a + p2.a
Changed line 133 from:

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

to:

Pattern-Matching

Changed line 135 from:

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

to:

The following examples adds any list that starts with two Number values to the point:

Added lines 137-157:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

Syntax overview

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Relation naming convention

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

April 06, 2004, at 09:44 AM by Sébastien -
Changed line 69 from:

Scoping rules

to:

Data encapsulation

Changed line 71 from:

Design patterns

to:

One of the basic mechanisms required by object-oriented design is encapsulation. Enapsulation means that direct access to an object internal state is forbidden, and always go through a set of accessors. Accessors are interface between the object internal state and the environment.

Changed line 73 from:

Concurrency

to:

Accessors are split between accessors and mutators. An accessor allows to access the value of a part of the object state, while a mutator allows to change this value.

Changed line 75 from:

Application operator and template system

to:

Here is an example of accessor with a Rectangle type:

Changed lines 77-81 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

type Rectangle:

  structure is (
    upper-left: type Point
    lower-right: type Point
  )
Changed lines 83-87 from:

If we go back to our point addition relation, we see the following block of code:

to:
  .upper-left access! is:
    <-- .upper-left

  .upper-left mutate! <p:Point> is:
    .upper-left = p
Deleted lines 88-89:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Changed line 90 from:

Can be rewritten :

to:
Changed line 92 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:

Scoping rules

Changed line 94 from:

Pattern-Matching

to:

Design patterns

Changed line 96 from:

The following examples adds any list that starts with two Number values to the point:

to:

Concurrency

Changed line 98 from:
 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )
to:

Application operator and template system

Changed lines 100-101 from:

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Changed line 102 from:

Syntax overview

to:

If we go back to our point addition relation, we see the following block of code:

Changed lines 104-105 from:

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

to:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Changed line 107 from:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

to:

Can be rewritten :

Added lines 109-135:
   (x, y) : <a> point.a = p1.a + p2.a

Pattern-Matching

The following examples adds any list that starts with two Number values to the point:

 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

Syntax overview

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

Relation naming convention

When a relation does not have any side effect (it is purely functional), it does not need any suffix.

If the relation has a side effects, i.e. it mutates one of the relation members, it must be suffixed by !.

If the relation is a predicate, i.e. it is purely functional and returns a Boolean value, it must be suffixed with ?.

This convention, inspired from Scheme, allow to clearly identify whether invoking a relation will have a side effect or not.

April 06, 2004, at 09:31 AM by Sébastien -
Changed line 28 from:
   return point
to:
   <-- point
Changed line 30 from:

This relation creates a new point which x and y values are the addition of the x and y value of both points.

to:

This relation creates a new point which x and y values are the addition of the x and y value of both points. Note that the <-- symbol means return.

Changed line 54 from:
   relations:
to:
   relations are (
Changed lines 59-60 from:
      return point
to:
      <-- point
   )
Added lines 69-70:

Scoping rules

Added lines 100-102:

Ink syntax was designed to be both clear and flexible, trying to limit the possible ambiguities, trying to enforce the code source presentation to be the most coherent. Ink source code tries to be explicit, clear and clearly differentiate the important structural and semantic elements.

April 06, 2004, at 09:27 AM by Sébastien -
Changed line 42 from:

Application operator and template system

to:

Object-orientation

Changed line 44 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Ink supports object-oriented design. As we presented it, the basic elements of Ink are types and relations. Roughly, types can be considered as classes, and relations as functions that can be bound to classes.

Changed line 46 from:

If we go back to our point addition relation, we see the following block of code:

to:

For instance, looking back at our Point class, we could have declared the type as follows:

Changed lines 48-49 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:
 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )
   relations:
     add <p:Point>:
      point := Point create!
      point.x = .x
      point.y = .y
      return point
Changed line 61 from:

Can be rewritteng :

to:

Here we can notice two things:

Changed lines 63-64 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:
  • The left member of the relation add was omitted
  • The .x and .y expressions have an implicit left member, which a value of the current type.
Changed line 66 from:

Syntax overview

to:

This notation is stricly equivalent to the form we presented above, it is expanded by the Ink compiler in the same way.

Added lines 68-95:

Design patterns

Concurrency

Application operator and template system

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

If we go back to our point addition relation, we see the following block of code:

   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y

Can be rewritten :

   (x, y) : <a> point.a = p1.a + p2.a

Pattern-Matching

The following examples adds any list that starts with two Number values to the point:

 relation <p:type? Point> add ( <x:type? Number>, <y:type? Number>, _ )

can also be written: relation <p:type? Point> add (<x,y:type? Number>, _ )

Syntax overview

April 06, 2004, at 09:15 AM by Sébastien -
Changed line 32 from:

Application operator and template system

to:

You can also note that there is something that looks like an invocation: Point create!. In fact, the create! symbol denotes a directive, which is a specific kind of relation. In our case, the create! directive is a primitive directive, which is note declared in Ink.

Changed line 34 from:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

to:

Here is an example of directive which creates a clone of a point:

Changed lines 36-40 from:

If we go back to our point addition relation, we see the following block of code:

to:
 directive <p:type Point> clone! :
   clone := Point create!
   clone.x = p.x
   clone.y = p.y
   return clone
Changed lines 42-43 from:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
to:

Application operator and template system

Changed line 44 from:

Can be rewritteng :

to:

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

Changed line 46 from:
   (x, y) : <a> point.a = p1.a + p2.a
to:

If we go back to our point addition relation, we see the following block of code:

Changed lines 48-49 from:

Syntax overview

to:
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
Added lines 51-56:

Can be rewritteng :

   (x, y) : <a> point.a = p1.a + p2.a

Syntax overview

April 06, 2004, at 09:07 AM by Sébastien -
Changed lines 18-47 from:

We see here that the type point is declared with the basic and immutable annotations, and that it declares its data structure to be composed of Numbers names x and y.

to:

We see here that the type point is declared with the basic and immutable annotations, and that it declares its data structure to be composed of Numbers names x and y.

Relations are processes that are bound to two values (a value is an instance of type), they are pretty much like (if not equivalent to) generic functions.

For instance, here is a relation related to the Point type:

 relation <p1:type Point> add <p2:type Point>:
   point   := Point create!
   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y
   return point

This relation creates a new point which x and y values are the addition of the x and y value of both points.

Application operator and template system

One of the most important Ink idiom the application operator :. It is the basic way of expressing the program structure.

If we go back to our point addition relation, we see the following block of code:

   point.x  = p1.x + p2.x
   point.y  = p1.y + p2.y

Can be rewritteng :

   (x, y) : <a> point.a = p1.a + p2.a

Syntax overview

Before getting into the depths of Ink, it would be good to have a slight overview of its syntax. Ink syntax shares some common points with Python, Io, Haskell and... ahem... C++ (just for templates, as you will see).

April 06, 2004, at 08:50 AM by Sébastien -
Changed lines 1-18 from:

Describe {{Ink}} here.

to:

The Ink Programming Language

Ink is a relation-based programming language. It is a based on a clear separation between data and processes, is reflective, offers choice between static or dynamic typing, features ddesign by contract and time-constraint programming.

Types and relations

Types and relations are the core concepts of Ink. A type is the formalisation of a data model, which consists in a composition of primitive elements (numbers, strings, lists, etc), which can be annotated with attributes.

For instance, Ink defines the Point type as follows:

 type Point:
   annotations are (basic, immutable)
   structure is (
     x : type Number
     y : type Number
   )

We see here that the type point is declared with the basic and immutable annotations, and that it declares its data structure to be composed of Numbers names x and y.

last modified on September 27, 2005, at 07:35 PM

© type-z.org and its contributing authors, 2001-2004.
Content is licensed under a Creative Commons License.