Ceylon (programming language)
This page was last modified on 1 June 2016, at 17:20.
Paradigm | Imperative, Object-Oriented |
---|---|
Designed by | Red Hat |
First appeared | 2011 |
Stable release | 1.2.0 / 29.10 2015 |
License | Apache License 2.0 |
Filename extensions | .ceylon |
Website | http://ceylon-lang.org |
Influenced by | |
Java, JavaScript, C# |
Ceylon is an imperative programming language aimed at team development of large-scale projects.
The first release of the language, Ceylon M1, was released on December 20th, 2011 and provides about 80% of intended language features[1].
Major design principles of the language:
- code readability: the value of this increases along with the size of development team[1].
- predictability: the compiler’s and program’s behavior must be intuitive and easy to be reproduced by the programmer[1].
- toolability: extensive usage of tools improves programmer’s productivity a lot, and the effect increases along with the scale of the project, so the language should provide a lot of tools, starting with IDE, and have as few features hard for tools to understand as possible[1].
- modularity: once again, the larger are the programs developed, the more important their organization becomes.
- metaprogramming: a lot of libraries and complex frameworks are based on the ability to write code which manipulates on other code[1].
The language syntax resembles Java and C# a lot. In fact, Ceylon is largely based on Java, but it aims to inherit successful features and eliminate or fix unsuccessful ones[1].
Contents
- 1 Ceylon language features[2]
- 2 Ceylon is as an extension or replacement of the Java language
- 3 Ceylon types[2]
- 4 Operators Ceylon
- 4.1 ! (not) operator
- 4.2 != (not equal) operator
- 4.3 % (remainder) operator
- 4.4 %= (remainder assign) operator
- 4.5 & (intersection) operator
- 4.6 && (and) operator
- 4.7 &&= (and assign) operator
- 4.8 &= (set intersect assign) operator
- 4.9 () (invoke) operator
- 4.10 * (product) operator
- 4.11 ** (scale) operator
- 4.12 *= (multiply assign) operator
- 4.13 + (sum) operator
- 4.14 + (unary plus) operator
- 4.15 ++ (increment) operator
- 4.16 += (add assign) operator
- 4.17 -(difference) operator
- 4.18 - (unary minus) operator
- 4.19 -- (decrement) operator
- 4.20 -= (subtract assign) operator
- 4.21 -> (entry) operator
- 4.22 . (member) operator
- 4.23 .. (spanned range) operator
- 4.24 y:z (measured range) operator
- 4.25 / (quotient) operator
- 4.26 /= (divide assign)operator
- 4.27 < (less than) operator
- 4.28 <= (less than or equal) operator
- 4.29 <=> (compare) operator
- 4.30 = (assign) operator
- 4.31 == (equal) operator
- 4.32 === (identical) operator
- 4.33 > (greater than) operator
- 4.34 >= (greater than or equal) operator
- 4.35 ?. (null-safe attribute) operator
- 4.36 ?. (null-safe method) operator
- 4.37 [] (lookup) operator
- 4.38 * (spread) operator
- 4.39 *. (spread attribute) operator
- 4.40 *. (spread method) operator
- 4.41 x[y..z] (span) operator
- 4.42 x[y...] (upper span) operator
- 4.43 x[...z] (lower span) operator
- 4.44 x[y:z] (measure) operator
- 4.45 ^ (power) operator
- 4.46 | (Set union) operator
- 4.47 |= (Set union assign) operator
- 4.48 || (or) operator
- 4.49 ||= (or assign) operator
- 4.50 {} (invoke) operator
- 4.51 ~ (Set complement) operator
- 4.52 ~= (Set complement assign) operator
- 4.53 else operator
- 4.54 exists operator
- 4.55 in operator
- 4.56 is operator
- 4.57 nonempty operator
- 4.58 of operator
- 4.59 then operator
- 5 Statements Cyelon
- 6 Examples
- 7 Ceylon's future [2]
- 8 References
- 9 External links
Ceylon language features[2]
Most languages today defy a simple categorization and instead represent a variety of programming styles. Ceylon is no different. Ceylon is a statically typed language (which means that type checking is performed at compile time, compared with dynamically type languages such as Lisp, where type checking is performed at run time). Ceylon is an object-oriented language, like the Java language, and also supports higher-order functions (which means that functions can take functions as input or output) with a typical C syntax style. Higher-order functions are not supported directly in the Java language, so this functionality represents a unique difference in the two languages.
Sometimes, however, improvements are more about what a language removes than what it adds. Ceylon simplifies and removes elements of the Java language, replacing them with a simpler scheme. One example of a simplification is the removal of the public, protected, and private keywords. Instead, Ceylon simply includes the shared annotation, which defines which elements of a class are visible externally. Ceylon also removes the ability to overload but provides some workarounds for this functionality (such as defaulted and sequenced parameters) with simpler syntax.
Ceylon includes support for inheritance, sequences (array or list construct), generics, named arguments, and more. It includes features for run time type management (we'll explore an example of this in the next section). The language is under active development, so the final feature set remains open.
Ceylon is as an extension or replacement of the Java language
King asked the question, what would a language look like with the lessons learned from the advantages and disadvantages of the Java language and SDK? His answer is Ceylon, a statically typed language that retains some of the best features of the Java language (and runs on the JVM) but improves on that language's readability, built-in modularity, and the incorporation of functional language features like high-order functions. Ceylon also incorporates features of C and Smalltalk. Much like the Java language, this new language is focused on business computing, but it is also flexible and useful in other domains[2].
Some have called Ceylon a "Java killer" (perhaps due to questions of the Java language's future), but Ceylon in fact runs on the JVM, so it's an extension of Java technology rather than a replacement. Using the JVM to support execution of Ceylon is an ideal model, because it means that Ceylon (like Java) is portable across the multitude of architectures that currently support the JVM.[2].
Ceylon types[2]
Ceylon incorporates a traditional set of types that are implemented as ordinary classes. These types are:
- Natural. Unsigned integers, including zero.
- Integer. Signed integers.
- Float. Floating point.
- Whole. Arbitrary precision signed integers.
- Decimal. Arbitrary precision and arbitrary scale decimals.
By default, the Natural, Integer, and Float types are 64 bit, but you can annotate them with small to specify 32-bit precision.
Operators Ceylon
! (not) operator
The right-associative, unary || operator is used to compute the logical not of its operand.
Example
Boolean true_ = !false;
!= (not equal) operator
The non-associating, binary infix != operator is used to test whether its operands are not equal.
Example
void m(Object x, Object y) {
Boolean identical = x != y;
}
% (remainder) operator
The binary, left-associative infix % operator is used to get the remainder of an integer division. Example
Integer two = 5 % 3;
%= (remainder assign) operator
The right-associative, binary infix %= operator takes the remainder of it's left-hand operand with respect to its right-hand operand and updates the left-hand operand with the result.
Example
variable Integer num = 10;
num %= 2; // half num
& (intersection) operator
The left-associative, binary infix & operator is used to compute the intersection of its operands.
Example
void m(Set<Integer> primes, Set<Integer> evens) {
Set<Integer> two = primes & evens;
}
&& (and) operator
The left-associative, binary infix && operator is used to compute the logical and of two operands
Example
Boolean false_ = true && false;
&&= (and assign) operator
The right-associative, binary infix &&= operator is used to compute the logical and of two operands, assigning the result to the left-hand operand.
Example
variable Boolean a = true;
Boolean b = false;
a &&= b; // a becomes false
&= (set intersect assign) operator
The right-associative, binary infix &= operator is used to compute the intersection of two operands, assigning the result to the left-hand operand.
Example
void m(Set<Integer> primes, Set<Integer> evens) {
variable Set<Integer> two = primes;
two &= evens;
}
() (invoke) operator
The left-associative, unary () and {} operators are used to invoke methods and instantiate classes.
Example
print("hello, world!"); // positional style
print{ // named-arguments style
line="hello, world";
};
MyClass instance = MyClass(); // invoking a class to get an instance
* (product) operator
The left-associative, binary infix * operator is used to compute the product of two operands.
Example
Integer six = 3 * 2;
** (scale) operator
The right-associative, binary infix ** operator is used to scale an instance of Scalable but an amount.
Example
value four_plus_6i = 2 ** Complex(2, 3);
*= (multiply assign) operator
The right-associative, binary infix *= operator multiplies it's left-hand operand by the amount given by its right-hand operand and assigns the result to the left-hand operand.
Example
variable Integer num = 1;
num *= 2; // double num
num *= num; // square num
+ (sum) operator
The left-associative, binary infix + operator is used to sum two operands.
Example
Integer three = 1 + 2;
String concatenated = "foo" + "bar";
+ (unary plus) operator
The right-associative, unary prefix + operator is used to clarify the positive value of its operand.
Example
Integer one = +1;
Integer minusOne = +(-1);
++ (increment) operator
The left-associative, unary ++ operators increment their operand; they differ in whether the result is assigned before or after the increment.
Example 1
variable Integer num = 1;
num++;
Example 2
variable Integer num = 1;
++num;
+= (add assign) operator
The right-associative, binary infix += operator increments it's left-hand operand by the amount given by its right-hand operand.
Example
variable Integer num = 1;
num += 1; // increment num by 1
num += num; // increment num by 2
-(difference) operator
The left-associative, binary infix - operator is used to take the difference of two operands.
Example
Integer one = 3 - 2;
- (unary minus) operator
The right-associative, unary prefix - operator is used to invert the sign of its operand.
Example
Integer minusOne = -1;
-- (decrement) operator
The left-associative, unary -- operators decrement their operand; they differ in whether the result is assigned before or after the decrement.
Example 1
variable Integer num = 1;
num--;
Example 1
variable Integer num = 1;
--num;
-= (subtract assign) operator
The right-associative, binary infix -= operator decrements it's left-hand operand by the amount given by its right-hand operand.
Example
variable Integer num = 4;
num -= 1; // decrement num by 1
num -= num; // decrement num by 3
-> (entry) operator
The infix entry operator creates an Entry from its key and value.
Example
Entry<Integer, String> intName = 1 -> "One";
. (member) operator
The left-associative, binary infix . operator is used to access the member named by the right-hand operand from left-hand operand.
Example
String[] args = process.arguments;
.. (spanned range) operator
The spanned range operator creates a Range from its endpoints.
Example
Range<Integer> ten = 1..10;
y:z (measured range) operator
The measured range operator creates a Range from a starting point and a length.
Example
Range<Integer> ten = 1:10;
/ (quotient) operator
The left-associative, binary infix / operator is used to compute the quotient of two operands.
Example
Integer three = 6 / 2;
/= (divide assign)operator
The right associative, binary infix /= operator divides it's left-hand operand by the amount given by its right-hand operand.
Example
variable Float num = 1.0;
num /= 2.0; // half num
< (less than) operator
The non-associating, binary infix < operator is used to test whether its left-hand operand is less than its right-hand operand.
Example
void m<T>(T x, T y)
given T satisfies Comparable<T> {
Boolean less = x < y;
}
<= (less than or equal) operator
The non-associating, binary infix <= operator is used to test whether its left-hand operand is less than or equal to its right-hand operand.
Example
void m<T>(T x, T y)
given T satisfies Comparable<T> {
Boolean lessOrEqual = x <= y;
}
<=> (compare) operator
The non-associating, binary infix <=> operator is used to compare the order of its operands.
Example
void m<T>(T x, T y) given T satisfies Comparable<T> {
Comparison cmp = x <=> y;
}
= (assign) operator
The right-associative, binary infix = operator is used to assign a value to a variable-annotated attribute.
Example
variable Integer num = 1; // assign
num = 2; //assign
Integer three = 3 // specify
== (equal) operator
The non-associating, binary infix == operator is used to test whether its operands are equal.
Example
void m(Object x, Object y) {
Boolean identical = x == y;
}
=== (identical) operator
The non-associating, binary infix === operator is used to test whether its operands are identica.
Example
void m(Identifiable x, Identifiable y) {
Boolean identical = x === y;
}
> (greater than) operator
The non-associating, binary infix > operator is used to test whether its left-hand operand is greater than its right-hand operand.
Example
void m<T>(T x, T y)
given T satisfies Comparable<T> {
Boolean more = x > y;
}
>= (greater than or equal) operator
The non-associating, binary infix >= operator is used to test whether its left-hand operand is greater than or equal to its right-hand operand.
Example
void m<T>(T x, T y)
given T satisfies Comparable<T> {
Boolean greaterOrEqual = x >= y;
}
?. (null-safe attribute) operator
The left-associative, binary ?. operator is used to access an attribute as if its right-hand operand were not null.
Example
void m(Integer? num) {
Integer? int = num?.positiveValue;
}
?. (null-safe method) operator
The left-associative, binary ?. operator is used to invoke a method as if its right-hand operand were not null.
Example
void m(Integer? num) {
Integer?(Integer) plus = num?.plus;
}
[] (lookup) operator
The lookup operator accesses a particular item in a Correspondence.
Example
void m(Integer[] seq) {
Integer? first = seq[0];
}
* (spread) operator
The spread operator, produces multiple values by iterating the iterable object to which the spread operator is applied.
Example
void spreadIterable(String* names) {
// note names is a variadic parameter
}
{String*} names = { "Tom", "Gavin" };
// Invocation using listed arguments
spreadIterable("Tom", "Gavin");
// Invocation using a spread iterable argument
spreadIterable(*names);
*. (spread attribute) operator
The spread attribute operator maps an iterable of instances through an attribute, resulting in a sequence of the attribute values.
Example
{String+} names = {"foo", "bar", "baz"};
{Integer+} sizes = names*.size;
*. (spread method) operator
The spread method operator maps an iterable of instances through a method, resulting in a new sequence containing the return values of each method invocation.
Example
{String+} names = {"foo", "bar", "baz"};
{String+} initials = names*.initial(1);
x[y..z] (span) operator
The span operator returns the subrange of its left-hand operand indexed by its centre and right-hand operands.
Example
String[] names = {"foo", "bar", "baz"};
String[] firstAndSecond = names[0..1];
String[] secondAndThird = names[1..2];
x[y...] (upper span) operator
The upper span operator returns the tail of its left-hand Ranged operand as specified by its right-hand operand.
Example
String[] names = {"foo", "bar", "baz"};
String[] secondAndThird = names[1...];
String[] third = names[2...];
String[] emptySequence = names[3...];
x[...z] (lower span) operator
The lower span operator returns the elements of its left-hand Ranged operand upto and including the element whose key is specified by its right-hand operand.
Example
String[] names = {"foo", "bar", "baz"};
String[] foo = names[...0];
String[] foobar = names[...1];
String[] emptySequence = names[...-1];
x[y:z] (measure) operator
The measure operator returns the subrange of its left-hand operand starting from its central operand and including as many elements as given by its right-hand operand.
Example
String[] names = {"foo", "bar", "baz"};
String[] foo = names[0:1];
String[] barBaz = names[1:2];
String[] empty = names[1:0];
^ (power) operator
The right-associative, binary infix ^ operator is used to compute its left-hand operand raised to the power of its right-hand operand.
Example
Integer eight = 2 ^ 3;
| (Set union) operator
The left-associative, binary infix | operator is used to compute the union of two operands.
Example
void m(Set<Integer> odds, Set<Integer> evens) {
Set<Integer> ints = odds | evens;
}
|= (Set union assign) operator
The right-associative, binary infix |= operator is used to compute the union of two operands, assigning the result to the left-hand operand
Example
void m(Set<Integer> odds, Set<Integer> evens) {
variable Set<Integer> all = odds;
all |= evens;
}
|| (or) operator
The left-associative, binary infix || operator is used to compute the logical or of two operands.
Example
Boolean true_ = true || false;
||= (or assign) operator
The right-associative, binary infix ||= operator is used to compute the logical or of two operands, assigning the result to the left-hand operand.
Example
variable Boolean a = false;
Boolean b = true;
a ||= b; // a becomes true
{} (invoke) operator
The left-associative, unary () and {} operators are used to invoke methods and instantiate classes.
Example
print("hello, world!"); // positional style
print{ // named-arguments style
line="hello, world";
};
MyClass instance = MyClass(); // invoking a class to get an instance
~ (Set complement) operator
The left-associative, binary infix ~ operator is used to compute the complement of its left-hand operand in its right-hand operand.
Example
void m<Dog>(Set<Dog> dogs, Set<Dog> blackDogs)
given Dog satisfies Object {
Set<Dog> nonBlackDogs = dogs ~ blackDogs;
}
~= (Set complement assign) operator
The right-associative, binary infix ~= operator is used to compute the complement of its left-hand operand in its right-hand operand, assigning the result to the left-hand operand.
Example
void m<Dog>(Set<Dog> dogs, Set<Dog> blackDogs)
given Dog satisfies Object {
variable Set<Dog> nonBlackDogs = dogs;
nonBlackDogs ~= blackDogs;
}
else operator
The left-associative, binary else operator is used to provide a default value when it's left operand is null.
Example
void m(Integer? num) {
Boolean haveNum = num exists;
}
exists operator
The non-associating, unary postfix exists operator is used to test its operand for nullness.
Example
void m(Integer? num) {
Boolean haveNum = num exists;
}
in operator
The non-associating, binary infix in operator is used to test whether its left-hand operand is contained in its right-hand operand
Example
void m(Object x, Category y) {
Boolean contained = x in y;
}
is operator
The non-associating, binary infix is operator is used to test the type of an expression
Example
void m(Object? obj) {
Boolean isNumber = obj is Number<out Anything>;
Boolean isNull = obj is Null;
}
nonempty operator
The non-associating, unary postfix nonempty operator is used to test its operand for emptiness.
Example
void m(Integer[] nums) {
Boolean haveNums = nums nonempty;
}
of operator
The non-associating, binary infix of operator is used to cast the type of an expression, when this can be statically proven to be safe.
Example
void m(Anything obj) {
Object|Null maybeNull = obj of Object|Null;
}
then operator
The left-associative, binary then operator evaluates its right operand only when it's left operand is true, otherwise it evaluates as null.
Example
void m(String s) {
String s2 = s.empty then "hello";
}
Statements Cyelon
- assert
- break
- continue
- Condition lists
- Expression statements
- for
- if statement
- import
- return
- Specification statements
- Destructuring specification
- switch statement
- throw
- try
- while
Examples
Hello, World!
void hello() {
print("Hello, World!");
}
Factorial
This example calculates factorials iteratively. variable keyword points out that the value of the variable fact is going to be changed later (exactly the opposite of Java keyword final). Integer data type allows to store values of factorial without overflow. The arguments of print are concatenated without any explicit operator, but for this the first and the last elements of the list to be concatenated have to be string literals.
void factorial() {
variable Integer fact := 1;
for (i in 0..16) {
print("" i "! = " fact "");
fact *= i + 1;
}
}
Fibonacci numbers
This example calculates Fibonacci numbers iteratively.
void fibon() {
variable String output := "";
variable Integer fib1 := 0;
variable Integer fib2 := 1;
variable Integer fib3;
for (i in 1..16) {
output := "" output "" fib2 ", ";
fib3 := fib1 + fib2;
fib1 := fib2;
fib2 := fib3;
}
print("" output "...");
}
Ceylon's future [2]
As King has said, Ceylon is a community effort and therefore needs software engineers and testers to help design, build, and validate the language and SDK. This call could encourage feedback from Java language users to help support their migration from that language to Ceylon. King is still somewhat silent on the current status of Ceylon, saying only that a language specification exists as well as ANTLR (Another Tool for Language Recognition) grammar..[2]
References
- ↑ 1.0 1.1 1.2 1.3 1.4 1.5 Ceylon
- ↑ 2.0 2.1 2.2 2.3 2.4 2.5 Ceylon: True advance, or just another language?
External links
- Official site Ceylon
- ibm.com Ceylon: True advance, or just another language?
Присоединяйся к команде
ISSN:
Следуй за Полисом
Оставайся в курсе последних событий
License
Except as otherwise noted, the content of this page is licensed under the Creative Commons Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0 License, and code samples are licensed under the Apache 2.0 License. See Terms of Use for details.