From 48deb8311e2b66485ff2e09d124e51b5444f337c Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Fri, 11 Feb 2011 21:09:43 -0500 Subject: [PATCH] doc: first real reference for the Nit language Signed-off-by: Jean Privat --- .gitignore | 4 + doc/nitreference/nitlanguage.sty | 46 + doc/nitreference/nitreference-main.tex | 1738 ++++++++++++++++++++++++++++++++ doc/nitreference/nitreference.tex | 63 ++ 4 files changed, 1851 insertions(+) create mode 100644 doc/nitreference/nitlanguage.sty create mode 100644 doc/nitreference/nitreference-main.tex create mode 100644 doc/nitreference/nitreference.tex diff --git a/.gitignore b/.gitignore index 6dee606..c68fc65 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ nitc nitdoc doc/stdlib +*.aux +*.log +*.out + src/nitc src/nitc_? src/parser/.nit.sablecc3 diff --git a/doc/nitreference/nitlanguage.sty b/doc/nitreference/nitlanguage.sty new file mode 100644 index 0000000..06a96d0 --- /dev/null +++ b/doc/nitreference/nitlanguage.sty @@ -0,0 +1,46 @@ +% This file is part of Nit ( http://www.nitlanguage.org ). +% +% Copyright 2011 Jean Privat +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +%\usepackage{lmodern} % because standard font does not have a boldface ttfamily variant (so no tt keyword) +\usepackage{listings} % because we extends it +\usepackage{xcolor} % because we like colors + +% definition of the nit language +\lstdefinelanguage{nit}{% +keywords={import,class,interface,universal,super,fun,var,redef,protected,private,module,init,do,end,new,% + return,if,then,else,while,for,loop,in,isa,isset,break,continue,label,% + is,abstract,self,true,false,null,nullable,writable,assert,and,or,not,extern,intern},% +morecomment=[l]{\#},% +morestring=[b]",% +} + +% disable spaces ij strings by default +\lstset{showstringspaces=false} + +% easy nice environement for nit listings +\lstnewenvironment{lst}[1][]{% + \lstset{basicstyle=\scriptsize\ttfamily,% + keywordstyle=\bf\color{blue!30!black},% + commentstyle=\itshape\color{green!30!black},% + language=nit,% + backgroundcolor=\color{black!10},% + moredelim=[is][\color{yellow!30!black}]{@}{@},% + tabsize=3,% + #1}}{} + +% makes @ a nice shortcut for inline Nit code +%\lstMakeShortInline[basicstyle=\small\ttfamily\color{blue!30!black}]{@} + diff --git a/doc/nitreference/nitreference-main.tex b/doc/nitreference/nitreference-main.tex new file mode 100644 index 0000000..9db1697 --- /dev/null +++ b/doc/nitreference/nitreference-main.tex @@ -0,0 +1,1738 @@ +% This file is part of Nit ( http://www.nitlanguage.org ). +% +% Copyright 2011 Jean Privat +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +\noindent\textbf{A Concise Reference of the Nit Language} + +This document attempts to be as short as possible while covering all features of the language in deepth. +It is not a real manual to learn the language since concepts are covered when required. +Forward and backward references about concepts are written like this~\goto{redef} which means Section~\ref*{redef}. +An index\goto{index} also lists concepts and keywords for an improved navigation. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Basic Syntax}\label{syntax}\label{end} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The syntax of Nit belongs to the Pascal tradition and is inspired by various script languages (especially Ruby). +Its objective is readability. + +Indentation is not meaningful in Nit; blocks usually starts by a specific keyword and finish with @end@. +Newlines are only meaningful at the end of declarations, at the end of statements, and after some specific keywords. +The philosophy is that the newline is ignored if something (a statement, a declaration, or whatever) obviously needs more input; while the newline terminates lines that seems completed. +See the complete Nit grammar for more details. + +\begin{lst} +print 1 + 1 # a first complete statement that outputs "2" +print 2 + # the second statement is not yet finished +2 # the end of the second statement, outputs "4" +\end{lst} + +Nit tries to achieve some uniformity in its usage of the common punctuation: +equal (@=@) is for assignment, +double equal (@==@) is for equality test\goto{Bool}, +column (@:@) is for type declaration, +dot (@.@) is for polymorphism\goto{call}, +comma (@,@) separates elements, +and quad (@::@) is for explicit designation. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Identifiers}\label{identifier} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Identifiers of modules, variables, methods, attributes and labels must begin with a lowercase letter and can be followed by letters, digits, or underscores. +However, the usage of uppercase letters (and camelcase) is discouraged and the usage of underscore to separate words in identifiers is preferred: @some_identifier@. + +Identifiers of classes and types must begin with a uppercase letter and can be followed by letters, digits, or underscores. +However, in classes, the usage of camelcase is preferred while formal types should be written all in uppercases: @SomeClass@ and @SOME_VIRTUAL_TYPE@. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Style} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +While Nit does not enforce any kind of source code formatting, the following is encouraged: +\begin{itemize} +\item indentation is done with the tabulation character and is displayed as 8 spaces; +\item lines are less than 80 characters long; +\item binary operators have spaces around them: @4 + 5@, @x = 5@; +\item columns (@:@) and commas (@,@) have a space after them but not before: @var x: X@, @[1, 2, 3]@; +\item parenthesis and brackets do not need spaces around them; +\item superfluous parenthesis should be avoided; +\item the @do@ of methods\goto{fun} and the single @do@\goto{do} is on its own line and not indented; +\item the other @do@ are not on a newline. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Comments and Documentation}\label{comment} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +As in many script languages, comments begin with a sharp (@#@) and run up to the end of the line. +Currently, there is no multiline-comments. + +A block of comments that precede any definition of module, class, or property, is considered as its documentation and will be displayed as such by the autodoc. +At this point, documentation is displayed verbatim (no special formatting or meta-information). + +\begin{lst} +# doc. of foo +module foo + +# doc. of Bar +class Bar + # doc. of baz + fun baz ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Types, Literals and Operations} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Object}\label{Object} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Nit is a full object language. +Each value is the instance of a class\goto{class}. +Even the basic types described in this section. + +@Object@ is the root of the class hierarchy. +All other classes, including the basic ones, are a specialization of @Object@. +\goto{superclass} + +Classes\goto{class}, methods\goto{fun} and operators\goto{operator} presented in this section are defined in the standard Nit library that is implicitly imported in every module\goto{module}. +Many other classes and methods are also defined in the standard library. +Please look at the specific standard library documentation for all details. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Int and Float}\label{Int}\label{Float} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@1@, @-1@ are @Int@ literals, and @1.0@, @-0.1@ are @Float@ literals. +Standard arithmetic operators are available with a common precedence rules: @*@, @/@, and @%@ (modulo) ; then @+@ and @-@. +Some operators can be composed with the assignment (@=@). \goto{operator} +\begin{lst} +var i = 5 +i += 2 +print i # outputs 7 +\end{lst} + +Conversion from @Int@ to @Float@ and @Float@ to @Int@ must be done with the @to_f@ and @to_i@ methods. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{String}\label{String} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Literal strings are enclosed within quotes (@"@). +Common escaping sequences are available (@\n@, @\t@, etc.) +To insert a value inside a literal string, include the values inside brackets (@{}@). +@+@ is the concatenation operator but is less efficient than the bracket form. + +\begin{lst} +var i = 5 +print "i={i}; i+1={i+1}" # outputs "i=5; i+1=6" +\end{lst} + +All objects have a @to_s@ method that converts the object to a String. +@print@ is a top-level method\goto{toplevel} that takes any number of arguments\goto{vararg} and prints to the standard output. +@print@ always add a newline, an other top-level method, @printn@ does not add the newline. + +\begin{lst} +var x: String +x = 5.to_s # -> the String "5" +print x, 6 # outputs "56" +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Bool}\label{Bool}\label{is} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@true@ and @false@ are the only two @Bool@ values. +Standard Boolean operators are available with the standard precedence rule: @not@; then @and@; then @or@. + +Common comparison operators are available: @==@ and @!=@ on all objects; @<@, @>@, @<=@, @>=@ and @<=>@ on @Comparable@ objects (which include @Int@, @String@ and others). \goto{operator} + +\begin{itemize} +\item @==@, @<@, @>@, @<=@, @>=@ and @<=>@ are standard Nit operators (it means they are redefinable)\goto{operator}. +\item @and@, @or@ and @not@ are not standard Nit operators: they are not redefinable, also they are lazy and have adaptive typing flow effects\goto{adaptive typing}. +\item @==@ is not for reference equality but for value equality (like @equals@ in Java). +There is a special reference equality operator, @is@, but it cannot be redefined and its usage is not recommended. +Note also that while @==@ is redefinable, it has a special adaptive typing flow effect when used with @null@\goto{null}. +\item @!=@ is not a standard Nit operator. In fact @x != y@ is syntactically equivalent to @not x == y@. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Array}\label{Array} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@Array@ is a generic class\goto{generic}, thus @Array[Int]@ denotes an array of integers and @Array[Array[Bool]]@ denotes an array of array of Booleans. +Literal arrays can be declared with the bracket notation (@[]@). +Empty arrays can also be instantiated with the @new@\goto{new} keyword and elements added with the @add@ method. +Elements can be retrieved or stored with the bracket operator\goto{operator}. + +\begin{lst} +var a = [1, 2, 3, 4] # A literal array of integers +print a.join(":") # outputs "1:2:3:4" +var b = new Array[Int] # A new empty array of integers +b.add(10) +b.add_all(a) +b.add(20) +print b[0] # outputs "10" +print b.length # outputs "6" +b[1] = 30 +print a.join(", ") # outputs "10, 30, 2, 3, 4, 20" +\end{lst} + +Note that the type of literal arrays is deduced using the static type combination rule\goto{combination}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Range}\label{Range} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@Range@ is also a generic class but accepts only @Discrete@ types (@Int@ is discrete). +There are two kinds of literal ranges, the open one @[1..5[@ that excludes the last element, and the closed one @[1..5]@ that includes it. + +\begin{lst} +print([1..5[.join(":")) # outputs "1:2:3:4" +print([1..5].join(":")) # outputs "1:2:3:4:5" +\end{lst} + +Ranges are mainly used in @for@ loops\goto{for}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{HashMap}\label{HashMap} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@HashMap@ is a generic class that associates keys with values. +There is no literal hashmap, therefore the @new@\goto{new} keyword is used to create an empty @HashMap@ and the bracket operators\goto{operator} are used to store and retrieve values. + +\begin{lst} +var h = new HashMap[String, Int] +# h associates strings to integers +h["six"] = 6 +print h["six"] + 1 # outputs "7" +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Control Structures}\label{control} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Traditional procedural control structures exist in Nit. +They also often exist in two versions: a one-liner and a block version. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Control Flow}\label{control flow} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Control structures dictate the control flow of the program. +Nit heavily refers to the control flow in its specification: +\begin{itemize} +\item No unreachable statement; +\item No usage of undefined variables\goto{var}; +\item No function without a @return@ with a value\goto{fun}; +\item Adaptive typing\goto{adaptive typing}. +\end{itemize} + +Some structure alters the control flow but are not described in this section: @and@, @or@, @not@\goto{Bool}, @or else@\goto{or else} and @return@\goto{return}. + +Note that the control flow is determined only from the position, the order and the nesting of the control structures. +The real value of the expressions used has no effect. +\begin{multicols}{2} +\begin{lst} +if true then + return +else + return +end +print 1 +# Compile error: +# unreachable statement +\end{lst} +\columnbreak +\begin{lst} +if true then + return +end +print 1 +# OK, but never executed +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{if}\label{if} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{multicols}{2} +\begin{lst} +if exp then stm +if exp then stm else stm +if exp then + stms +end +\end{lst} +\columnbreak +\begin{lst} +if exp then + stms +else if exp then + stms +else + stms +end +\end{lst} +\end{multicols} +Note that the following example is invalid since the fist line is syntactically complete thus the newline terminate the whole @if@ structure\goto{syntax}; then an error is signaled since a statement cannot begin with @else@. +\begin{lst} +if exp then stm # OK: complete 'if' structure +else stm # Syntax error: unexpected 'else' +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{while}\label{while} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{lst} +while exp do stm +while exp do + stms +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{for}\label{for} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@for@ declares an automatic variable\goto{var} used to iterates on @Collection@ (@Array@ and @Range@ are both @Collection@). + +\begin{lst} +for x in [1..5] do print x # outputs 1 2 3 4 5 +for x in [1, 4, 6] do + print x # outputs 1 4 6 +end +\end{lst} + +In fact, @for@ is a syntax sugar for a closure\goto{closure}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{loop}\label{loop} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Infinite loops are mainly used with breaks. +They are useful to implement \textit{until} loops or to simulate the \textit{exit when} control of Ada. + +\begin{lst} +loop + stms + if exp then break + stms +end +\end{lst} + +Note that @loop@ is different from @while true@ because the control flow does not consider the values of expression\goto{control flow}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{do}\label{do} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Single @do@ are used to create scope for variables or to be attached with labeled breaks. + +\begin{lst} +do + var x = 5 + print x +end +# x is not defined here +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{break, continue and label}\label{break}\label{continue}\label{label} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Unlabeled @break@ exits the current @for@, @while@, @loop@, or closure\goto{closure}. +Unlabeled @continue@ skips the current @for@, @while@, @loop@, or closure. + +@label@ can be precised with @break@ or @continue@ to designate a specific control structure (not necessary the current one). +The corresponding @label@ must be set after the @end@ keyword of the designated control structure. + +\begin{lst} +for i in [0..width[ do + for j in [0..height[ do + if foo(i, j) then break label outer_loop + # The 'break' breaks the 'for i' loop + end +end label outer_loop +\end{lst} + +@label@ can also be used with @break@ and single @do@ structures. + +\begin{lst} +do + stmts + if expr then break label block + stmts +end label block +\end{lst} + +In closures, @break@ and @continue@ can return values\goto{closure return}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{abort}\label{abort} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@abort@ stops the program with a fatal error and prints a stack trace. +Since there is currently no exception nor run-time-errors, abort is somewhat used to simulate them. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{assert}\label{assert} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@assert@ verifies that a given Boolean expression is true, or else it aborts. +An optional label can be precised, it will be displayed on the error message. +An optional @else@ can also be added and will be executed before the abort. +\begin{lst} +assert bla: whatever else + # "bla" is the label + # "whatever" is the expression to verify + print "Fatal error in module blablabla." + print "Please contact the customer service." +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Local Variables and Static Typing}\label{var}\label{static type} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@var@ declares local variables. +In fact there is no global variable in Nit, so in this document \textit{variable} always refers to a local variable. +A variable is visible up to the end of the current control structure. +Two variables with the same name cannot coexist: no nesting nor masking. + +Variables are bound to values. +A variable cannot be used unless it has a value in all control flow paths (\`a la Java). + +\begin{lst} +var x +var y +if whatever then + x = 5 + y = 6 +else + x = 7 +end +print x # OK +print y # Compile error: y is possibly not initialized +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Adaptive Typing}\label{adaptive typing} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Nit features adaptive typing, which means that the static type of a variable can change according to: +the assignments of variables, +the control flow\goto{control flow}, +and some special operators (@and@, @or@\goto{Bool}, @or else@\goto{or else}, @==@, @!=@\goto{null}, and @isa@\goto{isa}). + +\begin{multicols}{2} +\begin{lst} +var x # a variable +x = 5 +# static type is Int +print x + 1 # outputs 6 +x = [6, 7] +# static type is Array[Int] +print x[0] # outputs "6" +\end{lst} +\columnbreak +\begin{lst} +var x +if whatever then + x = 5 +else + x = 6 +end +# Static type is Int +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Variable Upper Bound}\label{upper bound} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +An optional type information can be added to a variable declaration. +This type is used as an upper bound of the type of the variable. +When a initial value is given in a variable declaration without a specific type information, the static type of the initial value is used as an upper bound. +If no type and no initial value are given, the upper bound is set to @nullable Object@\goto{null}. + +\begin{lst} +var x: Int # Upper bound is Int +x = "Hello" # Compile error: expected Int +var y: Object # Upper bound is Object +y = 5 # OK since Int specializes Object +var z = 5 # Upper bound is Int +z = "Hello" # Compile error: expected Int +var t: Object = 5 # Upper bound is Object +t = "Hello" # OK +\end{lst} + +The adaptive typing flow is straightforward, therefore loops (@for@\goto{for}, @while@\goto{for}, @loop@\goto{for}) and closures\goto{closure} have a special requirement: on enter, the upper bound is set to the current static type; on exit, the upper bound is reset to its previous value. + +\begin{lst} +var x: Object = ... +# static type is Object, upper bound is Object +x = 5 +# static type is Int, bound remains Object +while x > 0 do + # static type remains Int, bound sets to Int + x -= 1 # OK + x = "Hello" # Compile error: expected Int +end +# static type is Int, bound released to Object +x = "Hello" # OK +\end{lst} + +\future{A possible future version of Nit will use a fixed point analysis, thus remove the need of resetting the upper bound.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Type Checks}\label{isa} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@isa@ tests if an object is an instance of a given type. +If the expression used in an @isa@ is a variable, then its static type is automatically adapted, therefore avoiding the need of a specific cast\goto{as}. + +\begin{lst} +var x: Object = whatever +if x isa Int then + # static type of x is Int + print x * 10 # OK +end +\end{lst} + +Remember that adaptive typing follows the control flow\goto{control flow}, including the Boolean operators\goto{Bool}. + +\begin{lst} +var a: Array[Object] = ... +for i in a do + # the static type of i is Object + if not i isa Int then continue + # now the static type of i is Int + print i * 10 # OK +end +\end{lst} + +A funnier example: +\begin{lst} +var max = 0 +for i in whatever do + if i isa Int and i > max then max = i + # the > is valid since, in the right part + # of the "and", the static type of i is Int +end +\end{lst} + +Note that a type adaptation occurs only in an @isa@ if the target type is more specific that the current type. +\begin{lst} +var a: Collection[Int] = ... +if a isa Comparable then + # the static type is still Collection[Int] + # even if the dynamic type of a is a subclass + # of both Collection[Int] and Comparable + ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Nullable Types}\label{null}\label{nullable}\label{or else}\label{not null} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@null@ is a literal value that requires an explicit type acceptance. +However, thanks to adaptive typing, it can be mainly automatic. + +@nullable@ annotates types that can accept @null@ or an expression of a compatible nullable static type. + +\begin{lst} +var x: nullable Int +var y: Int +x = 1 # OK +y = 1 # OK +x = null # OK +y = null # Compile error +x = y # Compile error +y = x # OK +\end{lst} + +Adaptive typing works very well with nullable types. + +\begin{lst} +var x +if whatever then + x = 5 +else + x = null +end +# The static type of x is nullable Int +\end{lst} + +Moreover, alike the @isa@ keyword, the @==@ and @!=@ operators can adapt the static type of a variable when compared to @null@. + +\begin{lst} +var x: nullable Int = whatever +if x != null then + # The static type of x is Int (without nullable) + print x + 6 +end +# The static type of x is nullable Int +\end{lst} + +And a last example: +\begin{lst} +var x: nullable Int = whatever +loop + if x == null then continue + # The static type of x is Int +end +\end{lst} + +%FIXME: Pas clair il parrait +@or else@ can be used to compose a nullable expression with any other expression. +The value of @x or else y@ is @x@ if @x@ is not @null@ and is @y@ if @x@ is null. +The static type of @x or else y@ is the combination\goto{combination} of the type of @y@ and the not null version of the type of @x@. +\begin{lst} +var i: nullable Int = ... +var j = i or else 0 +# the static type of j is Int (without nullable) +\end{lst} + +Note that nullable types require a special management for attributes and constructors\goto{initialization}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Explicit Cast}\label{as} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@as@ casts an expression to a type. +It is either cast successfully or there is an @abort@\goto{abort}. + +\begin{lst} +var x: Object = 5 # static type of x is Object +print x.as(Int) * 10 # outputs 50 +print x.as(String) # aborts: cast failed +\end{lst} + +Note that @as@ does not change the objects nor does perform conversion. +\begin{lst} +var x: Object = 5 # static type of x is Object +print x.as(Int) + 10 # outputs "15" +print x.to_s + "10" # outputs "510" +\end{lst} + + +Because of type adaptation, @as@ is rarely used on variables. +@isa@ (sometime coupled with @assert@\goto{assert}) is preferred. +\begin{lst} +var x: Object = 5 # static type of x is Object +assert x isa Int +# static type of x is now Int +print x * 10 # outputs 50 +\end{lst} + +@as(not null)@ can be used to cast an expression typed by a nullable type to its non nullable version. +This form keeps the programmer from writing explicit static types. + +\begin{lst} +var x: nullable Int = 5 # static type of x is nullable Int +print x.as(not null) * 10 # cast, outputs 50 +print x.as(Int) * 10 # same cast, outputs 50 +assert x != null # same cast, but type of x is now Int +print x * 10 # outputs 50 +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Static Type Combination Rule}\label{combination} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Adaptive typing, literal arrays\goto{Array}, @or else@\goto{or else}, and valued @break@ in closure\goto{closure} need to determine a static type by combining other static types. +This is done by using the following rule: +\begin{itemize} +\item The final type is @nullable@ if at least one of the types is @nullable@. +\item The final type is the static type that is more general than all the other types. +\item If there is no such a type, and the thing typed is a variable, then the final type is the upper bound type of the variable; else there is a compilation error. +\end{itemize} +% FIXME: the 'thing' typed?! + +\begin{lst} +var d: Discrete = ... +# Note: Int < Discrete < Object +var x +if whatever then x = 1 else x = d +# static type is Discrete +if whatever then x = 1 else x = "1" +# static type is nullable Object (upper bound) +var a1 = [1, d] # a1 is a Array[Discrete] +var a2 = [1, "1"] # Compile error: + # incompatible types Int and String +\end{lst} + +\future{A possible future version of Nit will introduce union types, thus simplifying the rule of combination.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Modules}\label{module} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@module@ declares the name of modules. +While optional it is recommended to use it, at least to put a documentation\goto{comment}. +The basename of the source file must match the name declared with @module@. +The extension of the source file must be @nit@. + +A module is made of, in order: +\begin{itemize} +\item the module declaration; +\item module importations; +\item class definitions (and refinements) \goto{class}; +\item top-level function definitions (and redefinitions) \goto{toplevel}; +\item main instructions \goto{toplevel}. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Module Importation}\label{import} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@import@ declares dependencies between modules. +By default, a module publicly imports the module @standard@. +Dependencies must not produce cycles. +By importing a module, the importer module can see and use classes and properties defined in the imported module. + +\begin{itemize} +\item @import@ indicates a public importation. +Importers of a given module will also import its publicly imported modules. +%Modules that import the current module will implicitly also import the other module. +An analogy will be using @#include@ in a header file (@.h@) in C/C++. +\item @private import@ indicates a private importation. +Importers of a given module will not automatically import its privately imported modules. +An analogy will be using @#include@ in a body file (@.c@) in C/C++. +%Modules that import the current module will not see the classes and properties imported. +%However, while the classes and properties imported are invisible, the information that the module import an other one is still public and required to compile and run the program. +\item @intrude import@ indicates an intrusive importation. +@intrude@ @import@ bypasses the @private@ visibility and gives to the importer module a full access on the imported module. +Such an import may only be considered when modules are strongly bounded and developed together. +The closest, but insufficient, analogy will be something like including a body file in a body file in C/C++. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Visibility}\label{visibility} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +By default, all classes\goto{class}, methods\goto{fun}, constructors\goto{init} and virtual types\goto{type} are public whitch means freely usable by any importer module. +Once something is public it belongs to the API of the module and should not be changed. + +@private@ indicates classes and methods that do not belong to the API. +They are still freely usable inside the module but are invisible in other modules (except those that use @intrude import@). + +@protected@ indicates restricted methods and constructors. +Such methods belong to the API of the module but they can only be used with the @self@ receiver. +Basically, @protected@ methods are limited to the current class and its subclasses. +Note that inside the module (and in intrude importers), there is still no restriction. + +Visibility of attributes is more specific and is detailed in its own section\goto{attribute visibility}. + +\begin{multicols}{2} +\begin{lst} +module m1 +class Foo + fun pub do ... + protected fun pro + do ... + private fun pri + do ... +end +private class Bar + fun pri2 do ... +end +var x: Foo = ... +var y: Bar = ... +# All OK, it is +# inside the module +x.foo +x.pro +x.pro +y.pri2 +\end{lst} +\columnbreak +\begin{lst} +module m2 +import m1 +class Baz + super Foo + fun derp + do + self.pro # OK + end +end +var x: Foo = ... +x.pub # OK +x.pro # Compile error: + # pro is protected +x.pri # Compile error: + # unknown method pro + +var y: Bar +# Compile error: +# unknown class Bar +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Visibility Coherence} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +In order to guarantee the coherence in the visibility, the following rules apply: +\begin{itemize} +\item Classes and properties privately imported are considered private: they are not exported and do not belong to the API of the importer. +\item Properties defined in a private class are private. +\item A static type is private if it contains a private class or a private virtual type\goto{type}. +\item Signatures of public and protected properties cannot contain a private static type. +\item Bounds of public generic class\goto{generic} and public virtual types\goto{type} cannot contain a private static type. +\end{itemize} + +% FIXME: What about specialization links between a public class and a privately imported public class + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Classes}\label{class} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@interface@, @abstract class@, @class@ and @enum@ are the four kinds of classes. All these classes can be in multiple inheritance, can define new methods and redefine inherited method (yes, even interfaces). Here is the difference: +\begin{itemize} +\item interfaces can only specialize other interfaces, cannot have attributes, cannot have constructors, cannot be instantiated. +\item abstract classes cannot specialize enums, can have attributes, must have constructors, cannot be instantiated. +\item concrete classes (ie. @class@) cannot specialize enums, can have attributes, must have constructors, can be instantiated. +\item enums (eg. @Int@ or @Bool@) can only specialize interfaces, cannot have attributes, cannot have constructors, have proper instances but they are not instantiated by the programmer---it means no @new Int@. Note that at this point there is no user-defined enums. +\end{itemize} + +All kinds of classes must have a name, can have some superclasses and can have some definitions of properties. +Properties are methods\goto{fun}, attributes\goto{attribute}, constructors\goto{init} and virtual types\goto{type}. +All kinds of classes can also be generic\goto{generic}. +When we talk about ``classes'' in general, it means all these four kinds. +We say ``concrete classes'' to designate only the classes declared with the @class@ keyword alone. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Class Specialization}\label{superclass} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@super@ declares superclasses. +Classes inherit methods, attributes and virtual-types defined in their superclasses. +Currently, constructors are inherited in a specific manner\goto{init inheritance}. + +@Object@ is the root of the class hierarchy. +It is an interface and all other kinds of classes are implicitly a subclass of @Object@. + +There is no repeated inheritance nor private inheritance. +The specialization between classes is transitive, therefore @super@ declarations are superfluous (thus ignored). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Class Refinement}\label{refine} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@redef@ allows modules to refine imported classes (even basic ones). +Refining a class means: +\begin{itemize} +\item adding new properties: methods, attributes, constructors, virtual types; +\item redefining existing properties: methods and constructors; +\item adding new superclasses. +\end{itemize} + +Note that the kind\goto{class} or the visibility\goto{visibility} of a class cannot be changed by a refinement. +Therefore, it is authorized to just write @redef class X@ whatever is the kind or the visibility of @X@. + +In programs, the real instantiated classes are always the combination of all their refinements. +%This is quite powerful and permit a programing style only found in some dynamically typed languages or aspect-oriented languages. + +\begin{lst} +redef class Int + fun fib + do + if self < 2 then return self + return (self-1).fib + (self-2).fib + end +end +# Now all integers have the fib method +print 15.fib # outputs 610 +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Methods}\label{fun}\label{self}\label{return} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@fun@ declares methods. +Methods must have a name, may have parameters, and may have a return type. +Parameters are typed; however, a single type can be used for multiple parameters. +\begin{lst} +fun foo(x, y: Int, s: String): Bool ... +\end{lst} + +@do@ declares the body of methods. +Alike control structures\goto{control}, a one-liner version is available. +Moreover, a shorter version using the @=@ symbol is also available for functional methods. +Therefore, the three following methods are equivalent. +\begin{lst} +fun next1(i: Int): Int +do + return i + 1 +end + +fun next2(i: Int): Int do return i + 1 + +fun next3(i: Int): Int = i + 1 +\end{lst} + +Inside the method body, parameters are considered as variables\goto{var}. +They can be assigned and are subject to adaptive typing. + +@self@, the current receiver, is a special parameter. +It is not assignable but is subject to adaptive typing. + +@return@ exits the method and return to the caller. +In a function, the return value must be provided with a return in all control flow paths\goto{control flow}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Method Call}\label{call} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Calling a method is usually done with the dotted notation @x.foo(y, z)@. +The dotted notation can be chained. + +A method call with no argument does not need parentheses. +Moreover, even with arguments the parentheses are not required in the principal method of a statement. +\begin{lst} +var a = [1] +a.add 5 # no () for add +print a.length # no () for length, no () for print +\end{lst} + +However, this last facility requires that the first argument does not start with a parenthesis or a bracket. +\begin{lst} +foo (x).bar # will be interpreted as (foo(x)).bar +foo [x].bar # will be interpreted as (foo[x]).bar +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Method Redefinition}\label{redef} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@redef@ denotes methods that are redefined in subclasses\goto{superclass} or in class refinements\goto{refine}. +The number and the types of the parameters must be invariant. +Thus, there is no need to reprecise the types of the parameters, only names are mandatory. + +The return type can be redefined to be a more precise type. +If same type is returned, there is no need to reprecise it. + +The visibility, also, cannot be changed, thus there is also no need to reprecise it. + +\begin{lst} +class Foo + # implicitly an Object + # therefore inherit '==' and 'to_s' + var i: Int + redef to_s do return "Foo{self.i}" + redef ==(f) do return f isa Foo and f.i == self.i +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Abstract Methods}\label{abstract} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@is abstract@ indicates methods defined without a body. +Subclasses and refinements can then redefine it (the @redef@ is still mandatory) with a proper body. + +\begin{lst} +interface Foo + fun derp(x: Int): Int is abstract +end +class Bar + super Foo + redef derp(x) do return x + 1 +end +\end{lst} + +Concrete classes may have abstract methods. +It is up to a refinement\goto{refine} to provide a body. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Call to Super}\label{super} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@super@ calls the ``previous'' definition of the method. +It is used in a redefinition of a method in a subclass or in a refinement, +It can be used with or without arguments; in the latter case, the original arguments are implicitly used. + +The @super@ of Nit behave more like the @call-next-method@ of CLOS that the @super@ of Java or Smalltalk. +It permits the traversal of complex class hierarchies and refinement. +Basically, @super@ is polymorphic: the method called by @super@ is not only determined by the class of definition of the method but also by the dynamic type of @self@. + +\begin{comment} +The principle it to produce a strict order of the redefinitions of a method (the linearization). +Each call to @super@ call the next method definition in the linearization. +From a technical point of view, the linearization algorithm used is based on C4. +It ensures that: +\begin{itemize} +\item A definition comes after its redefinition. +\item A redefinition in a refinement comes before a redefnition in a +\item The order of the declaration of the superclasses is used as the ultimate deabiguization. +\end{itemize} + +%@super@ is really powerful and can deals with very complex multiple inheritance and multiple refinement thanks to some linearization algorithm. + +\begin{lst} +class A + fun derp: String do return "A" +end +class B + super A + redef fun derp do return "B" + super +end +class C + super A + redef fun derp do return "C" + super +end +class D + super B + super C + redef fun derp do return "D" + super + # Here the linearization order of the class D is DBCA + # D before B because D specializes B + # B before A because B specializes A + # D before C because D specializes C + # C before A because C specializes A + # B before C because in D 'super B' is before 'super C' +end +var b = new B +print b.derp # outputs "BA" +var d = new D +print d.derp # outputs "DBCA" +\end{lst} +\end{comment} + +% TODO: linearization. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Operators and Setters}\label{operator} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Operators and setters are methods that require a special syntax for their definition and their invocation. + +\begin{itemize} +\item binary operators: @+@, @-@, @*@, @/@, @\%@, @==@, @<@, @>@, @<=@, @>=@, @<<@, @>>@ and @<=>@. +Their definitions require exactly one parameter and a return value. +Their invocation is done with @x + y@ where @x@ is the receiver, @+@ is the operator, and @y@ is the argument. +\item unary operator: @-@. +Its definition requires a return value but no parameter. +Its invocation is done with @-x@ where @x@ is the receiver. +\item bracket operator: @[]@. +Its definition requires one parameter or more and a return value. +Its invocation is done with @x[y, z]@ where @x@ is the receiver, @y@ the first argument and @z@ the second argument. +\item setters: @something=@ where @something@ can be any valid method identifier. +Their definitions require one parameter or more and no return value. +If there is only one parameter, the invocation is done with @x.something = y@ where @x@ is the receiver and y the argument. +If there is more that one parameter, the invocation is done with @x.something(y, z) = t@ where @x@ is the receiver, @y@ the first argument, @z@ the second argument and @t@ the last argument. +\item bracket setter: @[]=@. +Its definition requires two parameters or more and no return value. +Its invocation is done with @x[y, z] = t@ where @x@ is the receiver, @y@ the first argument, @z@ the second argument and @t@ the last argument. +\end{itemize} + +\begin{lst} +class Foo + fun +(a: Bar): Baz do ... + fun -: Baz do ... + fun [](a: Bar): Baz do ... + fun derp(a: Bar): Baz do ... + fun derp=(a: Bar, b: Baz) do ... + fun []= (a: Bar, b: Baz) do ... +end +var a: Foo = ... +var b: Bar = ... +var c: Baz = ... +c = a + b +c = -b +c = a[b] # The bracket operator '[]' +c = a.derp(b) # A normal method 'derp' +a.derp(b) = c # A setter 'derp=' +a[b] = c # The bracket setter '[]=' +\end{lst} + +@+=@ and @-=@ are combinations of the assignment (@=@) and a binary operator. +These feature are extended to setters where a single @+=@ is in fact three method calls: a function call, the operator call, then a setter call. +\begin{lst} +a += c # equiv. a = a + c +a[b] += c # equiv. a[b] = a[b] + c +a.foo += c # equiv. a.foo = a.foo + c +a.bar(b) += c # equiv. a.bar(b) = a.bar(b) + c +\end{lst} + +% FIXME: priority of operators? + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Variable Number of Arguments}\label{vararg} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +A method can accept a variable number of arguments using ellipsis (@...@). +The definition use @x: Foo...@ where x is the name of the parameter and @Foo@ a type. +Inside the body, the static type of @x@ is @Array[Foo]@. +The caller can use 0, 1, or more arguments for the parameter @x@. +Only one ellipsis is allowed in a signature. + +\begin{lst} +fun foo(x: Int, y: Int..., z: Int) +do + print "{x};{y.join(",")};{z}" +end +foo(1, 2, 3, 4, 5) # outputs "1;2,3,4;5" +foo(1, 2) # outputs "1;;2" +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Top-level Methods and Main Body}\label{toplevel} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Some function, like @print@ are usable everywhere simply without using a specific receiver. +Such methods are just defined outside any classes. +In fact these methods are implicitly defined in the Object interface, therefore inherited by all classes, therefore usable everywhere. +However, this principle may change in a future version. + +In a module, the main body is a bunch of statements at the end of a file. +The main body of the main module is the entry point of a program. +In fact the main method of a program is implicitly defined as the redefinition of the method @main@ of the @Sys@ class. +The start of the program is in fact the implicit statement @(Sys.new).main@. +Note that because it is a redefinition, the main part can use @super@\goto{super} to call the ``previous'' main part in the imported modules. +If there is no main part in a module, it is inherited from imported modules. + +Top-level methods coupled with the main body can be used to program in a pseudo-procedural way. +Therefore, the following programs are valid: +\begin{multicols}{2} +\begin{lst} +print "Hello World!" +\end{lst} +\columnbreak +\begin{lst} +fun sum(i, j: Int): Int +do + return i + j +end +print sum(4, 5) +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Intern and Extern Methods}\label{intern}\label{extern} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@intern@ and @extern@ indicate concrete methods whose body is not written in Nit. + +The body of @intern@ methods is provided by the compiler itself for performance or bootstrap reasons. +For the same reasons, some intern methods, like @+@ in @Int@\goto{Int} are not redefinable. + +The body of @extern@ methods is provided by libraries written in C. +Especially the system libraries required for input/output. +Extern methods are always redefinable. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Attributes}\label{attribute}\label{writable} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@var@, used inside concrete and abstract classes, declares attributes. +Attributes require a static type and can possibly have an initial value (it may be any kind of expression, even including @self@\goto{self}) + +%In Nit, attributes cannot be directly accessed. +%In fact by declaring an attribute, two methods are automatically generated. +%One is the getter, the other is the setter. + +\begin{lst} +class Foo + var i: Int = 5 + fun dec(x: Int): Int + do + var k = self.i + if k > x then self.i = k - x else self.i = 0 + end +end +\end{lst} + +Note that from an API point of view, there is no way to distinguish the read access of an attribute with a normal method neither to distinguish a write access of an attribute with a setter. +Therefore, the read access of an attribute is caller a getter while the write access is called a setter. +\begin{lst} +var x = foo.bar # Is bar an attribute or a method? +foo.bar = y # Is bar an attribute or a setter? +# In fact, we do not need to know. +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Visibility of Attributes}\label{attribute visibility} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +By default, the getter is public and the setter is private. +The visibility of the getter can be precised with the @private@ or @protected@ keywords. +The visibility of the setter can be specified with an additional @writable@ keyword. + +\begin{lst} +class Foo + var pub_pri: X + protected var pro_pri: X + var pub_pub: X writable + private var pri_pro: X protected writable + var pub_pri2: X private writable # the default +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Redefinition of Attributes}\label{redef var} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Getters and setters of attributes behave like genuine methods that can be inherited and redefined. +Getters and setters can also redefine inherited methods. +@redef var@ declares that the getter is a redefinition while @redef writable@ declares that the setter is a redefinition. + +\begin{lst} +interface Foo + fun derp: Int is abstract + fun derp=(o: Int) is abstract +end +class Bar + super Foo + redef var derp: Int redef writable +end +class Baz + super Bar + redef fun derp do ... + redef fun derp=(o) do ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Constructors and Instantiation}\label{init} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@init@ declares constructors in concrete and in abstract classes. +The role of the constructors is to basically initialize the attributes of the class. +Constructors can have: a visibility (by default it is public), a name (by default, constructors are anonymous) and parameters. +They cannot have a return value. + +\begin{lst} +class Foo + init(i:Int) do ... + init herp do ... + init derp(i, j: Int) do ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Class Instantiation}\label{new} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@new@ instantiates a concrete class using a specific constructor. +\begin{lst} +var x = new Foo(4) # invoke init +var y = new Foo.herp # invoke herp +var z = new Foo.derp(1, 2) # invoke derp +\end{lst} +Note that syntactically, @new Bar@ means ``instantiate Bar with the anonymous constructor'', and @new Bar.foo@ means ``instantiate Bar with the constructor named foo'', but @(new Bar).foo@ means ``instantiate Bar with the anonymous constructor then call the method foo on the result''. + +Constructor can also be called by other constructors in order to factorize or delegate parts of the construction process. +In other constructors, @init@ denotes the anonymous constructor. +\begin{lst} +class Foo + init(i: Int) do self.derp(i.to_s) + init herp do self.init(5) + init derp(s: String) do ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Initialization of Attributes}\label{initialization}\label{isset} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The tricky part in constructors is the initialization of attributes since they cannot be initialized in an atomic way. +The various steps apply in the following order: +\begin{itemize} +\item Attributes typed by a nullable type are initialized with @null@\goto{null}; other attributes remain uninitialized. +\item Default values of all attributes (including inherited ones) are computed in the order of their definitions. +\item The constructor designated in the @new@ is executed. +\item During the constructor execution (including any methods or other constructors called), accessing an uninitialized attribute aborts the program. +\item After the execution of the constructor designated in the @new@, if some attributes remain uninitialized, the program aborts. +\end{itemize} + +\begin{comment} +@isset@ can be used to avoid aborting during the construction. +It checks if an attribute is defined. +\begin{lst} +class Foo + var x: Int + fun safe_x: nullable Int + do + if isset self.x then + return self.x + else + return null + end + end + init + do + print safe_x or else 0 # outputs 0 + # "print x" would have aborted the program + self.x = 5 + print safe_x or else 0 # outputs "5" + print x # outputs "5". It is safe. + end +end +var f = new Foo +\end{lst} +\end{comment} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Free and Inherited Constructors}\label{init inheritance} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +When there is no constructor defined in a concrete class or in an abstract class that specialize only interfaces (@Object@ is always a superclass), a free anonymous constructor is implicitly declared. +This free constructor gathers all attributes without a initial value and assign them in order. +If all attributes have an initial value (or if there is no attributes), the free constructor has no parameters. + +\begin{lst} +class Foo + var x: Int + var y: String + var z: Int = 0 + # a free init(x: Int, y: String) is implicit +end +var f = new Foo(5, "five") # OK +\end{lst} + +When there is no constructors defined in a concrete class or in an abstract class, and that this class has only one direct superclass that is a concrete class or an abstract class, and that all attributes defined in this class have an initial value, then all constructors of the superclass are inherited. + +\begin{lst} +class Bar + super Foo + var t: String = "Hello" + # init(Int, String) is inherited +end +\end{lst} + +If none of these two cases apply, then there is a compilation error. +The programmer usually has to define its own constructors for the class. + +\begin{lst} +class Baz + super Foo + var u: Int + # Compile error: a constructor must be defined +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Generic Classes and Virtual Types} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Generic Classes}\label{generic} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Generic classes are defined with formal generic parameters declared within brackets. +Formal generic parameters can then be used as a regular type inside the class. +Generic classes must always be qualified when used. + +\begin{lst} +class Pair[E] + var first: E + var second: E + fun is_same: Bool + do + return self.first == self.second + end +end +var p1 = new Pair[Int](1, 2) +print p1.second * 10 # outputs "20" +print p1.is_same # outputs "false" +var p2 = new Pair[String]("hello", "world") +p2.first = "world" +print p2.is_same # outputs "true" +\end{lst} + +Unlike many object-oriented languages, generic classes in Nit yield a kind of sub-typing. +For example, @Pair[Int]@ is a subtype of @Pair[Object]@. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Virtual Types}\label{type} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@type@ declares a virtual types in a class. +A bound type is mandatory. +Virtual types can then be used as a regular type in the class and its subclasses. +Subclasses can also redefine it with a more specific bound type. +One can see a virtual type as an internal formal generic parameter or as a redefinable \textit{typedef}. + +\begin{lst} +class Foo + type E: Object + var derp: E +end +class Bar + super Foo + redef type E: Int +end +var b = new Bar(5) +print b.derp + 1 # outputs 6 +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Closures}\label{closure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Closures are pieces of code that are passed to methods as additional arguments. +Closures are defined and used with the @!@ character. +The following example shows the use of the @sort@ method of arrays (defined in the Nit standard library). + +\begin{lst} +var a = [4, 2, 9, 6] +a.sort !cmp(x, y) = x <=> y +print a.join(", ") # outputs "2, 4, 6, 9" +a.sort !cmp(x, y) = y <=> x +print a.join(", ") # outputs "9, 6, 4, 2" +\end{lst} + +@!cmp@ indicates the closure parameter of the function sort. +The documentation of the method @sort@ says that @!cmp@ is used by @sort@ to know how to compare two elements. +Thus, @sort@ provides to @!cmp@ two elements and expects a Boolean result. %saying if the first element provided should be sorted before the second element provided. +Therefore, when invoking @sort@, the programmer gets two automatic variables (one associated to each element) and is expected to return a Boolean. + +Closures can also be used to perform work. +In the following example, @file_open@ is used to open a file for reading. +If the opening fails, the @!error@ closure is executed with the reason as argument (``file not found'' for instance). +If the opening is successful, @!work@ is executed and the automatic variable @f@ is associated with the opened file handler. +@file_open@ also ensures that the file is correctly closed when the @!work@ closure returns. + +\begin{lst} +var fname = "input.txt" +file_open(fname) !work(f) do + print f.read_line +!error(e) do + print "Cannot open '{fname}': {e}" +end +\end{lst} + + +Closures can access visible variables. +In the following example, the @iterate@ procedure asks for an @!each@ closure that is executed on each element of a @Collection@. +In fact, the @for@ control structure is a call of the @iterate@ method. +The two following examples are strictly equivalent. + +\begin{multicols}{2} +\begin{lst} +var sum = 0 +var a = [4, 2, 9] +a.iterate !each(i) do + sum += i +end +print sum # outputs "15" +\end{lst} +\columnbreak +\begin{lst} +var sum = 0 +var a = [4, 2, 9] +for i in a do + sum += i +end +print sum # outputs "15" +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Returning Values and Escaping}\label{closure return} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@break@ and @continue@ are extended to closures. + +@continue@ exits the closure. +If the closure expects a return value, @continue@ is also used to return the correct value. +As with method definition, closure allows one-liners. +Moreover, the @do continue value@ syntax can be replaced by @= value@ as in the first @sort@ example. + + +@break@ exits completely the called method. +If the called method is a function, @break@ is also used to set the result returned by the function. +The types returned by @break@ can be different from the return type of the function. +The return type of the whole expression is the combination\goto{combination} of the return type of the function and the types of each @break@. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Closures in Method Declarations} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Closure parameters are declared with their signature between the prototype and the @do@ of the method. +Closure invocations in the body of the method simply use the closure name (without the @!@) like a standard call. +More than one closure parameter can be declared. +Each one has to be declared on a separate line. +%At the method invocations, the closure name is used to associate each closure definition with each closure parameter. +The order of the closure definitions does not matter. + +\begin{multicols}{2} +\begin{lst} +fun twice + !work +do + work + work +end +twice !work do print "One" +# outputs "One One" +\end{lst} + + +\begin{lst} +fun foo(i: String): String + !f(j: String): String +do + var k = f(i + "B") + # k will be "ABC" + return k + "D" +end +var x = foo("A") !f(y) = + y + "C" +print x # outputs "ABCD" +\end{lst} +\columnbreak +\begin{lst} +fun bar(i: String) + !b1(j: String): String + !b2(k: String) +do + b2(b1(i)) +end + +bar("A") !b1(y) do + continue y + "B" +!b2(z) do + print z +end +# outputs "AB" +\end{lst} +\end{multicols} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Default Closures} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +A default closure can be given along with the closure parameter declaration in method. +If there is no default closure, then the corresponding closure argument is mandatory. +Otherwise, if there is a default closure, the corresponding closure argument is optional. + + +\begin{lst} +fun are_all_comparable(a: Collection[Int]): Bool + !cmp(x, y: Int): Bool = x == y +do + if a.is_empty then return true + var e1 = a.first + for e2 in a do if not cmp(e1, e2) then return false + return true +end + +var a = [2, 2, 6, 2] +print are_all_comparable(a) # outputs "false" +var x = are_all_comparable(a) !cmp(i, j) = i%2 == j%2 +print x # outputs "true" +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Break Closures}\label{break closure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Some closures, called break closures, cannot be continued. +On the method definition, it means that the closure invocation does not return (like a @return@ or an @abort@). +On method invocations, it means that the closure definition must not continue. +Break closures are usually used to process error or exception handling. + + +\begin{lst} +fun open_file(fname: String) + !work(f: File) + break !error(e: String) do + print "Cannot open {fname}: {e}." + abort + end +do + # ... +end + +open_file("config.ini") !error(e) do + print "Cannot open file (config.ini): {e}." +!work(f) do + # ... +end +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Full Closure Example} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +To conclude the explanation about closures, the last example shows the bracket operator\goto{operator} (@[]@) of the @Map@ interface. +A map, like @HashMap@ is used to implement a dictionary that associates some objects (keys) to some other objects (items). +The operator returns the item associated to key. +The operator has a @!def@ closure that is executed when the key is not found. +@!def@ is expected to return the item associated with the new key so it can be stored in the hashmap then returned. +By default, @!def@ aborts. + + +\begin{lst} +var map = new HashMap[Int, String] +map[5] = "five" # associate '5' to "five" +var x1 = map[5] # return "five" +var x2 = map[6] !def = "six" # associate '6' to "six" + # and return "six" +var x3 = map[6] !def = "?" # return "six" since '6' is + # a known key +var x4 = map[7] !def do break "seven" # return "seven" + # since '7' is not a known key +var x5 = map[7] # aborts since '7' was not associated + # with the previous statement +\end{lst} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Conclusion} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The specification of Nit is not yet finished. +The major following features need at least to be implemented and documented: +\begin{itemize} +\item User-defined @enum@ with full specialization. +\item Union an intersection types. +\item A usable native interface to bind Nit with system libraries and other languages. +\end{itemize} +Moreover, a language also need a complete and stable standard library. + +Some other topics also need a deeper analysis : exceptions, threads, parallelism, contracts, etc. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Index}\label{index}{\small\raggedleft +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@#@\goto{comment}, +@!@\goto{closure}, +@.@\goto{call}, +@..@\goto{Range}, +@...@\goto{vararg}, +@{}@\goto{String}, +@[]@ (array)\goto{Array}, +@[]@ (operator)\goto{operator}, +@[]@ (generic)\goto{generic}, +@"@\goto{String}, +@abstract@ (class)\goto{class}, +@abstract@ (method)\goto{abstract}, +adaptive typing\goto{adaptive typing}, +@and@\goto{Bool}, +@Array@\goto{Array}, +@as@\goto{as}, +@assert@\goto{assert}, +attribute\goto{attribute}, +@Bool@\goto{Bool}, +@break@\goto{break}, +break closure\goto{break closure}, +cast\goto{as}, +@class@\goto{class}, +closure\goto{closure}, +comment\goto{comment}, +constructor\goto{init}, +@continue@\goto{continue}, +control structure\goto{control}, +@do@\goto{do}, +@else@ (if)\goto{if}, +@else@ (abort)\goto{abort}, +@end@\goto{end}, +@enum@\goto{class}, +@extern@\goto{extern}, +@false@\goto{Bool}, +@Float@\goto{Float} +@for@\goto{for}, +@fun@\goto{fun}, +generic class\goto{generic}, +getter\goto{attribute}, +@HashMap@\goto{HashMap}, +identifier\goto{identifier}, +@if@\goto{if}, +@import@\goto{import}, +@in@\goto{for}, +@init@\goto{init}, +inheritance\goto{superclass}, +@Int@\goto{Int}, +@interface@\goto{class}, +@intern@\goto{intern}, +@is@\goto{is}, +@isa@\goto{isa}, +@isset@\goto{isset}, +@label@\goto{label}, +@loop@\goto{loop}, +@module@\goto{module} +@new@\goto{new}, +@not@\goto{Bool}, +@not null@\goto{null}, +@null@\goto{null}, +@nullable@\goto{null}, +@Object@\goto{Object}, +operator\goto{operator}, +@or@\goto{Bool}, +@or else@\goto{or else} +@private@\goto{visibility} +@protected@\goto{visibility}, +@Range@\goto{Range}, +@redef@ (class)\goto{refine}, +@redef@ (method)\goto{redef}, +@redef@ (attribute)\goto{redef var}, +@return@\goto{return}, +@self@\goto{self}, +setter\goto{operator}, +setter (attribute)\goto{attribute}, +specialization\goto{superclass}, +@String@\goto{String}, +@super@ (class)\goto{superclass}, +@super@ (method)\goto{super}, +syntax\goto{syntax}, +@then@\goto{if}, +@true@\goto{Bool}, +type (static)\goto{static type}, +@type@\goto{type}, +@upper bound@\goto{upper bound}, +@var@ (attribute)\goto{attribute}, +@var@ (variable)\goto{var}, +virtual type\goto{type}, +visibility\goto{visibility}, +@while@\goto{while}, +@writable@\goto{writable}, +} + diff --git a/doc/nitreference/nitreference.tex b/doc/nitreference/nitreference.tex new file mode 100644 index 0000000..9ee0ed6 --- /dev/null +++ b/doc/nitreference/nitreference.tex @@ -0,0 +1,63 @@ +% This file is part of Nit ( http://www.nitlanguage.org ). +% +% Copyright 2011 Jean Privat +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +\documentclass[10pt]{article} + +\usepackage[T1]{fontenc} +\usepackage{nitlanguage} +\usepackage{multicol} +\usepackage{savetrees} +\usepackage{listings} +\usepackage{microtype} +\usepackage{xcolor} +\usepackage{comment} + +\newcommand\thedoctitle{A Concise Reference of the Nit Language} +\title{\thedoctitle} +\author{Jean Privat} +\date{\today} + +\usepackage[bookmarks=false,pdftitle={\thedoctitle}]{hyperref} +\pdfcompresslevel=9 %best compression level for text and image + +%\setcounter{collectmore}{90} % Force better column breaks + +\lstMakeShortInline[basicstyle=\small\ttfamily\color{blue!30!black}]{@} + +\hypersetup{colorlinks=true} +\newcommand\goto[1]{\hyperref[#1]{{\color{red}\scriptsize[\ref*{#1}]}}} +\newcommand\future[1]{} + +\geometry{margin=0.35in} % short margins +% footer +\usepackage{fancyhdr} +\pagestyle{fancy} +\lhead{} +\chead{} +\rhead{} +\lfoot{\it\today} +\cfoot{\it\thedoctitle} +\rfoot{\it\thepage} +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt} +\setlength\footskip{15pt} + +\begin{document} +\setlength\columnsep{8pt} % space around big columns +\begin{multicols}{2} +\setlength\columnsep{4pt} % space around smalls columns (for examples) +\input{nitreference-main.tex} +\end{multicols} +\end{document} -- 1.7.9.5