Scala
Scala és un llenguatge de programació modern multi-paradigma dissenyat per a expressar patrons de programació generals d'una manera concisa, elegant i segura respecte els tipus. Integra característiques de orientació a objectes i de llenguatges funcionals.
Scala és orientat a objectes [modifica]
Scala és un llenguatge pur O.O. (orientat a objectes) en el sentit que cada valor és un objecte. Els tipus i comportaments dels objectes són descrits mitjançant classes i 'trets'. L'abstracció classe s'estén mitjançant subclasses i també amb un mecanisme flexible basat en classes 'mixins' (barrejables: similars als interface de Java però amb def. de tipus, variables i implementació de mètodes) anomenades trets com a substitució neta de l' 'herència múltiple'.
Scala és funcional [modifica]
Scala també és un llenguatge funcional en el sentit que cada funció és un valor. Scala proveeix una sintaxi fàcil per a la definició de funcions anònimes, suporta funcions d'ordre superior, permet l'aniuament de funcions i suporta el currying. Les classes per cas (ang.: case classes) i el suport que inclou de reconeixement de patrons, serveix per a modelar tipus algebraics, emprats en molts llenguatges de programació funcional.
A més a més, la noció de reconeixement de patrons estén de manera natural el procés de dades XML amb l'ajuda de seqüències de patrons ignorant el que hi ha a la dreta (ang.:right-ignoring). En aquest context, les comprehensions de seqüències (iteració sobre Generadors-Filtres-Mapeig) són útils per a formular consultes. Aquestes característiques fan de Scala l'ideal per a desenvolupar aplicacions com a serveis web.
Scala té tipus estàtics [modifica]
Scala està equipat amb un sistema de tipus expressiu que assegura estàticament que les abstraccions s'utilitzin de manera coherent i segura. En particular el sistema de tipus suporta:
- classes genèriques,
- anotacions de variació,
- acotacions de tipus per dalt i per baix,
- classes internes i tipus abstractes com a membres de l'objecte,
- tipus compostos,
- auto referències tipificades explícitament,
- vistes, i
- mètodes polimòrfics.
Un mecanisme d'inferència de tipus permet que l'usuari no hagi d'anotar els tipus de manera redundant. En combinació, aquestes característiques proporcionen una base potent per a la reutilització segura de les abstraccions de programació i també per a l'extensió de programari amb tipus de dades segurs.
Scala és extensible [modifica]
El disseny de Scala reconeix el fet que, a la pràctica, el desenvolupament d'aplicacions d'un domini específic requereix extensions de llenguatge igualment específiques. Scala proporciona una combinació única de mecanismes de llenguatge que fan fàcil afegir noves construccions al llenguatge, amb suavitat , en forma de biblioteques:
- qualsevol mètode pot ser emprat com a operador infix o postfix, i
- els tancaments es construeixen automàticament depenent del tipus esperat.
Un ús conjunt d'ambdues característiques facilita la definició de noves instruccions sense estendre la sintaxi i sense emprar tècniques de meta-programació com ara macros.
Scala interopera amb Java i .NET [modifica]
Scala està dissenyat per a interoperar bé amb entorns populars de programació com Java 2 (JRE) i el marc .NET (CLR). En particular, la interacció amb llenguatges orientats a objectes de gran acceptació com Java i C# és força suau. Scala té el mateix model de compilació (compilació separada, càrrega dinàmica de classes) que Java i C#, permetent accedir a milers de biblioteques d'alta qualitat.
Exemple: Hola món [modifica]
Per començar:
- Al Linux el podeu instal·lar pels paquets de la distribució. Altrament el compilador es pot descarregar d'aquí[1] o com endollable en un entorn IDE aquí[2]
El programa Hola món en Scala:
// fitxer test/hola-mon.scala package test object Principal { def main(args: Array[String]) = Console.println("Hola món!") }
alternativa
// fitxer test/hola-mon.scala package test object Principal extends Application { // Application defineix main Console.println("Hola món!") // la inicialització de l'objecte executa les expressions del cos. }
- Compilació i execució a consola de comandes:[3]
cd objdir scalac ../src/test/hola-mon.scala scala test.Principal # execució pel nom de l'objecte que conté el mètode ''main'' Hola món!
- A l'avaluador d'expressions (bucle Read-Eval-Print)
scala scala> println( "Hola món") Hola món scala>
Característiques [modifica]
Degut a ésser un llenguatge dissenyat inicialment per a la màquina virtual JVM, hereta del Java les característiques del lèxic i els tipus bàsics i les seves operacions així com una sintaxi molt similar.
Els punt-i-coma a final de línia es poden ometre (des de la versió 2).
tipus Unit [modifica]
Equival al tipus buit (void en Java) de les instruccions que no retornen res, habitualment assignacions i altres efectes laterals.
El seu únic valor és: () // no-op : no fer res (element neutre de les operacions)
altres tipus especials [modifica]
Vegeu ref.[4]
- Any
- generalització d'un tipus qualsevol
- AnyVal
- generalització dels tipus bàsics que es passen per valor.
- AnyRef
- generalització dels tipus que es passen per referència. Correspon a Java.lang.Object
- ScalaObject
- base per als objectes de Scala
- Null
- es considera subtipus de qualsevol classe o objecte, així el seu valor null pot pertànyer a totes elles.
- Nothing
- subtipus de tots els tipus.
restriccions en els tipus [modifica]
Els tipus poden parametritzar funcions, classes, objectes i trets. Admeten a més restriccions especials.
En el següent exemple Tipus ha d'ésser subtipus de TCotaSuperior.[5]
type Tipus <: TCotaSuperior
en el següent exemple Tipus ha d'ésser superclasse de TCotaInferior.[6]
type Tipus >: TCotaInferior
Convertibilitat
type A <% T // indica que A ha de ser convertible en T mitjançant una conversió implícita. Vegeu Scala Views[7]
trait Set[A <% Ordered[A]] ... class EmptySet[A <% Ordered[A]] ... class NonEmptySet[A <% Ordered[A]] ...
encaix segons el valor o el tipus [modifica]
Primer valors, després tipus
package test ; object Main extends Application { val llista: List[Any] = List(true, 'c', 8:Byte, 270:Short, 300, 200000000000L, 2.5F, 3.12345678, "abc") ; for (elem <- llista) { elem match { case 2 | 3 => print( "dos o tres") ; case v :Char => printf("%c u\\%04x", v, v.toInt ) ; // caràcter i hexadecimal case v :Byte => printf("és un byte: %d", v) ; case v :Short => printf("és un short: %d", v) ; case v :Int => printf("és un int: %d 0%o x%08x", v, v, v) ; // decimal, octal i hexad. case v :Long => printf("%d", v) ; case v :Float => printf("%.2f", v) ; case v :Double => printf("%.8f", v) ; case v :String => printf("%s", v) ; case v :AnyRef => print( v.toString) ; case v => print( v) ; } println("") } }
dóna
true c u\0063 és un byte: 8 és un short: 270 és un int: 300 0454 x0000012c 200000000000 2,50 3,12345678 abc
polimorfisme paramètric [modifica]
A més del polimorfisme per especialització dels objectes, les funcions es poden parametritzar per Tipus
def nom_funció[VariableDeTipus](param1: VariableDeTipus, ..) = ...
exemple:
object Main extends Application { def imprimeix[T]( dada: T) = dada match { case v: String => println( v) ; case v => println (v.toString) ; } imprimeix[Int]( 5) ; imprimeix[String]( "abc") ; imprimeix( 2) ; // si no s'explicita el tipus es dedueix dels paràmetres actuals. imprimeix( "def") ; }
classes "per cas" per implementar tipus "suma" algebraics [modifica]
El que en altres lleng. funcionals es descriu com a unió de tipus discriminats per etiquetes anomenades constructors, aquí es parteix de la classe que identifica el tipus i se'n deriven classes per cada cas de la unió discriminada, amb el constructor per nom i paràmetres corresponents als components del cas.
abstract class Arbre[T] // ''val'' al paràmetre el fa consultable externament (és membre de la classe) case class Fulla[T]( val dada: T) extends Arbre[T] case class Branca[T]( val dada: T, val esquerra: Arbre[T], val dreta: Arbre[T]) extends Arbre[T] object Main extends Application { def imprimeixArbre[T]( arbre: Arbre[T]):Unit = arbre match { case Fulla( d) => println ("fulla: " ++ d.toString) case Branca( d, esq, dreta) => { imprimeixArbre( esq) ; println("branca: " ++ d.toString) ; imprimeixArbre( dreta) ; } } val arbre1 = new Fulla( 1) ; // si s'omet el paràmetre de tipus ''[T]'', es pren el del literal. val arbre2 = new Branca[Int]( 2, arbre1, arbre1) ; imprimeixArbre( arbre2) ; }
Equivalència en ML Estàndard:
datatype 't Arbre = Fulla of 't | Branca of ('t * 't Arbre * 't Arbre)
Equivalència en Haskell:
data Arbre t = Fulla t | Branca t (Arbre t) (Arbre t)
Vegeu exemple #Encaixos de patrons.
Llistes [modifica]
object Main extends Application { val llista = List( 1, 2, 3) ; def descriuLlista[T]( llista: List[T]) = llista match { case Nil => println ("llista buida") ; case ll @ _::_ => // as-pattern (variable @ patró): unifica variable i terme encaixat println ("llista no buida: " + ll.toString) ; } descriuLlista( llista ) }
Llistes per comprensió [modifica]
La clàusula for admet una primera part amb generadors i filtres (clàusula if), i una segona part de mapeig que pot ésser o bé un bloc imperatiu d'efectes laterals, o bé una clàusula yield amb una expressió o bloc que retorna una llista resultant de l'aplicació del bloc a la llista del generador.
// retorna la llista dels dobles dels parells de l'interval for (i <- Iterator.range( des_de, topall_exclòs) if i % 2 == 0) yield 2 * i
Variables [modifica]
El tipus de les declaracions es pot ometre si es dedueix de la seva inicialització de manera inequívoca, altrament el compilador avisarà.
val nom_var :tipus = .. // amb val: variable assignable un sol cop var nom_var :tipus = .. // amb var: variable assignable més d'un cop
Operadors [modifica]
Els operadors són mètodes definits amb símbols.
class Q { def ##(that:Q) = this != that }
La precedència la determina el primer dels símbols. (Vegeu apartat 'Infix operators' al manual de ref. del llenguatge).
(all letters) | ^ & < > = ! : + - * / % (all other special characters)
L'associativitat la determina el darrer símbol, que si és ':' llavors és associatiu per la dreta, altrament associatiu per l'esquerra.
Tuples [modifica]
Definides les classes Tuple2, Tuple3, .., Tuple22. Pair equival a Tuple2, Triple a Tuple3
object Main extends Application { val parell = new Pair( 10, "abc") ; val parell2 = Pair( 10, "abc") ; // alternativa amb el mètode ''fàbrica d'instàncies'' // (ang: ''factory method'') a l'objecte Pair. val Pair(primer, segon) = parell ; // encaix de la tupla println( primer) ; println( segon) ; }
Classes i mòduls Object [modifica]
En Scala se separen les parts dinàmica i estàtica de les classes del Java en class i object (mòdul no instanciable que conté els membres estàtics), com a l'OCaml.
Extensibilitat. Els mòduls object tenen un tractament unificat amb les classes respecte a l'extensibilitat com si fossin classes d'una sola instància (singleton) que els permet implementar interfaces i estendre'ls amb altres object i traits com a l'exemple amb l' object Application.
Grafia. Els identificadors dels mòduls object comencen per majúscula segons el llibre d'estil.
La inicialització dels mòduls object i també de les classes, es produeix seqüencialment processant definicions i instruccions executables, com a l'ML Estàndard i l'OCaml.
// ''Application'' és l' ''object'' d'engegada que conté el mètode ''main'' object ProvaFiltratge extends Application { def filtrar(xs: List[Int], llindar: Int) = { def processa( ys: List[Int]): List[Int] = // funció a l'interior d'una altra funció if (ys.isEmpty) ys else if (ys.head >= llindar) ys.head :: processa( ys.tail) else processa( ys.tail) processa( xs) } println( filtrar( List(1, 9, 2, 8, 3, 7, 4), 5)) }
En importar una classe de Java, l'identificador designa la classe equivalent en Scala amb els mètodes dinàmics, així com l' Object que conté els mètodes, variables i constants estàtics.
import java.lang.{Color} val vermell = new Color( 0xFF, 0, 0) ; // constructor de la ''classe'' val componentRoigDelBlanc = Color.getRed( Color.WHITE) ; // membres estàtics de l' ''Object''
- override
- els mètodes que es redefineixen han de dur el qualificatiu override per distingir-los dels que es volen nous, per evitar que si algú afegeix un mètode amb el mateix nom i signatura a alguna de les superclasses o trets que s'hereten el comportament esdevingui diferent del que se n'espera.
Trets: variables, operacions i tipus, incorporables a classes i mòduls object [modifica]
Assimilables als interface del Java, però amb el potencial d'una classe abstracta.
Els trets poden contenir definició de tipus, variables i mètodes, i també implementacions dels mètodes, però no són instanciables per si mateixos, ni poden tenir paràmetres de valor.
import java.awt.{Color} ; trait Acoloriment { var color:Color ; def pinta( nouColor: Color): Unit = { color = nouColor} def imprimeixColor: Unit = { print( "color: ") ; println( color) } } trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone(); this } } trait Resetable { def reset: Unit } def cloneAndReset(obj: Cloneable with Resetable): Cloneable = { val cloned = obj.clone() obj.reset cloned }
herència múltiple [modifica]
L'herència múltiple es basa en la incorporació de trets.
import java.awt.{Color} ; class Punt(xInicial:Int) { var x: Double = xInicial.toDouble ; def desplaça( dx: Double): Unit = { x = x + dx} def imprimeixPosició: Unit = { print( "posició: ") ; println( x) } } trait Acoloriment { var color: Color ; def pinta( nouColor: Color): Unit = { color = nouColor} def imprimeixColor: Unit = { print( "color: ") ; println( color) } } class PuntAcolorit( xInicial:Int, colorInicial: Color) extends Punt( xInicial) with Acoloriment { var color = colorInicial ; def desplaçaIPinta( dx: Double, nouColor: Color) = { super.desplaça(dx) ; super.pinta(nouColor) ; } } object Main extends Application { val punt = new PuntAcolorit( 0, Color.WHITE) { // extensió en instanciar // només aquesta instància incorpora l'extensió def desplaçaRàpid( dx: Double) = { x = x + 10.0 * dx } } punt.desplaçaIPinta(2, Color.BLUE) ; punt.desplaçaRàpid( 3.5) punt.imprimeixPosició ; punt.imprimeixColor ; }
dóna el resultat:
posició: 37.0 color: java.awt.Color[r=0,g=0,b=255]
funcions anònimes com a expressió [modifica]
exemple:
(x: Int, y:Int) => x + y // el tipus del resultat és deduït per inferència en aquest cas
En l'exemple següent el compilador dedueix els tipus dels paràmetres de la funció sobre la qual s'aplica.
object Main extends Application { val llista = List(1,2,3,4) ; // pels literals infereix tipus List[Int] // aplica la funció a un acumulador i cada valor de la llista // els tipus dels paràmetres els dedueix de l'aplicació parcial (funció ometent paràmetres) precedent. // tipus de llista.foldleft( 0) : (Int * Int) => Int val result = llista.foldLeft( 0) { (x,y) => x+y } ; Console.print("resultat: ") ; Console.println( result); }
dóna l'esperat
resultat: 10
funcions d'ordre superior [modifica]
Amb funcions als paràmetres o al resultat.
// en aquest cas, funció que pren una funció d'argument i en retorna una altra def sum(f: Int => Int): (Int, Int) => Int = { def sumF(a: Int, b: Int): Int = // suma f(x), x <- [a..b] if (a > b) 0 else f(a) + sumF(a + 1, b) &sumF } def sumaDobles = &sum( x => 2 * x) def sumaQuadrats = &sum( x => x * x)
Assercions [modifica]
Vegeu Assercions[8] i Opció de compilació -enableassertions[3]
- assert( predicat [,missatge])
- especifica un predicat que cal provar i dispara l'excepció java.lang.AssertionError: assertion failed: missatge
- assume( axioma [,missatge])
- especifica un axioma. Dispara l'excepció java.lang.AssertionError: assumption failed: missatge
- require( predicat [,missatge])
- com assert però blasma la funció que el crida,[8] llançant l'excepció IllegalArgumentException: requirement failed
- error( missatge)
XML al codi [modifica]
Vegeu [9]
object Main extends Application { val idioma = "ca" ; val títol = "El meu títol" ; val xml_títol = <title> {títol} </title> ; // entre claus '{' <expr> '}' substitució d'expressions. val xml_capsalera = <head> {xml_títol} </head> // substitució a l'atribut, hi afegeix les cometes. val xml_pàgina = <html lang={idioma}> {xml_capsalera} <body> Aquesta pàgina porta el títol {títol} </body> </html> ; val capsal_xml ="<?xml version='1.0' encoding='UTF-8' ?>\n" ; val doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" ; println( capsal_xml + doctype + xml_pàgina) ; }
Genèrics mitjançant mòduls implícits (implicit object) [modifica]
Classes genèriques (parametritzades en tipus) per agrupar funcions. Les implementacions d'aquestes classes per a tipus concrets, constitueixen mòduls de instància única (singleton) que es passaran de manera implícita (implicit object).
La obtenció de la instància adequada al tipus de la crida és automàtica, mitjançant un paràmetre implícit (absent en la crida) del tipus del genèric. Permeten diversificar el tipus retornat per una funció.
A l'exemple el paràmetre (implicit m: Monoid[A]), m obtindrà el valor de la instància específica del genèric Monoid[A] per al tipus de A emprat en la crida a la funció def suma[A](xs: List[A])(implicit m: Monoid[A]).
abstract class SemiGroup[A] {
def add(x: A, y: A): A
}
abstract class Monoid[A] extends SemiGroup[A] {
def unit: A
}
object ImplicitTest extends Application {
// mòdul instància de Monoid per al tipus String
implicit object StringMonoid extends Monoid[String] {
def add(x: String, y: String): String = x concat y
def unit: String = ""
}
// mòdul instància de Monoid per al tipus Int
implicit object IntMonoid extends Monoid[Int] {
def add(x: Int, y: Int): Int = x + y
def unit: Int = 0
}
// param. implícit selecciona instància segons param. de tipus
// entre els ''implícit object''s visibles en l'àmbit.
def suma[A](xs: List[A])(implicit m: Monoid[A]): A =
if (xs.isEmpty) m.unit
else m.add(xs.head, suma(xs.tail))
println(suma(List(1, 2, 3)))
println(suma(List("a", "b", "c")))
}
Parametrització de tipus amb cota superior [modifica]
Admetre tipus més especialitzats que un tipus determinat.
trait Similar { def isSimilar(x: Any): Boolean } case class MyInt(x: Int) extends Similar { def isSimilar(m: Any): Boolean = m.isInstanceOf[MyInt] && m.asInstanceOf[MyInt].x == x } object UpperBoundTest extends Application { def findSimilar[T <: Similar](e: T, xs: List[T]): Boolean = if (xs.isEmpty) false else if (e.isSimilar(xs.head)) true else findSimilar[T](e, xs.tail) val list: List[MyInt] = List(MyInt(1), MyInt(2), MyInt(3)) println(findSimilar[MyInt](MyInt(4), list)) println(findSimilar[MyInt](MyInt(2), list)) }
La API de Scala [modifica]
Scala té una llarga biblioteca per facilitar la feina amb varietat de col·leccions immutables i mudables així com tractament de XML i altres que trobareu aquí.[10]
L'especificació oficial del llenguatge és aquí.[11]
Els elements predefinits són a l' object Predef[12]
Entorns de desenvolupament [modifica]
La millor manera de treballar amb Scala és descarregant d'aquí[2] l'endollable per a l'Eclipse (o altres entorns de desenvolupament Java) que ja incorpora el compilador i les biblioteques de les quals, clicant, se'n pot examinar el codi font.
Scala a l'Eclipse [modifica]
A l'Eclipse[13], un cop incorporat l'endollable al menú Help->Install new software podrem crear un "Projecte Scala" que incorporarà automàticament les biblioteques de Scala al projecte si ho fem amb el menú de context de la barra lateral esquerre a l'opció "New -> Project -> Scala Wizards -> Scala Project" del menú de context de la barra lateral de projectes.
Scala segueix la mateixa estructura de mòduls (package) que el Java. Tantmateix podem posar diversos objects, classes i traits al mateix fitxer de codi font.
És habitual crear primer sobre el directori src, abreviació de source (codi font), un Package amb nom on crear els fonts, si volem facilitar l'estructuració modular o la inter-operabilitat amb paquets d'altres projectes.
Després podrem triar, al menú de context del package, els assistents (ang:wizards) de generació d'esquelets Scala Application, Scala Object, Scala Class o Scala Trait
Execució: per cada projecte cal crear una configuració d'engegada que podrem desar, especificant projecte, nom de l'objecte que conté el mètode main i possibles paràmetres de l'aplicació. Clicant el menú de context del projecte, opcions "RunAs -> Run configurations -> especificar la configuració o seleccionar-la -> botó Run"
Exemples [modifica]
Encaixos de patrons [modifica]
package test // fitxer: test/LaMevaApp.scala abstract class Llista ; trait Imprimible { // en Java seria un ''interface'' // admet definició de tipus i implementació de mètodes. def imprimeix: Unit ; // tipus Unit: equival al ''void'' de Java i C } trait Igualable { def igual_que( aquell: Any): Boolean ; def desigual_que( aquell:Any): Boolean = ! igual_que( aquell) ; // amb implementació inclosa } // herència múltiple basada en ''mixins'' (cat: barrejables): traits class LlistaImprimible extends Llista with Imprimible with Igualable { def imprimeix: Unit = this match { // ''this'' es refereix a la instància case LlistaCons( cap, cua) => { // patró LlistaCons cap match { // encaix segons el tipus case v:Int => printf("%d", v) ; case v:Float => printf("%.2f", v) ; case _ => () ; // valor () de tipus Unit equival a ''no-op'' (no fer res) } print( " ") ; cua.imprimeix ; } case LlistaNil () => println ("Fi") // patró LlistaNil } def igual_que( aquell:Any): Boolean = // refinament amb guarda: comprova la subclasse (''isInstanceOf'') // i, si té èxit, en caracteritza el tipus (''asInstanceOf'') aquell.isInstanceOf[LlistaImprimible] && aquell.asInstanceOf[LlistaImprimible] match { case LlistaNil () => this match { case LlistaNil () => true case _ => false } case LlistaCons (aquell_cap, aquella_cua) => this match { case LlistaCons (aquest_cap, aquesta_cua) => aquest_cap == aquell_cap && aquesta_cua.igual_que( aquella_cua) ; case _ => false } } } // definició dels patrons // // en lleng. SML seria: // datatype 'tip_elem Llista = LlistaNil | LlistaCons of ('tip_elem * 'tip_elem Llista) // // en lleng. Haskell seria: // data Llista tip_elem = LlistaNil | LlistaCons tip_elem (Llista tip_elem) // class Imprimible a where // imprimeix :: a -> Unit // instance Imprimible (Llista tip_elem) where ... (implementació) case class LlistaNil() extends LlistaImprimible ; case class LlistaCons[Tip_elem](cap: Tip_elem, cua: LlistaImprimible ) extends LlistaImprimible ; object LaMevaApp extends Application { override def main(args : Array[String]) : Unit = { val llista1 = new LlistaNil() ; // val: assignable un sol cop val llista2 = new LlistaCons[AnyVal](1, llista1) ; // AnyVal: qualsevol valor escalar (String exclòs) // AnyRef: qualsevol per referència (inclou String) var llista = new LlistaCons[AnyVal](2.5F, llista2) ; // var: assignable més d'un cop for (val v <- Iterator.range(4,9)) { // de 4 a 9 exclòs el darrer llista = new LlistaCons[AnyVal]( v, llista) } llista.imprimeix ; } }
# compilació a l'Eclipse: clicar al menú de context RunAs -> Run configurations # -> doble-clic a Scala application -> New Configuration # -> Ajustar el nom de l'objecte d'engegada (el que deriva de Application o conté el mètode main) # -> prémer botó Run # compilació en consola de comandes cd objdir scalac ../src/test/LaMevaApp.scala # execució i resultat (cal cridar el nom de l'objecte que conté el mètode main o que deriva l'objecte Application). scala test.LaMevaApp 8 7 6 5 4 2.50 1 Fi
Exemples a LiteratePrograms.org [modifica]
- Camí més curt de Barcelona a Lausanne en Scala segons l'algorisme de Dijkstra[14]
- Ordenació per comptatge[15]
- Ordenació per Quicksort[16]
- Ordenació per inserció[17]
- Sèrie de Fibonacci[18]
Referències [modifica]
- ↑ Scala - descàrregues(anglès)
- ↑ 2,0 2,1 Endollables Scala a diversos entorns de desenv. (anglès)
- ↑ 3,0 3,1 Scala - Opcions d'execució(anglès)
- ↑ Tipus unificats(anglès)
- ↑ Cota superior en els tipus(anglès)
- ↑ Cota inferior en els tipus(anglès)
- ↑ A tour of Scala: Views
- ↑ 8,0 8,1 Assercions(anglès)
- ↑ Scala Tour - XML(anglès)
- ↑ La API de Scala (anglès)
- ↑ Manuals del llenguatge(anglès)
- ↑ Objecte Predef(anglès) tipus i funcions predefinits. Predefinits en format nou
- ↑ Eclipse (Entorn de desenvolupament)(anglès)
- ↑ Camí més curt segons alg. de Dijkstra en Scala (anglès) amb exemple Barcelona - Lausanne
- ↑ Ordenació per comptatge(anglès)
- ↑ Ordenació per QuickSort(anglès)
- ↑ Ordenació per inserció(anglès)
- ↑ Sèrie de Fibonaci(anglès)
Enllaços externs [modifica]
- Lloc web d'Scala (anglès)
- La Comunitat Scala (anglès)
Guies:
- A Tour of Scala (anglès) Una volta per les característiques de Scala (Vegeu taula a peu de pàg.)
- Programming in Scala - Martin Odersky, Lex Spoon, and Bill Venners (anglès)
- Guia: Escrivint programes modulars en Scala (anglès)
- Artima.com - Primeres passes en Scala(anglès)
- Programació a nivell de tipus en Scala(anglès)
- Programant en Scala (anglès)
Exemples:
- Wiki de desenvolupadors d'Scala (anglès)
- Literate Programes en Scala - (anglès) Exemples d'algorismes en Scala
Recursos:
- LAMP (Esc. Politècnica de Lausanne) - Exploring Android (anglès)
- Scala - Scala i Android (anglès) Guia: Android amb Scala
- Entorn Lift (anglès) Entorn de programació en Scala de serveis web. Funciona sobre qualsevol servidor de servlets Java (Tomcat, Jetty, etc)
|
|||||
Articles:
- Concurrència en Erlang i Scala (anglès)
- IBM - Scala al mòbil (anglès) Aplicacions per al mòbil amb Android, Scala i l'entorn de desenvolupament Eclipse.