Citrine (programming language): Difference between revisions

Content deleted Content added
Cut needless carriage returns in paragraphs and between items.
Line 18:
}}
 
'''Citrine''' is a general purpose [[programming language]] for [[Unix-like]] operating systems. It focuses on readability and maintainability. Readability is achieved by syntactic and conceptual minimalism. The language is heavily inspired by [[Smalltalk]] and [[Self (programming language)|Self]] but has some very distinctive features. Like Smalltalk, Citrine 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 [[Prototype-based programming|prototypes]]. The combination of Smalltalk like messages and prototypes is what makes Citrine unique.
Readability is achieved by syntactic and conceptual minimalism. The language is heavily inspired by [[Smalltalk]] and [[Self (programming language)|Self]] but has some very distinctive
features. Like Smalltalk, Citrine 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 [[Prototype-based programming|prototypes]]. The combination of Smalltalk like messages and prototypes is what makes Citrine unique.
 
== Syntax ==
 
== 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:
 
Line 40 ⟶ 36:
Citrine only supports full line comments, comments start with a '#'.
 
A Citrine program is basically a sequence of messages sent to objects,. forFor instance, to calculate the factorial of the number 5, onethe hasmessage 'factorial' is sent to the number 5.
to send the message 'factorial' to number 5.
 
<source lang="citrine">
Line 47 ⟶ 42:
</source>
 
This is called a ''unary'' message because it takes no arguments. A ''binary'' message is always a single UTF-8 character; this differs from Smalltalk, where there is a fixed set of binary messages. Here is an example:
from Smalltalk, where there is a fixed set of binary messages. Here is an example:
 
<source lang="citrine">
Line 54 ⟶ 48:
</source>
 
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'. Assigning the outcome of this operation to a variable uses the assignment operator: :=.
Assigning the outcome of this operation to a variable uses the assignment operator: :=.
 
<source lang="citrine">
Line 61 ⟶ 54:
</source>
 
Also note that each line in a Citrine program ends with a dot, just like in Smalltalk. Besides unary and binary messages, Citrine offers ''keyword messages'', which take arguments interspersed with the message itself just like Smalltalk and [[Objective-C]].
offers ''keyword messages'', which take arguments interspersed with the message itself just like Smalltalk and [[Objective-C]].
 
<source lang="citrine">
Line 70 ⟶ 62:
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, writing a conditional statement requires sending a block of code to a boolean.
 
Just like Smalltalk, control flow in Citrine is implemented by strategic use of messages. For instance, writing a conditional statement requires sending a block of code
to a boolean.
 
<source lang="citrine">
Line 101 ⟶ 91:
</source>
 
== 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 writing Unix-like ''[[Pipeline (Unix)|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...'.
 
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 writing Unix-like ''[[Pipeline (Unix)|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...'.
 
<source lang="citrine">
Line 111 ⟶ 98:
</source>
 
== 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:
 
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:
 
<source lang="citrine">
Line 129 ⟶ 114:
</source>
 
As stated above, inheritance is based on prototypes. To derive an object from another object, the new message must be sent to the object to be extended:
To derive an object from another object, the new message must be sent to the object
to be extended:
 
<source lang="citrine">
Line 146 ⟶ 129:
</source>
 
== 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:
 
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:
 
<source lang="citrine">
Line 165 ⟶ 145:
 
==Scoping==
Citrine uses [[dynamic scoping]] instead of [[lexical scoping]]. Thus, there is no need for [[dependency injection]] or global variables, but it might be harder to reason about than lexical scope. This is similar in programming languages like [[Emacs Lisp]] and [[BASIC]]. In code blocks the ''var'' keyword needs to be used to declare a local variable.
 
Citrine uses [[dynamic scoping]] instead of [[lexical scoping]], this means there is no need
for [[dependency Injection]] or global variables, but it might be harder to reason about than
lexical scope. This is similar as in programming language like
[[EMACS Lisp]] and [[BASIC]]. In code blocks the ''var'' keyword needs to be used to declare
a local variable.
 
Demonstration: