Ѧ simple laחguagέ
ഽor ƩveЯyone

Citrine is a universal programming language that can be written in and translated to any human language.

News | API | Why | C-API
☞ f := Lijst ← 0 ; 1.

   ☞ a := f laatste.
   ☞ b := f een-na-laatste.   
   ☞ som := a + b.
   ✎ schrijf: som.

   f erbij: som.

} * 12.
Download Citrine 0.7.12 download citrine

How to translate?

To translate a Citrine program from one language into another:

ctr -t en2nl.dict myprogram.ctr

Dictionaries have the following format:


Use t for tokens and s for strings.
To generate a dictionary from 2 versions of Citrine in different languages:

ctr -g /nl/dictionary.h /en/dictionary.h

In Citrine, everything is an object. You write a program by making these objects talk to each other, by sending messages.

The basics

There are 5 literal objects: Nil, Booleans (True,False), Numbers (i.e. 1,2,3.5,100 and so on), Strings (any text between 'single quotes') and code Blocks: { :parameter1 :parameter2 ...code... }. Every line ends with a dot (.). Assign a value to variable using :=.

☞ x := 3 factorial.
☞ x := 3 factorial factorial.

Here we send the message 'factorial' to 3, the resulting value (6) gets assigned to x (we use the hand for that, the keyword 'var' is also allowed). On the second line we chain two messages (factorial), resulting in x = 720. A keyword message is a message with arguments:

☞ x := 3 between: 1 and: 10.

