Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial import

git-svn-id: https://svn.infohazard.org/gavin/ceylon@2 1f44ac50-6449-0410-90d3-ad5476e90056
  • Loading branch information...
commit 0be895abc6b849c39f9b34e96a276c84b42450e1 1 parent 09eccb7
@gavinking gavinking authored
Showing with 33,597 additions and 0 deletions.
  1. +17 −0 .project
  2. +199 −0 build.xml
  3. +1 −0  en/.cvsignore
  4. +34 −0 en/master.xml
  5. +925 −0 en/modules/declarations.xml
  6. +422 −0 en/modules/expressions.xml
  7. +212 −0 en/modules/introduction.xml
  8. +443 −0 en/modules/literals.xml
  9. +1,267 −0 en/modules/operators.xml
  10. +475 −0 en/modules/statementblocks.xml
  11. +1,065 −0 en/modules/types.xml
  12. +35 −0 en/styles/filter.xsl
  13. +516 −0 en/styles/fopdf.xsl
  14. +96 −0 en/styles/html.css
  15. +84 −0 en/styles/html.xsl
  16. +86 −0 en/styles/html_chunk.xsl
  17. +363 −0 support/docbook-dtd/ChangeLog
  18. +8 −0 support/docbook-dtd/README
  19. +205 −0 support/docbook-dtd/calstblx.dtd
  20. +115 −0 support/docbook-dtd/catalog.xml
  21. +384 −0 support/docbook-dtd/dbcentx.mod
  22. +41 −0 support/docbook-dtd/dbgenent.mod
  23. +2,116 −0 support/docbook-dtd/dbhierx.mod
  24. +102 −0 support/docbook-dtd/dbnotnx.mod
  25. +8,250 −0 support/docbook-dtd/dbpoolx.mod
  26. +110 −0 support/docbook-dtd/docbook.cat
  27. +165 −0 support/docbook-dtd/docbookx.dtd
  28. +63 −0 support/docbook-dtd/ent/iso-amsa.ent
  29. +49 −0 support/docbook-dtd/ent/iso-amsb.ent
  30. +15 −0 support/docbook-dtd/ent/iso-amsc.ent
  31. +66 −0 support/docbook-dtd/ent/iso-amsn.ent
  32. +26 −0 support/docbook-dtd/ent/iso-amso.ent
  33. +91 −0 support/docbook-dtd/ent/iso-amsr.ent
  34. +45 −0 support/docbook-dtd/ent/iso-box.ent
  35. +72 −0 support/docbook-dtd/ent/iso-cyr1.ent
  36. +31 −0 support/docbook-dtd/ent/iso-cyr2.ent
  37. +19 −0 support/docbook-dtd/ent/iso-dia.ent
  38. +54 −0 support/docbook-dtd/ent/iso-grk1.ent
  39. +25 −0 support/docbook-dtd/ent/iso-grk2.ent
  40. +48 −0 support/docbook-dtd/ent/iso-grk3.ent
  41. +48 −0 support/docbook-dtd/ent/iso-grk4.ent
  42. +67 −0 support/docbook-dtd/ent/iso-lat1.ent
  43. +126 −0 support/docbook-dtd/ent/iso-lat2.ent
  44. +81 −0 support/docbook-dtd/ent/iso-num.ent
  45. +90 −0 support/docbook-dtd/ent/iso-pub.ent
  46. +69 −0 support/docbook-dtd/ent/iso-tech.ent
  47. +228 −0 support/docbook-dtd/htmltblx.mod
  48. +314 −0 support/docbook-dtd/soextblx.dtd
  49. +107 −0 support/docbook-xsl/README
  50. +84 −0 support/docbook-xsl/VERSION
  51. +624 −0 support/docbook-xsl/common/ChangeLog
  52. +1,153 −0 support/docbook-xsl/common/af.xml
  53. +1,153 −0 support/docbook-xsl/common/ar.xml
  54. +135 −0 support/docbook-xsl/common/autoidx-ng.xsl
  55. +1,153 −0 support/docbook-xsl/common/bg.xml
  56. +1,153 −0 support/docbook-xsl/common/bn.xml
  57. +1,153 −0 support/docbook-xsl/common/ca.xml
  58. +1,658 −0 support/docbook-xsl/common/common.xsl
  59. +624 −0 support/docbook-xsl/common/cs.xml
  60. +588 −0 support/docbook-xsl/common/da.xml
  61. +590 −0 support/docbook-xsl/common/de.xml
  62. +1,153 −0 support/docbook-xsl/common/el.xml
  63. +1,153 −0 support/docbook-xsl/common/en.xml
  64. +600 −0 support/docbook-xsl/common/es.xml
  65. +1,153 −0 support/docbook-xsl/common/et.xml
