Jump to content

Citrine (programming language)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Gabordemooij (talk | contribs) at 14:41, 24 January 2016 (Added article Citrine programming language.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
Citrine
Citrine logo
Paradigmobject oriented programming
Designed byGabor de Mooij
DeveloperGabor de Mooij
First appeared2014
Stable release
0.2 / 2014; 11 years ago (2014)
Typing disciplinedynamic
OSUNIX
LicenseBSD
Filename extensionsctr
Websitehttp://citrine-lang.org
Major implementations
C
Influenced by
Smalltalk Self

In computing, Citrine is a general purpose programming language for UNIX-like operating systems. The language focuses on readability and maintainability. Readability is achieved by syntactical and conceptual minimalism. The Citrine programming language is heavily inspired by Smalltalk and Self but has some very distinctive features. Like Smalltalk, the Citrine language treats everything as an object and focuses on sending messages to these objects. However unlike Smalltalk Citrine lacks the concept of a class. In this regard, Citrine is more like Self and Javascript because it uses prototypes. The combination of Smalltalk like messages and prototypes is what makes Citrine unique.

Syntax

Citrine has a very limited syntax and it's very closely related to Smalltalk. Everything in Citrine is an Object, there are 5 literals:

* Nil
* True False
* 0,1,2,3
* 'String'
* { param | ...block of code... }

The code block literal uses a pipe symbol to separate the parameters from the logic '|', if there are no parameters the backslash should be used instead '\'.

Citrine only supports full line comments, comments start with a '#'.

A Citrine program is basically a sequence of messages sent to objects, for instance to calculate the factorial of the number 5 one has to send the message 'factorial' to number 5.

5 factorial.

This is called a unary message becaus it does not take any arguments. A binary message is always a single UTF-8 character (this is different from Smalltalk where there is a fix set of binary messages), here is an example:

6 + 7.

Here a binary message '+' is send to number 6, the argument of this binary message is '7', this will result in a new number object '13'. To assign the outcome of this operation to a variable one uses the assignment operator: :=.

total := money + debt.

Also note that each line in a Citrine program ends with a dot, just like in Smalltalk. Besides unary and binary messages Citrine also offers keyword messages, these messages take arguments interspersed with the message itself just like Smalltalk and Objective-C.

3 between: 1 and: 5.

The code snippet above will return a boolean object True.

Control Flow

Just like Smalltalk, control flow in Citrine is implemented by strategic use of messages. For instance to write a conditional statement, one has to send a block of code to a boolean.

(money >= price) ifTrue: {\ Pen write: 'Yes, you can afford this'. }.

Likewise, a for-loop is written as:

1 to: 10 by: 1 do: { step | Pen write: 'this is step:' + step. }.

Besides for-loops, Citrine features each-loops, while-loops and a simple times loop, the latter uses the binary message '*'.

7 * { step | Pen write: 'this is step:' + step. }.

To break out of a loop in Citrine one has to send the message 'break' to a boolean, this allows a conditional break from a loop without having to factor out the break conditions:

#0-4
0 to: 10 by: 1 do: { i |
	Pen write: 'iteration #' + i, brk.
	(i = 4) break.
}.

Pipelines

Unlike Smalltalk, Citrine has no semi-colon to send a message to the original receiver. Instead Citrine has a comma token ',' used to chain keyword messages, this allows developers to write UNIX-like pipelines. The following code uses a pipeline-like syntax to replace all the 'o' characters with zeroes, the resulting string would be something like: '1010101...'.

onesAndZeroes := '1o1o1o1o1o1' split: 'o', map: mapUp, join: '0'.

Prototypes

The biggest difference from Smalltalk is the use of prototypes. Citrine does not have a concept of a class, it only knows about objects. An object is created using the new message:

cat := Object new.

One can make this object respond to messages by ordering the object to listen to events, this is kind of similar to adding methods in languages like Java:

cat on: 'meow' do: {\ 
  Pen write: 'meow!'.
}.

As has been mentioned in this article, inheritance is based on prototypes. To derive an object from another object one has to send the new message to the object one wishes to extend:

Animal := Object new.
Animal on: 'makeSound' do: {\
	Pen write: '?'.
}.
Cat := Animal new.
Cat on: 'makeSound' do: {\
	Pen write: 'meow!'.
}.
Tom := Cat new.
Tom makeSound.

Unicode

Citrine uses UTF-8 unicode extensively, both objects and messages can consist of unicode symbols. All string length are calculated using UTF-8. Citrine distinguishes string length and size in bytes:

'text' length.

returns the length of the string in UTF-8 code pointes, while:


'text' bytes.

returns the number of bytes.

Scoping

Citrine uses dynamic scoping instead of lexical scoping, this means there is no need for Dependency Injection or global variables. This is similar as in programming language like EMACS Lisp and BASIC.

Demonstration:

Application := {\
   mailer := Mailer new. #make mailer available to all modules
   module run. #mailer is now available in module
}.

See also