A message that is just one single symbol (+-/*) is a binary message and always has exactly one argument, the object that follows.

☞ x := 2 + 3.

You can chain keyword messages with a comma (,):

✎ write: 'hello ', write: 'world'.
hello world

Control Flow

To create a loop, send the message 'times:' to a number together with a block of code:

{ :i
  (i > 3) break.
  ✎ write: i.
} * 5.

This will run the block of code 3 times. To break out of a loop, use break. Note that we compare using = not ==.

To create conditional sections of code we use true: or false: like this:

(⛁ ≥ price) true: {
	✎ write: 'Buy'.
}, else: {
	✎ write: 'Too expensive'.

You can catch errors by attaching a catch block to your code:

{  2 / 0. } catch:
{ :error ✎ write: error. }, run.
Division by zero.

You can give a block of code a name:

☞ echo := { :x ↲ (x + x). }.
✎ write: (echo apply: 'hi').

Citrine uses dynamic scoping, the following example prints '2':

☞ f := { q := 2. }.
{ ☞ q := 1. f run. ✎ write: q. } run.


To create your own object and make it respond to messages:

Cat := Object new.
Cat on: 'name:' do: { :n ⚿ name := n. }.
Cat on: 'name' do: { ↲ ⚿ name. }. 

This creates a cat object that responds to 'name:' to change its name and 'name' to tell its name. The object stores its name in a property 'name'. To access a property, use or 'my'. Usage:

cat := Cat new.
cat name: 'Diva'.
✎ write: cat name.

If you want to reuse old code, base your object on a previously crafted one (this is called prototypal inheritance):

RoyalCat := Cat new.
RoyalCat on: 'name' do: { :n
	↲ 'your royal highness ' + ( ⛏ `name ).

Here, we override the behaviour for message 'name' with a new response. The symbol 'plays' back another response from the same object. To reference an overridden one, prefix the message with a backtick (`).

✎ write: ((RoyalCat new name: 'Diva') name).
your royal highness Diva

You can make objects respond to arbitrary messages (generic responses) as well:

echo := Object new.
echo on: 'respondTo:' do: { :s ↲ 2 × :s }.
echo ho!.


Can I change built-in object?

You can modify existing objects (malleable objects), for instance, to make numbers respond to × :

	Number on: '×' do: { :b ⛏ times: b. }.
	7 × { :i ✎ write: i. }.

Where can I find more documentation?

All documentation can be found in the man files. You can also consult the online manual pages.

Why does Citrine use icons in the language?

Citrine simply makes use of the possibilities of utf-8. Icons are more descriptive than abbreviations like 'var', they are quicker to type (once you configured your editor), language agnostic (can be used in Dutch source code as well) and allow more natural looking texts (in case of the thin space vs camelCase).

What's up with the languages?

Citrine can be compiled in different languages. This means the core messages can be English, Dutch, French or Icelandic. This allows Citrine to be used by a wider audience (i.e. schools). At time of writing, only English and Dutch versions are available. If you like to translate Citrine into your language, please contact me! While some language distributions are available on the download page, this site does not cover all different language versions (that would be too much work). The idea is that a Citrine ambassador will create and maintain a separate website for a language-specific distribution of Citrine.

Where can I find translation tables?

Here are the translation tables:

- Translation CSV English-Dutch

Can I fork Citrine?

Yes, find us on Github.

Can I use Citrine to teach programming?

Yes, because Citrine can be compiled in your native language. Citrine takes away language barriers and makes software development accessible to a wider audience. Citrine can also be tailored to suit the needs of a specific course and audience. Contact me for details!

Why has Citrine no built-in functionality X?

Citrine is a minimalist language. The Citrine project focuses on producing a better language. You can add new functionality by using a plugin. Plugins are automatically loaded as soon as you start talking to the object. Put your plugins here:


Some 3rd party plugins: Plugin: JSON (by MadCapJake), Plugin: CURL (by MadCapJake)

In line with the UNIX philosophy you can also invoke other programs to perform certain tasks using the shell:

✎ write: (💻  shell: 'ls -la').

This will print the contents of the current working directory on the screen.

How can I use a variable in a string?

Send an arbitrary message to a string:

✎ write: ('the answer is: this' this: 42).
the answer is 42

How can I use the icons in the examples?

Install 'Citrine.ttf' and configure your editor (I use Geany and Geany Macros, a macro package for Geany is included ):

cp ~/.config/geany/plugins/Geany_Macros/settings.conf ~/.config/geany/plugins/Geany_Macros/settings_backup.conf

cp macros.ini ~/.config/geany/plugins/Geany_Macros/settings.conf

icon code keys ascii
2264ALT+< or ALT+L<=:
2265ALT+> or ALT+M>=:

Trick: Use the thin space (2009) to form messages with a space. For instance:

(coffee < 10) if true: { ✎ write: 'refill'. }.


Can I use Citrine to write webapps?

Yes, Citrine ships with a CCGILIB-based HTTP plugin (mods/request/libctrrequest.so) that allows you to deal with GET and POST requests. you can use the Request object like this:

get  := Request get: 'search'.
list := Request getArray: 'orders[]'.
post := Request post: 'message'.
list := Request postArray: 'orders[]'.
file := Request file: 'avatar'.

Storm Server is a CCGILib based SCGI server for Citrine for hi-traffic web applications, to start an instance of Storm we put the following code in storm.ctr:

host: 'localhost' 
listen: 4000
pid:'/var/run/storm.pid' callback: {
	✎ write: 'Content-type: text/html\n\n'.
	☞ fname := Command env: 'DOCUMENT_URI'.
	☞ script := File new: '/var/www/htdocs' + fname.
	script include.


Can I serve Citrine applications with NGINX?

Sure, add the following configuration lines to: /etc/nginx/nginx.conf:

location ~ \.ctr$ {
        try_files $uri $uri/ =404;
        include   scgi_params;


What platforms are supported? How do I distribute Citrine?

Citrine runs on 64-bit X86 Linux and 64-bit X86 OpenBSD. There is a 64 bit X86 Windows port available as well. Community versions for FreeBSD and macOS are available as well (but I don't know where, please contact the community members).
If you want to use Citrine as your main programming language for a certain project, I recommend using one of the versions available on the download page. If you want to teach programming using the Citrine programming language, I recommend providing your students with a Virtual Machine.

What about functional programming style?

For the fans of functional programming:

☞ multiplier := { :m 
	↲ { :x 
		↲ (⚿ f * x).
	} set: 'f' value: m.
☞ double := multiplier applyTo: 2.
☞ q := double applyTo: 9. #yields 18

Have another question?
Visit Citrine Programming Language Forum!
There you can talk to other Citrine community members, ask questions, discuss new features, issues, bug reports and so on.

Citrine Support Contract Light € 39,-

gaborsoftware GaborSoftware offers various support contracts for the Citrine Programming Language. Benefits of a support contract include: priority status on github, a sponsor logo on the partner page and access to proprietary plugins (like GTK plugin) when available. With a Citrine Support Contract Light you also show your support for this project to the rest of the Citrine community. You can get a Citrine Support Contract Light for just € 39,- a year.

The Citrine Programming Language is a product of GaborSoftware © copyright 2018 all rights reserved. Citrine Programming Language created by Gabor de Mooij and the Citrine community. In-language (citrine.ttf) icons from the ionicons project (MIT licensed), FontAwesome (SIL OFL 1.1) by Dave Gandy - http://fontawesome.io and Typicons by S. Hutchings (SIL Open Font Licence).
Website and photography by Gabor de Mooij (photo 1: 'Train near Edinburgh Castle', photo 2: 'Box of wooden letter stamps at Apple Market, London', photo 3: 'Wall decorations in a pub in Edinburgh', photo 4: 'Moonstreet, London', photo 5: 'Ceiling of a monument in Paris'. ). Book icon from WikiMedia Commons Project. 'Citrine in a box' icon created by Gabor de Mooij using multiple assets from the WikiMedia Commons Project.
Contact me:

Founder & Original Author: Gabor de Mooij
Windows version of Citrine: Twiggler
Foundation work Json & Curl plugins: MadcapJake
Special thanks to: DennisCGc, Takano32, LeoTindall, Janus, Shinriyo, Marianne.
Citrine Community

Citrine respects your privacy and does not use cookies. For details read the Citrine Privacy Statement.
12700 visits since 3 March 2018