Sorry, we could not display the entire diff because too many files (610) changed.
View
17 .project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>jsr299</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.jboss.ide.eclipse.archives.core.archivesBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.jboss.ide.eclipse.archives.core.archivesNature</nature>
+ </natures>
+</projectDescription>
View
199 build.xml
@@ -0,0 +1,199 @@
+<!--
+ To build the reference docs for a particular language only, use "ant -Dlang=en", for
+ example, and call either lang.all, lang.docpdf, lang.dochtml, or lang.dochtmlsingle
+ for the target of your choice.
+
+ You can also call lang.section-check to track down missing identifiers in a particular
+ language, or you can call lang.revdiff to get a difference report for a particular
+ language, compared with the English reference.
+-->
+<project name="Project Ceylon" default="all.doc" basedir=".">
+ <!-- Allow this to be overriden by others importing this project. -->
+ <dirname property="imported.basedir" file="${ant.file.ReferenceDocumentation}"/>
+
+ <!-- Set build directories for all formats. -->
+ <property name="build.dir" value="${basedir}/build"/>
+
+ <!-- Support files for build process. -->
+ <property name="support.dir" value="${imported.basedir}/support"/>
+
+ <!-- Base name for documentation artifacts. -->
+ <tstamp />
+ <property name="docname" value="Project Ceylon ${DSTAMP}"/>
+
+ <!-- Set DocBook stylesheets. -->
+ <property name="db.style.fopdf" value="fopdf.xsl"/>
+ <property name="db.style.html" value="html_chunk.xsl"/>
+ <property name="db.style.htmlsingle" value="html.xsl"/>
+
+ <!-- Classpath for the build tools. -->
+ <path id="lib.classpath">
+ <fileset dir="${support.dir}/lib">
+ <include name="**/*.jar"/>
+ </fileset>
+ </path>
+
+ <!-- ################################################################## -->
+
+ <target name="all.doc"
+ depends="clean"
+ description="Compile documentation for all languages and all formats.">
+
+ <!-- TRANSLATOR: Duplicate this line for your language -->
+ <antcall target="lang.all"><param name="lang" value="en"/></antcall>
+
+ </target>
+
+ <target name="all.revdiff"
+ description="Generates a diff report for all translated versions.">
+
+ <!-- TRANSLATOR: Duplicate this line for your language -->
+ <antcall target="lang.revdiff"><param name="lang" value="de"/></antcall>
+
+ </target>
+
+ <!-- ################################################################## -->
+
+ <target name="clean">
+
+ <!-- Delete build directory. -->
+ <delete dir="${build.dir}"/>
+
+ </target>
+
+ <target name="lang.all">
+ <!-- Compile the documentation for a single language in all formats. -->
+ <antcall target="lang.docpdf"/>
+ <antcall target="lang.dochtml"/>
+ <antcall target="lang.dochtmlsingle"/>
+ <antcall target="lang.htmlmisc"/>
+ </target>
+
+
+ <target name="lang.docpdf.prepare">
+
+ <!-- Copy all the images to the output location, will be removed later. -->
+ <copy todir="${build.dir}/${lang}/pdf/images">
+ <fileset dir="${basedir}/${lang}/images">
+ <include name="**/*.png"/>
+ <include name="**/*.svg"/>
+ <include name="**/*.gif"/>
+ </fileset>
+ </copy>
+
+ <!-- Create the XSL/FO temporary file. -->
+ <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${basedir}" maxmemory="192m" >
+ <classpath refid="lib.classpath"/>
+ <arg value="-o"/>
+ <arg value="${build.dir}/${lang}/pdf/docbook_fop.tmp"/>
+ <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${basedir}/${lang}/styles/${db.style.fopdf}"/>
+ </java>
+
+ <available property="custom.fop.userconfig.present" file="userconfig.xml" filepath="${basedir}/${lang}/fop"/>
+ </target>
+
+ <target name="lang.docpdf.customized" depends="lang.docpdf.prepare" if="custom.fop.userconfig.present">
+
+ <copy todir="${build.dir}/${lang}/pdf">
+ <fileset dir="${basedir}/${lang}/fop">
+ <include name="*"/>
+ </fileset>
+ </copy>
+
+ <!-- Create a PDF from the XSL/FO, using customized fop userconfig.xml -->
+ <java classname="org.apache.fop.apps.Fop" fork="true" dir="${basedir}" maxmemory="192m" >
+ <classpath refid="lib.classpath"/>
+ <arg value="-c"/>
+ <arg value="${basedir}/${lang}/fop/userconfig.xml"/>
+ <arg value="${build.dir}/${lang}/pdf/docbook_fop.tmp"/>
+ <arg value="${build.dir}/${lang}/pdf/${docname}.pdf"/>
+ </java>
+ </target>
+
+ <target name="lang.docpdf.normal" depends="lang.docpdf.prepare" unless="custom.fop.userconfig.present">
+ <!-- Create a PDF from the XSL/FO. -->
+ <java classname="org.apache.fop.apps.Fop" fork="true" dir="${basedir}" maxmemory="192m">
+ <classpath refid="lib.classpath"/>
+ <arg value="${build.dir}/${lang}/pdf/docbook_fop.tmp"/>
+ <arg value="${build.dir}/${lang}/pdf/${docname}.pdf"/>
+ </java>
+ </target>
+
+ <target name="lang.docpdf" depends="lang.docpdf.normal,lang.docpdf.customized"
+ description="Generates the PDF documentation only for a language (set lang)">
+ <!-- House keeping,delete temporary files. -->
+ <delete>
+ <fileset dir="${build.dir}/${lang}/pdf" excludes="**/*.pdf"/>
+ </delete>
+ <delete dir="${build.dir}/${lang}/pdf/images"/>
+ </target>
+
+ <target name="lang.dochtml"
+ description="Generates the HTML documentation only for a language (set lang)">
+
+ <mkdir dir="${build.dir}/${lang}/html/"/>
+
+ <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${build.dir}/${lang}/html" maxmemory="192m">
+ <classpath refid="lib.classpath"/>
+ <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${basedir}/${lang}/styles/${db.style.html}"/>
+ </java>
+ </target>
+
+ <target name="lang.dochtmlsingle"
+ description="Generates the single-page HTML documentation only for a language (set lang)">
+
+ <mkdir dir="${build.dir}/${lang}/html_single/"/>
+
+ <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${basedir}" maxmemory="192m">
+ <classpath refid="lib.classpath"/>
+ <arg value="-o"/>
+ <arg value="${build.dir}/${lang}/html_single/index.html"/>
+ <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${basedir}/${lang}/styles/${db.style.htmlsingle}"/>
+ </java>
+ </target>
+
+ <target name="lang.htmlmisc">
+
+ <!-- Copy images and CSS for HTML documentation, language specific. -->
+ <copy todir="${build.dir}/${lang}/shared/images">
+ <fileset dir="${basedir}/${lang}/images">
+ <include name="**/*.png"/>
+ <include name="**/*.gif"/>
+ </fileset>
+ </copy>
+ <copy todir="${build.dir}/${lang}/shared/css">
+ <fileset dir="${basedir}/${lang}/styles">
+ <include name="**/*.css"/>
+ </fileset>
+ </copy>
+
+ </target>
+
+ <target name="lang.revdiff"
+ description="Reports difference between English and translation (set lang)">
+
+ <taskdef name="revdiff"
+ classname="org.hibernate.docproc.revdiff.RevDiffReportTask"
+ classpathref="lib.classpath">
+
+ </taskdef>
+
+ <revdiff original="${basedir}/en/master.xml"
+ copy="${basedir}/${lang}/master.xml"
+ report="${build.dir}/status_${lang}.html"/>
+
+ </target>
+
+ <target name="lang.section-check" depends="lang.dochtml"
+ description="Reports missing unique chapter/section identifiers (set lang)">
+ <java classname="com.icl.saxon.StyleSheet" fork="true" dir="${build.dir}/${lang}/html" maxmemory="192m">
+ <classpath refid="lib.classpath"/>
+ <arg value="${basedir}/${lang}/master.xml"/>
+ <arg value="${support.dir}/section-check.xsl"/>
+ </java>
+ </target>
+
+</project>
View
1  en/.cvsignore
@@ -0,0 +1 @@
+master.filtered.xml
View
34 en/master.xml
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
+ "../support/docbook-dtd/docbookx.dtd"
+
+[
+<!ENTITY introduction SYSTEM "modules/introduction.xml">
+<!ENTITY declarations SYSTEM "modules/declarations.xml">
+<!ENTITY statementblocks SYSTEM "modules/statementblocks.xml">
+<!ENTITY expressions SYSTEM "modules/expressions.xml">
+<!ENTITY literals SYSTEM "modules/literals.xml">
+<!ENTITY operators SYSTEM "modules/operators.xml">
+<!ENTITY types SYSTEM "modules/types.xml">
+]>
+
+<book lang="en">
+
+ <bookinfo>
+ <title>Project Ceylon</title>
+ <subtitle>A Better Java</subtitle>
+ <releaseinfo>For internal discussion only</releaseinfo>
+ </bookinfo>
+
+ <toc/>
+
+ &introduction;
+ &declarations;
+ &statementblocks;
+ &expressions;
+ &literals;
+ &operators;
+ &types;
+
+</book>
+
View
925 en/modules/declarations.xml
@@ -0,0 +1,925 @@
+<chapter id="declarations">
+ <title>Declarations</title>
+
+ <para>
+ All classes, interfaces, selectors, attributes, methods, constructors, variables,
+ functors, decorators and converters must be declared. Declarations conform to the
+ following general schema:
+ </para>
+
+ <programlisting>Annotations? Type* keyword? Identifier TypeParameters? VariableList? TypeConstraintList? Declaration?</programlisting>
+
+ <para>Where:</para>
+
+ <programlisting>Annotations := Annotation+ COLON</programlisting>
+
+ <programlisting>TypeParameters := LT Identifier (COMMA Identifier)* GT</programlisting>
+
+ <programlisting>VariableList := OPENPAREN Variables? CLOSEPAREN</programlisting>
+
+ <programlisting>Variables: =
+Variable ( Initializer | (COMMA Variable)* )
+(COMMA Variable Initializer)*
+(COMMA Variable "...")?</programlisting>
+
+ <programlisting>Variable := Annotations? Type+ Identifier</programlisting>
+
+ <programlisting>Initializer := EQUALS Expression</programlisting>
+
+ <programlisting>Type := Identifier (DOT Identifier)* TypeParameters?</programlisting>
+
+ <programlisting>TypeConstraintList = "where" OPENPAREN TypeConstraint (SEMICOLON TypeConstraint)* CLOSEPAREN</programlisting>
+
+ <programlisting>TypeConstraint := Ident (GT|LT) EQ? (Type|Ident)</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Comparable&lt;Person&gt; Person person = ... ;</programlisting>
+
+ <programlisting>Public Entity:
+class Customer(Organization org) = Person(org)
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Set&lt;T&gt;
+class HashSet&lt;T&gt;(Iterable&lt;Entry&lt;T&gt;&gt; entries = none)
+ where (T>Comparable)
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Sequence&lt;T&gt;
+Collection&lt;T&gt;
+interface List&lt;T&gt; {
+ ...
+}</programlisting>
+
+ <programlisting>Integer count = 0;</programlisting>
+
+ <programlisting>Protected: String firstName;</programlisting>
+
+ <programlisting>Public: String name { ... } assign { ... }</programlisting>
+
+ <programlisting>Public: Float total return ... ;</programlisting>
+
+ <programlisting>Public: Boolean login() { ... }</programlisting>
+
+ <programlisting>Public:
+String join(Iterable&lt;String&gt;, String delimiter = ", ") {
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Boolean functor Order&lt;T&gt;(T x, T y);</programlisting>
+
+ <programlisting>Public:
+Comparable&lt;Person&gt;
+decorator ComparablePerson(Person person)
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Float
+converter IntegerToFloat(Integer int)
+{
+ ...
+}</programlisting>
+
+ <para>Thus, the syntax of Ceylon declarations is more regular than Java or C#.</para>
+
+ <section>
+ <title>Classes</title>
+
+ <para>Class are declared according to the following:</para>
+
+ <programlisting>Annotations? Type*
+"class" Identifier TypeParameters?
+VariableList?
+TypeConstraintList?
+EQUALS Instantiation
+OPENBRACE
+( Attribute | Method | Assert SEMICOLON )*
+CLOSEBRACE</programlisting>
+
+ <para>TODO: do we really need to allow assertions in the class body,
+ or is it enough to let them put them in the PostInvoke: method?</para>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public Entity:
+class Customer(Organization org) = Person(org)
+{
+ ...
+}</programlisting>
+ <programlisting>Comparable&lt;Token&gt;
+Identifier
+class Token = Datetime()
+{
+ ...
+}</programlisting>
+
+ <para>
+ The types listed before the <literal>class</literal> keyword are the interfaces.
+ The type specified in the initializer clause is a superclass. The
+ semantics of class inheritance are exactly the same as Java, and the above
+ declarations are equivalent to the following Java declarations:
+ </para>
+
+ <programlisting>@Entity public class Customer
+ extends Person
+{
+ ...
+}</programlisting>
+
+ <programlisting>class Token
+ extends Datetime
+ implements Comparable&lt;Token&gt;, Identifier
+{
+ ...
+}</programlisting>
+
+ <para>
+ Ceylon classes do not support a Java-like constructor declaration syntax. However,
+ Ceylon supports <emphasis>class initialization parameters</emphasis>. A class
+ initialization parameter may be used by attribute initializers.
+ </para>
+
+ <para>This declaration:</para>
+
+ <programlisting>Public:
+class Key(Lock lock)
+{
+ Public Constant: Lock lock = lock;
+}</programlisting>
+
+ <para>Is equivalent to this Java class:</para>
+
+ <programlisting>public class Key
+{
+
+ private final ConstantAttribute&lt;Lock&gt; lock;
+
+ public ConstantAttribute&lt;Lock&gt; lock() { return lock; }
+
+ public Key(Lock lock)
+ {
+ this.lock = new ConstantSimpleAttribute&lt;Lock&gt;(lock);
+ }
+
+}</programlisting>
+
+ <para>The class initialization parameters are optional. The following
+ class:</para>
+
+ <programlisting>Public:
+class Point
+{
+ Public: Exact x;
+ Public: Exact y;
+}</programlisting>
+
+ <para>Is equivalent to a Java class with a default constructor:</para>
+
+ <programlisting>public class Point
+{
+
+ private final Attribute&lt;Exact&gt; x = new SimpleAttribute&lt;Exact&gt;();
+
+ public SimpleAttribute&lt;Exact&gt; x() { return x; }
+
+ private final Attribute&lt;Exact&gt; y = new SimpleAttribute&lt;Exact&gt;();
+
+ public SimpleAttribute&lt;Exact&gt; y() { return y; }
+
+}</programlisting>
+
+ <para>A subclass must pass values to each superclass initialization
+ parameter.</para>
+
+ <programlisting>Public:
+class SpecialKey1 = Key( SpecialLock() )
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+class SpecialKey2(Lock lock) = Key(lock)
+{
+ ...
+}</programlisting>
+
+ <para>Which are equivalent to the Java:</para>
+
+ <programlisting>public class SpecialKey1
+ extends Key
+{
+ public SpecialKey1() {
+ super( SpecialLock() );
+ }
+ ...
+}</programlisting>
+
+ <programlisting>public class SpecialKey2
+ extends Key
+{
+ public SpecialKey2(Lock lock) {
+ super(lock);
+ }
+ ...
+}</programlisting>
+
+ <para>Note that additional initialization may be performed in any
+ method annotated <literal>AfterCreate</literal>. Invariants may
+ be asserted in any method annotated <literal>AfterInvoke</literal>.</para>
+
+ <programlisting>
+Public:
+class Point(Float x, Float y)
+{
+
+ Public: Float x = x;
+ Public: Float y = y;
+ Public Constant: Date created;
+
+ AfterCreate:
+ void create()
+ created = Date();
+
+ AfterInvoke:
+ void check()
+ assert sqrt( x**2 + y**2 ) &lt; 100.0;
+
+}</programlisting>
+
+ </section>
+
+ <section>
+ <title>Interfaces</title>
+
+ <para>Interfaces are declared according to the following:</para>
+
+ <programlisting>Annotations? Type*
+"interface" Identifier TypeParameters?
+TypeConstraintList?
+OPENBRACE
+( Attribute | Method )*
+CLOSEBRACE</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>interface PaymentStrategy
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+interface Comparable&lt;T&gt;
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Sequence&lt;T&gt;
+Collection&lt;T&gt;
+interface List&lt;T&gt;
+{
+ ...
+}</programlisting>
+
+ <para>
+ The types listed before the <literal>interface</literal> keyword are the supertypes.
+ All supertypes of an interface must be interfaces. The semantics of interface inheritance
+ are exactly the same as Java, and the above declarations are equivalent to the following
+ Java declarations:
+ </para>
+
+ <programlisting>interface PaymentStrategy
+{
+ ...
+}</programlisting>
+
+ <programlisting>public interface Comparable&lt;T&gt;
+{
+ ...
+}</programlisting>
+
+ <programlisting>public interface List&lt;T&gt;
+ extends Sequence&lt;T&gt;, Collection&lt;T&gt;
+{
+ ...
+}</programlisting>
+
+ </section>
+
+ <!--
+ <section>
+ <title>Constructors</title>
+
+ <para>Constructors are declared according to the following:</para>
+
+ <programlisting>Annotations? Identifier
+VariableList
+( SEMICOLON | ClosedBlock )</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public: User(String username, Person person);</programlisting>
+ <programlisting>Public: Integer(String string): value = parse(string);</programlisting>
+ <programlisting>Public: User(String u, Person p) { username = u; person = p; }</programlisting>
+
+ <para>
+ The semantics of constructor declarations are identical to Java.
+ </para>
+
+ <para>
+ A method body may omit the braces if it consists of exactly one statement. If
+ there is no constructor body at all, the constructor assigns each parameter to
+ the attribute with the same name.
+ </para>
+
+ <para>
+ A Ceylon constructor invocation is equivalent to a Java constructor invocation.
+ </para>
+
+ <programlisting>@FormalParameterNames({"username", "person"})
+public User(String username, Person person);</programlisting>
+
+ </section>
+ -->
+
+ <section>
+ <title>Methods</title>
+
+ <para>Methods are declared according to one of the following schemes:</para>
+
+ <programlisting>Annotations? Type+
+Identifier TypeParameters?
+VariableList
+TypeConstraintList?
+( SEMICOLON | ClosedBody )</programlisting>
+
+ <programlisting>Annotations? "void"
+Identifier TypeParameters?
+VariableList
+TypeConstraintList?
+( SEMICOLON | VoidBody )</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public Nullable: U get(Nullable: V key);</programlisting>
+
+ <programlisting>Protected:
+void init(Integer initialCount=0)
+ count=initialCount;</programlisting>
+
+ <programlisting>Public:
+Integer add(Integer x, Integer y)
+ return x + y;</programlisting>
+
+ <programlisting>Identifier Datetime createToken()
+ return Token();</programlisting>
+
+ <programlisting>Public:
+Boolean login()
+{
+ ...
+}</programlisting>
+
+ <programlisting>Protected:
+void destroy()
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+void print(Object...)
+{
+ ...
+}</programlisting>
+
+ <para>
+ A method body may omit the braces if it consists of exactly one statement. If
+ there is no method body at all, the method throws <literal>UnsupportedMethodException</literal>
+ when invoked.
+ </para>
+
+ <para>
+ The semantics of method declarations are identical to Java, except that Ceylon methods
+ may declare optional parameters. Methods with optional parameters may not be overloaded.
+ When a method with an optional parameter is called, and a value is not assigned to the
+ optional parameter by the caller, the default value specified by the initializer is used.
+ </para>
+
+ <!--
+ <para>
+ The semantics of method declarations are identical to Java, except that Ceylon methods
+ may declare multiple types for any formal parameter and multiple return types. This
+ indicates that the value passed or returned must implement or extend all the declared
+ types.
+ </para>
+ -->
+
+ <para>The Ceylon compiler preserves the names of method parameters.</para>
+
+ <programlisting>@FormalParameterNames({"x", "y"})
+public Integer add(Integer x, Integer y) { ... }</programlisting>
+
+ <para>
+ A Ceylon method invocation is equivalent to a Java method invocation.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Attributes</title>
+
+ <para>Attributes are declared according to the following:</para>
+
+ <programlisting>Annotations? Type+
+Identifier
+( Initializer? SEMICOLON | ClosedBody | OpenBody "assign" VoidBody )</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Protected: String firstName;</programlisting>
+ <programlisting>Integer count = 0;</programlisting>
+ <programlisting>Public: Float total
+ return find (Float sum = 0.0)
+ for (LineItem li in lineItems)
+ sum += li.amount;</programlisting>
+ <programlisting>Public: String name
+{
+ return " ".join(firstName, lastName);
+}
+assign
+{
+ Iterator tokens = name.tokens().iterator();
+ firstName = tokens.next();
+ lastName = tokens.next();
+}</programlisting>
+
+ <programlisting>Public:
+String name
+ return renderName()
+ assign parseName(name);</programlisting>
+
+ <para>
+ An attribute declaration is equivalent to a Java method declaration together with
+ a Java field declaration, both of type <literal>lang.Attribute</literal>, both with
+ the same name as the attribute.
+ </para>
+
+ <para>
+ When getter code is specified, the field is initialized to an instance
+ of an anonymous inner subclass of <literal>lang.Attribute</literal> that overrides
+ the <literal>get()</literal> and <literal>set()</literal> methods with the content of
+ the getter and setter code blocks, if any. For example:
+ </para>
+
+ <programlisting>Public: Float total
+ return items.totalPrice;</programlisting>
+
+ <para>is equivalent to this Java code:</para>
+
+ <programlisting>private final Attribute&lt;Float&gt; total = new Attribute&lt;Float&gt;() {
+ @Override public Float get() { return items.get().totalPrice; }
+};
+
+public Attribute&lt;Float&gt; total() { return total; }</programlisting>
+
+ <para>While:</para>
+
+ <programlisting>Public: String name { return renderName(); } assign { parseName(name); }</programlisting>
+
+ <para>is equivalent to this Java code:</para>
+
+ <programlisting>private final Attribute&lt;String&gt; name = new Attribute&lt;String&gt;() {
+ @Override public String get() { return renderName(); }
+ @Override public void set(String value) { parseName(value); }
+};
+
+public Attribute&lt;String&gt; name() { return name; }</programlisting>
+
+ <para>
+ If getter code is not specified, the equivalent Java declaration uses a
+ an instance of <literal>lang.SimpleAttribute</literal>. For example:
+ </para>
+
+ <programlisting>Protected: String firstName;</programlisting>
+
+ <para>is equivalent to this Java code:</para>
+
+ <programlisting>private final Attribute&lt;String&gt; firstName = new SimpleAttribute&lt;String&gt;();
+
+protected Attribute&lt;String&gt; firstName() { return firstName; }</programlisting>
+
+ <para>While:</para>
+
+ <programlisting>Integer count = 0;</programlisting>
+
+ <para>is equivalent to this Java code:</para>
+
+ <programlisting>private final Attribute&lt;Integer&gt; count = new SimpleAttribute&lt;Integer&gt;(0);
+
+private Attribute&lt;Integer&gt; count() { return count; }</programlisting>
+
+ <para>TODO: Should we generate getters and setters, just for interop with Java?</para>
+
+ <para>
+ This attribute getter call:
+ </para>
+
+ <programlisting>String name = person.name;</programlisting>
+
+ <para>
+ is equivalent to the following Java code:
+ </para>
+
+ <programlisting>String name = person.name().get();</programlisting>
+
+ <para>
+ This attribute setter call:
+ </para>
+
+ <programlisting>person.name = "Gavin";</programlisting>
+
+ <para>
+ is equivalent to the following Java code:
+ </para>
+
+ <programlisting>person.name().set("Gavin");</programlisting>
+
+ <para>
+ If getter code is specified, and <literal>assign</literal> is not specified,
+ the attribute is not settable, and any attempt to assign to the attribute will
+ result in a compiler error.
+ </para>
+
+ <para>
+ Unlike Java fields, Ceylon attribute access is polymorphic and attribute definitions
+ may be overridden by subclasses. A Ceylon attribute may declare multiple types, in which
+ case the value of the attribute must be an instance of all the declared types.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Selectors</title>
+
+ <para>Selectors are declared according to the following:</para>
+
+ <programlisting>Annotations? Type*
+"selector" Identifier
+VariableList?
+OPENBRACE
+SelectorValue (COMMA SelectorValue)*
+( SEMICOLON ( Attribute | Method )* )?
+CLOSEBRACE</programlisting>
+
+ <para>Where:</para>
+
+ <programlisting>SelectorValue := Identifier ( OPENPAREN ( Expression (COMMA Expression)* )? CLOSEPAREN )?</programlisting>
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public:
+selector DayOfWeek
+{
+ MON, TUES, WED, THURS, FRI, SAT, SUN
+}</programlisting>
+
+ <programlisting>Public:
+selector DayOfWeek(String name)
+{
+ MON("Monday"), TUES("Tuesday"), ...
+
+ Public Constant: String name = name;
+
+}</programlisting>
+
+ <programlisting>Public:
+Comparator&lt;String&gt;
+selector ComparisonOperation {
+ ...
+}</programlisting>
+
+ <para>
+ The types listed before the <literal>selector</literal> keyword are the supertypes.
+ All supertypes of a selector must be interfaces. Any constructors must be private. The
+ semantics of selector declarations and selector interface implementation are exactly the
+ same as for Java <literal>enum</literal>s, except that a Ceylon selector implicitly
+ implements <literal>lang.Selector</literal>, and the above declarations are equivalent to
+ the following Java declarations:
+ </para>
+
+ <programlisting>public enum DayOfWeek
+ implements Selector&lt;DayOfWeek&gt;
+{
+ MON, TUES, WED, THURS, FRI, SAT, SUN
+}</programlisting>
+
+ <programlisting>public enum DayOfWeek
+ implements Selector&lt;DayOfWeek&gt;
+{
+
+ MON("Monday"), TUES("Tuesday"), ...
+
+ private DayOfWeek(String name) { ... }
+
+ ...
+
+}</programlisting>
+ <programlisting>public enum Comparison
+ implements Comparator&lt;String&gt;, Selector&lt;Comparison&gt;
+{
+ ...
+}</programlisting>
+
+ <para>TODO: let selectors have abstract methods that are overridden by the selector values!</para>
+
+ </section>
+
+ <section>
+ <title>Functors</title>
+
+ <para>Functors are declared according to the following:</para>
+
+ <programlisting>Annotations? ( Type+ | "void" )
+"functor" Identifier TypeParameters?
+VariableList
+TypeConstraintList?
+SEMICOLON</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public: Comparison functor Order&lt;T&gt;(T x, T y);</programlisting>
+
+ <para>
+ A functor declaration is equivalent to a Java abstract class declaration that extends
+ <literal>lang.Functor</literal> with a single abstract method declaration. For the example
+ above, the equivalent Java declaration is:
+ </para>
+
+ <programlisting>public abstract class Order&lt;T&gt;
+ extends Functor&lt;Comparison&gt;
+{
+ public abstract Comparison call(T x, T y);
+
+ protected Order(Object... locals)
+ {
+ super(locals);
+ }
+
+}</programlisting>
+
+ <para>
+ Consider the following functor literal:
+ </para>
+
+ <programlisting>Order&lt;String&gt; order = (String x, String y) { x &lt;=&gt; y }</programlisting>
+
+ <para>Or:</para>
+
+ <programlisting>Order&lt;String&gt; order = (String x, String y) x &lt;=&gt; y;</programlisting>
+
+ <para>
+ These literals are equivalent to this Java code:
+ </para>
+
+ <programlisting>Order&lt;String&gt; order = new Order&lt;String&gt;()
+{
+ public Comparison call(String x, String y)
+ {
+ return Comparison.compare(x,y);
+ }
+};</programlisting>
+
+ <para>
+ And this functor invocation:
+ </para>
+
+ <programlisting>Boolean result = order("Gavin", "Emmanuel");</programlisting>
+
+ <para>
+ Is equivalent to this Java code:
+ </para>
+
+ <programlisting>Boolean result = order.call("Gavin", "Emmanuel");</programlisting>
+
+ </section>
+
+ <section>
+ <title>Decorators</title>
+
+ <para>Decorators are declared according to the following:</para>
+
+ <programlisting>Annotations? Type*
+"decorator" Identifier TypeParameters?
+TypeConstraintList?
+OPENPAREN Variable CLOSEPAREN
+OPENBRACE Method* CLOSEBRACE</programlisting>
+
+ <para>Types appearing before the <literal>decorator</literal> keyword must be interfaces, and
+ are called the <emphasis>introduced types</emphasis>. Methods declared by a decorator are
+ called <emphasis>introduced methods</emphasis>.</para>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Public:
+decorator CollectionUtils&lt;T&gt;(Collection&lt;T&gt; collection)
+{
+ ...
+}</programlisting>
+
+ <programlisting>Public:
+Comparable&lt;User&gt;
+decorator ComparableUser(User u)
+{
+ ...
+}</programlisting>
+
+ <para>
+ A decorator declaration is equivalent to a Java class declaration. For example:
+ </para>
+
+ <programlisting>Public:
+decorator CollectionUtils&lt;T&gt;(Collection&lt;T&gt; collection)
+{
+
+ Public:
+ Collection&lt;T&gt; nonZeroElements()
+ return collection.exclude(0);
+
+ Public Override:
+ void clear()
+ if ( collection.isEmpty() )
+ throw new IllegalStateException()
+ else
+ collection.clear();
+
+}</programlisting>
+
+ <para>
+ is equivalent to this Java declaration:
+ </para>
+
+ <programlisting>public final class CollectionUtils&lt;T&gt;
+{
+
+ private final Collection&lt;T&gt; collection
+
+ public CollectionUtils(Collection&lt;T&gt; collection)
+ {
+ this.collection = collection;
+ }
+
+ public Collection&lt;T&gt; nonZeroElements()
+ {
+ return collection.exclude(0);
+ }
+
+ public void clear() {
+ if ( collection.isEmpty() )
+ throw new IllegalStateException()
+ else
+ collection.clear();
+ }
+
+}</programlisting>
+
+ <para>And this decorator declaration:</para>
+
+ <programlisting>Public:
+Comparable&lt;User&gt;
+decorator ComparableUser(User u)
+{
+
+ Public: Comparison compareTo(User other)
+ other.userId &lt;=&gt; u.userId;
+
+}</programlisting>
+
+ <para>
+ is equivalent to this Java declaration:
+ </para>
+
+ <programlisting>public final class ComparableUser
+ implements Comparable&lt;User&gt;
+{
+
+ private final User u;
+
+ public ComparableUser(User u)
+ {
+ this.u = u;
+ }
+
+ public Comparison compareTo(User other)
+ {
+ return Comparison.compare(other.userId, u.userId);
+ }
+
+}</programlisting>
+
+ <para>
+ Finally, this introduced method call:
+ </para>
+
+ <programlisting>Collection&lt;Integer&gt; result = collection.nullElements();</programlisting>
+
+ <para>
+ Is equivalent to this Java code:
+ </para>
+
+ <programlisting>Collection&lt;Integer&gt; result = new CollectionUtils(collection).nullElements();</programlisting>
+
+ </section>
+
+ <section>
+ <title>Converters</title>
+
+ <para>Converters are declared according to the following:</para>
+
+ <programlisting>Annotations? Type
+"converter" Identifier TypeParameters?
+TypeConstraintList?
+OPENPAREN Variable CLOSEPAREN
+ClosedBody</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>User
+converter PersonUser(Person person)
+ return person.user;</programlisting>
+
+ <para>
+ A converter declaration is equivalent to a Java class declaration. The example above is
+ equivalent to the following Java class:
+ </para>
+
+ <programlisting>public final class PersonUser
+ extends Converter&lt;Person, User&gt;
+{
+ @Override User convert(Person person) {
+ return person.user;
+ }
+}</programlisting>
+
+ <para>The Ceylon compiler searches for an appropriate converter whenever a value is
+ assigned to a non-assignable type. If a converter for the types is found, the
+ compiler inserts a call to the converter. For example, this Ceylon assignment:</para>
+
+ <programlisting>Person person = ...;
+User user = person;</programlisting>
+
+ <para>Is equivalent to the following Java code:</para>
+
+ <programlisting>Person person = ...;
+User user = new PersonUser().convert(person);</programlisting>
+
+ </section>
+
+ <section>
+ <title>Variables</title>
+
+ <para>(Local) variables are declared according to the following:</para>
+
+ <programlisting>Annotations? Type+ Identifier Initializer? SEMICOLON</programlisting>
+
+ <para>
+ For example:
+ </para>
+
+ <programlisting>Nullable: String firstName;</programlisting>
+ <programlisting>Integer count = 0;</programlisting>
+
+ <para>
+ The semantics of variable declarations are identical to Java local variables, except
+ that Ceylon variables may declare multiple types. This indicates that the value must
+ implement or extend all the declared types.
+ </para>
+
+ </section>
+
+</chapter>
View
422 en/modules/expressions.xml
@@ -0,0 +1,422 @@
+<chapter id="expressions">
+ <title>Expressions</title>
+ <!--
+ <programlisting>items.accumulate&lt;Float&gt;( 0.0, (Float sum, Item i): sum+i.amount )</programlisting>
+ -->
+
+ <section>
+ <title>Invocations</title>
+
+ <para>Methods, classes, class instances and functors are <emphasis>invokable</emphasis>.
+ Invocation of a class is called <emphasis>instantiation</emphasis>. Invocation of a
+ class instance is called <emphasis>attribute configuration</emphasis>.</para>
+
+ <para>Any invocation must specify values for parameters, either by listing or naming
+ parameter values. Required parameters must be specified. Optional parameters and
+ varargs may also be specified.</para>
+
+ <programlisting>ParameterValueSet := ParameterValueList | NamedParameterValueList</programlisting>
+
+ <para>When parameter values are listed, required parameters are assigned first, in the order
+ in which they were declared, followed by optional parameters, in the order they were declared.
+ If there are any remaining optional parameters, they will be assigned their default values.
+ On the other hand, if any parameter values are unassigned, they will be treated as varargs.</para>
+
+ <programlisting>ParameterValueList := OPENPAREN ( ParameterValue (COMMA ParameterValue)* )? CLOSEPAREN</programlisting>
+
+ <programlisting>ParameterValue := Expression</programlisting>
+
+ <para>When parameter values are named, required and optional parameter values are specified
+ by name. Vararg parameter values are specified by listing them.</para>
+
+ <programlisting>NamedParameterValueList :=
+OPENBRACE
+NamedParameterValue*
+( VarargParameterValue (COMMA VarargParameterValue)* )?
+CLOSEBRACE</programlisting>
+
+ <programlisting>NamedParameterValue := Identifier Initializer SEMICOLON</programlisting>
+
+ <programlisting>VarargParameterValue := Expression | Variable Initializer | ForExpression</programlisting>
+
+ <para>A vararg parameter may be a local variable declaration. Multiple vararg parameters may be
+ constructed using a <literal>for</literal> comprehension.</para>
+
+ <para>TODO: should there be a special syntax to "spread" the values of a list into vararg
+ parameters, eg. <literal>*list</literal>.</para>
+
+ <section>
+ <title>Method invocation</title>
+
+ <para>Method invocations follow the following schema.</para>
+
+ <programlisting>MethodInvocation := (Expression DOT)? Identifier ParameterValueSet</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>log.info("Hello world!")</programlisting>
+ <programlisting>log.info { message = "Hello world!"; }</programlisting>
+ <programlisting>printer.print { join = ", "; "Gavin", "Emmanuel", "Max", "Steve" }</programlisting>
+ <programlisting>printer.print { "Names: ", for (Person p in people) p.name }</programlisting>
+
+ <para>The value of a method invocation is the return value of the method.
+ The parameter values are passed to the formal parameters of the method.</para>
+
+ </section>
+
+ <section>
+ <title>Static method invocation</title>
+
+ <para>Static method invocations follow the following schema.</para>
+
+ <programlisting>StaticMethodInvocation := (Type DOT)? Identifier ParameterValueSet</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>HashCode.calculate(DEFAULT, firstName, initial, lastName)</programlisting>
+ <programlisting>HashCode.calculate { algorithm=DEFAULT; firstName, initial, lastName }</programlisting>
+
+ <para>The value of a static method invocation is the return value of the static method.
+ The parameter values are passed to the formal parameters of the method.</para>
+
+ </section>
+
+ <section>
+ <title>Class instantiation</title>
+
+ <para>Classes may be instantiated according to the following schema:</para>
+
+ <programlisting>Instantiation := Type ParameterValueSet</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Map&lt;String, Person&gt;(entries)</programlisting>
+ <programlisting>Point { x=1.1; y=-2.3; }</programlisting>
+ <programlisting>ArrayList&lt;String&gt; { capacity=10; "gavin", "max", "emmanuel", "steve", "christian" }</programlisting>
+
+ <programlisting>Panel {
+ label = "Hello";
+ Input i = Input(),
+ Button {
+ label = "Hello";
+ action = () {
+ log.info(i.value);
+ }
+ }
+}</programlisting>
+
+ <para>The value of a class instantiation is a new instance of the class.
+ The parameter values are passed to the initialization parameters of the
+ class. If the class has no initialization parameters, they are assigned
+ directly to attributes of the class (in this case, named parameters must
+ be used).</para>
+
+ </section>
+
+ <section>
+ <title>Enumeration instantiation</title>
+
+ <para>Enumerations may be instantiated according to the following
+ simplified syntax:</para>
+
+ <programlisting>EnumerationInstantiation := OPENBRACE ParameterValues CLOSEBRACE</programlisting>
+
+ <para>In this case, there is no need to explicitly specify the type.</para>
+
+ <para>For example:</para>
+
+ <programlisting>Enumeration&lt;String&gt; names = { "gavin", "max", "emmanuel", "steve", "christian" };</programlisting>
+
+ </section>
+
+ <section>
+ <title>Inline classes</title>
+
+ <para>Inline classes may be instantiated according to:</para>
+
+ <programlisting>InlineClass := Annotations Type* Instantiation NamedParameterValueAndMemberList</programlisting>
+
+ <programlisting>NamedParameterValueAndMemberList :=
+OPENBRACE
+NamedParameterValue* ParameterValues?
+( Method | Attribute | Assert SEMICOLON )*
+CLOSEBRACE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Task task = Task() {
+ timeout=1000;
+ Override: void run() { ... }
+ Override: void fail(Exception e) { ... }
+}</programlisting>
+
+ <programlisting>return Transactional: Resource Database() {
+ url = "jdbc:hsqldb:.";
+ username = "gavin";
+ password = "foobar";
+ void create() open();
+ void destroy() close();
+};</programlisting>
+
+ <para>The value of an inline class instantiation is a new instance of the inline class.
+ The named parameter values are assigned directly to attributes of the superclass.</para>
+
+ </section>
+
+ <section>
+ <title>Attribute configuration</title>
+
+ <para>Attribute configuration follows the following schema.</para>
+
+ <programlisting>AttributeConfiguration := Expression NamedParameterValueList</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>person { firstName="Gavin"; initial='A'; lastName="King"; }</programlisting>
+
+ <para>The value of an attribute configuration is the instance being configured.
+ The parameter values are assigned to attributes of the instance.</para>
+
+ </section>
+
+ <section>
+ <title>Functor invocation</title>
+
+ <para>Functor invocations follow the following schema.</para>
+
+ <programlisting>MethodInvocation := Expression ParameterValues</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>compare("AAA", "aaa")</programlisting>
+ <programlisting>compare { x = "AAA"; y = "aaa"; }</programlisting>
+
+ <para>The value of a functor invocation is the return value of the functor.
+ The parameter values are passed to the formal parameters of the functor
+ implementation.</para>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>Control expressions</title>
+
+ <section>
+ <title><literal>find</literal></title>
+
+ <para>The <literal>find</literal> expression has the following form:</para>
+
+ <programlisting>FindExpression := "find" OPENPAREN Variable Initializer? CLOSEPAREN OpenBlock</programlisting>
+
+ <para>The construct evaluates to the value of the variable after
+ executing the block. All execution paths must result in an
+ initialized variable.</para>
+
+ <programlisting>Public: String welcome
+ return find (String greeting)
+ if (user exists)
+ greeting = "Hi ${user.name}!"
+ else
+ greeting = "Hello World!";</programlisting>
+
+ <programlisting>return find (Nullable: Person p) {
+ using (Session s = sf.openSession())
+ try
+ p = s.get(#Person, pid)
+ catch (NotFoundException nfe)
+ p = null;
+ if (p.deleted) p = null;
+};</programlisting>
+
+ <programlisting>Person gavin = find (Person gavin)
+ for (Person p ~> people)
+ if (p.firstName.lower == "gavin")
+ found gavin = if (p.deleted) null else p
+ fail
+ throw NotFoundException();</programlisting>
+
+ <programlisting>return find (Boolean allowed=false)
+ for (Permission p ~> user.permissions)
+ if (p.action == action &amp;&amp; p.object = object)
+ found allowed=true;</programlisting>
+
+ <programlisting>log.info {
+ message = find (Float sum=0.0)
+ for (Order o~>orders)
+ sum += o.total;
+}</programlisting>
+
+ <programlisting>return find (OpenList&lt;Person&gt; adults=none)
+ for (Person p~>people)
+ if (p.age>=18) adults.add(p);</programlisting>
+
+ <programlisting>return find (OpenMap&lt;String, Integer&gt; ages=none)
+ for (Person p~>people) ages.add( p.name->p.age );</programlisting>
+
+ </section>
+
+ <section>
+ <title><literal>if/else</literal></title>
+
+ <para>The <literal>if/else</literal> expression has the following form:</para>
+
+ <programlisting>IfElseExpression :=
+"if" OPENPAREN Condition (COMMA Condition) CLOSEPAREN CaseExpression
+"else" CaseExpression</programlisting>
+
+ <programlisting>CaseExpression := Expression | ThrowDirective | FoundDirective | BreakDirective</programlisting>
+
+ <para>If all conditions are satisfied, the whole expression evaluates
+ to the value of the first expression. Otherwise, the whole expression
+ evaluates to the value of the second expression.</para>
+
+ <para>For example:</para>
+
+ <programlisting>Public: String welcome
+ return if (user exists)
+ "Hi ${user.name}!"
+ else
+ "Hello World!";</programlisting>
+
+ <programlisting>Boolean paid = if (Payment payment = order.payment exists) payment.paid else false;</programlisting>
+
+ <programlisting>Nullable:String name = if (person exists, person.active) "$(person.firstName) $(person.lastName)";</programlisting>
+
+ </section>
+
+ <section>
+ <title><literal>switch/case/else</literal></title>
+
+ <para>The <literal>switch/case/else</literal> expression has the following form:</para>
+
+ <programlisting>SwitchCaseElseExpression :=
+"switch" OPENPAREN Expression CLOSEPAREN
+( "case" "null" CaseExpression )?
+( "case" OPENPAREN Expression (COMMA Expression)* CLOSEPAREN CaseExpression )*
+( "else" CaseExpression )?</programlisting>
+
+ <para>The whole expression evaluates to the value of the first case expression
+ for which the case value tests true.</para>
+
+ <para>For example:</para>
+
+ <programlisting>PaymentProcessor processor
+ return switch (payment.type)
+ case null throw NoPaymentTypeException
+ case (CREDIT, DEBIT) cardPaymentProcessor
+ case (CHECK) checkPaymentProcessor
+ else interactivePaymentProcessor;</programlisting>
+
+ <programlisting>log.info {
+ message = switch (num)
+ case (0) "Zero"
+ case (1) "Unity"
+ else $num
+}</programlisting>
+
+ </section>
+
+ <section>
+ <title><literal>for/fail</literal></title>
+
+ <para>The <literal>for/fail</literal> expression has one of the following forms:</para>
+
+ <programlisting>ForExpression :=
+"for" OPENPAREN Iteration (SEMICOLON Iteration)* CLOSEPAREN
+( "by" OPENPAREN Order (SEMICOLON Order) CLOSEPAREN )?
+Expression?</programlisting>
+
+ <programlisting>ForAnyAllExpression :=
+"for" ("any"|"all") OPENPAREN Iteration (SEMICOLON Iteration)* CLOSEPAREN
+Expression</programlisting>
+
+ <programlisting>ForFailExpression :=
+"for" OPENPAREN Iteration (SEMICOLON Iteration)* CLOSEPAREN
+CaseExpression
+"fail" CaseExpression</programlisting>
+
+ <programlisting>Order := Expression ("asc"|"desc")</programlisting>
+
+ <para>The semantics of the expression depend upon whether the <literal>any</literal> or
+ <literal>all</literal> modifier appears, and upon whether a <literal>fail</literal>
+ expression appears.</para>
+
+ <para>If a <literal>fail</literal> expression appears, the whole expression
+ evaluates to the value of the fail expression, unless the loop exists early
+ due to execution of a <literal>found</literal> directive, in which case
+ the whole expression evaluates to the value specified by the
+ <literal>found</literal> directive.</para>
+
+ <para>If <literal>any</literal> or <literal>all</literal> is specified,
+ the element expression must be of type <literal>Boolean</literal>, and the
+ whole expression evaluates to a <literal>Boolean</literal> value.</para>
+
+ <para>If neither modifier appears, and if no <literal>fail</literal> expression appears,
+ the whole expression evaluates to an enumeration of element expression values, one element
+ for each iteration of the loop (that satisfies the all iteration conditions). If no expression
+ appears, the result is an enumeration of elements of the first iteration. If <literal>by</literal>
+ appears, the results are ordered according to the order expression values. Each
+ comparison expression must be of type <literal>Comparable</literal>.</para>
+
+ <para>For example:</para>
+
+ <programlisting>List&lt;String&gt; adults = for (Person p in people: p.age>18);</programlisting>
+
+ <programlisting>List&lt;String&gt; adultNames = for (Person p in people: p.age>18) p.name;</programlisting>
+
+ <programlisting>Public: List&lt;Person&gt; employees(Country country)
+ return for (Organization o in orgs: o.country==country; Person p in o.employees) p;</programlisting>
+
+ <programlisting>log.info( ", ".join( for (String key -> Integer value in map) "$key = $value" ) );</programlisting>
+
+ <programlisting>return for all (LineItem li in lineItems) li.quantity>0;</programlisting>
+
+ <programlisting>Person gavin = for (Person p in people)
+ if (p.name.lower=="gavin") found gavin
+ fail null;</programlisting>
+
+ </section>
+
+ <section>
+ <title><literal>using</literal></title>
+
+ <para>The <literal>using</literal> expression has the form:</para>
+
+ <programlisting>UsingExpression := "using" OPENPAREN Resource (COMMA Resource)* CLOSEPAREN Expression</programlisting>
+
+ <para>The whole expression evaluates to the value of the expression.</para>
+
+ <para>For example:</para>
+
+ <programlisting>return using (semaphore) map[key];</programlisting>
+
+ <programlisting>Person p = using ( Session s = Session() ) s.get(#Person, id);</programlisting>
+
+ </section>
+
+ <section>
+ <title><literal>try/catch</literal></title>
+
+ <para>The <literal>try/catch</literal> expression has the form:</para>
+
+ <programlisting>TryCatchFinallyExpression :=
+"try" Expression
+("catch" OPENPAREN Variable CLOSEPAREN CaseExpression)+</programlisting>
+
+ <para>If the try block executes without exception, the construct evaluates to the
+ value of the try block. If an exception is handled by a catch block, the construct
+ evaluates to the value of that catch block.</para>
+
+ <para>For example:</para>
+
+ <programlisting>Person p = try
+ s.get(#Person, id)
+ catch (NotFoundException e)
+ null;</programlisting>
+
+ </section>
+
+ </section>
+
+</chapter>
View
212 en/modules/introduction.xml
@@ -0,0 +1,212 @@
+<chapter id="introduction">
+ <title>Introduction</title>
+
+ <para>
+ Ceylon is a statically-typed, general-purpose, object-oriented language
+ featuring a syntax derived from the class of languages that includes
+ Java and C#. Ceylon programs execute in any standard Java Virtual Machine
+ and, like Java, take advantage of the memory management and concurrency
+ features of that environment. The Ceylon compiler is able to compile
+ Ceylon code that calls Java classes or interfaces, and Java code that
+ calls Ceylon classes or interfaces. Ceylon differs from Java by
+ eliminating primitive types and arrays and introducing a number of
+ improvements (inspired in some cases by dynamic languages such as SmallTalk,
+ Python and Ruby) to the language and type system that reduce verbosity
+ compared to Java or C#. Moreover, Ceylon provides its own native SDK as a
+ replacement for the Java platform class libraries.
+ </para>
+
+ <para>
+ Ceylon features the same inheritance and generic type models as Java.
+ There are no primitive types or arrays in Ceylon, so all values are
+ instances of the type hierarchy root <literal>lang.Object</literal>.
+ However, the Ceylon compiler is permitted to optimize certain code to
+ take advantage of the better performance of primitive types on the JVM.
+ </para>
+
+ <para>
+ By default, Ceylon attributes and variables do not accept null values.
+ Nullable variables and attributes must be explicitly declared using the
+ <literal>Nullable</literal> annotation. Nullable expressions are not
+ assignable to non-<literal>Nullable</literal> variables or attributes,
+ except via use of the <literal>if ( ... exists)</literal> construct. Thus,
+ the Ceylon compiler is able to detect illegal use of a null value at
+ compile time. Therefore, there is no equivalent to Java's
+ <literal>NullPointerException</literal> in Ceylon.
+ </para>
+
+ <para>
+ Ceylon classes do not contain fields, in the traditional sense.
+ Instead, Ceylon supports only a higher-level construct:
+ <emphasis>attributes</emphasis>, which are similar to C# properties.
+ </para>
+
+ <para>
+ Ceylon methods are similar to Java methods. However, Ceylon does not
+ feature any Java-like constructor declaration and so each Ceylon class
+ has exactly one "constructor". Instead, Ceylon provides a sophisticated
+ object initialization syntax.
+ </para>
+
+ <para>
+ Ceylon control flow structures are significantly enhanced versions of the
+ traditional constructs found in C, C# and Java, including features inspired
+ by Python. Unlike C or Java, Ceylon's control flow structures may be used to
+ produce a value, eliminating the need for many local variables.
+ </para>
+
+ <para>
+ Ceylon features a large set of operators, including most of the operators
+ supported by C and Java. True operator overloading is not supported. However,
+ each operator is defined to act upon a certain class or interface type,
+ allowing application of the operator to any class which extends or implements
+ that type.
+ </para>
+
+ <para>
+ True closures are not supported. However, Ceylon does support
+ <emphasis>functors</emphasis>, which provide many of the same benefits.
+ </para>
+
+ <para>
+ True open classes are not supported. However, Ceylon supports
+ <emphasis>decorators</emphasis>, which allows addition of methods
+ and interfaces to existing types, and overriding of existing
+ methods. Decorators only affect the behavior
+ </para>
+
+ <para>
+ Ceylon features an exceptions model inspired by Java and C#, but
+ checked exceptions are not supported. In addition, Ceylon provides the
+ <literal>using</literal> construct which simplifies management of
+ heavyweight resources.
+ </para>
+
+ <para>
+ Ceylon introduces certain syntax extensions that support the definition
+ of domain-specific languages and expression of structured data. These
+ syntax extensions include significantly improved support for expressing
+ literal values, compared to Java. One application of this syntax is the
+ support for Java/C# like code annotations.
+ </para>
+
+ <para>
+ Ceylon provides sophisticated support for meta-programming, including
+ a typesafe metamodel and events. This facility is inspired by similar,
+ features found in dynamic languages such as Smalltalk, Python and Ruby,
+ and by the much more complex features found in aspect oriented languages
+ like Aspect J. Ceylon does not, however, support aspect oriented
+ programming as a language feature.
+ </para>
+
+ <para>
+ Finally, Ceylon provides an extensible type conversion facility that
+ allows values of different types to be treated as interchangeable by
+ the compiler. This facility makes it easy for Ceylon code to transparently
+ interoperate and inter-compile with Java code.
+ </para>
+
+ <section>
+ <title>A simple example</title>
+
+ <para>
+ Here's a classic example, implemented in Ceylon:
+ </para>
+
+ <programlisting>import system.Main;
+
+class Hello {
+
+ Main Static:
+ void hello() log.info("Hello, World!");
+
+}</programlisting>
+
+ <para>
+ This code defines a Ceylon class named <literal>Hello</literal>, with
+ a single method with no parameters and no return value, named
+ <literal>hello</literal>. Two <emphasis>annotations</emphasis> appear on
+ the method declaration. The <literal>Static</literal> annotation specifies
+ that the method may be called without any receiving instance of
+ <literal>Hello</literal>. The <literal>Main</literal> annotation specifies
+ that this method is called automatically when the virtual machine is
+ started. The <literal>hello()</literal> method calls the
+ <literal>info()</literal> method of an attribute named
+ <literal>log</literal> defined by the <literal>lang.Object</literal> class.
+ By default, this method displays its parameter on the console.
+ </para>
+
+ <para>
+ This improved version of the program takes a name as input from the console:
+ </para>
+
+ <programlisting><![CDATA[import system.Main;
+import container.Current;
+import collections.List;
+
+class Hello {
+
+ Main Static:
+ void hello(Current: Process process) {
+
+ String name = process.args.firstOrNull default "World";
+
+ log.info("Hello, $name!");
+
+ }
+
+}]]></programlisting>
+
+ <para>
+ This time, the <literal>hello()</literal> method has a parameter. This
+ parameter value is <emphasis>injected</emphasis> by Ceylon's built-in
+ dependency management engine. The <literal>Process</literal> object
+ has an attribute named <literal>args</literal>, which holds a
+ <literal>List</literal> of the program's command line arguments. The
+ local variable <literal>args</literal> is initialized from these
+ arguments. The <literal>default</literal> operator returns the
+ first argument that is not null. Finally, the value of the local
+ variable is interpolated into the message string.
+ </para>
+
+ <para>Finally, lets rewrite this program as a web page:</para>
+
+ <programlisting><![CDATA[import html.Html;
+import html.Head;
+import html.Body;
+import html.Div;
+import web.Page;
+
+Page { resource="/hello.html"; }:
+Html class Hello {
+
+ Current: Request request;
+
+ String name
+ return request.parameters["name"].firstOrNull
+ default "World";
+
+ head = Head { title="Hello World"; };
+
+ body = Body {
+ Div {
+ cssClass = "greeting";
+ "Hello, $name!"
+ },
+ Div {
+ cssClass = "footer";
+ "Powered by Ceylon."
+ }
+ };
+
+}]]></programlisting>
+
+ <para>This program demonstrates Ceylon's support for defining structured data,
+ in this case, HTML. The <literal>Hello</literal> class extends Ceylon's
+ <literal>Html</literal> class and specifies named parameter values for the
+ superclass constructor. The <literal>Page</literal> annotation specifies the
+ URL at which this HTML should be accessible.</para>
+
+ </section>
+
+</chapter>
View
443 en/modules/literals.xml
@@ -0,0 +1,443 @@
+<chapter id="literals">
+ <title>Literals</title>
+
+ <para>Ceylon supports a special literal value syntax for each of the following types
+ <literal>Integer</literal>, <literal>Float</literal>, <literal>String</literal>,
+ <literal>Byte</literal>, <literal>Character</literal>, <literal>Boolean</literal>,
+ <literal>Functor</literal> and <literal>Regex</literal>.
+ </para>
+
+ <programlisting>Literal :=
+BooleanLiteral |
+DatetimeLiteral | DateLiteral | TimeLiteral
+IntegerLiteral | FloatLiteral |
+CharacterLiteral | ByteLiteral |
+StringLiteral | RegexLiteral |
+EnumerationLiteral |
+FunctorLiteral |
+"this" | "super"</programlisting>
+
+ <section>
+ <title>Boolean literals</title>
+
+ <para>A boolean literal has this form:</para>
+
+ <programlisting>BooleanLiteral := "true" | "false"</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Boolean found = false;</programlisting>
+
+ <para>Equivalent to this Java code:</para>
+
+ <programlisting>Boolean found = lang.Boolean.FALSE;</programlisting>
+
+ </section>
+
+ <section>
+ <title>Datetime literals</title>
+
+ <para>A datetime literal has the form:</para>
+
+ <programlisting>DatetimeLiteral := "now"</programlisting>
+
+ <programlisting>DateLiteral :=
+SINGEQUOTE
+Digit{1,2} SLASH Digit{1,2} SLASH DIGIT{4}
+SINGEQUOTE</programlisting>
+
+ <programlisting>TimeLiteral :=
+SINGEQUOTE
+Digit{1,2} COLON Digit{2} ( COLON DIGIT{2} ( COLON DIGIT{3} )? )?
+(SPACE "AM"|"PM")?
+(SPACE Character{3,4})?
+SINGEQUOTE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Datetime datetime = now;</programlisting>
+ <programlisting>Date date = '25/03/2005';</programlisting>
+ <programlisting>Time time = '12:00 AM PST';</programlisting>
+
+ <para>Datetimes may be composed from dates and times using the <literal>@</literal> operator.</para>
+
+ <programlisting>Datetime datetime = '25/03/2005' @ '12:00 AM PST';</programlisting>
+
+ <para>The attributes <literal>hours</literal>, <literal>minutes</literal>, <literal>seconds</literal>,
+ <literal>years</literal>, <literal>months</literal>, <literal>days</literal>, <literal>weeks</literal>
+ of the <literal>Integer</literal> class let us construct durations.</para>
+
+ <programlisting>Duration&lt;Time&gt; duration = 12.hours + 34.minutes;</programlisting>
+ <programlisting>Duration&lt;Date&gt; duration = 1.year + 2.months + 3.days;</programlisting>
+
+ <para>Durations may be composed using the arithmetic operators <literal>+</literal>,
+ <literal>-</literal>, <literal>*</literal> and <literal>/</literal>.</para>
+
+ <programlisting>Duration&lt;Time&gt; duration = 1.seconds / 10 - 1.seconds / 1000;</programlisting>
+
+ <para>The methods <literal>before()</literal> and <literal>after()</literal> let us add and
+ subtract durations to and from datetimes.</para>
+
+ <programlisting>Time time = 10.seconds.before('12:00 AM');</programlisting>
+ <programlisting>Date date = 1.week.after('2/9/1974');</programlisting>
+
+ <para>The <literal>..</literal> operator lets us construct intervals:</para>
+
+ <programlisting>Interval&lt;Date&gt; timeRange = '0:0:00' .. '12:59:59 PM';</programlisting>
+ <programlisting>Interval&lt;Date&gt; dateRange = '1/1/2008' .. '31/12/2007';</programlisting>
+ <programlisting>Interval&lt;Datetime&gt; datetimeRange = '1/1/2008' @ '0:0:00' .. '31/12/2007' @ '12:59:59 PM';</programlisting>
+
+ </section>
+
+ <section>
+ <title>Integer literals</title>
+
+ <para>An integer literal has this form:</para>
+
+ <programlisting>IntegerLiteral =
+Digit+ |
+SINGLEQUOTE ( HexDigit{4} | HexDigit{8} ) SINGLEQUOTE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Integer i = i + 10;</programlisting>
+
+ <programlisting>panel.backgroundColor = 'FF33';</programlisting>
+
+ </section>
+
+ <section>
+ <title>Float literals</title>
+
+ <para>A float literal has this form:</para>
+
+ <programlisting>FloatLiteral :=
+Digit+ PERIOD Digit+
+( ("E"|"e")? (PLUS|MINUS)? Digit+ )?</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Public Static Constant: Float PI = 3.14159;</programlisting>
+
+ <para>Equivalent to this Java code:</para>
+
+ <programlisting>public static final Float PI = new lang.Float(3.14159f);</programlisting>
+
+ </section>
+
+ <section>
+ <title>String literals</title>
+
+ <para>A string literal has this form:</para>
+
+ <programlisting>StringLiteral = DOUBLEQUOTE ( Character+ | DOLLAR OPENBRACE Expression CLOSEBRACE )* DOUBLEQUOTE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>person.name = "Gavin";</programlisting>
+
+ <programlisting>log.info("$(Time()) $message");</programlisting>
+
+ <programlisting>String multilineString = "Strings may
+span multiple lines
+if you prefer.";</programlisting>
+
+ <para>The first example is equivalent to this Java code:</para>
+
+ <programlisting>person.name().set( new lang.String("Gavin") );</programlisting>
+
+ </section>
+
+ <section>
+ <title>Character literals</title>
+
+ <para>A character literal has this form:</para>
+
+ <programlisting>CharacterLiteral := SINGLEQUOTE Character SINGLEQUOTE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>if ( string[i] == '+' ) { ... }</programlisting>
+
+ <para>Equivalent to this Java code:</para>
+
+ <programlisting>if ( string.at(i).equals( new lang.Character('+') ) ) { ... }</programlisting>
+
+ </section>
+
+ <section>
+ <title>Byte literals</title>
+
+ <para>A byte literal has this form:</para>
+
+ <programlisting>ByteLiteral := SINGLEQUOTE ( BinaryDigit{8} | HexDigit{2} ) SINGLEQUOTE</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Byte masked = b &amp; '01101001';</programlisting>
+
+ <programlisting>Byte byte = 'A0';</programlisting>
+
+ <para>Equivalent to this Java code:</para>
+
+ <programlisting>Byte masked = b.and( new lang.Byte("01101001") );</programlisting>
+
+ <programlisting>Byte byte = new lang.Byte("A0")</programlisting>
+
+ </section>
+
+ <section>
+ <title>Regex literals</title>
+
+ <para>A regex literal has this form:</para>
+
+ <programlisting>RegexLiteral := BACKTICK RegularExpression BACKTICK</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Boolean isEmail = email.matches( `^\w+@((\w+)\.)+$` );</programlisting>
+
+ <programlisting>Integer quotedWords = `\W"w+"\W`.matcher(text).count();</programlisting>
+
+ <para>The second example is equivalent to this Java code:</para>
+
+ <programlisting>Integer quotedWords = new lang.Regex("\\W\"w+\"\\W").matcher(text).count();</programlisting>
+
+ </section>
+
+ <section>
+ <title>Functor literals</title>
+
+ <para>A functor literal has this form:</para>
+
+ <programlisting>FunctorLiteral :=
+(Type TypeParameters?)?
+( VariableList FunctorBody? | OPENPAREN MethodPointer CLOSEPAREN )</programlisting>
+
+ <programlisting>FunctorBody := Block | MethodDirective | Expression</programlisting>
+
+ <para>TODO: functor literal variable lists can't define default parameter values, they
+ are defined by the functor declaration.</para>
+
+ <!--
+ <programlisting>VariableAndConditionList := OPENPAREN Variables? (COLON Condition)? CLOSEPAREN</programlisting>
+ -->
+
+ <para>For example:</para>
+
+ <programlisting>Order&lt;Float&gt; order = Order&lt;Float&gt;(Float x, Float y) { return x&lt;=&gt;y; };</programlisting>
+
+ <programlisting>people.sort( Order&lt;Person&gt;(Person x, Person y) return y.name&lt;=&gt;x.name );</programlisting>
+
+ <programlisting>lineItems.sort( Order&lt;Float&gt;(lineItemComparator#compare) );</programlisting>
+
+ <programlisting>people.select( Select&lt;Person&gt;(Person p) return p.age>18 )
+ .collect( Collect&lt;Person&gt;(Person p) return p.name );</programlisting>
+
+ <!--
+ <programlisting>people.collect( Collect&lt;Person&gt;(Person p: p.age>18) return p.name );</programlisting>
+
+ <programlisting>people.select( Collect&lt;Person&gt;(Person p: p.age>18) );</programlisting>
+ -->
+
+ <para>The functor type may be omitted in variable assignments, return directives or
+ method parameters, if the type can be inferred.</para>
+
+ <programlisting>Order&lt;Float&gt; order = (Float x, Float y) { return x&lt;=&gt;y; };</programlisting>
+
+ <programlisting>people.sort( (Person x, Person y) return y.name&lt;=&gt;x.name );</programlisting>
+
+ <programlisting>lineItems.sort( (lineItemComparator#compare) );</programlisting>
+
+ <programlisting>people.select( (Person p) return p.age>18 )
+ .collect( (Person p) return p.name );</programlisting>
+ <!--
+ <programlisting>people.collect( (Person p: p.age>18) return p.name; );</programlisting>
+
+ <programlisting>people.select( (Person p: p.age>18) );</programlisting>
+ -->
+
+ <para>Furthermore, if a method takes exactly one closure as its argument, the
+ parentheses may be eliminated in the method call:</para>
+
+ <programlisting>amounts.sort(Float x, Float y)
+{
+ return x&lt;=&gt;y;
+}</programlisting>
+
+ <programlisting>people.sort(Person x, Person y)
+ return y.name&lt;=&gt;x.name;</programlisting>
+
+ <programlisting>lineItems.sort(lineItemComparator#compare);</programlisting>
+
+ <programlisting>people.select (Person p) { return p.age>18 }
+ .collect (Person p) { return p.name };</programlisting>
+ <!--
+ <programlisting>people.collect(Person p: p.age>18) return p.name;</programlisting>
+
+ <programlisting>people.select(Person p: p.age>18);</programlisting>
+ -->
+
+ <!--
+ <para>Finally, if the functor has exactly one parameter, the variable list
+ may be eliminated.</para>
+
+ <programlisting>people.select( return it.age>18 )
+ .collect( return it.name );</programlisting>
+ -->
+
+ <para>The following code:</para>
+
+ <programlisting>(0..10).each (Integer num)
+ log.info(num);</programlisting>
+
+ <para>Is equivalent to:</para>
+
+ <programlisting>new Range&lt;Integer&gt;(0, 10).each( new Do() {
+ @Override Boolean call(Integer x) {
+ ParentClass.this.log.info(num);
+ }
+ } );</programlisting>
+
+ <para>This code:</para>
+
+ <programlisting>Integer min = 0;
+Integer max = 0;
+List list = list.select(Integer x)
+ return x > min &amp;&amp; x &lt; max;</programlisting>
+
+ <para>Is equivalent to this Java code:</para>
+
+ <programlisting>Integer min = 0;
+Integer max = 10;
+List list = list.select( new Select(min, max) {
+ final Integer min = (Integer) locals[0];
+ final Integer max = (Integer) locals[1];
+ @Override Boolean call(Integer x) {
+ return x > min &amp;&amp; x &lt; max;
+ }
+ } );</programlisting>
+
+ <section>
+
+ <title>Possible extension</title>
+
+ <para>The following code:</para>
+
+ <programlisting>Integer min = 0;
+Integer max = 0;
+Integer count = 0;
+Integer size = list.each(Integer x) {
+ if ( x > min ) count++;
+ if ( x > max) max = x;
+};</programlisting>
+
+ <para>Is equivalent to this Java code:</para>
+
+ <programlisting>Integer min = 0;
+Integer max = 0;
+Integer count = 0;
+final List list$1 = list;
+final Select functor$1 = new Do(min, max, count) {
+ Integer min = (Integer) locals[0];
+ Integer max = (Integer) locals[1];
+ Integer count = (Integer) locals[2];
+ @Override Boolean call(Integer x) {
+ if ( x > min ) count++;
+ if ( x > max) max = x;
+ locals[0] = min;
+ locals[1] = max;
+ locals[2] = count;
+ }
+ };
+final Integer result$1 = list$1.each(functor$1);
+final Object[] locals$1 = functor$1.locals();
+min = (Integer) locals[0];
+max = (Integer) locals[1];
+count = (Integer) locals[2];
+Integer size = result$1;</programlisting>
+
+ <para>Or, perhaps:</para>
+
+ <programlisting>Integer min = 0;
+Integer max = 0;
+Integer count = 0;
+final List list$1 = list;
+final Select functor$1 = new Select(min, max, count) {
+ @Override Boolean call(Integer x) {
+ if ( x > locals[0] ) locals[3]++;
+ if ( x > locals[1] ) locals[1] = x;
+ }
+ };
+final Integer result$1 = list$1.each(functor$1);
+final Object[] locals$1 = functor$1.locals();
+min = (Integer) locals[0];
+max = (Integer) locals[1];
+count = (Integer) locals[2];
+Integer size = result$1;</programlisting>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>Enumeration literals</title>
+
+ <para>The following literal is supported, representing an
+ empty enumeration:</para>
+
+ <programlisting>"none"</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>Enumeration&lt;String&gt; enum = none;</programlisting>
+
+ <para>Equivalent to this Java code:</para>
+
+ <programlisting>Enumeration&lt;String&gt; enum = collections.Enumeration.emptyEnumeration&lt;String&gt;();</programlisting>
+
+ <para>There are no true literals for lists, sets or maps. However, the
+ <literal>..</literal> and <literal>-></literal> operators, together with
+ the convenient enumeration constructor syntax help us achieve the desired
+ effect.</para>
+
+ <programlisting>List&lt;Integer&gt; numbers = 1..10;</programlisting>
+ <programlisting>List&lt;String&gt; languages = { "Java", "Ceylon", "Smalltalk" };</programlisting>
+
+ <para>Enumerations are transparently converted to sets or maps,
+ allowing sets and maps to be initialized as follows:</para>
+
+ <programlisting>Map&lt;String, String&gt; map = { "Java"->"Boring...", "Scala"->"Difficult :-(", "Ceylon"->"Fun!" };</programlisting>
+ <programlisting>Set&lt;String&gt; set = { "Java", "Ceylon", "Scala" };</programlisting>
+ <programlisting>OpenList&lt;String&gt; list = none;</programlisting>
+
+ </section>
+
+ <section>
+ <title>Object literals</title>
+
+ <para>There are no true literals for objects. Rather, there is a nice syntax
+ for calling the class constructor, assigning attribute values (including
+ constant attribute values) and (optionally) overriding methods and attributes.
+ For example:</para>
+
+ <programlisting>Person gavin = Person {
+ firstName = "Gavin";
+ initial = 'A';
+ lastName = "King";
+ address = Address { ... };
+ birthdate = Date { day = 25; month = MARCH; year = ... }
+ employer = jboss;
+};</programlisting>
+
+ <programlisting>Person gavin = Person(jboss) {
+ firstName = "Gavin";
+ initial = 'A';
+ lastName = "King";
+ address = Address { ... };
+ birthdate = Date { day = 25; month = MARCH; year = ... }
+};</programlisting>
+
+ </section>
+
+</chapter>
View
1,267 en/modules/operators.xml
@@ -0,0 +1,1267 @@
+<chapter id="operators">
+ <title>Operators</title>
+
+ <para>Operators are syntactic shorthand for more complex expressions
+ involving method invocation or attribute access. Each operator is defined
+ for a particular type. There is support for user-defined operator
+ <emphasis>overloading</emphasis>. However, the semantics of an operator
+ may be customized by the implementation of the type that the operator
+ applies to.</para>
+
+ <para>For example, the following Ceylon code examples:</para>
+
+ <programlisting>Double z = x * y;</programlisting>
+
+ <programlisting>++count;</programlisting>
+
+ <programlisting>Integer j = i++;</programlisting>
+
+ <programlisting>x *= 2;</programlisting>
+
+ <programlisting>if ( x > 100 ) { ... }</programlisting>
+
+ <programlisting>User gavin = users["Gavin"];</programlisting>
+
+ <programlisting>List&lt;Item&gt; firstPage = list[0..20];</programlisting>
+
+ <programlisting>for ( Integer i in 1..10 ) { ... }</programlisting>
+
+ <programlisting>if ( name == value ) return ... ;</programlisting>
+
+ <programlisting>if ( x&gt;10 || x&lt;0 ) { ... }</programlisting>
+
+ <programlisting>log.info( "Hello " + $person + "!")</programlisting>
+
+ <programlisting>List&lt;String&gt; names = ArrayList&lt;Person&gt;()^.add(person1)^.add(person2)*.name;</programlisting>
+
+ <programlisting>Nullable: String name = person?.name;</programlisting>
+
+
+ <para>Are equivalent to the following (Ceylon) code:</para>
+
+ <programlisting>Double z = x.multiply(y);</programlisting>
+
+ <programlisting>count = count.successor;</programlisting>
+
+ <programlisting>Integer j = ( i = i.successor ).predecessor;</programlisting>
+
+ <programlisting>z = z.multiply(2);</programlisting>
+
+ <programlisting>if ( x.compare(100).larger ) { ... }</programlisting>
+
+ <programlisting>User gavin = users.value("Gavin");</programlisting>
+
+ <programlisting>List&lt;Item&gt; firstPage = list.range(0..20);</programlisting>
+
+ <programlisting>for ( Integer i in Range(1,10) ) { ... }</programlisting>
+
+ <programlisting>if ( if (name exists) name.equals(value) else if (value exists) false else true ) return ... ;</programlisting>
+
+ <programlisting>if ( x.compare(10).larger ) true else x.compare(0).smaller ) { ... }</programlisting>
+
+ <programlisting>log.info( "Hello ".join(person.string).join("!") )</programlisting>
+
+ <programlisting>List&lt;String&gt; names =
+ Spread&lt;String&gt; {
+ lhs: Chain&lt;String&gt; {
+ lhs: Chain&lt;String&gt; {
+ lhs: ArrayList();
+ Override: void call() { lhs.add(person1); } }.lhs
+ }
+ Override: void call() { lhs.add(person2); } }.lhs
+ }
+ Override: void call(String element) { element.name; }
+ }.result;</programlisting>
+
+ <programlisting>Nullable: String name = if (person exists) person.name else null;</programlisting>
+
+ <section>
+ <title>List of operators</title>
+
+ <para>The following table defines the semantics of the Ceylon operators:</para>
+
+ <table>
+ <tgroup cols="7">
+ <colspec colnum="1" colwidth="2.0*" align="center" colname="first"/>
+ <colspec colnum="2" colwidth="4.5*" align="center"/>
+ <colspec colnum="3" colwidth="4.0*" align="center"/>
+ <colspec colnum="4" colwidth="8.5*" align="center"/>
+ <colspec colnum="5" colwidth="4.0*" align="center"/>
+ <colspec colnum="6" colwidth="3.5*" align="center"/>
+ <colspec colnum="7" colwidth="3.5*" align="center" colname="last"/>
+ <thead>
+ <row>
+ <entry>Op</entry>
+ <entry>Example</entry>
+ <entry>Name</entry>
+ <entry>Equivalent</entry>
+ <entry>LHS type</entry>
+ <entry>RHS type</entry>
+ <entry>Return type</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row><entry namest="first" nameend="last"><emphasis>Assignment</emphasis></entry></row>
+
+ <row>
+ <entry><literal>=</literal></entry>
+ <entry><literal>lhs = rhs</literal></entry>
+ <entry>assign</entry>
+ <entry></entry>
+ <entry><literal>Nullable: Object</literal></entry>
+ <entry><literal>Nullable: Object</literal></entry>
+ <entry><literal>Nullable: Object</literal></entry>
+ </row>
+
+ <row><entry namest="first" nameend="last"><emphasis>Member invocation</emphasis></entry></row>
+
+ <row>
+ <entry><literal>.</literal></entry>