summaryrefslogtreecommitdiffhomepage
path: root/el-gr
diff options
context:
space:
mode:
Diffstat (limited to 'el-gr')
-rw-r--r--el-gr/css-gr.html.markdown242
-rw-r--r--el-gr/java-gr.html.markdown858
-rw-r--r--el-gr/racket-gr.html.markdown745
-rw-r--r--el-gr/scala-gr.html.markdown689
4 files changed, 2534 insertions, 0 deletions
diff --git a/el-gr/css-gr.html.markdown b/el-gr/css-gr.html.markdown
new file mode 100644
index 00000000..31b30479
--- /dev/null
+++ b/el-gr/css-gr.html.markdown
@@ -0,0 +1,242 @@
+---
+language: css
+contributors:
+ - ["Kostas Bariotis", "http://kostasbariotis.com"]
+filename: css-gr.html.markdown
+lang: el-gr
+---
+
+Η αρχική μορφή του Παγκόσμιου Ιστού αποτελείτο απο καθαρό κείμενο, χωρίς οπτικά αντικείμενα. Με το πέρας
+του χρόνου και την εξέλιξη των Φυλλομετρητών, οι πλούσιες σελίδες, σε οπτικά και πολυμεσικά αντικείμενα,
+έγιναν καθημερινότητα.
+
+Η CSS μας βοηθάει να διαχωρήσουμε το περιεχόμενο της σελίδας μας (HTML) απο την οπτική της περιγραφή.
+
+Με την CSS ορίζουμε οπτικές ιδιότητες (χρώμα, μέγεθος, κλπ) σε HTML αντικείμενα (H1, div, κλπ).
+
+```css
+/* Τα σχόλια εμφανίζονται εντός καθέτου-αστερίσκου, όπως εδώ.
+ Δεν υπάρχουν σχόλια μια γραμμής και πολλών. */
+
+/* ####################
+ ## ΚΑΝΟΝΕΣ
+ #################### */
+
+/* ένας κανόνας χρησιμοποιείται για να στοχεύσουμε ένα αντικείμενο (selector). */
+selector { property: value; /* περισσότερες ιδιότητες...*/ }
+
+/*
+Αυτό είναι ενα παράδειγμα αντικειμένου
+<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
+*/
+
+/* Μπορούμε να το στοχεύσουμε με την χρήση CSS κλάσεων */
+.class1 { }
+
+/* Ή και με τις δύο κλάσεις! */
+.class1.class2 { }
+
+/* Και με το όνομα του */
+div { }
+
+/* Ή με το id του */
+#anID { }
+
+/* Ή με το γεγονός ότι περιέχει ενα attribute */
+[attr] { font-size:smaller; }
+
+/* Ή οτι το attribute αυτό έχει μια συγκεκριμένη τιμή */
+[attr='value'] { font-size:smaller; }
+
+/* Ξεκινάει απο το λεκτικό (CSS 3) */
+[attr^='val'] { font-size:smaller; }
+
+/* Καταλήγει σε αυτο το λεκτικό (CSS 3) */
+[attr$='ue'] { font-size:smaller; }
+
+/* Περιέχει κάποιο λεκτικό */
+[otherAttr~='foo'] { }
+[otherAttr~='bar'] { }
+
+/* περιέχει το λεκτικό σε λίστα χωρισμένη με παύλες, δηλαδή: "-" (U+002D) */
+[otherAttr|='en'] { font-size:smaller; }
+
+
+/* Μπορούμε να προσθέσουμε μεταξύ τους selectors για να δημιουργήσουμε πιο αυστηρούς.
+ Δεν βάζουμε κενά ανάμεσα. */
+div.some-class[attr$='ue'] { }
+
+/* Μπορούμε να επιλέξουμε αντικείμενα που βρίσκονται μέσα σε άλλα. */
+div.some-parent > .class-name { }
+
+/* Ή κάποιο αντικείμενο απόγονο ανεξαρτήτου του βάθους της σχέσης τους. */
+div.some-parent .class-name { }
+
+/* ΠΡΟΣΟΧΗ: ο ίδιος selector χωρίς κενά έχει άλλο νόημα. (Άσκηση προς τον αναγνώστη) */
+div.some-parent.class-name { }
+
+/* Μπορούμε να επιλέξουμε αντικείμενα με βάση το αμέσως επόμενο αντικείμενο στο ίδιο επίπεδο. */
+.i-am-just-before + .this-element { }
+
+/* Ή οποιοδήποτε αντικείμενο που προηγείται */
+.i-am-any-element-before ~ .this-element { }
+
+/* Με την βοήθεια των ψευδο-κλάσεων μπορούμε να επιλέξουμε αντικείμενα που βρίσκονται σε μια
+ ορισμένη κατάασταση. */
+
+/* π.χ. όταν ο κέρσορας είναι πάνω απο ένα αντικείμενο */
+selector:hover { }
+
+/* ή ένας υπερσύνδεσμος που πατήθηκε */
+selector:visited { }
+
+/* ή που δεν πατήθηκε */
+selected:link { }
+
+/* ή ένα αντικείμενο που επιλέχθηκε */
+selected:focus { }
+
+/* οποιοδήποτε αντικείμενο είναι το πρώτο παιδί των γονέων του */
+selector:first-child {}
+
+/* οποιοδήποτε αντικείμενο είναι το πρώτοτελευταίο παιδί των γονέων του */
+selector:last-child {}
+
+/* Όπως και με τις ψευδο-κλάσεις, τα ψευδο-αντικείμενα μας επιτρέπουν τα τροποοιήσουμε συγκεκριμένα
+ κομμάτια της σελίδας */
+
+/* επιλέγει το ψευδο-αντικείμενο ακριβώς πριν απο το αντικείμενο */
+selector::before {}
+
+/* επιλέγει το ψευδο-αντικείμενο ακριβώς μετά απο τον αντικείμενο */
+selector::after {}
+
+/* Σε σωστά σημεία (όχι πολύ ψηλά στην ιεραρχία) ο αστερίσκος μπορείς να χρησιμοποιηθεί για να
+ επιλέξουμε όλα τα αντικείμενα */
+* { } /* όλα τα αντικείμενα της σελίδας */
+.parent * { } /* όλους τους απόγονους */
+.parent > * { } /* όλους τους απόγονους πρώτου επιπέδου */
+
+/* ####################
+ ## Ιδιότητες
+ #################### */
+
+selector {
+
+ /* Οι μονάδες μπορούν να είναι είτε απόλυτες είτε σχετικές */
+
+ /* Σχετικές μονάδες */
+ width: 50%; /* ποσοστό επί του πλάτους του γονέα */
+ font-size: 2em; /* πολλαπλασιαστής της αρχικής τιμής του αντικειμένου */
+ font-size: 2rem; /* ή της τιμής του πρώτου αντικειμένου στην ιεραρχία */
+ font-size: 2vw; /* πολλαπλαστιαστής του 1% του οπτικού πλάτους */
+ font-size: 2vh; /* ή τους ύψους */
+ font-size: 2vmin; /* οποιοδήποτε απο αυτα τα δύο είναι το μικρότερο */
+ font-size: 2vmax; /* ή το μεγαλύτερο */
+
+ /* Απόλυτες μονάδες */
+ width: 200px; /* pixels */
+ font-size: 20pt; /* στιγμες */
+ width: 5cm; /* εκατοστά */
+ min-width: 50mm; /* χιλιοστά */
+ max-width: 5in; /* ίντσες */
+
+ /* Χρώματα */
+ color: #F6E; /* σύντομη δεκαεξαδική μορφή */
+ color: #FF66EE; /* δεκαεξαδική μορφή */
+ color: tomato; /* χρώμα με το όνομα του (συγκεκριμένα χρώματα) */
+ color: rgb(255, 255, 255); /* τιμή RGB */
+ color: rgb(10%, 20%, 50%); /* τιμή RGB με ποσοστά */
+ color: rgba(255, 0, 0, 0.3); /* τιμή RGBA (CSS3) σσ. 0 < a < 1 */
+ color: transparent; /* όπως και το παραπάνω με a = 0 */
+ color: hsl(0, 100%, 50%); /* τιμή hsl με ποσοστά (CSS 3) */
+ color: hsla(0, 100%, 50%, 0.3); /* τιμή hsla με ποσοστά και a */
+
+ /* Εικόνες μπορούν να τοποθετηθούν στον φόντο ενός αντικειμένου */
+ background-image: url(/img-path/img.jpg);
+
+ /* Γραμματοσειρές */
+ font-family: Arial;
+ /* εάν η γραμματοσειρα περιέχει κενά */
+ font-family: "Courier New";
+ /* εάν η πρώτη γραμματοσειρα δε βρεθεί εγκατεστημένη στο Λειτουργικό Σύστυμα, αυτόματα
+ επιλέγετε η δεύτερη, κ.κ.ε. */
+ font-family: "Courier New", Trebuchet, Arial, sans-serif;
+}
+```
+
+## Χρήση
+
+Αποθηκεύουμε ένα αρχείο CSS με την επέκταση `.css`.
+
+```xml
+<!-- Πρέπει να συμπεριλάβουμε το αρχείο στην επικεφαλίδα(head) ενος HTML αρχείου.
+ σσ. http://stackoverflow.com/questions/8284365 -->
+<link rel='stylesheet' type='text/css' href='path/to/style.css' />
+
+<!-- Μπορούμε να το ενσωματώσουμε -->
+<style>
+ a { color: purple; }
+</style>
+
+<!-- Ή απευθείας σε κάποιο αντικείμενο (inline) -->
+<div style="border: 1px solid red;">
+</div>
+```
+
+## Ειδικότητα των κανόνων (Cascading απο το αγγλικό τίτλο Cascading Style Sheets)
+
+Ένα αντικείμενο μπορεί να στοχευθεί απο πολλούς κανόνες και μπορεί η ίδια ιδιότητα να
+περιλαμβάνετε σε πολλούς κανόνες. Σε αυτές της περιπτώσεις υπερισχύει πάντα ο πιο ειδικός
+κανόνας και απο αυτούς, αυτός που εμφανίζεται τελευταίος.
+
+```css
+/* A */
+p.class1[attr='value']
+
+/* B */
+p.class1 { }
+
+/* C */
+p.class2 { }
+
+/* D */
+p { }
+
+/* E */
+p { property: value !important; }
+```
+
+```xml
+<p style='/*F*/ property:value;' class='class1 class2' attr='value' />
+```
+
+Η σειρά θα είναι:
+
+* `E` έχει μεγαλύτερο βάρος λόγω του `!important`. Κάλες πρακτικές λένε να το αποφεύγουμε.
+* `F` επόμενο λόγω του inline κανόνα.
+* `A` επόμενο λόγω του το οτι είναι πιο ειδικό. Περιέχει τρεις selectors.
+* `C` επόμενο, λόγω του οτι εμφανίζεται μετα το Β και ας έχει την ίδια ειδικότητα.
+* `B` επόμενο.
+* `D` τελευταίο.
+
+## Συμβατότητα
+
+Τα περισσότερα απο τα παραπάνω ήδη υποστηρίζονται απο τους γνωστούς φυλλομετρητές. Άλλα θα πρέπει
+πάντα να ελέγχουμε πρωτου τους χρησιμοποιήσουμε.
+
+## Περισσότερα
+
+* Έλεγχος συμβατότητας, [CanIUse](http://caniuse.com).
+* CSS Playground [Dabblet](http://dabblet.com/).
+* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS)
+* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/)
+
+## Μελέτη
+
+* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
+* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
+* [QuirksMode CSS](http://www.quirksmode.org/css/)
+* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
+* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
+* [CSS-Tricks](https://css-tricks.com)
diff --git a/el-gr/java-gr.html.markdown b/el-gr/java-gr.html.markdown
new file mode 100644
index 00000000..5dad4a60
--- /dev/null
+++ b/el-gr/java-gr.html.markdown
@@ -0,0 +1,858 @@
+---
+language: java
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Jakukyo Friel", "http://weakish.github.io"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
+ - ["Simon Morgan", "http://sjm.io/"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "http://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+filename: LearnJava-gr.java
+translators:
+ - ["Andreas Loizou" , "https://github.com/lack3r/"]
+lang: el-gr
+---
+
+H Java είναι μία γενικού-σκοπού, συντρέχων (concurrent), βασισμένη σε κλάσεις,
+αντικειμενοστρεφής (object oriented) γλώσσα προγραμματισμού.
+[Διαβάστε περισσότερα εδώ.](http://docs.oracle.com/javase/tutorial/java/)
+
+```java
+// Τα σχόλια μονής γραμμής ξεκινούν με //
+/*
+Τα σχόλια πολλών γραμμών μοιάζουν κάπως έτσι.
+*/
+/**
+Τα σχόλια JavaDoc μοιάζουν κάπως έτσι. Χρησιμοποιούνται για να περιγράψουν την
+Κλάση ή διάφορα χαρακτηριστικά της Κλάσης.
+*/
+
+// Εισαγωγή της κλάσης ArrayList η οποία βρίσκεται εντός του πακέτου java.util
+import java.util.ArrayList;
+// Εισαγωγή όλων των κλάσεων που βρίσκονται εντός του πακέτου java.security
+import java.security.*;
+
+// Κάθε αρχείο .java περιέχει μία δημόσια(public) κλάση εξωτερικού-επιπέδου
+// (outer-level), η οποία έχει το ίδιο ονομα με το αρχείο.
+public class LearnJava {
+
+ // Για να τρέξει ένα πρόγραμμα java, πρέπει να έχει μία κύρια μέθοδο (main
+ // method) ως αρχικό σημείο.
+ public static void main (String[] args) {
+
+ // Χρησιμοποιούμε τη μέθοδο System.out.println() για να τυπώσουμε
+ // γραμμές.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Για να τυπώσουμε χωρίς να τυπωθεί αλλαγή γραμμής (newline),
+ // χρησιμοποιούμε System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // Χρησιμοποιούμε τη μέθοδο System.out.printf() για έυκολη μορφοποίηση
+ // της εκτύπωσης.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ ///////////////////////////////////////
+ // Μεταβλητές(Variables)
+ ///////////////////////////////////////
+
+ /*
+ * Δήλωση Μεταβλητών
+ */
+ // Δηλώνουμε μία μεταβλητή χρησιμοποιώντας τη μορφή
+ // <Τύπος Μεταβλητής> <Όνομα Μεταβλητής>
+ int fooInt;
+ // Δηλώνουμε πολλαπλές μεταβλητές ίδιου τύπου χρησιμοποιώντας τη μορφή
+ // <Τύπος> <Όνομα1>, <Όνομα2>, <Όνομα3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Αρχικοποίηση Μεταβλητών
+ */
+
+ // Αρχικοποιούμε μια μεταβλητή χρησιμοποιώντας τη μορφή
+ // <τύπος> <όνομα> = <τιμή>
+ int fooInt = 1;
+ // Αρχικοποιούμε πολλαπλές μεταβλητές ιδίου τύπου με την ίδια τιμή
+ // χρησιμοποιώντας <τύπος> <Όνομα1>, <Όνομα2>, <Όνομα3> = <τιμή>
+ int fooInt1, fooInt2, fooInt3;
+ fooInt1 = fooInt2 = fooInt3 = 1;
+
+ /*
+ * Τύποι μεταβλητών
+ */
+ // Byte - 8-bit signed two's complement integer
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Short - 16-bit signed two's complement integer
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 32-bit signed two's complement integer
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Long - 64-bit signed two's complement integer
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // Το L χρησιμοποιείται για να δηλώσει ότι η συγκεκριμένη τιμή της
+ // μεταβλητής είναι τύπου Long;
+ // Ό,τιδήποτε χρησιμοποιείται χωρίς αυτό τυχαίνει μεταχείρισης όπως
+ // μία τιμή μεταβλητής integer by default.
+
+ // Σημείωση: Η Java δεν έχει unsigned τύπους.
+
+ // Float - Single-precision 32-bit IEEE 754 Floating Point
+ // 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f or F χρησιμοποιείται για να δηλώσει ότι η συγκεκριμένη τιμή
+ // μεταβλητής είναι τύπου float;
+ // αλλιώς τυγχαίνει μεταχείρισης όπως μία τιμή μεταβλητής double.
+
+ // Double - Double-precision 64-bit IEEE 754 Floating Point
+ // 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // Boolean - Αληθής και Ψευδής (true & false)
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - Ένας μόνο χαρακτήρας 16-bit Unicode
+ char fooChar = 'A';
+
+ // Οι μεταβλητές final δεν μπορούν να πάρουν άλλη τιμή
+ // μετά την αρχικοποίηση τους,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // αλλά μπορούν να αρχικοποιηθούν αργότερα.
+ final double E;
+ E = 2.71828;
+
+
+ // BigInteger - Immutable αυθαίρετης-ακρίβειας ακέραιος
+ //
+ // Ο BigInteger είναι ένας τύπος δεδομένων ο οποίος επιτρέπει στους
+ // προγραμματιστές να χειρίζονται ακέραιους μεγαλύτερους από 64-bits.
+ // Οι ακέραιοι αποθηκεύονται ως πίνακας από bytes και τυχαίνουν
+ // επεξεργασίας χρησιμοποιώντας συναρτήσεις εσωματωμένες στην κλάση
+ // BigInteger
+ // Ένας BigInteger μπορεί να αρχικοποιηθεί χρησιμοποιώντας ένα πίνακα
+ // από bytes ή γραμματοσειρά (string).
+
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+
+ // BigDecimal - Immutable, αυθαίρετης-ακρίβειας, εμπρόσημος (signed)
+ // δεκαδικός αριθμός
+ //
+ // Ένας BigDecimal παίρνει δύο μέρη: Μία αυθαίρετης ακρίβειας,
+ // ακέραια, unscaled τιμή και μία κλιμάκωση(scale) ως ένα 32-bit
+ // ακέραιο (integer).
+ //
+ // Ο BigDecimal επιτρέπει στον προγραμματιστή να έχει πλήρη έλεγχο
+ // όσον αφορά τη δεκαδική στρογγυλοποίηση (rounding). Προτείνεται η
+ // χρήση του BigDecimal με τιμές νομισμάτων και όπου απαιτείται η
+ // ακριβής δεκαδική ακρίβεια.
+ //
+ // Ο BigDecimal μπορεί να αρχικοποιηθεί με int, long, double ή String
+ // ή με την αρχικοποίηση της unscaled τιμής (BigInteger) και της
+ // κλίμακας (scale) (int).
+
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Χρειάζεται να είμαστε προσεκτικοί με τον κατασκευαστή (constructor)
+ // ο οποίος παίρνει float ή double καθώς η ανακρίβεια του float/double
+ // θα αντιγραφεί στον BigDecimal.
+ // Είναι προτιμότερο να χρησιμοποιείται ο κατασκευαστής String (String
+ // constructor) όταν χρειάζεται ακριβής τιμή.
+
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // Strings - Γραμματοσειρές
+ String fooString = "My String Is Here!";
+
+ // Ο χαρακτήρας \n είναι ένας χαρακτήρας διαφυγής (escaped character)
+ // ο οποίος ξεκινά μία νέα γραμμή
+ String barString = "Printing on a new line?\nNo Problem!";
+ // Ο χαρακτήρας \t είναι ένας χαρακτήρας διαφυγής (escaped character)
+ // ο οποίος προσθέτει ένα χαρακτήρα tab
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Πίνακες (Arrays)
+ // Το μέγεθος του πίνακα πρέπει να αποφασιστεί με την αρχικοποίηση του
+ // πίνακα
+ // Οι ακόλουθες μορφές μπορούν να χρησιμοποιηθούν για την δήλωση ενός
+ // πίνακα
+ // <Τυπος δεδομένων>[] <Όνομα Μεταβλητής> = new <Τύπος Δεδομένων>[<μέγεθος πίνακα>];
+ // <Τυπος δεδομένων> <Όνομα Μεταβλητής>[] = new <Τυπος δεδομένων>[<μέγεθος πίνακα>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Ακόμη ένας τρόπος για να δηλώσεις (to declare) και να
+ // αρχικοποιήσεις ένα πίνακα
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = new boolean[] {true, false, false};
+
+ // Ευρετηρίαση (indexing) ενός πίνακα - Πρόσβαση (accessing) ενός
+ // στοιχείου
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Οι πίνακες ξεκινούν από το μηδέν (zero-indexed) και είναι ευμετάβλητοι (mutable).
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Παρόμοια
+ // ArrayLists - Παρόμοιοι με τους πίνακες με τη διαφορά ότι προσφέρουν
+ // περισσότερη λειτουργικότητα και το μέγεθος είναι ευμετάβλητο
+ // (mutable).
+ // LinkedLists - Υλοποίηση διπλά-συνδεδεμένης λίστας(doubly-linked
+ // list). Όλες οι λειτουργίες εκτελώνται όπως αναμένεται σε μία διπλά
+ // συνδεδεμένη (doubly-linked) λίστα.
+ // Maps - Ένα σύνολο αντικειμένων τα οποία συνδέου (map) κλειδιά (keys)
+ // σε τιμές (values). Ο Map είναι διεπαφή (interface) και συνεπώς δεν
+ // μπορεί να συγκεκριμενοποίηθεί (instantiated).
+ // Ο τύπος των κλειδιών και των τιμών τα οποία συμπεριλαμβάνονται σε
+ // ένα Map πρέπει να καθοριστεί κατά τη διάρκεια της
+ // συγκεκριμενοποίησης (instantiation) της κλάσης που υλοποιεί τη
+ // διεπαφή Map. Κάθε κλειδί (key) μπορεί να συνδεθεί (map) σε μόνο μία
+ // αντίστοιχη τιμή και κάθε κλειδί μπορεί να εμφανιστεί μόνο μία φορά
+ // (no duplicates).
+ // HashMaps - Η κλάση αυτή χρησιμοποιεί ένα πίνακα-κατακερματισμού
+ // (hashtable) για να υλοποιήσει τη διεπαφή Map. Αυτό επιτρέπει το
+ // χρόνο εκτέλεσης βασικών λειτουργιών, όπως της get και insert
+ // στοιχείου να παραμείνει σταθερός (constant) ακόμη και για μεγάλα
+ // σύνολα (sets.)
+
+
+ ///////////////////////////////////////
+ // Τελεστές (Operators)
+ ///////////////////////////////////////
+ System.out.println("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Συντομογραφία για πολλαπλές δηλώσεις
+
+ // Οι αριθμητικοί τελεστές είναι απλοί
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns int)
+ System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
+
+ // Υπόλοιπο (Modulo)
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Τελεστές σύγκρισης
+ System.out.println("3 == 2? " + (3 == 2)); // => false
+ System.out.println("3 != 2? " + (3 != 2)); // => true
+ System.out.println("3 > 2? " + (3 > 2)); // => true
+ System.out.println("3 < 2? " + (3 < 2)); // => false
+ System.out.println("2 <= 2? " + (2 <= 2)); // => true
+ System.out.println("2 >= 2? " + (2 >= 2)); // => true
+
+ // Λογικοί Τελεστές (Boolean)
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Τελεστές πράξεων με bits (Bitwise)!
+ /*
+ ~ bitwise τελεστής μοναδιαίου συμπληρώματος (Unary bitwise complement)
+ << Προσημασμένη ολίσθηση αριστερά (Signed left shift)
+ >> Προσημασμένη/Αριθμητική ολίσθηση Δεξιά (Signed/Arithmetic right shift)
+ >>> Μη προσημασμένη/Λογική ολίσθηση δεξιά (Unsigned/Logical right shift)
+ & Διαδικός τελεστής AND (Bitwise AND)
+ ^ Διαδικός τελεστής XOR (Bitwise exclusive OR)
+ | Διαδικός τελεστής OR (Bitwise inclusive OR)
+ */
+
+ // Αυξητικοί τελεστές
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ // Οι τελεστές ++ και -- μειώνουν και αυξάνουν κατά 1 αντίστοιχα.
+ // Εάν τοποθετητούν πριν τη μεταβλητή, αυξάνουν και μετά επιστρέφουν.
+ // Μετά τη μεταβλητή επιστρέφουν και μετά αυξάνουν.
+ System.out.println(i++); // i = 1, τυπώνει 0 (post-increment)
+ System.out.println(++i); // i = 2, τυπώνει 2 (pre-increment)
+ System.out.println(i--); // i = 1, τυπώνει 2 (post-decrement)
+ System.out.println(--i); // i = 0, τυπώνει 0 (pre-decrement)
+
+ ///////////////////////////////////////
+ // Δομές ελέγχου (Control Structures)
+ ///////////////////////////////////////
+ System.out.println("\n->Control Structures");
+
+ // Οι δηλώσεις If είναι c-like
+ int j = 10;
+ if (j == 10) {
+ System.out.println("I get printed");
+ } else if (j > 10) {
+ System.out.println("I don't");
+ } else {
+ System.out.println("I also don't");
+ }
+
+ // Επανάληψη While (While loop)
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Άυξησε τον μετρητή
+ // Επανάλαβε 100 φορές, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("fooWhile Value: " + fooWhile);
+
+ // Επανάληψη Do While (Do While Loop)
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Άυξησε το μετρητή(counter)
+ // Επανάλαβε 99 times, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("fooDoWhile Value: " + fooDoWhile);
+
+ // Επανάληψη For (For Loop)
+ // Δομή επανάληψης for =>
+ // for(<Αρχική Δήλωση>; <προυπόθεση (conditional)>; <βήμα (step)>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Iterated 10 times, fooFor 0->9
+ }
+ System.out.println("fooFor Value: " + fooFor);
+
+ // Έξοδος από εμφωλευμένη (nested) επανάληψη For με ετικέττα (Label)
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // δραπετεύει εκτός της εξωτερικής(outer) επανάληψης αντί μόνο της εσωτερικής
+ }
+ }
+ }
+
+ // Επανάληψη For Each
+ // Η επανάληψη for είναι επίσης ικανή να επαναλαμβάνεται τόσο σε
+ // πίνακες όσο και σε αντικείμενα τα οποία υλοποιούν τη διεπαφή
+ // Iterable.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // Σύνταξη της επανάληψης for each => for (<αντικείμενο> : <iterable>)
+ // Διαβάζεται ως: Για κάθε αντικείμενο στο iterable
+ // Σημείωση: ο τύπος του αντικειμένου πρέπει να τεριάζει με τον τύπο του στοιχείου του iterable.
+
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Επαναλαμβάνεται 9 φορές και τυπώνει 1-9 σε καινούριες γραμμές
+ }
+
+ // Switch Case
+ // Ένα switch δουλέυει με byte, short, char, και int τύπους δεδομένων.
+ // Δουλέυει επίσης με τύπους enumerated (Συζήτηση στους τύπους Enum),
+ // τη κλάση String, και μερικές ειδικές περιπτώσεις οι οποίες
+ // περιλαμβάνουν primitive τύπους: Character, Byte, Short, and Integer.
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "January";
+ break;
+ case 2: monthString = "February";
+ break;
+ case 3: monthString = "March";
+ break;
+ default: monthString = "Some other month";
+ break;
+ }
+ System.out.println("Switch Case Result: " + monthString);
+
+ // Αρχίζοντας από τη Java 7, switching για Strings δουλεύει έτσι:
+ String myAnswer = "maybe";
+ switch(myAnswer) {
+ case "yes":
+ System.out.println("You answered yes.");
+ break;
+ case "no":
+ System.out.println("You answered no.");
+ break;
+ case "maybe":
+ System.out.println("You answered maybe.");
+ break;
+ default:
+ System.out.println("You answered " + myAnswer);
+ break;
+ }
+
+ // Συντομογραφία του Conditional
+ // Μπορείς να χρησιμοποιήσεις τον τελεστή '?' για γρήγορες αναθέσεις ή
+ // logic forks. Διαβάζεται ως "Αν η (πρόταση) είναι αληθής,
+ // χρησιμοποίησε <την πρώτη τιμή>, αλλιώς, χρησιμοποία <την δεύτερη
+ // τιμή>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println(bar); // Prints A, because the statement is true
+
+
+ ////////////////////////////////////////
+ // Μετατροπή Τύπων Δεδομένων και Typecasting
+ ////////////////////////////////////////
+
+ // Μετατροπή δεδομένων
+
+ // Μετατροπή από String σε Integer
+ Integer.parseInt("123");//returns an integer version of "123"
+
+ // Μετατροπή από Integer σε String
+ Integer.toString(123);//returns a string version of 123
+
+ // Για άλλες μετατροπές δες τις ακόλουθες κλάσεις:
+ // Double
+ // Long
+ // String
+
+ // Typecasting
+ // Μπορείς επίσης να κάνεις cast αντικείμενα Java. Υπάρχουν πολλές
+ // λεπτομέρειες και μερικές πραγματεύονται κάποιες πιο προχωρημένες
+ // ένοιες. Για δες εδώ:
+ // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+
+ ///////////////////////////////////////
+ // Κλάσεις και Συναρτήσεις
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes & Functions");
+
+ // (Ο ορισμός της κλάσης Bicycle ακολουθεί)
+
+ // Χρησιμοποία το new για να δημιουργήσεις ένα αντικείμενο μίας κλάσης
+ Bicycle trek = new Bicycle();
+
+ // Κλήση μεθόδων του αντικειμένου
+ trek.speedUp(3); // Πάντοτε πρέπει να χρησιμοποιείς μεθόδους setter
+ // και getter
+ trek.setCadence(100);
+
+ // Το toString επιστρέφει την αναπαράσταση σε String μορφή του
+ // αντικειμένου αυτού.
+ System.out.println("trek info: " + trek.toString());
+
+ // Double Brace Initialization
+ // Η Γλώσσα Java δεν έχει σύνταξη για το πως να δημιουργήσεις static
+ // Collections με κάποιο εύκολο τρόπο. Συνήθως θα το κάνεις αυτό με
+ // τον παρακάτω τρόπο:
+
+ private static final Set<String> COUNTRIES = new HashSet<String>();
+ static {
+ validCodes.add("DENMARK");
+ validCodes.add("SWEDEN");
+ validCodes.add("FINLAND");
+ }
+
+ // Αλλά υπάρχει ένας κομψός τρόπος να επιτύχεις το ίδιο πράγμα
+ // ευκολότερα, χρησιμοποιώντας κάτι το οποίο λέγεται Double Brace
+ // Initialization.
+
+ private static final Set<String> COUNTRIES = new HashSet<String>() {{
+ add("DENMARK");
+ add("SWEDEN");
+ add("FINLAND");
+ }}
+
+ // Η πρώτη αγκύλη δημιουργεί μία νέα AnonymousInnerClass και η
+ // δεύτερη δηλώνει ένα instance initializer block. Το block
+ // καλείται όταν η ανώνυμη εσωτερική κλάση δημιουργηθεί.
+ // Η μέθοδος αύτή δεν δουλεύει μόνο για τις Collections, αλλά για όλες
+ // τις non-final κλάσεις.
+
+ } // Τέλος μεθόδου main
+} // Τέλος κλάσης LearnJava
+
+
+// Μπορείς να κάνεις include άλλες, όχι-δημόσιες (non-public)
+// εξωτερικού-επιπέδου (outer-level) κλάσεις σε ένα αρχείο .java, αλλά δεν
+// είναι καλή πρακτική. Αντί αυτού, διαχώρησε τις κλάσεις σε ξεχωριστά αρχεία.
+
+// Σύνταξη Δήλωσης Κλάσης (Class Declaration Syntax):
+// <public/private/protected> class <class name> {
+// // Συμπεριλαμβάνονται πεδία δεδομένων (data fields), κατασκευαστές (constructors), συναρτήσεις (functions) .
+// // Οι συναρτήσεις ονομάζονται "μεθόδοι" στη Java.
+// }
+
+class Bicycle {
+
+ // Πεδία/μεταβλητές της Κλάσης Bicycle
+ // Public(Δημόσιες): Μπορούν να γίνουν προσβάσιμες από παντού
+ public int cadence;
+ // Private(Ιδιωτικές): Προσβάσιμες μόνο εντός της κλάσης
+ private int speed;
+ // Protected(Προστατευμένες): Προσβάσιμες από την κλάση και τις υποκλάσεις (subclasses) της
+ protected int gear;
+ String name; // Προκαθορισμένο: Προσβάσιμη μόνο εντός του πακέτου
+
+ static String className; // Static μεταβλητή κλάσης
+
+ // Static block
+ // H Java δεν υποστηρίζει υλοποίησεις στατικών κατασκευαστών (static
+ // constructors), αλλά έχει ένα static block το οποίο μπορεί να
+ // χρησιμοποιηθεί για να αρχικοποιήσει στατικές μεταβλητές (static
+ // variables). Το block αυτό θα καλεσθεί όταν η κλάση φορτωθεί.
+ static {
+ className = "Bicycle";
+ }
+
+ // Οι κατασκευαστές (constructors) είναι ένας τρόπος για δημιουργία κλάσεων
+ // Αυτός είναι ένας κατασκευαστής (constructor)
+ public Bicycle() {
+ // Μπορείς επίσης να καλέσεις άλλο κατασκευαστή:
+ // this(1, 50, 5, "Bontrager");
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+
+ // Αυτός είναι ένας κατασκευαστής ο οποίος δέχεται arguments
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // Οι μεθόδοι (Methods) συντάσσονται ως ακολούθως:
+ // <public/private/protected> <return type> <όνομα μεθόδου>(<args>)
+
+ // Οι κλάσεις Java συχνά υλοποιούν getters and setters for their fields
+
+ // Σύνταξη δήλωσης μεθόδου:
+ // <Προσδιοριστές πρόσβασης> <τύπος επιστροφής> <όνομα μεθόδου>(<args>)
+ public int getCadence() {
+ return cadence;
+ }
+
+ // Οι μεθόδοι void δεν απαιτούν return statement
+ public void setCadence(int newValue) {
+ cadence = newValue;
+ }
+
+ public void setGear(int newValue) {
+ gear = newValue;
+ }
+
+ public void speedUp(int increment) {
+ speed += increment;
+ }
+
+ public void slowDown(int decrement) {
+ speed -= decrement;
+ }
+
+ public void setName(String newName) {
+ name = newName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ //Μέθοδος η οποία επιστρέφει ως String τις τιμές των χαρακτηριστικών του
+ // αντικειμένου.
+ @Override // Χρησιμοποιείται, καθώς η συγκεκριμένη μέθοδος κληρονομήθηκε από τη κλάση Object.
+ public String toString() {
+ return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
+ " name: " + name;
+ }
+} // Τέλος κλάσης Bicycle
+
+// Η PennyFarthing είναι υποκλάση της Bicycle
+class PennyFarthing extends Bicycle {
+ // (Tα Penny Farthings είναι τα ποδήλατα με τον μεγάλο μπροστινό τροχό.
+ // Δεν έχουν ταχύτητες.)
+
+ public PennyFarthing(int startCadence, int startSpeed) {
+ // Κάλεσε τον parent constructor χρησιμοποιώντας το super
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // Χρειάζεται να μαρκάρεις τη μέθοδο την οποία κάνεις overriding
+ // χρησιμοποιώντας ένα @annotation.
+ // Για να μάθεις περισσότερα σχετικά με το τι είναι οι επισημάνσεις
+ // (annotations) και τον σκοπό τους δες αυτό:
+ // http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ gear = 0;
+ }
+}
+
+// Διεπαφές (Interfaces)
+// Σύνταξη δήλωσης διεπαφής
+// <access-level> interface <interface-name> extends <super-interfaces> {
+// // Σταθερές (Constants)
+// // Δηλώσεις Μεθόδων (Method declarations)
+// }
+
+// Παράδειγμα - Food:
+public interface Edible {
+ public void eat(); // Κάθε κλάση η οποία υλοποιεί τη διεπαφή αυτή πρέπει
+ // να υλοποιήσει τη συγκεκριμένη μέθοδο.
+}
+
+public interface Digestible {
+ public void digest();
+}
+
+
+// Μπορούμε να δημιουργήσουμε μία κλάση η οποία υλοποιεί και τις δύο αυτές διεπαφές.
+public class Fruit implements Edible, Digestible {
+
+ @Override
+ public void eat() {
+ // ...
+ }
+
+ @Override
+ public void digest() {
+ // ...
+ }
+}
+
+// Στην Java, μπορείς να κληρονομήσεις (extend) από μόνο μία κλάση,
+// αλλά μπορείς να υλοποιήσεις πολλές διεπαφές. Για παράδειγμα:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne,
+ InterfaceTwo {
+
+ @Override
+ public void InterfaceOneMethod() {
+ }
+
+ @Override
+ public void InterfaceTwoMethod() {
+ }
+
+}
+
+// Abstract (Αφηρημένες) Κλάσεις
+
+// Σύνταξη Δήλωσης Abstract Κλάσης
+// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
+// // Σταθερές και μεταβλητές
+// // Δηλώσεις μεθόδων
+// }
+
+// Μαρκάροντας μία κλάση ως abstract σημαίνει ότι περιέχει abstract μεθόδους
+// οι οποίες πρέπει να οριστούν σε μία κλάση παιδί (child class).
+// Παρόμοια με τις διεπαφές (interfaces), οι abstract κλάσεις δεν μπορούν να
+// γίνουν instantiated, αλλά αντί αυτού πρέπει να γίνει extend και οι abstract
+// μεθόδοι πρέπει να οριστούν. Διαφορετικά από τις Διεπαφές, οι abstract
+// κλάσεις μπορούν να περιέχουν τόσο υλοποιημένες όσο και abstract μεθόδους.
+// Οι μεθόδοι σε μια Διεπαφή δεν μπορούν να έχουν σώμα (δεν είναι υλοποιημένες
+// δηλαδή εκτός εάν η μέθοδος είναι στατική και οι μεταβλητές είναι final by
+// default αντίθετα απο μία abstract κλάση. Επίσης, οι abstract κλάσεις
+// ΜΠΟΡΟΥΝ να έχουν την μέθοδο "main".
+
+public abstract class Animal
+{
+ public abstract void makeSound();
+
+ // Οι μεθόδοι μπορούν να έχουν σώμα (body)
+ public void eat()
+ {
+ System.out.println("I am an animal and I am Eating.");
+ // Σημείωση: Μπορούμε να έχουμε πρόσβαση σε ιδιωτικές (private) μεταβλητές εδώ.
+ age = 30;
+ }
+
+ // Δεν χρειάζεται να αρχικοποιηθεί, εντούτοις σε ένα interface μία
+ // μεταβλητή είναι implicitly final και έτσι χρειάζεται να αρχικοποιηθεί
+ protected int age;
+
+ public void printAge()
+ {
+ System.out.println(age);
+ }
+
+ // Οι Abstract κλάσεις μπορούν να έχουν συνάρτηση main.
+ public static void main(String[] args)
+ {
+ System.out.println("I am abstract");
+ }
+}
+
+class Dog extends Animal
+{
+ // Σημείωση ότι χρειάζεται να κάνουμε override τις abstract μεθόδους στην
+ // abstract κλάση.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Bark");
+ // age = 30; ==> ERROR! Το πεδίο age είναι private στο Animal
+ }
+
+ // ΣΗΜΕΙΩΣΗ: Θα πάρεις error εάν χρησιμοποίησεις το
+ // @Override annotation εδώ, καθώς η java δεν επιτρέπει
+ // να γίνονται override οι static μεθόδοι.
+ // Αυτό που γίνεται εδώ ονομάζεται METHOD HIDING.
+ // Για δες αυτό το εξαιρετικό ποστ στο SO (Stack Overflow): http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Dog pluto = new Dog();
+ pluto.makeSound();
+ pluto.eat();
+ pluto.printAge();
+ }
+}
+
+// Κλάσεις Final
+
+// Σύνταξη δήλωσης μίας Final κλάσης
+// <access-level> final <final-class-name> {
+// // Σταθερές και μεταβλητές
+// // Δήλωση μεθόδων
+// }
+
+// Οι κλάσεις Final είναι κλάσεις οι οποίες δεν μπορούν να κληρονομηθούν και
+// συνεπώς είναι final child. In a way, final classes are the opposite of
+// abstract classes because abstract classes must be extended, but final
+// classes cannot be extended.
+public final class SaberToothedCat extends Animal
+{
+ // Σημείωση ότι χρειάζεται και πάλι να κάνουμε override τις abstract
+ // μεθόδους στην abstract κλάση.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Τελικές (Final) μεθόδοι
+public abstract class Mammal()
+{
+ // Σύνταξη μίας Final μεθόδου:
+ // <Προσδιοριστής πρόσβασης (access modifier)> final <τύπος επιστροφής> <Όνομα μεθόδου>(<args>)
+
+ // Οι Final μεθόδοι, όπως και οι final κλάσεις δεν μπορούν να γίνουν
+ // overridden από κλάση παιδί,
+ // και είναι συνεπώς η τελική υλοποίηση της μεθόδου.
+ public final boolean isWarmBlooded()
+ {
+ return true;
+ }
+}
+
+
+// Τύποι Enum
+//
+// Ένας τύπος enum είναι ένας ειδικός τύπος δεδομένων, ο οποίος επιτρέπει σε
+// μια μεταβλητή να είναι ένα σύνολο από προκαθορισμένες σταθερές. Η μεταβλητή
+// πρέπει να είναι ίση με μία από τις τιμές αυτές που έχουν προκαθοριστεί.
+// Επειδή είναι σταθερές, τα ονόματα ενός enum πεδίου γράφονται με κεφαλαίους
+// χαρακτήρες. Στην γλώσσα προγραμματισμού Java, ορίζεις ένα τύπο enum
+// χρησιμοποιώντας τη δεσμευμένη λέξη enum. Για παράδειγμα, θα μπορούσες να
+// καθορίσεις ένα τύπο enum με όνομα days-of-the-week ως:
+
+public enum Day {
+ SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
+ THURSDAY, FRIDAY, SATURDAY
+}
+
+// Μπορούμε να χρησιμοποιήσουμε τον enum Day όπως παρακάτω:
+
+public class EnumTest {
+
+ // Μεταβλητή Enum
+ Day day;
+
+ public EnumTest(Day day) {
+ this.day = day;
+ }
+
+ public void tellItLikeItIs() {
+ switch (day) {
+ case MONDAY:
+ System.out.println("Mondays are bad.");
+ break;
+
+ case FRIDAY:
+ System.out.println("Fridays are better.");
+ break;
+
+ case SATURDAY:
+ case SUNDAY:
+ System.out.println("Weekends are best.");
+ break;
+
+ default:
+ System.out.println("Midweek days are so-so.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest firstDay = new EnumTest(Day.MONDAY);
+ firstDay.tellItLikeItIs(); // => Mondays are bad.
+ EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
+ thirdDay.tellItLikeItIs(); // => Midweek days are so-so.
+ }
+}
+
+// Οι τύποι Enum είναι πολύ πιο δυνατοί από όσο έχουμε δείξει πιο πάνω.
+// Το σώμα του enum (enum body) μπορεί να περιέχει μεθόδους και άλλα πεδία.
+// Μπορείς να δεις περισσότερα στο
+// https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+```
+
+## Επιπλέων διάβασμα
+
+Οι σύνδεσμοι που παρέχονται εδώ είναι απλά για να κατανοήσεις περισσότερο το θέμα.
+Σε προτρύνουμε να ψάξεις στο Google και να βρεις συγκεκριμένα παραδείγματα.
+
+**Eπίσημοι Οδηγοί της Oracle**:
+
+* [Φροντιστήριο εκμάθησης Java από τη Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
+
+* [Τροποποιητές επιπέδου πρόσβασης(Access level modifiers) Java](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Έννοιες αντικειμενοστραφούς (Object-Oriented) προγραμματισμού](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Κληρονομικότητα (Inheritance)](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Πολυμορφισμός (Polymorphism)](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Αφαιρετικότητα (Abstraction)](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Εξαιρέσεις (Exceptions)](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Διεπαφές (Interfaces)](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Συμβάσεις κώδικα Java (Code Conventions)](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+**Πρακτικές και Φροντιστήρια Online**
+
+* [Learneroo.com - Μάθε Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+
+**Βιβλία**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300)
diff --git a/el-gr/racket-gr.html.markdown b/el-gr/racket-gr.html.markdown
new file mode 100644
index 00000000..589adfeb
--- /dev/null
+++ b/el-gr/racket-gr.html.markdown
@@ -0,0 +1,745 @@
+---
+language: racket
+filename: learnracket-gr.rkt
+contributors:
+ - ["th3rac25", "https://github.com/voila"]
+ - ["Eli Barzilay", "https://github.com/elibarzilay"]
+ - ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
+ - ["Duong H. Nguyen", "https://github.com/cmpitg"]
+ - ["Keyan Zhang", "https://github.com/keyanzhang"]
+translators:
+ - ["Vasilis Panagiotopoulos" , "https://github.com/billpcs/"]
+lang: el-gr
+---
+
+H Racket είναι μια γενικού σκοπού, πολυ-υποδειγματική γλώσσα προγραμματισμού που ανήκει
+στην οικογένεια της Lisp/Scheme
+
+```racket
+#lang racket ; ορίζει την γλώσσα που χρησιμοποιόυμε
+
+;;; Σχόλια
+
+;; Τα σχόλια μιας γραμμής ξεκινούν με ερωτηματικό
+
+#| Τα σχόλια ολόκληρου μπλόκ
+ μπορούν να εκτείνονται σε πολλές γραμμές και...
+ #|
+ μπορούν να είναι εμφωλευμένα!
+ |#
+|#
+
+;; Τα σχόλια S-expression (εκφράσεις S) comments απορρίπτουν την
+;; έκφραση που ακολουθεί, δυνατότητα που είναι χρήσιμη για να
+;; κάνουμε σχόλια κάποιες εκφράσεις κατά τη διάρκεια του debugging
+
+#; (αυτή η έκφραση δεν θα εκτελεστεί)
+
+;; (Αν δεν καταλαβαίνεται τι είναι οι εκφράσεις , περιμένετε... Θα το μάθουμε
+;; πολύ σύντομα!)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. Πρωτογενείς τύποι μεταβλητών και τελεστές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Αριθμοί
+9999999999999999999999 ; ακέραιοι
+#b111 ; δυαδικοί => 7
+#o111 ; οκταδικοί => 73
+#x111 ; δεκαεξαδικοί => 273
+3.14 ; πραγματικοί
+6.02e+23
+1/2 ; ρητοί
+1+2i ; μιγαδικοί
+
+;; Οι μορφή των συναρτήσεων είναι (f x y z)
+;; όπου το f είναι η συνάρτηση και τα x y z
+;; είναι οι όροι που η συνάρτηση δέχεται
+;; ως ορίσματα. Αν θέλουμε να δημιουργήσουμε
+;; μια λίστα στην κυριολεξία από δίαφορα δεδομένα,
+;; χρησιμοποιούμε το ' για να το εμποδίσουμε από το να
+;; αξιολογηθεί σαν έκφραση. Για παράδειγμα:
+'(+ 1 2) ; => Παραμένει (+ 1 2) και δεν γίνεται η πράξη
+;; Τώρα , ας κάνουμε μερικές πράξεις
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(quotient 5 2) ; => 2
+(remainder 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(exact->inexact 1/3) ; => 0.3333333333333333
+(+ 1+2i 2-3i) ; => 3-1i
+
+;;; Λογικές μεταβλητές
+#t ; για το true (αληθής)
+#f ; για το false (ψευδής)
+(not #t) ; => #f
+(and 0 #f (error "doesn't get here")) ; => #f
+(or #f 0 (error "doesn't get here")) ; => 0
+
+;;; Χαρακτήρες
+#\A ; => #\A
+#\λ ; => #\λ
+#\u03BB ; => #\λ
+
+;;; Τα αλφαριθμητικά είναι πίνακες χαρακτήρων συγκεκριμένου μήκους
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; Το backslash είναι χαρακτήρας διαφυγής
+"Foo\tbar\41\x21\u0021\a\r\n" ; Συμπεριλαμβάνονται οι χαρακτήρες διαφυγής της C,
+ ; σε Unicode
+"λx:(μα.α→α).xx" ; Μπορούν να υπάρχουν και Unicode χαρακτήρες
+
+;; Μπορούμε να ενώσουμε αλφαριθμητικά!
+(string-append "Hello " "world!") ; => "Hello world!"
+
+;; Ένα αλφαριθμητικό μπορούμε να το χρησιμοποιήσουμε
+;; όπως και μια λίστα από χαρακτήρες
+(string-ref "Apple" 0) ; => #\A ;; Παίρνουμε το πρώτο στοιχείο
+
+;; Η συνάρτηση format μπορεί να χρησιμοποιηθεί για
+;; να μορφοποιήσουμε αλφαριθμητικά
+(format "~a can be ~a" "strings" "formatted") ;; => "strings can be formatted"
+
+;; Η εκτύπωση είναι εύκολη.
+(printf "I'm Racket. Nice to meet you!\n")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Μεταβλητές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Μπορούμε να δημιουργήσουμε μεταβλητές
+;; χρησιμοποιώντας το define.
+;; Ένα όνομα μεταβλητής μπορεί να χρησιμοποιεί οποιονδήποτε
+;; χαρακτήρα, εκτός από τους: ()[]{}",'`;#|\
+(define some-var 5)
+some-var ; => 5
+
+;; Μπορούμε επίσης να χρησιμοποιήσουμε unicode χαρακτήρες.
+(define ⊆ subset?) ;; Εδώ ουσιαστικά δίνουμε στη ήδη υπάρχουσα συνάρτηση subset?
+ ;; ένα νέο όνομα ⊆ , και παρακάτω την καλούμε με το νέο της όνομα.
+(⊆ (set 3 2) (set 1 2 3)) ; => #t
+
+;; Αν ζητήσουμε μια μεταβλητή που δεν έχει οριστεί πριν π.χ.
+(printf name)
+;; θα πάρουμε το παρακάτω μήνυμα
+;name: undefined;
+; cannot reference undefined identifier
+; context...:
+
+;; Η τοπική δέσμευση : `me' δεσμεύεται με το "Bob" μόνο μέσα στο (let ...)
+(let ([me "Bob"])
+ "Alice"
+ me) ; => "Bob"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Δομές και συλλογές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Δομές
+(struct dog (name breed age))
+(define my-pet
+ (dog "lassie" "collie" 5))
+my-pet ; => #<dog>
+(dog? my-pet) ; => #t
+(dog-name my-pet) ; => "lassie"
+
+;;; Ζεύγη (αμετάβλητα)
+;; Η δεσμευμένη λέξη `cons' δημιουργεί ζεύγη,
+;; και το `car' και το `cdr' εξάγουν το πρώτο και
+;; το δεύτερο στοιχείο αντίστοιχα.
+(cons 1 2) ; => '(1 . 2)
+(car (cons 1 2)) ; => 1
+(cdr (cons 1 2)) ; => 2
+
+;;; Λίστες
+
+;; Οι λίστες είναι linked-list δομές δεδομένων,
+;; που έχουν δημιουργηθεί από ζευγάρια 'cons'
+;; και τελειώνουν με 'null' (ή αλλιώς '()) για να
+;; δηλώσουν ότι αυτό είναι το τέλος της λίστας
+(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
+;; Η δεσμευμένη λέξη 'list' είναι ένας εναλλακτικός
+;; (και σαφώς πιο βολικός) τρόπος για να δημιουργούμε
+;; λίστες
+(list 1 2 3) ; => '(1 2 3)
+;; αλλά και χρησιμοποιώντας ένα μονό εισαγωγικό το
+;; το αποτέλεσμα είναι και πάλι το ίδιο
+'(1 2 3) ; => '(1 2 3)
+
+;; Μπορούμε και πάλι όμως να χρησιμοποιούμε το 'cons' για να
+;; προσθέσουμε ένα στοιχείο στην αρχή της λίστας
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; Μπορούμε να χρησιμοποιούμε το 'append' για να προσθέτουμε
+;; στοιχεία στο τέλος μιας λίστας. Το στοιχείο αυτό μπορεί
+;; και να είναι ολόκληρη λίστα!
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; Οι λίστες στην Racket είναι πολύ βασικές , οπότε υπάρχουν πολλές
+;; δυνατές λειτουργίες για αυτές. Παρακάτω είναι μερικά παραδείγματα:
+(map add1 '(1 2 3)) ; => '(2 3 4)
+(map + '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(filter even? '(1 2 3 4)) ; => '(2 4)
+(count even? '(1 2 3 4)) ; => 2
+(take '(1 2 3 4) 2) ; => '(1 2)
+(drop '(1 2 3 4) 2) ; => '(3 4)
+
+;;; Διανύσματα
+
+;; Τα διανύσματα είναι πίνακες σταθερού μήκους
+#(1 2 3) ; => '#(1 2 3)
+
+;; Χρησιμοποιούμε το `vector-append' για να προσθέσουμε διανύσματα
+(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; Σύνολα
+
+;; Δημιουργούμε ένα σύνολο από μία λίστα
+(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
+
+;; Προσθέτουμε έναν αριθμό στο σύνολο χρησιμοποιώντας το `set-add'
+(set-add (set 1 2 3) 4) ; => (set 1 2 3 4)
+
+;; Αφαιρούμε με το `set-remove'
+(set-remove (set 1 2 3) 1) ; => (set 2 3)
+
+;; Βλέπουμε αν υπάρχει ένας αριθμός στο σύνολο με το `set-member?'
+(set-member? (set 1 2 3) 1) ; => #t
+(set-member? (set 1 2 3) 4) ; => #f
+
+;;; Πίνακες κατακερματισμού (Hashes)
+
+;; Δημιουργήστε ένα αμετάβλητο πίνακα κατακερματισμού
+(define m (hash 'a 1 'b 2 'c 3))
+
+;; Παίρνουμε μια τιμή από τον πίνακα
+(hash-ref m 'a) ; => 1
+
+;; Αν ζητήσουμε μια τιμή που δεν υπάρχει παίρνουμε μία εξαίρεση
+; (hash-ref m 'd) => no value found for key
+
+;; Μπορούμε να δώσουμε μια default τιμή για τα κλειδιά που λείπουν
+(hash-ref m 'd 0) ; => 0
+
+
+;; Χρησιμοποιούμε το 'hash-set' για να επεκτείνουμε
+;; ένα πίνακα κατακερματισμού
+(define m2 (hash-set m 'd 4))
+m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
+
+;; Θυμηθείτε ! Αυτοί οι πίνακες κατακερματισμού
+;; είναι αμετάβλητοι!
+m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
+
+;; Χρησιμοποιούμε το `hash-remove' για να αφαιρέσουμε
+;; κλειδιά
+(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Συναρτήσεις
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Χρησιμοποιούμε το `lambda' για να δημιουργήσουμε συναρτήσεις.
+;; Μια συνάρτηση πάντα επιστρέφει την τιμή της τελευταίας της έκφρασης
+(lambda () "Hello World") ; => #<procedure>
+;; Μπορούμε επίσης να χρησιμοποιήσουμε το `λ'
+(λ () "Hello World") ; => Ίδια συνάρτηση
+
+;; Χρησιμοποιούμε τις παρενθέσεις για να καλέσουμε όλες τις συναρτήσεις
+;; συμπεριλαμβανομένων και των εκφράσεων 'λάμδα'
+((lambda () "Hello World")) ; => "Hello World"
+((λ () "Hello World")) ; => "Hello World"
+
+;; Εκχωρούμε σε μια μεταβλητή την συνάρτηση
+(define hello-world (lambda () "Hello World"))
+(hello-world) ; => "Hello World"
+
+;; Μπορούμε αυτό να το κάνουμε συντομότερο χρησιμοποιώντας
+;; το λεγόμενο syntactic sugar :
+(define (hello-world2) "Hello World")
+
+;; Το () στο παραπάνω είναι η λίστα από τα ορίσματα για την συνάρτηση
+
+(define hello
+ (lambda (name)
+ (string-append "Hello " name)))
+(hello "Steve") ; => "Hello Steve"
+;; ... ή ισοδύναμα, χρησιμοποιώντας sugared ορισμό:
+(define (hello2 name)
+ (string-append "Hello " name))
+
+;; Μπορούμε να έχουμε συναρτήσεις με πολλές μεταβλητές χρησιμοποιώντας
+;; το `case-lambda'
+(define hello3
+ (case-lambda
+ [() "Hello World"]
+ [(name) (string-append "Hello " name)]))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+;; ... ή να ορίσουμε προαιρετικά ορίσματα με μια έκφραση προκαθορισμένης τιμής
+(define (hello4 [name "World"])
+ (string-append "Hello " name))
+
+;; Οι συναρτήσεις μπορούν να πακετάρουν επιπλέον
+;; ορίσματα μέσα σε μια λίστα
+(define (count-args . args)
+ (format "You passed ~a args: ~a" (length args) args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+;; ... ή με unsugared μορφή `lambda':
+(define count-args2
+ (lambda args
+ (format "You passed ~a args: ~a" (length args) args)))
+
+;; Μπορούμε να εμπλέξουμε κανονικά και πακεταρισμένα ορίσματα
+(define (hello-count name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args)))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+;; ... και unsugared:
+(define hello-count2
+ (lambda (name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args))))
+
+;; Και με λέξεις κλειδιά
+(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
+ (format "~a ~a, ~a extra args" g name (length args)))
+(hello-k) ; => "Hello World, 0 extra args"
+(hello-k 1 2 3) ; => "Hello World, 3 extra args"
+(hello-k #:greeting "Hi") ; => "Hi World, 0 extra args"
+(hello-k #:name "Finn" #:greeting "Hey") ; => "Hey Finn, 0 extra args"
+(hello-k 1 2 3 #:greeting "Hi" #:name "Finn" 4 5 6)
+ ; => "Hi Finn, 6 extra args"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Ισότητα
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; για αριθμούς χρησιμοποιούμε το `='
+(= 3 3.0) ; => #t
+(= 2 1) ; => #f
+
+;; Το `eq?' επιστρέφει #t αν δύο 2 ορίσματα αναφέρονται στο
+;; ίδιο αντικείμενο (στη μνήμη),αλλιώς επιστρέφει #f.
+;; Με άλλα λόγια, είναι απλή σύγκριση δεικτών.
+(eq? '() '()) ; => #t, αφού υπάρχει μόνο μια άδεια λίστα στη μνήμη
+(let ([x '()] [y '()])
+ (eq? x y)) ; => #t, το ίδιο με πάνω
+
+(eq? (list 3) (list 3)) ; => #f
+(let ([x (list 3)] [y (list 3)])
+ (eq? x y)) ; => #f — δεν είναι η ίδια λίστα στην μνήμη!
+
+(let* ([x (list 3)] [y x])
+ (eq? x y)) ; => #t, Αφού το x και το y τώρα δείχνουν στην ίδια θέση
+
+(eq? 'yes 'yes) ; => #t
+(eq? 'yes 'no) ; => #f
+
+(eq? 3 3) ; => #t — να είστε προσεκτικοί εδώ
+ ; Είναι προτιμότερο να χρησιμοποιείτε `=' για την
+ ; σύγκριση αριθμών.
+(eq? 3 3.0) ; => #f
+
+(eq? (expt 2 100) (expt 2 100)) ; => #f
+(eq? (integer->char 955) (integer->char 955)) ; => #f
+
+(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; Το `eqv?' υποστηρίζει την σύγκριση αριθμών αλλά και χαρακτήρων
+;; Για άλλα ήδη μεταβλητών το `eqv?' και το `eq?' επιστρέφουν το ίδιο.
+(eqv? 3 3.0) ; => #f
+(eqv? (expt 2 100) (expt 2 100)) ; => #t
+(eqv? (integer->char 955) (integer->char 955)) ; => #t
+
+(eqv? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; Το `equal?' υποστηρίζει την σύγκριση των παρακάτω τύπων μεταβλητών:
+;; αλφαριθμητικά, αλφαριθμητικά από bytes, μεταβλητά ζεύγη , διανύσματα,
+;; πίνακες κατακερματισμού και δομές.
+;; Για άλλα ήδη τύπων μεταβλητών το `equal?' και το `eqv?' επιστρέφουν το
+;; ίδιο αποτέλεσμα.
+(equal? 3 3.0) ; => #f
+(equal? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #t
+(equal? (list 3) (list 3)) ; => #t
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Έλεγχος Ροής
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Συνθήκες (conditionals)
+
+(if #t ; έκφραση ελέγχου
+ "this is true" ; έκφραση then
+ "this is false") ; έκφραση else
+; => "this is true"
+
+
+;; Στα conditionals, όλες οι μη #f τιμές θεωρούνται ως #t
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(Groucho Zeppo)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'yep
+
+;; Οι αλυσίδες `cond' είναι σειρές από ελέγχους για να
+;; επιλεγεί ένα αποτέλεσμα
+(cond [(> 2 2) (error "wrong!")]
+ [(< 2 2) (error "wrong again!")]
+ [else 'ok]) ; => 'ok
+
+;;; Αντιστοίχιση μοτίβων
+
+(define (fizzbuzz? n)
+ (match (list (remainder n 3) (remainder n 5))
+ [(list 0 0) 'fizzbuzz]
+ [(list 0 _) 'fizz]
+ [(list _ 0) 'buzz]
+ [_ #f]))
+
+(fizzbuzz? 15) ; => 'fizzbuzz
+(fizzbuzz? 37) ; => #f
+
+;;; Βρόχοι
+
+;; Οι επαναλήψεις μπορούν να γίνουν μέσω αναδρομής
+(define (loop i)
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i))))
+(loop 5) ; => i=5, i=6, ...
+
+;; Παρομοίως με τη χρήση 'let'
+(let loop ((i 0))
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i)))) ; => i=0, i=1, ...
+
+
+;; Θα δείτε παρακάτω πως να προσθέσουμε μια νέα μορφή επανάληψης
+;; αλλά η Racket έχει ήδη πολύ ευέλικτη μορφή για τους βρόχους
+(for ([i 10])
+ (printf "i=~a\n" i)) ; => i=0, i=1, ...
+(for ([i (in-range 5 10)])
+ (printf "i=~a\n" i)) ; => i=5, i=6, ...
+
+;;;
+;;; Επανάληψη μέσα σε ακολουθίες:
+;; Το `for' επιτρέπει την επανάληψη μέσα σε πολλά
+;; άλλα ήδη από ακολουθίες: Λίστες, διανύσματα,
+;; αλφαριθμητικά, σύνολα κτλ..
+
+(for ([i (in-list '(l i s t))])
+ (displayln i))
+
+(for ([i (in-vector #(v e c t o r))])
+ (displayln i))
+
+(for ([i (in-string "string")])
+ (displayln i))
+
+(for ([i (in-set (set 'x 'y 'z))])
+ (displayln i))
+
+(for ([(k v) (in-hash (hash 'a 1 'b 2 'c 3 ))])
+ (printf "key:~a value:~a\n" k v))
+
+;;; Πιο περίπλοκες επαναλήψεις
+
+;; Παράλληλη σάρωση σε πολλαπλές ακολουθίες
+;; (σταματά στην πιο σύντομη)
+(for ([i 10] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x 1:y 2:z
+
+;; Εμφολευμένοι βρόχοι
+(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z
+
+;; Συνθήκες
+(for ([i 1000]
+ #:when (> i 5)
+ #:unless (odd? i)
+ #:break (> i 10))
+ (printf "i=~a\n" i))
+; => i=6, i=8, i=10
+
+;;; Σάρωση σε λίστες
+;; Παρόμοιο με τους βρόχους 'for', απλά συλλέγουμε τα αποτελέσματα
+
+(for/list ([i '(1 2 3)])
+ (add1 i)) ; => '(2 3 4)
+
+(for/list ([i '(1 2 3)] #:when (even? i))
+ i) ; => '(2)
+
+(for/list ([i 10] [j '(x y z)])
+ (list i j)) ; => '((0 x) (1 y) (2 z))
+
+(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10))
+ i) ; => '(6 8 10)
+
+(for/hash ([i '(1 2 3)])
+ (values i (number->string i)))
+; => '#hash((1 . "1") (2 . "2") (3 . "3"))
+
+;; Υπάρχουν πολλά είδη από προϋπάρχοντες τρόπους για να συλλέγουμε
+;; τιμές από τους βρόχους
+
+(for/sum ([i 10]) (* i i)) ; => 285
+(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000
+(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
+(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
+
+;; Και για να χρησιμοποιήσουμε ένα αυθαίρετο συνδυασμό χρησιμοποιούμε
+;; το 'for/fold'
+(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
+
+;; Αυτό συχνά μπορεί να αντικαταστήσει τους κοινούς
+;; προστακτικούς βρόχους (imperative loops)
+
+;;; Εξαιρέσεις
+
+;; Για να πιάσουμε τις εξαιρέσεις χρησιμοποιούμε το
+;; `with-handlers'
+(with-handlers ([exn:fail? (lambda (exn) 999)])
+ (+ 1 "2")) ; => 999
+(with-handlers ([exn:break? (lambda (exn) "no time")])
+ (sleep 3)
+ "phew") ; => "phew", αλλά αν γίνει το break => "no time"
+
+;; Χρησιμοποιούμε το 'raise' για να άρουμε μια εξαίρεση
+;; ή οποιαδήποτε άλλη τιμή
+(with-handlers ([number? ; πιάνουμε αριθμητικές τιμές
+ identity]) ; και τις επιστρέφουμε σαν απλές τιμές
+ (+ 1 (raise 2))) ; => 2
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Αλλαγή τιμών
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Χρησιμοποιούμε το 'set!' για να θέσουμε μια νέα τιμή
+;; σε μια ήδη υπάρχουσα μεταβλητή
+(define n 5)
+(set! n (add1 n))
+n ; => 6
+
+;; Χρησιμοποιούμε τα boxes για να δηλώσουμε ρητά ότι μια μεταβλητή
+;; θα είναι mutable (θα μπορεί να αλλάξει η τιμή της)
+;; Αυτό είναι παρόμοιο με τους pointers σε άλλες γλώσσες
+(define n* (box 5))
+(set-box! n* (add1 (unbox n*)))
+(unbox n*) ; => 6
+
+
+;; Πολλοί τύποι μεταβλητών στη Racket είναι αμετάβλητοι π.χ. τα ζεύγη, οι
+;; λίστες κτλ. Άλλοι υπάρχουν και σε μεταβλητή και σε αμετάβλητη μορφή
+;; π.χ. αλφαριθμητικά, διανύσματα κτλ.
+(define vec (vector 2 2 3 4))
+(define wall (make-vector 100 'bottle-of-beer))
+;; Χρησιμοποιούμε το 'vector-set!' για να ανεώσουμε κάποια
+;; συγκεκριμένη θέση
+(vector-set! vec 0 1)
+(vector-set! wall 99 'down)
+vec ; => #(1 2 3 4)
+
+
+;; Έτσι δημιουργούμε ένα άδειο μεταβλητό πίνακα κατακερματισμού
+;; και τον χειριζόμαστε κατάλληλα
+(define m3 (make-hash))
+(hash-set! m3 'a 1)
+(hash-set! m3 'b 2)
+(hash-set! m3 'c 3)
+(hash-ref m3 'a) ; => 1
+(hash-ref m3 'd 0) ; => 0
+(hash-remove! m3 'a)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Ενότητες (modules)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; Οι ενότητες μας επιτρέπουν να οργανώνουμε τον κώδικα σε πολλαπλά
+;; αρχεία και επαναχρησιμοποιούμενες βιβλιοθήκες
+;; Εδώ χρησιμοποιούμε υπο-ενότητες, εμφωλευμένες μέσα σε μια
+;; άλλη ενότητα που δημιουργεί αυτό το κείμενο (ξεκινώντας από
+;; την γραμμή '#lang' )
+(module cake racket/base ; ορίζουμε μια ενότητα 'cake' βασισμένο στο
+ ; racket/base
+
+ (provide print-cake) ; συνάρτηση που εξάγεται από την ενότητα
+
+ (define (print-cake n)
+ (show " ~a " n #\.)
+ (show " .-~a-. " n #\|)
+ (show " | ~a | " n #\space)
+ (show "---~a---" n #\-))
+
+ (define (show fmt n ch) ; εσωτερική συνάρτηση
+ (printf fmt (make-string n ch))
+ (newline)))
+
+;; Χρησιμοποιουμε το 'require' για να πάρουμε όλα τα
+;; παρεχόμενα ονόματα από μία ενότητα
+(require 'cake) ; το ' είναι για τοπική υποενότητα
+(print-cake 3)
+; (show "~a" 1 #\A) ; => error, το `show' δεν έχει εξαχθεί
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. Κλάσεις και αντικείμενα
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Δημιουργούμε μια κλάση fish% (- συνήθως χρησιμοποιούμε
+;; το % στο όνομα μιας κλάσης )
+(define fish%
+ (class object%
+ (init size) ; initialization argument
+ (super-new) ; superclass initialization
+ ;; Field
+ (define current-size size)
+ ;; Public methods
+ (define/public (get-size)
+ current-size)
+ (define/public (grow amt)
+ (set! current-size (+ amt current-size)))
+ (define/public (eat other-fish)
+ (grow (send other-fish get-size)))))
+
+;; Δημιουργούμε ένα instance του fish%
+(define charlie
+ (new fish% [size 10]))
+
+;; Χρησιμοποιούμε το 'send' για να καλέσουμε
+;; τις μεθόδους ενός αντικειμένου
+(send charlie get-size) ; => 10
+(send charlie grow 6)
+(send charlie get-size) ; => 16
+
+;; Το `fish%' είναι μία τιμή "πρώτης κλάσης"
+;; με το οποίο μπορούμε να κάνουμε προσμείξεις
+(define (add-color c%)
+ (class c%
+ (init color)
+ (super-new)
+ (define my-color color)
+ (define/public (get-color) my-color)))
+(define colored-fish% (add-color fish%))
+(define charlie2 (new colored-fish% [size 10] [color 'red]))
+(send charlie2 get-color)
+;; ή χωρίς καθόλου ονόματα :
+(send (new (add-color fish%) [size 10] [color 'red]) get-color)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 9. Μακροεντολές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Οι μακροεντολές μας επιτρέπουν να επεκτείνουμε
+;; το συντακτικό μιας γλώσσας.
+
+;; Ας προσθέσουμε έναν βρόχο while
+(define-syntax-rule (while condition body ...)
+ (let loop ()
+ (when condition
+ body ...
+ (loop))))
+
+(let ([i 0])
+ (while (< i 10)
+ (displayln i)
+ (set! i (add1 i))))
+
+;; Macros are hygienic, you cannot clobber existing variables!
+(define-syntax-rule (swap! x y) ; -! is idiomatic for mutation
+ (let ([tmp x])
+ (set! x y)
+ (set! y tmp)))
+
+(define tmp 2)
+(define other 3)
+(swap! tmp other)
+(printf "tmp = ~a; other = ~a\n" tmp other)
+;; Η μεταβλητή 'tmp' μετονομάζεται σε 'tmp_1'
+;; για να αποφευχθεί η σύγκρουση με τα ονόματα
+;; (let ([tmp_1 tmp])
+;; (set! tmp other)
+;; (set! other tmp_1))
+
+;; Αλλά ακόμα υπάρχουν ακόμη μετασχηματισμοί του κώδικα, π.χ.:
+(define-syntax-rule (bad-while condition body ...)
+ (when condition
+ body ...
+ (bad-while condition body ...)))
+;; αυτή η μακροεντολή είναι χαλασμένη: δημιουργεί ατέρμονα βρόχο
+;; και αν προσπαθήσουμε να το χρησιμοποιήσουμε, ο μεταγλωττιστής
+;; θα μπει στον ατέρμονα βρόχο.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 10. Συμβόλαια (Contracts)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Τα συμβόλαια βάζουν περιορισμούς σε τιμές που προέρχονται
+;; από ενότητες (modules)
+(module bank-account racket
+ (provide (contract-out
+ [deposit (-> positive? any)] ; οι ποσότητες είναι πάντα θετικές
+ [balance (-> positive?)]))
+
+ (define amount 0)
+ (define (deposit a) (set! amount (+ amount a)))
+ (define (balance) amount)
+ )
+
+(require 'bank-account)
+(deposit 5)
+
+(balance) ; => 5
+
+;; Πελάτες που προσπαθούν να καταθέσουν ένα μη θετικό ποσό παίρνουν
+;; το μήνυμα (deposit -5) ; => deposit: contract violation
+;; expected: positive?
+;; given: -5
+;; more details....
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 11. Είσοδος και έξοδος
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Η Racket έχει την έννοια του "port", που είναι παρόμοιο με τα
+;; file descriptors σε άλλες γλώσσες.
+
+;; Ανοίγουμε το "/tmp/tmp.txt" και γράφουμε μέσα "Hello World"
+;; Αυτό θα προκαλούσε σφάλμα αν το αρχείο υπήρχε ήδη
+(define out-port (open-output-file "/tmp/tmp.txt"))
+(displayln "Hello World" out-port)
+(close-output-port out-port)
+
+;; Προσθέτουμε στο τέλος του "/tmp/tmp.txt"
+(define out-port (open-output-file "/tmp/tmp.txt"
+ #:exists 'append))
+(displayln "Hola mundo" out-port)
+(close-output-port out-port)
+
+;; Διαβάζουμε από αρχείο ξανά
+(define in-port (open-input-file "/tmp/tmp.txt"))
+(displayln (read-line in-port))
+; => "Hello World"
+(displayln (read-line in-port))
+; => "Hola mundo"
+(close-input-port in-port)
+
+;; Εναλλακτικά, με το call-with-output-file δεν χρειάζεται να κλείσουμε
+;; ρητά το αρχείο
+(call-with-output-file "/tmp/tmp.txt"
+ #:exists 'update ; Rewrite the content
+ (λ (out-port)
+ (displayln "World Hello!" out-port)))
+
+;; Και το call-with-input-file κάνει το ίδιο πράγμα για την είσοδο
+(call-with-input-file "/tmp/tmp.txt"
+ (λ (in-port)
+ (displayln (read-line in-port))))
+```
+
+## Επιπλέον πηγές
+
+Ψάχνεις για περισσότερα ; [Getting Started with Racket](http://docs.racket-lang.org/getting-started/)
diff --git a/el-gr/scala-gr.html.markdown b/el-gr/scala-gr.html.markdown
new file mode 100644
index 00000000..415fda5c
--- /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)
+