summaryrefslogtreecommitdiffhomepage
path: root/el-gr/scala-gr.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'el-gr/scala-gr.html.markdown')
-rw-r--r--el-gr/scala-gr.html.markdown689
1 files changed, 689 insertions, 0 deletions
diff --git a/el-gr/scala-gr.html.markdown b/el-gr/scala-gr.html.markdown
new file mode 100644
index 00000000..e29c7e70
--- /dev/null
+++ b/el-gr/scala-gr.html.markdown
@@ -0,0 +1,689 @@
+---
+language: Scala
+contributors:
+ - ["George Petrov", "http://github.com/petrovg"]
+ - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+translators:
+ - ["Vasilis Panagiotopoulos" , "https://github.com/billpcs/"]
+filename: learnscala-gr.scala
+lang: el-gr
+---
+
+Scala - Η επεκτάσιμη γλώσσα
+
+```scala
+
+/*
+ Προετοιμαστείτε:
+
+ 1) Κατεβάστε την Scala - http://www.scala-lang.org/downloads
+ 2) Κάνετε εξαγωγή στην επιθυμητή σας τοποθεσία και βάλτε τον υποφάκελο bin
+ στο path του συστήματος
+ 3) Ξεκινήστε ένα scala REPL γράφοντας scala. Θα πρέπει να βλέπετε το prompt:
+
+ scala>
+
+ Αυτό είναι το αποκαλούμενο REPL (Read-Eval-Print Loop) *.
+ Μπορείτε να πληκτρολογήσετε οποιαδήποτε έγκυρη έκφραση σε Scala μέσα του ,
+ και το αποτέλεσμα θα τυπωθεί. Θα εξηγήσουμε πως μοιάζουν τα αρχεία της Scala
+ αργότερα μέσα στο tutorial , αλλά για τώρα ας αρχίσουμε με κάποια βασικά.
+ *[Βρόχος του Διάβασε - Αξιολόγησε - Τύπωσε]
+*/
+
+
+/////////////////////////////////////////////////
+// 1. Βασικές έννοιες
+/////////////////////////////////////////////////
+
+// Τα σχόλια μίας γραμμής ξεκινούν με δύο "/" (:forward slashes) .
+
+/*
+ Τα σχόλια που επεκτείνονται σε πολλές γραμμές , όπως μπορείτε
+ να δείτε , φαίνοται κάπως έτσι.
+*/
+
+// Εκτύπωση με νέα γραμμή στην επόμενη εκτύπωση
+println("Hello world!")
+println(10)
+
+// Εκτύπωση χωρίς νέα γραμμή στην επόμενη εκτύπωση
+print("Hello world")
+
+// Η δήλωση μεταβλητών γίνεται χρησιμοποιώντας var ή val.
+// Οι δηλώσεις val είναι αμετάβλητες, ενώ οι var είναι μεταβλητές.
+// Η αμεταβλητότητα είναι συμφέρουσα και προσπαθούμε να την χρησιμοποιούμε.
+val x = 10 // το x είναι τώρα 10
+x = 20 // σφάλμα: αλλαγή σε val
+var y = 10
+y = 20 // το y είναι τώρα 20
+
+/*
+ Η Scala είναι στατικού τύπου γλώσσα, εν τούτις προσέξτε ότι στις παραπάνω
+ δηλώσεις , δεν προσδιορίσαμε κάποιον τύπο. Αυτό συμβαίνει λόγω ενός
+ χαρακτηριστικού της Scala που λέγεται συμπερασματολογία τύπων. Στις
+ περισσότερες των περιπτώσεων, ο μεταγλωττιστής της Scala μπορεί να
+ μαντέψει ποιός είναι ο τύπος μιας μεταβλητής. Μπορούμε να δηλώσουμε
+ αναλυτικά τον τύπο μιάς μεταβλητής ως εξής:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+/*
+ Προσέξτε ότι υπάρχει αυτόματη μετατροπή από ακέραιο (Int) σε διπλής
+ ακρίβειας (Double), και συνεπώς το αποτέλεσμα είναι 10.0 και όχι 10.
+*/
+val b: Double = 10
+
+// Λογικές τιμές
+true
+false
+
+// Λογικές Πράξεις
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// Η αριθμιτική είναι όπως τα συνηθισμένα
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
+
+
+/*
+ Αξιολογώντας μια έκφραση στο REPL, σας δίνεται ο τύπος και
+ η τιμή του αποτελέσματος
+*/
+
+1 + 7
+
+/* Η παραπάνω γραμμή έχει το εξής αποτέλεσμα:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Αυτό σημαίνει ότι το αποτέλεσμα της αξιολόγησης του 1 + 7 είναι ένα αντικείμενο
+ τύπου Int με τιμή 8
+
+ Σημειώστε ότι το "res29" είναι ένα σειριακά δημιουργούμενο όνομα μεταβλητής
+ για να αποθηκεύονται τα αποτελέσματα των εκφράσεων που έχετε πληκτρολογήσει
+ και συνεπώς η έξοδός σας μπορεί να διαφέρει.
+*/
+
+"Τα αλφαριθμητικά στην Scala περικλείονται από διπλά εισαγωγικά"
+'a' // Ένας χαρακτήρας στην Scala
+// res30: Char = a
+// 'Αλφαριθημτικά με μονά εισαγωγικά δεν υφίστανται <= Αυτό θα προκαλέσει σφάλμα.
+
+// Τα αλφαριθμητικά έχουν τις συνηθισμένες μεθόδους της Java ορισμένες πάνω τους.
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
+
+// Έχουν επίσης μερικές επιπλένον μεθόδους Scala.
+// Δείτε επίσης : scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
+
+// Παρεμβολή αλφαριθμητικών : παρατηρήστε το πρόθεμα "s"
+val n = 45
+s"We have $n apples" // => "We have 45 apples"
+
+// Παρατηρήστε την χρήση των '{', '}'
+val a = Array(11, 9, 6)
+s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
+s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
+s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
+
+// Μορφοποίηση με παρεμβεβλημένα αλφαριθμητικά με το πρόθεμα "f"
+f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
+f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
+
+// Raw αλφαριθμητικά, που αγνοούν τους ειδικούς χαρακτήρες.
+raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
+
+// Μερικούς χαρακτήρες πρέπει να τους κάνουμε "escape",
+// λ.χ ένα διπλό εισαγωγικό μέσα σε ένα αλφαριθμητικό :
+"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
+
+/*
+ Τα τριπλά διπλά-εισαγωγικά επιτρέπουν στα αλφαριθμητικά να εκτείνονται σε
+ πολλαπλές γραμμές και να περιέχουν διπλά εισαγωγικά
+*/
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Συναρτήσεις
+/////////////////////////////////////////////////
+
+// Οι συναρτήσεις ορίζονται ως εξής:
+//
+// def functionName(args...): ReturnType = { body... }
+//
+// Αν προέρχεστε απο πιο παραδοσιακές γλώσσες (C/C++ , Java) παρατηρήστε
+// την παράλειψη του return. Στην Scala , η τελευταία έκφραση στο μπλόκ
+// της συνάρτησης είναι η τιμή που επιστρέφει η συνάρτηση.
+def sumOfSquares(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// Τα { } μπορούν να παραλειφθούν αν η συνάρτηση αποτελείται απο μια απλή έκφραση:
+def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
+
+// Η σύνταξη για την κλήση συναρτήσεων είναι γνώριμη:
+sumOfSquares(3, 4) // => 25
+
+// Στις περισσότερες των περιπτώσεων (με τις αναδρομικές συναρτήσεις να αποτελούν
+// την πιο αξιοπρόσεκτη εξαίρεση) , ο τύπος επιστροφής της συνάρτησης μπορεί να
+// παραλειφθεί, και η ίδια συμπερασματολογία τύπων που είδαμε με τις μεταβλητές
+// θα δουλεύει και με τους τύπους επιστροφής της συνάρτησης:
+def sq(x: Int) = x * x // Ο μεταγλωττιστής μπορεί να μαντέψει ότι
+ // ο τύπος επιστροφής της συνάρτησης είναι Int
+
+// Οι συναρτήσεις μπορούν να έχουν προκαθορισμένες τιμές:
+def addWithDefault(x: Int, y: Int = 5) = x + y
+addWithDefault(1, 2) // => 3
+addWithDefault(1) // => 6
+
+
+// Οι ανώνυμες συναρτήσεις είναι ως εξής:
+(x:Int) => x * x
+
+// Σε αντίθεση με τα defs , ακόμα και ο τύπος εισόδου απο τις ανώνυμες
+// συναρτήσεις μπορεί να παραληφθεί αν τα συμφραζόμενα το κάνουν ξεκάθαρο.
+// Προσέξτε τον τύπο "Int => Int" που σημαίνει ότι μια συνάρτηση παίρνει
+// ένα Int και επιστρέφει ένα Int.
+val sq: Int => Int = x => x * x
+
+// Οι ανώνυμες συναρτήσεις μπορούν να κληθούν όπως συνήθως:
+sq(10) // => 100
+
+// Αν κάθε όρισμα στην ανώνυμη συνάρτηση χρησιμοποιείται μόνο μία φορά,
+// η Scala επιτρέπει έναν ακόμα πιο σύντομο τρόπο να οριστεί. Αυτές
+// οι ανώνυμες συναρτήσεις αποδεικνύεται ότι είναι πολύ κοινές ,
+// όπως θα γίνει προφανές στο μέρος των δομών δεδομένων.
+val addOne: Int => Int = _ + 1
+val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+addOne(5) // => 6
+weirdSum(2, 4) // => 16
+
+// Η δεσμευμένη λέξη return υπάρχει στην Scala , αλλά επιστρέφει μόνο
+// από το πιο εσωτερικό def που την περικλείει.
+// ΠΡΟΣΟΧΗ: Η χρήση του return στην Scala είναι επιρρεπής σε λάθη
+// και θα πρέπει να αποφεύγεται.
+// Δεν έχει καμία επίδραση στις ανώνυμες συναρτήσεις. Για παράδειγμα:
+def foo(x: Int): Int = {
+ val anonFunc: Int => Int = { z =>
+ if (z > 5)
+ return z // Αυτή η σειρά κάνει το z την τιμή που επιστρέφει η foo!
+ else
+ z + 2 // Αυτή η γραμμή είναι η τιμή που επιστρέφει η anonFunc
+ }
+ anonFunc(x) // Αυτή η γραμμή είναι η τιμή που επιστρέφει η foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Έλεγχος ροής
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach( println )
+
+r foreach println
+// ΠΡΟΣΟΧΗ: Η Scala είναι σχετικά επιεικής ως αναφορά τις τελείες και
+// τις παρενθέσεις. Διαβάστε τους κανόνες ξεχωριστά.
+// Αυτό βοηθάει στο να γράφεις DSLs και APIs που διαβάζονται σαν τα Αγγλικά.
+
+(5 to 1 by -1) foreach ( println )
+
+// Ένας βρόχος while :
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+while (i < 10) { println("i " + i); i+=1 } // Ναι ξανά! Τι συνέβει; Γιατί;
+
+i // Εμφάνισε την τιμή του i. Σημειώστε ότι ένας βρόχος while είναι βρόχος
+ // με την κλασική έννοια - εκτελείται σειριακά καθώς αλλάζει η μεταβλητή
+ // του βρόχου. Το while είναι πολύ γρήγορο , γρηγορότερο απο τους βρόχους
+ // της Java , αλλά η χρήση combinators και comprehensions όπως πιο πάνω ,
+ // είναι πιο εύκολη στην κατανόηση και στην παραλληλοποίηση.
+
+// Ένας βρόχος do while :
+do {
+ println("x is still less than 10");
+ x += 1
+} while (x < 10)
+
+// Η αναδρομή ουράς είναι ένας ιδιωματικός τρόπος να κάνεις επαναλαμβανόμενα
+// πράγματα στην Scala. Οι αναδρομικές συναρτήσεις απαιτούν να γράφτεί
+// ρητά ο τύπος που θα επιστρέψουν , αλλιώς ο μεταγλωττιστής δεν μπορεί
+// αλλιώς να τον συνάγει. Παρακάτω είναι μια συνάρτηση που επιστρέφει Unit.
+def showNumbersInRange(a:Int, b:Int):Unit = {
+ print(a)
+ if (a < b)
+ showNumbersInRange(a + 1, b)
+}
+showNumbersInRange(1,14)
+
+
+// Έλεγχος Ροής
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Δομές Δεδομένων
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0)
+a(3)
+a(21) // "Πετάει" exception
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork")
+m("spoon")
+m("bottle") // "Πετάει" exception
+
+val safeM = m.withDefaultValue("no lo se")
+safeM("bottle")
+
+val s = Set(1, 3, 7)
+s(0)
+s(1)
+
+/* Δείτε το documentation του map εδώ -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ */
+
+
+// Πλειάδες
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Γιατί να το έχουμε αυτό;
+val divideInts = (x:Int, y:Int) => (x / y, x % y)
+
+divideInts(10,3) // Η συνάρτηση divideInts επιστρέφει το αποτέλεσμα
+ // της ακαίρεας διαίρεσης και το υπόλοιπο.
+
+// Για να έχουμε πρόσβαση στα στοιχεία μιας πλειάδας, χρησιμοποιούμε το _._n
+// όπου το n είναι ο δείκτης με βάση το 1 του στοιχείου.
+val d = divideInts(10,3)
+
+d._1
+
+d._2
+
+
+/////////////////////////////////////////////////
+// 5. Αντικειμενοστραφής Προγραμματισμός
+/////////////////////////////////////////////////
+
+/*
+ Ότι έχουμε κάνει ως τώρα σε αυτό το tutorial ήταν απλές εκφράσεις
+ (τιμές , συναρτήσεις , κτλ). Αυτές οι εκφράσεις βολεύουν όταν τις
+ γράφουμε στο REPL για γρήγορες δοκιμές, αλλά δεν μπορούν να υπάρχουν
+ από μόνες τους σε ένα αρχείο Scala. Για παράδειγμα , δεν μπορούμε να
+ έχουμε μόνο ένα "val x = 5" στο αρχείο Scala. Αντί αυτού , τα μόνα
+ στοιχεία του πάνω επιπέδου που επιτρέπονται στην Scala είναι:
+
+ - αντικείμενα (objects)
+ - κλάσεις (classes)
+ - κλάσεις περίπτωσης (case classes στην Scala)
+ - Χαρακτηριστικά (traits , όπως ονομάζονται στην Scala)
+
+ Και τώρα θα εξηγήσουμε τι είναι αυτά.
+*/
+// Οι κλάσεις είναι παρόμοιες με τις κλάσεις σε άλλες γλώσσες. Τα ορίσματα του
+// "κατασκευαστή" (constructor) δηλώνονται μετά από το όνομα της κλάσης ,
+// και η αρχικοποιήση γίνεται μέσα στο σώμα της κλάσης.
+class Dog(br: String) {
+ // Κώδικας για τον "κατασκευαστή"
+ var breed: String = br
+
+ // Ορίζεται μια μέθοδος bark , που επιστρέφει ένα αλφαριθμητικό
+ def bark = "Woof, woof!"
+
+ // Οι τιμές και οι μέθοδοι είναι public εκτός αν χρησιμοποιήσουμε κάποια
+ // απο τις λέξεις κλειδιά "protected" και "private" .
+ private def sleep(hours: Int) =
+ println(s"I'm sleeping for $hours hours")
+
+ // Οι abstract μέθοδοι είναι απλά μέθοδοι χωρίς σώμα. Αν βγάζαμε
+ // το σχόλιο απο την επόμενη γραμμή η κλάση Dog θα έπρεπε να
+ // δηλωθεί ως abstract class Dog(...) { ... } :
+ // def chaseAfter(what: String): String
+}
+
+val mydog = new Dog("greyhound")
+println(mydog.breed) // => "greyhound"
+println(mydog.bark) // => "Woof, woof!"
+
+
+// Η λέξη "object" δημιουργεί ένα type ΚΑΙ ένα singleton instance αυτού.
+// Είναι κοινό για τις κλάσεις στην Scala να έχουν ένα "συντροφικό object",
+// όπου η συμπεριφορά για κάθε instance αιχμαλωτίζεται μέσα στις κλάσεις
+// αυτές καθ' αυτές, αλλά η συμπρεριφορά που σχετίζεται με όλα τα instances
+// της κλάσης πάνε μέσα στο object. Η διαφορά είναι παρόμοια με τις
+// μεθόδους κλάσεων σε σχέση με στατικές μεθόδους σε άλλες γλώσσες.
+// Προσέξτε οτι τα objects και οι κλάσεις μπορούν να έχουν το ίδιο όνομα.
+object Dog {
+ def allKnownBreeds = List("pitbull", "shepherd", "retriever")
+ def createDog(breed: String) = new Dog(breed)
+}
+
+// Οι κλάσεις περίπτωσης (case classes) είναι που έχουν την επιπλέον
+// λειτουργικότητα ενσωματωμένη. Μιά συνήθης ερώτηση για αρχάριους στην
+// Scala είναι πότε να χρησιμοπούνται κλάσεις και πότε case κλάσεις.
+// Γενικά οι κλάσεις τείνουν να εστιάζουν στην ενθυλάκωση, τον
+// πολυμορφισμό και τη συμπεριφορά. Οι τιμές μέσα σε αυτές τις κλάσεις
+// τείνουν να είναι private , και μόνο οι μέθοδοι είναι εκτεθειμένες.
+// Ο κύριος σκοπός των case classes είναι να κρατούν δεδομένα που είναι
+// σταθερές(immutable). Συνήθως έχουν λίγες μεθόδους και οι μέθοδοι σπάνια
+// έχουν παρενέργειες.
+case class Person(name: String, phoneNumber: String)
+
+// Δημιουργία ενός instance. Πραρατηρήστε ότι τα case classes
+// δεν χρειάζονται την λέξη "new" .
+val george = Person("George", "1234")
+val kate = Person("Kate", "4567")
+
+// Με τα case classes, παίρνεις μερικά προνόμια δωρεάν , όπως:
+george.phoneNumber // => "1234"
+
+// Ελέχγεται η ισότητα για κάθε πεδίο (δεν χρειάζεται να
+// κάνουμε override στο .equals)
+Person("George", "1234") == Person("Kate", "1236") // => false
+
+// Έυκολος τρόπος να κάνουμε αντιγραφή. Δημιουργούμε έναν νέο geroge:
+// otherGeorge == Person("george", "9876")
+val otherGeorge = george.copy(phoneNumber = "9876")
+
+// Και πολλά άλλα. Τα case classes έχουν και αντιστοίχιση προτύπων
+// (pattern matching) δωρεάν, δείτε παρακάτω.
+
+// Τα χαρακτηριστικά (traits) έρχονται σε λίγο καιρό !
+
+/////////////////////////////////////////////////
+// 6. Αντιστοίχιση Προτύπων
+/////////////////////////////////////////////////
+
+// Η αντιστοίχιση προτύπων (pattern matching) είναι ένα πολύ δυνατό και
+// ευρέως χρησιμοποιούμενο χαρακτηριστικό στην Scala. Παρακάτω βλέπουμε
+// πως γίνεται το pattern matching σε ένα case class. Σημείωση: Σε
+// αντίθεση με άλλες γλώσσες η Scala δεν χρειάζεται breaks, γιατί γίνεται
+// αυτόματα όταν γίνει κάποιο match.
+
+def matchPerson(person: Person): String = person match {
+ // Μετά προσδιορίζουμε το πρότυπο (pattern):
+ case Person("George", number) => "We found George! His number is " + number
+ case Person("Kate", number) => "We found Kate! Her number is " + number
+ case Person(name, number) => "We matched someone : " + name + ", phone : " + number
+}
+
+val email = "(.*)@(.*)".r // Ορίζουμε ένα regex για το επόμενο παράδειγμα.
+ // (regex <- REGular EXpression)
+
+// Το pattern matching μπορεί να μοιάζει γνώριμο απο τα switch statements σε
+// γλώσσες που ανήκουν στην οικογένεια της C αλλά είναι πολύ πιο ισχυρό.
+// Στην Scala , μπορούμε να κάνουμε match πολύ περισσότερα:
+def matchEverything(obj: Any): String = obj match {
+ // Μπορούμε να ταιριάξουμε τιμές:
+ case "Hello world" => "Got the string Hello world"
+
+ // Μπορούμε να ταιριάξουμε τύπους:
+ case x: Double => "Got a Double: " + x
+
+ // Μπορούμε να βάλουμε συνθήκες:
+ case x: Int if x > 10000 => "Got a pretty big number!"
+
+ // Μπορούμε να ταιριάξουμε case classes όπως πρίν:
+ case Person(name, number) => s"Got contact info for $name!"
+
+ // Μπορούμε να ταιριάξουμε regex:
+ case email(name, domain) => s"Got email address $name@$domain"
+
+ // Μπορούμε να ταιριάξουμε πλειάδες:
+ case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
+
+ // Μπορούμε να ταιριάξουμε δομές δεδομένων:
+ case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
+
+ // Μπορούμε να ταιριάξουμε πρότυπα που το ένα είναι μέσα στο άλλο:
+ case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
+}
+
+// Στην πραγματικότητα , μπορούμε να κάνουμε pattern matching σε όποιο αντικείμενο
+// έχει την μέθοδο "unapply". Αυτό το χαρακτηριστικό είναι τόσο ισχυρό ώστε
+// η Scala επιτρέπει να ορίστούν ολόκληρες συναρτήσεις σαν patterns.
+val patternFunc: Person => String = {
+ case Person("George", number) => s"George's number: $number"
+ case Person(name, number) => s"Random person's number: $number"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Συναρτησιακός Προγραμματισμός
+/////////////////////////////////////////////////
+
+// Η Scala επιτρέπει στις μεθόδους και τις συναρτήσεις να επιστρέφουν ή να
+// δέχονται ως παραμέτρους άλλες μεθόδους ή συναρτήσεις.
+
+val add10: Int => Int = _ + 10 // Μια συνάρτηση που δέχεται Int και επιστρέφει Int
+List(1, 2, 3) map add10 // List(11, 12, 13) - το add10 εφαρμόζεται σε κάθε στοιχείο
+ // μέσω του map
+
+// Οι ανώνυμες συναρτήσεις μπορούν να χρησιμοποιηθούν αντί
+// ονοματισμένων (όπως απο πάνω) :
+List(1, 2, 3) map (x => x + 10)
+
+// Και το σύμβολο της κάτω παύλας , μπορεί να χρησιμοποιηθεί αν υπάρχει μόνο
+// ένα όρισμα στην ανώνυμη συνάρτηση. Έτσι δεσμεύεται ως η μεταβλητή.
+List(1, 2, 3) map (_ + 10)
+
+// Αν το μπλόκ της ανώνυμης συνάρτησης ΚΑΙ η συνάρτηση που εφαρμόζεται
+// (στην περίπτωσή μας το foreach και το println) παίρνουν ένα όρισμα
+// μπορείτε να παραλείψετε την κάτω παύλα.
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Συνδυαστές
+
+s.map(sq)
+
+val sSquared = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// Η συνάρτηση filter παίρνει ένα κατηγορούμενο (predicate)
+// που είναι μια συνάρτηση απο το A -> Boolean και διαλέγει
+// όλα τα στοιχεία που ικανοποιούν αυτό το κατηγορούμενο.
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Person(name:String, age:Int)
+List(
+ Person(name = "Dom", age = 23),
+ Person(name = "Bob", age = 30)
+).filter(_.age > 25) // List(Person("Bob", 30))
+
+
+// Το foreach είναι μια μέθοδος της Scala , που ορίζεται για ορισμένες
+// συλλογές (collections). Παίρνει έναν τύπο και επιστρέφει Unit
+// (μια μέθοδο void)
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+
+// For comprehensions
+
+for { n <- s } yield sq(n)
+
+val nSquared2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/*
+ Προσοχή : Αυτά δεν ήταν βρόχοι for. Η σημασιολογία ενός βρόχου for είναι
+ η επανάληψη, ενώ ένα for-comprehension ορίζει μια σχέση μεταξύ δύο
+ συνόλων δεδομένων.
+*/
+
+/////////////////////////////////////////////////
+// 8. Implicits
+/////////////////////////////////////////////////
+/*
+ ΠΡΟΣΟΧΗ! Τα implicits είναι ένα σύνολο απο ισχυρά χαρακτηριστικά της Scala
+ και επομένως είναι εύκολο να γίνει κατάχρηση. Οι αρχάριοι στην Scala θα
+ πρέπει να αντισταθούν στον πειρασμό να τα χρησιμοποιήσουν έως ότου, όχι
+ μόνο καταλάβουν πως λειτουργούν, αλλά ακόμα εξασκηθούν πάνω τους.
+ Ο μόνος λόγος που συμπεριλάβαμε αυτό το κομμάτι στο tutorial είναι
+ γιατί είναι τόσο κοινό στις βιβλιοθήκες της Scala , που αδύνατο να κάνεις
+ οτιδήποτε σημαντικό χωρίς να χρησιμοποιήσεις μια που να έχει implicits.
+
+*/
+
+// Κάθε τιμή (vals , συναρτήσεις , αντικείμενα , κτλ) μπορεί να δηλωθεί ως
+// implicit χρησιμοποιώντας , ναι το μαντέψατε , την λέξη "implicit".
+// Σημειώστε ότι χρησιμοποιούμε την κλάση Dog που δημιουργήσαμε στο
+// 5ο μέρος των παραδειγμάτων.
+implicit val myImplicitInt = 100
+implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
+
+
+// Απο μόνη της, η λέξη implicit, δεν αλλάζει την συμπεριφορά μιάς τιμής
+// οπότε οι παραπάνω μπορούν να χρησιμοποιοηθούν όπως συνήθως.
+myImplicitInt + 2 // => 102
+myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
+
+// Η διαφορά είναι ότι τώρα αυτές οι τιμές έχουν την δυνατότητα να
+// χρησιμοποιηθούν όταν ένα άλλο κομμάτι κώδικα "χρειάζεται" μια
+// implicit τιμή. Μια τέτοια περίπτωση είναι τα ορίσματα μιας implicit
+// συνάρτησης:
+def sendGreetings(toWhom: String)(implicit howMany: Int) =
+ s"Hello $toWhom, $howMany blessings to you and yours!"
+
+// Άν τροφοδοτήσουμε μια τιμή για το "homMany", η συνάρτηση συμπεριφέρεται
+// ως συνήθως
+sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
+
+// Αλλά αν παραλείψουμε την παράμετρο implicit , μια implicit τιμή του ιδίου τύπου
+// χρησιμοποιείται, στην περίπτωσή μας, το "myImplicitInt"
+sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+
+// Οι παράμετροι implicit συναρτήσεων μας επιτρέπουν να προσομοιάζουμε
+// κλάσεις τύπων (type classes) σε άλλες συναρτησιακές γλώσσες.
+// Χρησιμοποιείται τόσο συχνά που έχει την δικιά του συντομογραφία.
+// Οι επόμενες δύο γραμμές κώδικα σημαίνουν το ίδιο πράγμα.
+def foo[T](implicit c: C[T]) = ...
+def foo[T : C] = ...
+
+
+
+// Μια άλλη περίπτωση στην οποία ο μεταγλωττιστής αναζητά μια implicit τιμή
+// είναι αν έχετε obj.method (...)
+// αλλά το "obj" δεν έχει την "method" ως μέθοδο. Σε αυτή την περίπτωση,
+// αν υπάρχει μια implicit μετατροπή του τύπου Α => Β, όπου Α είναι ο τύπος
+// του obj, ενώ το Β έχει μία μέθοδο που ονομάζεται «method», εφαρμόζεται η
+// εν λόγω μετατροπή. Έτσι, έχοντας την MyImplicitFunction μέσα στο πεδίο
+// εφαρμογής(scope), μπορούμε να πούμε:
+"Retriever".breed // => "Golden Retriever"
+"Sheperd".bark // => "Woof, woof!"
+
+// Εδώ το String αρχικά μετατρέπεται σε Dog χρησιμοποιώντας την συνάρτησή μας
+// παραπάνω, και μετά καλείται η κατάλληλη μέθοδος. Αυτό είναι ένα εξερετικά
+// ισχυρό χαρακτηριστικό, αλλά δεν πρέπει να χρησιμοποιείται με ελαφριά την
+// καρδιά. Μάλιστα, όταν ορίσατε την συνάρτηση implicit παραπάνω, ο μεταγλωττιστής
+// θα πρέπει να σας έδωσε μια προειδοποιήση, ότι δεν πρέπει να το κάνετε αυτό
+// εκτός αν πραγματικά γνωρίζετε τι κάνετε.
+
+
+/////////////////////////////////////////////////
+// 9. Διάφορα
+/////////////////////////////////////////////////
+
+// Εισαγωγή βιβλιοθηκών κτλ
+import scala.collection.immutable.List
+
+// Εισαγωγή των πάντων απο το scala.collection.immutable
+import scala.collection.immutable._
+
+// Εισαγωγή πολλών κλάσεων σε μία έκφραση
+import scala.collection.immutable.{List, Map}
+
+// Δώστε ένα νέο όνομα στην εισαγωγή σας χρησιμοποιώντας το '=>'
+import scala.collection.immutable.{ List => ImmutableList }
+
+// Εισαγωγή όλων των κλάσεων εκτός απο μερικές.
+// Το επόμενο δεν εισάγει το Map και το Set:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// Το σημείο εισαγωγής του προγράμματος σας ορίζεται σε ένα αρχείο scala ,
+// χρησιμοποιώντας ένα αντικείμενο (object), με μία μέθοδο , την main.
+object Application {
+ def main(args: Array[String]): Unit = {
+ // Εδω γράφουμε ...
+ }
+}
+
+// Files can contain multiple classes and objects. Compile with scalac
+// Τα files μπορούν να περιέχουν περισσότερες απο μία κλάσεις και
+// αντικείμενα. Το compile γίνεται με την εντολή scalac
+
+// Εισαγωγή και εξαγωγή.
+
+// Για να διβάσετε ένα αρχείο γραμμή προς γραμμή
+import scala.io.Source
+for(line <- Source.fromFile("myfile.txt").getLines())
+ println(line)
+
+// Για να γράψετε σε ένα αρχείο
+val writer = new PrintWriter("myfile.txt")
+writer.write("Writing line for line" + util.Properties.lineSeparator)
+writer.write("Another line here" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Further resources
+
+[Scala for the impatient](http://horstmann.com/scala/)
+
+[Twitter Scala school](http://twitter.github.io/scala_school/)
+
+[The scala documentation](http://docs.scala-lang.org/)
+
+[Try Scala in your browser](http://scalatutorials.com/tour/)
+
+Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
+