summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--de-de/scala-de.html.markdown518
-rw-r--r--haskell.html.markdown2
-rw-r--r--java.html.markdown15
-rw-r--r--ms-my/javascript-my.html.markdown588
-rw-r--r--objective-c.html.markdown46
-rw-r--r--python.html.markdown5
6 files changed, 919 insertions, 255 deletions
diff --git a/de-de/scala-de.html.markdown b/de-de/scala-de.html.markdown
index 7fd299b4..456403a2 100644
--- a/de-de/scala-de.html.markdown
+++ b/de-de/scala-de.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
- ["Geoff Liu", "http://geoffliu.me"]
- ["Ha-Duong Nguyen", "http://reference-error.org"]
+ - ["Dennis Keller", "github.com/denniskeller"]
translators:
- ["Christian Albrecht", "https://github.com/coastalchief"]
filename: learnscala-de.scala
@@ -16,167 +17,172 @@ für die Java Virtual Machine (JVM), um allgemeine Programmieraufgaben
zu erledigen. Scala hat einen akademischen Hintergrund und wurde an
der EPFL (Lausanne / Schweiz) unter der Leitung von Martin Odersky entwickelt.
-
-# 0. Umgebung einrichten
+```scala
+/*
Scala Umgebung einrichten:
1. Scala binaries herunterladen- http://www.scala-lang.org/downloads
2. Unzip/untar in ein Verzeichnis
3. das bin Unterverzeichnis der `PATH` Umgebungsvariable hinzufügen
4. Mit dem Kommando `scala` wird die REPL gestartet und zeigt als Prompt:
-```
+
scala>
-```
Die REPL (Read-Eval-Print Loop) ist der interaktive Scala Interpreter.
Hier kann man jeden Scala Ausdruck verwenden und das Ergebnis wird direkt
ausgegeben.
Als nächstes beschäftigen wir uns mit ein paar Scala Basics.
+*/
-# 1. Basics
-Einzeilige Kommentare beginnen mit zwei vorwärts Slash
+/////////////////////////////////////////////////
+// 1. Basics
+/////////////////////////////////////////////////
+
+// Einzeilige Kommentare beginnen mit zwei Slashes
/*
- Mehrzeilige Kommentare, werden starten
- mit Slash-Stern und enden mit Stern-Slash
+ Mehrzeilige Kommentare, starten
+ mit einem Slash-Stern und enden mit einem Stern-Slash
*/
// Einen Wert, und eine zusätzliche neue Zeile ausgeben
-```
+
println("Hello world!")
println(10)
-```
+
// Einen Wert, ohne eine zusätzliche neue Zeile ausgeben
-```
+
print("Hello world")
-```
-// Variablen werden entweder mit var oder val deklariert.
-// Deklarationen mit val sind immutable, also unveränderlich
-// Deklarationen mit var sind mutable, also veränderlich
-// Immutability ist gut.
-```
+/*
+ Variablen werden entweder mit var oder val deklariert.
+ Deklarationen mit val sind immutable, also unveränderlich
+ Deklarationen mit var sind mutable, also veränderlich
+ Immutability ist gut.
+*/
val x = 10 // x ist 10
x = 20 // error: reassignment to val
var y = 10
y = 20 // y ist jetzt 20
-```
-Scala ist eine statisch getypte Sprache, auch wenn in dem o.g. Beispiel
+/*
+Scala ist eine statisch getypte Sprache, auch wenn wir in dem o.g. Beispiel
keine Typen an x und y geschrieben haben.
-In Scala ist etwas eingebaut, was sich Type Inference nennt. D.h. das der
-Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine ist,
-so dass der Typ nicht jedes mal angegeben werden soll.
+In Scala ist etwas eingebaut, was sich Type Inference nennt. Das heißt das der
+Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine Variable ist,
+so dass der Typ nicht jedes mal angegeben werden muss.
Einen Typ gibt man bei einer Variablendeklaration wie folgt an:
-```
+*/
val z: Int = 10
val a: Double = 1.0
-```
+
// Bei automatischer Umwandlung von Int auf Double wird aus 10 eine 10.0
-```
+
val b: Double = 10
-```
+
// Boolean Werte
-```
+
true
false
-```
+
// Boolean Operationen
-```
+
!true // false
!false // true
true == false // false
10 > 5 // true
-```
+
// Mathematische Operationen sind wie gewohnt
-```
+
1 + 1 // 2
2 - 1 // 1
5 * 3 // 15
6 / 2 // 3
6 / 4 // 1
6.0 / 4 // 1.5
-```
+
// Die Auswertung eines Ausdrucks in der REPL gibt den Typ
// und das Ergebnis zurück.
-```
+
scala> 1 + 7
res29: Int = 8
-```
+/*
Das bedeutet, dass das Resultat der Auswertung von 1 + 7 ein Objekt
von Typ Int ist und einen Wert 0 hat.
"res29" ist ein sequentiell generierter name, um das Ergebnis des
Ausdrucks zu speichern. Dieser Wert kann bei Dir anders sein...
-
+*/
"Scala strings werden in doppelten Anführungszeichen eingeschlossen"
'a' // A Scala Char
// 'Einzeln ge-quotete strings gibt es nicht!' <= This causes an error
// Für Strings gibt es die üblichen Java Methoden
-```
+
"hello world".length
"hello world".substring(2, 6)
"hello world".replace("C", "3")
-```
+
// Zusätzlich gibt es noch extra Scala Methoden
// siehe: scala.collection.immutable.StringOps
-```
+
"hello world".take(5)
"hello world".drop(5)
-```
+
// String interpolation: prefix "s"
-```
+
val n = 45
s"We have $n apples" // => "We have 45 apples"
-```
-// Ausdrücke im innern von interpolierten Strings gibt es auch
-```
+
+// Ausdrücke im Innern von interpolierten Strings gibt es auch
+
val a = Array(11, 9, 6)
val n = 100
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"
-```
+
// Formatierung der interpolierten Strings mit dem prefix "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 Strings, ignorieren Sonderzeichen.
-```
+
raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
-```
+
// Manche Zeichen müssen "escaped" werden, z.B.
// ein doppeltes Anführungszeichen in innern eines Strings.
-```
+
"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
-```
+
// Dreifache Anführungszeichen erlauben es, dass ein String über mehrere Zeilen geht
// und Anführungszeichen enthalten kann.
-```
+
val html = """<form id="daform">
<p>Press belo', Joe</p>
<input type="submit">
</form>"""
-```
-# 2. Funktionen
+
+/////////////////////////////////////////////////
+// 2. Funktionen
+/////////////////////////////////////////////////
// Funktionen werden so definiert
//
@@ -184,74 +190,74 @@ val html = """<form id="daform">
//
// Beachte: Es gibt kein return Schlüsselwort. In Scala ist der letzte Ausdruck
// in einer Funktion der Rückgabewert.
-```
+
def sumOfSquares(x: Int, y: Int): Int = {
val x2 = x * x
val y2 = y * y
x2 + y2
}
-```
+
// Die geschweiften Klammern können weggelassen werden, wenn
// die Funktion nur aus einem einzigen Ausdruck besteht:
-```
+
def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
-```
+
// Syntax für Funktionsaufrufe:
-```
+
sumOfSquares(3, 4) // => 25
-```
+
// In den meisten Fällen (mit Ausnahme von rekursiven Funktionen), können
// Rückgabetypen auch weggelassen werden, da dieselbe Typ Inference, wie bei
// Variablen, auch bei Funktionen greift:
-```
+
def sq(x: Int) = x * x // Compiler errät, dass der return type Int ist
-```
+
// Funktionen können default parameter haben:
-```
+
def addWithDefault(x: Int, y: Int = 5) = x + y
addWithDefault(1, 2) // => 3
addWithDefault(1) // => 6
-```
+
// Anonyme Funktionen sehen so aus:
-```
+
(x: Int) => x * x
-```
+
// Im Gegensatz zu def bei normalen Funktionen, kann bei anonymen Funktionen
// sogar der Eingabetyp weggelassen werden, wenn der Kontext klar ist.
// Beachte den Typ "Int => Int", dies beschreibt eine Funktion,
// welche Int als Parameter erwartet und Int zurückgibt.
-```
+
val sq: Int => Int = x => x * x
-```
+
// Anonyme Funktionen benutzt man ganz normal:
-```
+
sq(10) // => 100
-```
+
// Wenn ein Parameter einer anonymen Funktion nur einmal verwendet wird,
// bietet Scala einen sehr kurzen Weg diesen Parameter zu benutzen,
// indem die Parameter als Unterstrich "_" in der Parameterreihenfolge
// verwendet werden. Diese anonymen Funktionen werden sehr häufig
// verwendet.
-```
+
val addOne: Int => Int = _ + 1
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
addOne(5) // => 6
weirdSum(2, 4) // => 16
-```
+
// Es gibt einen keyword return in Scala. Allerdings ist seine Verwendung
// nicht immer ratsam und kann fehlerbehaftet sein. "return" gibt nur aus
// dem innersten def, welches den return Ausdruck umgibt, zurück.
// "return" hat keinen Effekt in anonymen Funktionen:
-```
+
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
@@ -261,28 +267,30 @@ def foo(x: Int): Int = {
}
anonFunc(x) // Zeile ist der return Wert von foo
}
-```
-# 3. Flow Control
-## Wertebereiche und Schleifen
-```
+/////////////////////////////////////////////////
+// 3. Flow Control
+/////////////////////////////////////////////////
+
+// Wertebereiche und Schleifen
+
1 to 5
val r = 1 to 5
r.foreach(println)
r foreach println
(5 to 1 by -1) foreach (println)
-```
-// Scala ist syntaktisch sehr grosszügig, Semikolons am Zeilenende
+
+// Scala ist syntaktisch sehr großzügig, Semikolons am Zeilenende
// sind optional, beim Aufruf von Methoden können die Punkte
// und Klammern entfallen und Operatoren sind im Grunde austauschbare Methoden
// while Schleife
-```
+
var i = 0
while (i < 10) { println("i " + i); i += 1 }
i // i ausgeben, res3: Int = 10
-```
+
// Beachte: while ist eine Schleife im klassischen Sinne -
// Sie läuft sequentiell ab und verändert die loop-Variable.
@@ -291,28 +299,28 @@ i // i ausgeben, res3: Int = 10
// und zu parellelisieren.
// Ein do while Schleife
-```
+
do {
println("x ist immer noch weniger wie 10")
x += 1
} while (x < 10)
-```
+
// Endrekursionen sind ideomatisch um sich wiederholende
// Dinge in Scala zu lösen. Rekursive Funtionen benötigen explizit einen
// return Typ, der Compiler kann ihn nicht erraten.
// Unit, in diesem Beispiel.
-```
+
def showNumbersInRange(a: Int, b: Int): Unit = {
print(a)
if (a < b)
showNumbersInRange(a + 1, b)
}
showNumbersInRange(1, 14)
-```
-## Conditionals
-```
+
+// Conditionals
+
val x = 10
if (x == 1) println("yeah")
if (x == 10) println("yeah")
@@ -320,186 +328,193 @@ 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. Daten Strukturen (Array, Map, Set, Tuples)
-## Array
-```
+/////////////////////////////////////////////////
+// 4. Daten Strukturen (Array, Map, Set, Tuples)
+/////////////////////////////////////////////////
+
+// Array
+
val a = Array(1, 2, 3, 5, 8, 13)
a(0)
a(3)
a(21) // Exception
-```
-## Map - Speichert Key-Value-Paare
-```
+
+// Map - Speichert Key-Value-Paare
+
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")
-```
-## Set - Speichert Unikate, unsortiert (sortiert -> SortedSet)
-```
+
+// Set - Speichert Unikate, unsortiert (sortiert -> SortedSet)
+
val s = Set(1, 3, 7)
s(0) //false
s(1) //true
val s = Set(1,1,3,3,7)
s: scala.collection.immutable.Set[Int] = Set(1, 3, 7)
-```
-## Tuple - Speichert beliebige Daten und "verbindet" sie miteinander
+
+// Tuple - Speichert beliebige Daten und "verbindet" sie miteinander
// Ein Tuple ist keine Collection.
-```
+
(1, 2)
(4, 3, 2)
(1, 2, "three")
(a, 2, "three")
-```
+
// Hier ist der Rückgabewert der Funktion ein Tuple
// Die Funktion gibt das Ergebnis, so wie den Rest zurück.
-```
+
val divideInts = (x: Int, y: Int) => (x / y, x % y)
divideInts(10, 3)
-```
+
// Um die Elemente eines Tuples anzusprechen, benutzt man diese
// Notation: _._n wobei n der index des Elements ist (Index startet bei 1)
-```
+
val d = divideInts(10, 3)
d._1
d._2
-```
-# 5. Objekt Orientierte Programmierung
-Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar
-zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in
-einem Scala file selten alleine zu finden sind.
-Die einzigen Top-Level Konstrukte in Scala sind nämlich:
-- Klassen (classes)
-- Objekte (objects)
-- case classes
-- traits
+/////////////////////////////////////////////////
+// 5. Objektorientierte Programmierung
+/////////////////////////////////////////////////
+
+/*
+ Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar
+ zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in
+ einem Scala file selten alleine zu finden sind.
+ Die einzigen Top-Level Konstrukte in Scala sind nämlich:
+
+ - Klassen (classes)
+ - Objekte (objects)
+ - case classes
+ - traits
-Diesen Sprachelemente wenden wir uns jetzt zu.
+ Diesen Sprachelemente wenden wir uns jetzt zu.
+*/
-## Klassen
+// Klassen
// Zum Erstellen von Objekten benötigt man eine Klasse, wie in vielen
// anderen Sprachen auch.
// erzeugt Klasse mit default Konstruktor
-```
+
class Hund
scala> val t = new Hund
t: Hund = Hund@7103745
-```
+
// Der Konstruktor wird direkt hinter dem Klassennamen deklariert.
-```
+
class Hund(sorte: String)
scala> val t = new Hund("Dackel")
t: Hund = Hund@14be750c
scala> t.sorte //error: value sorte is not a member of Hund
-```
+
// Per val wird aus dem Attribut ein unveränderliches Feld der Klasse
// Per var wird aus dem Attribut ein veränderliches Feld der Klasse
-```
+
class Hund(val sorte: String)
scala> val t = new Hund("Dackel")
t: Hund = Hund@74a85515
scala> t.sorte
res18: String = Dackel
-```
+
// Methoden werden mit def geschrieben
-```
+
def bark = "Woof, woof!"
-```
+
// Felder und Methoden können public, protected und private sein
// default ist public
// private ist nur innerhalb des deklarierten Bereichs sichtbar
-```
+
class Hund {
private def x = ...
def y = ...
}
-```
+
// protected ist nur innerhalb des deklarierten und aller
// erbenden Bereiche sichtbar
-```
+
class Hund {
protected def x = ...
}
class Dackel extends Hund {
// x ist sichtbar
}
-```
-## Object
-Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
-"companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
-ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
-benutzen ohne ein Objekt instanziieren zu müssen.
-Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn
-es genauso heisst und in derselben Datei wie die Klasse definiert wurde.
-```
+
+// Object
+// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
+// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
+// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
+// benutzen ohne ein Objekt instanziieren zu müssen.
+// Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn
+// es genauso heisst und in derselben Datei wie die Klasse definiert wurde.
+
object Hund {
def alleSorten = List("Pitbull", "Dackel", "Retriever")
def createHund(sorte: String) = new Hund(sorte)
}
-```
-## Case classes
-Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra
-Funktionalität erweitern. Mit Case Klassen bekommt man ein paar
-Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.
-ein companion object mit den entsprechenden Methoden,
-Hilfsmethoden wie toString(), equals() und hashCode() und auch noch
-Getter für unsere Attribute (das Angeben von val entfällt dadurch)
-```
+
+// Case classes
+// Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra
+// Funktionalität erweitern. Mit Case Klassen bekommt man ein paar
+// Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.
+// ein companion object mit den entsprechenden Methoden,
+// Hilfsmethoden wie toString(), equals() und hashCode() und auch noch
+// Getter für unsere Attribute (das Angeben von val entfällt dadurch)
+
class Person(val name: String)
class Hund(val sorte: String, val farbe: String, val halter: Person)
-```
+
// Es genügt das Schlüsselwort case vor die Klasse zu schreiben.
-```
+
case class Person(name: String)
case class Hund(sorte: String, farbe: String, halter: Person)
-```
+
// Für neue Instanzen brauch man kein "new"
-```
+
val dackel = Hund("dackel", "grau", Person("peter"))
val dogge = Hund("dogge", "grau", Person("peter"))
-```
+
// getter
-```
+
dackel.halter // => Person = Person(peter)
-```
+
// equals
-```
+
dogge == dackel // => false
-```
+
// copy
// otherGeorge == Person("george", "9876")
-```
+
val otherGeorge = george.copy(phoneNumber = "9876")
-```
-## Traits
-Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp
-und Methodensignaturen. Scala erlaubt allerdings das teilweise
-implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.
-Traits können von anderen Traits oder Klassen erben, aber nur von
-parameterlosen.
-```
+
+// Traits
+// Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp
+// und Methodensignaturen. Scala erlaubt allerdings das teilweise
+// implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.
+// Traits können von anderen Traits oder Klassen erben, aber nur von
+// parameterlosen.
+
trait Hund {
def sorte: String
def farbe: String
@@ -511,9 +526,9 @@ class Bernhardiner extends Hund{
val farbe = "braun"
def beissen = false
}
-```
+
-```
+
scala> b
res0: Bernhardiner = Bernhardiner@3e57cd70
scala> b.sorte
@@ -522,10 +537,10 @@ scala> b.bellen
res2: Boolean = true
scala> b.beissen
res3: Boolean = false
-```
+
// Traits können auch via Mixins (Schlüsselwort "with") eingebunden werden
-```
+
trait Bellen {
def bellen: String = "Woof"
}
@@ -541,25 +556,27 @@ scala> val b = new Bernhardiner
b: Bernhardiner = Bernhardiner@7b69c6ba
scala> b.bellen
res0: String = Woof
-```
-# 6. Pattern Matching
-Pattern matching in Scala ist ein sehr nützliches und wesentlich
-mächtigeres Feature als Vergleichsfunktionen in Java. In Scala
-benötigt ein case Statement kein "break", ein fall-through gibt es nicht.
-Mehrere Überprüfungen können mit einem Statement gemacht werden.
-Pattern matching wird mit dem Schlüsselwort "match" gemacht.
-```
+/////////////////////////////////////////////////
+// 6. Pattern Matching
+/////////////////////////////////////////////////
+
+// Pattern matching in Scala ist ein sehr nützliches und wesentlich
+// mächtigeres Feature als Vergleichsfunktionen in Java. In Scala
+// benötigt ein case Statement kein "break", ein fall-through gibt es nicht.
+// Mehrere Überprüfungen können mit einem Statement gemacht werden.
+// Pattern matching wird mit dem Schlüsselwort "match" gemacht.
+
val x = ...
x match {
case 2 =>
case 3 =>
case _ =>
}
-```
+
// Pattern Matching kann auf beliebige Typen prüfen
-```
+
val any: Any = ...
val gleicht = any match {
case 2 | 3 | 5 => "Zahl"
@@ -568,19 +585,19 @@ val gleicht = any match {
case 45.35 => "Double"
case _ => "Unbekannt"
}
-```
+
// und auf Objektgleichheit
-```
+
def matchPerson(person: Person): String = person match {
case Person("George", nummer) => "George! Die Nummer ist " + number
case Person("Kate", nummer) => "Kate! Die Nummer ist " + nummer
case Person(name, nummer) => "Irgendjemand: " + name + ", Telefon: " + nummer
}
-```
+
// Und viele mehr...
-```
+
val email = "(.*)@(.*)".r // regex
def matchEverything(obj: Any): String = obj match {
// Werte:
@@ -600,18 +617,21 @@ def matchEverything(obj: Any): String = obj match {
// Patterns kann man ineinander schachteln:
case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
}
-```
+
// Jedes Objekt mit einer "unapply" Methode kann per Pattern geprüft werden
// Ganze Funktionen können Patterns sein
-```
+
val patternFunc: Person => String = {
case Person("George", number) => s"George's number: $number"
case Person(name, number) => s"Random person's number: $number"
}
-```
-# 7. Higher-order functions
+
+/////////////////////////////////////////////////
+// 37. Higher-order functions
+/////////////////////////////////////////////////
+
Scala erlaubt, das Methoden und Funktion wiederum Funtionen und Methoden
als Aufrufparameter oder Return Wert verwenden. Diese Methoden heissen
higher-order functions
@@ -621,116 +641,117 @@ Nennenswerte sind:
"filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"
## List
-```
+
def isGleichVier(a:Int) = a == 4
val list = List(1, 2, 3, 4)
val resultExists4 = list.exists(isEqualToFour)
-```
+
## map
// map nimmt eine Funktion und führt sie auf jedem Element aus und erzeugt
// eine neue Liste
// Funktion erwartet ein Int und returned ein Int
-```
+
val add10: Int => Int = _ + 10
-```
+
// add10 wird auf jedes Element angewendet
-```
+
List(1, 2, 3) map add10 // => List(11, 12, 13)
-```
+
// Anonyme Funktionen können anstatt definierter Funktionen verwendet werden
-```
+
List(1, 2, 3) map (x => x + 10)
-```
+
// Der Unterstrich wird anstelle eines Parameters einer anonymen Funktion
// verwendet. Er wird an die Variable gebunden.
-```
+
List(1, 2, 3) map (_ + 10)
-```
+
// Wenn der anonyme Block und die Funtion beide EIN Argument erwarten,
// kann sogar der Unterstrich weggelassen werden.
-```
+
List("Dom", "Bob", "Natalia") foreach println
-```
-## filter
+
+// filter
// filter nimmt ein Prädikat (eine Funktion von A -> Boolean) und findet
// alle Elemente die auf das Prädikat passen
-```
+
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))
-```
-## reduce
+
+// reduce
// reduce nimmt zwei Elemente und kombiniert sie zu einem Element,
// und zwar solange bis nur noch ein Element da ist.
-## foreach
+// foreach
// foreach gibt es für einige Collections
-```
+
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
-```
-## For comprehensions
+
+// For comprehensions
// Eine for-comprehension definiert eine Beziehung zwischen zwei Datensets.
// Dies ist keine for-Schleife.
-```
+
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
-```
+
/////////////////////////////////////////////////
-# 8. Implicits
+// 8. Implicits
/////////////////////////////////////////////////
-**ACHTUNG:**
-Implicits sind ein sehr mächtiges Sprachfeature von Scala. Es sehr einfach
-sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am
-besten erst dann benutzen, wenn man versteht wie sie funktionieren.
-Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle
-vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles
-machen kann.
-Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.
+// **ACHTUNG:**
+// Implicits sind ein sehr mächtiges Sprachfeature von Scala.
+// Es sehr einfach
+// sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am
+// besten erst dann benutzen, wenn man versteht wie sie funktionieren.
+// Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle
+// vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles
+// machen kann.
+// Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.
// Mit dem Schlüsselwort implicit können Methoden, Werte, Funktion, Objekte
// zu "implicit Methods" werden.
-```
+
implicit val myImplicitInt = 100
implicit def myImplicitFunction(sorte: String) = new Hund("Golden " + sorte)
-```
+
// implicit ändert nicht das Verhalten eines Wertes oder einer Funktion
-```
+
myImplicitInt + 2 // => 102
myImplicitFunction("Pitbull").sorte // => "Golden Pitbull"
-```
+
// Der Unterschied ist, dass diese Werte ausgewählt werden können, wenn ein
// anderer Codeteil einen implicit Wert benötigt, zum Beispiel innerhalb von
// implicit Funktionsparametern
// Diese Funktion hat zwei Parameter: einen normalen und einen implicit
-```
+
def sendGreetings(toWhom: String)(implicit howMany: Int) =
s"Hello $toWhom, $howMany blessings to you and yours!"
-```
+
// Werden beide Parameter gefüllt, verhält sich die Funktion wie erwartet
-```
+
sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
-```
+
// Wird der implicit Parameter jedoch weggelassen, wird ein anderer
// implicit Wert vom gleichen Typ genommen. Der Compiler sucht im
@@ -739,66 +760,69 @@ sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!
// geforderten Typ konvertieren kann.
// Hier also: "myImplicitInt", da ein Int gesucht wird
-```
+
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
-```
+
// bzw. "myImplicitFunction"
// Der String wird erst mit Hilfe der Funktion in Hund konvertiert, und
// dann wird die Methode aufgerufen
-```
+
"Retriever".sorte // => "Golden Retriever"
-```
-# 9. Misc
-## Importe
-```
+
+/////////////////////////////////////////////////
+// 19. Misc
+/////////////////////////////////////////////////
+// Importe
+
import scala.collection.immutable.List
-```
+
// Importiere alle Unterpackages
-```
+
import scala.collection.immutable._
-```
+
// Importiere verschiedene Klassen mit einem Statement
-```
+
import scala.collection.immutable.{List, Map}
-```
+
// Einen Import kann man mit '=>' umbenennen
-```
+
import scala.collection.immutable.{List => ImmutableList}
-```
+
// Importiere alle Klasses, mit Ausnahem von....
// Hier ohne: Map and Set:
-```
+
import scala.collection.immutable.{Map => _, Set => _, _}
-```
-## Main
-```
+
+// Main
+
object Application {
def main(args: Array[String]): Unit = {
- // stuff goes here.
+ // Sachen kommen hierhin
}
}
-```
-## I/O
+
+// I/O
// Eine Datei Zeile für Zeile lesen
-```
+
import scala.io.Source
for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
-```
+
// Eine Datei schreiben
-```
+
val writer = new PrintWriter("myfile.txt")
writer.write("Schreibe Zeile" + util.Properties.lineSeparator)
writer.write("Und noch eine Zeile" + util.Properties.lineSeparator)
writer.close()
+
```
## Weiterführende Hinweise
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 08611e63..936744a0 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -81,7 +81,7 @@ not False -- True
[5,4..1] -- [5, 4, 3, 2, 1]
-- indexing into a list
-[0..] !! 5 -- 5
+[1..10] !! 3 -- 4
-- You can also have infinite lists in Haskell!
[1..] -- a list of all the natural numbers
diff --git a/java.html.markdown b/java.html.markdown
index 1813f81c..e1efc375 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -128,7 +128,7 @@ public class LearnJava {
//
// BigInteger can be initialized using an array of bytes or a string.
- BigInteger fooBigInteger = new BigDecimal(fooByteArray);
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
// BigDecimal - Immutable, arbitrary-precision signed decimal number
@@ -144,7 +144,12 @@ public class LearnJava {
// or by initializing the unscaled value (BigInteger) and scale (int).
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
-
+
+ // Be wary of the constructor that takes a float or double as
+ // the inaccuracy of the float/double will be copied in BigDecimal.
+ // Prefer the String constructor when you need an exact value.
+
+ BigDecimal tenCents = new BigDecimal("0.1");
// Strings
@@ -207,8 +212,8 @@ public class LearnJava {
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 (0.5 truncated down)
- System.out.println("1/2 = " + (i1 / (i2*1.0))); // => 0.5
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns an int)
+ System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
// Modulo
System.out.println("11%3 = "+(11 % 3)); // => 2
@@ -416,7 +421,7 @@ public class LearnJava {
// easier way, by using something that is called Double Brace
// Initialization.
- private static final Set<String> COUNTRIES = HashSet<String>() {{
+ private static final Set<String> COUNTRIES = new HashSet<String>() {{
add("DENMARK");
add("SWEDEN");
add("FINLAND");
diff --git a/ms-my/javascript-my.html.markdown b/ms-my/javascript-my.html.markdown
new file mode 100644
index 00000000..90e37133
--- /dev/null
+++ b/ms-my/javascript-my.html.markdown
@@ -0,0 +1,588 @@
+---
+language: javascript
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+filename: javascript-ms.js
+translators:
+ - ["abdalim", "https://github.com/abdalim"]
+lang: ms-my
+---
+
+Javascript dicipta oleh Brendan Eich dari Netscape pada 1995. Pada awalnya, ia
+dicipta sebagai bahasa skrip yang ringkas untuk laman web, melengkapi penggunaan
+Java untuk aplikasi web yang lebih rumit, namun begitu, integrasi rapat pada
+halaman web dan sokongan tersedia dalam pelayar web telah menyebabkan ia menjadi
+lebih kerap digunakan berbanding Java pada bahagian hadapan laman web.
+
+Namun begitu, Javascript tidak terhad pada pelayar web; Node.js, sebuah projek
+yang menyediakan 'runtime' berdiri sendiri untuk enjin V8 Google Chrome sedang
+kian mendapat sambutan yang hangat.
+
+```js
+// Komentar adalah seperti dalam C. Komentar sebaris bermula dengan dua sengkang
+/* dan komentar banyak baris bermula dengan sengkang-bintang
+ dan berakhir dengan bintang-sengkang */
+
+// Pernyataan boleh ditamatkan dengan ';'
+doStuff();
+
+// ... tetapi ia tidak wajib, kerana koma bertitik secara automatik akan
+// dimasukkan dimana tempat yang ada baris baru, kecuali dalam kes - kes
+// tertentu.
+doStuff()
+
+// Disebabkan kes - kes itu boleh menyebabkan hasil yang tidak diduga, kami
+// akan sentiasa menggunakan koma bertitik dalam panduan ini.
+
+///////////////////////////////////
+// 1. Nombor, String dan Operator
+
+// Javascript mempunyai satu jenis nombor (iaitu 64-bit IEEE 754 double).
+// Double mempunyai 52-bit mantissa, iaitu ia cukup untuk menyimpan integer
+// sehingga 9✕10¹⁵ secara tepatnya.
+3; // = 3
+1.5; // = 1.5
+
+// Sebahagian aritmetic asas berfungsi seperti yang anda jangkakan.
+1 + 1; // = 2
+0.1 + 0.2; // = 0.30000000000000004
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+
+// Termasuk pembahagian tidak rata.
+5 / 2; // = 2.5
+
+// Dan pembahagian modulo.
+10 % 2; // = 0
+30 % 4; // = 2
+18.5 % 7; // = 4.5
+
+// Operasi bitwise juga boleh digunakan; bila anda melakukan operasi bitwise,
+// float anda akan ditukarkan kepada int bertanda *sehingga* 32 bit.
+1 << 2; // = 4
+
+// Keutamaan ditekankan menggunakan kurungan.
+(1 + 3) * 2; // = 8
+
+// Terdapat tiga nilai nombor-tidak-nyata istimewa
+Infinity; // hasil operasi seperti 1/0
+-Infinity; // hasil operasi seperti -1/0
+NaN; // hasil operasi seperti 0/0, bermaksud 'Bukan Sebuah Nombor'
+
+// Terdapat juga jenis boolean
+true;
+false;
+
+// Talian dicipta dengan ' atau ''.
+'abc';
+"Hello, world";
+
+// Penafian menggunakan simbol !
+!true; // = tidak benar
+!false; // = benar
+
+// Sama ialah ===
+1 === 1; // = benar
+2 === 1; // = tidak benar
+
+// Tidak sama ialah !==
+1 !== 1; // = tidak benar
+2 !== 1; // = benar
+
+// Lagi perbandingan
+1 < 10; // = benar
+1 > 10; // = tidak benar
+2 <= 2; // = benar
+2 >= 2; // = benar
+
+// Talian disambungkan dengan +
+"Hello " + "world!"; // = "Hello world!"
+
+// dan dibandingkan dengan < dan >
+"a" < "b"; // = benar
+
+// Paksaan jenis dilakukan untuk perbandingan menggunakan dua sama dengan...
+"5" == 5; // = benar
+null == undefined; // = benar
+
+// ...melainkan anda menggunakan ===
+"5" === 5; // = tidak benar
+null === undefined; // = tidak benar
+
+// ...yang boleh menghasilkan keputusan yang pelik...
+13 + !0; // 14
+"13" + !0; // '13true'
+
+// Anda boleh akses huruf dalam perkataan dengan `charAt`
+"This is a string".charAt(0); // = 'T'
+
+// ...atau menggunakan `substring` untuk mendapatkan bahagian yang lebih besar.
+"Hello world".substring(0, 5); // = "Hello"
+
+// `length` adalah ciri, maka jangan gunakan ().
+"Hello".length; // = 5
+
+// Selain itu, terdapat juga `null` dan `undefined`.
+null; // digunakan untuk menandakan bukan-nilai yang disengajakan
+undefined; // digunakan untuk menandakan nilai yang tidak wujud pada waktu ini (walaupun `undefined` adalah nilai juga)
+
+// false, null, undefined, NaN, 0 dan "" adalah tidak benar; semua selain itu adalah benar.
+// Peringatan, 0 adalah tidak benar dan "0" adalah benar, walaupun 0 == "0".
+
+///////////////////////////////////
+// 2. Pembolehubah, Array dan Objek
+
+// Pembolehubah digunakan dengan kata kunci 'var'. Javascript ialah sebuah
+// bahasa aturcara yang jenisnya dinamik, maka anda tidak perlu spesifikasikan
+// jenis pembolehubah. Penetapan menggunakan satu '=' karakter.
+var someVar = 5;
+
+// jika anda tinggalkan kata kunci var, anda tidak akan dapat ralat...
+someOtherVar = 10;
+
+// ...tetapi pembolehubah anda akan dicipta di dalam skop global, bukan di
+// dalam skop anda menciptanya.
+
+// Pembolehubah yang dideklarasikan tanpa ditetapkan sebarang nilai akan
+// ditetapkan kepada undefined.
+var someThirdVar; // = undefined
+
+// jika anda ingin mendeklarasikan beberapa pembolehubah, maka anda boleh
+// menggunakan koma sebagai pembahagi
+var someFourthVar = 2, someFifthVar = 4;
+
+// Terdapat cara mudah untuk melakukan operasi - operasi matematik pada
+// pembolehubah:
+someVar += 5; // bersamaan dengan someVar = someVar +5; someVar sama dengan 10 sekarang
+someVar *= 10; // sekarang someVar bernilai 100
+
+// dan cara lebih mudah untuk penambahan atau penolakan 1
+someVar++; // sekarang someVar ialah 101
+someVar--; // kembali kepada 100
+
+// Array adalah senarai nilai yang tersusun, yang boleh terdiri daripada
+// pembolehubah pelbagai jenis.
+var myArray = ["Hello", 45, true];
+
+// Setiap ahli array boleh diakses menggunakan syntax kurungan-petak.
+// Indeks array bermula pada sifar.
+myArray[1]; // = 45
+
+// Array boleh diubah dan mempunyai panjang yang tidak tetap dan boleh ubah.
+myArray.push("World");
+myArray.length; // = 4
+
+// Tambah/Ubah di index yang spesifik
+myArray[3] = "Hello";
+
+// Objek javascript adalah sama dengan "dictionaries" atau "maps" dalam bahasa
+// aturcara yang lain: koleksi pasangan kunci-nilai yang tidak mempunyai
+// sebarang susunan.
+var myObj = {key1: "Hello", key2: "World"};
+
+// Kunci adalah string, tetapi 'quote' tidak diperlukan jika ia adalah pengecam
+// javascript yang sah. Nilai boleh mempunyai sebarang jenis.
+var myObj = {myKey: "myValue", "my other key": 4};
+
+// Ciri - ciri objek boleh juga diakses menggunakan syntax subskrip (kurungan-
+// petak),
+myObj["my other key"]; // = 4
+
+// ... atau menggunakan syntax titik, selagi kuncinya adalah pengecam yang sah.
+myObj.myKey; // = "myValue"
+
+// Objek adalah boleh diubah; nilai boleh diubah dan kunci baru boleh ditambah.
+myObj.myThirdKey = true;
+
+// Jika anda cuba untuk akses nilai yang belum ditetapkan, anda akan mendapat
+// undefined.
+myObj.myFourthKey; // = undefined
+
+///////////////////////////////////
+// 3. Logik dan Struktur Kawalan
+
+// Syntax untuk bahagian ini adalah hampir sama dengan Java.
+
+// Struktur `if` berfungsi seperti yang anda jangkakan.
+var count = 1;
+if (count == 3){
+ // dinilai jika count ialah 3
+} else if (count == 4){
+ // dinilai jika count ialah 4
+} else {
+ // dinilai jika count bukan 3 atau 4
+}
+
+// Sama juga dengan `while`.
+while (true){
+ // Sebuah ulangan yang tidak terhingga!
+ // An infinite loop!
+}
+
+// Ulangan do-while adalah sama dengan ulangan while, kecuali ia akan diulang
+// sekurang-kurangnya sekali.
+var input;
+do {
+ input = getInput();
+} while (!isValid(input))
+
+// Ulangan `for` adalah sama dengan C dan Java:
+// Persiapan; kondisi untuk bersambung; pengulangan.
+for (var i = 0; i < 5; i++){
+ // akan berulang selama 5 kali
+}
+
+// Pernyataan ulangan For/In akan mengulang setiap ciri seluruh jaringan
+// 'prototype'
+var description = "";
+var person = {fname:"Paul", lname:"Ken", age:18};
+for (var x in person){
+ description += person[x] + " ";
+}
+
+// Jika anda cuma mahu mengambil kira ciri - ciri yang ditambah pada objek it
+// sendiri dan bukan 'prototype'nya, sila gunakan semakan hasOwnProperty()
+var description = "";
+var person = {fname:"Paul", lname:"Ken", age:18};
+for (var x in person){
+ if (person.hasOwnProperty(x)){
+ description += person[x] + " ";
+ }
+}
+
+// for/in tidak sepatutnya digunakan untuk mengulang sebuah Array di mana
+// indeks susunan adalah penting.
+// Tiada sebarang jaminan bahawa for/in akan mengembalikan indeks dalam
+// mana - mana susunan
+
+// && adalah logikal dan, || adalah logikal atau
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear";
+}
+if (colour == "red" || colour == "blue"){
+ // warna adalah sama ada 'red' atau 'blue'
+}
+
+// && dan || adalah "lintar pintas", di mana ia berguna untuk menetapkan
+// nilai asal.
+var name = otherName || "default";
+
+
+// Pernyataan `switch` menyemak persamaan menggunakan `===`.
+// gunakan pernyataan `break` selepas setiap kes
+// atau tidak, kes - kes selepas kes yang betul akan dijalankan juga.
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
+
+
+///////////////////////////////////
+// 4. Functions, Skop dan Closures
+
+// Function javascript dideklarasikan dengan kata kunci `function`.
+function myFunction(thing){
+ return thing.toUpperCase();
+}
+myFunction("foo"); // = "FOO"
+
+// Perhatikan yang nilai yang dikembalikan mesti bermula pada baris yang sama
+// dengan kata kunci `return`, jika tidak, anda akan sentiasa mengembalikan
+// `undefined` disebabkan kemasukan 'semicolon' secara automatik. Sila berjaga -
+// jaga dengan hal ini apabila menggunakan Allman style.
+function myFunction(){
+ return // <- semicolon dimasukkan secara automatik di sini
+ {thisIsAn: 'object literal'}
+}
+myFunction(); // = undefined
+
+// Function javascript adalah objek kelas pertama, maka ia boleh diberikan
+// nama pembolehubah yang lain dan diberikan kepada function yang lain sebagai
+// input - sebagai contoh, apabila membekalkan pengendali event:
+function myFunction(){
+ // kod ini akan dijalankan selepas 5 saat
+}
+setTimeout(myFunction, 5000);
+// Nota: setTimeout bukan sebahagian daripada bahasa JS, tetapi ia disediakan
+// oleh pelayar web dan Node.js.
+
+// Satu lagi function yang disediakan oleh pelayar web adalah setInterval
+function myFunction(){
+ // kod ini akan dijalankan setiap 5 saat
+}
+setInterval(myFunction, 5000);
+
+// Objek function tidak perlu dideklarasikan dengan nama - anda boleh menulis
+// function yang tidak bernama didalam input sebuah function lain.
+setTimeout(function(){
+ // kod ini akan dijalankan dalam 5 saat
+}, 5000);
+
+// Javascript mempunyai skop function; function mempunyai skop mereka
+// tersendiri tetapi blok tidak.
+if (true){
+ var i = 5;
+}
+i; // = 5 - bukan undefined seperti yang anda jangkakan di dalam bahasa blok-skop
+
+// Ini telah menyebabkan corak biasa iaitu "immediately-executing anonymous
+// functions", yang mengelakkan pembolehubah sementara daripada bocor ke
+// skop global.
+(function(){
+ var temporary = 5;
+ // Kita boleh akses skop global dengan menetapkan nilai ke "objek global",
+ // iaitu dalam pelayar web selalunya adalah `window`. Objek global mungkin
+ // mempunyai nama yang berlainan dalam alam bukan pelayar web seperti Node.js.
+ window.permanent = 10;
+})();
+temporary; // akan menghasilkan ralat ReferenceError
+permanent; // = 10
+
+// Salah satu ciri terhebat Javascript ialah closure. Jika sebuah function
+// didefinisikan di dalam sebuah function lain, function yang di dalam akan
+// mempunyai akses kepada semua pembolehubah function yang di luar, mahupun
+// selepas function yang di luar tersebut selesai.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!";
+ // Function dalam diletakkan di dalam skop lokal secara asal, seperti
+ // ia dideklarasikan dengan `var`.
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout adalah tak segerak atau asinkroni, maka function sayHelloInFiveSeconds akan selesai serta merta, dan setTimeout akan memanggil
+ // inner selepas itu. Walaubagaimanapun, disebabkan inner terletak didalam
+ // sayHelloInFiveSeconds, inner tetap mempunyai akses kepada pembolehubah
+ // `prompt` apabila ia dipanggil.
+}
+sayHelloInFiveSeconds("Adam"); // akan membuka sebuah popup dengan "Hello, Adam!" selepas 5s
+
+///////////////////////////////////
+// 5. Lagi tentang Objek, Constructor dan Prototype
+
+// Objek boleh mengandungi function.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Apabila function sesebuah object dipanggil, ia boleh mengakses objek asalnya
+// dengan menggunakan kata kunci `this`.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Nilai sebenar yang ditetapkan kepada this akan ditentukan oleh bagaimana
+// sesebuah function itu dipanggil, bukan dimana ia didefinisikan. Oleh it,
+// sesebuah function tidak akan berfungsi jika ia dipanggil bukan pada konteks
+// objeknya.
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+
+// Sebaliknya, sebuah function boleh ditetapkan kepada objek dan mendapat akses
+// kepada objek itu melalui `this`, walaupun ia tidak ditetapkan semasa ia
+// didefinisikan.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+}
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// Kita juga boleh menentukan konteks untuk sebuah function dijalankan apabila
+// ia dipanggil menggunakan `call` atau `apply`.
+
+var anotherFunc = function(s){
+ return this.myString + s;
+}
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// Function `apply` adalah hampir sama, tetapi ia mengambil sebuah array
+// sebagai senarai input.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// Ini sangat berguna apabila menggunakan sebuah function yang menerima senarai
+// input dan anda mahu menggunakan sebuah array sebagai input.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// Tetapi, `call` dan `apply` adalah hanya sementara, sebagaimana hidup ini.
+// Apabila kita mahu ia kekal, kita boleh menggunakan `bind`.
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// `bind` boleh juga digunakan untuk menggunakan sebuah function tidak
+// sepenuhnya (curry).
+
+var product = function(a, b){ return a * b; }
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
+// Apabila anda memanggil sebuah function dengan kata kunci `new`, sebuah
+// objek baru akan dicipta dan dijadikan tersedia kepada function itu melalui
+// kata kunci `this`. Function yang direka bentuk untuk dipanggil sebegitu rupa
+// dikenali sebagai constructors.
+
+var MyConstructor = function(){
+ this.myNumber = 5;
+}
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+
+// Setiap objek JavaScript mempunyai `prototype`. Apabila anda akses sesuatu
+// ciri sebuah objek yang tidak wujud dalam objek sebenar itu, interpreter akan
+// mencari ciri itu didalam `prototype`nya.
+
+// Sebahagian implementasi JS membenarkan anda untuk akses prototype sebuah
+// objek pada ciri istimewa `__proto__`. Walaupun ini membantu dalam menerangkan
+// mengenai prototypes, ia bukan sebahagian dari piawai; kita akan melihat
+// cara - cara piawai untuk menggunakan prototypes nanti.
+var myObj = {
+ myString: "Hello world!"
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+};
+
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+
+// Ini berfungsi untuk function juga.
+myObj.myFunc(); // = "hello world!"
+
+// Sudah pasti, jika ciri anda bukan pada prototype anda, prototype kepada
+// prototype anda akan disemak, dan seterusnya.
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+
+// Tiada penyalinan terlibat disini; setiap objek menyimpan rujukan kepada
+// prototypenya sendiri. Ini bermaksud, kita boleh mengubah prototypenya dan
+// pengubahsuaian itu akan dilihat dan berkesan dimana sahaja.
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// Kami menyatakan yang `__proto__` adalah bukan piawai, dan tiada cara rasmi
+// untuk mengubah prototype sesebuah objek. Walaubagaimanapun, terdapat dua
+// cara untuk mencipta objek baru dengan sesebuah prototype.
+
+// Yang pertama ialah Object.create, yang merupakan tambahan terbaru pada JS,
+// dan oleh itu tiada dalam semua implementasi buat masa ini.
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// Cara kedua, yang boleh digunakan dimana sahaja, adalah berkaitan dengan
+// constructor. Constructors mempunyai sebuah ciri yang dipanggil prototype.
+// Ini *bukan* prototype constructor terbabit; tetapi, ia adalah prototype yang
+// diberikan kepada objek baru apabila ia dicipta menggunakan constructor dan
+// kata kunci new.
+MyConstructor.prototype = {
+ myNumber: 5,
+ getMyNumber: function(){
+ return this.myNumber;
+ }
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6
+myNewObj2.getMyNumber(); // = 6
+
+// Jenis yang terbina sedia seperti string dan nombor juga mempunyai constructor
+// yang mencipta objek pembalut yang serupa.
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+
+// Kecuali, mereka sebenarnya tak sama sepenuhnya.
+typeof myNumber; // = 'number'
+typeof myNumberObj; // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // Kod ini tidak akan dilaksanakan, kerana 0 adalah tidak benar.
+}
+
+// Walaubagaimanapun, pembalut objek dan jenis terbina yang biasa berkongsi
+// prototype, maka sebagai contoh, anda sebenarnya boleh menambah fungsi
+// kepada string.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+}
+"abc".firstCharacter(); // = "a"
+
+// Fakta ini selalu digunakan dalam "polyfilling", iaitu melaksanakan fungsi
+// baru JavaScript didalam subset JavaScript yang lama, supaya ia boleh
+// digunakan di dalam persekitaran yang lama seperti pelayar web yang lama.
+
+// Sebagai contoh, kami menyatakan yang Object.create belum lagi tersedia
+// di semua implementasi, tetapi kita masih boleh menggunakannya dengan polyfill:
+if (Object.create === undefined){ // jangan ganti jika ia sudah wujud
+ Object.create = function(proto){
+ // buat satu constructor sementara dengan prototype yang betul
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // kemudian gunakannya untuk mencipta objek baru yang diberikan
+ // prototype yang betul
+ return new Constructor();
+ }
+}
+```
+## Bacaan Lanjut
+
+[Mozilla Developer Network][1] menyediakan dokumentasi yang sangat baik untuk
+JavaScript kerana ia digunakan di dalam pelayar - pelayar web. Tambahan pula,
+ia adalah sebuah wiki, maka, sambil anda belajar lebih banyak lagi, anda boleh
+membantu orang lain dengan berkongsi pengetahuan anda.
+
+[A re-introduction to JavaScript][2] oleh MDN meliputi semua konsep yang
+diterangkan di sini dengan lebih terperinci. Panduan ini menerangkan bahasa
+aturcara JavaScript dengan agak mudah; jika anda mahu belajar lebih lanjut
+tentang menggunakan JavaScript didalam laman web, mulakan dengan mempelajari
+tentang [Document Object Model][3].
+
+[Learn Javascript by Example and with Challenges][4] adalah variasi panduan ini
+dengan cabaran yang tersedia pakai.
+
+[JavaScript Garden][5] pula adalah panduan yang lebih terperinci mengenai
+semua bahagian bahasa aturcara ini yang bertentangan dengan naluri atau
+kebiasaan.
+
+[JavaScript: The Definitive Guide][6] adalah panduan klasik dan buku rujukan.
+
+Selain daripada penyumbang terus kepada artikel ini, sebahagian kandungannya
+adalah adaptasi daripada tutorial Python Louie Dinh di dalam laman web ini,
+dan [JS Tutorial][7] di Mozilla Developer Network.
+
+
+[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
+[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
+[4]: http://www.learneroo.com/modules/64/nodes/350
+[5]: http://bonsaiden.github.io/JavaScript-Garden/
+[6]: http://www.amazon.com/gp/product/0596805527/
+[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index f130ea0c..05bb5c6a 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -599,6 +599,52 @@ int main (int argc, const char * argv[]) {
@end
+// Starting in Xcode 7.0, you can create Generic classes,
+// allowing you to provide greater type safety and clarity
+// without writing excessive boilerplate.
+@interface Result<__covariant A> : NSObject
+
+- (void)handleSuccess:(void(^)(A))success
+ failure:(void(^)(NSError *))failure;
+
+@property (nonatomic) A object;
+
+@end
+
+// we can now declare instances of this class like
+Result<NSNumber *> *result;
+Result<NSArray *> *result;
+
+// Each of these cases would be equivalent to rewriting Result's interface
+// and substituting the appropriate type for A
+@interface Result : NSObject
+- (void)handleSuccess:(void(^)(NSArray *))success
+ failure:(void(^)(NSError *))failure;
+@property (nonatomic) NSArray * object;
+@end
+
+@interface Result : NSObject
+- (void)handleSuccess:(void(^)(NSNumber *))success
+ failure:(void(^)(NSError *))failure;
+@property (nonatomic) NSNumber * object;
+@end
+
+// It should be obvious, however, that writing one
+// Class to solve a problem is always preferable to writing two
+
+// Note that Clang will not accept generic types in @implementations,
+// so your @implemnation of Result would have to look like this:
+
+@implementation Result
+
+- (void)handleSuccess:(void (^)(id))success
+ failure:(void (^)(NSError *))failure {
+ // Do something
+}
+
+@end
+
+
///////////////////////////////////////
// Protocols
///////////////////////////////////////
diff --git a/python.html.markdown b/python.html.markdown
index 541bd36d..5bc8d28a 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -238,7 +238,7 @@ li.remove(2) # Raises a ValueError as 2 is not in the list
li.insert(1, 2) # li is now [1, 2, 3, 4, 5, 6] again
# Get the index of the first item found
-li.index(2) # => 3
+li.index(2) # => 1
li.index(7) # Raises a ValueError as 7 is not in the list
# Check for existence in a list with "in"
@@ -261,8 +261,9 @@ tup[:2] # => (1, 2)
# You can unpack tuples (or lists) into variables
a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
+d, e, f = 4, 5, 6 # you can leave out the parentheses
# Tuples are created by default if you leave out the parentheses
-d, e, f = 4, 5, 6
+g = 4, 5, 6 # => (4, 5, 6)
# Now look how easy it is to swap two values
e, d = d, e # d is now 5 and e is now 4