summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c.html.markdown4
-rw-r--r--clojure-macros.html.markdown152
-rw-r--r--de-de/css-de.html.markdown230
-rw-r--r--es-es/git-es.html.markdown2
-rw-r--r--fr-fr/lua-fr.html.markdown449
-rw-r--r--fr-fr/objective-c-fr.html.markdown527
-rw-r--r--hy.html.markdown174
-rw-r--r--javascript.html.markdown14
-rw-r--r--julia.html.markdown81
-rw-r--r--ko-kr/go-kr.html.markdown314
-rw-r--r--objective-c.html.markdown239
-rw-r--r--php.html.markdown2
-rw-r--r--racket.html.markdown40
-rw-r--r--zh-cn/clojure-cn.html.markdown366
-rw-r--r--zh-cn/go-cn.html.markdown16
-rw-r--r--zh-cn/javascript-cn.html.markdown2
-rw-r--r--zh-cn/php-cn.html.markdown6
-rw-r--r--zh-cn/ruby-cn.html.markdown3
18 files changed, 2539 insertions, 82 deletions
diff --git a/c.html.markdown b/c.html.markdown
index 84856b32..e55ff148 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -92,7 +92,7 @@ int main() {
printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words)
- // If the argument of the `sizeof` operator an expression, then its argument
+ // If the argument of the `sizeof` operator is an expression, then its argument
// is not evaluated (except VLAs (see below)).
// The value it yields in this case is a compile-time constant.
int a = 1;
@@ -376,7 +376,7 @@ int main() {
// or when it's the argument of the `sizeof` or `alignof` operator:
int arr[10];
int *ptr = arr; // equivalent with int *ptr = &arr[0];
- printf("%zu %zu\n", sizeof arr, sizeof ptr); // probably prints "40, 4" or "40, 8"
+ printf("%zu, %zu\n", sizeof arr, sizeof ptr); // probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
diff --git a/clojure-macros.html.markdown b/clojure-macros.html.markdown
new file mode 100644
index 00000000..8e671936
--- /dev/null
+++ b/clojure-macros.html.markdown
@@ -0,0 +1,152 @@
+---
+language: "clojure macros"
+filename: learnclojuremacros.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+---
+
+As with all Lisps, Clojure's inherent [homoiconicity](https://en.wikipedia.org/wiki/Homoiconic)
+gives you access to the full extent of the language to write code-generation routines
+called "macros". Macros provide a powerful way to tailor the language to your needs.
+
+Be careful though. It's considered bad form to write a macro when a function will do.
+Use a macro only when you need control over when or if the arguments to a form will
+be evaluated.
+
+You'll want to be familiar with Clojure. Make sure you understand everything in
+[Clojure in Y Minutes](/docs/clojure/).
+
+```clojure
+;; Define a macro using defmacro. Your macro should output a list that can
+;; be evaluated as clojure code.
+;;
+;; This macro is the same as if you wrote (reverse "Hello World")
+(defmacro my-first-macro []
+ (list reverse "Hello World"))
+
+;; Inspect the result of a macro using macroexpand or macroexpand-1.
+;;
+;; Note that the call must be quoted.
+(macroexpand '(my-first-macro))
+;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World")
+
+;; You can eval the result of macroexpand directly:
+(eval (macroexpand '(my-first-macro)))
+; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; But you should use this more succinct, function-like syntax:
+(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; You can make things easier on yourself by using the more succinct quote syntax
+;; to create lists in your macros:
+(defmacro my-first-quoted-macro []
+ '(reverse "Hello World"))
+
+(macroexpand '(my-first-quoted-macro))
+;; -> (reverse "Hello World")
+;; Notice that reverse is no longer function object, but a symbol.
+
+;; Macros can take arguments.
+(defmacro inc2 [arg]
+ (list + 2 arg))
+
+(inc2 2) ; -> 4
+
+;; But, if you try to do this with a quoted list, you'll get an error, because
+;; the argument will be quoted too. To get around this, clojure provides a
+;; way of quoting macros: `. Inside `, you can use ~ to get at the outer scope
+(defmacro inc2-quoted [arg]
+ `(+ 2 ~arg))
+
+(inc2-quoted 2)
+
+;; You can use the usual destructuring args. Expand list variables using ~@
+(defmacro unless [arg & body]
+ `(if (not ~arg)
+ (do ~@body))) ; Remember the do!
+
+(macroexpand '(unless true (reverse "Hello World")))
+;; ->
+;; (if (clojure.core/not true) (do (reverse "Hello World")))
+
+;; (unless) evaluates and returns its body if the first argument is false.
+;; Otherwise, it returns nil
+
+(unless true "Hello") ; -> nil
+(unless false "Hello") ; -> "Hello"
+
+;; Used without care, macros can do great evil by clobbering your vars
+(defmacro define-x []
+ '(do
+ (def x 2)
+ (list x)))
+
+(def x 4)
+(define-x) ; -> (2)
+(list x) ; -> (2)
+
+;; To avoid this, use gensym to get a unique identifier
+(gensym 'x) ; -> x1281 (or some such thing)
+
+(defmacro define-x-safely []
+ (let [sym (gensym 'x)]
+ `(do
+ (def ~sym 2)
+ (list ~sym))))
+
+(def x 4)
+(define-x-safely) ; -> (2)
+(list x) ; -> (4)
+
+;; You can use # within ` to produce a gensym for each symbol automatically
+(defmacro define-x-hygenically []
+ `(do
+ (def x# 2)
+ (list x#)))
+
+(def x 4)
+(define-x-hygenically) ; -> (2)
+(list x) ; -> (4)
+
+;; It's typical to use helper functions with macros. Let's create a few to
+;; help us support a (dumb) inline arithmatic syntax
+(declare inline-2-helper)
+(defn clean-arg [arg]
+ (if (seq? arg)
+ (inline-2-helper arg)
+ arg))
+
+(defn apply-arg
+ "Given args [x (+ y)], return (+ x y)"
+ [val [op arg]]
+ (list op val (clean-arg arg)))
+
+(defn inline-2-helper
+ [[arg1 & ops-and-args]]
+ (let [ops (partition 2 ops-and-args)]
+ (reduce apply-arg (clean-arg arg1) ops)))
+
+;; We can test it immediately, without creating a macro
+(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5))
+
+; However, we'll need to make it a macro if we want it to be run at compile time
+(defmacro inline-2 [form]
+ (inline-2-helper form)))
+
+(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1)))
+; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1)
+
+(inline-2 (1 + (3 / 2) - (1 / 2) + 1))
+; -> 3 (actually, 3N, since the number got cast to a rational fraction with /)
+```
+
+### Further Reading
+
+Writing Macros from [Clojure for the Brave and True](http://www.braveclojure.com/)
+[http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/)
+
+Official docs
+[http://clojure.org/macros](http://clojure.org/macros)
+
+When to use macros?
+[http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html)
diff --git a/de-de/css-de.html.markdown b/de-de/css-de.html.markdown
new file mode 100644
index 00000000..e03b3174
--- /dev/null
+++ b/de-de/css-de.html.markdown
@@ -0,0 +1,230 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+translators:
+ - ["Kyr", "http://github.com/kyrami"]
+lang: de-de
+---
+
+In den frühen Tagen des Internets gab es keine visuellen Elemente, alles war nur reiner Text. Aber mit der Weiterentwickliung von Browsern wurden auch vollständig visuelle Webseiten zu einem Standard.
+CSS ist die allgemeine Sprache, die dazu da ist, damit man den HTML-Code und die Designelemente von Webseiten (strikt) unterscheiden kann.
+
+Kurzgefasst, CSS ermöglicht es, verschiedene HTML-Elemente anzuvisieren und ihnen stilistische Eigenschaften zu geben.
+
+CSS hat wie jede andere Sprache viele Versionen. Hier fokussieren wir uns auf CSS2.0, welche nicht die neueste, aber die am weitesten verbreitete und unterstützte Version ist.
+
+**NOTE:** Weil die Ausgabe von CSS visuelle Eigenschaften sind, wirst du wahrscheinlich eine CSS-Sandbox wie [dabblet](http://dabblet.com/) benutzen müssen, um die Sprache richtig zu lernen.
+In diesem Artikel wird am meisten auf generelle Hinweise und die Syntax geachtet.
+
+
+```css
+/* kommentare werden in sternchen-schrägstrichkombinationen gepackt (genauso wie hier!) */
+
+/* ####################
+ ## SELEKTOREN
+ ####################*/
+
+/* Eigentlich ist die häufigste Anwendungsweise von CSS sehr simpel */
+selektor { eigenschaft: wert; /* mehr eigenschaften...*/ }
+
+/* der selektor wird dazu benutzt, ein element auf der seite anzuvisieren
+
+Aber man kann auch alle Elemente auf einer Seite anvisieren! */
+* { color:red; } /* farbe:rot */
+
+/*
+Wenn wir so ein Element auf einer Seite haben:
+
+<div class='eine-klasse klasse2' id='eineId' attr='wert' />
+*/
+
+/* kann man es so bei seiner klasse anvisieren */
+.eine-klasse { }
+
+/*oder bei beiden klassen! */
+.eine-klasse.klasse2 { }
+
+/* oder beim namen des tags */
+div { }
+
+/* oder bei seiner id */
+#eineId { }
+
+/* oder daran, dass es ein Attribut hat! */
+[attr] { font-size:smaller; }
+
+/* oder daran, dass das attribut einen bestimmten wert hat*/
+[attr='wert'] { font-size:smaller; }
+
+/* beginnt mit einem wert*/
+[attr^='wert'] { font-size:smaller; }
+
+/* oder endet mit */
+[attr$='rt'] { font-size:smaller; }
+
+/* oder sogar nur beinhaltet */
+[attr~='er'] { font-size:smaller; }
+
+
+/* was aber noch wichtiger ist, ist dass man alle diese kombinieren
+kann - man sollte nur mit der leerzeichensetzung vorsichtig sein,
+da es mit einem leerzeichen zwei verschiedene selektoren wären*/
+div.eine-klasse[attr$='rt'] { } /* so ist es richtig */
+
+/* man kann auch ein element daran festmachen, wie sich die übergeordneten
+elemente verhalten!*/
+
+/*es muss allerdings ein direktes kind sein */
+div.ein-elternteil > .klassen-name {}
+
+/* oder jeder seiner eltern in der struktur */
+/* das folgende heißt also, dass jedes element mit der klasse 'klassen-name'
+und dem elternteil IN JEDER TIEFE ausgewählt wird */
+div.ein-elternteil .klassen-name {}
+
+/* achtung: dasselbe ohne das leerzeichen hat eine andere bedeutung,
+kannst du mir sagen, was? */
+div.ein-elternteil.klassen-name {}
+
+/* man kann auch ein element nach seinem direkten vorherigen zwilling
+auswählen */
+.ich-bin-vorher + .dieses-element { }
+
+/* oder jeden zwilling davor */
+.ich-kann-jeder-davor-sein ~ .dieses-element {}
+
+/* es gibt ein paar pseudoklassen, die sich basierend auf dem
+seitenverhalten, nämlich nicht auf der seitenstruktur auswählen
+lassen können */
+
+/* zum beispiel, wenn über ein element mit dem mauszeiger gefahren wird */
+:hover {}
+
+/* oder einen bereits besuchten link*/
+:visited {}
+
+/* oder einen noch nicht besuchten link*/
+:link {}
+
+/* oder ein eingabeelement, das zurzeit im fokus steht */
+:focus {}
+
+
+/* ####################
+ ## EIGENSCHAFTEN
+ ####################*/
+
+selector {
+
+ /* einheiten */
+ width: 50%; /* in prozent */
+ font-size: 2em; /* mal der derzeitigen schriftgröße */
+ width: 200px; /* in pixeln */
+ font-size: 20pt; /* in punkten */
+ width: 5cm; /* in zentimetern */
+ width: 50mm; /* in millimetern */
+ width: 5in; /* in zoll */
+
+ /* farben */
+ background-color: #F6E /* in kurzem hex */
+ background-color: #F262E2 /* in langem hex */
+ background-color: tomato /* kann auch eine genannte farbe sein */
+ background-color: rgb(255, 255, 255) /* in rgb */
+ background-color: rgb(10%, 20%, 50%) /* in rgb prozent */
+ background-color: rgba(255, 0, 0, 0.3); /* in semi-transparentem rgb */
+
+ /* bilder */
+ background-image: url(/pfad-zum-bild/image.jpg);
+
+ /* schriften */
+ font-family: Arial;
+ font-family: "Courier New"; /* wenn der name ein leerzeichen beinhält, kommt er in
+ apostrophe */
+ font-family: "Courier New", Trebuchet, Arial; /* wenn der erste nicht gefunden wird, wird
+ der zweite benutzt, und so weiter */
+}
+
+```
+
+## Benutzung
+
+speichere das css, das du benutzen willst mit der endung '.css'.
+
+```xml
+<!-- du musst die css-datei im <head>-bereich der seite erwähnen -->
+<link rel='stylesheet' type='text/css' href='filepath/filename.css' />
+
+<!-- es geht allerdings auch direkt, wobei diese methode nicht
+empfohlen ist -->
+<style>
+ selector { property:value; }
+</style>
+
+<!-- oder direkt am element (sollte aber gelassen werden) -->
+<div style='property:value;'>
+</div>
+
+```
+
+## Wichtigkeit
+
+ein element kann von mehr als einem selektoren angezielt werden.
+und kann auch eine eigenschaft mehr als einmal zugewiesen bekommen.
+in diesen fällen gibt es regeln, die die wichtigkeit von selektoren einführen.
+
+wie haben dieses CSS:
+
+```css
+/*A*/
+p.klasse1[attr='wert']
+
+/*B*/
+p.klasse1 {}
+
+/*C*/
+p.klasse2 {}
+
+/*D*/
+p {}
+
+/*E*/
+p { property: wert !important; }
+
+```
+
+und das folgende markup:
+
+```xml
+<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
+</p>
+```
+
+die wichtigkeit der stile ist wie folgt:
+(die wichtigkeit gilt nur für **eigenschaften**, nicht für ganze blöcke)
+
+* `E` hat die größte wichtigkeit wegen dem schlüsselwort `!important`.
+ man sollte diese form aber vermeiden.
+* `F` ist als nächstes, da es direkt an dem element definiert ist.
+* `A` ist als nächstes, da es "spezifischer" als alle anderen ist.
+ spezifischer = mehr zuweisungen: 1 tagname `p` +
+ klassenname `klasse1` + 1 attribut `attr='value'`
+* `C` ist als nächstes obwohl es genau so ist wie `B`
+ aber es erscheint als letztes.
+* dann ist `B`
+* und als letztes `D`.
+
+## Kompabilität
+
+die meisten features von CSS sind in allen browsern verfügbar.
+man sollte jedoch immer darauf achten, wenn man etwas mit CSS
+programmiert.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) ist eine der besten quellen dafür.
+
+## Weiterlesen
+
+* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
+* [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)
+
diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown
index 0623b29b..5c9d3378 100644
--- a/es-es/git-es.html.markdown
+++ b/es-es/git-es.html.markdown
@@ -6,7 +6,7 @@ contributors:
translator:
- ["Raúl Ascencio", "http://rscnt.github.io"]
filename: LearnGit.txt
-language: es-es
+lang: es-es
---
diff --git a/fr-fr/lua-fr.html.markdown b/fr-fr/lua-fr.html.markdown
new file mode 100644
index 00000000..922d6ebc
--- /dev/null
+++ b/fr-fr/lua-fr.html.markdown
@@ -0,0 +1,449 @@
+---
+language: lua
+filename: learnlua-fr.lua
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
+translators:
+ - ["Roland Yonaba", "http://github.com/Yonaba"]
+lang: fr-fr
+---
+
+```lua
+-- Les commentaires unilignes commencent par un double tiret.
+
+--[[
+ Les doubles crochets à la suite du double tiret
+ permettent d'insérer des commentaires multilignes.
+--]]
+
+----------------------------------------------------
+-- 1. Variables et contrôle d'exécution.
+----------------------------------------------------
+
+num = 42 -- Tous les nombres sont de type double.
+-- Rassurez vous cependant, les doubles stockés sur 64-bits
+-- en réservent 52 pour la valeur exacte des entiers. La
+-- précision n'est donc pas un problème pour tout entier qui
+-- peut être codé sur moins de 52 bits.
+
+s = 'walternate' -- Chaines de caractères immuables comme en Python.
+t = "une chaine avec des guillemets doubles"
+u = [[les double crochets permettent
+ d'avoir une chaine de caractères
+ sur plusieurs lignes.]]
+t = nil -- Affecte la valeur nulle à t; Lua possède un ramasse-miettes
+
+-- Le do/end définit un bloc de code
+while num < 50 do
+ num = num + 1 -- Pas d'opérateurs de type ++ ou +=.
+end
+
+-- Les structures en if:
+if num > 40 then
+ print('supérieur à 40')
+elseif s ~= 'walternate' then -- ~= : est différent de.
+ -- Le test d'égalité se fait avec == comme en Python.
+ io.write('inférieur à 40\n') -- Écrit par defaut sur la sortie stdout.
+else
+ -- Les variables sont globales par défaut.
+ thisIsGlobal = 5 -- le style camelCase est courant.
+
+ -- Une variable locale est déclarée avec le mot-clé local:
+ local line = io.read() -- Permet de lire la ligne suivante dans stdin.
+
+ -- .. est l'opérateur de concaténation:
+ print("L'hiver approche, " .. line)
+end
+
+-- Les variables non définies reçoivent par défaut la valeur nil.
+foo = anUnknownVariable -- Maintenant, foo = nil.
+
+aBoolValue = false
+
+-- Seuls nil et false sont des valeurs fausses.
+-- Mais 0 et '' sont des valeurs vraies!
+if not aBoolValue then print('etait faux') end
+
+-- L'évaluation du 'or' et du 'and' est court-circuité.
+-- Comme avec les ternaires du C et du JS: a?b:c
+ans = aBoolValue and 'oui' or 'non' --> 'non'
+
+karlSum = 0
+for i = 1, 100 do -- Les bornes sont incluses dans l'intervalle.
+ karlSum = karlSum + i
+end
+
+-- Utilisez "100, 1, -1" pour la décrémentation:
+fredSum = 0
+for j = 100, 1, -1 do fredSum = fredSum + j end
+
+-- En général, l'intervalle est début, fin[, pas].
+
+-- Un autre type de boucle:
+repeat
+ print('the way of the future')
+ num = num - 1
+until num == 0
+
+
+----------------------------------------------------
+-- 2. Fonctions.
+----------------------------------------------------
+
+function fib(n)
+ if n < 2 then return n end
+ return fib(n - 2) + fib(n - 1)
+end
+
+-- Lua implémente les fermetures et les fonctions anonymes:
+function adder(x)
+ -- La fonction retournée est créée lorsque adder est appelé
+ -- et elle se rappelle de la valeur de x.
+ return function (y) return x + y end
+end
+a1 = adder(9)
+a2 = adder(36)
+print(a1(16)) --> 25
+print(a2(64)) --> 100
+
+-- Les valeurs de retour, les appels de fonction, les assignations
+-- supportent tous les listes qui peuvent ne pas correspondre en longueur.
+-- Dans ce cas, les variables à assigner en supplément reçoivent nil
+-- tandis que les valeurs à attribuer en supplément sont ignorées
+
+x, y = 1, 2 -- x = 1 et y = 2
+x, y, z = 1, 2 -- x = 1, y = 2 et z = nil
+x, y, z = 1, 2, 3, 4 -- x = 1, y = 2, z = 3, et 4 est ignoré.
+
+function bar(a, b, c)
+ print(a, b, c)
+ return 4, 8, 15, 16, 23, 42
+end
+
+x, y = bar('zaphod') --> affiche "zaphod nil nil"
+-- x = 4, y = 8, les valeurs 15 à 42 sont ignorées.
+
+-- Les fonctions sont des valeurs de première classe
+-- et peuvent être locales/globales.
+-- Les déclarations suivantes sont identiques:
+function f(x) return x * x end
+f = function (x) return x * x end
+
+-- Il en va de même pour les déclarations suivantes:
+local function g(x) return math.sin(x) end
+local g = function(x) return math.sin(x) end
+-- Sauf que pour le dernier cas, même si local g = function(x)
+-- est équivalent à local function g(x), il n'est pas possible
+-- de faire appel à g à l'intérieur du corps de la fonction (récursion)
+
+-- À moins de déclarer la fonction auparavant:
+local g; g = function (x) return math.sin(x) end
+
+-- À propos, les fonctions trigonométriques interprètent
+-- leurs arguments en radians.
+print(math.cos(math.pi)) -- affiche "-1"
+print(math.sin(math.pi)) -- affiche "0"
+
+-- Lorsqu'une fonction est appelée avec un seul argument qui est une chaine,
+-- les parenthèses peuvent être omises:
+print 'hello' -- équivalent à print('hello').
+
+-- Lorsqu'une fonction est appelée avec un seul argument qui est une table,
+-- les parenthèses peuvent aussi être omises.
+print {} -- équivalent à print({}).
+
+
+----------------------------------------------------
+-- 3. Tables.
+----------------------------------------------------
+
+-- Tables = Seule structure de données en Lua;
+-- Ce sont des listes assotiatives.
+-- Elles sont similaires aux tables PHP ou aux objets JS :
+-- des tables-dictionnaires que l'on peut utiliser en tant que listes.
+
+-- Tables en tant que dictionnaires:
+
+-- Les clés sont des chaines de caractères par défaut:
+t = {key1 = 'valeur1', key2 = false}
+
+-- Elles peuvent être indexées avec la notation en point, comme en JS:
+print(t.key1) -- Affiche "valeur1".
+t.newKey = {} -- Ajoute une nouvelle paire clé/valeur.
+t.key2 = nil -- Supprime la clé "key2" de la table.
+
+-- Notation littérale pour toute valeur non nulle en tant que clé:
+u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
+print(u[6.28]) -- affiche "tau"
+
+-- La correspondance des clés se fait par valeur pour
+-- les nombres et les chaines, mais par référence pour les tables.
+a = u['@!#'] -- a = 'qbert'.
+b = u[{}] -- On pourrait s'attendre à 1729, mais l'on obtient nil:
+-- b = nil car la clé utilisée n'est pas le même objet que celui
+-- utilisé pour stocker la valeur originale 1729.
+
+-- Si une fonction prend en argument une seule table, l'on peut
+-- omettre les parenthèses:
+function h(x) print(x.key1) end
+h{key1 = 'Sonmi~451'} -- Affiche 'Sonmi~451'.
+
+for key, val in pairs(u) do -- Parcours d'une table.
+ print(key, val)
+end
+
+-- _G est une table spéciale contenant toutes les variables globales,
+-- et donc elle même.
+print(_G['_G'] == _G) -- Affiche 'true'.
+
+-- Tables en tant que listes:
+
+-- De manière implicite, les clés sont des nombres entiers:
+v = {'value1', 'value2', 1.21, 'gigawatts'}
+for i = 1, #v do -- #v retourne la taille de la table v si elle est une liste.
+ print(v[i]) -- Attention, en Lua, les indices commencent à 1!
+end
+-- Il n'existe pas vraiment de type 'liste' en Lua, v est juste
+-- une table avec des clés qui sont des nombres entiers consécutifs
+-- commençant à 1. Lua le traite comme étant une liste.
+
+----------------------------------------------------
+-- 3.1 Métatables and métaméthodes.
+----------------------------------------------------
+
+-- Une table peut avoir une métatable qui confère à la table
+-- un patron/prototype de conception (surcharge d'opération). Nous verrons
+-- dans la suite comment les métatables imitent le prototypage du JS.
+
+f1 = {a = 1, b = 2} -- Représente la fraction a/b.
+f2 = {a = 2, b = 3}
+
+-- Ceci créée une erreur:
+-- s = f1 + f2
+
+metafraction = {}
+function metafraction.__add(f1, f2)
+ local sum = {}
+ sum.b = f1.b * f2.b
+ sum.a = f1.a * f2.b + f2.a * f1.b
+ return sum
+end
+
+setmetatable(f1, metafraction)
+setmetatable(f2, metafraction)
+
+s = f1 + f2 -- appèle __add(f1, f2) de la métatable de f1
+
+-- f1, f2 ne possèdent pas de clé qui pointent vers leur métatable, comme
+-- avec les prototypes en JS. Mais l'on peut utiliser getmetatable(f1).
+-- La métatable est une table normale avec des clés prédéfinies, comme __add.
+
+-- Mais la ligne suivante génère une erreur puisque s n'a pas de métatable:
+-- t = s + s
+-- En implémentant de l'orienté objet, comme nous le verrons par la suite,
+-- le problème est résolu.
+
+-- Une clé __index dans une métatable mt surcharge l'indexation dans sa table t
+-- si la clé est absente de cette table t:
+defaultFavs = {animal = 'gru', food = 'donuts'}
+myFavs = {food = 'pizza'}
+setmetatable(myFavs, {__index = defaultFavs})
+eatenBy = myFavs.animal -- Affiche "gru"! merci à la métatable!
+
+-- Ainsi donc, un accès direct à une valeur dans une table via une clé
+-- inexistante (ce qui normalement retourne "nil") conduira à exploiter
+-- le champ __index de la métatable. Cela peut être récursif.
+
+-- Le champ __index peut aussi être une fonction (tbl, clé)
+-- ce qui permet une gestion plus souple des indexations.
+
+-- Les clés __index, __add,... sont appelées métaméthodes.
+-- En voici la liste complète:
+
+-- __add(a, b) pour a + b
+-- __sub(a, b) pour a - b
+-- __mul(a, b) pour a * b
+-- __div(a, b) pour a / b
+-- __mod(a, b) pour a % b
+-- __pow(a, b) pour a ^ b
+-- __unm(a) pour -a
+-- __concat(a, b) pour a .. b
+-- __len(a) pour #a
+-- __eq(a, b) pour a == b
+-- __lt(a, b) pour a < b
+-- __le(a, b) pour a <= b
+-- __index(a, b) <fn ou table> pour a.b
+-- __newindex(a, b, c) pour a.b = c
+-- __call(a, ...) pour a(...)
+
+----------------------------------------------------
+-- 3.2 Pseudo-orienté objet et héritage.
+----------------------------------------------------
+
+-- Lua n'implémente pas d'orienté objet par défaut.
+-- Mais il reste possible d'imiter de plusieurs manières
+-- le concept de "classe" grâce aux tables et aux métatables.
+
+-- L'explication pour l'exemple qui suit vient juste après.
+
+Dog = {} -- 1.
+
+function Dog:new() -- 2.
+ local newObj = {sound = 'woof'} -- 3.
+ self.__index = self -- 4.
+ return setmetatable(newObj, self) -- 5.
+end
+
+function Dog:makeSound() -- 6.
+ print('Je dis: ' .. self.sound..'!')
+end
+
+mrDog = Dog:new() -- 7.
+mrDog:makeSound() -- 'Je dis: woof! -- 8.
+
+-- 1. Dog agit comme une classe; c'est une simple table.
+-- 2. L'expression tbl:fn(...) est identique à
+-- tbl.fn(self, ...)
+-- La notation : permet de passer par défaut un premier
+-- argument appelé "self" à la fonction tbl.fn
+-- Voir 7 & 8 ci-après pour comprendre comment self prend
+-- sa valeur.
+-- 3. newObj sera une instance de la classe Dog.
+-- 4. self = la classe instanciée. Souvent, self = Dog, mais
+-- cela peut changer du fait de l'héritage.
+-- newObj reçoit les fonctions de self si l'__index des
+-- métatables de newObj et de self pointent vers self.
+-- 5. Rappel: setmetatable retourne son premier argument.
+-- 6. La notation : fonctionne comme au 2, mais cette fois, self
+-- est une instance au lieu d'être une classe.
+-- 7. Similaire à Dog.new(Dog), donc self = Dog dans new().
+-- 8. Similaire à mrDog.makeSound(mrDog); self = mrDog.
+
+----------------------------------------------------
+
+-- Exemple d'héritage:
+
+LoudDog = Dog:new() -- 1.
+
+function LoudDog:makeSound()
+ local s = self.sound .. ' ' -- 2.
+ print(s .. s .. s..'!')
+end
+
+seymour = LoudDog:new() -- 3.
+seymour:makeSound() -- 'woof woof woof!' -- 4.
+
+-- 1. LoudDog reçoit les méthodes et les variables de Dog.
+-- 2. self possède une clé 'sound', reçue de new(), voir 3.
+-- 3. Similaire à LoudDog.new(LoudDog) et traduit en Dog.new(LoudDog),
+-- puisque LoudDog ne possède pas de clé 'new', mais a une métatable
+-- qui a la clé __index = Dog.
+-- Résulat: la métatable de seymour est LoudDog, et
+-- LoudDog.__index = LoudDog. Donc seymour.key deviendra soit égal à
+-- seymour.key, LoudDog.key, Dog.key, selon le fait qu'il s'agira
+-- de la première table ayant la clé 'key' en question, en remontant
+-- dans la hiérarchie.
+-- 4. La clé 'makeSound' est trouvée dans LoudDog; cela est similaire
+-- à LoudDog.makeSound(seymour).
+
+-- Si besoin est, la méthode new() de la sous-classe est
+-- identique à la méthode new() de sa classe mère:
+function LoudDog:new()
+ local newObj = {}
+ -- Prépare self à être la superclasse de newObj:
+ self.__index = self
+ return setmetatable(newObj, self)
+end
+
+----------------------------------------------------
+-- 4. Modules.
+----------------------------------------------------
+
+
+--[[ Cette section est mise en commentaire afin que le reste du
+-- ce script reste exécutable.
+```
+
+```lua
+-- Supposons que le fichier mod.lua contienne ceci:
+local M = {}
+
+local function sayMyName()
+ print('Hrunkner')
+end
+
+function M.sayHello()
+ print('hello')
+ sayMyName()
+end
+
+return M
+
+-- Un autre fichier peut exploiter le contenu défini dans mod.lua's:
+local mod = require('mod') -- Exécute le fichier mod.lua.
+
+-- require est le moyen par défaut d'inclure des modules.
+-- require agit comme: (si non trouvé en cache; voir ci-après)
+local mod = (function ()
+ <contenu de mod.lua>
+end)()
+-- Comme si le contenu de mod.lua était enveloppé dans le corps d'une fonction,
+-- si bien que les variables locales contenues dans mod.lua sont
+-- inaccessibles en dehors de ce module.
+
+-- Le code suivant fonctionne car mod = M (dans mod.lua):
+mod.sayHello() -- Dis bonjour à Hrunkner.
+
+-- Le code suivant génère une erreur car sayMyName est local à mod.lua:
+mod.sayMyName() -- erreur!
+
+-- Les valeurs retournées par require sont mises en cache, ce qui fait
+-- qu'un module est toujours chargé une seule fois, même s'il est inclus
+-- avec require à plusieurs reprises.
+
+-- Supposons que mod2.lua contienne le code "print('Hi!')".
+local a = require('mod2') -- Affiche "Hi!"
+local b = require('mod2') -- N'affiche rien; et a = b.
+
+-- dofile est identique à require, sauf qu'il ne fait pas de mise en cache:
+dofile('mod2') --> Hi!
+dofile('mod2') --> Hi! (le code de mod2.lua est encore exécuté)
+
+-- loadfile charge le contenu d'un fichier, sans l'exécuter.
+f = loadfile('mod2') -- L'appel f() exécute le contenu de mod2.lua.
+
+-- loadstring est similaire à loadfile, mais pour les chaines de caractères.
+g = loadstring('print(343)') -- Retourne une fonction.
+g() -- Affiche 343; Rien n'est affiché avant cet appel.
+
+--]]
+
+```
+## Références
+
+*Les références qui suivent sont en Anglais.*
+
+Les sujets non abordés dans ce tutoriel sont couverts en intégralité par
+les librairies standard:
+
+* La librairie <a href="http://lua-users.org/wiki/StringLibraryTutorial">string</a>
+* La librairie <a href="http://lua-users.org/wiki/TableLibraryTutorial">table</a>
+* La librairie <a href="http://lua-users.org/wiki/MathLibraryTutorial">math</a>
+* La librairie <a href="http://lua-users.org/wiki/IoLibraryTutorial">io</a>
+* La librairie <a href="http://lua-users.org/wiki/OsLibraryTutorial">os</a>
+
+Autres références complémentaires:
+
+* <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">Lua for programmers</a>
+* <a href="lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Courte de référence de Lua</a>
+* <a href="http://www.lua.org/pil/contents.html">Programming In Lua</a>
+* <a href="http://www.lua.org/manual/">Les manuels de référence Lua</a>
+
+A propos, ce fichier est exécutable. Sauvegardez-le sous le nom *learn.lua* et
+exécutez-le avec la commande `lua learn.lua` !
+
+Ce tutoriel a été originalement écrit pour <a href="tylerneylon.com">tylerneylon.com</a> et est aussi
+disponible en tant que <a href="https://gist.github.com/tylerneylon/5853042">gist</a>.
+Il a été traduit en français par Roland Yonaba (voir son <a href="http://github.com/Yonaba">github</a>).
+
+Amusez-vous bien avec Lua! \ No newline at end of file
diff --git a/fr-fr/objective-c-fr.html.markdown b/fr-fr/objective-c-fr.html.markdown
new file mode 100644
index 00000000..b14b3a52
--- /dev/null
+++ b/fr-fr/objective-c-fr.html.markdown
@@ -0,0 +1,527 @@
+---
+
+language: Objective-C
+contributors:
+ - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
+translators:
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+filename: LearnObjectiveC.m
+
+---
+
+L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations Mac OS X et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch.
+
+```objective-c
+// Les commentaires sur une seule ligne commencent par //
+
+/*
+Les
+commentaires
+multi-lignes
+ressemblent
+ceci
+*/
+
+// #import permet d'importer les en-têtes d'autres fichiers
+// Utilisez <> pour importer des fichiers globaux (en général des frameworks)
+// Utilisez "" pour importer des fichiers locaux (du projet)
+#import <Foundation/Foundation.h>
+#import "MaClasse.h"
+
+// Si vous activez les modules dans les projets iOS >= 7 ou Mac OS X >= 10.9
+// dans Xcode 5, vous pouvez importer les frameworks comme cela :
+@import Foundation;
+
+// Le point d'entrée de votre programme est une fonction qui s'appelle main
+// et qui retourne un entier comme type
+int main (int argc, const char * argv[])
+{
+ // Créer un groupe de libération automatique de la mémoire pour l'ensemble
+ // du programme
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ // Si vous utilisez le comptage de référence automatique (ARC), utilisez
+ // @autoreleasepool à la place :
+ @autoreleasepool {
+
+ // NSLog() permet d'afficher une chaine de caractères dans la console
+ // Affiche la chaine de caractères "Bonjour Tous Le Monde !"
+ NSLog(@"Bonjour tous le Monde !");
+
+ ///////////////////////////////////////
+ // Les Types & Les Variables
+ ///////////////////////////////////////
+
+ // La déclaration de primitive
+ int maPrimitive1 = 1;
+ long maPrimitive2 = 234554664565;
+
+ // La déclaration d'objet
+ // Il faut mettre un astérisque devant la déclaration d'objet fortement typé
+ MaClasse *monObject1 = nil; // Typage fort
+ id monObject2 = nil; // Typage faible
+ // 'description' est une méthode qui permet de retourner un aperçut de l'objet sous forme textuelle
+ // La méthode 'description' est appelée par défaut quand on utilise le paramètre '%@'
+ NSLog(@"%@ and %@", monObject1, [monObject2 description]); // Affiche "(null) et (null)"
+
+ // Les chaines de caractères
+ NSString *chaineMonde = @"Monde";
+ NSLog(@"Bonjour tous le %@ !", chaineMonde); // affiche => "Bonjour Tous Le Monde !"
+ // NSMutableString est une chaine mutable
+ NSMutableString *chaineMutable = [NSMutableString stringWithString:@"Bonjour tous le"];
+ [chaineMutable appendString:@" Monde !"];
+ NSLog(@"%@", chaineMutable); // affiche => "Bonjour Tous Le Monde !"
+
+ // Les caractères
+ NSNumber *laLettreZSousFormeDeNombre = @'Z';
+ char laLettreZ = [laLettreZSousFormeDeNombre charValue]; // ou 'Z'
+ NSLog(@"%c", laLettreZ);
+
+ // Les nombres
+ NSNumber *nombreQuaranteDeux = @42;
+ int quaranteDeux = [nombreQuaranteDeux intValue]; // ou 42
+ NSLog(@"%i", quaranteDeux);
+
+ NSNumber *nombreQuaranteDeuxnonSigne = @42U;
+ unsigned int quaranteDeuxnonSigne = [nombreQuaranteDeuxnonSigne unsignedIntValue];
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *nombreQuaranteDeuxCourt = [NSNumber numberWithShort:42];
+ short quaranteDeuxCourt = [nombreQuaranteDeuxCourt shortValue]; // ou 42
+ NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *nombreQuaranteDeuxLong = @42L;
+ long quaranteDeuxLong = [nombreQuaranteDeuxLong longValue]; // ou 42
+ NSLog(@"%li", fortyTwoLong);
+
+ // Les nombres flottants
+ NSNumber *nombrePiFlottant = @3.141592654F;
+ float piFlottant = [nombrePiFlottant floatValue]; // ou 3.141592654f
+ NSLog(@"%f", piFlottant); // affiche => 3.141592654
+ NSLog(@"%5.2f", piFlottant); // affiche => " 3.14"
+
+ NSNumber *nombrePiDouble = @3.1415926535;
+ double piDouble = [nombrePiDouble doubleValue]; // ou 3.1415926535
+ NSLog(@"%f", piDouble);
+ NSLog(@"%4.2f", piDouble); // affiche => "3.14"
+
+ // NSDecimalNumber est une classe pour avoir plus de précision sur les nombres
+ // flottants et les doubles
+ NSDecimalNumber *decNumUn = [NSDecimalNumber decimalNumberWithString:@"10.99"];
+ NSDecimalNumber *decNumDeux = [NSDecimalNumber decimalNumberWithString:@"5.002"];
+ // NSDecimalNumber ne permet pas d'utiliser les opérations standards (+, -, *, /)
+ // Il faut utiliser les méthodes suivantes à la place :
+ [decNumUn decimalNumberByAdding:decNumDeux];
+ [decNumUn decimalNumberBySubtracting:decNumDeux];
+ [decNumUn decimalNumberByMultiplyingBy:decNumDeux];
+ [decNumUn decimalNumberByDividingBy:decNumDeux];
+ NSLog(@"%@", decNumUn); // affiche => 10.99 comme NSDecimalNumber est immuable
+
+ // Les booléens
+ NSNumber *ouiNumber = @YES;
+ NSNumber *nonNumber = @NO;
+ // ou
+ BOOL ouiBool = YES;
+ BOOL nonBool = NO;
+ NSLog(@"%i", ouiBool); // affiche => 1
+
+ // Les listes
+ // Une liste peut contenir uniquement des objets
+ NSArray *uneListe = @[@1, @2, @3, @4];
+ NSNumber *troisiemeNombre = uneListe[2];
+ NSLog(@"Troisième nombre = %@", troisiemeNombre); // affiche "Troisième nombre = 3"
+ // NSMutableArray est une version mutable de NSArray
+ // Cela permet de modifier la liste en ajoutant de nouveaux éléments et en supprimant ou
+ // changeant de place des objets déjà présent
+ // C'est très pratique, mais pas aussi performant que l'utilisation de la classe NSArray
+ NSMutableArray *listeMutable = [NSMutableArray arrayWithCapacity:2];
+ [listeMutable addObject:@"Bonjour tous le"];
+ [listeMutable addObject:@"Monde"];
+ [listeMutable removeObjectAtIndex:0];
+ NSLog(@"%@", [listeMutable objectAtIndex:0]); // affiche => "Monde"
+
+ // Les dictionnaires
+ // Un dictionnaire est un ensemble de clés : valeurs
+ NSDictionary *unDictionnaire = @{ @"cle1" : @"valeur1", @"cle2" : @"valeur2" };
+ NSObject *valeur = unDictionnaire[@"Une clé"];
+ NSLog(@"Objet = %@", valeur); // affiche "Objet = (null)"
+ // NSMutableDictionary est un dictionnaire mutable, c-à-d que l'on peut modifier
+ NSMutableDictionary *dictionnaireMutable = [NSMutableDictionary dictionaryWithCapacity:2];
+ [dictionnaireMutable setObject:@"valeur1" forKey:@"cle1"];
+ [dictionnaireMutable setObject:@"valeur2" forKey:@"cle2"];
+ [dictionnaireMutable removeObjectForKey:@"cle1"];
+
+ // Les ensembles
+ // Un ensemble ne peut contenir de duplicatas contrairement aux NSArray
+ NSSet *ensemble = [NSSet setWithObjects:@"Salut", @"Salut", @"Monde", nil];
+ NSLog(@"%@", ensemble); // affiche => {(Salut, Monde)} (Pas forcément dans le même ordre)
+ // NSMutableSet est un ensemble mutable
+ NSMutableSet *ensembleMutable = [NSMutableSet setWithCapacity:2];
+ [ensembleMutable addObject:@"Salut"];
+ [ensembleMutable addObject:@"Salut"];
+ NSLog(@"%@", ensembleMutable); // affiche => {(Salut)}
+
+ ///////////////////////////////////////
+ // Les Operateurs
+ ///////////////////////////////////////
+
+ // Les opérateurs sont pareil qu'en C
+ // Par exemple :
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (NO)
+ 3 != 2; // => 1 (YES)
+ 1 && 1; // => 1 (et logique)
+ 0 || 1; // => 1 (ou logique)
+ ~0x0F; // => 0xF0 (négation bit à bit)
+ 0x0F & 0xF0; // => 0x00 (et bit à bit)
+ 0x01 << 1; // => 0x02 (décalage à gauche (par 1))
+
+ ///////////////////////////////////////
+ // Les Structures de Contrôle
+ ///////////////////////////////////////
+
+ // Structure "Si-Sinon" (If-Else)
+ if (NO)
+ {
+ NSLog(@"Je ne suis jamais affiché");
+ } else if (0)
+ {
+ NSLog(@"Je ne suis jamais affiché aussi");
+ } else
+ {
+ NSLog(@"Je suis affiché");
+ }
+
+ // Structure "Selon" (Switch)
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"Je ne suis jamais affiché");
+ } break;
+ case 1:
+ {
+ NSLog(@"Je ne suis jamais affiché aussi");
+ } break;
+ default:
+ {
+ NSLog(@"Je suis affiché");
+ } break;
+ }
+
+ // Structure de boucle "Tant Que" (While)
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++ incrémente ii après avoir utilisé sa valeur
+ } // => affiche "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Structure de boucle "Pour" (For)
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj);
+ } // => affiche "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Structure de boucle "Pour Chaque" (Foreach)
+ NSArray *valeurs = @[@0, @1, @2, @3];
+ for (NSNumber *valeur in valeurs)
+ {
+ NSLog(@"%@,", valeur);
+ } // => affiche "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Structure "Essayer-Attraper-Finalement" (Try-Catch-Finally)
+ @try
+ {
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"Fichier non trouvé" userInfo:nil];
+ } @catch (NSException * e)
+ {
+ NSLog(@"Une exception est survenue : %@", e);
+ } @finally
+ {
+ NSLog(@"Finalement");
+ } // => affiche "Une exception est survenue : Fichier non trouvé"
+ // "Finalement"
+
+ ///////////////////////////////////////
+ // Les Objets
+ ///////////////////////////////////////
+
+ // Définis et créé une instance d'objet en allouant un espace mémoire puis en
+ // l'initialisant. Un objet n'est pas complétement fonctionnel tant que les deux
+ // étapes précédentes ne sont pas terminées
+ MaClass *monObjet = [[MaClass alloc] init];
+
+ // L'Objet en Objective-C est basé sur le principe d'envoie de message et non sur
+ // celui d'appel de méthode comme la plupart des autres langages
+ // C'est un détail important car cela veut dire que l'on peut envoyer un message
+ // à un objet qui ne possède pas la méthode demandée sans aucune incidence sur le
+ // fonctionnement du programme (aucune exception ne sera levée)
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Nettoie la mémoire qui a été utilisée dans le programme
+ [pool drain];
+
+ // Fin de l'@autoreleasepool
+ }
+
+ // Fin du programme
+ return 0;
+}
+
+///////////////////////////////////////
+// Les Classes et Les Fonctions
+///////////////////////////////////////
+
+// Déclaration d'une classe dans un en-tête de fichier (MaClasse.h) :
+// La déclaration d'une classe en Objective-C commence par la déclaration de son interface :
+// @interface NomDeLaClasse : NomDeLaClasseParent <ListeDesProtocoles>
+// {
+// type nom; // Déclaration d'une variable;
+// }
+// @property type nom; // Déclaration d'une propriété
+// -/+ (type)nomDeLaMethode; // Déclaration d'une methode
+// @end // Termine la déclaration
+// NSObject est la classe de base (super classe) en Objective-C
+@interface MaClasse : NSObject <MonProtocole>
+{
+ int nombre; // Accès protégé par défaut (équivalent à '@protected int nombre;')
+ @private id donnee; // Accès privé (il est plus pratique de le faire dans l'implémentation)
+ NSString *nom;
+}
+// Les propriétés permettent de générer les accésseurs/affecteurs publiques à la compilation
+// Par défaut, le nom de l'affecteur est la chaine 'set' suivi par le nom de la @property
+@property int propInt; // Nom de l'affecteur = 'setPropInt'
+@property (copy) id copyId; // (copy) => Copie l'objet pendant l'affectation
+// (readonly) => Ne peut pas affecté la variable en dehors de l'@interface
+// Il faut utiliser le mot clé '@synthesize' dans l'@implementation pour créer l'accésseur
+@property (readonly) NSString *roString;
+// Vous pouvez aussi personnaliser les noms des accésseurs ou des affecteurs
+@property (getter=longeurGet, setter=longeurSet:) int longeur;
+
+// Methodes
++/- (TypeDeRetour)signatureDeLaMethode:(TypeDuParametre *)nomDuParametre;
+
+// '+' signifie que c'est une méthode de classe (statique) :
++ (NSString *)methodeDeClasse;
++ (MaClasse *)maClasseDepuisLaHauteur:(NSNumber *)hauteurParDefaut;
+
+// '-' pour les méthodes d'instances :
+- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string;
+- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number;
+
+// Contructeur avec des arguments :
+- (id)initAvecDistance:(int)distanceParDefault;
+// Les méthodes en Objective-C sont très descriptives
+
+@end // Fin de l'interface
+
+
+// Voici un exemple d'utilisation de MaClasse
+MaClasse *maClasse = [[MaClasse alloc] init]; // créer une instance de MaClasse
+[maClasse setNombre:10];
+NSLog(@"%d", [maClasse nombre]); // affiche => 10
+[myClass longeurSet:32];
+NSLog(@"%i", [maClasse longeurGet]); // affiche => 32
+// Pour des raisons pratiques vous pouvez aussi utiliser la notation en point pour accéder aux
+// variables d'instances :
+maClasse.nombre = 45;
+NSLog(@"%i", maClasse.nombre); // maClasse => 45
+
+// Pour appeler une méthode de classe :
+NSString *s1 = [MaClasse methodeDeClasse];
+MaClasse *m2 = [MaClasse maClasseDepuisLaHauteur:38];
+
+// Pour appeler une méthode d'instance :
+MaClasse *maClasse = [[MaClasse alloc] init]; // Créer une instance de MaClasse
+NSString *stringDepuisUneInstanceDeMethode = [maClasse methodeInstanceAvecUnParametre:@"Salut"];
+
+// Les sélecteurs sont un moyen de décrire les méthodes dynamiquement
+// Ils sont utilisés pour appeler des méthodes de classe et avoir des pointeurs de fonctions
+// facilement manipulable
+// SEL est un type de donnée et @selector retourne un selecteur à partir d'un nom de methode
+SEL selecteur = @selector(methodeInstanceAvecUnParametre:puisUnDeuxieme:);
+if ([maClasse respondsToSelector:selecteur]) { // Vérifie si la classe possède la méthode
+ // Met les arguments de la méthode dans un seul objet pour l'envoyer via la fonction
+ // performSelector:withObject:
+ NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
+ [myClass performSelector:selectorVar withObject:arguments]; // Appele la méthode via le sélecteur
+}
+else {
+ // NSStringFromSelector() retourne une chaine de caractères à partir d'un sélecteur
+ NSLog(@"MaClasse ne possède pas de méthode : %@", NSStringFromSelector(selecteur));
+}
+
+// Le fichier d'implémentation de la classe MaClasse (MaClasse.m) doit commencer comme ceci :
+@implementation MaClasse {
+ long distance; // Variable d'instance privée (équivalent à @private dans l'interface)
+ NSNumber hauteur;
+}
+
+// Pour accéder à une variable depuis l'implémentation on peut utiliser le _ (tiret bas) devant le nom
+// de la variable :
+_nombre = 5;
+// Accès d'une variable définie dans le fichier d'implémentation :
+distance = 18;
+// Pour utiliser la variable définie par l'intermédiaire de @property, il faut utiliser @synthesize
+// qui permet de créer les affecteurs et les accésseurs correspondants :
+@synthesize roString = _roString; // _roString est maintenant disponible dans l'implementation
+
+// A l'inverse dela méthode 'init' qui est appelée lors de la création d'un objet, la fonction
+// 'dealloc' est appelée quand l'objet est supprimé
+- (void)dealloc
+{
+ [hauteur release]; // Si vous n'utilisez pas ARC, pensez bien à supprimer l'objet
+ [super dealloc]; // et à appeler la méthode 'dealloc' de la classe parent
+}
+
+// Les constructeurs sont des fonctions qui permettent d'instancier un objet
+// 'init' est le constructeur par défaut en Objective-C
+- (id)init
+{
+ if ((self = [super init])) // 'super' est utilisé pour appeler la méthode de la classe parent
+ {
+ self.count = 1; // 'self' permet d'appeler la méthode de l'instance courante
+ }
+ return self;
+}
+
+// Vous pouvez aussi créer des constructeurs avec des arguments
+// Attention : chaque nom de constructeur doit absolument commencer par 'init'
+- (id)initAvecUneDistance:(int)distanceParDefault
+{
+ if ((self = [super init]))
+ {
+ distance = distanceParDefault;
+ return self;
+ }
+}
+
+// Implémentation d'une méthode de classe
++ (NSString *)methodDeClasse
+{
+ return [[self alloc] init];
+}
+
++ (MaClasse *)maClasseDepuisUneHauteur:(NSNumber *)hauteurParDefaut
+{
+ hauteur = hauteurParDefaut;
+ return [[self alloc] init];
+}
+
+// Implémentation d'une méthode d'instance
+- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string
+{
+ return @"Ma chaine de caractère";
+}
+
+- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number
+{
+ return @42;
+}
+
+// Pour créer une méthode privée, il faut la définir dans l'implementation et non pas dans
+// l'interface
+- (NSNumber *)methodePrivee
+{
+ return @72;
+}
+
+[self methodePrivee]; // Appel de la méthode privée
+
+// Implémentation d'une méthode qui est déclarée dans <MonProtocole>
+- (void)methodeDuProtocole
+{
+ // expressions
+}
+
+@end // Fin de l'implémentation
+
+/*
+ * Un protocole déclare des méthodes et propriétés que chaque implémentation doit avoir afin de se
+ * conformer à celui-ci
+ * Un protocole n'est pas une classe, c'est juste une interface
+ */
+@protocol MonProtocole
+ - (void)methodeDuProtocole;
+@end
+
+
+///////////////////////////////////////
+// Gestion de la mémoire
+///////////////////////////////////////
+/*
+À chaque fois qu'un objet est créé dans l'application, un bloc mémoire doit être alloué.
+Quand l'application en a fini avec cet objet, la mémoire doit être libérée afin d'éviter les fuites
+mémoires
+Il n'y a pas de ramasse-miettes en Objective-C contrairement à Java par exemple. La gestion de la
+mémoire repose sur le comptage de référence qui, pour chaque objet, assigne un compteur qui permet
+de connaitre le nombre de référence qui l'utilise.
+
+Le principe est le suivant :
+Lorsque l'objet est créé, le compteur est initialisé à 1. Quand une instance détient un objet, le
+compteur est incrémenté de un. Quand l'objet est libéré, le compteur est décrémenté de un. Au moment
+où le compteur arrive à zéro, l'objet est supprimé de la mémoire
+
+Une bonne pratique à suivre quand on travaille avec des objets est la suivante :
+(1) créer un objet, (2) utiliser l'objet, (3) supprimer l'objet de la mémoire
+*/
+
+MaClasse *classeVar = [MyClass alloc]; // 'alloc' incrémente le compteur de référence
+[classeVar release]; // Décrémente le compteur de rérence
+// 'retain' incrémente le compteur de référence
+// Si 'classeVar' est libéré, l'objet reste en mémoire car le compteur de référence est non nul
+MaClasse *nouvelleVar = [classVar retain];
+[classeVar autorelease]; // Supprime l'appartenance de l'objet à la fin du bloc
+
+// Les @property peuvent utiliser 'retain' et 'assign'
+@property (retain) MaClasse *instance; // Libère l'ancienne valeur et retient la nouvelle
+@property (assign) NSSet *set; // Pointeur vers la valeur sans retenir/libérer l'ancienne valeur
+
+// Automatic Reference Counting (ARC)
+// La gestion de la mémoire étant pénible, depuis iOS 4 et Xcode 4.2, Apple a introduit le comptage de
+// référence automatique (Automatic Reference Counting en anglais)
+// ARC est une fonctionnalité du compilateur qui permet d'ajouter les 'retain', 'release' et 'autorelease'
+// automatiquement. Cela veut dire que lorsque vous utilisez ARC vous ne devez plus utiliser ces mot-clés
+MaClasse *arcMaClasse = [[MaClasse alloc] init];
+// ... code utilisant arcMaClasse
+// Sans ARC, vous auriez dû appeler [arcMaClasse release] après avoir utilisé l'objet. Mais avec ARC
+// activé il n'est plus nécessaire de le faire car le compilateur ajoutera l'expréssion automatiquement
+// pour vous
+
+// Les mots clés 'assign' et 'retain', avec ARC sont respectivement remplacé par 'weak' et 'strong'
+@property (weak) MaClasse *weakVar; // 'weak' ne retient pas l'objet. Si le compteur de référence
+// descend à zero, weakVar sera automatiquement mis à nil
+@property (strong) MaClasse *strongVar; // 'strong' prend possession de l'objet comme le ferait avec
+// le mot-clé 'retain'
+
+// Pour l'instanciation des variables (en dehors de @property), vous pouvez utiliser les instructions
+// suivantes :
+__strong NSString *strongString; // Par défaut. La variable est retenue en mémoire jusqu'à la fin
+// de sa portée
+__weak NSSet *weakSet; // Maintient une référence vers l'objet sans incrémenter son compteur de référence :
+// Lorsque l'objet sera supprimé, weakSet sera mis à nil automatiquement
+__unsafe_unretained NSArray *unsafeArray; // Comme __weak, mais la variable n'est pas mis à nil quand
+// l'objet est supprimé
+
+```
+## Lectures Complémentaires
+
+[La Page Wikipedia de l'Objective-C](http://fr.wikipedia.org/wiki/Objective-C)
+
+[iOS pour les écoliers : Votre première app iOS](http://www.raywenderlich.com/fr/39272/ios-pour-les-ecoliers-votre-premiere-app-ios-partie-12)
+
+[Programming with Objective-C. Apple PDF book](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf) \ No newline at end of file
diff --git a/hy.html.markdown b/hy.html.markdown
new file mode 100644
index 00000000..04bd05c9
--- /dev/null
+++ b/hy.html.markdown
@@ -0,0 +1,174 @@
+---
+language: hy
+filename: learnhy.hy
+contributors:
+ - ["Abhishek L", "http://twitter.com/abhishekl"]
+---
+
+Hy is a lisp dialect built on top of python. This is achieved by
+converting hy code to python's abstract syntax tree (ast). This allows
+hy to call native python code or python to call native hy code as well
+
+This tutorial works for hy ≥ 0.9.12
+
+```clojure
+;; this gives an gentle introduction to hy for a quick trial head to
+;; http://try-hy.appspot.com
+;;
+; Semicolon comments, like other LISPS
+
+;; s-expression basics
+; lisp programs are made of symbolic expressions or sexps which
+; resemble
+(some-function args)
+; now the quintessential hello world
+(print "hello world")
+
+;; simple data types
+; All simple data types are exactly similar to their python counterparts
+; which
+42 ; => 42
+3.14 ; => 3.14
+True ; => True
+4+10j ; => (4+10j) a complex number
+
+; lets start with some really simple arithmetic
+(+ 4 1) ;=> 5
+; the operator is applied to all arguments, like other lisps
+(+ 4 1 2 3) ;=> 10
+(- 2 1) ;=> 1
+(* 4 2) ;=> 8
+(/ 4 1) ;=> 4
+(% 4 2) ;=> 0 the modulo operator
+; power is represented by ** operator like python
+(** 3 2) ;=> 9
+; nesting forms will do the expected thing
+(+ 2 (* 4 2)) ;=> 10
+; also logical operators and or not and equal to etc. do as expected
+(= 5 4) ;=> False
+(not (= 5 4)) ;=> True
+
+;; variables
+; variables are set using setv, variable names can use utf-8 except
+; for ()[]{}",'`;#|
+(setv a 42)
+(setv π 3.14159)
+(def *foo* 42)
+;; other container data types
+; strings, lists, tuples & dicts
+; these are exactly same as python's container types
+"hello world" ;=> "hello world"
+; string operations work similar to python
+(+ "hello " "world") ;=> "hello world"
+; lists are created using [], indexing starts at 0
+(setv mylist [1 2 3 4])
+; tuples are immutable data structures
+(setv mytuple (, 1 2))
+; dictionaries are key value pairs
+(setv dict1 {"key1" 42 "key2" 21})
+; :name can be used to define keywords in hy which can be used for keys
+(setv dict2 {:key1 41 :key2 20})
+; use `get' to get the element at an index/key
+(get mylist 1) ;=> 2
+(get dict1 "key1") ;=> 42
+; Alternatively if keywords were used they can directly be called
+(:key1 dict2) ;=> 41
+
+;; functions and other program constructs
+; functions are defined using defn, the last sexp is returned by default
+(defn greet [name]
+ "A simple greeting" ; an optional docstring
+ (print "hello " name))
+
+(greet "bilbo") ;=> "hello bilbo"
+
+; functions can take optional arguments as well as keyword arguments
+(defn foolist [arg1 &optional [arg2 2]]
+ [arg1 arg2])
+
+(foolists 3) ;=> [3 2]
+(foolists 10 3) ;=> [10 3]
+
+; anonymous functions are created using `fn' or `lambda' constructs
+; which are similiar to `defn'
+(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
+
+;; Sequence operations
+; hy has some builtin utils for sequence operations etc.
+; retrieve the first element using `first' or `car'
+(setv mylist [1 2 3 4])
+(setv mydict {"a" 1 "b" 2})
+(first mylist) ;=> 1
+
+; slice lists using slice
+(slice mylist 1 3) ;=> [2 3]
+
+; get elements from a list or dict using `get'
+(get mylist 1) ;=> 2
+(get mydict "b") ;=> 2
+; list indexing starts from 0 same as python
+; assoc can set elements at keys/indexes
+(assoc mylist 2 10) ; makes mylist [1 2 10 4]
+(assoc mydict "c" 3) ; makes mydict {"a" 1 "b" 2 "c" 3}
+; there are a whole lot of other core functions which makes working with
+; sequences fun
+
+;; Python interop
+;; import works just like in python
+(import datetime)
+(import [functools [partial reduce]]) ; imports fun1 and fun2 from module1
+(import [matplotlib.pyplot :as plt]) ; doing an import foo as bar
+; all builtin python methods etc. are accessible from hy
+; a.foo(arg) is called as (.foo a arg)
+(.split (.strip "hello world ")) ;=> ["hello" "world"]
+
+;; Conditionals
+; (if condition (body-if-true) (body-if-false)
+(if (= passcode "moria")
+ (print "welcome")
+ (print "Speak friend, and Enter!"))
+
+; nest multiple if else if clauses with cond
+(cond
+ [(= someval 42)
+ (print "Life, universe and everything else!")]
+ [(> someval 42)
+ (print "val too large")]
+ [(< someval 42)
+ (print "val too small")])
+
+; group statements with do, these are executed sequentially
+; forms like defn have an implicit do
+(do
+ (setv someval 10)
+ (print "someval is set to " someval)) ;=> 10
+
+; create lexical bindings with `let', all variables defined thusly
+; have local scope
+(let [[nemesis {"superman" "lex luther"
+ "sherlock" "moriarty"
+ "seinfeld" "newman"}]]
+ (for [(, h v) (.items nemesis)]
+ (print (.format "{0}'s nemesis was {1}" h v))))
+
+;; classes
+; classes are defined in the following way
+(defclass Wizard [object]
+ [[--init-- (fn [self spell]
+ (setv self.spell spell) ; init the spell attr
+ None)]
+ [get-spell (fn [self]
+ self.spell)]])
+
+;; do checkout hylang.org
+```
+
+### Further Reading
+
+This tutorial is just a very basic introduction to hy/lisp/python.
+
+Hy docs are here: [http://hy.readthedocs.org](http://hy.readthedocs.org)
+
+Hy's Github repo: [http://github.com/hylang/hy](http://github.com/hylang/hy)
+
+On freenode irc #hy, twitter hashtag #hylang
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 7fb7ba55..85c5d817 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -5,7 +5,7 @@ contributors:
filename: javascript.js
---
-Javascript was created by Netscape's Brendan Eich in 1995. It was originally
+JavaScript was created by Netscape's Brendan Eich in 1995. It was originally
intended as a simpler scripting language for websites, complimenting the use of
Java for more complex web applications, but its tight integration with Web pages
and built-in support in browsers has caused it to become far more common than
@@ -37,7 +37,7 @@ doStuff()
///////////////////////////////////
// 1. Numbers, Strings and Operators
-// Javascript has one number type (which is a 64-bit IEEE 754 double).
+// JavaScript has one number type (which is a 64-bit IEEE 754 double).
// As with Lua, don't freak out about the lack of ints: doubles have a 52-bit
// mantissa, which is enough to store integers up to about 9✕10¹⁵ precisely.
3; // = 3
@@ -116,7 +116,7 @@ undefined; // used to indicate a value is not currently present (although
///////////////////////////////////
// 2. Variables, Arrays and Objects
-// Variables are declared with the var keyword. Javascript is dynamically typed,
+// Variables are declared with the var keyword. JavaScript is dynamically typed,
// so you don't need to specify type. Assignment uses a single = character.
var someVar = 5;
@@ -175,14 +175,14 @@ myObj.myFourthKey; // = undefined
var count = 1;
if (count == 3){
// evaluated if count is 3
-} else if (count == 4) {
+} else if (count == 4){
// evaluated if count is 4
} else {
// evaluated if it's not either 3 or 4
}
// As does while.
-while (true) {
+while (true){
// An infinite loop!
}
@@ -327,7 +327,7 @@ var anotherFunc = function(s){
}
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
-// The 'apply' function is nearly identical, but takes an array for an argument list.
+// The 'apply' function is nearly identical, but takes an array for an argument list.
anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
@@ -477,7 +477,7 @@ more about how to use JavaScript in web pages, start by learning about the
[Document Object
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
-[Javascript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
+[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
guide of all the counter-intuitive parts of the language.
In addition to direct contributors to this article, some content is adapted
diff --git a/julia.html.markdown b/julia.html.markdown
index 4b946d46..3bc660cf 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -427,7 +427,7 @@ end
keyword_args(name2="ness") #=> ["name2"=>"ness","k1"=>4]
keyword_args(k1="mine") #=> ["k1"=>"mine","name2"=>"hello"]
-keyword_args() #=> ["name2"=>"hello","k2"=>4]
+keyword_args() #=> ["name2"=>"hello","k1"=>4]
# You can combine all kinds of arguments in the same function
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
@@ -560,7 +560,7 @@ type Panther <: Cat # Panther is also a subtype of Cat
Panther() = new("green")
# Panthers will only have this constructor, and no default constructor.
end
-# Using inner constructors, like Panter does, gives you control
+# Using inner constructors, like Panther does, gives you control
# over how values of the type can be created.
# When possible, you should use outer constructors rather than inner ones.
@@ -657,6 +657,83 @@ fight(Lion("RAR"),Lion("brown","rarrr")) #=> prints The victorious cat says rarr
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
fight(Lion("RAR"),Lion("brown","rarrr")) #=> prints The lions come to a tie
+
+# Under the hood
+# You can take a look at the llvm and the assembly code generated.
+
+square_area(l) = l * l # square_area (generic function with 1 method)
+
+square_area(5) #25
+
+# What happens when we feed square_area an integer?
+code_native(square_area, (Int32,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1 # Prologue
+ # push RBP
+ # mov RBP, RSP
+ # Source line: 1
+ # movsxd RAX, EDI # Fetch l from memory?
+ # imul RAX, RAX # Square l and store the result in RAX
+ # pop RBP # Restore old base pointer
+ # ret # Result will still be in RAX
+
+code_native(square_area, (Float32,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1
+ # push RBP
+ # mov RBP, RSP
+ # Source line: 1
+ # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
+ # pop RBP
+ # ret
+
+code_native(square_area, (Float64,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1
+ # push RBP
+ # mov RBP, RSP
+ # Source line: 1
+ # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
+ # pop RBP
+ # ret
+ #
+# Note that julia will use floating point instructions if any of the
+# arguements are floats.
+# Let's calculate the area of a circle
+circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
+circle_area(5) # 78.53981633974483
+
+code_native(circle_area, (Int32,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1
+ # push RBP
+ # mov RBP, RSP
+ # Source line: 1
+ # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
+ # movabs RAX, 4593140240 # Load pi
+ # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
+ # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
+ # pop RBP
+ # ret
+ #
+
+code_native(circle_area, (Float64,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1
+ # push RBP
+ # mov RBP, RSP
+ # movabs RAX, 4593140496
+ # Source line: 1
+ # vmulsd XMM1, XMM0, QWORD PTR [RAX]
+ # vmulsd XMM0, XMM1, XMM0
+ # pop RBP
+ # ret
+ #
```
## Further Reading
diff --git a/ko-kr/go-kr.html.markdown b/ko-kr/go-kr.html.markdown
new file mode 100644
index 00000000..7404572c
--- /dev/null
+++ b/ko-kr/go-kr.html.markdown
@@ -0,0 +1,314 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+translators:
+ - ["Jongmin Kim", "http://github.com/atomaths"]
+lang: ko-kr
+---
+
+Go는 어떤 일을 잘 끝낼 수 있도록 하기위해 만들어졌다. Go가 잘 알려진 최신의
+트렌드는 아니지만, 실세계의 문제들을 해결하기 위해서는 가장
+새롭고 빠른 방법이다.
+
+Go는 정적 타이핑(static typing)의 명령형 언어들(imperative languages)이
+갖고 있는 특징과 유사한 개념들을 가지고 있다. Go는 컴파일과 실행속도가
+빠르며, 오늘날의 멀티코어 CPU를 위해 이해하기 쉬운 동시성(concurrency)
+기능이 추가되었다. 그리고 큰 스케일의 프로그래밍에도 도움이 되는
+기능들을 가지고 있다.
+
+또한 Go에는 훌륭한 표준 라이브러리와 열정적인 커뮤니티가 있다.
+
+```go
+// 한 줄 주석
+/* 여러 줄
+ 주석 */
+
+// 모든 Go 소스 파일은 package로 시작한다.
+// 패키지 이름 중 main은 라이브러리가 아닌 실행파일을 선언하는 특별한 이름이다.
+package main
+
+// import는 이 Go 소스 파일 내에서 참조하는 라이브러리 패키지들을 선언한다.
+import (
+ "fmt" // Go 표준 라이브러리에 있는 패키지
+ "net/http" // 표준 라이브러리에는 웹 서버 패키지도 있다! (클라이언트도 있음)
+ "strconv" // 문자열 변환 패키지
+)
+
+// 함수 선언. main은 실행 프로그램에서 시작점이 되는 특별한 함수다.
+// 중괄호를 사용한다.
+func main() {
+ // Println은 표준 출력으로 개행을 출력한다.
+ // fmt 패키지를 통해 이용할 수 있다.
+ fmt.Println("Hello world!")
+
+ // 다른 함수를 호출한다.
+ beyondHello()
+}
+
+// 함수에 파라미터가 없더라도 빈 괄호는 있어야 한다.
+func beyondHello() {
+ var x int // 변수 선언. 변수는 사용하기 전에 선언해야 한다.
+ x = 3 // 변수에 값 할당.
+ // 짧은 선언(short declaration)으로 := 를 사용하는데,
+ // 이렇게 값을 할당하면 값의 타입에 따라 변수의 타입이 결정된다.
+ y := 4
+ sum, prod := learnMultiple(x, y) // 함수는 두 개 이상의 리턴 값을 줄 수 있다.
+ fmt.Println("sum:", sum, "prod:", prod) // 간단한 출력
+ learnTypes() // 잠시 후에 좀더 자세히!
+}
+
+// 함수는 파라미터들을 가질 수 있고, 복수개의 값을 리턴할 수 있다.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // 두 개의 값을 리턴.
+}
+
+// 내장 타입과 리터럴
+func learnTypes() {
+ // 짧은 선언은 유용하다.
+ s := "Learn Go!" // string 타입
+
+ s2 := `역따옴표 안의 string 리터럴은
+개행을 포함할 수 있다.` // 같은 string 타입
+
+ // non-ASCII 리터럴. Go 소스는 UTF-8로 작성해야 한다.
+ g := 'Σ' // 유니코드 코드 포인트를 담고 있고, uint32 타입의 가칭(alias)인 rune 타입
+
+ f := 3.14195 // float64, an IEEE-754 64-bit 부동소수 타입
+ c := 3 + 4i // complex128, 내부적으로는 두 개의 float64 타입으로 표현됨
+
+ // 초기값과 함께 사용하는 var 키워드.
+ var u uint = 7 // unsigned, 하지만 int에 따른 구현의존적인 크기
+ var pi float32 = 22. / 7
+
+ // 짧은 선언으로 변환(conversion)하는 문법.
+ // Go에서는 type casting 이라고 하지않고 type conversion 이라고 함.
+ n := byte('\n') // byte는 uint8의 가칭(alias)
+
+ // 배열은 컴파일 시에 크기가 정해진다.
+ var a4 [4]int // 모두 0으로 초기화되는 int 타입 4개짜리 배열
+ a3 := [...]int{3, 1, 5} // 3, 1, 5로 초기화되는 int 타입 3개짜리 배열
+
+ // 슬라이스(slice)라고 하는 타입은 배열에 대한 가변 크기를 가진다.
+ // 배열, 슬라이스 각자 장점이 있지만, 슬라이스가 더 많이 사용된다.
+ s3 := []int{4, 5, 9} // 위의 a3와 비교해보면 생략부호(...)가 없다.
+ s4 := make([]int, 4) // 모두 0으로 초기화되는 int 4개에 대한 슬라이스를 할당.
+ var d2 [][]float64 // 여기에서는 선언만 있고 할당은 없다.
+ bs := []byte("a slice") // string 타입을 byte 슬라이스 타입으로 형변환(type conversion)
+
+ p, q := learnMemory() // int에 대한 포인터 타입인 p와 q를 선언
+ fmt.Println(*p, *q) // C에서처럼 *는 포인터를 따라가 값을 참조한다. 여기서는 두 개의 int를 출력.
+
+ // 맵(map)은 다른 언어의 해시(hash)나 딕셔너리(dictionary)처럼 가변의 연관배열 타입.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // 선언만 하고 사용하지 않는 변수가 있다면 Go에서는 컴파일 시 에러가 난다.
+ // 언더바를 이용해서 변수를 사용한 것처럼 하고 그 값은 무시해버릴 수 있다.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // 물론 출력을 하면 변수로 취급한다.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // 잠시 후에 다시 나옴
+}
+
+// Go는 가비지 컬렉션 기능을 JVM 같은 곳이 아닌 실행파일 런타임에 포함하고 있다.
+// 그리고 포인터는 있지만, 포인터 연산(*p++ 같은)은 없다.
+// 그래서 nil 포인터 접근같은 것 때문에 실수를 할 수는 있지만
+// 포인터 연산으로 인한 실수는 없게 된다.
+func learnMemory() (p, q *int) {
+ // 지명된 리턴 값(named return value)인 p와 q는 int에 대한 포인터 타입이다.
+ p = new(int) // 내장함수인 new는 메모리를 할당해준다.
+ // 메모리 할당된 int는 0으로 초기화 되고, p는 이제 nil이 아니다.
+ s := make([]int, 20) // 메모리의 단일 블록으로 20개의 int 공간을 할당한다.
+ s[3] = 7 // 그중 하나에 값을 준다.
+ r := -2 // 또다른 로컬 변수를 선언한다.
+ return &s[3], &r // &는 어떤 대상체의 메모리 주소를 가져오게 된다.
+}
+
+func expensiveComputation() int {
+ return 1e6
+}
+
+func learnFlowControl() {
+ // if문에 중괄호는 필요하지만, 조건이 들어갈 곳에 소괄호는 쓰지 않는다.
+ if true {
+ fmt.Println("told ya")
+ }
+ // 모든 Go 소스의 코드 포맷팅은 "go fmt" 커맨드라인 명령으로 소스코드의 포맷을 맞춘다.
+ if false {
+ // pout
+ } else {
+ // gloat
+ }
+ // if-else 체인 형태보다 switch 사용이 권장된다.
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // case 안에서는 break가 없어도 자동으로 다음 case로 내려가지 않는다.
+ // 자동으로 내려가게 하려면 fallthrough 키워드를 사용한다.
+ case 2:
+ // x는 1이므로 여기는 실행되지 않음.
+ }
+ // if 에서처럼 for 에서도 양쪽에 소괄호를 쓰지 않는다.
+ for x := 0; x < 3; x++ { // ++ 은 실행을 제어하는 하나의 구문(statement)이다.
+ fmt.Println("iteration", x)
+ }
+ // 여기서 x는 1이다. 위 for에서 x는 for 안의 블록 범위에 있기 때문.
+
+ // For is the only loop statement in Go, but it has alternate forms.
+ // for 는 Go에서 유일한 루프 구문이지만 다양한 형태로 조건을 주거나 while
+ // 처럼 쓸 수도 있다.
+ for { // 무한루프
+ break // 여기서 곧바로 break를 한 건 단지
+ continue // break, continue를 루프 안에서 쓸 수 있다는 것을 보여주기 위함.
+ }
+ // for 에서처럼 if 에서 := 를 사용하는것은 y에 먼저 값을 대입하고,
+ // 그리고 y > x를 검사한다는 의미.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // 함수 리터럴은 클로저다.
+ xBig := func() bool {
+ return x > 100 // 위 switch 문 바로 위에 있는 x를 참조한다.
+ }
+ fmt.Println("xBig:", xBig()) // true (x에 1e6를 대입했었다.)
+ x /= 1e5 // x는 10이 된다.
+ fmt.Println("xBig:", xBig()) // 이제 xBig()의 결과는 false가 된다.
+
+ // `goto`가 필요하다면, 좋아하게 될지도...
+ goto love
+love:
+
+ learnInterfaces() // 곧이어서 좋은 기능에 대한 설명이 나올 거다.
+}
+
+// String 이라는 메서드 하나를 가진 Stringer 라는 인터페이스 타입을 정의하자.
+type Stringer interface {
+ String() string
+}
+
+// x와 y라는 이름의 int 타입 필드를 가진 pair라는 struct를 정의하자.
+type pair struct {
+ x, y int
+}
+
+// pair 타입에 메서드 String을 정의하자.
+// 이제 pair는 Stringer 인터페이스를 구현(implement)한 것이 되었다.
+func (p pair) String() string { // 여기서 p는 리시버(receiver)라고 부른다.
+ // Sprintf는 fmt 패키지 안에 있는 외부로 공개된(exported) 함수다.
+ // 점(.)으로 p의 필드들을 참조할 수 있다.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // 중괄호 문법은 "구조체 리터럴(struct literal)"인데, 초기화된 구조체로
+ // 취급하게 해준다. := 문법으로 p를 이 구조체로 선언하고 초기화한다.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // 타입 pair인 p의 String 메서드를 호출.
+ var i Stringer // Stringer 인터페이스 타입 i를 선언.
+ i = p // pair는 Stringer를 구현했기 때문에 이 대입은 유효하다.
+ // 타입 Stringer인 i의 String 메서드 호출. 결과는 위와 같다.
+ fmt.Println(i.String())
+
+ // fmt 패키지의 함수들을 통해 어떤 객체를 출력해보려고 할 때,
+ // fmt 패키지 내에서는 그 객체가 가진 String 메서드를 호출하도록 되어 있다.
+ fmt.Println(p) // 결과는 위와 같다. Println은 String 메서드를 호출한다.
+ fmt.Println(i) // 결과는 위와 같다.
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" (comma okay)표현은 무언가가 맞는 것인지 아닌지 확인하는데 사용된다.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // 이 map 안에 키가 1인 것은 없으므로 ok는 false가 된다.
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // 만일 1이 map에 있었다면 x는 키 1의 값이 들어가게 된다.
+ }
+
+ // Go에서는 함수가 복수 개의 리턴 값을 줄 수 있다는 점을 활용해 함수의 두 번째 리턴
+ // 값으로 error를 리턴해주고 그 error가 nil 인지 아닌지 확인하는 관례가 있다.
+ // 이때 이 error 값은 단지 위에서처럼 함수의 결과가 성공했는지 실패했는지를 확인하는
+ // 것뿐만 아니라 실패 시 어떤 문제가 있었는지 확인할 수 있는 수단도 된다.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ 는 값을 안 쓰고 버린다는 의미.
+ // "strconv.ParseInt: parsing "non-int": invalid syntax" 이런 에러가 출력된다.
+ fmt.Println(err)
+ }
+ // 인터페이스에 대해 잠시 후에 다시 잠깐 볼 것이다.
+ learnConcurrency()
+}
+
+// c는 goroutine 간의 통신을 위한 채널(channel)이다.
+func inc(i int, c chan int) {
+ c <- i + 1 // 채널이 <- 이 연산자 왼쪽에 온다면 그 채널로 데이터를 보낸다는 의미다.
+}
+
+// 우리는 어떤 숫자들을 동시에 증가시키기 위해 inc 함수를 사용할 것이다.
+func learnConcurrency() {
+ // make는 slice, map, channel 타입들에 대해 메모리를 할당하고 초기화를 한다.
+ // Go에는 메모리 할당 방법으로 new와 make가 있다.
+ c := make(chan int)
+ // 3개의 동시에 실행되는 goroutine를 시작한다. 만약 실행하고 있는 머신이
+ // 멀티코어 CPU를 가지고 있고 올바르게 설정되어(GOMAXPROCS) 있다면
+ // 숫자가 정말로 병렬적으로 증가하게 될 것이다.
+ go inc(0, c) // go는 새로운 goroutine을 시작하는 구문이다.
+ go inc(10, c)
+ go inc(-805, c)
+ // 채널로부터 3개의 결과를 읽어 출력한다.
+ // 결과가 어떤 순서로 오는지는 알 수 없다.
+ fmt.Println(<-c, <-c, <-c) // 채널이 <- 연산자 오른쪽에 있는 건, 채널로부터 데이터를 받는 연산이다.
+
+ cs := make(chan string) // string을 다루는 또 다른 채널
+ cc := make(chan chan string) // string 채널의 채널
+ go func() { c <- 84 }() // c 채널로 값을 보내는 goroutine 시작.
+ go func() { cs <- "wordy" }() // cs 채널로 값을 보내느 goroutine 시작.
+ // select 구문은 switch 문과 비슷하지만, case에서 채널 연산에 관한 일을 한다.
+ // select의 case들은 채널통신을 할 준비가 된 case 하나가 무작위로 선택되어
+ // 그 부분이 실행된다.
+ select {
+ case i := <-c: // 채널로부터 받아진 값은 변수에 대입할 수 있다.
+ fmt.Printf("it's a %T", i)
+ case <-cs: // 또는 받은 값을 그냥 버릴 수도 있다.
+ fmt.Println("it's a string")
+ case <-cc: // 통신할 준비가 되어 있지 않은 비어있는 채널.
+ fmt.Println("didn't happen.")
+ }
+ // 여기서는 c나 cs 채널로부터 값 하나를 받을 수 있다. 위에서 실행한 두 개의
+ // goroutine 중 하나가 완료되면 다른 하나는 블락된 상태로 있게 된다.
+
+ learnWebProgramming() // Go에서는 웹 서버쪽 개발도 쉽게 할 수 있다.
+}
+
+// http 패키지의 함수 하나로 웹 서버를 실행시킨다.
+func learnWebProgramming() {
+ // ListenAndServe의 첫 번째 파라미터는 listen 하기 위한 TCP 주소고,
+ // 두 번째 파라미터는 http.Handler 인터페이스다.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // don't ignore errors
+}
+
+// http.Handler의 하나 뿐인 메서드, ServeHTTP를 pair에서 구현한다.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // http.ResponseWriter의 메서드로 클라이언트에게 데이터를 보낸다.
+ w.Write([]byte("You learned Go in Y minutes!"))
+}
+```
+
+## 더 읽어볼 것들
+
+Go에 대한 모든 것들은 [Go 공식 웹 사이트](http://golang.org/)를 참고하자.
+여기에는 따라해볼 튜토리얼, 웹 기반의 인터랙티브 실행환경과 많은 읽을거리들이 있다.
+
+Go 언어 자체에 대한 스펙도 읽어보기를 적극 추천한다. 읽기 쉽게 되어있고
+그리 길지는 않다.
+
+Go 소스코드에 대해 좀더 알아보고 싶다면 [Go 표준 라이브러리](http://golang.org/src/pkg/)를
+분석해보기 바란다. 이해하기 쉽게 문서화되어 있고, Go 스타일 그리고 Go에서의
+관례 배우기에 가장 좋은 방법일 것이다. 또는 [문서](http://golang.org/pkg/) 안에서
+함수 이름 하나를 클릭해보면 소스코드를 브라우저에서 살펴볼 수도 있다.
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index 419c0475..453a42a5 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -4,6 +4,7 @@ language: Objective-C
contributors:
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
- ["Yannick Loriot", "https://github.com/YannickL"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
filename: LearnObjectiveC.m
---
@@ -11,24 +12,32 @@ filename: LearnObjectiveC.m
Objective-C is the main programming language used by Apple for the OS X and iOS operating systems and their respective frameworks, Cocoa and Cocoa Touch.
It is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language.
-```cpp
+```objective-c
// Single-line comments start with //
/*
-Multi-line comments look like this.
+Multi-line comments look like this
*/
// Imports the Foundation headers with #import
+// Use <> to import global files (in general frameworks)
+// Use "" to import local files (from project)
#import <Foundation/Foundation.h>
#import "MyClass.h"
+// If you enable modules for iOS >= 7.0 or OS X >= 10.9 projects in
+// Xcode 5 you can import frameworks like that:
+@import Foundation;
+
// Your program's entry point is a function called
-// main with an integer return type.
+// main with an integer return type
int main (int argc, const char * argv[])
{
// Create an autorelease pool to manage the memory into the program
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
+ // If using automatic reference counting (ARC), use @autoreleasepool instead:
+ @autoreleasepool {
+
// Use NSLog to print lines to the console
NSLog(@"Hello World!"); // Print the string "Hello World!"
@@ -51,7 +60,7 @@ int main (int argc, const char * argv[])
// String
NSString *worldString = @"World";
NSLog(@"Hello %@!", worldString); // prints => "Hello World!"
- // NSMutableString is a mutable version of the NSString object.
+ // NSMutableString is a mutable version of the NSString object
NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
[mutableString appendString:@" World!"];
NSLog(@"%@", mutableString); // prints => "Hello World!"
@@ -74,16 +83,16 @@ int main (int argc, const char * argv[])
short fortyTwoShort = [fortyTwoShortNumber shortValue]; // or 42
NSLog(@"%hi", fortyTwoShort);
- NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:41];
- unsigned short fortyTwoUnsigned = [fortyTwoShortNumber unsignedShortValue]; // or 41
- NSLog(@"%hu", fortyTwoUnsigned);
+ NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41];
+ unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // or 41
+ NSLog(@"%u", fortyOneUnsigned);
NSNumber *fortyTwoLongNumber = @42L;
long fortyTwoLong = [fortyTwoLongNumber longValue]; // or 42
NSLog(@"%li", fortyTwoLong);
- NSNumber *fortyTwoLongNumber = @53L;
- unsigned long fiftyThreeUnsigned = [fortyTwoLongNumber unsignedLongValue]; // or 53
+ NSNumber *fiftyThreeLongNumber = @53L;
+ unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // or 53
NSLog(@"%lu", fiftyThreeUnsigned);
// Floating point literals
@@ -105,7 +114,7 @@ int main (int argc, const char * argv[])
[oneDecNum decimalNumberBySubtracting:twoDecNum];
[oneDecNum decimalNumberByMultiplyingBy:twoDecNum];
[oneDecNum decimalNumberByDividingBy:twoDecNum];
- NSLog(@"%@", oneDecNum); // prints => 10.99 as NSDecimalNumber is immutable.
+ NSLog(@"%@", oneDecNum); // prints => 10.99 as NSDecimalNumber is immutable
// BOOL literals
NSNumber *yesNumber = @YES;
@@ -116,11 +125,12 @@ int main (int argc, const char * argv[])
NSLog(@"%i", yesBool); // prints => 1
// Array object
+ // May contain different data types, but must be an Objective-C object
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
// NSMutableArray is mutable version of NSArray allowing to change items in array
- // and extend or shrink array object. Convenient, but not as efficient as NSArray.
+ // and extend or shrink array object. Convenient, but not as efficient as NSArray
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
[mutableArray addObject:@"Hello"];
[mutableArray addObject:@"World"];
@@ -131,7 +141,7 @@ int main (int argc, const char * argv[])
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
NSObject *valueObject = aDictionary[@"A Key"];
NSLog(@"Object = %@", valueObject); // Print "Object = (null)"
- // NSMutableDictionary also available as a mutable dictionary object.
+ // NSMutableDictionary also available as a mutable dictionary object
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
[mutableDictionary setObject:@"value1" forKey:@"key1"];
[mutableDictionary setObject:@"value2" forKey:@"key2"];
@@ -140,7 +150,7 @@ int main (int argc, const char * argv[])
// Set object
NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil];
NSLog(@"%@", set); // prints => {(Hello, World)} (may be in different order)
- // NSMutableSet also available as a mutable set object.
+ // NSMutableSet also available as a mutable set object
NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2];
[mutableSet addObject:@"Hello"];
[mutableSet addObject:@"Hello"];
@@ -199,7 +209,7 @@ int main (int argc, const char * argv[])
int ii = 0;
while (ii < 4)
{
- NSLog(@"%d,", ii++); // ii++ increments ii in-place, after using its value.
+ NSLog(@"%d,", ii++); // ii++ increments ii in-place, after using its value
} // => prints "0,"
// "1,"
// "2,"
@@ -225,7 +235,7 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
- // Object for loop statement. Can be used with any Objective-C object type.
+ // Object for loop statement. Can be used with any Objective-C object type
for (id item in values) {
NSLog(@"%@,", item);
} // => prints "0,"
@@ -252,17 +262,20 @@ int main (int argc, const char * argv[])
// Objects
///////////////////////////////////////
- // Create an object instance by allocating memory and initializing it.
- // An object is not fully functional until both steps have been completed.
+ // Create an object instance by allocating memory and initializing it
+ // An object is not fully functional until both steps have been completed
MyClass *myObject = [[MyClass alloc] init];
// The Objective-C model of object-oriented programming is based on message
- // passing to object instances.
- // In Objective-C one does not simply call a method; one sends a message.
+ // passing to object instances
+ // In Objective-C one does not simply call a method; one sends a message
[myObject instanceMethodWithParameter:@"Steve Jobs"];
// Clean up the memory you used into your program
[pool drain];
+
+ // End of @autoreleasepool
+ }
// End the program
return 0;
@@ -272,79 +285,141 @@ int main (int argc, const char * argv[])
// Classes And Functions
///////////////////////////////////////
-// Declare your class in a header(MyClass.h) file:
-// Class Declaration Syntax:
+// Declare your class in a header file (MyClass.h):
+// Class declaration syntax:
// @interface ClassName : ParentClassName <ImplementedProtocols>
// {
-// Member variable declarations;
+// type name; <= variable declarations;
// }
-// -/+ (type) Method declarations;
+// @property type name; <= property declarations
+// -/+ (type) Method declarations; <= Method declarations
// @end
-@interface MyClass : NSObject <MyProtocol>
+@interface MyClass : NSObject <MyProtocol> // NSObject is Objective-C's base object class.
{
// Instance variable declarations (can exist in either interface or implementation file)
int count; // Protected access by default.
- @private id data; // Private access. (More convenient to declare in implementation file)
+ @private id data; // Private access (More convenient to declare in implementation file)
NSString *name;
}
-// Convenient notation to auto generate public access getter and setter
-@property int count;
-@property (copy) NSString *name; // Copy the object during assignment.
-@property (readonly) id data; // Declare only a getter method.
-// To access public variable in implementation file, use '_' followed by variable name:
-_count = 5;
-NSLog(@"%d", _count); // prints => 5
-// To access public variable outside implementation file, @property generates setter method
-// automatically. Method name is 'set' followed by @property variable name:
-MyClass *myClass = [[MyClass alloc] init]; // create MyClass object instance.
-[myClass setCount:10];
-NSLog(@"%@", [myClass count]); // prints => 10
+// Convenient notation for public access variables to auto generate a setter method
+// By default, setter method name is 'set' followed by @property variable name
+@property int propInt; // Setter method name = 'setPropInt'
+@property (copy) id copyId; // (copy) => Copy the object during assignment
+// (readonly) => Cannot set value outside @interface
+@property (readonly) NSString *roString; // Use @synthesize in @implementation to create accessor
// You can customize the getter and setter names instead of using default 'set' name:
-@property (getter=countGet, setter=countSet:) int count;
-[myClass countSet:32];
-NSLog(@"%i", [myClass countGet]); // prints => 32
-// For convenience, you may use dot notation to set object instance variables:
-myClass.count = 45;
-NSLog(@"%i", myClass.count); // prints => 45
-
+@property (getter=lengthGet, setter=lengthSet:) int length;
+
// Methods
+/- (return type)methodSignature:(Parameter Type *)parameterName;
-// + for class method
+// + for class methods:
+ (NSString *)classMethod;
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight;
-// - for instance method
+// - for instance methods:
- (NSString *)instanceMethodWithParameter:(NSString *)string;
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
-@end
+// Constructor methods with arguments:
+- (id)initWithDistance:(int)defaultDistance;
+// Objective-C method names are very descriptive. Always name methods according to their arguments
+
+@end // States the end of the interface
+
+
+// To access public variables from the implementation file, @property generates a setter method
+// automatically. Method name is 'set' followed by @property variable name:
+MyClass *myClass = [[MyClass alloc] init]; // create MyClass object instance
+[myClass setCount:10];
+NSLog(@"%d", [myClass count]); // prints => 10
+// Or using the custom getter and setter method defined in @interface:
+[myClass lengthSet:32];
+NSLog(@"%i", [myClass lengthGet]); // prints => 32
+// For convenience, you may use dot notation to set and access object instance variables:
+myClass.count = 45;
+NSLog(@"%i", myClass.count); // prints => 45
+
+// Call class methods:
+NSString *classMethodString = [MyClass classMethod];
+MyClass *classFromName = [MyClass myClassFromName:@"Hello"];
+
+// Call instance methods:
+MyClass *myClass = [[MyClass alloc] init]; // Create MyClass object instance
+NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"];
+
+// Selectors
+// Way to dynamically represent methods. Used to call methods of a class, pass methods
+// through functions to tell other classes they should call it, and to save methods
+// as a variable
+// SEL is the data type. @selector() returns a selector from method name provided
+// methodAParameterAsString:andAParameterAsNumber: is method name for method in MyClass
+SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
+if ([myClass respondsToSelector:selectorVar]) { // Checks if class contains method
+ // Must put all method arguments into one object to send to performSelector function
+ NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
+ [myClass performSelector:selectorVar withObject:arguments]; // Calls the method
+} else {
+ // NSStringFromSelector() returns a NSString of the method name of a given selector
+ NSLog(@"MyClass does not have method: %@", NSStringFromSelector(selectedVar));
+}
// Implement the methods in an implementation (MyClass.m) file:
@implementation MyClass {
- long count; // Private access instance variable.
+ long distance; // Private access instance variable
+ NSNumber height;
+}
+
+// To access a public variable from the interface file, use '_' followed by variable name:
+_count = 5; // References "int count" from MyClass interface
+// Access variables defined in implementation file:
+distance = 18; // References "long distance" from MyClass implementation
+// To use @property variable in implementation, use @synthesize to create accessor variable:
+@synthesize roString = _roString; // _roString available now in @implementation
+
+// Called before calling any class methods or instantiating any objects
++ (void)initialize
+{
+ if (self == [MyClass class]) {
+ distance = 0;
+ }
}
-// Call when the object is releasing
+// Counterpart to initialize method. Called when an object's reference count is zero
- (void)dealloc
{
+ [height release]; // If not using ARC, make sure to release class variable objects
+ [super dealloc]; // and call parent class dealloc
}
-// Constructors are a way of creating classes
-// This is a default constructor which is called when the object is creating
+// Constructors are a way of creating instances of a class
+// This is a default constructor which is called when the object is initialized.
- (id)init
{
- if ((self = [super init]))
+ if ((self = [super init])) // 'super' used to access methods from parent class
{
- self.count = 1;
+ self.count = 1; // 'self' used for object to call itself
}
return self;
}
+// Can create constructors that contain arguments:
+- (id)initWithDistance:(int)defaultDistance
+{
+ distance = defaultDistance;
+ return self;
+}
+ (NSString *)classMethod
{
return [[self alloc] init];
}
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight
+{
+ height = defaultHeight;
+ return [[self alloc] init];
+}
+
- (NSString *)instanceMethodWithParameter:(NSString *)string
{
return @"New string";
@@ -355,13 +430,19 @@ NSLog(@"%i", myClass.count); // prints => 45
return @42;
}
+// To create a private method, create the method in the @implementation but not in the @interface
+- (NSNumber *)secretPrivateMethod {
+ return @72;
+}
+[self secretPrivateMethod]; // Calls private method
+
// Methods declared into MyProtocol
- (void)myProtocolMethod
{
// statements
}
-@end
+@end // States the end of the implementation
/*
* A protocol declares methods that can be implemented by any class.
@@ -373,12 +454,58 @@ NSLog(@"%i", myClass.count); // prints => 45
@end
+///////////////////////////////////////
+// Memory Management
+///////////////////////////////////////
+/*
+For each object used in an application, memory must be allocated for that object. When the application
+is done using that object, memory must be deallocated to ensure application efficiency.
+Objective-C does not use garbage collection and instead uses reference counting. As long as
+there is at least one reference to an object (also called "owning" an object), then the object
+will be available to use (known as "ownership").
+
+When an instance owns an object, its reference counter is increments by one. When the
+object is released, the reference counter decrements by one. When reference count is zero,
+the object is removed from memory.
+
+With all object interactions, follow the pattern of:
+(1) create the object, (2) use the object, (3) then free the object from memory.
+*/
+
+MyClass *classVar = [MyClass alloc]; // 'alloc' sets classVar's reference count to one. Returns pointer to object
+[classVar release]; // Decrements classVar's reference count
+// 'retain' claims ownership of existing object instance and increments reference count. Returns pointer to object
+MyClass *newVar = [classVar retain]; // If classVar is released, object is still in memory because newVar is owner
+[classVar autorelease]; // Removes ownership of object at end of @autoreleasepool block. Returns pointer to object
+
+// @property can use 'retain' and 'assign' as well for small convenient definitions
+@property (retain) MyClass *instance; // Release old value and retain a new one (strong reference)
+@property (assign) NSSet *set; // Pointer to new value without retaining/releasing old (weak reference)
+
+// Automatic Reference Counting (ARC)
+// Because memory management can be a pain, Xcode 4.2 and iOS 4 introduced Automatic Reference Counting (ARC).
+// ARC is a compiler feature that inserts retain, release, and autorelease automatically for you, so when using ARC,
+// you must not use retain, relase, or autorelease
+MyClass *arcMyClass = [[MyClass alloc] init];
+// ... code using arcMyClass
+// Without ARC, you will need to call: [arcMyClass release] after you're done using arcMyClass. But with ARC,
+// there is no need. It will insert this release statement for you
+
+// As for the 'assign' and 'retain' @property attributes, with ARC you use 'weak' and 'strong'
+@property (weak) MyClass *weakVar; // 'weak' does not take ownership of object. If original instance's reference count
+// is set to zero, weakVar will automatically receive value of nil to avoid application crashing
+@property (strong) MyClass *strongVar; // 'strong' takes ownership of object. Ensures object will stay in memory to use
+
+// For regular variables (not @property declared variables), use the following:
+__strong NSString *strongString; // Default. Variable is retained in memory until it leaves it's scope
+__weak NSSet *weakSet; // Weak reference to existing object. When existing object is released, weakSet is set to nil
+__unsafe_unretained NSArray *unsafeArray; // Like __weak, but unsafeArray not set to nil when existing object is released
```
## Further Reading
[Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
-[Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
+[Programming with Objective-C. Apple PDF book](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf)
[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
diff --git a/php.html.markdown b/php.html.markdown
index c3317d59..e1bb86a0 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -212,7 +212,7 @@ assert($c >= $d);
// The following will only be true if the values match and are the same type.
assert($c === $d);
assert($a !== $d);
-assert(1 == '1');
+assert(1 === '1');
assert(1 !== '1');
// Variables can be converted between types, depending on their usage.
diff --git a/racket.html.markdown b/racket.html.markdown
index adacd91d..eddc00bf 100644
--- a/racket.html.markdown
+++ b/racket.html.markdown
@@ -6,6 +6,7 @@ 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"]
---
Racket is a general purpose, multi-paradigm programming language in the Lisp/Scheme family.
@@ -600,6 +601,45 @@ vec ; => #(1 2 3 4)
;; expected: positive?
;; given: -5
;; more details....
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 11. Input & output
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Racket has this concept of "port", which is very similar to file
+;; descriptors in other languages
+
+;; Open "/tmp/tmp.txt" and write "Hello World"
+;; This would trigger an error if the file's already existed
+(define out-port (open-output-file "/tmp/tmp.txt"))
+(displayln "Hello World" out-port)
+(close-output-port out-port)
+
+;; Append to "/tmp/tmp.txt"
+(define out-port (open-output-file "/tmp/tmp.txt"
+ #:exists 'append))
+(displayln "Hola mundo" out-port)
+(close-output-port out-port)
+
+;; Read from the file again
+(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)
+
+;; Alternatively, with call-with-output-file you don't need to explicitly
+;; close the file
+(call-with-output-file "/tmp/tmp.txt"
+ #:exists 'update ; Rewrite the content
+ (λ (out-port)
+ (displayln "World Hello!" out-port)))
+
+;; And call-with-input-file does the same thing for input
+(call-with-input-file "/tmp/tmp.txt"
+ (λ (in-port)
+ (displayln (read-line in-port))))
```
## Further Reading
diff --git a/zh-cn/clojure-cn.html.markdown b/zh-cn/clojure-cn.html.markdown
new file mode 100644
index 00000000..d5d8232b
--- /dev/null
+++ b/zh-cn/clojure-cn.html.markdown
@@ -0,0 +1,366 @@
+---
+language: clojure
+filename: learnclojure-cn.clj
+contributors:
+ - ["Bill Zhang", "http://jingege.github.io/"]
+lang: zh-cn
+---
+
+Clojure是运行在JVM上的Lisp家族中的一员。她比Common Lisp更强调纯[函数式编程](https://en.wikipedia.org/wiki/Functional_programming),且自发布时便包含了一组工具来处理状态。
+
+这种组合让她能十分简单且自动地处理并发问题。
+
+(你需要使用Clojure 1.2或更新的发行版)
+
+```clojure
+; 注释以分号开始。
+
+; Clojure代码由一个个form组成, 即写在小括号里的由空格分开的一组语句。
+; Clojure解释器会把第一个元素当做一个函数或者宏来调用,其余的被认为是参数。
+
+; Clojure代码的第一条语句一般是用ns来指定当前的命名空间。
+(ns learnclojure)
+
+; 更基本的例子:
+
+; str会使用所有参数来创建一个字符串
+(str "Hello" " " "World") ; => "Hello World"
+
+; 数学计算比较直观
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; 等号是 =
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; 逻辑非
+(not true) ; => false
+
+; 嵌套的form工作起来应该和你预想的一样
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; 类型
+;;;;;;;;;;;;;
+
+; Clojure使用Java的Object来描述布尔值、字符串和数字
+; 用函数 `class` 来查看具体的类型
+(class 1) ; 整形默认是java.lang.Long类型
+(class 1.); 浮点默认是java.lang.Double类型的
+(class ""); String是java.lang.String类型的,要用双引号引起来
+(class false) ; 布尔值是java.lang.Boolean类型的
+(class nil); "null"被称作nil
+
+; 如果你想创建一组数据字面量,用单引号(')来阻止form被解析和求值
+'(+ 1 2) ; => (+ 1 2)
+; (单引号是quote的简写形式,故上式等价于(quote (+ 1 2)))
+
+; 可以对一个引用列表求值
+(eval '(+ 1 2)) ; => 3
+
+; 集合(Collection)和序列
+;;;;;;;;;;;;;;;;;;;
+
+; List的底层实现是链表,Vector的底层实现是数组
+; 二者也都是java类
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; list本可以写成(1 2 3), 但必须用引用来避免被解释器当做函数来求值。
+; (list 1 2 3)等价于'(1 2 3)
+
+; 集合其实就是一组数据
+; List和Vector都是集合:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; 序列 (seqs) 是数据列表的抽象描述
+; 只有列表才可称作序列。
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; 序列被访问时只需要提供一个值,所以序列可以被懒加载——也就意味着可以定义一个无限序列:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (无限序列)
+(take 4 (range)) ; (0 1 2 3)
+
+; cons用以向列表或向量的起始位置添加元素
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; conj将以最高效的方式向集合中添加元素。
+; 对于列表,数据会在起始位置插入,而对于向量,则在末尾位置插入。
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; 用concat来合并列表或向量
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; 用filter来过滤集合中的元素,用map来根据指定的函数来映射得到一个新的集合
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; recuce使用函数来规约集合
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; reduce还能指定一个初始参数
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; 函数
+;;;;;;;;;;;;;;;;;;;;;
+
+; 用fn来创建函数。函数的返回值是最后一个表达式的值
+(fn [] "Hello World") ; => fn
+
+; (你需要再嵌套一组小括号来调用它)
+((fn [] "Hello World")) ; => "Hello World"
+
+; 你可以用def来创建一个变量(var)
+(def x 1)
+x ; => 1
+
+; 将函数定义为一个变量(var)
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; 你可用defn来简化函数的定义
+(defn hello-world [] "Hello World")
+
+; 中括号内的内容是函数的参数。
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; 你还可以用这种简写的方式来创建函数:
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; 函数也可以有多个参数列表。
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; 可以定义变参函数,即把&后面的参数全部放入一个序列
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+
+; 可以混用定参和变参(用&来界定)
+(defn hello-count [name & args]
+ (str "Hello " name ", you passed " (count args) " extra args"))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+
+
+; 哈希表
+;;;;;;;;;;
+
+; 基于hash的map和基于数组的map(即arraymap)实现了相同的接口,hashmap查询起来比较快,
+; 但不保证元素的顺序。
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; arraymap在足够大的时候,大多数操作会将其自动转换成hashmap,
+; 所以不用担心(对大的arraymap的查询性能)。
+
+; map支持很多类型的key,但推荐使用keyword类型
+; keyword类型和字符串类似,但做了一些优化。
+(class :a) ; => clojure.lang.Keyword
+
+(def stringmap {"a" 1, "b" 2, "c" 3})
+stringmap ; => {"a" 1, "b" 2, "c" 3}
+
+(def keymap {:a 1, :b 2, :c 3})
+keymap ; => {:a 1, :c 3, :b 2}
+
+; 顺便说一下,map里的逗号是可有可无的,作用只是提高map的可读性。
+
+; 从map中查找元素就像把map名作为函数调用一样。
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; 可以把keyword写在前面来从map中查找元素。
+(:b keymap) ; => 2
+
+; 但不要试图用字符串类型的key来这么做。
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; 查找不存在的key会返回nil。
+(stringmap "d") ; => nil
+
+; 用assoc函数来向hashmap里添加元素
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; 但是要记住的是clojure的数据类型是不可变的!
+keymap ; => {:a 1, :b 2, :c 3}
+
+; 用dissoc来移除元素
+(dissoc keymap :a :b) ; => {:c 3}
+
+; 集合(Set)
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; 用conj新增元素
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; 用disj移除元素
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; 把集合当做函数调用来检查元素是否存在:
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; 在clojure.sets模块下有很多相关函数。
+
+; 常用的form
+;;;;;;;;;;;;;;;;;
+
+; clojure里的逻辑控制结构都是用宏(macro)实现的,这在语法上看起来没什么不同。
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; 用let来创建临时的绑定变量。
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; 用do将多个语句组合在一起依次执行
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; 函数定义里有一个隐式的do
+(defn print-and-say-hello [name]
+ (print "Saying hello to " name)
+ (str "Hello " name))
+(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
+
+; let也是如此
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+; 模块
+;;;;;;;;;;;;;;;
+
+; 用use来导入模块里的所有函数
+(use 'clojure.set)
+
+; 然后就可以使用set相关的函数了
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; 你也可以从一个模块里导入一部分函数。
+(use '[clojure.set :only [intersection]])
+
+; 用require来导入一个模块
+(require 'clojure.string)
+
+; 用/来调用模块里的函数
+; 下面是从模块`clojure.string`里调用`blank?`函数。
+(clojure.string/blank? "") ; => true
+
+; 在`import`里你可以给模块名指定一个较短的别名。
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#""用来表示一个正则表达式)
+
+; 你可以在一个namespace定义里用:require的方式来require(或use,但最好不要用)模块。
+; 这样的话你无需引用模块列表。
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java有大量的优秀的库,你肯定想学会如何用clojure来使用这些Java库。
+
+; 用import来导入java类
+(import java.util.Date)
+
+; 也可以在ns定义里导入
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; 用类名末尾加`.`的方式来new一个Java对象
+(Date.) ; <a date object>
+
+; 用`.`操作符来调用方法,或者用`.method`的简化方式。
+(. (Date.) getTime) ; <a timestamp>
+(.getTime (Date.)) ; 和上例一样。
+
+; 用`/`调用静态方法
+(System/currentTimeMillis) ; <a timestamp> (system is always present)
+
+; 用`doto`来更方便的使用(可变)类。
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0)
+ .getTime) ; => A Date. set to 2000-01-01 00:00:00
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; 软件内存事务(Software Transactional Memory)被clojure用来处理持久化的状态。
+; clojure里内置了一些结构来使用STM。
+; atom是最简单的。给它传一个初始值
+(def my-atom (atom {}))
+
+; 用`swap!`更新atom。
+; `swap!`会以atom的当前值为第一个参数来调用一个指定的函数,
+; `swap`其余的参数作为该函数的第二个参数。
+(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
+
+; 用`@`读取atom的值
+my-atom ;=> Atom<#...> (返回Atom对象)
+@my-atom ; => {:a 1 :b 2}
+
+; 下例是一个使用atom实现的简单计数器
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; 其他STM相关的结构是ref和agent.
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+```
+
+### 进阶读物
+
+本文肯定不足以讲述关于clojure的一切,但是希望足以让你迈出第一步。
+
+Clojure.org官网有很多文章:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org有大多数核心函数的文档,还带了示例哦:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure是个很赞的用来练习clojure/FP技能的地方:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org (你没看错)有很多入门级的文章:
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown
index 7cc9c171..4a87dc21 100644
--- a/zh-cn/go-cn.html.markdown
+++ b/zh-cn/go-cn.html.markdown
@@ -5,6 +5,8 @@ filename: learngo-cn.go
contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
- ["pantaovay", "https://github.com/pantaovay"]
+ - ["lidashuang", "https://github.com/lidashuang"]
+
---
发明Go语言是出于更好地完成工作的需要。Go不是计算机科学的最新发展潮流,但它却提供了解决现实问题的最新最快的方法。
@@ -30,7 +32,7 @@ import (
)
// 函数声明:Main是程序执行的入口。
-// 不管你喜欢还是不喜欢,反正G就用了花括号来包住函数体。
+// 不管你喜欢还是不喜欢,反正Go就用了花括号来包住函数体。
func main() {
// 往标准输出打印一行。
// 用包名fmt限制打印函数。
@@ -47,7 +49,7 @@ func beyondHello() {
x = 3 // 变量赋值。
// 可以用:=来偷懒,它自动把变量类型、声明和赋值都搞定了。
y := 4
- sum, prod := learnMultiple(x, y) // 多个返回变量的函数
+ sum, prod := learnMultiple(x, y) // 返回多个变量的函数
fmt.Println("sum:", sum, "prod:", prod) // 简单输出
learnTypes() // 少于y分钟,学的更多!
}
@@ -82,7 +84,7 @@ can include line breaks.` // 同样是String类型
var a4 [4] int // 有4个int变量的数组,初始为0
a3 := [...]int{3, 1, 5} // 有3个int变量的数组,同时进行了初始化
- // Slice 有动态大小。Array和Slice各有千秋,但是使用slice的地方更多些。
+ // Slice 可以动态的增删。Array和Slice各有千秋,但是使用slice的地方更多些。
s3 := []int{4, 5, 9} // 和a3相比,这里没有省略号
s4 := make([]int, 4) // 分配一个有4个int型变量的slice,全部被初始化为0
@@ -114,7 +116,7 @@ func learnMemory() (p, q *int) {
s := make([]int, 20) // 给20个int变量分配一块内存
s[3] = 7 // 赋值
r := -2 // 声明另一个局部变量
- return &s[3], &r // & 取址
+ return &s[3], &r // & 取地址
}
func expensiveComputation() int {
@@ -149,7 +151,7 @@ func learnFlowControl() {
// x在这里还是1。为什么?
// for 是go里唯一的循环关键字,不过它有很多变种
- for { // 无限循环
+ for { // 死循环
break // 骗你的
continue // 不会运行的
}
@@ -239,7 +241,7 @@ func learnConcurrency() {
go inc(-805, c)
// 从channel中独处结果并打印。
// 打印出什么东西是不可预知的。
- fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是接收操作。
+ fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是读操作。
cs := make(chan string) // 操作string的channel
cc := make(chan chan string) // 操作channel的channel
@@ -255,7 +257,7 @@ func learnConcurrency() {
case <-cc: // 空的,还没作好通讯的准备
fmt.Println("didn't happen.")
}
- // 上面c或者cs的值被取到,其中一个goroutine结束,另外一个保持阻塞。
+ // 上面c或者cs的值被取到,其中一个goroutine结束,另外一个一直阻塞。
learnWebProgramming() // Go很适合web编程,我知道你也想学!
}
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index 89fc256e..86ad1d07 100644
--- a/zh-cn/javascript-cn.html.markdown
+++ b/zh-cn/javascript-cn.html.markdown
@@ -401,8 +401,6 @@ if (Object.create === undefined){ // 如果存在则不覆盖
[Mozilla 开发者
网络](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 提供了很好的
Javascript文档,并且由于是wiki,所以你也可以自行编辑来分享你的知识。
-wiki, so as you learn more you can help others out by sharing your own
-knowledge.
MDN的 [A re-introduction to
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
diff --git a/zh-cn/php-cn.html.markdown b/zh-cn/php-cn.html.markdown
index c6ebb515..24939681 100644
--- a/zh-cn/php-cn.html.markdown
+++ b/zh-cn/php-cn.html.markdown
@@ -180,7 +180,7 @@ assert($c >= $d);
// 下面的比较只有在类型相同、值相同的情况下才为真
assert($c === $d);
assert($a !== $d);
-assert(1 == '1');
+assert(1 === '1');
assert(1 !== '1');
// 变量可以根据其使用来进行类型转换
@@ -243,7 +243,7 @@ if ($x === '0') {
-// 下面的语法常用语模板中:
+// 下面的语法常用于模板中:
?>
<?php if ($x): ?>
@@ -333,7 +333,7 @@ function my_function () {
echo my_function(); // => "Hello"
// 函数名需要以字母或者下划线开头,
-// 后面可以跟着任意的字幕、下划线、数字.
+// 后面可以跟着任意的字母、下划线、数字.
function add ($x, $y = 1) { // $y 是可选参数,默认值为 1
$result = $x + $y;
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 619e6e92..3c47f3f9 100644
--- a/zh-cn/ruby-cn.html.markdown
+++ b/zh-cn/ruby-cn.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["lidashuang", "https://github.com/lidashuang"]
translators:
- ["Lin Xiangyu", "https://github.com/oa414"]
---
@@ -173,7 +174,7 @@ new_hash = { defcon: 3, action: true}
new_hash.keys #=> [:defcon, :action]
# 小贴士:数组和哈希表都是可枚举的
-# 它们可以共享一些有用的方法,比如each, map, count, 和more
+# 它们可以共享一些有用的方法,比如each, map, count 等等
# 控制流