summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.markdown64
-rw-r--r--bash.html.markdown168
-rw-r--r--brainfuck.html.markdown79
-rw-r--r--c.html.markdown769
-rw-r--r--clojure-macros.html.markdown152
-rw-r--r--clojure.html.markdown10
-rw-r--r--coffeescript.html.markdown46
-rw-r--r--common-lisp.html.markdown622
-rw-r--r--csharp.html.markdown806
-rw-r--r--css.html.markdown233
-rw-r--r--de-de/bash-de.html.markdown92
-rw-r--r--de-de/css-de.html.markdown231
-rw-r--r--de-de/elixir-de.html.markdown419
-rw-r--r--de-de/git-de.html.markdown374
-rw-r--r--de-de/javascript-de.html.markdown450
-rw-r--r--de-de/python-de.html.markdown487
-rw-r--r--elisp.html.markdown14
-rw-r--r--elixir.html.markdown4
-rw-r--r--es-es/c-es.html.markdown2
-rw-r--r--es-es/clojure-es.html.markdown393
-rw-r--r--es-es/coffeescript-es.html.markdown57
-rw-r--r--es-es/csharp-es.html.markdown632
-rw-r--r--es-es/git-es.html.markdown411
-rw-r--r--es-es/go-es.html.markdown326
-rw-r--r--es-es/julia-es.html.markdown759
-rw-r--r--es-es/perl-es.html.markdown160
-rw-r--r--fa-ir/brainfuck.html.markdown81
-rw-r--r--fa-ir/javascript.html.markdown556
-rw-r--r--fr-fr/clojure-fr.html.markdown398
-rw-r--r--fr-fr/coffeescript-fr.html.markdown58
-rw-r--r--fr-fr/csharp-fr.html.markdown812
-rw-r--r--fr-fr/haskell.html.markdown431
-rw-r--r--fr-fr/lua-fr.html.markdown449
-rw-r--r--fr-fr/objective-c-fr.html.markdown528
-rw-r--r--fr-fr/python-fr.html.markdown489
-rw-r--r--fr-fr/racket-fr.html.markdown628
-rw-r--r--fr-fr/ruby-fr.html.markdown411
-rw-r--r--git.html.markdown5
-rw-r--r--go.html.markdown331
-rw-r--r--groovy.html.markdown427
-rw-r--r--haskell.html.markdown18
-rw-r--r--haxe.html.markdown776
-rw-r--r--hu-hu/go.html.markdown337
-rw-r--r--hy.html.markdown174
-rw-r--r--id-id/css-id.html.markdown246
-rw-r--r--it-it/brainfuck-it.html.markdown101
-rw-r--r--it-it/java-it.html.markdown502
-rw-r--r--java.html.markdown114
-rw-r--r--javascript.html.markdown367
-rw-r--r--json.html.markdown48
-rw-r--r--julia.html.markdown619
-rw-r--r--ko-kr/brainfuck-kr.html.markdown84
-rw-r--r--ko-kr/clojure-kr.html.markdown383
-rw-r--r--ko-kr/coffeescript-kr.html.markdown58
-rw-r--r--ko-kr/go-kr.html.markdown314
-rw-r--r--ko-kr/java-kr.html.markdown408
-rw-r--r--ko-kr/javascript-kr.html.markdown436
-rw-r--r--ko-kr/lua-kr.html.markdown422
-rw-r--r--ko-kr/php-kr.html.markdown662
-rw-r--r--ko-kr/python-kr.html.markdown484
-rw-r--r--livescript.html.markdown16
-rw-r--r--lua.html.markdown156
-rw-r--r--matlab.html.markdown452
-rw-r--r--neat.html.markdown297
-rw-r--r--objective-c.html.markdown749
-rw-r--r--perl.html.markdown147
-rw-r--r--php.html.markdown47
-rw-r--r--pogo.html.markdown202
-rw-r--r--pt-br/elisp-pt.html.markdown359
-rw-r--r--pt-br/erlang-pt.html.markdown254
-rw-r--r--pt-br/go-pt.html.markdown308
-rw-r--r--pt-br/haskell-pt.html.markdown620
-rw-r--r--pt-br/java-pt.html.markdown435
-rw-r--r--pt-br/php-pt.html.markdown700
-rw-r--r--pt-br/python-pt.html.markdown2
-rw-r--r--pt-br/ruby-pt.html.markdown387
-rw-r--r--pt-br/visualbasic-pt.html.markdown285
-rw-r--r--pt-pt/brainfuck-pt.html.markdown84
-rw-r--r--pt-pt/git-pt.html.markdown416
-rw-r--r--python.html.markdown313
-rw-r--r--python3.html.markdown578
-rw-r--r--r.html.markdown4
-rw-r--r--racket.html.markdown48
-rw-r--r--red.html.markdown219
-rw-r--r--ro-ro/bash-ro.html.markdown177
-rw-r--r--ro-ro/python-ro.html.markdown490
-rw-r--r--ro-ro/ruby-ro.html.markdown491
-rw-r--r--ru-ru/c-ru.html.markdown483
-rw-r--r--ru-ru/clojure-ru.html.markdown427
-rw-r--r--ru-ru/erlang-ru.html.markdown256
-rw-r--r--ru-ru/go-ru.html.markdown336
-rw-r--r--ru-ru/haskell-ru.html.markdown546
-rw-r--r--ru-ru/julia-ru.html.markdown750
-rw-r--r--ru-ru/objective-c-ru.html.markdown317
-rw-r--r--ru-ru/php-ru.html.markdown663
-rw-r--r--ru-ru/python-ru.html.markdown493
-rw-r--r--ru-ru/ruby-ru.html.markdown468
-rw-r--r--ruby-ecosystem.html.markdown16
-rw-r--r--ruby.html.markdown168
-rw-r--r--scala.html.markdown9
-rw-r--r--standard-ml.html.markdown396
-rw-r--r--tr-tr/brainfuck-tr.html.markdown87
-rw-r--r--tr-tr/c-tr.html.markdown488
-rw-r--r--tr-tr/objective-c-tr.html.markdown320
-rw-r--r--tr-tr/php-tr.html.markdown705
-rw-r--r--tr-tr/python-tr.html.markdown502
-rw-r--r--vi-vn/git-vi.html.markdown393
-rw-r--r--vi-vn/objective-c-vi.html.markdown318
-rw-r--r--whip.html.markdown18
-rw-r--r--xml.html.markdown131
-rw-r--r--yaml.html.markdown139
-rw-r--r--zh-cn/bash-cn.html.markdown148
-rw-r--r--zh-cn/brainfuck-cn.html.markdown70
-rw-r--r--[-rwxr-xr-x]zh-cn/c-cn.html.markdown394
-rw-r--r--zh-cn/clojure-cn.html.markdown368
-rw-r--r--zh-cn/clojure-macro-cn.html.markdown152
-rw-r--r--zh-cn/coffeescript-cn.html.markdown101
-rw-r--r--zh-cn/common-lisp-cn.html.markdown624
-rw-r--r--zh-cn/csharp-cn.html.markdown798
-rw-r--r--zh-cn/css-cn.html.markdown212
-rw-r--r--[-rwxr-xr-x]zh-cn/elisp-cn.html.markdown4
-rw-r--r--zh-cn/elixir-cn.html.markdown399
-rw-r--r--[-rwxr-xr-x]zh-cn/git-cn.html.markdown4
-rw-r--r--zh-cn/go-cn.html.markdown286
-rw-r--r--[-rwxr-xr-x]zh-cn/haskell-cn.html.markdown0
-rw-r--r--[-rwxr-xr-x]zh-cn/java-cn.html.markdown2
-rw-r--r--[-rwxr-xr-x]zh-cn/javascript-cn.html.markdown2
-rw-r--r--zh-cn/lua-cn.html.markdown413
-rw-r--r--zh-cn/perl-cn.html.markdown152
-rw-r--r--[-rwxr-xr-x]zh-cn/php-cn.html.markdown6
-rw-r--r--[-rwxr-xr-x]zh-cn/python-cn.html.markdown277
-rw-r--r--zh-cn/r-cn.html.markdown541
-rw-r--r--zh-cn/racket-cn.html.markdown608
-rw-r--r--zh-cn/ruby-cn.html.markdown8
-rw-r--r--zh-cn/scala-cn.html.markdown1
-rw-r--r--zh-cn/visualbasic-cn.html.markdown274
136 files changed, 41271 insertions, 1155 deletions
diff --git a/README.markdown b/README.markdown
index efc2fa07..dc379a9b 100644
--- a/README.markdown
+++ b/README.markdown
@@ -9,18 +9,68 @@ commented code and explained as they go.
... to write more inline code tutorials. Just grab an existing file from
this repo and copy the formatting (don't worry, it's all very simple).
Make a new file, send a pull request, and if it passes muster I'll get it up pronto.
-Remember to fill in the author and author\_url fields so you get credited
+Remember to fill in the "contributors" fields so you get credited
properly!
-### Requests
+## Contributing
-The most requested languages are:
+All contributions welcome, from the tiniest typo to a brand new article. Translations
+in all languages are welcome (or, for that matter, original articles in any language).
+Send a pull request or open an issue any time of day or night.
-* Go
-* ~~Scala~~
-* ~~Javascript~~
+**Please tag your issues pull requests with [language/lang-code] at the beginning**
+**(e.g. [python/en] for english python).** This will help everyone pick out things they
+care about.
-... but there are many more requests to do "every language", so don't let that stop you.
+### Style Guidelines
+
+* **Keep lines under 80 chars**
+* **Prefer example to exposition**
+* **Eschew surplusage**
+* **Use utf-8**
+
+Long version:
+
+* Try to keep **line length in code blocks to 80 characters or fewer**, or they'll overflow
+ and look odd.
+
+* Try to use as few words as possible. Code examples are preferred over exposition in all cases.
+
+* We welcome newcomers, but the target audience for this site is programmers with some experience.
+ So, try to avoid explaining basic concepts except for those specific to the language in question,
+ to keep articles succinct and scannable. We all know how to use google here.
+
+* For translations (or english articles with non-ASCII characters), please make sure your file is
+ utf-8 encoded, and try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in vim)
+
+### Header configuration
+
+The actual site uses Middleman to generate HTML files from these markdown ones. Middleman, or at least
+the custom scripts underpinning the site, required that some key information be defined in the header.
+
+The following fields are necessary for english articles about programming languages:
+
+* **language** The *programming language* in question
+* **contributors** A list of [author, url] lists to credit
+
+Other fields:
+
+* **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable.
+ For non-english articles, *filename* should have a language-specific suffix.
+* **lang**: For translations, the human language this article is in. For categorization, mostly.
+
+Here's an example header for an esperanto translation of Ruby:
+
+```yaml
+---
+language: ruby
+filename: learnruby-epo.ruby
+contributors:
+ - ["Doktor Esperanto", "http://example.com/"]
+ - ["Someone else", "http://someoneelseswebsite.com/"]
+lang: ep-ep
+---
+```
## License
diff --git a/bash.html.markdown b/bash.html.markdown
new file mode 100644
index 00000000..d5d08e9d
--- /dev/null
+++ b/bash.html.markdown
@@ -0,0 +1,168 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Darren Lin", "https://github.com/CogBear"]
+ - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
+ - ["Denis Arh", "https://github.com/darh"]
+filename: LearnBash.sh
+---
+
+Bash is a name of the unix shell, which was also distributed as the shell for the GNU operating system and as default shell on Linux and Mac OS X.
+Nearly all examples below can be a part of a shell script or executed directly in the shell.
+
+[Read more here.](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# First line of the script is shebang which tells the system how to execute
+# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# As you already figured, comments start with #. Shebang is also a comment.
+
+# Simple hello world example:
+echo Hello world!
+
+# Each command starts on a new line, or after semicolon:
+echo 'This is the first line'; echo 'This is the second line'
+
+# Declaring a variable looks like this:
+VARIABLE="Some string"
+
+# But not like this:
+VARIABLE = "Some string"
+# Bash will decide that VARIABLE is a command it must execute and give an error
+# because it couldn't be found.
+
+# Using the variable:
+echo $VARIABLE
+echo "$VARIABLE"
+echo '$VARIABLE'
+# When you use the variable itself — assign it, export it, or else — you write
+# its name without $. If you want to use variable's value, you should use $.
+# Note that ' (single quote) won't expand the variables!
+
+# String substitution in variables
+echo ${VARIABLE/Some/A}
+# This will substitute the first occurance of "Some" with "A"
+
+# Substring from a variable
+echo ${VARIABLE:0:7}
+# This will return only the first 7 characters of the value
+
+# Default value for variable
+echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
+# This works for null (FOO=), empty string (FOO=""), zero (FOO=0) returns 0
+
+# Builtin variables:
+# There are some useful builtin variables, like
+echo "Last program return value: $?"
+echo "Script's PID: $$"
+echo "Number of arguments: $#"
+echo "Scripts arguments: $@"
+echo "Scripts arguments seperated in different variables: $1 $2..."
+
+# Reading a value from input:
+echo "What's your name?"
+read NAME # Note that we didn't need to declare a new variable
+echo Hello, $NAME!
+
+# We have the usual if structure:
+# use 'man test' for more info about conditionals
+if [ $NAME -ne $USER ]
+then
+ echo "Your name is your username"
+else
+ echo "Your name isn't your username"
+fi
+
+# There is also conditional execution
+echo "Always executed" || echo "Only executed if first command fails"
+echo "Always executed" && echo "Only executed if first command does NOT fail"
+
+# Expressions are denoted with the following format:
+echo $(( 10 + 5 ))
+
+# Unlike other programming languages, bash is a shell — so it works in a context
+# of current directory. You can list files and directories in the current
+# directory with the ls command:
+ls
+
+# These commands have options that control their execution:
+ls -l # Lists every file and directory on a separate line
+
+# Results of the previous command can be passed to the next command as input.
+# grep command filters the input with provided patterns. That's how we can list
+# .txt files in the current directory:
+ls -l | grep "\.txt"
+
+# You can also redirect a command, input and error output.
+python2 hello.py < "input.in"
+python2 hello.py > "output.out"
+python2 hello.py 2> "error.err"
+# The output error will overwrite the file if it exists, if you want to
+# concatenate them, use ">>" instead.
+
+# Commands can be substituted within other commands using $( ):
+# The following command displays the number of files and directories in the
+# current directory.
+echo "There are $(ls | wc -l) items here."
+
+# The same can be done using backticks `` but they can't be nested - the preferred way
+# is to use $( ).
+echo "There are `ls | wc -l` items here."
+
+# Bash uses a case statement that works similarly to switch in Java and C++:
+case "$VARIABLE" in
+ #List patterns for the conditions you want to meet
+ 0) echo "There is a zero.";;
+ 1) echo "There is a one.";;
+ *) echo "It is not null.";;
+esac
+
+# for loops iterate for as many arguments given:
+# The contents of var $VARIABLE is printed three times.
+for VARIABLE in {1..3}
+do
+ echo "$VARIABLE"
+done
+
+# while loop:
+while [true]
+do
+ echo "loop body here..."
+ break
+done
+
+# You can also define functions
+# Definition:
+function foo ()
+{
+ echo "Arguments work just like script arguments: $@"
+ echo "And: $1 $2..."
+ echo "This is a function"
+ return 0
+}
+
+# or simply
+bar ()
+{
+ echo "Another way to declare functions!"
+ return 0
+}
+
+# Calling your function
+foo "My name is" $NAME
+
+# There are a lot of useful commands you should learn:
+tail -n 10 file.txt
+# prints last 10 lines of file.txt
+head -n 10 file.txt
+# prints first 10 lines of file.txt
+sort file.txt
+# sort file.txt's lines
+uniq -d file.txt
+# report or omit repeated lines, with -d it reports them
+cut -d ',' -f 1 file.txt
+# prints only the first column before the ',' character
+```
diff --git a/brainfuck.html.markdown b/brainfuck.html.markdown
new file mode 100644
index 00000000..27ac6921
--- /dev/null
+++ b/brainfuck.html.markdown
@@ -0,0 +1,79 @@
+---
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+---
+
+Brainfuck (not capitalized except at the start of a sentence) is an extremely
+minimal Turing-complete programming language with just 8 commands.
+
+```
+Any character not "><+-.,[]" (excluding quotation marks) is ignored.
+
+Brainfuck is represented by an array with 30,000 cells initialized to zero
+and a data pointer pointing at the current cell.
+
+There are eight commands:
++ : Increments the value at the current cell by one.
+- : Decrements the value at the current cell by one.
+> : Moves the data pointer to the next cell (cell on the right).
+< : Moves the data pointer to the previous cell (cell on the left).
+. : Prints the ASCII value at the current cell (i.e. 65 = 'A').
+, : Reads a single input character into the current cell.
+[ : If the value at the current cell is zero, skips to the corresponding ] .
+ Otherwise, move to the next instruction.
+] : If the value at the current cell is zero, move to the next instruction.
+ Otherwise, move backwards in the instructions to the corresponding [ .
+
+[ and ] form a while loop. Obviously, they must be balanced.
+
+Let's look at some basic brainfuck programs.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+This program prints out the letter 'A'. First, it increments cell #1 to 6.
+Cell #1 will be used for looping. Then, it enters the loop ([) and moves
+to cell #2. It increments cell #2 10 times, moves back to cell #1, and
+decrements cell #1. This loop happens 6 times (it takes 6 decrements for
+cell #1 to reach 0, at which point it skips to the corresponding ] and
+continues on).
+
+At this point, we're on cell #1, which has a value of 0, while cell #2 has a
+value of 60. We move on cell #2, increment 5 times, for a value of 65, and then
+print cell #2's value. 65 is 'A' in ASCII, so 'A' is printed to the terminal.
+
+
+, [ > + < - ] > .
+
+This program reads a character from the user input and copies the character into
+cell #1. Then we start a loop. Move to cell #2, increment the value at cell #2,
+move back to cell #1, and decrement the value at cell #1. This continues on
+until cell #1 is 0, and cell #2 holds cell #1's old value. Because we're on
+cell #1 at the end of the loop, move to cell #2, and then print out the value
+in ASCII.
+
+Also keep in mind that the spaces are purely for readability purposes. You
+could just as easily write it as:
+
+,[>+<-]>.
+
+Try and figure out what this program does:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+This program takes two numbers for input, and multiplies them.
+
+The gist is it first reads in two inputs. Then it starts the outer loop,
+conditioned on cell #1. Then it moves to cell #2, and starts the inner
+loop conditioned on cell #2, incrementing cell #3. However, there comes a
+problem: At the end of the inner loop, cell #2 is zero. In that case,
+inner loop won't work anymore since next time. To solve this problem,
+we also increment cell #4, and then recopy cell #4 into cell #2.
+Then cell #3 is the result.
+```
+
+And that's brainfuck. Not that hard, eh? For fun, you can write your own
+brainfuck programs, or you can write a brainfuck interpreter in another
+language. The interpreter is fairly simple to implement, but if you're a
+masochist, try writing a brainfuck interpreter… in brainfuck.
diff --git a/c.html.markdown b/c.html.markdown
index d243b19d..0190125b 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -1,293 +1,421 @@
---
-name: c
-category: language
language: c
filename: learnc.c
contributors:
- ["Adam Bard", "http://adambard.com/"]
+ - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
+
---
-Ah, C. Still the language of modern high-performance computing.
+Ah, C. Still **the** language of modern high-performance computing.
C is the lowest-level language most programmers will ever use, but
it more than makes up for it with raw speed. Just be aware of its manual
memory management and C will take you as far as you need to go.
```c
-// Single-line comments start with //
+// Single-line comments start with // - only available in C99 and later.
/*
-Multi-line comments look like this.
+Multi-line comments look like this. They work in C89 as well.
*/
+// Constants: #define <keyword>
+#define DAYS_IN_YEAR 365
+
+//enumeration constants are also ways to declare constants.
+enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
+// MON gets 2 automatically, TUE gets 3, etc.
+
// Import headers with #include
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+// (File names between <angle brackets> are headers from the C standard library.)
+// For your own headers, use double quotes instead of angle brackets:
+#include "my_header.h"
+
// Declare function signatures in advance in a .h file, or at the top of
// your .c file.
-void function_1();
-void function_2();
+void function_1(char c);
+int function_2(void);
+
+// Must declare a 'function prototype' before main() when functions occur after
+// your main() function.
+int add_two_ints(int x1, int x2); // function prototype
// Your program's entry point is a function called
// main with an integer return type.
int main() {
+ // print output using printf, for "print formatted"
+ // %d is an integer, \n is a newline
+ printf("%d\n", 0); // => Prints 0
+ // All statements must end with a semicolon
+
+ ///////////////////////////////////////
+ // Types
+ ///////////////////////////////////////
+
+ // ints are usually 4 bytes
+ int x_int = 0;
+
+ // shorts are usually 2 bytes
+ short x_short = 0;
+
+ // chars are guaranteed to be 1 byte
+ char x_char = 0;
+ char y_char = 'y'; // Char literals are quoted with ''
+
+ // longs are often 4 to 8 bytes; long longs are guaranteed to be at least
+ // 64 bits
+ long x_long = 0;
+ long long x_long_long = 0;
+
+ // floats are usually 32-bit floating point numbers
+ float x_float = 0.0;
+
+ // doubles are usually 64-bit floating-point numbers
+ double x_double = 0.0;
+
+ // Integral types may be unsigned.
+ unsigned short ux_short;
+ unsigned int ux_int;
+ unsigned long long ux_long_long;
+
+ // chars inside single quotes are integers in machine's character set.
+ '0' // => 48 in the ASCII character set.
+ 'A' // => 65 in the ASCII character set.
+
+ // sizeof(T) gives you the size of a variable with type T in bytes
+ // sizeof(obj) yields the size of the expression (variable, literal, etc.).
+ printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words)
+
+
+ // 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;
+ // size_t is an unsiged integer type of at least 2 bytes used to represent
+ // the size of an object.
+ size_t size = sizeof(a++); // a++ is not evaluated
+ printf("sizeof(a++) = %zu where a = %d\n", size, a);
+ // prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
+
+ // Arrays must be initialized with a concrete size.
+ char my_char_array[20]; // This array occupies 1 * 20 = 20 bytes
+ int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes
+ // (assuming 4-byte words)
+
+
+ // You can initialize an array to 0 thusly:
+ char my_array[20] = {0};
+
+ // Indexing an array is like other languages -- or,
+ // rather, other languages are like C
+ my_array[0]; // => 0
+
+ // Arrays are mutable; it's just memory!
+ my_array[1] = 2;
+ printf("%d\n", my_array[1]); // => 2
+
+ // In C99 (and as an optional feature in C11), variable-length arrays (VLAs)
+ // can be declared as well. The size of such an array need not be a compile
+ // time constant:
+ printf("Enter the array size: "); // ask the user for an array size
+ char buf[0x100];
+ fgets(buf, sizeof buf, stdin);
+
+ // strtoul parses a string to an unsigned integer
+ size_t size = strtoul(buf, NULL, 10);
+ int var_length_array[size]; // declare the VLA
+ printf("sizeof array = %zu\n", sizeof var_length_array);
+
+ // A possible outcome of this program may be:
+ // > Enter the array size: 10
+ // > sizeof array = 40
+
+ // Strings are just arrays of chars terminated by a NUL (0x00) byte,
+ // represented in strings as the special character '\0'.
+ // (We don't have to include the NUL byte in string literals; the compiler
+ // inserts it at the end of the array for us.)
+ char a_string[20] = "This is a string";
+ printf("%s\n", a_string); // %s formats a string
+
+ printf("%d\n", a_string[16]); // => 0
+ // i.e., byte #17 is 0 (as are 18, 19, and 20)
+
+ // If we have characters between single quotes, that's a character literal.
+ // It's of type `int`, and *not* `char` (for historical reasons).
+ int cha = 'a'; // fine
+ char chb = 'a'; // fine too (implicit conversion from int to char)
+
+ //Multi-dimensional arrays:
+ int multi_array[2][5] = {
+ {1, 2, 3, 4, 5},
+ {6, 7, 8, 9, 0}
+ }
+ //access elements:
+ int array_int = multi_array[0][2]; // => 3
+
+ ///////////////////////////////////////
+ // Operators
+ ///////////////////////////////////////
+
+ // Shorthands for multiple declarations:
+ int i1 = 1, i2 = 2;
+ float f1 = 1.0, f2 = 2.0;
+
+ int a, b, c;
+ a = b = c = 0;
+
+ // Arithmetic is straightforward
+ i1 + i2; // => 3
+ i2 - i1; // => 1
+ i2 * i1; // => 2
+ i1 / i2; // => 0 (0.5, but truncated towards 0)
+
+ f1 / f2; // => 0.5, plus or minus epsilon
+ // Floating-point numbers and calculations are not exact
+
+ // Modulo is there as well
+ 11 % 3; // => 2
+
+ // Comparison operators are probably familiar, but
+ // there is no boolean type in c. We use ints instead.
+ // (Or _Bool or bool in C99.)
+ // 0 is false, anything else is true. (The comparison
+ // operators always yield 0 or 1.)
+ 3 == 2; // => 0 (false)
+ 3 != 2; // => 1 (true)
+ 3 > 2; // => 1
+ 3 < 2; // => 0
+ 2 <= 2; // => 1
+ 2 >= 2; // => 1
+
+ // C is not Python - comparisons don't chain.
+ int a = 1;
+ // WRONG:
+ int between_0_and_2 = 0 < a < 2;
+ // Correct:
+ int between_0_and_2 = 0 < a && a < 2;
+
+ // Logic works on ints
+ !3; // => 0 (Logical not)
+ !0; // => 1
+ 1 && 1; // => 1 (Logical and)
+ 0 && 1; // => 0
+ 0 || 1; // => 1 (Logical or)
+ 0 || 0; // => 0
+
+ //Conditional expression ( ? : )
+ int a = 5;
+ int b = 10;
+ int z;
+ z = (a > b) ? a : b; // => 10 "if a > b return a, else return b."
+
+ //Increment and decrement operators:
+ char *s = "iLoveC"
+ int j = 0;
+ s[j++]; // => "i". Returns the j-th item of s THEN increments value of j.
+ j = 0;
+ s[++j]; // => "L". Increments value of j THEN returns j-th value of s.
+ // same with j-- and --j
+
+ // Bitwise operators!
+ ~0x0F; // => 0xF0 (bitwise negation, "1's complement")
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x0F | 0xF0; // => 0xFF (bitwise OR)
+ 0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
+ 0x01 << 1; // => 0x02 (bitwise left shift (by 1))
+ 0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
+
+ // Be careful when shifting signed integers - the following are undefined:
+ // - shifting into the sign bit of a signed integer (int a = 1 << 32)
+ // - left-shifting a negative number (int a = -1 << 2)
+ // - shifting by an offset which is >= the width of the type of the LHS:
+ // int a = 1 << 32; // UB if int is 32 bits wide
+
+ ///////////////////////////////////////
+ // Control Structures
+ ///////////////////////////////////////
+
+ if (0) {
+ printf("I am never run\n");
+ } else if (0) {
+ printf("I am also never run\n");
+ } else {
+ printf("I print\n");
+ }
-// print output using printf, for "print formatted"
-// %d is an integer, \n is a newline
-printf("%d\n", 0); // => Prints 0
-// All statements must end with a semicolon
-
-///////////////////////////////////////
-// Types
-///////////////////////////////////////
-
-// You have to declare variables before using them. A variable declaration
-// requires you to specify its type; a variable's type determines its size
-// in bytes.
-
-// ints are usually 4 bytes
-int x_int = 0;
-
-// shorts are usually 2 bytes
-short x_short = 0;
-
-// chars are guaranteed to be 1 byte
-char x_char = 0;
-char y_char = 'y'; // Char literals are quoted with ''
-
-// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
-// 64 bits
-long x_long = 0;
-long long x_long_long = 0;
-
-// floats are usually 32-bit floating point numbers
-float x_float = 0.0;
-
-// doubles are usually 64-bit floating-point numbers
-double x_double = 0.0;
-
-// Integral types may be unsigned. This means they can't be negative, but
-// the maximum value of an unsigned variable is greater than the maximum
-// signed value of the same size.
-unsigned char ux_char;
-unsigned short ux_short;
-unsigned int ux_int;
-unsigned long long ux_long_long;
-
-// Other than char, which is always 1 byte, these types vary in size depending
-// on your machine. sizeof(T) gives you the size of a variable with type T in
-// bytes so you can express the size of these types in a portable way.
-// For example,
-printf("%lu\n", sizeof(int)); // => 4 (on machines with 4-byte words)
-
-// Arrays must be initialized with a concrete size.
-char my_char_array[20]; // This array occupies 1 * 20 = 20 bytes
-int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes
- // (assuming 4-byte words)
-
-
-// You can initialize an array to 0 thusly:
-char my_array[20] = {0};
-
-// Indexing an array is like other languages -- or,
-// rather, other languages are like C
-my_array[0]; // => 0
-
-// Arrays are mutable; it's just memory!
-my_array[1] = 2;
-printf("%d\n", my_array[1]); // => 2
-
-// Strings are just arrays of chars terminated by a NUL (0x00) byte,
-// represented in strings as the special character '\0'.
-// (We don't have to include the NUL byte in string literals; the compiler
-// inserts it at the end of the array for us.)
-char a_string[20] = "This is a string";
-printf("%s\n", a_string); // %s formats a string
-
-/*
-You may have noticed that a_string is only 16 chars long.
-Char #17 is the NUL byte.
-Chars #18, 19 and 20 have undefined values.
-*/
-
-printf("%d\n", a_string[16]); // => 0
-
-///////////////////////////////////////
-// Operators
-///////////////////////////////////////
-
-int i1 = 1, i2 = 2; // Shorthand for multiple declaration
-float f1 = 1.0, f2 = 2.0;
-
-// Arithmetic is straightforward
-i1 + i2; // => 3
-i2 - i1; // => 1
-i2 * i1; // => 2
-i1 / i2; // => 0 (0.5, but truncated towards 0)
-
-f1 / f2; // => 0.5, plus or minus epsilon
-
-// Modulo is there as well
-11 % 3; // => 2
-
-// Comparison operators are probably familiar, but
-// there is no boolean type in c. We use ints instead.
-// 0 is false, anything else is true. (The comparison
-// operators always return 0 or 1.)
-3 == 2; // => 0 (false)
-3 != 2; // => 1 (true)
-3 > 2; // => 1
-3 < 2; // => 0
-2 <= 2; // => 1
-2 >= 2; // => 1
-
-// Logic works on ints
-!3; // => 0 (Logical not)
-!0; // => 1
-1 && 1; // => 1 (Logical and)
-0 && 1; // => 0
-0 || 1; // => 1 (Logical or)
-0 || 0; // => 0
-
-// Bitwise operators!
-~0x0F; // => 0xF0 (bitwise negation)
-0x0F & 0xF0; // => 0x00 (bitwise AND)
-0x0F | 0xF0; // => 0xFF (bitwise OR)
-0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
-0x01 << 1; // => 0x02 (bitwise left shift (by 1))
-0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
-
-///////////////////////////////////////
-// Control Structures
-///////////////////////////////////////
-
-if (0) {
- printf("I am never run\n");
-} else if (0) {
- printf("I am also never run\n");
-} else {
- printf("I print\n");
-}
-
-// While loops exist
-int ii = 0;
-while (ii < 10) {
- printf("%d, ", ii++); // ii++ increments ii in-place, after using its value.
-} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-
-printf("\n");
-
-int kk = 0;
-do {
- printf("%d, ", kk);
-} while (++kk < 10); // ++kk increments kk in-place, before using its value
-// => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-
-printf("\n");
-
-// For loops too
-int jj;
-for (jj=0; jj < 10; jj++) {
- printf("%d, ", jj);
-} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-
-printf("\n");
-
-///////////////////////////////////////
-// Typecasting
-///////////////////////////////////////
+ // While loops exist
+ int ii = 0;
+ while (ii < 10) { //ANY value not zero is true.
+ printf("%d, ", ii++); // ii++ increments ii AFTER using it's current value.
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-// Every value in C has a type, but you can cast one value into another type
-// if you want.
+ printf("\n");
-int x_hex = 0x01; // You can assign vars with hex literals
+ int kk = 0;
+ do {
+ printf("%d, ", kk);
+ } while (++kk < 10); // ++kk increments kk BEFORE using it's current value.
+ // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-// Casting between types will attempt to preserve their numeric values
-printf("%d\n", x_hex); // => Prints 1
-printf("%d\n", (short) x_hex); // => Prints 1
-printf("%d\n", (char) x_hex); // => Prints 1
+ printf("\n");
-// Types will overflow without warning
-printf("%d\n", (char) 257); // => 1 (Max char = 255)
+ // For loops too
+ int jj;
+ for (jj=0; jj < 10; jj++) {
+ printf("%d, ", jj);
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-// Integral types can be cast to floating-point types, and vice-versa.
-printf("%f\n", (float)100); // %f formats a float
-printf("%lf\n", (double)100); // %lf formats a double
-printf("%d\n", (char)100.0);
+ printf("\n");
-///////////////////////////////////////
-// Pointers
-///////////////////////////////////////
+ // *****NOTES*****:
+ // Loops and Functions MUST have a body. If no body is needed:
+ int i;
+ for (i = 0; i <= 5; i++) {
+ ; // use semicolon to act as the body (null statement)
+ }
-// A pointer is a variable declared to store a memory address. Its declaration will
-// also tell you the type of data it points to. You can retrieve the memory address
-// of your variables, then mess with them.
-
-int x = 0;
-printf("%p\n", &x); // Use & to retrieve the address of a variable
-// (%p formats a pointer)
-// => Prints some address in memory;
-
-// Pointer types end with * in their declaration
-int* px; // px is a pointer to an int
-px = &x; // Stores the address of x in px
-printf("%p\n", px); // => Prints some address in memory
-
-// To retreive the value at the address a pointer is pointing to,
-// put * in front to de-reference it.
-printf("%d\n", *px); // => Prints 0, the value of x, which is what px is pointing to the address of
-
-// You can also change the value the pointer is pointing to.
-// We'll have to wrap the de-reference in parenthesis because
-// ++ has a higher precedence than *.
-(*px)++; // Increment the value px is pointing to by 1
-printf("%d\n", *px); // => Prints 1
-printf("%d\n", x); // => Prints 1
-
-int x_array[20]; // Arrays are a good way to allocate a contiguous block of memory
-int xx;
-for (xx=0; xx<20; xx++) {
- x_array[xx] = 20 - xx;
-} // Initialize x_array to 20, 19, 18,... 2, 1
-
-// Declare a pointer of type int and initialize it to point to x_array
-int* x_ptr = x_array;
-// x_ptr now points to the first element in the array (the integer 20).
-// This works because arrays are actually just pointers to their first element.
-
-// Arrays are pointers to their first element
-printf("%d\n", *(x_ptr)); // => Prints 20
-printf("%d\n", x_array[0]); // => Prints 20
-
-// Pointers are incremented and decremented based on their type
-printf("%d\n", *(x_ptr + 1)); // => Prints 19
-printf("%d\n", x_array[1]); // => Prints 19
-
-// You can also dynamically allocate contiguous blocks of memory with the
-// standard library function malloc, which takes one integer argument
-// representing the number of bytes to allocate from the heap.
-int* my_ptr = (int*) malloc(sizeof(int) * 20);
-for (xx=0; xx<20; xx++) {
- *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx would also work here
-} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
-
-// Dereferencing memory that you haven't allocated gives
-// unpredictable results
-printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what?
-
-// When you're done with a malloc'd block of memory, you need to free it,
-// or else no one else can use it until your program terminates
-free(my_ptr);
-
-// Strings can be char arrays, but are usually represented as char
-// pointers:
-char* my_str = "This is my very own string";
-
-printf("%c\n", *my_str); // => 'T'
-
-function_1();
+ // branching with multiple choices: switch()
+ switch (some_integral_expression) {
+ case 0: // labels need to be integral *constant* epxressions
+ do_stuff();
+ break; // if you don't break, control flow falls over labels
+ case 1:
+ do_something_else();
+ break;
+ default:
+ // if `some_integral_expression` didn't match any of the labels
+ fputs("error!\n", stderr);
+ exit(-1);
+ break;
+ }
+
+
+ ///////////////////////////////////////
+ // Typecasting
+ ///////////////////////////////////////
+
+ // Every value in C has a type, but you can cast one value into another type
+ // if you want (with some constraints).
+
+ int x_hex = 0x01; // You can assign vars with hex literals
+
+ // Casting between types will attempt to preserve their numeric values
+ printf("%d\n", x_hex); // => Prints 1
+ printf("%d\n", (short) x_hex); // => Prints 1
+ printf("%d\n", (char) x_hex); // => Prints 1
+
+ // Types will overflow without warning
+ printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
+
+ // For determining the max value of a `char`, a `signed char` and an `unisigned char`,
+ // respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h>
+
+ // Integral types can be cast to floating-point types, and vice-versa.
+ printf("%f\n", (float)100); // %f formats a float
+ printf("%lf\n", (double)100); // %lf formats a double
+ printf("%d\n", (char)100.0);
+
+ ///////////////////////////////////////
+ // Pointers
+ ///////////////////////////////////////
+
+ // A pointer is a variable declared to store a memory address. Its declaration will
+ // also tell you the type of data it points to. You can retrieve the memory address
+ // of your variables, then mess with them.
+
+ int x = 0;
+ printf("%p\n", (void *)&x); // Use & to retrieve the address of a variable
+ // (%p formats an object pointer of type void *)
+ // => Prints some address in memory;
+
+
+ // Pointers start with * in their declaration
+ int *px, not_a_pointer; // px is a pointer to an int
+ px = &x; // Stores the address of x in px
+ printf("%p\n", (void *)px); // => Prints some address in memory
+ printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
+ // => Prints "8, 4" on a typical 64-bit system
+
+ // To retrieve the value at the address a pointer is pointing to,
+ // put * in front to de-reference it.
+ // Note: yes, it may be confusing that '*' is used for _both_ declaring a
+ // pointer and dereferencing it.
+ printf("%d\n", *px); // => Prints 0, the value of x
+
+ // You can also change the value the pointer is pointing to.
+ // We'll have to wrap the de-reference in parenthesis because
+ // ++ has a higher precedence than *.
+ (*px)++; // Increment the value px is pointing to by 1
+ printf("%d\n", *px); // => Prints 1
+ printf("%d\n", x); // => Prints 1
+
+ // Arrays are a good way to allocate a contiguous block of memory
+ int x_array[20]; //declares array of size 20 (cannot change size)
+ int xx;
+ for (xx = 0; xx < 20; xx++) {
+ x_array[xx] = 20 - xx;
+ } // Initialize x_array to 20, 19, 18,... 2, 1
+
+ // Declare a pointer of type int and initialize it to point to x_array
+ int* x_ptr = x_array;
+ // x_ptr now points to the first element in the array (the integer 20).
+ // This works because arrays often decay into pointers to their first element.
+ // For example, when an array is passed to a function or is assigned to a pointer,
+ // it decays into (implicitly converted to) a pointer.
+ // Exceptions: when the array is the argument of the `&` (address-od) operator:
+ int arr[10];
+ int (*ptr_to_arr)[10] = &arr; // &arr is NOT of type `int *`!
+ // It's of type "pointer to array" (of ten `int`s).
+ // or when the array is a string literal used for initializing a char array:
+ char arr[] = "foobarbazquirk";
+ // 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"
+
+
+ // Pointers are incremented and decremented based on their type
+ // (this is called pointer arithmetic)
+ printf("%d\n", *(x_ptr + 1)); // => Prints 19
+ printf("%d\n", x_array[1]); // => Prints 19
+
+ // You can also dynamically allocate contiguous blocks of memory with the
+ // standard library function malloc, which takes one argument of type size_t
+ // representing the number of bytes to allocate (usually from the heap, although this
+ // may not be true on e. g. embedded systems - the C standard says nothing about it).
+ int *my_ptr = malloc(sizeof(*my_ptr) * 20);
+ for (xx = 0; xx < 20; xx++) {
+ *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
+ } // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
+
+ // Dereferencing memory that you haven't allocated gives
+ // "unpredictable results" - the program is said to invoke "undefined behavior"
+ printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what? It may even crash.
+
+ // When you're done with a malloc'd block of memory, you need to free it,
+ // or else no one else can use it until your program terminates
+ // (this is called a "memory leak"):
+ free(my_ptr);
+
+ // Strings are arrays of char, but they are usually represented as a
+ // pointer-to-char (which is a pointer to the first element of the array).
+ // It's good practice to use `const char *' when referring to a string literal,
+ // since string literals shall not be modified (i. e. "foo"[0] = 'a' is ILLEGAL.)
+ const char *my_str = "This is my very own string literal";
+ printf("%c\n", *my_str); // => 'T'
+
+ // This is not the case if the string is an array
+ // (potentially initialized with a string literal)
+ // that resides in writable memory, as in:
+ char foo[] = "foo";
+ foo[0] = 'a'; // this is legal, foo now contains "aoo"
+
+ function_1();
} // end main function
///////////////////////////////////////
@@ -297,22 +425,29 @@ function_1();
// Function declaration syntax:
// <return type> <function name>(<args>)
-int add_two_ints(int x1, int x2){
+int add_two_ints(int x1, int x2)
+{
return x1 + x2; // Use return to return a value
}
/*
-Functions are pass-by-value, but you can make your own references
-with pointers so functions can mutate their values.
+Functions are call by value. When a function is called, the arguments passed to
+the function are copies of the original arguments (except arrays). Anything you
+do to the arguments in the function do not change the value of the original
+argument where the function was called.
+
+Use pointers if you need to edit the original argument values.
Example: in-place string reversal
*/
// A void function returns no value
-void str_reverse(char* str_in){
+void str_reverse(char *str_in)
+{
char tmp;
- int ii=0, len = strlen(str_in); // Strlen is part of the c standard library
- for(ii=0; ii<len/2; ii++){
+ int ii = 0;
+ size_t len = strlen(str_in); // `strlen()` is part of the c standard library
+ for (ii = 0; ii < len / 2; ii++) {
tmp = str_in[ii];
str_in[ii] = str_in[len - ii - 1]; // ii-th char from end
str_in[len - ii - 1] = tmp;
@@ -325,6 +460,21 @@ str_reverse(c);
printf("%s\n", c); // => ".tset a si sihT"
*/
+//if referring to external variables outside function, must use extern keyword.
+int i = 0;
+void testFunc() {
+ extern int i; //i here is now using external variable i
+}
+
+//make external variables private to source file with static:
+static int i = 0; //other files using testFunc() cannot access variable i
+void testFunc() {
+ extern int i;
+}
+//**You may also declare functions as static to make them private**
+
+
+
///////////////////////////////////////
// User-defined types and structs
///////////////////////////////////////
@@ -333,15 +483,20 @@ printf("%s\n", c); // => ".tset a si sihT"
typedef int my_type;
my_type my_type_var = 0;
-// Structs are just collections of data
+// Structs are just collections of data, the members are allocated sequentially,
+// in the order they are written:
struct rectangle {
int width;
int height;
};
+// It's not generally true that
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int)
+// due to potential padding between the structure members (this is for alignment
+// reasons). [1]
-void function_1(){
-
+void function_1()
+{
struct rectangle my_rec;
// Access struct members with .
@@ -349,37 +504,46 @@ void function_1(){
my_rec.height = 20;
// You can declare pointers to structs
- struct rectangle* my_rec_ptr = &my_rec;
+ struct rectangle *my_rec_ptr = &my_rec;
// Use dereferencing to set struct pointer members...
(*my_rec_ptr).width = 30;
- // ... or use the -> shorthand
+ // ... or even better: prefer the -> shorthand for the sake of readability
my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10;
}
// You can apply a typedef to a struct for convenience
typedef struct rectangle rect;
-int area(rect r){
+int area(rect r)
+{
return r.width * r.height;
}
+// if you have large structs, you can pass them "by pointer" to avoid copying
+// the whole struct:
+int area(const rect *r)
+{
+ return r->width * r->height;
+}
+
///////////////////////////////////////
// Function pointers
///////////////////////////////////////
/*
At runtime, functions are located at known memory addresses. Function pointers are
-much likely any other pointer (they just store a memory address), but can be used
+much like any other pointer (they just store a memory address), but can be used
to invoke functions directly, and to pass handlers (or callback functions) around.
However, definition syntax may be initially confusing.
Example: use str_reverse from a pointer
*/
-void str_reverse_through_pointer(char * str_in) {
+void str_reverse_through_pointer(char *str_in) {
// Define a function pointer variable, named f.
void (*f)(char *); // Signature should exactly match the target function.
f = &str_reverse; // Assign the address for the actual function (determined at runtime)
+ // f = str_reverse; would work as well - functions decay into pointers, similar to arrays
(*f)(str_in); // Just calling the function through the pointer
// f(str_in); // That's an alternative but equally valid syntax for calling it.
}
@@ -391,16 +555,81 @@ Function pointers are usually typedef'd for simplicity and readability, as follo
typedef void (*my_fnp_type)(char *);
-// The used when declaring the actual pointer variable:
+// Then used when declaring the actual pointer variable:
// ...
// my_fnp_type f;
+//Special characters:
+'\a' // alert (bell) character
+'\n' // newline character
+'\t' // tab character (left justifies text)
+'\v' // vertical tab
+'\f' // new page (formfeed)
+'\r' // carriage return
+'\b' // backspace character
+'\0' // null character. Usually put at end of strings in C lang.
+ // hello\n\0. \0 used by convention to mark end of string.
+'\\' // backslash
+'\?' // question mark
+'\'' // single quote
+'\"' // double quote
+'\xhh' // hexadecimal number. Example: '\xb' = vertical tab character
+'\ooo' // octal number. Example: '\013' = vertical tab character
+
+//print formatting:
+"%d" // integer
+"%3d" // integer with minimum of length 3 digits (right justifies text)
+"%s" // string
+"%f" // float
+"%ld" // long
+"%3.2f" // minimum 3 digits left and 2 digits right decimal float
+"%7.4s" // (can do with strings too)
+"%c" // char
+"%p" // pointer
+"%x" // hexidecimal
+"%o" // octal
+"%%" // prints %
+
+///////////////////////////////////////
+// Order of Evaluation
+///////////////////////////////////////
+
+//---------------------------------------------------//
+// Operators | Associativity //
+//---------------------------------------------------//
+// () [] -> . | left to right //
+// ! ~ ++ -- + = *(type)sizeof | right to left //
+// * / % | left to right //
+// + - | left to right //
+// << >> | left to right //
+// < <= > >= | left to right //
+// == != | left to right //
+// & | left to right //
+// ^ | left to right //
+// | | left to right //
+// && | left to right //
+// || | left to right //
+// ?: | right to left //
+// = += -= *= /= %= &= ^= |= <<= >>= | right to left //
+// , | left to right //
+//---------------------------------------------------//
+
```
## Further Reading
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
+It is *the* book about C, written by the creators of C. Be careful, though - it's ancient and it contains some
+inaccuracies (well, ideas that are not considered good anymore) or now-changed practices.
+
+Another good resource is [Learn C the hard way](http://c.learncodethehardway.org/book/).
-Another good resource is [Learn C the hard way](http://c.learncodethehardway.org/book/)
+If you have a question, read the [compl.lang.c Frequently Asked Questions](http://c-faq.com).
+
+It's very important to use proper spacing, indentation and to be consistent with your coding style in general.
+Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the
+[Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
Other than that, Google is your friend.
+
+[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
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/clojure.html.markdown b/clojure.html.markdown
index 6baae0ce..7917ab08 100644
--- a/clojure.html.markdown
+++ b/clojure.html.markdown
@@ -63,7 +63,7 @@ and often automatically.
; If you want to create a literal list of data, use ' to stop it from
; being evaluated
'(+ 1 2) ; => (+ 1 2)
-; (shorthand for (quote (+ 1 2))
+; (shorthand for (quote (+ 1 2)))
; You can eval a quoted list
(eval '(+ 1 2)) ; => 3
@@ -205,7 +205,7 @@ keymap ; => {:a 1, :c 3, :b 2}
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
-; Retrieving a non-present value returns nil
+; Retrieving a non-present key returns nil
(stringmap "d") ; => nil
; Use assoc to add new keys to hash-maps
@@ -341,7 +341,7 @@ keymap ; => {:a 1, :b 2, :c 3}
(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)
- ; Use '@' to dereference the atom and get the value
+; Use '@' to dereference the atom and get the value
my-atom ;=> Atom<#...> (Returns the Atom object)
@my-atom ; => {:a 1 :b 2}
@@ -365,7 +365,7 @@ my-atom ;=> Atom<#...> (Returns the Atom object)
### Further Reading
-This is far from exhaustive, but hopefully it's enought o get you on your feet.
+This is far from exhaustive, but hopefully it's enough to get you on your feet.
Clojure.org has lots of articles:
[http://clojure.org/](http://clojure.org/)
@@ -376,5 +376,5 @@ Clojuredocs.org has documentation with examples for most core functions:
4Clojure is a great way to build your clojure/FP skills:
[http://www.4clojure.com/](http://www.4clojure.com/)
-Clojure-doc.org (yeah, really) has a number of getting started articles:
+Clojure-doc.org (yes, really) has a number of getting started articles:
[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/coffeescript.html.markdown b/coffeescript.html.markdown
index 429f10b5..4fdf5903 100644
--- a/coffeescript.html.markdown
+++ b/coffeescript.html.markdown
@@ -2,13 +2,19 @@
language: coffeescript
contributors:
- ["Tenor Biel", "http://github.com/L8D"]
+ - ["Xavier Yao", "http://github.com/xavieryao"]
filename: coffeescript.coffee
---
+CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime.
+As one of the succeeders of JavaScript, CoffeeScript tries its best to output readable, pretty-printed and smooth-running JavaScript codes working well in every JavaScript runtime.
+
+See also [the CoffeeScript website](http://coffeescript.org/), which has a complete tutorial on CoffeeScript.
+
``` coffeescript
# CoffeeScript is a hipster language.
# It goes with the trends of many modern languages.
-# So comments are like Ruby and Python, they use hashes.
+# So comments are like Ruby and Python, they use number symbols.
###
Block comments are like these, and they translate directly to '/ *'s and '* /'s
@@ -28,6 +34,17 @@ number = -42 if opposite #=> if(opposite) { number = -42; }
# Functions:
square = (x) -> x * x #=> var square = function(x) { return x * x; }
+fill = (container, liquid = "coffee") ->
+ "Filling the #{container} with #{liquid}..."
+#=>var fill;
+#
+#fill = function(container, liquid) {
+# if (liquid == null) {
+# liquid = "coffee";
+# }
+# return "Filling the " + container + " with " + liquid + "...";
+#};
+
# Ranges:
list = [1..5] #=> var list = [1, 2, 3, 4, 5];
@@ -45,11 +62,36 @@ math =
# Splats:
race = (winner, runners...) ->
print winner, runners
+#=>race = function() {
+# var runners, winner;
+# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+# return print(winner, runners);
+#};
# Existence:
alert "I knew it!" if elvis?
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
# Array comprehensions:
-cubes = (math.cube num for num in list) #=> ...
+cubes = (math.cube num for num in list)
+#=>cubes = (function() {
+# var _i, _len, _results;
+# _results = [];
+# for (_i = 0, _len = list.length; _i < _len; _i++) {
+# num = list[_i];
+# _results.push(math.cube(num));
+# }
+# return _results;
+# })();
+
+foods = ['broccoli', 'spinach', 'chocolate']
+eat food for food in foods when food isnt 'chocolate'
+#=>foods = ['broccoli', 'spinach', 'chocolate'];
+#
+#for (_k = 0, _len2 = foods.length; _k < _len2; _k++) {
+# food = foods[_k];
+# if (food !== 'chocolate') {
+# eat(food);
+# }
+#}
```
diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown
new file mode 100644
index 00000000..8de81549
--- /dev/null
+++ b/common-lisp.html.markdown
@@ -0,0 +1,622 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+---
+
+ANSI Common Lisp is a general purpose, multi-paradigm programming
+language suited for a wide variety of industry applications. It is
+frequently referred to as a programmable programming language.
+
+The classic starting point is [Practical Common Lisp and freely available.](http://www.gigamonkeys.com/book/)
+
+Another popular and recent book is
+[Land of Lisp](http://landoflisp.com/).
+
+
+
+```scheme
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 0. Syntax
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; General form.
+
+;; Lisp has two fundamental pieces of syntax: the ATOM and the
+;; S-expression. Typically, grouped S-expressions are called `forms`.
+
+10 ; an atom; it evaluates to itself
+
+:THING ;Another atom; evaluating to the symbol :thing.
+
+t ; another atom, denoting true.
+
+(+ 1 2 3 4) ; an s-expression
+
+'(4 :foo t) ;another one
+
+
+;;; Comments
+
+;; Single line comments start with a semicolon; use two for normal
+;; comments, three for section comments, and four for file-level
+;; comments.
+
+#| Block comments
+ can span multiple lines and...
+ #|
+ they can be nested!
+ |#
+|#
+
+;;; Environment.
+
+;; A variety of implementations exist; most are
+;; standard-conformant. CLISP is a good starting one.
+
+;; Libraries are managed through Quicklisp.org's Quicklisp system.
+
+;; Common Lisp is usually developed with a text editor and a REPL
+;; (Read Evaluate Print Loop) running at the same time. The REPL
+;; allows for interactive exploration of the program as it is "live"
+;; in the system.
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 1. Primitive Datatypes and Operators
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Symbols
+
+'foo ; => FOO Notice that the symbol is upper-cased automatically.
+
+;; Intern manually creates a symbol from a string.
+
+(intern "AAAA") ; => AAAA
+
+(intern "aaa") ; => |aaa|
+
+;;; Numbers
+9999999999999999999999 ; integers
+#b111 ; binary => 7
+#o111 ; octal => 73
+#x111 ; hexadecimal => 273
+3.14159s0 ; single
+3.14159d0 ; double
+1/2 ; ratios
+#C(1 2) ; complex numbers
+
+
+;; Function application is written (f x y z ...)
+;; where f is a function and x, y, z, ... are operands
+;; If you want to create a literal list of data, use ' to stop it from
+;; being evaluated - literally, "quote" the data.
+'(+ 1 2) ; => (+ 1 2)
+;; You can also call a function manually:
+(funcall #'+ 1 2 3) ; => 6
+;; Some arithmetic operations
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+ ;;; Booleans
+t ; for true (any not-nil value is true)
+nil ; for false - and the empty list
+(not nil) ; => t
+(and 0 t) ; => t
+(or 0 nil) ; => 0
+
+ ;;; Characters
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Strings are fixed-length arrays of characters.
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; backslash is an escaping character
+
+;; Strings can be concatenated too!
+(concatenate 'string "Hello " "world!") ; => "Hello world!"
+
+;; A string can be treated like a sequence of characters
+(elt "Apple" 0) ; => #\A
+
+;; format can be used to format strings:
+(format nil "~a can be ~a" "strings" "formatted")
+
+;; Printing is pretty easy; ~% is the format specifier for newline.
+(format t "Common Lisp is groovy. Dude.~%")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Variables
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; You can create a global (dynamically scoped) using defparameter
+;; a variable name can use any character except: ()",'`;#|\
+
+;; Dynamically scoped variables should have earmuffs in their name!
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;; You can also use unicode characters.
+(defparameter *AΛB* nil)
+
+
+;; Accessing a previously unbound variable is an
+;; undefined behavior (but possible). Don't do it.
+
+
+;; Local binding: `me` is bound to "dance with you" only within the
+;; (let ...). Let always returns the value of the last `form` in the
+;; let form.
+
+(let ((me "dance with you"))
+ me)
+;; => "dance with you"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Structs and Collections
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Structs
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+
+(dog-p *rover*) ; => t ;; ewww)
+(dog-name *rover*) ; => "rover"
+
+;; Dog-p, make-dog, and dog-name are all created by defstruct!
+
+;;; Pairs
+;; `cons' constructs pairs, `car' and `cdr' extract the first
+;; and second elements
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+;;; Lists
+
+;; Lists are linked-list data structures, made of `cons' pairs and end
+;; with a `nil' (or '()) to mark the end of the list
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+;; `list' is a convenience variadic constructor for lists
+(list 1 2 3) ; => '(1 2 3)
+;; and a quote can also be used for a literal list value
+'(1 2 3) ; => '(1 2 3)
+
+;; Can still use `cons' to add an item to the beginning of a list
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; Use `append' to - surprisingly - append lists together
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; Or use concatenate -
+
+(concatenate 'list '(1 2) '(3 4))
+
+;; Lists are a very central type, so there is a wide variety of functionality for
+;; them, a few examples:
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => nil
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Vectors
+
+;; Vector's literals are fixed-length arrays
+#(1 2 3) ; => #(1 2 3)
+
+;; Use concatenate to add vectors together
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; Arrays
+
+;; Both vectors and strings are special-cases of arrays.
+
+;; 2D arrays
+
+(make-array (list 2 2))
+
+;; (make-array '(2 2)) works as well.
+
+; => #2A((0 0) (0 0))
+
+(make-array (list 2 2 2))
+
+; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;; Caution- the default initial values are
+;; implementation-defined. Here's how to define them:
+
+(make-array '(2) :initial-element 'unset)
+
+; => #(UNSET UNSET)
+
+;; And, to access the element at 1,1,1 -
+(aref (make-array (list 2 2 2)) 1 1 1)
+
+; => 0
+
+;;; Adjustable vectors
+
+;; Adjustable vectors have the same printed representation
+;; as fixed-length vector's literals.
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+
+*adjvec* ; => #(1 2 3)
+
+;; Adding new element:
+(vector-push-extend 4 *adjvec*) ; => 3
+
+*adjvec* ; => #(1 2 3 4)
+
+
+
+;;; Naively, sets are just lists:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;; But you'll want to use a better data structure than a linked list
+;; for performant work!
+
+;;; Dictionaries are implemented as hash tables.
+
+;; Create a hash table
+(defparameter *m* (make-hash-table))
+
+;; set a value
+(setf (gethash 'a *m*) 1)
+
+;; Retrieve a value
+(gethash 'a *m*) ; => 1, t
+
+;; Detail - Common Lisp has multiple return values possible. gethash
+;; returns t in the second value if anything was found, and nil if
+;; not.
+
+;; Retrieving a non-present value returns nil
+ (gethash 'd *m*) ;=> nil, nil
+
+;; You can provide a default value for missing keys
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;; Let's handle the multiple return values here in code.
+
+(multiple-value-bind
+ (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind
+ (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Use `lambda' to create anonymous functions.
+;; A function always returns the value of its last expression.
+;; The exact printable representation of a function will vary...
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;; Use funcall to call lambda functions
+(funcall (lambda () "Hello World")) ; => "Hello World"
+
+;; Or Apply
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;; De-anonymize the function
+(defun hello-world ()
+ "Hello World")
+(hello-world) ; => "Hello World"
+
+;; The () in the above is the list of arguments for the function
+(defun hello (name)
+ (format nil "Hello, ~a " name))
+
+(hello "Steve") ; => "Hello, Steve"
+
+;; Functions can have optional arguments; they default to nil
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~a, from ~a" name from)
+ (format t "Hello, ~a" name)))
+
+ (hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas
+
+;; And the defaults can be set...
+(defun hello (name &optional (from "The world"))
+ (format t "Hello, ~a, from ~a" name from))
+
+(hello "Steve")
+; => Hello, Steve, from The world
+
+(hello "Steve" "the alpacas")
+; => Hello, Steve, from the alpacas
+
+
+;; And of course, keywords are allowed as well... usually more
+;; flexible than &optional.
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~a ~a, from ~a" honorific name from))
+
+(generalized-greeter "Jim") ; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Equality
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Common Lisp has a sophisticated equality system. A couple are covered here.
+
+;; for numbers use `='
+(= 3 3.0) ; => t
+(= 2 1) ; => nil
+
+;; for object identity (approximately) use `eql`
+(eql 3 3) ; => t
+(eql 3 3.0) ; => nil
+(eql (list 3) (list 3)) ; => nil
+
+;; for lists, strings, and bit-vectors use `equal'
+(equal (list 'a 'b) (list 'a 'b)) ; => t
+(equal (list 'a 'b) (list 'b 'a)) ; => nil
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Control Flow
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Conditionals
+
+(if t ; test expression
+ "this is true" ; then expression
+ "this is false") ; else expression
+; => "this is true"
+
+;; In conditionals, all non-nil values are treated as true
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;; `cond' chains a series of tests to select a result
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;; Typecase switches on the type of the value
+(typecase 1
+ (string :string)
+ (integer :int))
+
+; => :int
+
+;;; Iteration
+
+;; Of course recursion is supported:
+
+(defun walker (n)
+ (if (zerop n)
+ :walked
+ (walker (1- n))))
+
+(walker) ; => :walked
+
+;; Most of the time, we use DOLIST or LOOP
+
+
+(dolist (i '(1 2 3 4))
+ (format t "~a" i))
+
+; => 1234
+
+(loop for i from 0 below 10
+ collect i)
+
+; => (0 1 2 3 4 5 6 7 8 9)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Mutation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Use `setf' to assign a new value to an existing variable. This was
+;; demonstrated earlier in the hash table example.
+
+(let ((variable 10))
+ (setf variable 2))
+ ; => 2
+
+
+;; Good Lisp style is to minimize destructive functions and to avoid
+;; mutation when reasonable.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Classes and Objects
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; No more Animal classes, let's have Human-Powered Mechanical
+;; Conveyances.
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;; defclass, followed by name, followed by the superclass list,
+;; followed by slot list, followed by optional qualities such as
+;; :documentation.
+
+;; When no superclass list is set, the empty list defaults to the
+;; standard-object class. This *can* be changed, but not until you
+;; know what you're doing. Look up the Art of the Metaobject Protocol
+;; for more information.
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+
+;; Calling DESCRIBE on the human-powered-conveyance class in the REPL gives:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;; Note the reflective behavior available to you! Common Lisp is
+;; designed to be an interactive system
+
+;; To define a method, let's find out what our circumference of the
+;; bike wheel turns out to be using the equation: C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;; pi is defined in Lisp already for us!
+
+;; Let's suppose we find out that the efficiency value of the number
+;; of rowers in a canoe is roughly logarithmic. This should probably be set
+;; in the constructor/initializer.
+
+;; Here's how to initialize your instance after Common Lisp gets done
+;; constructing it:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;; Then to construct an instance and check the average efficiency...
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. Macros
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Macros let you extend the syntax of the language
+
+;; Common Lisp doesn't come with a WHILE loop- let's add one.
+;; If we obey our assembler instincts, we wind up with:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)))
+ `(tagbody
+ (unless ,condition
+ (go ,block-name))
+ (progn
+ ,@body)
+ ,block-name)))
+
+;; Let's look at the high-level version of this:
+
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;; However, with a modern compiler, this is not required; the LOOP
+;; form compiles equally well and is easier to read.
+
+;; Note that ``` is used, as well as `,` and `@`. ``` is a quote-type operator
+;; known as quasiquote; it allows the use of `,` . `,` allows "unquoting"
+;; variables. @ interpolates lists.
+
+;; Gensym creates a unique symbol guaranteed to not exist elsewhere in
+;; the system. This is because macros are expanded at compile time and
+;; variables declared in the macro can collide with variables used in
+;; regular code.
+
+;; See Practical Common Lisp for more information on macros.
+```
+
+
+## Further Reading
+
+[Keep moving on to the Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
+
+
+## Credits.
+
+Lots of thanks to the Scheme people for rolling up a great starting
+point which could be easily moved to Common Lisp.
+
+- [Paul Khuong](https://github.com/pkhuong) for some great reviewing.
diff --git a/csharp.html.markdown b/csharp.html.markdown
new file mode 100644
index 00000000..81eb467d
--- /dev/null
+++ b/csharp.html.markdown
@@ -0,0 +1,806 @@
+---
+language: c#
+contributors:
+ - ["Irfan Charania", "https://github.com/irfancharania"]
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Melvyn Laïly", "http://x2a.yt"]
+ - ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
+filename: LearnCSharp.cs
+---
+
+C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework.
+
+[Read more here.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
+
+```c#
+// Single-line comments start with //
+/*
+Multi-line comments look like this
+*/
+/// <summary>
+/// This is an XML documentation comment
+/// </summary>
+
+// Specify namespaces application will be using
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Net;
+using System.Threading.Tasks;
+using System.IO;
+
+// defines scope to organize code into "packages"
+namespace Learning
+{
+ // Each .cs file should at least contain a class with the same name as the file
+ // you're allowed to do otherwise, but shouldn't for sanity.
+ public class LearnCSharp
+ {
+ // BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before
+ public static void Syntax()
+ {
+ // Use Console.WriteLine to print lines
+ Console.WriteLine("Hello World");
+ Console.WriteLine(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // To print without a new line, use Console.Write
+ Console.Write("Hello ");
+ Console.Write("World");
+
+ ///////////////////////////////////////////////////
+ // Types & Variables
+ //
+ // Declare a variable using <type> <name>
+ ///////////////////////////////////////////////////
+
+ // Sbyte - Signed 8-bit integer
+ // (-128 <= sbyte <= 127)
+ sbyte fooSbyte = 100;
+
+ // Byte - Unsigned 8-bit integer
+ // (0 <= byte <= 255)
+ byte fooByte = 100;
+
+ // Short - 16-bit integer
+ // Signed - (-32,768 <= short <= 32,767)
+ // Unsigned - (0 <= ushort <= 65,535)
+ short fooShort = 10000;
+ ushort fooUshort = 10000;
+
+ // Integer - 32-bit integer
+ int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
+ uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
+
+ // Long - 64-bit integer
+ long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
+ // Numbers default to being int or uint depending on size.
+ // L is used to denote that this variable value is of type long or ulong
+
+ // Double - Double-precision 64-bit IEEE 754 Floating Point
+ double fooDouble = 123.4; // Precision: 15-16 digits
+
+ // Float - Single-precision 32-bit IEEE 754 Floating Point
+ float fooFloat = 234.5f; // Precision: 7 digits
+ // f is used to denote that this variable value is of type float
+
+ // Decimal - a 128-bits data type, with more precision than other floating-point types,
+ // suited for financial and monetary calculations
+ decimal fooDecimal = 150.3m;
+
+ // Boolean - true & false
+ bool fooBoolean = true; // or false
+
+ // Char - A single 16-bit Unicode character
+ char fooChar = 'A';
+
+ // Strings -- unlike the previous base types which are all value types,
+ // a string is a reference type. That is, you can set it to null
+ string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
+ Console.WriteLine(fooString);
+
+ // You can access each character of the string with an indexer:
+ char charFromString = fooString[1]; // => 'e'
+ // Strings are immutable: you can't do fooString[1] = 'X';
+
+ // Compare strings with current culture, ignoring case
+ string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
+
+ // Formatting, based on sprintf
+ string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
+
+ // Dates & Formatting
+ DateTime fooDate = DateTime.Now;
+ Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+
+ // You can split a string over two lines with the @ symbol. To escape " use ""
+ string bazString = @"Here's some stuff
+on a new line! ""Wow!"", the masses cried";
+
+ // Use const or read-only to make a variable immutable
+ // const values are calculated at compile time
+ const int HOURS_I_WORK_PER_WEEK = 9001;
+
+ ///////////////////////////////////////////////////
+ // Data Structures
+ ///////////////////////////////////////////////////
+
+ // Arrays - zero indexed
+ // The array size must be decided upon declaration
+ // The format for declaring an array is follows:
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+
+ // Another way to declare & initialize an array
+ int[] y = { 9000, 1000, 1337 };
+
+ // Indexing an array - Accessing an element
+ Console.WriteLine("intArray @ 0: " + intArray[0]);
+ // Arrays are mutable.
+ intArray[1] = 1;
+
+ // Lists
+ // Lists are used more frequently than arrays as they are more flexible
+ // The format for declaring a list is follows:
+ // List<datatype> <var name> = new List<datatype>();
+ List<int> intList = new List<int>();
+ List<string> stringList = new List<string>();
+ List<int> z = new List<int> { 9000, 1000, 1337 }; // intialize
+ // The <> are for generics - Check out the cool stuff section
+
+ // Lists don't default to a value;
+ // A value must be added before accessing the index
+ intList.Add(1);
+ Console.WriteLine("intList @ 0: " + intList[0]);
+
+ // Others data structures to check out:
+ // Stack/Queue
+ // Dictionary (an implementation of a hash map)
+ // HashSet
+ // Read-only Collections
+ // Tuple (.Net 4+)
+
+ ///////////////////////////////////////
+ // Operators
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Shorthand for multiple declarations
+
+ // Arithmetic is straightforward
+ Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
+
+ // Modulo
+ Console.WriteLine("11%3 = " + (11 % 3)); // => 2
+
+ // Comparison operators
+ Console.WriteLine("3 == 2? " + (3 == 2)); // => false
+ Console.WriteLine("3 != 2? " + (3 != 2)); // => true
+ Console.WriteLine("3 > 2? " + (3 > 2)); // => true
+ Console.WriteLine("3 < 2? " + (3 < 2)); // => false
+ Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
+ Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
+
+ // Bitwise operators!
+ /*
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
+ */
+
+ // Incrementations
+ int i = 0;
+ Console.WriteLine("\n->Inc/Dec-rementation");
+ Console.WriteLine(i++); //i = 1. Post-Incrementation
+ Console.WriteLine(++i); //i = 2. Pre-Incrementation
+ Console.WriteLine(i--); //i = 1. Post-Decrementation
+ Console.WriteLine(--i); //i = 0. Pre-Decrementation
+
+ ///////////////////////////////////////
+ // Control Structures
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Control Structures");
+
+ // If statements are c-like
+ int j = 10;
+ if (j == 10)
+ {
+ Console.WriteLine("I get printed");
+ }
+ else if (j > 10)
+ {
+ Console.WriteLine("I don't");
+ }
+ else
+ {
+ Console.WriteLine("I also don't");
+ }
+
+ // Ternary operators
+ // A simple if/else can be written as follows
+ // <condition> ? <true> : <false>
+ string isTrue = (true) ? "True" : "False";
+
+ // While loop
+ int fooWhile = 0;
+ while (fooWhile < 100)
+ {
+ //Iterated 100 times, fooWhile 0->99
+ fooWhile++;
+ }
+
+ // Do While Loop
+ int fooDoWhile = 0;
+ do
+ {
+ //Iterated 100 times, fooDoWhile 0->99
+ fooDoWhile++;
+ } while (fooDoWhile < 100);
+
+ //for loop structure => for(<start_statement>; <conditional>; <step>)
+ for (int fooFor = 0; fooFor < 10; fooFor++)
+ {
+ //Iterated 10 times, fooFor 0->9
+ }
+
+ // For Each Loop
+ // foreach loop structure => foreach(<iteratorType> <iteratorName> in <enumerable>)
+ // The foreach loop loops over any object implementing IEnumerable or IEnumerable<T>
+ // All the collection types (Array, List, Dictionary...) in the .Net framework
+ // implement one or both of these interfaces.
+ // (The ToCharArray() could be removed, because a string also implements IEnumerable)
+ foreach (char character in "Hello World".ToCharArray())
+ {
+ //Iterated over all the characters in the string
+ }
+
+ // Switch Case
+ // A switch works with the byte, short, char, and int data types.
+ // It also works with enumerated types (discussed in Enum Types),
+ // the String class, and a few special classes that wrap
+ // primitive types: Character, Byte, Short, and Integer.
+ int month = 3;
+ string monthString;
+ switch (month)
+ {
+ case 1:
+ monthString = "January";
+ break;
+ case 2:
+ monthString = "February";
+ break;
+ case 3:
+ monthString = "March";
+ break;
+ // You can assign more than one case to an action
+ // But you can't add an action without a break before another case
+ // (if you want to do this, you would have to explicitly add a goto case x
+ case 6:
+ case 7:
+ case 8:
+ monthString = "Summer time!!";
+ break;
+ default:
+ monthString = "Some other month";
+ break;
+ }
+
+ ///////////////////////////////////////
+ // Converting Data Types And Typecasting
+ ///////////////////////////////////////
+
+ // Converting data
+
+ // Convert String To Integer
+ // this will throw an Exception on failure
+ int.Parse("123");//returns an integer version of "123"
+
+ // try parse will default to type default on failure
+ // in this case: 0
+ int tryInt;
+ if (int.TryParse("123", out tryInt)) // Funciton is boolean
+ Console.WriteLine(tryInt); // 123
+
+ // Convert Integer To String
+ // Convert class has a number of methods to facilitate conversions
+ Convert.ToString(123);
+ // or
+ tryInt.ToString();
+ }
+
+ ///////////////////////////////////////
+ // CLASSES - see definitions at end of file
+ ///////////////////////////////////////
+ public static void Classes()
+ {
+ // See Declaration of objects at end of file
+
+ // Use new to instantiate a class
+ Bicycle trek = new Bicycle();
+
+ // Call object methods
+ trek.SpeedUp(3); // You should always use setter and getter methods
+ trek.Cadence = 100;
+
+ // ToString is a convention to display the value of this Object.
+ Console.WriteLine("trek info: " + trek.Info());
+
+ // Instantiate a new Penny Farthing
+ PennyFarthing funbike = new PennyFarthing(1, 10);
+ Console.WriteLine("funbike info: " + funbike.Info());
+
+ Console.Read();
+ } // End main method
+
+ // CONSOLE ENTRY A console application must have a main method as an entry point
+ public static void Main(string[] args)
+ {
+ OtherInterestingFeatures();
+ }
+
+ //
+ // INTERESTING FEATURES
+ //
+
+ // DEFAULT METHOD SIGNATURES
+
+ public // Visibility
+ static // Allows for direct call on class without object
+ int // Return Type,
+ MethodSignatures(
+ int maxCount, // First variable, expects an int
+ int count = 0, // will default the value to 0 if not passed in
+ int another = 3,
+ params string[] otherParams // captures all other parameters passed to method
+ )
+ {
+ return -1;
+ }
+
+ // Methods can have the same name, as long as the signature is unique
+ public static void MethodSignature(string maxCount)
+ {
+ }
+
+ // GENERICS
+ // The classes for TKey and TValue is specified by the user calling this function.
+ // This method emulates the SetDefault of Python
+ public static TValue SetDefault<TKey, TValue>(
+ IDictionary<TKey, TValue> dictionary,
+ TKey key,
+ TValue defaultItem)
+ {
+ TValue result;
+ if (!dictionary.TryGetValue(key, out result))
+ return dictionary[key] = defaultItem;
+ return result;
+ }
+
+ // You can narrow down the objects that are passed in
+ public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
+ {
+ // We can iterate, since T is a IEnumerable
+ foreach (var item in toPrint)
+ // Item is an int
+ Console.WriteLine(item.ToString());
+ }
+
+ public static void OtherInterestingFeatures()
+ {
+ // OPTIONAL PARAMETERS
+ MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
+ MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones
+
+ // EXTENSION METHODS
+ int i = 3;
+ i.Print(); // Defined below
+
+ // NULLABLE TYPES - great for database interaction / return values
+ // any value type (i.e. not a class) can be made nullable by suffixing a ?
+ // <type>? <var name> = <value>
+ int? nullable = null; // short hand for Nullable<int>
+ Console.WriteLine("Nullable variable: " + nullable);
+ bool hasValue = nullable.HasValue; // true if not null
+
+ // ?? is syntactic sugar for specifying default value (coalesce)
+ // in case variable is null
+ int notNullable = nullable ?? 0; // 0
+
+ // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
+ var magic = "magic is a string, at compile time, so you still get type safety";
+ // magic = 9; will not work as magic is a string, not an int
+
+ // GENERICS
+ //
+ var phonebook = new Dictionary<string, string>() {
+ {"Sarah", "212 555 5555"} // Add some entries to the phone book
+ };
+
+ // Calling SETDEFAULT defined as a generic above
+ Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No Phone
+ // nb, you don't need to specify the TKey and TValue since they can be
+ // derived implicitly
+ Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
+
+ // LAMBDA EXPRESSIONS - allow you to write code in line
+ Func<int, int> square = (x) => x * x; // Last T item is the return value
+ Console.WriteLine(square(3)); // 9
+
+ // DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily.
+ // Most of objects that access unmanaged resources (file handle, device contexts, etc.)
+ // implement the IDisposable interface. The using statement takes care of
+ // cleaning those IDisposable objects for you.
+ using (StreamWriter writer = new StreamWriter("log.txt"))
+ {
+ writer.WriteLine("Nothing suspicious here");
+ // At the end of scope, resources will be released.
+ // Even if an exception is thrown.
+ }
+
+ // PARALLEL FRAMEWORK
+ // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
+ var websites = new string[] {
+ "http://www.google.com", "http://www.reddit.com",
+ "http://www.shaunmccarthy.com"
+ };
+ var responses = new Dictionary<string, string>();
+
+ // Will spin up separate threads for each request, and join on them
+ // before going to the next step!
+ Parallel.ForEach(websites,
+ new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
+ website =>
+ {
+ // Do something that takes a long time on the file
+ using (var r = WebRequest.Create(new Uri(website)).GetResponse())
+ {
+ responses[website] = r.ContentType;
+ }
+ });
+
+ // This won't happen till after all requests have been completed
+ foreach (var key in responses.Keys)
+ Console.WriteLine("{0}:{1}", key, responses[key]);
+
+ // DYNAMIC OBJECTS (great for working with other languages)
+ dynamic student = new ExpandoObject();
+ student.FirstName = "First Name"; // No need to define class first!
+
+ // You can even add methods (returns a string, and takes in a string)
+ student.Introduce = new Func<string, string>(
+ (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
+ Console.WriteLine(student.Introduce("Beth"));
+
+ // IQUERYABLE<T> - almost all collections implement this, which gives you a lot of
+ // very useful Map / Filter / Reduce style methods
+ var bikes = new List<Bicycle>();
+ bikes.Sort(); // Sorts the array
+ bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels
+ var result = bikes
+ .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type)
+ .Where(b => b.IsBroken && b.HasTassles)
+ .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable<string>
+
+ var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection
+
+ // Create a list of IMPLICIT objects based on some parameters of the bike
+ var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
+ // Hard to show here, but you get type ahead completion since the compiler can implicitly work
+ // out the types above!
+ foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
+ Console.WriteLine(bikeSummary.Name);
+
+ // ASPARALLEL
+ // And this is where things get wicked - combines linq and parallel operations
+ var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
+ // this will happen in parallel! Threads will automagically be spun up and the
+ // results divvied amongst them! Amazing for large datasets when you have lots of
+ // cores
+
+ // LINQ - maps a store to IQueryable<T> objects, with delayed execution
+ // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document
+ var db = new BikeRespository();
+
+ // execution is delayed, which is great when querying a database
+ var filter = db.Bikes.Where(b => b.HasTassles); // no query run
+ if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality
+ filter = filter.Where(b => b.IsBroken); // no query run
+
+ var query = filter
+ .OrderBy(b => b.Wheels)
+ .ThenBy(b => b.Name)
+ .Select(b => b.Name); // still no query run
+
+ // Now the query runs, but opens a reader, so only populates are you iterate through
+ foreach (string bike in query)
+ Console.WriteLine(result);
+
+
+
+ }
+
+ } // End LearnCSharp class
+
+ // You can include other classes in a .cs file
+
+ public static class Extensions
+ {
+ // EXTENSION FUNCTIONS
+ public static void Print(this object obj)
+ {
+ Console.WriteLine(obj.ToString());
+ }
+ }
+
+ // Class Declaration Syntax:
+ // <public/private/protected/internal> class <class name>{
+ // //data fields, constructors, functions all inside.
+ // //functions are called as methods in Java.
+ // }
+
+ public class Bicycle
+ {
+ // Bicycle's Fields/Variables
+ public int Cadence // Public: Can be accessed from anywhere
+ {
+ get // get - define a method to retrieve the property
+ {
+ return _cadence;
+ }
+ set // set - define a method to set a proprety
+ {
+ _cadence = value; // Value is the value passed in to the setter
+ }
+ }
+ private int _cadence;
+
+ protected virtual int Gear // Protected: Accessible from the class and subclasses
+ {
+ get; // creates an auto property so you don't need a member field
+ set;
+ }
+
+ internal int Wheels // Internal: Accessible from within the assembly
+ {
+ get;
+ private set; // You can set modifiers on the get/set methods
+ }
+
+ int _speed; // Everything is private by default: Only accessible from within this class.
+ // can also use keyword private
+ public string Name { get; set; }
+
+ // Enum is a value type that consists of a set of named constants
+ // It is really just mapping a name to a value (an int, unless specified otherwise).
+ // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
+ // An enum can't contain the same value twice.
+ public enum BikeBrand
+ {
+ AIST,
+ BMC,
+ Electra = 42, //you can explicitly set a value to a name
+ Gitane // 43
+ }
+ // We defined this type inside a Bicycle class, so it is a nested type
+ // Code outside of this class should reference this type as Bicycle.Brand
+
+ public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type
+
+ // Static members belong to the type itself rather then specific object.
+ // You can access them without a reference to any object:
+ // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
+ static public int BicyclesCreated = 0;
+
+ // readonly values are set at run time
+ // they can only be assigned upon declaration or in a constructor
+ readonly bool _hasCardsInSpokes = false; // read-only private
+
+ // Constructors are a way of creating classes
+ // This is a default constructor
+ public Bicycle()
+ {
+ this.Gear = 1; // you can access members of the object with the keyword this
+ Cadence = 50; // but you don't always need it
+ _speed = 5;
+ Name = "Bontrager";
+ Brand = BikeBrand.AIST;
+ BicyclesCreated++;
+ }
+
+ // This is a specified constructor (it contains arguments)
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ string name, bool hasCardsInSpokes, BikeBrand brand)
+ : base() // calls base first
+ {
+ Gear = startGear;
+ Cadence = startCadence;
+ _speed = startSpeed;
+ Name = name;
+ _hasCardsInSpokes = hasCardsInSpokes;
+ Brand = brand;
+ }
+
+ // Constructors can be chained
+ public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
+ this(startCadence, startSpeed, 0, "big wheels", true, brand)
+ {
+ }
+
+ // Function Syntax:
+ // <public/private/protected> <return type> <function name>(<args>)
+
+ // classes can implement getters and setters for their fields
+ // or they can implement properties (this is the preferred way in C#)
+
+ // Method parameters can have default values.
+ // In this case, methods can be called with these parameters omitted
+ public void SpeedUp(int increment = 1)
+ {
+ _speed += increment;
+ }
+
+ public void SlowDown(int decrement = 1)
+ {
+ _speed -= decrement;
+ }
+
+ // properties get/set values
+ // when only data needs to be accessed, consider using properties.
+ // properties may have either get or set, or both
+ private bool _hasTassles; // private variable
+ public bool HasTassles // public accessor
+ {
+ get { return _hasTassles; }
+ set { _hasTassles = value; }
+ }
+
+ // You can also define an automatic property in one line
+ // this syntax will create a backing field automatically.
+ // You can set an access modifier on either the getter or the setter (or both)
+ // to restrict its access:
+ public bool IsBroken { get; private set; }
+
+ // Properties can be auto-implemented
+ public int FrameSize
+ {
+ get;
+ // you are able to specify access modifiers for either get or set
+ // this means only Bicycle class can call set on Framesize
+ private set;
+ }
+
+ //Method to display the attribute values of this Object.
+ public virtual string Info()
+ {
+ return "Gear: " + Gear +
+ " Cadence: " + Cadence +
+ " Speed: " + _speed +
+ " Name: " + Name +
+ " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
+ "\n------------------------------\n"
+ ;
+ }
+
+ // Methods can also be static. It can be useful for helper methods
+ public static bool DidWeCreateEnoughBycles()
+ {
+ // Within a static method, we only can reference static class members
+ return BicyclesCreated > 9000;
+ } // If your class only needs static members, consider marking the class itself as static.
+
+
+ } // end class Bicycle
+
+ // PennyFarthing is a subclass of Bicycle
+ class PennyFarthing : Bicycle
+ {
+ // (Penny Farthings are those bicycles with the big front wheel.
+ // They have no gears.)
+
+ // calling parent constructor
+ public PennyFarthing(int startCadence, int startSpeed) :
+ base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
+ {
+ }
+
+ protected override int Gear
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ throw new ArgumentException("You can't change gears on a PennyFarthing");
+ }
+ }
+
+ public override string Info()
+ {
+ string result = "PennyFarthing bicycle ";
+ result += base.ToString(); // Calling the base version of the method
+ return result;
+ }
+ }
+
+ // Interfaces only contain signatures of the members, without the implementation.
+ interface IJumpable
+ {
+ void Jump(int meters); // all interface members are implicitly public
+ }
+
+ interface IBreakable
+ {
+ bool Broken { get; } // interfaces can contain properties as well as methods & events
+ }
+
+ // Class can inherit only one other class, but can implement any amount of interfaces
+ class MountainBike : Bicycle, IJumpable, IBreakable
+ {
+ int damage = 0;
+
+ public void Jump(int meters)
+ {
+ damage += meters;
+ }
+
+ public bool Broken
+ {
+ get
+ {
+ return damage > 100;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Used to connect to DB for LinqToSql example.
+ /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
+ /// http://msdn.microsoft.com/en-us/data/jj193542.aspx
+ /// </summary>
+ public class BikeRespository : DbSet
+ {
+ public BikeRespository()
+ : base()
+ {
+ }
+
+ public DbSet<Bicycle> Bikes { get; set; }
+ }
+} // End Namespace
+```
+
+## Topics Not Covered
+
+ * Flags
+ * Attributes
+ * Static properties
+ * Exceptions, Abstraction
+ * ASP.NET (Web Forms/MVC/WebMatrix)
+ * Winforms
+ * Windows Presentation Foundation (WPF)
+
+## Further Reading
+
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
+ * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
+ * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
+ * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
+ * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+
+
+
+[C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
diff --git a/css.html.markdown b/css.html.markdown
new file mode 100644
index 00000000..cdef50cc
--- /dev/null
+++ b/css.html.markdown
@@ -0,0 +1,233 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+filename: learncss.css
+---
+
+In early days of web there was no visual elements, just pure text. But with the
+further development of browser fully visual web pages also became common.
+CSS is the standard language that exists to keep the separation between
+the content (HTML) and the look-and-feel of web pages.
+
+In short, what CSS does is to provide a syntax that enables you to target
+different elements on an HTML page and assign different visual properties to them.
+
+Like any other language, CSS has many versions. Here we focus on CSS2.0
+which is not the most recent but the most widely supported and compatible version.
+
+**NOTE:** Because the outcome of CSS is some visual effects, in order to
+learn it, you need try all different things in a
+CSS playground like [dabblet](http://dabblet.com/).
+The main focus of this article is on the syntax and some general tips.
+
+
+```css
+/* comments appear inside slash-asterisk, just like this line! */
+
+/* ####################
+ ## SELECTORS
+ ####################*/
+
+/* Generally, the primary statement in CSS is very simple */
+selector { property: value; /* more properties...*/ }
+
+/* the selector is used to target an element on page.
+
+You can target all elments on the page! */
+* { color:red; }
+
+/*
+Given an element like this on the page:
+
+<div class='some-class class2' id='someId' attr='value' />
+*/
+
+/* you can target it by its name */
+.some-class { }
+
+/*or by both classes! */
+.some-class.class2 { }
+
+/* or by its element name */
+div { }
+
+/* or its id */
+#someId { }
+
+/* or by the fact that it has an attribute! */
+[attr] { font-size:smaller; }
+
+/* or that the attribute has a specific value */
+[attr='value'] { font-size:smaller; }
+
+/* start with a value*/
+[attr^='val'] { font-size:smaller; }
+
+/* or ends with */
+[attr$='ue'] { font-size:smaller; }
+
+/* or even contains a value */
+[attr~='lu'] { font-size:smaller; }
+
+
+/* and more importantly you can combine these together -- there shouldn't be
+any spaaace between different parts because that makes it to have another
+meaning.*/
+div.some-class[attr$='ue'] { }
+
+/* you can also select an element based on its parent.*/
+
+/*an element which is direct child of an element (selected the same way) */
+div.some-parent > .class-name {}
+
+/* or any of its parents in the tree */
+/* the following basically means any element that has class "class-name"
+and is child of a div with class name "some-parent" IN ANY DEPTH */
+div.some-parent .class-name {}
+
+/* warning: the same selector wihout spaaace has another meaning.
+can you say what? */
+div.some-parent.class-name {}
+
+/* you also might choose to select an element based on its direct
+previous sibling */
+.i-am-before + .this-element { }
+
+/*or any sibling before this */
+.i-am-any-before ~ .this-element {}
+
+/* There are some pseudo classes that allows you to select an element
+based on its page behaviour (rather than page structure) */
+
+/* for example for when an element is hovered */
+:hover {}
+
+/* or a visited link*/
+:visited {}
+
+/* or not visited link*/
+:link {}
+
+/* or an input element which is focused */
+:focus {}
+
+
+/* ####################
+ ## PROPERTIES
+ ####################*/
+
+selector {
+
+ /* Units */
+ width: 50%; /* in percent */
+ font-size: 2em; /* times current font-size */
+ width: 200px; /* in pixels */
+ font-size: 20pt; /* in points */
+ width: 5cm; /* in centimeters */
+ width: 50mm; /* in millimeters */
+ width: 5in; /* in inches */
+
+ /* Colors */
+ background-color: #F6E; /* in short hex */
+ background-color: #F262E2; /* in long hex format */
+ background-color: tomato; /* can be a named color */
+ background-color: rgb(255, 255, 255); /* in rgb */
+ background-color: rgb(10%, 20%, 50%); /* in rgb percent */
+ background-color: rgba(255, 0, 0, 0.3); /* in semi-transparent rgb */
+
+ /* Images */
+ background-image: url(/path-to-image/image.jpg);
+
+ /* Fonts */
+ font-family: Arial;
+ font-family: "Courier New"; /* if name has spaaace it appears in double-quote */
+ font-family: "Courier New", Trebuchet, Arial; /* if first one was not found
+ browser uses the second font, and so forth */
+}
+
+```
+
+## Usage
+
+Save any CSS you want in a file with extension `.css`.
+
+```xml
+<!-- you need to include the css file in your page's <head>: -->
+<link rel='stylesheet' type='text/css' href='filepath/filename.css' />
+
+<!-- you can also include some CSS inline in your markup. However it is highly
+recommended to avoid this. -->
+<style>
+ selector { property:value; }
+</style>
+
+<!-- or directly set CSS properties on the element.
+This has to be avoided as much as you can. -->
+<div style='property:value;'>
+</div>
+
+```
+
+## Precedence
+
+As you noticed an element may be targetted by more than one selector.
+and may have a property set on it in more than one.
+In these cases, one of the rules takes precedence over others.
+
+Given the following CSS:
+
+```css
+/*A*/
+p.class1[attr='value']
+
+/*B*/
+p.class1 {}
+
+/*C*/
+p.class2 {}
+
+/*D*/
+p {}
+
+/*E*/
+p { property: value !important; }
+
+```
+
+and the following markup:
+
+```xml
+<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
+</p>
+```
+
+The precedence of style is as followed:
+Remember, the precedence is for each **property**, not for the entire block.
+
+* `E` has the highest precedence because of the keyword `!important`.
+ It is recommended to avoid this unless it is strictly necessary to use.
+* `F` is next, because it is inline style.
+* `A` is next, because it is more "specific" than anything else.
+ more specific = more specifiers. here 3 specifiers: 1 tagname `p` +
+ class name `class1` + 1 attribute `attr='value'`
+* `C` is next. although it has the same specificness as `B`
+ but it appears last.
+* Then is `B`
+* and lastly is `D`.
+
+## Compatibility
+
+Most of the features in CSS2 (and gradually in CSS3) are compatible across
+all browsers and devices. But it's always vital to have in mind the compatiblity
+of what you use in CSS with your target browsers.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) is one of the best sources for this.
+
+## Further Reading
+
+* [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/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown
new file mode 100644
index 00000000..ad782e06
--- /dev/null
+++ b/de-de/bash-de.html.markdown
@@ -0,0 +1,92 @@
+---
+category: tool
+tool: bash
+lang: de-de
+contributors:
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Darren Lin", "https://github.com/CogBear"]
+translators:
+ - ["kultprok", "http://www.kulturproktologie.de"]
+filename: LearnBash-de.sh
+---
+
+Bash ist der Name der Unix-Shell, die als Shell des GNU-Betriebssystems und auch als Standard-Shell von Linux und Mac OS X ausgeliefert wurde.
+Beinahe alle der folgenden Beispiele können als Teile eines Shell-Skripts oder direkt in der Shell ausgeführt werden.
+
+[Weitere Informationen \(Englisch\)](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# Die erste Zeile des Scripts nennt sich Shebang in gibt dem System an, wie
+# wie das Script ausgeführt werden soll: http://de.wikipedia.org/wiki/Shebang
+# Du hast es bestimmt schon mitgekriegt, Kommentare fangen mit # an. Das Shebang ist auch ein Kommentar
+
+# Ein einfaches Beispiel mit hello world:
+echo Hello, world!
+
+# Jeder Befehl fängt auf einer neuen Zeile oder nach einem Semikolon an:
+echo 'Dies ist die erste Zeile'; echo 'Dies die zweite Zeile'
+
+# Variablen deklariert man so:
+VARIABLE="irgendein String"
+
+# Aber nicht so:
+VARIABLE = "irgendein String"
+# Bash wird VARIABLE für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,
+# weil es den Befehl nicht findet.
+
+# Eine Variable wird so benutzt:
+echo $VARIABLE
+echo "$VARIABLE"
+# Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anders –,
+# dann über ihren Namen ohne $. Aber wenn du ihren zugewiesenen Wert willst, dann musst du $ voranstellen.
+
+# Einen Wert aus der Eingabe lesen:
+echo "Wie heisst du?"
+read NAME # Wir mussten nicht mal eine neue Variable deklarieren
+echo Hello, $NAME!
+
+# Wir haben die übliche if-Struktur:
+if true
+then
+ echo "Wie erwartet"
+else
+ echo "Und dies nicht"
+fi
+
+# Ausdrücke werden im folgenden Format festgehalten:
+echo $(( 10 + 5 ))
+
+# Anders als andere Programmiersprachen ist Bash eine Shell – es arbeitet also im Kontext von Verzeichnissen.
+# Du kannst alle Dateien und Verzeichnisse im aktiven Verzeichnis mit ls auflisten:
+ls
+
+# Diese Befehle haben Optionen, die ihre Ausführung beeinflussen:
+ls -l # Liste alle Dateien und Unterverzeichnisse auf einer eigenen Zeile auf
+
+# Ergebnisse eines vorangegangenen Befehls können an den nächsten Befehl als Input übergeben werden.
+# Der grep-Befehl filtert den Input nach dem vorgegebenen Muster. So können wir alle
+# txt-Dateien im aktuellen Verzeichnis auflisten:
+ls -l | grep "\.txt"
+
+# Befehle können innerhalb anderer Befehle mit $( ) erstetzt werden:
+# Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse
+# im aktuellen Verzeichnis an.
+echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse."
+
+# Bash nutzt einen case-Ausdruck, der sich ähnlich wie switch in Java oder C++ verhält.
+case "$VARIABLE"
+in
+ # Liste der Fälle, die unterschieden werden sollen
+ 0) echo "Hier ist eine Null."
+ 1) echo "Hier ist eine Eins."
+ *) echo "Das ist nicht Null."
+esac
+
+# loops iterieren über die angegebene Zahl von Argumenten:
+# Der Inhalt von $VARIABLE wird dreimal ausgedruckt.
+for $VARIABLE in x y z
+do
+ echo "$VARIABLE"
+done
+```
diff --git a/de-de/css-de.html.markdown b/de-de/css-de.html.markdown
new file mode 100644
index 00000000..8909b251
--- /dev/null
+++ b/de-de/css-de.html.markdown
@@ -0,0 +1,231 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+translators:
+ - ["Kyr", "http://github.com/kyrami"]
+lang: de-de
+filename: learncss-de.css
+---
+
+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/de-de/elixir-de.html.markdown b/de-de/elixir-de.html.markdown
new file mode 100644
index 00000000..29d5132d
--- /dev/null
+++ b/de-de/elixir-de.html.markdown
@@ -0,0 +1,419 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+translators:
+ - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
+filename: learnelixir-de.ex
+lang: de-de
+---
+
+Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
+kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
+viele Features mit.
+
+```ruby
+
+# Einzeilige Kommentare werden mit der Raute gesetzt.
+
+# Es gibt keine mehrzeiligen Kommentare;
+# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
+# zu setzen (so wie hier).
+
+# Mit 'iex' ruft man die Elixir-Shell auf.
+# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
+
+# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
+# installiert wurde.
+
+## ---------------------------
+## -- Basistypen
+## ---------------------------
+
+# Es gibt Nummern:
+3 # Integer
+0x1F # Integer
+3.0 # Float
+
+# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
+# ':'.
+:hello # Atom
+
+# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
+{1,2,3} # Tupel
+
+# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
+# werden:
+elem({1, 2, 3}, 0) # => 1
+
+# Listen sind als verkettete Listen implementiert.
+[1, 2, 3] # list
+
+# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
+[ kopf | rest ] = [1,2,3]
+kopf # => 1
+rest # => [2, 3]
+
+# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
+# (Musterabgleich) und keine Zuweisung.
+# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
+# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
+# werden.
+
+# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
+# zusammenpassen.
+# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
+# Elementen:
+{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
+
+# Es gibt außerdem 'binaries',
+<<1,2,3>> # binary.
+
+# Strings und 'char lists'
+"hello" # String
+'hello' # Char-Liste
+
+# ... und mehrzeilige Strings
+"""
+Ich bin ein
+mehrzeiliger String.
+"""
+#=> "Ich bin ein\nmehrzeiliger String.\n"
+
+# Alles Strings werden in UTF-8 enkodiert:
+"héllò" #=> "héllò"
+
+# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
+# Listen.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
+?a #=> 97
+
+# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'hello ' ++ 'world' #=> 'hello world'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"hello " <> "world" #=> "hello world"
+
+## ---------------------------
+## -- Operatoren
+## ---------------------------
+
+# Einfache Arithmetik
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
+
+# Für Division mit ganzzahligen Ergebnis gibt es 'div'
+div(10, 2) #=> 5
+
+# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
+rem(10, 3) #=> 1
+
+# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
+# Operatoren erwarten einen Boolean als erstes Argument.
+true and true #=> true
+false or true #=> true
+# 1 and true #=> ** (ArgumentError) argument error
+
+# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
+# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+
+!true #=> false
+
+# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
+# `<` und `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
+1 < :hello #=> true
+
+# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
+# number < atom < reference < functions < port < pid < tuple < list < bitstring
+
+# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
+# total ordering is well defined is important."
+
+## ---------------------------
+## -- Kontrollstrukturen
+## ---------------------------
+
+# Es gibt die `if`-Verzweigung
+if false do
+ "Dies wird nie jemand sehen..."
+else
+ "...aber dies!"
+end
+
+# ...und ebenso `unless`
+unless true do
+ "Dies wird nie jemand sehen..."
+else
+ "...aber dies!"
+end
+
+# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
+# arbeiten damit.
+
+# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
+case {:one, :two} do
+ {:four, :five} ->
+ "Das wird nicht passen"
+ {:one, x} ->
+ "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
+ _ ->
+ "Dieser Fall greift immer."
+end
+
+# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
+# nicht weiter verwendet wird.
+# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
+[kopf | _] = [1,2,3]
+kopf #=> 1
+
+# Für bessere Lesbarkeit können wir auch das Folgende machen:
+[kopf | _rest] = [:a, :b, :c]
+kopf #=> :a
+
+# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
+# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
+cond do
+ 1 + 1 == 3 ->
+ "Ich werde nie aufgerufen."
+ 2 * 5 == 12 ->
+ "Ich auch nicht."
+ 1 + 2 == 3 ->
+ "Aber ich!"
+end
+
+# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
+cond do
+ 1 + 1 == 3 ->
+ "Ich werde nie aufgerufen."
+ 2 * 5 == 12 ->
+ "Ich auch nicht."
+ true ->
+ "Aber ich! (dies ist im Grunde ein 'else')"
+end
+
+# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
+# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
+# egal ob zuvor ein Wert gefangen wurde.
+try do
+ throw(:hello)
+catch
+ nachricht -> "#{nachricht} gefangen."
+after
+ IO.puts("Ich bin die 'after'-Klausel.")
+end
+#=> Ich bin die 'after'-Klausel.
+# ":hello gefangen"
+
+## ---------------------------
+## -- Module und Funktionen
+## ---------------------------
+
+# Anonyme Funktionen (man beachte den Punkt)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
+# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
+# eingeführt:
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
+# Geltungsbereich ('scope') verfügbar.
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
+# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
+# definieren.
+defmodule Math do
+ def sum(a, b) do
+ a + b
+ end
+
+ def square(x) do
+ x * x
+ end
+end
+
+Math.sum(1, 2) #=> 3
+Math.square(3) #=> 9
+
+# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
+# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
+# werden: elixirc math.ex
+
+# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
+# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
+# werden; eine private Funktion kann nur lokal angesprochen werden.
+defmodule PrivateMath do
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
+defmodule Geometry do
+ def area({:rectangle, w, h}) do
+ w * h
+ end
+
+ def area({:circle, r}) when is_number(r) do
+ 3.14 * r * r
+ end
+end
+
+Geometry.area({:rectangle, 2, 3}) #=> 6
+Geometry.area({:circle, 3}) #=> 28.25999999999999801048
+# Geometry.area({:circle, "not_a_number"})
+#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
+
+# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
+# Bestandteil von Elixir.
+defmodule Recursion do
+ def sum_list([head | tail], acc) do
+ sum_list(tail, acc + head)
+ end
+
+ def sum_list([], acc) do
+ acc
+ end
+end
+
+Recursion.sum_list([1,2,3], 0) #=> 6
+
+# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
+# ist es möglich eigene Attribute hinzuzufügen.
+defmodule MyMod do
+ @moduledoc """
+ Dies ist ein eingebautes Attribut in einem Beispiel-Modul
+ """
+
+ @my_data 100 # Dies ist ein selbst-definiertes Attribut.
+ IO.inspect(@my_data) #=> 100
+end
+
+## ---------------------------
+## -- 'Records' und Ausnahmebehandlung
+## ---------------------------
+
+# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
+# Namen zuzuweisen.
+defrecord Person, name: nil, age: 0, height: 0
+
+joe_info = Person.new(name: "Joe", age: 30, height: 180)
+#=> Person[name: "Joe", age: 30, height: 180]
+
+# Zugriff auf den Wert von 'name'
+joe_info.name #=> "Joe"
+
+# Den Wert von 'age' überschreiben
+joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
+
+# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
+# um Ausnahmen beziehungsweise Fehler zu behandeln.
+try do
+ raise "Irgendein Fehler."
+rescue
+ RuntimeError -> "Laufzeit-Fehler gefangen."
+ _error -> "Und dies fängt jeden Fehler."
+end
+
+# Alle Ausnahmen haben das Attribut 'message'
+try do
+ raise "ein Fehler"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+
+## ---------------------------
+## -- Nebenläufigkeit
+## ---------------------------
+
+# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
+# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
+# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
+
+# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
+# wiederum eine Funktion als Argument entgegen nimmt.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
+# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
+# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
+# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
+# 'receive'-Mechanismus sichergestellt:
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Area = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Area = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
+# in der Shell mit, etwa so:
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+
+# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
+# erfüllt:
+pid <- {:rectangle, 2, 3}
+#=> Area = 6
+# {:rectangle,2,3}
+
+pid <- {:circle, 2}
+#=> Area = 12.56000000000000049738
+# {:circle,2}
+
+# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
+# die aktuelle pid herausfinden.
+self() #=> #PID<0.27.0>
+
+```
+
+## Referenzen und weitere Lektüre
+
+* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
+* [Elixir Documentation](http://elixir-lang.org/docs/master/)
+* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
+* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong
diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown
new file mode 100644
index 00000000..c7b6ad86
--- /dev/null
+++ b/de-de/git-de.html.markdown
@@ -0,0 +1,374 @@
+---
+category: tool
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+translators:
+ - ["kultprok", "http://www.kulturproktologie.de"]
+lang: de-de
+---
+
+Git ist eine verteilte Versions- und Quellcodeverwaltung.
+
+Es nimmt Schnappschüsse der Projekte, um mit diesen Schnappschüssen verschiedene Versionen unterscheiden und den Quellcode verwalten zu können.
+
+Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit* oder *Head* sind idiomatische Bestandteile im Umgang mit Git. Sie wurden nicht übersetzt.
+
+## Konzepte der Versionsverwaltung
+
+### Was ist Versionsverwaltung?
+
+Eine Versionskontrolle erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit.
+
+### Zentrale im Vergleich mit verteilter Versionverwaltung
+
+* Zentrale Versionskontrolle konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien.
+* Verteilte Versionskontrolle konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID.
+* Verteilte Systeme haben keine vorbestimmte Struktur. Ein SVN-ähnliches, zentrales System wäre mit Git ebenso umsetzbar.
+
+[Weiterführende Informationen](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Warum Git?
+
+* Ist offline einsetzbar.
+* Einfache Kollaboration!
+* Branching ist einfach!
+* Merging ist einfach!
+* Git ist schnell.
+* Git ist flexibel.
+
+## Die Architektur von Git
+
+
+### Repository (Repo)
+
+Ein Satz von Dateien, Verzeichnisen, Historieneinträgen, Commits und Heads. Stell es dir wie eine Quellcode-Datenstruktur vor, unter anderem mit der Eigenschaft, dass alle *Elemente* dir Zugriff auf die Revisionshistorie geben.
+
+Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichnis.
+
+### .git-Verzeichnis (Teil des Repositorys)
+
+Das .git-Verzeichnis enth? alle Einstellung, Logs, Branches, den HEAD und mehr.
+[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Arbeitsverzeichnis (Teil des Repositorys)
+
+Dies sind die Verzeichnisse und Dateien in deinem Repository.
+
+### Index (Teil des .git-Verzeichnisses)
+
+Der Index ist die die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht.
+
+### Commit
+
+Ein Commit ist ein Schnappschuss von Uderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositorys gepusht werden. Oder nicht!
+
+### Branch
+
+Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit, den du gemacht hast. Während des Commits wird der Pointer automatisch auf Stand gebracht und zeigt dann auf den neuen letzten Commit.
+
+### HEAD und head (Teil des .git-Verzeichnisses)
+
+HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD. Ein head ist ein Pointer, der auf ein beliebige Zahl von heads zeigt.
+
+### Konzeptionelle Hintergründe
+
+* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
+
+
+## Befehle
+
+
+### init
+
+Erstelle ein leeres Git-Repository. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt.
+
+```bash
+$ git init
+```
+
+### config
+
+Hiermit werden Einstellungen vorgenommen. Dies kann das Repository, das System selbst oder globale Einstellungen betreffen.
+
+```bash
+# Grundlegende Config-Variablen ausgeben und setzen
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[Mehr über git config](http://git-scm.com/docs/git-config)
+
+### help
+
+Schnellzugriff auf extrem detaillierte Anleitungen zu allen Befehlen. Oder als Erinnerung zu semantischen Eigenheiten.
+
+```bash
+# Übersicht gängiger Befehle
+$ git help
+
+# Übersicht aller verfügbaren Befehle
+$ git help -a
+
+# Befehlspezifische Hilfe - Bedienungsanleitung
+# git help <gesuchter_befehl>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Zeigt die Unterschiede zwischen Index (im Grunde dein Arbeitsverzeichnis/-repository) und dem aktuellen HEAD an.
+
+
+```bash
+# Zeigt den Branch, nicht-verfolgte Dateien, Uderungen und andere Unterschiede an
+$ git status
+
+# Anderes Wissenswertes über git status anzeigen
+$ git help status
+```
+
+### add
+
+Hinzufügen von Dateien zum Arbeitsverzeichnis/-repository. Wenn du neue Dateien nicht mit *git add* zum Arbeitsverzeichnis hinzufügst, werden sie nicht in den Commit aufgenommen!
+
+```bash
+# Fügt eine Datei deinem aktuellen Arbeitsverzeichnis hinzu
+$ git add HelloWorld.java
+
+# Fügt eine Datei aus einem verschachtelten Verzeichnis hinzu
+$ git add /path/to/file/HelloWorld.c
+
+# Reguläre Ausdrücke werden unterstützt!
+$ git add ./*.java
+```
+
+### branch
+
+Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erschaffen oder löschen.
+
+```bash
+# Liste alle bestehenden Branches und Remotes auf
+$ git branch -a
+
+# Erstelle einen neuen Branch
+$ git branch myNewBranch
+
+# Lösche einen Branch
+$ git branch -d myBranch
+
+# Benenne einen Branch um
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# Ändere die Beschreibung eines Branchs
+$ git branch myBranchName --edit-description
+```
+
+### checkout
+
+Bringt alle Dateien im Arbeitsverzeichnis auf den Stand des Index oder des angegebenen Branches.
+
+```bash
+# Ein Repo auschecken - wenn nicht anders angegeben ist das der master
+$ git checkout
+# Einen bestimmten Branch auschecken
+$ git checkout branchName
+# Erstelle einen neuen Branch und wechsle zu ihm. Wie: "git branch <name>; git checkout <name>"
+$ git checkout -b newBranch
+```
+
+### clone
+
+Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für hedes geklonte Repo remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen.
+
+```bash
+# Klone learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+```
+
+### commit
+
+Speichert die aktuellen Inhalte des Index in einen neuen *Commit*. Dieser Commit enthält alle Änderungen und eine vom Benutzer erstellte Beschreibung der Änderungen.
+
+```bash
+# Commit mit Beschreibung erstellen.
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+```
+
+### diff
+
+Zeigt die Unterschiede zwischen Dateien von Arbeitsverzeichnisse, dem Index und Commits an.
+
+```bash
+# Unterschiede zwischen deinem Arbeitsverzeichnis und dem Index anzeigen
+$ git diff
+
+# Unterschiede zwischen dem Index und dem aktuellsten Commit anzeigen
+$ git diff --cached
+
+# Unterschiede zwischen deinem Arbeitsverzeichnis und dem aktuellsten Commit anzeigen
+$ git diff HEAD
+```
+
+### grep
+
+Schnell ein Repository durchsuchen.
+
+Optionale Einstellungen:
+
+```bash
+# Vielen Dank an Travis Jeffery für die Hinweise.
+# Zeilennummerierung in grep-Suchergebnissen
+$ git config --global grep.lineNumber true
+
+# Suchergebnisse lesbarer gestalten, auch Gruppierungen sind möglich
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Suche nach "variableName" in allen java-Dateien
+$ git grep 'variableName' -- '*.java'
+
+# Suche nach eine Zeile, die "arrayListName" und "add" oder "remove" enthält
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Google ist dein Freund; für mehr Beispiele:
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Zeige Commits für das Repository an.
+
+```bash
+# Zeige alle Commits
+$ git log
+
+# Zeige die Anzahl n an Commits
+$ git log -n 10
+
+# Zeige nur Merges an
+$ git log --merges
+```
+
+### merge
+
+*Merge*, also verschmelze, alle Änderungen von externen Commits in den aktuellen Branch.
+
+```bash
+# Merge den angegebenen Branch in den aktuellen.
+$ git merge branchName
+
+# Erstelle immer einen Merge-Commit.
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Eine Datei umbenennen oder verschieben.
+
+```bash
+# Umbenennen
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Verschieben
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Umbenennung oder Verschieben erzwingen
+# "existingFile" besteht schon im Verzeichnis, wird überschrieben mit "myFile"
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Führe einen Pull, zieht alle Daten, eines Repositorys und f?? einen Merge mit einem anderen Branch durch.
+
+```bash
+# Update deines lokalen Repos, indem ein Merge der neuen Uderungen
+# von den remote-liegenden "origin"- und "master"-Branches durchgef?? wird.
+# git pull <remote> <branch>
+# git pull => impliziter Verweis auf origin und master
+$ git pull origin master
+
+# F?? einen Merge von Uderungen eines remote-Branch und ein Rebase
+# des Branch-Commits im lokalen Repo durch. Wie: pull <remote> <branch>, git rebase <branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Führe einen Push, ein Hochladen, und einen Merge von Änderungen eines remote-Branch mit einem Branch aus.
+
+```bash
+# Führe Push und Merge von Änderungen des lokalen Repo zu einem
+# remote-Branch namens "origin" und dem "master"-Branch aus.
+# git push <remote> <branch>
+# git push => impliziter Verweis auf => git push origin master
+$ git push origin master
+```
+
+### rebase (mit Vorsicht einsetzen)
+
+Nimm alle Änderungen, die in einem Branch durch Commits vorgenommen wurden, und übertrage sie auf einen anderen Branch. Achtung: Führe keinen Rebase von Commits durch, die auf ein öffentliches Repo gepusht wurden.
+
+```bash
+# Rebase "experimentBranch" in den "master"-Branch
+# git rebase <basisbranch> <themenbranch>
+$ git rebase master experimentBranch
+```
+
+[Weiterführende Informationen](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (mit Vorsicht einsetzen)
+
+Setze den aktuellen HEAD auf den angegebenen Zustand zurück. So können Merges, Pulls, Commits, Hinzufügungen und andere Änderungen rückgängig gemacht werden. Es ist ein hervorragender Befehl, aber auch sehr gefährlich, wenn du nicht weißt, was du tust.
+
+```bash
+# Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen (das Verzeichnis bleibt unberührt)
+$ git reset
+
+# Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen und überschreibe das Arbeitsverzeichnis
+$ git reset --hard
+
+# Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unber??)
+# Alle Uderungen bleiben im Verzeichnis erhalten
+$ git reset 31f2bb1
+
+# Bewegt die Spitze des Branches zurück zu dem angegebenen Commit
+# und gleicht die Arbeitsverzeichnisse ab (löscht nicht vom Commit erfasste Änderungen und alle Commits,
+# die dem angegebenen Commit folgen).
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+Das Gegenteil von *git add*. *git rm* löscht Dateien vom Arbeitsverzeichnis.
+
+```bash
+# Entferne HelloWorld.c
+$ git rm HelloWorld.c
+
+# Entferne eine Datei aus einem verschachtelten Verzeichnis
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Weiterführende Informationen
+
+* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video Tutorials](http://git-scm.com/videos)
+
+* [git-scm - Documentation](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
+
+* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/de-de/javascript-de.html.markdown b/de-de/javascript-de.html.markdown
new file mode 100644
index 00000000..0418b2b6
--- /dev/null
+++ b/de-de/javascript-de.html.markdown
@@ -0,0 +1,450 @@
+---
+language: javascript
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+translators:
+ - ["ggb", "http://www.ideen-und-soehne.de"]
+filename: learnjavascript-de.js
+lang: de-de
+---
+
+(Anmerkungen des Original-Autors:)
+JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzent zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java.
+
+Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, dass eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
+
+Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@adambrenecki](https://twitter.com/adambrenecki) oder [adam@brenecki.id.au](mailto:adam@brenecki.id.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.id.au).
+
+```js
+// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei
+// Slashes
+/* während mehrzeilige Kommentare mit einem
+Slash und einem Stern anfangen und enden */
+
+// Statements können mit einem Semikolon beendet werden
+machWas();
+
+// ...müssen sie aber nicht, weil Semikola automatisch eingefügt werden, wenn
+// eine neue Zeile beginnt, abgesehen von einigen Ausnahmen.
+machWas()
+
+// Obwohl wir uns für den Anfang nicht um diese Ausnahmen kümmern müssen ist
+// es besser die Semikola immer zu setzen.
+
+///////////////////////////////////
+// 1. Nummern, Strings und Operationen
+
+// JavaScript hat einen Nummern-Typ (64-bit IEEE 754 double).
+3; // = 3
+1.5; // = 1.5
+
+// Alle grundlegenden arithmetischen Operationen arbeiten wie erwartet.
+1 + 1; // = 2
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+
+// Division funktioniert auch mit einem Ergebnis nach dem Komma.
+5 / 2; // = 2.5
+
+// Bit-weise Operationen sind auch möglich; wenn eine Bit-weise Operation
+// ausgeführt wird, wird die Fließkomma-Zahl in einen 32-bit Integer (mit
+// Vorzeichen) umgewandelt.
+1 << 2; // = 4
+
+// Die Rangfolge der Operationen kann mit Klammern erzwungen werden.
+(1 + 3) * 2; // = 8
+
+// Es gibt drei spezielle, nicht-reale Nummern-Werte:
+Infinity; // Ergebnis von z. B. 1 / 0
+-Infinity; // Ergebnis von z. B. -1 / 0
+NaN; // Ergebnis von z. B. 0 / 0
+
+// Es gibt auch einen Boolean-Typ (für Wahrheitswerte).
+true;
+false;
+
+// Strings werden mit ' oder " erzeugt.
+'abc';
+"Hello, world";
+
+// Für die Negation wird das ! benutzt.
+!true; // = false
+!false; // = true
+
+// Gleichheit wird mit == geprüft.
+1 == 1; // = true
+2 == 1; // = false
+
+// Ungleichheit wird mit != überprüft.
+1 != 1; // = false
+2 != 1; // = true
+
+// Andere Vergleichsoperatoren sind
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
+
+// Strings können mit + verbunden
+"Hello " + "world!"; // = "Hello world!"
+
+// und mit < und > verglichen werden.
+"a" < "b"; // = true
+
+// Für den Vergleich von Werten wird eine Typumwandlung erzwungen...
+"5" == 5; // = true
+
+// ...solange man nicht === verwendet.
+"5" === 5; // = false
+
+// Auf einzelne Buchstaben innerhalb eines Strings kann mit der Methode
+// charAt zugegriffen werden
+"This is a string".charAt(0); // = "T"
+
+// Es gibt außerdem die Werte 'null' und 'undefined'
+null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen
+undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht
+ // verfügbar ist (obwohl genau genommen undefined selbst einen Wert
+ // darstellt)
+
+// false, null, undefined, NaN, 0 und "" sind 'falsy', d. h. alles andere ist
+// wahr. Man beachte, dass 0 falsch und "0" wahr ist, obwohl 0 == "0".
+
+///////////////////////////////////
+// 2. Variablen, Arrays und Objekte
+
+// Variablen werden mit dem Schlüsselwort 'var' und einem frei wählbaren
+// Bezeichner deklariert. JavaScript ist dynamisch typisiert, so dass man einer
+// Variable keinen Typ zuweisen muss. Die Zuweisung verwendet ein einfaches =.
+var einWert = 5;
+
+ // Wenn man das Schlüsselwort 'var' weglässt, bekommt man keinen Fehler
+einAndererWert = 10;
+
+// ...aber die Variable wird im globalen Kontext erzeugt, nicht in dem Kontext,
+// in dem sie erzeugt wurde.
+
+// Variablen die erzeugt wurden ohne ihnen einen Wert zuzuweisen, erhalten den
+// Wert 'undefined'.
+var einDritterWert; // = undefined
+
+// Es existiert eine Kurzform, um mathematische Operationen mit Variablen
+// auszuführen:
+einWert += 5; // äquivalent zu einWert = einWert + 5; einWert ist nun also 10
+einWert *= 10; // einWert ist nach dieser Operation 100
+
+// Und es existiert eine weitere, sogar noch kürzere Form, um 1 zu addieren
+// oder zu subtrahieren
+einWert++; // nun ist einWert 101
+einWert--; // wieder 100
+
+// Arrays sind geordnete Listen von Werten irgendeines Typs
+var myArray = ["Hello", 45, true];
+
+// Auf einzelne Elemente eines Arrays kann zugegriffen werden, in dem der Index
+// in eckigen Klammern hinter das Array geschrieben werden. Die Indexierung
+// beginnt bei 0.
+myArray[1]; // = 45
+
+// Die Objekte in JavaScript entsprechen 'dictionaries' oder 'maps' in anderen
+// Sprachen: es handelt sich um ungeordnete Schlüssel-Wert-Paare.
+var myObj = { key1: "Hello", key2: "World" };
+
+// Schlüssel sind Strings, aber es werden keine Anführungszeichen benötigt,
+// sofern es sich um reguläre JavaScript-Bezeichner handelt. Werte können von
+// jedem Typ sein.
+var myObj = { myKey: "myValue", "my other key": 4 };
+
+// Auf Attribute von Objekten kann ebenfalls mit eckigen Klammern zugegriffen
+// werden,
+myObj["my other key"]; // = 4
+
+// ... oder in dem man die Punkt-Notation verwendet, vorausgesetzt es handelt
+// sich bei dem Schlüssel um einen validen Bezeichner.
+myObj.myKey; // = "myValue"
+
+// Objekte sind veränderlich, Werte können verändert und neue Schlüssel
+// hinzugefügt werden.
+myObj.myThirdKey = true;
+
+// Der Zugriff auf einen noch nicht definierten Schlüssel, liefert ein
+// undefined.
+myObj.myFourthKey; // = undefined
+
+///////////////////////////////////
+// 3. Logik und Kontrollstrukturen
+
+// Die if-Struktur arbeitet, wie man es erwartet.
+var count = 1;
+if (count == 3){
+ // wird evaluiert, wenn count gleich 3 ist
+} else if (count == 4) {
+ // wird evaluiert, wenn count gleich 4 ist
+} else {
+ // wird evaluiert, wenn es weder 3 noch 4 ist
+}
+
+// Genauso 'while'.
+while (true) {
+ // Eine unendliche Schleife!
+}
+
+// Do-while-Scheifen arbeiten wie while-Schleifen, abgesehen davon, dass sie
+// immer mindestens einmal ausgeführt werden.
+var input;
+do {
+ input = getInput();
+} while ( !isValid( input ) )
+
+// Die for-Schleife arbeitet genau wie in C und Java:
+// Initialisierung; Bedingung, unter der die Ausführung fortgesetzt wird;
+// Iteration.
+for ( var i = 0; i < 5; i++ ) {
+ // wird 5-mal ausgeführt
+}
+
+// '&&' ist das logische und, '||' ist das logische oder
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear";
+ // Die Größe des Hauses ist groß und die Farbe blau.
+}
+if (colour == "red" || colour == "blue"){
+ // Die Farbe ist entweder rot oder blau.
+}
+
+// Die Auswertung von '&&' und '||' erfolgt so, dass abgebrochen wird, wenn die
+// Bedingung erfüllt ist (bei oder) oder nicht-erfüllt ist (bei und). Das ist
+// nützlich, um einen Default-Wert zu setzen.
+var name = otherName || "default";
+
+///////////////////////////////////
+// 4. Funktionen, Geltungsbereich und Closures
+
+// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert.
+function myFunction(thing){
+ return thing.toUpperCase();
+}
+myFunction("foo"); // = "FOO"
+
+// In JavaScript sind Funktionen 'Bürger erster Klasse', also können sie wie
+// Variablen verwendet und als Parameter anderen Funktionen übergeben werden
+// - zum Beispiel, um einen 'event handler' zu 'beliefern'.
+function myFunction() {
+ // wird ausgeführt, nachdem 5 Sekunden vergangen sind
+}
+setTimeout(myFunction, 5000);
+
+// Funktionen können auch deklariert werden, ohne ihnen einen Namen zuzuweisen.
+// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument
+// einer anderen Funktion zu definieren.
+setTimeout(function() {
+ // wird ausgeführt, nachdem 5 Sekunden vergangen sind
+}, 5000);
+
+// JavaScript hat einen Geltungsbereich, der sich auf Funktionen erstreckt:
+// Funktionen haben ihren eigenen Geltungsbereich, andere Blöcke nicht.
+if(true) {
+ var i = 5;
+}
+i; // = 5 - nicht undefined, wie man es von einer Sprache erwarten würde, die
+ // ihren Geltungsbereich nach Blöcken richtet
+
+// Daraus ergibt sich ein bestimmtes Muster für sofort-ausführbare, anonyme
+// Funktionen, die es vermeiden, dass der globale Geltungsbereich von Variablen
+// 'verschmutzt' wird.
+(function(){
+ var temporary = 5;
+ // Auf eine Variable im globalen Geltungsbereich kann zugegriffen werden,
+ // sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist
+ // dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js,
+ // kann das anders aussehen).
+ window.permanent = 10;
+})();
+temporary; // wirft einen ReferenceError
+permanent; // = 10
+
+// Eines der mächtigsten Charakteristika von JavaScript sind Closures. Wird
+// eine Funktion innerhalb einer anderen Funktion definiert, dann hat die
+// innere Funktion Zugriff auf alle Variablen der äußeren Funktion, sogar dann,
+// wenn die äußere Funktion beendet wurde.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!";
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds
+ // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
+ // aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
+ // Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
+ // Variable prompt.
+}
+sayHelloInFiveSeconds("Adam"); // wird nach 5 Sekunden ein Popup mit der
+ // Nachricht "Hello, Adam!" öffnen.
+
+///////////////////////////////////
+// 5. Mehr über Objekte, Konstruktoren und Prototypen
+
+// Objekte können Funktionen enthalten.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Wenn Funktionen aufgerufen werden, die zu einem Objekt gehören, können sie
+// auf das eigene Objekt mit dem Schlüsselwort 'this' zugreifen.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Worauf 'this' gesetzt wird, ist davon abhängig, wie die Funktion aufgerufen
+// wird, nicht wo sie definiert wurde. Unsere Funktion wird daher nicht
+// funktionieren, sofern sie außerhalb des Kontextes des Objekts aufgerufen
+// wird.
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+
+// Umgekehrt ist es möglich eine Funktion einem Objekt zuzuweisen und dadurch
+// Zugriff auf den this-Kontext zu erhalten, sogar dann, wenn die Funktion dem
+// Objekt nach dessen Definition zugewiesen wird.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+}
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// Wenn eine Funktion mit dem Schlüsselwort 'new' aufgerufen wird, dann wird
+// ein neues Objekt erzeugt. Funktionen, die darauf ausgelegt sind in dieser
+// Art aufgerufen zu werden, werden Konstruktoren genannt.
+var MyConstructor = function(){
+ this.myNumber = 5;
+}
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+
+// Jedes JavaScript-Objekt hat einen Prototyp. Wenn man versucht auf eine
+// Eigenschaft des Objekts zuzugreifen, das nicht im Objekt selbst existiert,
+// schaut der Interpreter in dessen Prototyp nach.
+
+// Einige JavaScript-Implementierungen erlauben den direkten Zugriff auf den
+// Prototyp eines Objekts durch die magische Eigenschaft __proto__. Obwohl das
+// nützlich ist, um Prototypen im Allgemeinen zu erklären, ist das nicht Teil
+// des Standards; zum Standard-Weg der Nutzung von Prototypen kommen wir
+// später.
+var myObj = {
+ myString: "Hello world!",
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+};
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+
+// Das funktioniert auch bei Funktionen.
+myObj.myFunc(); // = "hello world!"
+
+// Sollte die Eigenschaft nicht im Prototypen des Objekts enthalten sein, dann
+// wird im Prototypen des Prototypen nachgesehen und so weiter.
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+
+// Dafür wird nichts hin und her kopiert; jedes Objekt speichert eine Referenz
+// auf seinen Prototypen. Das heißt wenn der Prototyp geändert wird, dann
+// werden die Änderungen überall sichtbar.
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// Es wurde bereits erwähnt, dass __proto__ nicht zum Standard gehört und es
+// gibt ebenso keinen Standard-Weg, um den Prototyp eines existierenden Objekts
+// zu ändern. Es gibt dennoch zwei Wege, wie man ein neues Objekt mit einem
+// gegebenen Prototypen erzeugt.
+
+// Der erste Weg ist die Methode Object.create, die eine jüngere Ergänzung des
+// JavaScript-Standards ist und daher noch nicht in allen Implementierungen
+// verfügbar.
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// Der zweite Weg, der immer funktioniert, hat mit den Konstruktoren zu tun.
+// Konstruktoren haben eine Eigenschaft, die Prototyp heißt. Dabei handelt es
+// sich *nicht* um den Prototypen der Konstruktor-Funktion; stattdessen handelt
+// es sich um den Prototypen, der einem neuen Objekt mitgegeben wird, wenn es
+// mit dem Konstruktor und dem Schlüsselwort 'new' erzeugt wird.
+myConstructor.prototype = {
+ getMyNumber: function(){
+ return this.myNumber
+ }
+};
+var myNewObj2 = new myConstructor();
+myNewObj2.getMyNumber(); // = 5
+
+// Die eingebauten Typen, also strings und numbers, haben auch Konstruktoren,
+// die zu dem Typ äquivalente Wrapper-Objekte erzeugen.
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+
+// Genau genommen: Sie sind nicht exakt äquivalent.
+typeof(myNumber); // = 'number'
+typeof(myNumberObj); // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist.
+}
+if (Number(0)){
+ // Dieser Teil des Codes wird ausgeführt, weil Number(0) zu wahr evaluiert.
+}
+
+// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen
+// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen
+// hinzuzufügen.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+}
+"abc".firstCharacter(); // = "a"
+
+// Diese Tatsache wird häufig bei einer Methode mit dem Namen 'polyfilling'
+// verwendet: Dabei wird ein neues Feature von JavaScript in einer älteren
+// Untermenge der Sprache integriert, so dass bestimmte Funktionen auch in
+// älteren Umgebungen und Browsern verwendet werden können.
+
+// Ein Beispiel: Es wurde erwähnt, dass die Methode Object.create nicht in
+// allen Umgebungen verfügbar ist - wir können sie dennoch verwenden, mit einem
+// 'polyfill':
+if (Object.create === undefined){ // überschreib nichts, was eventuell bereits
+ // existiert
+ Object.create = function(proto){
+ // erstelle einen vorübergehenden Konstruktor mit dem richtigen
+ // Prototypen
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // verwende es dann, um ein neues Objekt mit einem passenden
+ // Prototypen zurückzugeben
+ return new Constructor();
+ }
+}
+```
+
+## Zur weiteren Lektüre (englisch)
+
+Das [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) bietet eine ausgezeichnete Dokumentation für die Verwendung von JavaScript im Browser. Es ist außerdem ein Wiki und ermöglicht es damit anderen zu helfen, wenn man selbst ein wenig Wissen angesammelt hat.
+
+MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) führt sehr viele der hier vorgestellten Konzepte im Detail aus.
+
+Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den Einsatz in Websites zu lernen, ist es ein guter Start etwas über das [Document Object Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) zu lernen.
+
+[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache.
+
+Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden.
diff --git a/de-de/python-de.html.markdown b/de-de/python-de.html.markdown
new file mode 100644
index 00000000..5ddb6f4b
--- /dev/null
+++ b/de-de/python-de.html.markdown
@@ -0,0 +1,487 @@
+---
+language: python
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["kultprok", "http:/www.kulturproktologie.de"]
+filename: learnpython-de.py
+lang: de-de
+---
+
+Anmerkungen des ursprünglichen Autors:
+Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
+
+Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service]
+
+Hinweis: Dieser Beitrag bezieht sich besonders auf Python 2.7, er sollte aber auf Python 2.x anwendbar sein. Haltet Ausschau nach einem Rundgang durch Python 3, der bald erscheinen soll.
+
+```python
+# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz)
+""" Mehrzeilige Strings werden mit
+ drei '-Zeichen geschrieben und werden
+ oft als Kommentare genutzt.
+"""
+
+####################################################
+## 1. Primitive Datentypen und Operatoren
+####################################################
+
+# Die Zahlen
+3 #=> 3
+
+# Mathematik funktioniert so, wie man das erwartet
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Division ist ein wenig kniffliger. Ganze Zahlen werden ohne Rest dividiert
+# und das Ergebnis wird automatisch abgerundet.
+5 / 2 #=> 2
+
+# Um das zu ändern, müssen wir Gleitkommazahlen einführen und benutzen
+2.0 # Das ist eine Gleitkommazahl
+11.0 / 4.0 #=> 2.75 Ahhh...schon besser
+
+# Rangfolge wird mit Klammern erzwungen
+(1 + 3) * 2 #=> 8
+
+# Boolesche Ausdrücke sind primitive Datentypen
+True
+False
+
+# Mit not wird negiert
+not True #=> False
+not False #=> True
+
+# Gleichheit ist ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Ungleichheit ist !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Ein paar weitere Vergleiche
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Vergleiche können verknüpft werden!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Strings werden mit " oder ' gebildet
+"Das ist ein String."
+'Das ist auch ein String.'
+
+# Strings können addiert werden!
+"Hello " + "world!" #=> "Hello world!"
+
+# Ein String kann wie eine Liste von Zeichen verwendet werden
+"Das ist ein String"[0] #=> 'D'
+
+# Mit % können Strings formatiert werden, etwa so:
+"%s können %s werden" % ("Strings", "interpoliert")
+
+# Ein modernerer Weg, um Strings zu formatieren, ist die format-Methode.
+# Diese Methode wird bevorzugt
+"{0} können {1} werden".format("Strings", "formatiert")
+# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen.
+"{name} will {food} essen".format(name="Bob", food="Lasagne")
+
+# None ist ein Objekt
+None #=> None
+
+# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen
+# Benutzt stattdessen `is`
+"etc" is None #=> False
+None is None #=> True
+
+# Der 'is'-Operator testet Objektidentität. Das ist nicht
+# sehr nützlich, wenn wir mit primitiven Datentypen arbeiten, aber
+# sehr nützlich bei Objekten.
+
+# None, 0, und leere Strings/Listen werden alle als False bewertet.
+# Alle anderen Werte sind True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variablen und Collections
+####################################################
+
+# Textausgabe ist sehr einfach
+print "Ich bin Python. Schön, dich kennenzulernen!"
+
+
+# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren.
+some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm
+some_var #=> 5
+
+# Das Ansprechen einer noch nicht deklarierte Variable löst eine Exception aus.
+# Unter "Kontrollstruktur" kann noch mehr über
+# Ausnahmebehandlung erfahren werden.
+some_other_var # Löst einen NameError aus
+
+# if kann als Ausdruck verwendet werden
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listen speichern Sequenzen
+li = []
+# Wir können mit einer bereits gefüllten Liste anfangen
+other_li = [4, 5, 6]
+
+# append fügt Daten am Ende der Liste ein
+li.append(1) #li ist jetzt [1]
+li.append(2) #li ist jetzt [1, 2]
+li.append(4) #li ist jetzt [1, 2, 4]
+li.append(3) #li ist jetzt [1, 2, 4, 3]
+# Vom Ende der Liste mit pop entfernen
+li.pop() #=> 3 und li ist jetzt [1, 2, 4]
+# und dann wieder hinzufügen
+li.append(3) # li ist jetzt wieder [1, 2, 4, 3].
+
+# Greife auf Listen wie auf Arrays zu
+li[0] #=> 1
+# Das letzte Element ansehen
+li[-1] #=> 3
+
+# Bei Zugriffen außerhal der Liste kommt es jedoch zu einem IndexError
+li[4] # Raises an IndexError
+
+# Wir können uns Ranges mit Slice-Syntax ansehen
+li[1:3] #=> [2, 4]
+# Den Anfang auslassen
+li[2:] #=> [4, 3]
+# Das Ende auslassen
+li[:3] #=> [1, 2, 4]
+
+# Ein bestimmtes Element mit del aus der Liste entfernen
+del li[2] # li ist jetzt [1, 2, 3]
+
+# Listen können addiert werden
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Hinweis: li und other_li werden in Ruhe gelassen
+
+# Listen mit extend verknüpfen
+li.extend(other_li) # Jetzt ist li [1, 2, 3, 4, 5, 6]
+
+# Mit in auf Existenz eines Elements prüfen
+1 in li #=> True
+
+# Die Länge der Liste mit len ermitteln
+len(li) #=> 6
+
+
+# Tupel sind wie Listen, nur unveränderlich.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Löst einen TypeError aus
+
+# Wir können all diese Listen-Dinge auch mit Tupeln anstellen
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Wir können Tupel (oder Listen) in Variablen entpacken
+a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3
+# Tuple werden standardmäßig erstellt, wenn wir uns die Klammern sparen
+d, e, f = 4, 5, 6
+# Es ist kinderleicht zwei Werte zu tauschen
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionarys (Wörterbucher) speichern Key-Value-Paare
+empty_dict = {}
+# Hier ein gefülltes Wörterbuch
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Wir können Einträge mit [] nachschlagen
+filled_dict["one"] #=> 1
+
+# So holen wir alle Keys (Schlüssel) als Liste
+filled_dict.keys() #=> ["three", "two", "one"]
+# Hinweis - Die Reihenfolge von Schlüsseln in der Liste ist nicht garantiert.
+# Einzelne Resultate können anders angeordnet sein.
+
+# Alle Values (Werte) als Liste
+filled_dict.values() #=> [3, 2, 1]
+# Hinweis - Hier gelten dieselben Einschränkungen für die Reihenfolge wie bei Schlüsseln.
+
+# Das Vorhandensein eines Schlüssels im Wörterbuch mit in prüfen
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus
+filled_dict["four"] # KeyError
+
+# Mit der get-Methode verhindern wir das
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# Die get-Methode unterstützt auch ein Standardargument, falls der Wert fehlt
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# Die setdefault-Methode ist ein sicherer Weg, ein neues Schlüssel-Wert-Paar anzulegen
+filled_dict.setdefault("five", 5) #filled_dict["five"] wird auf 5 gesetzt
+filled_dict.setdefault("five", 6) #filled_dict["five"] ist noch immer 5
+
+
+# Sets speichern Mengen
+empty_set = set()
+# Initialisieren wir ein Set mit ein paar Werten
+some_set = set([1,2,2,3,4]) # some_set ist jetzt set([1, 2, 3, 4])
+
+# Seit Python 2.7 kann {} benutzt werden, um ein Set zu erstellen
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Mehr Elemente hinzufügen
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# Schnittmengen werden mit & gebildet
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Mengen werden mit | vereinigt
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Die Differenz einer Menge mit - bilden
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Auf Vorhandensein von Elementen mit in prüfen
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Kontrollstruktur
+####################################################
+
+# Erstellen wir mal eine Variable
+some_var = 5
+
+# Hier eine if-Anweisung. Die Einrückung ist in Python wichtig!
+# gibt "some_var ist kleiner als 10" aus
+if some_var > 10:
+ print "some_var ist viel größer als 10."
+elif some_var < 10: # Dieser elif-Absatz ist optional.
+ print "some_var ist kleiner als 10."
+else: # Das hier ist auch optional.
+ print "some_var ist tatsächlich 10."
+
+
+"""
+For-Schleifen iterieren über Listen
+Ausgabe:
+ hund ist ein Säugetier
+ katze ist ein Säugetier
+ maus ist ein Säugetier
+"""
+for animal in ["hund", "katze", "maus"]:
+ # Wir können Strings mit % formatieren
+ print "%s ist ein Säugetier" % animal
+
+"""
+`range(Zahl)` gibt eine null-basierte Liste bis zur angegebenen Zahl wieder
+Ausgabe:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While-Schleifen laufen, bis eine Bedingung erfüllt ist.
+Ausgabe:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Kurzform für x = x + 1
+
+# Ausnahmebehandlung mit einem try/except-Block
+
+# Funktioniert in Python 2.6 und höher:
+try:
+ # Mit raise wird ein Fehler ausgegeben
+ raise IndexError("Das hier ist ein Index-Fehler")
+except IndexError as e:
+ pass # Pass ist nur eine no-op. Normalerweise würden wir hier den Fehler klären.
+
+
+####################################################
+## 4. Funktionen
+####################################################
+
+# Mit def neue Funktionen erstellen
+def add(x, y):
+ print "x ist %s und y ist %s" % (x, y)
+ return x + y # Werte werden mit return zurückgegeben
+
+# Funktionen mit Parametern aufrufen
+add(5, 6) #=> Ausgabe ist "x ist 5 und y ist 6" und gibt 11 zurück
+
+# Ein anderer Weg des Funktionsaufrufs sind Schlüsselwort-Argumente
+add(y=6, x=5) # Schlüsselwörter können in beliebiger Reihenfolge übergeben werden.
+
+# Wir können Funktionen mit beliebiger Anzahl von # Positionsargumenten definieren
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# Wir können auch Funktionen mit beliebiger Anzahl
+# Schlüsselwort-Argumenten definieren
+def keyword_args(**kwargs):
+ return kwargs
+
+# Rufen wir es mal auf, um zu sehen, was passiert
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Wir können beides gleichzeitig machem, wenn wir wollen
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) Ausgabe:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Beim Aufruf von Funktionen können wir das Gegenteil von varargs/kwargs machen!
+# Wir benutzen dann *, um Tupel auszuweiten, und ** für kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # äquivalent zu foo(1, 2, 3, 4)
+all_the_args(**kwargs) # äquivalent zu foo(a=3, b=4)
+all_the_args(*args, **kwargs) # äquivalent zu foo(1, 2, 3, 4, a=3, b=4)
+
+# Python hat First-Class-Funktionen
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Es gibt auch anonyme Funktionen
+(lambda x: x > 2)(3) #=> True
+
+# Es gibt auch Funktionen höherer Ordnung als Built-Ins
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Wir können bei map- und filter-Funktionen auch List Comprehensions einsetzen
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. Klassen
+####################################################
+
+# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten.
+class Human(object):
+
+ # Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
+ species = "H. sapiens"
+
+ # Ein simpler Konstruktor
+ def __init__(self, name):
+ # Wir weisen das Argument name dem name-Attribut der Instanz zu
+ self.name = name
+
+ # Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Eine Klassenmethode wird von allen Instanzen geteilt.
+ # Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Eine statische Methode wird ohne Klasse oder Instanz aufgerufen
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Eine Instanz einer Klasse erstellen
+i = Human(name="Ian")
+print i.say("hi") # gibt "Ian: hi" aus
+
+j = Human("Joel")
+print j.say("hello") #gibt "Joel: hello" aus
+
+# Rufen wir mal unsere Klassenmethode auf
+i.get_species() #=> "H. sapiens"
+
+# Ändern wir mal das gemeinsame Attribut
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Aufruf der statischen Methode
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Module
+####################################################
+
+# Wir können Module importieren
+import math
+print math.sqrt(16) #=> 4
+
+# Wir können auch nur spezielle Funktionen eines Moduls importieren
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Wir können auch alle Funktionen eines Moduls importieren
+# Warnung: Dies wird nicht empfohlen
+from math import *
+
+# Wir können Modulnamen abkürzen
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Module sind in Python nur gewöhnliche Dateien. Wir
+# können unsere eigenen schreiben und importieren. Der Name des
+# Moduls ist der Dateiname.
+
+# Wir können auch die Funktionen und Attribute eines
+# Moduls herausfinden.
+import math
+dir(math)
+
+
+```
+
+## Lust auf mehr?
+
+### Kostenlos online (Englisch)
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Totholz (Englisch)
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/elisp.html.markdown b/elisp.html.markdown
index d3910759..3208ffb8 100644
--- a/elisp.html.markdown
+++ b/elisp.html.markdown
@@ -280,10 +280,10 @@ filename: learn-emacs-lisp.el
;; should stop searching at some point in the buffer, and whether it
;; should silently fail when nothing is found:
-;; (search-forward "Hello" nil t) does the trick:
+;; (search-forward "Hello" nil 't) does the trick:
;; The `nil' argument says: the search is not bound to a position.
-;; The `t' argument says: silently fail when nothing is found.
+;; The `'t' argument says: silently fail when nothing is found.
;; We use this sexp in the function below, which doesn't throw an error:
@@ -294,7 +294,7 @@ filename: learn-emacs-lisp.el
(mapcar 'hello list-of-names)
(goto-char (point-min))
;; Replace "Hello" by "Bonjour"
- (while (search-forward "Hello" nil t)
+ (while (search-forward "Hello" nil 't)
(replace-match "Bonjour"))
(other-window 1))
@@ -305,7 +305,7 @@ filename: learn-emacs-lisp.el
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
- (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
+ (while (re-search-forward "Bonjour \\([^!]+\\)!" nil 't)
(add-text-properties (match-beginning 1)
(match-end 1)
(list 'face 'bold)))
@@ -317,9 +317,9 @@ filename: learn-emacs-lisp.el
;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
;; the string "Bonjour ", and
-;; a group of | this is the \\( ... \\) construct
-;; any character | this is the .
-;; possibly repeated | this is the +
+;; a group of | this is the \\( ... \\) construct
+;; any character not ! | this is the [^!]
+;; possibly repeated | this is the +
;; and the "!" string.
;; Ready? Test it!
diff --git a/elixir.html.markdown b/elixir.html.markdown
index 8ea499ff..0892deb7 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -9,9 +9,9 @@ Elixir is a modern functional language built on top of the Erlang VM.
It's fully compatible with Erlang, but features a more standard syntax
and many more features.
-```ruby
+```elixir
-# Single line comments start with a hashtag.
+# Single line comments start with a number symbol.
# There's no multi-line comment,
# but you can stack multiple comments.
diff --git a/es-es/c-es.html.markdown b/es-es/c-es.html.markdown
index b109f761..5d3aae0c 100644
--- a/es-es/c-es.html.markdown
+++ b/es-es/c-es.html.markdown
@@ -284,7 +284,7 @@ for (xx=0; xx<20; xx++) {
// impredecibles
printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what?
-// Cuando hallas acabado con el bloque de memoría malloc, necesitas
+// Cuando hayas acabado con el bloque de memoría malloc, necesitas
// liberarlo o sino nadie más podrá usarlo hasta que tu programa se cierre
free(my_ptr);
diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown
new file mode 100644
index 00000000..150d0bb2
--- /dev/null
+++ b/es-es/clojure-es.html.markdown
@@ -0,0 +1,393 @@
+---
+language: clojure
+filename: learnclojure-es.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Antonio Hernández Blas", "https://twitter.com/nihilipster"]
+ - ["Guillermo Vayá Pérez", "http://willyfrog.es"]
+lang: es-es
+---
+
+Clojure es un lenguaje de la familia Lisp desarrollado sobre la Máquina Virtual
+de Java. Tiene un énfasis mayor en la [programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) pura
+que Common Lisp, pero incluyendo la posibilidad de usar [SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular
+el estado según se presente.
+
+Esta combinación le permite gestionar la concurrencia de manera muy sencilla
+y a menudo automáticamente.
+
+(Necesitas la versión de Clojure 1.2 o posterior)
+
+
+```clojure
+; Los comentatios comienzan con punto y coma.
+
+; Clojure se escribe mediante "forms" (patrones), los cuales son
+; listas de objectos entre paréntesis, separados por espacios en blanco.
+
+; El "reader" (lector) de Clojure asume que el primer objeto es una
+; función o una macro que se va a llamar, y que el resto son argumentos.
+
+; El primer form en un archivo debe ser ns, para establecer el namespace (espacio de
+; nombres)
+(ns learnclojure)
+
+; Algunos ejemplos básicos:
+
+; str crea una cadena de caracteres a partir de sus argumentos
+(str "Hello" " " "World") ; => "Hello World"
+
+; Las operaciones matemáticas son sencillas
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; La igualdad es =
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; También es necesaria la negación para las operaciones lógicas
+(not true) ; => false
+
+; Cuando se anidan Los patrones, estos funcionan de la manera esperada
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Tipos
+;;;;;;;;;;;;;
+
+; Clojure usa los tipos de objetos de Java para booleanos, strings (cadenas de
+; caracteres) y números.
+; Usa class para saber de qué tipo es.
+(class 1); Los enteros son java.lang.Long por defecto
+(class 1.); Los numeros en coma flotante son java.lang.Double
+(class ""); Los strings van entre comillas dobles, y son
+; son java.lang.String
+(class false); Los Booleanos son java.lang.Boolean
+(class nil); El valor "null" se escribe nil
+
+; Si quieres crear una lista de datos, precedela con una comilla
+; simple para evitar su evaluación
+'(+ 1 2) ; => (+ 1 2)
+; (que es una abreviatura de (quote (+ 1 2)) )
+
+; Puedes evaluar una lista precedida por comilla con eval
+(eval '(+ 1 2)) ; => 3
+
+; Colecciones & Secuencias
+;;;;;;;;;;;;;;;;;;;
+
+; Las Listas están basadas en las listas enlazadas, mientras que los Vectores en
+; arrays.
+; ¡Los Vectores y las Listas también son clases de Java!
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; Una lista podría ser escrita como (1 2 3), pero debemos ponerle una
+; comilla simple delante para evitar que el reader piense que es una función.
+; Además, (list 1 2 3) es lo mismo que '(1 2 3)
+
+; Las "Colecciones" son solo grupos de datos
+; Tanto las listas como los vectores son colecciones:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; Las "Secuencias" (seqs) son descripciones abstractas de listas de datos.
+; Solo las listas son seqs.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Una seq solo necesita proporcionar una entrada cuando es accedida.
+; Así que, las seqs pueden ser perezosas -- pueden establecer series infinitas:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (una serie infinita)
+(take 4 (range)) ; (0 1 2 3)
+
+; Usa cons para agregar un elemento al inicio de una lista o vector
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; conj agregará un elemento a una colección en la forma más eficiente.
+; Para listas, se añade al inicio. Para vectores, al final.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; Usa concat para concatenar listas o vectores
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; Usa filter y map para actuar sobre colecciones
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Usa reduce para combinar sus elementos
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; reduce puede tener un argumento indicando su valor inicial.
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Funciones
+;;;;;;;;;;;;;;;;;;;;;
+
+; Usa fn para crear nuevas funciones. Una función siempre devuelve
+; su última expresión
+(fn [] "Hello World") ; => fn
+
+; (Necesitas rodearlo con paréntesis para invocarla)
+((fn [] "Hello World")) ; => "Hello World"
+
+; Puedes crear una var (variable) mediante def
+(def x 1)
+x ; => 1
+
+; Asigna una función a una var
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; Puedes defn como atajo para lo anterior
+(defn hello-world [] "Hello World")
+
+; El [] es el vector de argumentos de la función.
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; Otra abreviatura para crear funciones es:
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; Puedes tener funciones multi-variadic: funciones con un numero variable de
+; argumentos
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; Las funciones pueden usar argumentos extras dentro de un seq utilizable en la función
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+
+; Y puedes mezclarlos con el resto de argumentos declarados de la función.
+(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"
+
+
+; Mapas
+;;;;;;;;;;
+
+; Mapas de Hash y mapas de arrays comparten una misma interfaz. Los mapas de Hash
+; tienen búsquedas más rápidas pero no mantienen el orden de las claves.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Los mapas de arrays se convertidos en mapas de Hash en la mayoría de
+; operaciones si crecen mucho, por lo que no debes preocuparte.
+
+; Los mapas pueden usar cualquier tipo para sus claves, pero generalmente las
+; keywords (palabras clave) son lo habitual.
+; Las keywords son parecidas a cadenas de caracteres con algunas ventajas de eficiencia
+(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}
+
+; Por cierto, las comas son equivalentes a espacios en blanco y no hacen
+; nada.
+
+; Recupera un valor de un mapa tratandolo como una función
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; ¡Las keywords pueden ser usadas para recuperar su valor del mapa, también!
+(:b keymap) ; => 2
+
+; No lo intentes con strings.
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Si preguntamos por una clave que no existe nos devuelve nil
+(stringmap "d") ; => nil
+
+; Usa assoc para añadir nuevas claves a los mapas de Hash
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Pero recuerda, ¡los tipos de Clojure son inmutables!
+keymap ; => {:a 1, :b 2, :c 3}
+
+; Usa dissoc para eliminar llaves
+(dissoc keymap :a :b) ; => {:c 3}
+
+; Conjuntos
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; Añade un elemento con conj
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; Elimina elementos con disj
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Comprueba su existencia usando el conjunto como una función:
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; Hay más funciones en el namespace clojure.sets
+
+; Patrones útiles
+;;;;;;;;;;;;;;;;;
+
+; Las construcciones lógicas en clojure son macros, y presentan el mismo aspecto
+; que el resto de forms.
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; Usa let para crear un binding (asociación) temporal
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; Agrupa expresiones mediante do
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; Las funciones tienen implicita la llamada a 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")
+
+; Y el let también
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+; Módulos
+;;;;;;;;;;;;;;;
+
+; Usa use para obtener todas las funciones del módulo
+(use 'clojure.set)
+
+; Ahora podemos usar más operaciones de conjuntos
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Puedes escoger un subgrupo de funciones a importar, también
+(use '[clojure.set :only [intersection]])
+
+; Usa require para importar un módulo
+(require 'clojure.string)
+
+; Usa / para llamar a las funciones de un módulo
+; Aquí, el módulo es clojure.string y la función es blank?
+(clojure.string/blank? "") ; => true
+
+; Puedes asignarle una abreviatura a un modulo al importarlo
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#"" es una expresión regular)
+
+; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombre
+; usando :require,
+; No necesitas preceder con comilla simple tus módulos si lo haces de esta
+; forma.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java tiene una enorme librería estándar, por lo que resulta util
+; aprender como interactuar con ella.
+
+; Usa import para cargar un módulo de java
+(import java.util.Date)
+
+; Puedes importar desde un ns también.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Usa el nombre de la clase con un "." al final para crear una nueva instancia
+(Date.) ; <un objeto Date>
+
+; Usa "." para llamar a métodos o usa el atajo ".método"
+(. (Date.) getTime) ; <un timestamp>
+(.getTime (Date.)) ; exactamente la misma cosa
+
+; Usa / para llamar métodos estáticos.
+(System/currentTimeMillis) ; <un timestamp> (System siempre está presente)
+
+; Usa doto para hacer frente al uso de clases (mutables) más tolerable
+(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 es un mecanismo que usa clojure para gestionar
+; el estado persistente. Hay unas cuantas construcciones en clojure que
+; hacen uso de este mecanismo.
+
+; Un atom es el más sencillo. Se le da un valor inicial
+(def my-atom (atom {}))
+
+; Actualiza un atom con swap!
+; swap! toma una función y la llama con el valor actual del atom
+; como su primer argumento, y cualquier argumento restante como el segundo
+(swap! my-atom assoc :a 1) ; Establece my-atom al resultado de (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Establece my-atom al resultado de (assoc {:a 1} :b 2)
+
+; Usa '@' para no referenciar al atom sino para obtener su valor
+my-atom ;=> Atom<#...> (Regresa el objeto Atom)
+@my-atom ; => {:a 1 :b 2}
+
+; Un sencillo contador usando un atom sería
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; Otros forms que utilizan STM son refs y agents.
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+### Lectura adicional
+
+Ésto queda lejos de ser exhaustivo, pero espero que sea suficiente para que puedas empezar tu camino.
+
+Clojure.org tiene muchos artículos:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org contiene documentación con ejemplos para la mayoría de
+funciones principales (pertenecientes al core):
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure es una genial forma de mejorar tus habilidades con clojure/FP:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure:
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/es-es/coffeescript-es.html.markdown b/es-es/coffeescript-es.html.markdown
new file mode 100644
index 00000000..6bf430e6
--- /dev/null
+++ b/es-es/coffeescript-es.html.markdown
@@ -0,0 +1,57 @@
+---
+language: coffeescript
+lang: es-es
+contributors:
+ - ["Tenor Biel", "http://github.com/L8D"]
+translators:
+ - ["Pablo Elices", "http://github.com/pabloelices"]
+filename: coffeescript-es.coffee
+---
+
+``` coffeescript
+# CoffeeScript es un lenguaje hipster.
+# Tiene convenciones de muchos lenguajes modernos.
+# Los comentarios son como en Ruby y Python, usan almohadillas.
+
+###
+Los comentarios en bloque son como estos, y se traducen directamente a '/*' y '*/'
+para el código JavaScript resultante.
+
+Deberías entender la mayor parte de la semántica de JavaScript antes de continuar.
+###
+
+# Asignación:
+number = 42 #=> var number = 42;
+opposite = true #=> var opposite = true;
+
+# Condiciones:
+number = -42 if opposite #=> if(opposite) { number = -42; }
+
+# Funciones:
+square = (x) -> x * x #=> var square = function(x) { return x * x; }
+
+# Rangos:
+list = [1..5] #=> var list = [1, 2, 3, 4, 5];
+
+# Objetos:
+math =
+ root: Math.sqrt
+ square: square
+ cube: (x) -> x * square x
+#=> var math = {
+# "root": Math.sqrt,
+# "square": square,
+# "cube": function(x) { return x * square(x); }
+#}
+
+# Número de argumentos variable:
+race = (winner, runners...) ->
+ print winner, runners
+
+# Existencia:
+alert "I knew it!" if elvis?
+#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
+
+# Listas:
+cubes = (math.cube num for num in list) #=> ...
+```
diff --git a/es-es/csharp-es.html.markdown b/es-es/csharp-es.html.markdown
new file mode 100644
index 00000000..ef26d8ce
--- /dev/null
+++ b/es-es/csharp-es.html.markdown
@@ -0,0 +1,632 @@
+---
+language: c#
+contributors:
+ - ["Irfan Charania", "https://github.com/irfancharania"]
+ - ["Max Yankov", "https://github.com/golergka"]
+translators:
+ - ["Olfran Jiménez", "https://twitter.com/neslux"]
+filename: LearnCSharp-es.cs
+lang: es-es
+---
+
+C# es un lenguaje orientado a objetos elegante y de tipado seguro que
+permite a los desarrolladores construir una variedad de aplicaciones
+seguras y robustas que se ejecutan en el Framework .NET.
+
+[Lee más aquí.](http://msdn.microsoft.com/es-es/library/vstudio/z1zx9t92.aspx)
+
+```c#
+// Los comentarios de una sola línea comienzan con //
+/*
+Los comentarios de múltiples líneas son de esta manera
+*/
+/// <summary>
+/// Este es un comentario de documentación XML
+/// </summary>
+
+// Especifica el espacio de nombres que estará usando la aplicación
+using System;
+using System.Collections.Generic;
+
+
+// Define un ambito para organizar el código en "paquetes"
+namespace Learning
+{
+ // Cada archivo .cs debe contener al menos una clase con el mismo nombre que el archivo
+ // Se permite colocar cualquier nombre, pero no deberías por cuestiones de consistencia.
+ public class LearnCSharp
+ {
+ // Una aplicación de consola debe tener un método main como punto de entrada
+ public static void Main(string[] args)
+ {
+ // Usa Console.WriteLine para imprimir líneas
+ Console.WriteLine("Hello World");
+ Console.WriteLine(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Para imprimir sin una nueva línea, usa Console.Write
+ Console.Write("Hello ");
+ Console.Write("World");
+
+
+ ///////////////////////////////////////////////////
+ // Variables y Tipos
+ //
+ // Declara una variable usando <tipo> <nombre>
+ ///////////////////////////////////////////////////
+
+ // Sbyte - Entero de 8 bits con signo
+ // (-128 <= sbyte <= 127)
+ sbyte fooSbyte = 100;
+
+ // Byte - Entero de 8 bits sin signo
+ // (0 <= byte <= 255)
+ byte fooByte = 100;
+
+ // Short - Entero de 16 bits con signo
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Ushort - Entero de 16 bits sin signo
+ // (0 <= ushort <= 65,535)
+ ushort fooUshort = 10000;
+
+ // Integer - Entero de 32 bits con signo
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Uinteger - Entero de 32 bits sin signo
+ // (0 <= uint <= 4,294,967,295)
+ uint fooUint = 1;
+
+ // Long - Entero de 64 bits con signo
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L es usado para indicar que esta variable es de tipo long o ulong
+ // un valor sin este sufijo es tratado como int o uint dependiendo del tamaño.
+
+ // Ulong - Entero de 64 bits sin signo
+ // (0 <= ulong <= 18,446,744,073,709,551,615)
+ ulong fooUlong = 100000L;
+
+ // Float - Precisión simple de 32 bits. IEEE 754 Coma flotante
+ // Precisión: 7 dígitos
+ float fooFloat = 234.5f;
+ // f es usado para indicar que el valor de esta variable es de tipo float
+ // de otra manera sería tratado como si fuera de tipo double.
+
+ // Double - Doble precisión de 32 bits. IEEE 754 Coma flotante
+ // Precisión: 15-16 dígitos
+ double fooDouble = 123.4;
+
+ // Bool - true & false (verdadero y falso)
+ bool fooBoolean = true;
+ bool barBoolean = false;
+
+ // Char - Un solo caracter Unicode de 16 bits
+ char fooChar = 'A';
+
+ // Strings
+ string fooString = "My string is here!";
+ Console.WriteLine(fooString);
+
+ // Formato de cadenas
+ string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
+ Console.WriteLine(fooFormattedString);
+
+ // Formato de fechas
+ DateTime fooDate = DateTime.Now;
+ Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+
+ // \n es un caracter de escape que comienza una nueva línea
+ string barString = "Printing on a new line?\nNo Problem!";
+ Console.WriteLine(barString);
+
+ // Puede ser escrito mejor usando el símbolo @
+ string bazString = @"Here's some stuff
+ on a new line!";
+ Console.WriteLine(bazString);
+
+ // Las comillas deben ser escapadas
+ // usa \" para escaparlas
+ string quotedString = "some \"quoted\" stuff";
+ Console.WriteLine(quotedString);
+
+ // usa "" cuando las cadenas comiencen con @
+ string quotedString2 = @"some MORE ""quoted"" stuff";
+ Console.WriteLine(quotedString2);
+
+ // Usa const o readonly para hacer las variables inmutables
+ // los valores const son calculados en tiempo de compilación
+ const int HOURS_I_WORK_PER_WEEK = 9001;
+
+ // Tipos que aceptan valores NULL (Nullable)
+ // cualquier tipo de dato puede ser un tipo nulo añadiendole el sufijo ?
+ // <tipo>? <variable> = <valor>
+ int? nullable = null;
+ Console.WriteLine("Nullable variable: " + nullable);
+
+ // Para usar valores nulos, tienes que usar la propiedad Value
+ // o usar conversión explícita
+ string? nullableString = "not null";
+ Console.WriteLine("Nullable value is: " + nullableString.Value + " or: " + (string) nullableString );
+
+ // ?? is una manera corta de especificar valores por defecto
+ // en caso de que la variable sea null
+ int notNullable = nullable ?? 0;
+ Console.WriteLine("Not nullable variable: " + notNullable);
+
+ // var - el compilador escogerá el tipo de dato más apropiado basado en el valor
+ var fooImplicit = true;
+
+ ///////////////////////////////////////////////////
+ // Estructura de datos
+ ///////////////////////////////////////////////////
+ Console.WriteLine("\n->Data Structures");
+
+ // Arreglos
+ // El tamaño del arreglo debe decidirse al momento de la declaración
+ // El formato para declarar un arreglo es el siguiente:
+ // <tipo_de_dato>[] <nombre_variable> = new <tipo_de_dato>[<tamaño>];
+ int[] intArray = new int[10];
+ string[] stringArray = new string[1];
+ bool[] boolArray = new bool[100];
+
+ // Otra forma de declarar e inicializar un arreglo
+ int[] y = { 9000, 1000, 1337 };
+
+ // Indexar arreglos - Acceder a un elemento
+ Console.WriteLine("intArray @ 0: " + intArray[0]);
+
+ // Los arreglos son de índice cero y son mutables.
+ intArray[1] = 1;
+ Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1
+
+ // Listas
+ // Las listas son usadas más frecuentemente que los arreglos ya que son más flexibles
+ // El formato para declarar una lista es el siguiente:
+ // List<tipo_de_dato> <nombre_variable> = new List<tipo_de_dato>();
+ List<int> intList = new List<int>();
+ List<string> stringList = new List<string>();
+
+ // Otra forma de declarar e inicializar una lista
+ List<int> z = new List<int> { 9000, 1000, 1337 };
+
+ // Indexar una lista - Acceder a un elemento
+ // Las listas son de índice cero y son mutables.
+ Console.WriteLine("z @ 0: " + z[2]);
+
+ // Las listas no tienen valores por defecto;
+ // Un valor debe ser añadido antes de acceder al índice
+ intList.Add(1);
+ Console.WriteLine("intList @ 0: " + intList[0]);
+
+
+ // Otras estructuras de datos a chequear:
+ //
+ // Pilas/Colas
+ // Diccionarios
+ // Colecciones de sólo lectura
+ // Tuplas (.Net 4+)
+
+
+ ///////////////////////////////////////
+ // Operadores
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Modo corto para múltiples declaraciones
+
+ // La aritmética es sencilla
+ Console.WriteLine("1+2 = " + (i1 + i2)); // => 3
+ Console.WriteLine("2-1 = " + (i2 - i1)); // => 1
+ Console.WriteLine("2*1 = " + (i2 * i1)); // => 2
+ Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down)
+
+ // Módulo
+ Console.WriteLine("11%3 = " + (11 % 3)); // => 2
+
+ // Operadores de comparación
+ Console.WriteLine("3 == 2? " + (3 == 2)); // => false
+ Console.WriteLine("3 != 2? " + (3 != 2)); // => true
+ Console.WriteLine("3 > 2? " + (3 > 2)); // => true
+ Console.WriteLine("3 < 2? " + (3 < 2)); // => false
+ Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
+ Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
+
+ // Operadores a nivel de bits
+ /*
+ ~ Complemento a nivel de bits
+ << Desplazamiento a la izquierda con signo
+ >> Desplazamiento a la derecha con signo
+ >>> Desplazamiento a la derecha sin signo
+ & AND a nivel de bits
+ ^ XOR a nivel de bits
+ | OR a nivel de bits
+ */
+
+ // Incremento
+ int i = 0;
+ Console.WriteLine("\n->Inc/Dec-remento");
+ Console.WriteLine(i++); //i = 1. Posincrementación
+ Console.WriteLine(++i); //i = 2. Preincremento
+ Console.WriteLine(i--); //i = 1. Posdecremento
+ Console.WriteLine(--i); //i = 0. Predecremento
+
+
+ ///////////////////////////////////////
+ // Estructuras de control
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Control Structures");
+
+ // Las condiciones if son como en lenguaje c
+ int j = 10;
+ if (j == 10)
+ {
+ Console.WriteLine("I get printed");
+ }
+ else if (j > 10)
+ {
+ Console.WriteLine("I don't");
+ }
+ else
+ {
+ Console.WriteLine("I also don't");
+ }
+
+ // Operador ternario
+ // Un simple if/else puede ser escrito de la siguiente manera;
+ // <condición> ? <true> : <false>
+ string isTrue = (true) ? "True" : "False";
+ Console.WriteLine("Ternary demo: " + isTrue);
+
+
+ // Bucle while
+ int fooWhile = 0;
+ while (fooWhile < 100)
+ {
+ //Console.WriteLine(fooWhile);
+ //Incrementar el contador
+ //Iterar 99 veces, fooWhile 0->99
+ fooWhile++;
+ }
+ Console.WriteLine("fooWhile Value: " + fooWhile);
+
+ // Bucle Do While
+ int fooDoWhile = 0;
+ do
+ {
+ //Console.WriteLine(fooDoWhile);
+ //Incrementar el contador
+ //Iterar 99 veces, fooDoWhile 0->99
+ fooDoWhile++;
+ } while (fooDoWhile < 100);
+ Console.WriteLine("fooDoWhile Value: " + fooDoWhile);
+
+ // Bucle For
+ int fooFor;
+ //Estructura del bucle for => for(<declaración_inicial>; <condición>; <incremento>)
+ for (fooFor = 0; fooFor < 10; fooFor++)
+ {
+ //Console.WriteLine(fooFor);
+ //Iterated 10 times, fooFor 0->9
+ }
+ Console.WriteLine("fooFor Value: " + fooFor);
+
+ // Switch Case
+ // El switch funciona con los tipos de datos byte, short, char e int
+ // También funciona con las enumeraciones (discutidos en in Tipos Enum),
+ // la clase string y algunas clases especiales que encapsulan
+ // tipos primitivos: Character, Byte, Short, Integer.
+ int month = 3;
+ string monthString;
+ switch (month)
+ {
+ case 1:
+ monthString = "January";
+ break;
+ case 2:
+ monthString = "February";
+ break;
+ case 3:
+ monthString = "March";
+ break;
+ default:
+ monthString = "Some other month";
+ break;
+ }
+ Console.WriteLine("Switch Case Result: " + monthString);
+
+
+ ////////////////////////////////
+ // Conversión de tipos de datos
+ ////////////////////////////////
+
+ // Convertir datos
+
+ // Convertir String a Integer
+ // esto generará una excepción al fallar la conversión
+ int.Parse("123");//retorna una versión entera de "123"
+
+ // TryParse establece la variable a un tipo por defecto
+ // en este caso: 0
+ int tryInt;
+ int.TryParse("123", out tryInt);
+
+ // Convertir Integer a String
+ // La clase Convert tiene algunos métodos para facilitar las conversiones
+ Convert.ToString(123);
+
+ ///////////////////////////////////////
+ // Clases y Funciones
+ ///////////////////////////////////////
+
+ Console.WriteLine("\n->Classes & Functions");
+
+ // (Definición de la clase Bicycle (Bicicleta))
+
+ // Usar new para instanciar una clase
+ Bicycle trek = new Bicycle();
+
+ // Llamar a los métodos del objeto
+ trek.speedUp(3); // Siempre deberías usar métodos setter y métodos getter
+ trek.setCadence(100);
+
+ // ToString es una convención para mostrar el valor del objeto.
+ Console.WriteLine("trek info: " + trek.ToString());
+
+ // Instanciar otra nueva bicicleta
+ Bicycle octo = new Bicycle(5, 10);
+ Console.WriteLine("octo info: " + octo.ToString());
+
+ // Instanciar un Penny Farthing (Biciclo)
+ PennyFarthing funbike = new PennyFarthing(1, 10);
+ Console.WriteLine("funbike info: " + funbike.ToString());
+
+ Console.Read();
+ } // Fin del método main
+
+
+ } // Fin de la clase LearnCSharp
+
+ // Puedes incluir otras clases en un archivo .cs
+
+
+ // Sintaxis para la declaración de clases:
+ // <public/private/protected> class <nombre_de_clase>{
+ // //campos, constructores, funciones todo adentro de la clase.
+ // //las funciones son llamadas métodos como en java.
+ // }
+
+ public class Bicycle
+ {
+ // Campos/Variables de la clase Bicycle
+ public int cadence; // Public: Accesible desde cualquier lado
+ private int _speed; // Private: Sólo es accesible desde dentro de la clase
+ protected int gear; // Protected: Accesible desde clases y subclases
+ internal int wheels; // Internal: Accesible en el ensamblado
+ string name; // Todo es privado por defecto: Sólo es accesible desde dentro de esta clase
+
+ // Enum es un tipo valor que consiste un una serie de constantes con nombres
+ public enum Brand
+ {
+ AIST,
+ BMC,
+ Electra,
+ Gitane
+ }
+ // Definimos este tipo dentro de la clase Bicycle, por lo tanto es un tipo anidado
+ // El código afuera de esta clase debería referenciar este tipo como Bicycle.Brand
+
+ public Brand brand; // Declaramos un tipo enum, podemos declarar un campo de este tipo
+
+ // Los miembros estáticos pertenecen al tipo mismo, no a un objeto en específico.
+ static public int bicyclesCreated = 0;
+ // Puedes acceder a ellos sin referenciar ningún objeto:
+ // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
+
+ // Los valores readonly (Sólo lectura) son establecidos en tiempo de ejecución
+ // sólo pueden ser asignados al momento de la declaración o dentro de un constructor
+ readonly bool hasCardsInSpokes = false; // privado de sólo lectura
+
+ // Los constructores son una forma de crear clases
+ // Este es un constructor por defecto
+ private Bicycle()
+ {
+ gear = 1;
+ cadence = 50;
+ _speed = 5;
+ name = "Bontrager";
+ brand = Brand.AIST;
+ bicyclesCreated++;
+ }
+
+ // Este es un constructor específico (contiene argumentos)
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ string name, bool hasCardsInSpokes, Brand brand)
+ {
+ this.gear = startGear; // La palabra reservada "this" señala el objeto actual
+ this.cadence = startCadence;
+ this._speed = startSpeed;
+ this.name = name; // Puede ser útil cuando hay un conflicto de nombres
+ this.hasCardsInSpokes = hasCardsInSpokes;
+ this.brand = brand;
+ }
+
+ // Los constructores pueden ser encadenados
+ public Bicycle(int startCadence, int startSpeed, Brand brand) :
+ this(startCadence, startSpeed, 0, "big wheels", true)
+ {
+ }
+
+ // Sintaxis para Funciones:
+ // <public/private/protected> <tipo_retorno> <nombre_funcion>(<args>)
+
+ // Las clases pueden implementar getters y setters para sus campos
+ // o pueden implementar propiedades
+
+ // Sintaxis para la declaración de métodos:
+ // <ámbito> <tipo_retorno> <nombre_método>(<argumentos>)
+ public int GetCadence()
+ {
+ return cadence;
+ }
+
+ // Los métodos void no requieren usar return
+ public void SetCadence(int newValue)
+ {
+ cadence = newValue;
+ }
+
+ // La palabra reservada virtual indica que este método puede ser sobrescrito
+ public virtual void SetGear(int newValue)
+ {
+ gear = newValue;
+ }
+
+ // Los parámetros de un método pueden tener valores por defecto.
+ // En este caso, los métodos pueden ser llamados omitiendo esos parámetros
+ public void SpeedUp(int increment = 1)
+ {
+ _speed += increment;
+ }
+
+ public void SlowDown(int decrement = 1)
+ {
+ _speed -= decrement;
+ }
+
+ // Propiedades y valores get/set
+ // Cuando los datos sólo necesitan ser accedidos, considera usar propiedades.
+ // Las propiedades pueden tener get, set o ambos
+ private bool _hasTassles; // variable privada
+ public bool HasTassles // acceso público
+ {
+ get { return _hasTassles; }
+ set { _hasTassles = value; }
+ }
+
+ // Las propiedades pueden ser auto implementadas
+ public int FrameSize
+ {
+ get;
+ // Puedes especificar modificadores de acceso tanto para get como para set
+ // esto significa que sólo dentro de la clase Bicycle se puede modificar Framesize
+ private set;
+ }
+
+ //Método para mostrar los valores de atributos de este objeto.
+ public override string ToString()
+ {
+ return "gear: " + gear +
+ " cadence: " + cadence +
+ " speed: " + _speed +
+ " name: " + name +
+ " cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") +
+ "\n------------------------------\n"
+ ;
+ }
+
+ // Los métodos también pueden ser estáticos. Puede ser útil para métodos de ayuda
+ public static bool DidWeCreateEnoughBycles()
+ {
+ // Dentro de un método esático,
+ // Sólo podemos hacer referencia a miembros estáticos de clases
+ return bicyclesCreated > 9000;
+ } // Si tu clase sólo necesita miembros estáticos,
+ // considera establecer la clase como static.
+
+ } // fin de la clase Bicycle
+
+ // PennyFarthing es una subclase de Bicycle
+ class PennyFarthing : Bicycle
+ {
+ // (Penny Farthings son las bicicletas con una rueda delantera enorme.
+ // No tienen engranajes.)
+
+ // llamar al constructor de la clase padre
+ public PennyFarthing(int startCadence, int startSpeed) :
+ base(startCadence, startSpeed, 0, "PennyFarthing", true)
+ {
+ }
+
+ public override void SetGear(int gear)
+ {
+ gear = 0;
+ }
+
+ public override string ToString()
+ {
+ string result = "PennyFarthing bicycle ";
+ result += base.ToString(); // Llamar a la versión base del método
+ return reuslt;
+ }
+ }
+
+ // Las interfaces sólo contienen las declaraciones
+ // de los miembros, sin la implementación.
+ interface IJumpable
+ {
+ void Jump(int meters); // todos los miembros de interfaces son implícitamente públicos
+ }
+
+ interface IBreakable
+ {
+ // Las interfaces pueden contener tanto propiedades como métodos, campos y eventos
+ bool Broken { get; }
+ }
+
+ // Las clases sólo heredan de alguna otra clase, pero pueden implementar
+ // cualquier cantidad de interfaces
+ class MountainBike : Bicycle, IJumpable, IBreakable
+ {
+ int damage = 0;
+
+ public void Jump(int meters)
+ {
+ damage += meters;
+ }
+
+ public void Broken
+ {
+ get
+ {
+ return damage > 100;
+ }
+ }
+ }
+} // Fin del espacio de nombres
+
+```
+
+## Temas no cubiertos
+
+ * Flags
+ * Attributes
+ * Generics (T), Delegates, Func, Actions, lambda expressions
+ * Static properties
+ * Exceptions, Abstraction
+ * LINQ
+ * ASP.NET (Web Forms/MVC/WebMatrix)
+ * Winforms
+ * Windows Presentation Foundation (WPF)
+
+
+
+## Lecturas recomendadas
+
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
+ * [MSDN Library](http://msdn.microsoft.com/es-es/library/618ayhy6.aspx)
+ * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
+ * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
+ * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+
+
+
+[Convenciones de código de C#](http://msdn.microsoft.com/es-es/library/vstudio/ff926074.aspx)
diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown
new file mode 100644
index 00000000..5c9d3378
--- /dev/null
+++ b/es-es/git-es.html.markdown
@@ -0,0 +1,411 @@
+---
+category: tool
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+translator:
+ - ["Raúl Ascencio", "http://rscnt.github.io"]
+filename: LearnGit.txt
+lang: es-es
+
+---
+
+Git es un sistema de control de versiones distribuido diseñado para manejar
+cualquier tipo de proyecto ya sea largos o pequeños, con velocidad y eficiencia.
+
+Git realiza esto haciendo "snapshots" del proyecto, con ello permite
+versionar y administrar nuestro código fuente.
+
+## Versionamiento, conceptos.
+
+### Que es el control de versiones?
+El control de versiones es un sistema que guarda todos los cambios realizados a
+uno o varios archivos, a lo largo del tiempo.
+
+### Versionamiento centralizado vs Versionamiento Distribuido.
+
++ El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar
+ archivos.
++ El versionamiento distribuido se enfoca en compartir los cambios realizados.
+ Cada cambio tiene un único identificador.
++ El versionamiento distribuido no tiene una estructura definida, incluso se
+ puede mantener el estilo de los repositorios SVN con git.
+
+[Informacion adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
+
+### Por que usar Git?
+
+* Se puede trabajar sin conexion.
+* Colaborar con otros es sencillo!.
+* Derivar, Crear ramas del proyecto (aka: Branching) es facil!.
+* Combinar (aka: Marging)
+* Git es rapido.
+* Git es flexible.
+
+## Arquitectura de Git.
+
+### Repositorio
+
+Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:
+comits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
+y que sus atributos otorgan acceso al historial del elemento, ademas de otras
+cosas.
+
+Un repositorio esta compuesto por la carpeta .git y un "arbol de trabajo".
+
+### Directorio .git (componentes del repositorio)
+
+El directorio .git contiene todas las configuraciones, registros, branches, HEAD
+y mas.
+
+[Lista detallada.](http://es.gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Directorio de trabajo (componentes del repositorio)
+
+Es basicamente los directorios y archivos dentro del repositorio. La mayorioa de
+las veces se le llama "directorio de trabajo".
+
+### Inidice (componentes del directorio .git)
+
+El inidice es la area de inicio en git. Es basicamente la capa que separa el
+directorio de trabajo, del repositorio en git. Esto otorga a los desarrolladores
+mas poder sobre lo que envia y recibe en el repositorio.
+
+### Commit (aka: cambios)
+
+Un commit es una captura de un conjunto de cambios, o modificaciones hechas en
+el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se remueven 2,
+estos cambios se almacenaran en un commit (aka: captura). Este commit puede ser o
+no ser enviado (aka: "pusheado") hacia un repositorio.
+
+### Branch (rama)
+
+Un "branch", es escencialmente un apuntador hacia el ultimo commit (cambio
+registrado) que se ha realizado. A medida que se realizan mas commits, este
+apuntador se actualizara automaticamente hacia el ultimo commit.
+
+### "HEAD" y "head" (component of .git dir)
+
+"HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un
+repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a
+cualquier commit realizado, un repositorio puede tener cualquier numero de
+"heads".
+
+### conceptos - recursos.
+
+* [Git para informaticos](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html)
+
+
+## Comandos.
+
+
+### init
+
+Crear un repositorio de git vacio. Las configuraciones, informacion almacenada y
+demas son almacenadas en el directorio ".git".
+
+```bash
+$ git init
+```
+
+### config
+
+Se utiliza para configurar las opciones ya sea globalmente, o solamente en el
+repositorio.
+
+```bash
+# Imprime y guarda algunas variables de configuracion basicas. (Globalmente)
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "corre@gmail.com"
+$ git config --global user.name "nombre"
+```
+
+[Mas sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git)
+
+### help
+
+Otorga un accceso rapido a una guia extremadamente detallada de cada comando en
+git. O puede ser usada simplemente como un recordatorio de estos.
+
+```bash
+# Una vista rapido de los comandos disponibles.
+$ git help
+
+# Chequear todos los comandos disponibles
+$ git help -a
+
+# Obtener ayuda especifica de un comando - manual de usuario
+# git help <comando>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Muestra las diferencias entre el archivo indice y el commit al cual apunta el
+HEAD actualmente.
+
+
+```bash
+# Mostrara el "branch", archivos sin añadir a la repo, cambios y otras
+# diferencias
+$ git status
+
+# Devuelve ayuda sobre el comando status.
+$ git help status
+```
+
+### add
+
+Para añadir archivos al arbol (directorio, repositorio) de trabajo. Si no se
+utiliza `git add`, los nuevos archivos no se añadiran al arbol de trabajo, por
+lo que no se incluiran en los commits (cambios).
+
+```bash
+# Añade un archivo en el directorio de trabajo actual.
+$ git add FooBar.java
+
+# Añade un archivo que se encuentra bajo un directorio.
+$ git add /directorio/del/archivo/Foo.c
+
+# Soporte para expresiones regulares!
+$ git add ./*.py
+```
+
+### branch
+
+Administra las ramas del repositorios ("branches"). Puedes ver, editar, crear y
+borrar ramas ("branches"), usando este comando.
+
+```bash
+# lista todas las ramas (remotas y locales)
+$ git branch -a
+
+# Añada una nueva rama ("branch").
+$ git branch branchNueva
+
+# Eliminar una rama.
+$ git branch -d branchFoo
+
+# Renombra una rama.
+# git branch -m <anterior> <nuevo>
+$ git branch -m youngling padawan
+
+# Edita la descripcion de la rama.
+$ git branch master --edit-description
+```
+
+### checkout
+
+Actualiza todos los archivos en el directorio de trabajo para que sean igual que
+las versiones almacenadas en el indice, o en un arbol de trabajo especificado.
+
+```bash
+# Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master')
+$ git checkout
+# Despacha una rama especifica.
+$ git checkout padawan
+# Crea una nueva rama y cambia hacia ella, es igual a utilizar: "git brach jedi; git checkout jedi"
+$ git checkout -b jdei
+```
+
+### clone
+
+Clona, o copia, una repo existente en un nuevo directorio. Tambien añada el
+seguimiento hacia las ramas existentes del repo que ha sido clonada, lo que
+permite subir (push) los archivos hacia una rama remota.
+
+```bash
+# Clonar la repo de jquery.
+$ git clone https://github.com/jquery/jquery.git
+```
+
+### commit
+
+Almacena los cambios que almacenados en el indice en un nuevo "commit". Este
+commit contiene los cambios hechos mas un resumen hecho por el desarrollador.
+
+```bash
+# commit with a message
+# realizar un commit y añadirle un mensaje.
+$ git commit -m "jedi anakin wil be - jedis.list"
+```
+
+### diff
+
+Muestra las diferencias entre un archivo en el directorio de trabajo, el indice
+y commits.
+
+```bash
+# Muestra la diferencia entre un directorio de trabajo y el indice.
+$ git diff
+
+# Muestra la diferencia entre el indice y los commits mas recientes.
+$ git diff --cached
+
+# Muestra la diferencia entre el directorio de trabajo y el commit mas reciente.
+$ git diff HEAD
+```
+
+### grep
+
+Permite realizar una busqueda rapida en un repositorio.
+
+Configuracion opcionales:
+
+```bash
+# Gracias a Travis Jeffery por compartir lo siguiente.
+# Permite mostrar numeros de lineas en la salida de grep.
+$ git config --global grep.lineNumber true
+
+# Realiza una busqueda mas lejible, incluyendo agrupacion.
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Busca por "unaVariable" en todos los archivos ,java
+$ git grep 'unaVariable' -- '*.java'
+
+# Busca por una linea que contenga "nombreArreglo" y , "agregar" o "remover"
+$ git grep -e 'nombreArreglo' --and \( -e agregar -e remover \)
+```
+
+Mas ejemplos:
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Muestra los commits (cambios) registrados en el repositotrio.
+
+```bash
+# Muestra todos los commits.
+$ git log
+
+# Muestra un numero x de commits.
+$ git log -n 10
+
+# Muestra solo los commits que se han combinado en el hisotrial
+$ git log --merges
+```
+
+### merge
+
+Combina los cambios de commits realizados externamente dentro de la rama en la
+que se trabaja.
+
+```bash
+# Combina la rama especificada en la rama actual.
+$ git merge jediMaster
+
+# Siempre genere un solo merge commit cuando se utilizar merge.
+$ git merge --no-ff jediMaster
+```
+
+### mv
+
+Renombra o mueve un archivo
+
+```bash
+# Renombrando un archivo
+$ git mv HolaMundo.c AdiosMundo.c
+
+# Moviendo un archivo.
+$ git mv HolaOtraVezMundo.c ./nuevo/directorio/NuevoArchivo.c
+
+# Sustituye un archivo.
+$ git mv -f archivoA archivoB
+```
+
+### pull
+
+Sube (Empuja) de un repositorio y lo combina en otro en una rama diferente.
+
+```bash
+# Actualiza el repositorio local, combinando los nuevos cambios.
+# de las ramas remotas "origin" y "master".
+# from the remote "origin" and "master" branch.
+# git pull <remota> <rama>
+$ git pull origin master
+```
+
+### push
+
+Push and merge changes from a branch to a remote & branch.
+
+```bash
+# Push and merge changes from a local repo to a
+# Empuja y combina cambios de un repositorio local hacian un repositorio remoto
+# llamados "origin" y "master", respectivamente.
+# git push <remota> <rama>
+# git push => por defecto es lo mismo que poner => git push origin master
+$ git push origin master
+```
+
+
+Toma todos los cambios que fueron registrados en una rama, y los repite dentro
+de otra rama.
+*No reescribe los commits que se han empujado antes a un repositorio publico*
+
+```bash
+# Integrar ramaExperimento dentro de la rama "master"
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Informacion adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar)
+
+### reset (precaucion)
+
+Reinicia el cabezal actual hacia un estado especificado. Esto permite desacer
+combinaciones (merges), pulls, commits, adds y mas. Es un comando util, pero
+tambien peligrosa si no se sabe lo que se hace.
+
+```bash
+# Reinica el area principal, con el ultimo cambio registrado. (deja los
+# directorios sin cambios)
+$ git reset
+
+# Reinica el area principal, con el ultimo cambio registrado, y reescribe el
+# directorio de trabajo.
+$ git reset --hard
+
+# Mueve la rama actual hacia el commit especificado (no realiza cambios a los
+# directorios), todos los cambios aun existen el directorio.
+$ git reset 31f2bb1
+
+# Mueve la rama actual devuelta a un commit especificado asi como el
+# directorios (borra todos los cambios que no fueron registros y todos los
+# cambios realizados despues del commit especificado).
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+Lo contrario de git add, git rm remueve los archivos del directorio de trabajo
+actual.
+
+```bash
+# Remueve FooBar.c
+$ git rm FooBar.c
+
+# Remueve un archivo de un directorio.
+$ git rm /directorio/del/archivo/FooBar.c
+```
+
+## Informacion Adicional
+
+* [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video-tutoriales](http://git-scm.com/videos)
+
+* [git-scm - Documentacion](http://git-scm.com/book/es)
+
+* [Atlassian Git - Tutoriales y Flujos de trabajo](https://www.atlassian.com/git/)
+
+* [SalesForce Chuleta](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown
new file mode 100644
index 00000000..e788e810
--- /dev/null
+++ b/es-es/go-es.html.markdown
@@ -0,0 +1,326 @@
+---
+language: Go
+lang: es-es
+filename: learngo-es.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+translators:
+ - ["Adrian Espinosa", "http://www.adrianespinosa.com"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+---
+
+Go fue creado por la necesidad de hacer el trabajo rápidamente. No es
+la última tendencia en informática, pero es la forma nueva y más
+rápida de resolver problemas reales.
+
+Tiene conceptos familiares de lenguajes imperativos con tipado
+estático. Es rápido compilando y rápido al ejecutar, añade una
+concurrencia fácil de entender para las CPUs de varios núcleos de hoy
+en día, y tiene características que ayudan con la programación a gran
+escala.
+
+Go viene con una librería estándar muy buena y una comunidad entusiasta.
+
+```go
+// Comentario de una sola línea
+/* Comentario
+ multi línea */
+
+// La cláusula package aparece al comienzo de cada archivo fuente.
+// Main es un nombre especial que declara un ejecutable en vez de una librería.
+package main
+
+// La declaración Import declara los paquetes de librerías
+// referenciados en este archivo.
+import (
+ "fmt" // Un paquete en la librería estándar de Go.
+ "net/http" // Sí, un servidor web!
+ "strconv" // Conversiones de cadenas.
+ m "math" // Librería matemáticas con alias local m.
+)
+
+// Definición de una función. Main es especial. Es el punto de
+// entrada para el ejecutable. Te guste o no, Go utiliza llaves.
+func main() {
+ // Println imprime una línea a stdout.
+ // Cualificalo con el nombre del paquete, fmt.
+ fmt.Println("Hello world!")
+
+ // Llama a otra función de este paquete.
+ beyondHello()
+}
+
+// Las funciones llevan parámetros entre paréntesis.
+// Si no hay parámetros, los paréntesis siguen siendo obligatorios.
+func beyondHello() {
+ var x int // Declaración de una variable.
+ // Las variables se deben declarar antes de utilizarlas.
+ x = 3 // Asignación de variables.
+ // Declaración "corta" con := para inferir el tipo, declarar y asignar.
+ y := 4
+ sum, prod := learnMultiple(x, y) // Función devuelve dos valores.
+ fmt.Println("sum:", sum, "prod:", prod) // Simple salida.
+ learnTypes() // < y minutes, learn more!
+}
+
+// Las funciones pueden tener parámetros y (múltiples!) valores de retorno.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Devolver dos valores.
+}
+
+// Algunos tipos incorporados y literales.
+func learnTypes() {
+ // La declaración corta suele darte lo que quieres.
+ s := "Learn Go!" // tipo cadena
+
+ s2 := ` Un tipo cadena "puro" puede incluir
+saltos de línea.` // mismo tipo cadena
+
+ // Literal no ASCII. Los fuentes de Go son UTF-8.
+ g := 'Σ' // Tipo rune, un alias de uint32, alberga un punto unicode.
+ f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit.
+ c := 3 + 4i // complex128, representado internamente por dos float64.
+ // Sintaxis Var con inicializadores.
+ var u uint = 7 // Sin signo, pero la implementación depende del
+ // tamaño como en int.
+ var pi float32 = 22. / 7
+
+ // Sintáxis de conversión con una declaración corta.
+ n := byte('\n') // byte es un alias de uint8.
+
+ // Los Arrays tienen un tamaño fijo a la hora de compilar.
+ var a4 [4]int // Un array de 4 ints, inicializados a 0.
+ a3 := [...]int{3, 1, 5} // Un array de 3 ints, inicializados como se indica.
+
+ // Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas
+ // y desventajas pero los casos de uso para los slices son más comunes.
+ s3 := []int{4, 5, 9} // Comparar con a3. No hay puntos suspensivos.
+ s4 := make([]int, 4) // Asigna slices de 4 ints, inicializados a 0.
+ var d2 [][]float64 // Solo declaración, sin asignación.
+ bs := []byte("a slice") // Sintaxis de conversión de tipo.
+
+ p, q := learnMemory() // Declara p, q para ser un tipo puntero a int.
+ fmt.Println(*p, *q) // * sigue un puntero. Esto imprime dos ints.
+
+ // Los Maps son arrays asociativos dinámicos, como los hash o
+ // diccionarios de otros lenguajes.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // Las variables no utilizadas en Go producen error.
+ // El guión bajo permite "utilizar" una variable, pero descartar su valor.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Esto cuenta como utilización de variables.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // Vuelta al flujo.
+}
+
+// Go posee recolector de basura. Tiene puntero pero no aritmética de
+// punteros. Puedes cometer un errores con un puntero nil, pero no
+// incrementando un puntero.
+func learnMemory() (p, q *int) {
+ // q y p tienen un tipo puntero a int.
+ p = new(int) // Función incorporada que asigna memoria.
+ // La asignación de int se inicializa a 0, p ya no es nil.
+ s := make([]int, 20) // Asigna 20 ints a un solo bloque de memoria.
+ s[3] = 7 // Asignar uno de ellos.
+ r := -2 // Declarar otra variable local.
+ return &s[3], &r // & toma la dirección de un objeto.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // La declaración If requiere llaves, pero no paréntesis.
+ if true {
+ fmt.Println("told ya")
+ }
+ // El formato está estandarizado por el comando "go fmt."
+ if false {
+ // Pout.
+ } else {
+ // Gloat.
+ }
+ // Utiliza switch preferiblemente para if encadenados.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Los cases no se mezclan, no requieren de "break".
+ case 43:
+ // No llega.
+ }
+ // Como if, for no utiliza paréntesis tampoco.
+ // Variables declaradas en for y if son locales de su ámbito local.
+ for x := 0; x < 3; x++ { // ++ es una sentencia.
+ fmt.Println("iteration", x)
+ }
+ // x == 42 aqui.
+
+ // For es la única sentencia de bucle en Go, pero tiene formas alternativas.
+ for { // Bucle infinito.
+ break // Solo bromeaba!
+ continue // No llega.
+ }
+ // Como en for, := en una sentencia if significa declarar y asignar primero,
+ // luego comprobar y > x.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Los literales de funciones son "closures".
+ xBig := func() bool {
+ return x > 100 // Referencia a x declarada encima de la sentencia switch.
+ }
+ fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x).
+ x /= m.Exp(9) // Esto lo hace x == e.
+ fmt.Println("xBig:", xBig()) // Ahora es falso.
+
+ // Cuando lo necesites, te encantará.
+ goto love
+love:
+
+ learnInterfaces() // Buen material dentro de poco!
+}
+
+// Define Stringer como un tipo interfaz con un método, String.
+type Stringer interface {
+ String() string
+}
+
+// Define pair como un struct con dos campos int, x e y.
+type pair struct {
+ x, y int
+}
+
+// Define un método del tipo pair. Pair ahora implementa Stringer.
+func (p pair) String() string { // p se llama "recibidor"
+ // Sprintf es otra función pública del paquete fmt.
+ // La sintaxis con punto referencia campos de p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // La sintaxis de llaves es un "literal struct". Evalúa a un struct
+ // inicializado. La sintaxis := declara e inicializa p a este struct.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Llamar al método String de p, de tipo pair.
+ var i Stringer // Declarar i como interfaz tipo Stringer.
+ i = p // Válido porque pair implementa Stringer.
+ // Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba.
+ fmt.Println(i.String())
+
+ // Las funciones en el paquete fmt llaman al método String para
+ // preguntar a un objeto por una versión imprimible de si mismo.
+ fmt.Println(p) // Salida igual que arriba. Println llama al método String.
+ fmt.Println(i) // Salida igual que arriba.
+
+ learnVariadicParams("great", "learning", "here!")
+}
+
+// Las funciones pueden tener número variable de argumentos.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Iterar cada valor de la variadic.
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // Pasar valor variadic como parámetro variadic.
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" forma utilizada para saber si algo funcionó o no.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok será falso porque 1 no está en el map.
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // x sería el valor, si estuviera en el map.
+ }
+ // Un valor de error comunica más información sobre el problema aparte de "ok".
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor
+ // Imprime "strconv.ParseInt: parsing "non-int": invalid syntax".
+ fmt.Println(err)
+ }
+ // Revisarmeos las interfaces más tarde. Mientras tanto,
+ learnConcurrency()
+}
+
+// c es un canal, un objeto de comunicación de concurrencia segura.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- es el operador "enviar" cuando un canal aparece a la izquierda.
+}
+
+// Utilizaremos inc para incrementar algunos números concurrentemente.
+func learnConcurrency() {
+ // Misma función make utilizada antes para crear un slice. Make asigna e
+ // inicializa slices, maps, y channels.
+ c := make(chan int)
+ // Iniciar tres goroutines concurrentes. Los números serán incrementados
+ // concurrentemente, quizás en paralelo si la máquina es capaz y
+ // está correctamente configurada. Las tres envían al mismo channel.
+ go inc(0, c) // go es una sentencia que inicia una nueva goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Leer los tres resultados del channel e imprimirlos.
+ // No se puede saber en que orden llegarán los resultados!
+ fmt.Println(<-c, <-c, <-c) // Channel a la derecha, <- es el operador "recibir".
+
+ cs := make(chan string) // Otro channel, este gestiona cadenas.
+ ccs := make(chan chan string) // Un channel de cadenas de channels.
+ go func() { c <- 84 }() // Iniciar una nueva goroutine solo para
+ // enviar un valor.
+ go func() { cs <- "wordy" }() // Otra vez, para cs en esta ocasión.
+ // Select tiene una sintáxis parecida a la sentencia switch pero
+ // cada caso involucra una operacion de channels. Selecciona un caso
+ // de forma aleatoria de los casos que están listos para comunicarse.
+ select {
+ case i := <-c: // El valor recibido puede ser asignado a una variable,
+ fmt.Printf("it's a %T", i)
+ case <-cs: // o el valor puede ser descartado.
+ fmt.Println("it's a string")
+ case <-ccs: // Channel vacío, no está listo para la comunicación.
+ fmt.Println("didn't happen.")
+ }
+
+ // En este punto un valor fue devuelvto de c o cs. Uno de las dos
+ // goroutines que se iniciaron se ha completado, la otrá permancerá
+ // bloqueada.
+
+ learnWebProgramming() // Go lo hace. Tu también quieres hacerlo.
+}
+
+// Una simple función del paquete http inicia un servidor web.
+func learnWebProgramming() {
+ // El primer parámetro de la direccinón TCP a la que escuchar.
+ // El segundo parámetro es una interfaz, concretamente http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // no ignorar errores
+}
+
+// Haz pair un http.Handler implementando su único método, ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Servir datos con un método de http.ResponseWriter.
+ w.Write([]byte("You learned Go in Y minutes!"))
+}
+```
+
+## Para leer más
+
+La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/).
+Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho.
+
+La propia definición del lenguaje también está altamente
+recomendada. Es fácil de leer e increíblemente corta (como otras
+definiciones de lenguajes hoy en día)
+
+En la lista de lectura de estudiantes de Go está el código fuente de
+la librería estándar. Muy bien documentada, demuestra lo mejor de Go
+leíble, comprendible, estilo Go y formas Go. Pincha en el nombre de
+una función en la documentación y te aparecerá el código fuente!
+
diff --git a/es-es/julia-es.html.markdown b/es-es/julia-es.html.markdown
new file mode 100644
index 00000000..41a7c68b
--- /dev/null
+++ b/es-es/julia-es.html.markdown
@@ -0,0 +1,759 @@
+---
+language: julia
+contributors:
+ - ["Leah Hanson", "http://leahhanson.us"]
+ - ["Guillermo Garza" ]
+filename: learnjulia-es.jl
+lang: es-es
+---
+
+Julia es un nuevo lenguaje funcional homoiconic enfocado en computación técnica.
+Aunque que tiene todo el poder de macros homoiconic, funciones de primera
+clase, y control de bajo nivel, Julia es tan fácil de aprender y utilizar como
+Python.
+
+Esto se basa en la versión de desarrollo actual de Julia, del 18 de octubre de
+2013.
+
+```ruby
+
+# Comentarios de una línea comienzan con una almohadilla (o signo gato)
+
+#= Commentarios multilinea pueden escribirse
+ usando '#=' antes de el texto y '=#'
+ después del texto. También se pueden anidar.
+=#
+
+####################################################
+## 1. Tipos de datos primitivos y operadores.
+####################################################
+
+# Todo en Julia es una expresión.
+
+# Hay varios tipos básicos de números.
+3 # => 3 (Int64)
+3.2 # => 3.2 (Float64)
+2 + 1im # => 2 + 1im (Complex{Int64})
+2//3 # => 2//3 (Rational{Int64})
+
+# Todos los operadores infijos normales están disponibles.
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+5/2 # => 2.5 # dividir un Int por un Int siempre resulta en un Float
+div (5, 2) # => 2 # para un resultado truncado, usa div
+5 \ 35 # => 7.0
+2 ^ 2 # => 4 # exponente, no es xor
+12 % 10 # => 2
+
+# Refuerza la precedencia con paréntesis
+(1 + 3) * 2 # => 8
+
+# Operadores a nivel de bit
+~2 # => -3 # bitwise not
+3 & 5 # => 1 # bitwise and
+2 | 4 # => 6 # bitwise or
+2 $ 4 # => 6 # bitwise xor
+2 >>> 1 # => 1 # logical shift right
+2 >> 1 # => 1 # arithmetic shift right
+2 << 1 # => 4 # logical/arithmetic shift left
+
+# Se puede utilizar la función bits para ver la representación binaria de un
+# número.
+bits(12345)
+# => "0000000000000000000000000000000000000000000000000011000000111001"
+bits(12345.0)
+# => "0100000011001000000111001000000000000000000000000000000000000000"
+
+# Valores 'boolean' (booleanos) son primitivos
+true
+false
+
+# Operadores Boolean (booleanos)
+!true # => false
+!false # => true
+1 == 1 # => true
+2 == 1 # => false
+1 != 1 # => false
+2 != 1 # => true
+1 < 10 # => true
+1 > 10 # => false
+2 <= 2 # => true
+2 >= 2 # => true
+# ¡Las comparaciones pueden ser concatenadas!
+1 < 2 < 3 # => true
+2 < 3 < 2 # => false
+
+# Strings se crean con "
+"Esto es un string."
+
+# Literales de caracteres se escriben con '
+'a'
+
+# Una string puede ser indexado como una array de caracteres
+"Esto es un string."[1] # => 'E' # Índices en Julia empiezen del 1
+# Sin embargo, esto no va a funcionar bien para strings UTF8,
+# Lo que se recomienda es la iteración (map, for, etc).
+
+# $ puede ser utilizado para la interpolación de strings:
+"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
+# Se puede poner cualquier expresión de Julia dentro los paréntesis.
+
+# Otro forma de formatear strings es el macro printf
+@printf "%d es menor de %f" 4.5 5.3 # 5 es menor de 5.300000
+
+# Imprimir es muy fácil
+println("Soy Julia. ¡Encantado de conocerte!")
+
+####################################################
+## 2. Variables y Colecciones
+####################################################
+
+# No hay necesidad de declarar las variables antes de asignarlas.
+una_variable = 5 # => 5
+una_variable # => 5
+
+# Acceder a variables no asignadas previamente es una excepción.
+try
+ otra_variable # => ERROR: some_other_var not defined
+catch e
+ println(e)
+end
+
+# Los nombres de variables comienzan con una letra.
+# Después de eso, puedes utilizar letras, dígitos, guiones y signos de
+# exclamación.
+OtraVariable123! = 6 # => 6
+
+# También puede utilizar caracteres unicode
+☃ = 8 # => 8
+# Estos son especialmente útiles para la notación matemática
+2 * π # => 6.283185307179586
+
+# Una nota sobre las convenciones de nomenclatura de Julia:
+#
+# * Los nombres de las variables aparecen en minúsculas, con separación de
+# palabra indicado por underscore ('\ _').
+#
+# * Los nombres de los tipos comienzan con una letra mayúscula y separación de
+# palabras se muestra con CamelCase en vez de underscore.
+#
+# * Los nombres de las funciones y los macros están en minúsculas, sin
+# underscore.
+#
+# * Funciones que modifican sus inputs tienen nombres que terminan en!. Estos
+# funciones a veces se llaman mutating functions o in-place functions.
+
+# Los Arrays almacenan una secuencia de valores indexados entre 1 hasta n
+a = Int64[] # => 0-element Int64 Array
+
+# Literales de arrays 1-dimensionales se pueden escribir con valores separados
+# por comas.
+b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
+b[1] # => 4
+b[end] # => 6
+
+# Los arrays 2-dimensionales usan valores separados por espacios y filas
+# separados por punto y coma.
+matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
+
+# Añadir cosas a la final de una lista con push! y append!
+push!(a,1) # => [1]
+push!(a,2) # => [1,2]
+push!(a,4) # => [1,2,4]
+push!(a,3) # => [1,2,4,3]
+append!(a,b) # => [1,2,4,3,4,5,6]
+
+# Eliminar de la final con pop
+pop!(b) # => 6 y b ahora es [4,5]
+
+# Vamos a ponerlo de nuevo
+push!(b, 6) # b es ahora [4,5,6] de nuevo.
+
+a[1] # => 1 # recuerdan que los índices de Julia empiezan desde 1, no desde 0!
+
+# end es una abreviatura para el último índice. Se puede utilizar en cualquier
+# expresión de indexación
+a[end] # => 6
+
+# tambien hay shift y unshift
+shift!(a) # => 1 y a es ahora [2,4,3,4,5,6]
+unshift!(a,7) # => [7,2,4,3,4,5,6]
+
+# Nombres de funciónes que terminan en exclamaciones indican que modifican
+# su argumento.
+arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
+sort(arr) # => [4,5,6]; arr es todavía [5,4,6]
+sort!(arr) # => [4,5,6]; arr es ahora [4,5,6]
+
+# Buscando fuera de límites es un BoundsError
+try
+ a[0] # => ERROR: BoundsError() in getindex at array.jl:270
+ a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
+catch e
+ println(e)
+end
+
+# Errors dan la línea y el archivo de su procedencia, aunque sea en el standard
+# library. Si construyes Julia de source, puedes buscar en el source para
+# encontrar estos archivos.
+
+# Se puede inicializar arrays de un range
+a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
+
+# Puedes mirar en ranges con sintaxis slice.
+a[1:3] # => [1, 2, 3]
+a[2:end] # => [2, 3, 4, 5]
+
+# Eliminar elementos de una array por índice con splice!
+arr = [3,4,5]
+splice!(arr,2) # => 4 ; arr es ahora [3,5]
+
+# Concatenar listas con append!
+b = [1,2,3]
+append!(a,b) # ahroa a es [1, 2, 3, 4, 5, 1, 2, 3]
+
+# Comprueba la existencia en una lista con in
+in(1, a) # => true
+
+# Examina la longitud con length
+length(a) # => 8
+
+# Tuples son immutable.
+tup = (1, 2, 3) # => (1,2,3) # un (Int64,Int64,Int64) tuple.
+tup[1] # => 1
+try:
+ tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
+catch e
+ println(e)
+end
+
+# Muchas funciones de lista también trabajan en las tuples
+length(tup) # => 3
+tup[1:2] # => (1,2)
+in(2, tup) # => true
+
+# Se puede desempacar tuples en variables
+a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
+
+# Los tuples se crean, incluso si se omite el paréntesis
+d, e, f = 4, 5, 6 # => (4,5,6)
+
+# Un tuple 1-elemento es distinto del valor que contiene
+(1,) == 1 # => false
+(1) == 1 # => true
+
+# Mira que fácil es cambiar dos valores
+e, d = d, e # => (5,4) # d is now 5 and e is now 4
+
+
+# Dictionaries almanecan mapeos
+dict_vacio = Dict() # => Dict{Any,Any}()
+
+# Se puede crear un dictionary usando un literal
+dict_lleno = ["one"=> 1, "two"=> 2, "three"=> 3]
+# => Dict{ASCIIString,Int64}
+
+# Busca valores con []
+dict_lleno["one"] # => 1
+
+# Obtén todas las claves
+keys(dict_lleno)
+# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# Nota - claves del dictionary no están ordenados ni en el orden en que se
+# insertan.
+
+# Obtén todos los valores
+values(dict_lleno)
+# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# Nota - Igual que el anterior en cuanto a ordenamiento de claves.
+
+# Compruebe si hay existencia de claves en un dictionary con in y haskey
+in(("uno", 1), dict_lleno) # => true
+in(("tres", 3), dict_lleno) # => false
+haskey(dict_lleno, "one") # => true
+haskey(dict_lleno, 1) # => false
+
+# Tratando de buscar una clave que no existe producirá un error
+try
+ dict_lleno["dos"] # => ERROR: key not found: dos in getindex at dict.jl:489
+catch e
+ println(e)
+end
+
+# Utilice el método get para evitar ese error proporcionando un valor
+# predeterminado
+# get(dictionary,key,default_value)
+get(dict_lleno,"one",4) # => 1
+get(dict_lleno,"four",4) # => 4
+
+# Usa Sets para representar colecciones (conjuntos) de valores únicos, no
+# ordenadas
+conjunto_vacio = Set() # => Set{Any}()
+# Iniciar una set de valores
+conjunto_lleno = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
+
+# Añadir más valores a un conjunto
+push!(conjunto_lleno,5) # => Set{Int64}(5,4,2,3,1)
+push!(conjunto_lleno,5) # => Set{Int64}(5,4,2,3,1)
+
+# Compruebe si los valores están en el conjunto
+in(2, conjunto_lleno) # => true
+in(10, conjunto_lleno) # => false
+
+# Hay funciones de intersección de conjuntos, la unión, y la diferencia.
+conjunto_otro= Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
+intersect(conjunto_lleno, conjunto_otro) # => Set{Int64}(3,4,5)
+union(conjunto_lleno, conjunto_otro) # => Set{Int64}(1,2,3,4,5,6)
+setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
+
+
+####################################################
+## 3. Control de Flujo
+####################################################
+
+# Hagamos una variable
+una_variable = 5
+
+# Aquí está una declaración de un 'if'. La indentación no es significativa en
+# Julia
+if una_variable > 10
+ println("una_variable es completamente mas grande que 10.")
+elseif una_variable < 10 # Este condición 'elseif' es opcional.
+ println("una_variable es mas chica que 10.")
+else # Esto también es opcional.
+ println("una_variable es de hecho 10.")
+end
+# => imprime "una_variable es mas chica que 10."
+
+# For itera sobre tipos iterables
+# Tipos iterables incluyen Range, Array, Set, Dict, y String.
+for animal=["perro", "gato", "raton"]
+ println("$animal es un mamifero")
+ # Se puede usar $ para interpolar variables o expresiónes en strings
+end
+# imprime:
+# perro es un mamifero
+# gato es un mamifero
+# raton es un mamifero
+
+for a in ["perro"=>"mamifero","gato"=>"mamifero","raton"=>"mamifero"]
+ println("$(a[1]) es un $(a[2])")
+end
+# imprime:
+# perro es un mamifero
+# gato es un mamifero
+# raton es un mamifero
+
+for (k,v) in ["perro"=>"mamifero", "gato"=>"mamifero", "raton"=>"mamifero"]
+ println("$k es un $v")
+end
+# imprime:
+# perro es un mamifero
+# gato es un mamifero
+# raton es un mamifero
+
+# While itera hasta que una condición no se cumple.
+x = 0
+while x < 4
+ println(x)
+ x += 1 # versión corta de x = x + 1
+end
+# imprime:
+# 0
+# 1
+# 2
+# 3
+
+# Maneja excepciones con un bloque try/catch
+try
+ error("ayuda")
+catch e
+ println("capturando $e")
+end
+# => capturando ErrorException("ayuda")
+
+
+####################################################
+## 4. Funciones
+####################################################
+
+# Usa 'function' para crear nuevas funciones
+
+#function nombre(arglist)
+# cuerpo...
+#end
+function suma(x, y)
+ println("x es $x e y es $y")
+
+ # Las funciones devuelven el valor de su última declaración
+ x + y
+end
+
+suma(5, 6) # => 11 # después de imprimir "x es 5 e y es de 6"
+
+# Puedes definir funciones que toman un número variable de
+# argumentos posicionales
+function varargs(args...)
+ return args
+ # Usa la palabra clave return para devolver en cualquier lugar de la función
+end
+# => varargs (generic function with 1 method)
+
+varargs(1,2,3) # => (1,2,3)
+
+# El ... se llama un splat.
+# Acabamos de utilizar lo en una definición de función.
+# También se puede utilizar en una llamada de función,
+# donde va splat un Array o el contenido de un Tuple en la lista de argumentos.
+Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # Produce un Set de Arrays
+Set([1,2,3]...) # => Set{Int64}(1,2,3) # esto es equivalente a Set(1,2,3)
+
+x = (1,2,3) # => (1,2,3)
+Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # un Set de Tuples
+Set(x...) # => Set{Int64}(2,3,1)
+
+
+# Puede definir funciones con argumentos posicionales opcionales
+function defaults(a,b,x=5,y=6)
+ return "$a $b y $x $y"
+end
+
+defaults('h','g') # => "h g y 5 6"
+defaults('h','g','j') # => "h g y j 6"
+defaults('h','g','j','k') # => "h g y j k"
+try
+ defaults('h') # => ERROR: no method defaults(Char,)
+ defaults() # => ERROR: no methods defaults()
+catch e
+ println(e)
+end
+
+# Puedes definir funciones que toman argumentos de palabra clave
+function args_clave(;k1=4,nombre2="hola") # note the ;
+ return ["k1"=>k1,"nombre2"=>nombre2]
+end
+
+args_clave(nombre2="ness") # => ["nombre2"=>"ness","k1"=>4]
+args_clave(k1="mine") # => ["k1"=>"mine","nombre2"=>"hola"]
+args_clave() # => ["nombre2"=>"hola","k1"=>4]
+
+# Puedes combinar todo tipo de argumentos en la misma función
+function todos_los_args(arg_normal, arg_posicional_opcional=2; arg_clave="foo")
+ println("argumento normal: $arg_normal")
+ println("argumento optional: $arg_posicional_opcional")
+ println("argumento de clave: $arg_clave")
+end
+
+todos_los_args(1, 3, arg_clave=4)
+# imprime:
+# argumento normal: 1
+# argumento optional: 3
+# argumento de clave: 4
+
+# Julia tiene funciones de primera clase
+function crear_suma(x)
+ suma = function (y)
+ return x + y
+ end
+ return suma
+end
+
+# Esta es el sintaxis "stabby lambda" para crear funciones anónimas
+(x -> x > 2)(3) # => true
+
+# Esta función es idéntica a la crear_suma implementación anterior.
+function crear_suma(x)
+ y -> x + y
+end
+
+# También puedes nombrar la función interna, si quieres
+function crear_suma(x)
+ function suma(y)
+ x + y
+ end
+ suma
+end
+
+suma_10 = crear_suma(10)
+suma_10(3) # => 13
+
+
+# Hay funciones integradas de orden superior
+map(suma_10, [1,2,3]) # => [11, 12, 13]
+filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# Podemos usar listas por comprensión para mapeos
+[suma_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
+[suma_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+
+####################################################
+## 5. Tipos
+####################################################
+
+# Julia tiene sistema de tipos.
+# Cada valor tiene un tipo y las variables no tienen propios tipos.
+# Se puede utilizar la función `typeof` para obtener el tipo de un valor.
+typeof(5) # => Int64
+
+# Los tipos son valores de primera clase
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
+# DataType es el tipo que representa los tipos, incluyéndose a sí mismo.
+
+# Los tipos se usan para la documentación, optimizaciones, y envio.
+# No están comprobados estáticamente.
+
+# Los usuarios pueden definir tipos
+# Son como registros o estructuras en otros idiomas.
+# Nuevos tipos se definen utilizado la palabra clave `type`.
+
+# type Nombre
+# field::OptionalType
+# ...
+# end
+type Tigre
+ longituddecola::Float64
+ colordelpelaje # no incluyendo una anotación de tipo es el mismo que `::Any`
+end
+
+# Los argumentos del constructor por default son las propiedades
+# del tipo, en el orden en que están listados en la definición
+tigger = Tigre(3.5,"anaranjado") # => Tiger(3.5,"anaranjado")
+
+# El tipo funciona como la función constructora de valores de ese tipo
+sherekhan = typeof(tigger)(5.6,"fuego") # => Tiger(5.6,"fuego")
+
+
+# Este estilo de tipos son llamados tipos concrete
+# Se pueden crear instancias, pero no pueden tener subtipos.
+# La otra clase de tipos es tipos abstractos (abstract types).
+
+# abstract Nombre
+abstract Gato # sólo un nombre y un punto en la jerarquía de tipos
+
+# De los tipos Abstract no se pueden crear instancias, pero pueden tener
+# subtipos. Por ejemplo, Number es un tipo abstracto.
+subtypes(Number) # => 6-element Array{Any,1}:
+ # Complex{Float16}
+ # Complex{Float32}
+ # Complex{Float64}
+ # Complex{T<:Real}
+ # Real
+subtypes(Gato) # => 0-element Array{Any,1}
+
+# Cada tipo tiene un supertipo, utilice la función `súper` para conseguirlo.
+typeof(5) # => Int64
+super(Int64) # => Signed
+super(Signed) # => Real
+super(Real) # => Number
+super(Number) # => Any
+super(super(Signed)) # => Number
+super(Any) # => Any
+# Todo de estos tipos, a excepción de Int64, son abstractos.
+
+# <: es el operador de subtipos
+type Leon <: Gato # Leon es un subtipo de Gato
+ color_de_crin
+ rugido::String
+end
+
+# Se puede definir más constructores para su tipo.
+# Sólo defina una función del mismo nombre que el tipo
+# y llame a un constructor existente para obtener un valor del tipo correcto
+Leon(rugido::String) = Leon("verde",rugido)
+# Este es un constructor externo porque es fuera de la definición del tipo
+
+type Pantera <: Gato # Pantera tambien es un a subtipo de Cat
+ color_de_ojos
+ Pantera() = new("verde")
+ # Panteras sólo tendrán este constructor, y ningún constructor
+ # predeterminado.
+end
+# Utilizar constructores internos, como Panther hace, te da control sobre cómo
+# se pueden crear valores del tipo. Cuando sea posible, debes utilizar
+# constructores exteriores en lugar de los internos.
+
+####################################################
+## 6. Envio múltiple
+####################################################
+
+# En Julia, todas las funciones nombradas son funciones genéricas.
+# Esto significa que se construyen a partir de muchos métodos pequeños
+# Cada constructor de Leon es un método de la función genérica Leon.
+
+# Por ejemplo, vamos a hacer un maullar función:
+
+# Definiciones para Leon, Pantera, y Tigre
+function maullar(animal::Leon)
+ animal.rugido # acceso utilizando notación de puntos
+end
+
+function maullar(animal::Pantera)
+ "grrr"
+end
+
+function maullar(animal::Tigre)
+ "rawwwr"
+end
+
+# Prueba de la función maullar
+maullar(tigger) # => "rawwr"
+maullar(Leon("cafe","ROAAR")) # => "ROAAR"
+maullar(Pantera()) # => "grrr"
+
+# Revisar la jerarquía de tipos locales
+issubtype(Tigre,Gato) # => false
+issubtype(Leon,Gato) # => true
+issubtype(Pantera,Gato) # => true
+
+# Definición de una función que toma Gatos
+function mascota(gato::Gato)
+ println("El gato dice $(maullar(gato))")
+end
+
+mascota(Leon("42")) # => imprime "El gato dice 42"
+try
+ mascota(tigger) # => ERROR: no method mascota(Tigre))
+catch e
+ println(e)
+end
+
+# En los lenguajes orientados a objetos, expedición única es común. Esto
+# significa que el método se recogió basándose en el tipo del primer argumento.
+# En Julia, todos los tipos de argumentos contribuyen a seleccionar el mejor
+# método.
+
+# Vamos a definir una función con más argumentos, para que podamos ver la
+# diferencia
+function pelear(t::Tigre,c::Gato)
+ println("¡El tigre $(t.colordelpelaje) gana!")
+end
+# => pelear (generic function with 1 method)
+
+pelear(tigger,Pantera()) # => imprime ¡El tigre anaranjado gana!
+pelear(tigger,Leon("ROAR")) # => ¡El tigre anaranjado gana!
+
+# Vamos a cambiar el comportamiento cuando el Gato es específicamente un Leon
+pelear(t::Tigre,l::Leon) = println("El león con melena $(l.color_de_crin) gana")
+# => pelear (generic function with 2 methods)
+
+pelear(tigger,Pantera()) # => imprime ¡El tigre anaranjado gana!
+pelear(tigger,Leon("ROAR")) # => imprime El león con melena verde gana
+
+# No necesitamos un tigre para poder luchar
+pelear(l::Leon,c::Gato) = println("El gato victorioso dice $(maullar(c))")
+# => fight (generic function with 3 methods)
+
+pelear(Leon("balooga!"),Pantera()) # => imprime El gato victorioso dice grrr
+try
+ pelear(Pantera(),Leon("RAWR")) # => ERROR: no method pelear(Pantera, Leon))
+catch
+end
+
+# Un metodo con el gato primero
+pelear(c::Gato,l::Leon) = println("El gato le gana al León")
+# Warning: New definition
+# pelear(Gato,Leon) at none:1
+# is ambiguous with:
+# pelear(Leon,Gato) at none:1.
+# To fix, define
+# pelear(Leon,Leon)
+# before the new definition.
+# pelear (generic function with 4 methods)
+
+# Esta advertencia se debe a que no está claro que metodo de pelear será llamado
+# en:
+pelear(Leon("RAR"),Leon("cafe","rar")) # => imprime El gato victorioso dice rar
+# El resultado puede ser diferente en otras versiones de Julia
+
+pelear(l::Leon,l2::Leon) = println("Los leones llegan a un empate")
+pelear(Leon("GR"),Leon("cafe","rar")) # => imprime Los leones llegan a un empate
+
+
+# Un vistazo al nivel bajo
+# Se puede echar un vistazo a la LLVM y el código ensamblador generado.
+
+area_cuadrada(l) = l * l # area_cuadrada (generic function with 1 method)
+
+area_cuadrada(5) # => 25
+
+# ¿Qué sucede cuando damos area_cuadrada diferentes argumentos?
+code_native(area_cuadrada, (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(area_cuadrada, (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(area_cuadrada, (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
+ #
+
+# Ten en cuenta que Julia usará instrucciones de "floating point" si alguno de
+# los argumentos son "floats"
+# Vamos a calcular el área de un círculo
+area_circulo(r) = pi * r * r # circle_area (generic function with 1 method)
+area_circulo(5) # 78.53981633974483
+
+code_native(area_circulo, (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(area_circulo, (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
+ #
+```
+
+## ¿Listo para más?
+
+Puedes obtener muchos más detalles en [The Julia Manual](http://docs.julialang.org/en/latest/manual/)
+
+El mejor lugar para obtener ayuda con Julia es el (muy amable) [lista de correos](https://groups.google.com/forum/#!forum/julia-users).
+
diff --git a/es-es/perl-es.html.markdown b/es-es/perl-es.html.markdown
new file mode 100644
index 00000000..4f0c26c1
--- /dev/null
+++ b/es-es/perl-es.html.markdown
@@ -0,0 +1,160 @@
+---
+name: perl
+category: language
+language: perl
+filename: learnperl-es.pl
+contributors:
+ - ["Korjavin Ivan", "http://github.com/korjavin"]
+translators:
+ - ["Francisco Gomez", "http://github.com/frncscgmz"]
+lang: es-es
+---
+
+Perl 5 es un lenguaje de programación altamente capaz, rico en características con mas de 25 años de desarrollo.
+
+Perl 5 corre en mas de 100 plataformas desde portales hasta mainframes y es adecuado para realizar prototipos rápidos hasta desarrollar proyectos a gran escala.
+
+```perl
+# Comentarios de una sola linea con un carácter hash.
+
+#### Tipos de variables en Perl
+
+# Las variables comienzan con el símbolo $.
+# Un nombre de variable valido empieza con una letra o un guión bajo,
+# seguido por cualquier numero de letras, números o guiones bajos.
+
+### Perl tiene tres tipos principales de variables: escalares, arreglos y hashes.
+
+## Escalares
+# Un escalar representa un solo valor:
+my $animal = "camello";
+my $respuesta = 42;
+
+# Los valores escalares pueden ser cadenas de caracteres, números enteros o
+# de punto flotante, Perl automáticamente los convertirá como sea requerido.
+
+## Arreglos
+# Un arreglo representa una lista de valores:
+my @animales = {"camello","llama","buho"};
+my @numeros = {23,42,69};
+my @mixto = {"camello",42,1.23};
+
+
+
+## Hashes
+# Un hash representa un conjunto de pares llave/valor:
+
+my %color_fruta = {"manzana","rojo","banana","amarillo"};
+
+# Puedes usar un espacio en blanco y el operador "=>" para asignarlos mas
+# fácilmente.
+
+my %color_fruta = (
+ manzana => "rojo",
+ banana => "amarillo",
+ );
+# Los escalares, arreglos y hashes están mas documentados en perldata. (perldoc perldata).
+
+# Los tipos de datos mas complejos pueden ser construidos utilizando
+# referencias, las cuales te permiten construir listas y hashes dentro
+# de listas y hashes.
+
+#### Estructuras condicionales y de ciclos
+
+# Perl tiene la mayoría de las estructuras condicionales y de ciclos mas comunes.
+
+if ( $var ) {
+ ...
+} elsif ( $var eq 'bar' ) {
+ ...
+} else {
+ ...
+}
+
+unless ( condicion ) {
+ ...
+ }
+# Esto es proporcionado como una version mas fácil de leer que "if (!condición)"
+
+# La post condición al modo Perl
+print "Yow!" if $zippy;
+print "No tenemos bananas" unless $bananas;
+
+# while
+ while ( condicion ) {
+ ...
+ }
+
+
+# for y foreach
+for ($i = 0; $i <= $max; $i++) {
+ ...
+ }
+
+foreach (@array) {
+ print "Este elemento es $_\n";
+ }
+
+
+#### Expresiones regulares
+
+# El soporte de expresiones regulares en Perl es muy amplio y profundo, y es
+# sujeto a una extensa documentación en perlrequick, perlretut, entre otros.
+# Sin embargo, resumiendo:
+
+# Pareo simple
+if (/foo/) { ... } # verdadero si $_ contiene "foo"
+if ($a =~ /foo/) { ... } # verdadero si $a contiene "foo"
+
+# Substitución simple
+$a =~ s/foo/bar/; # remplaza foo con bar en $a
+$a =~ s/foo/bar/g; # remplaza TODAS LAS INSTANCIAS de foo con bar en $a
+
+
+#### Archivos e I/O
+
+# Puedes abrir un archivo para obtener datos o escribirlos utilizando la
+# función "open()".
+
+open(my $entrada, "<" "entrada.txt") or die "No es posible abrir entrada.txt: $!";
+open(my $salida, ">", "salida.txt") or die "No es posible abrir salida.txt: $!";
+open(my $log, ">>", "mi.log") or die "No es posible abrir mi.log: $!";
+
+# Es posible leer desde un gestor de archivo abierto utilizando el operador "<>"
+# operador. En contexto escalar leer una sola linea desde el gestor de
+# archivo, y en contexto de lista leer el archivo completo en donde, asigna
+# cada linea a un elemento de la lista.
+
+my $linea = <$entrada>;
+my @lineas = <$entrada>;
+
+#### Escribiendo subrutinas
+
+# Escribir subrutinas es fácil:
+
+sub logger {
+ my $mensajelog = shift;
+ open my $archivolog, ">>", "mi.log" or die "No es posible abrir mi.log: $!";
+ print $archivolog $mensajelog;
+}
+
+# Ahora podemos utilizar la subrutina al igual que cualquier otra función
+# incorporada:
+
+logger("Tenemos una subrutina logger!");
+
+
+```
+
+#### Utilizando módulos Perl
+
+Los módulos en Perl proveen una gama de funciones que te pueden ayudar a evitar reinventar la rueda, estas pueden ser descargadas desde CPAN( http://www.cpan.org/ ). Algunos de los módulos mas populares ya están incluidos con la misma distribución de Perl.
+
+perlfaq contiene preguntas y respuestas relacionadas con muchas tareas comunes, y algunas veces provee sugerencias sobre buenos módulos CPAN para usar.
+
+#### Material de Lectura
+
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [Aprende en www.perl.com](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - y perl incorporado: `perldoc perlintro`
diff --git a/fa-ir/brainfuck.html.markdown b/fa-ir/brainfuck.html.markdown
new file mode 100644
index 00000000..ef2bcba3
--- /dev/null
+++ b/fa-ir/brainfuck.html.markdown
@@ -0,0 +1,81 @@
+---
+language: brainfuck
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+lang: fa-ir
+---
+
+<p dir='rtl'>برین فاک زبان برنامه نویسی تورینگ کامل بی نهایت ساده ایست که دارای فقط هشت</p>
+<p dir='rtl'>دستور است.</p>
+
+<p dir='rtl'>هر کارکتری به جر کارکتر های زیر در این زبان در نظر گرفته نمیشود.</p>
+
+
+`>` `<` `+` `-` `.` `,` `[` `]`
+
+<p dir='rtl'>برین فاک به صورت یک آرایه ی سی هزار خانه ای کار میکند که در ابتدا تمامی خانه های آن صفر هستند.</p>
+<p dir='rtl'>همچنین یک اشاره گر در این برنامه به خانه ی فعلی اشاره میکند.</p>
+
+<p dir='rtl'>در زیر هشت دستور این زبان شرح داده شده است:</p>
+
+<p dir='rtl'>`+` : یک عدد به خانه ی فعلی اضافه می کند.
+<p dir='rtl'>`-` : یک عدد از خانه ی فعلی کم می کند. </p>
+<p dir='rtl'>`>` : اشاره گر به خانه ی بعدی میرود -- به راست</p>
+<p dir='rtl'>`<` : اشاره گر به خانه ی قبلی میرود -- به چپ</p>
+<p dir='rtl'>`.` : کارکتر اسکی معادل مقدار خانه ی فعلی را چاپ میکند. -- به عنوان مثال 65 برای A</p>
+<p dir='rtl'>`,` : یک کارکتر را از ورودی خوانده و مقدار آن را در خانه ی فعلی زخیره میکند.</p>
+<p dir='rtl'>`[` : اگر مقدار خانه ی فعلی صفر باشد به محل بسته شدن کروشه جهش میکند. -- و از همه ی دستور های بین آن صرف نظر میشود.</p>
+<p dir='rtl'>در غیر این صورت به دستور بعدی میرود.</p>
+<p dir='rtl'>`]` : اگر مقدار خانه ی فعلی صفر باشد به خانه ی بعدی و در غیر این صورت به محل باز شدن کروشه جهش می کند. -- به عقب</p>
+
+<p dir='rtl'>دو علامت کروشه امکان ایجاد حلقه را فراهم میکنند.</p>
+
+<p dir='rtl'>در اینجا یک برنامه ی ساره برین فاک را مشاهده میکنید.</p>
+
+```
+++++++ [ > ++++++++++ < - ] > +++++ .
+```
+
+<p dir='rtl'>این برنامه کارکتر A را بر روی خروجی چاپ میکند.</p>
+<p dir='rtl'>در این برنامه خانه ی اول به عنوان متغیر حلقه و خانه ی دوم برای مقدار عددی A</p>
+<p dir='rtl'>ابتدا عدد شش در خانه ی اول ایجاد شده. سپس برنامه وارد یک حلقه میشود که در هر بار </p>
+<p dir='rtl'>تکرار آن اشاره گر به خانه ی دوم رفته و ده بار به خانه ی فعلی اضافه می کند.</p>
+<p dir='rtl'>-- و در انتهای حلقه به خانه ی اول برگشته تا حلقه کنترل شود</p>
+<p dir='rtl'>بعد از اتمام حلقه به خانه ی دوم میرود و پنج بار به این خانه اضافه کرده و سپس آنرا چاپ میکند.</p>
+
+```
+, [ > + < - ] > .
+```
+
+<p dir='rtl'>در این برنامه ابتدا یک کارکتر از ورودی خوانده می شود. سپس یک حلقه به تعداد بار مقدار</p>
+<p dir='rtl'>عددی کارکتر، یک عدد به خانه ی دوم اضافه می کند. با این کار در واقع برنامه مقدار ورودی را در خانه ی </p>
+<p dir='rtl'>دوم کپی می کند. و در نهایت آن را برروی خروجی چاپ می کند.</p>
+
+<p dir='rtl'>توجه داشته باشید که ردر بالا فواصل بین دستور ها فقط برای خوانایی بیشتر گذاشته شده اند.</p>
+<p dir='rtl'>در واقع برنامه بالا به شکل زیر صحیح می باشد.</p>
+
+```
+,[>+<-]>.
+```
+
+<p dir='rtl'>حال سعی کنید ببینید که برنامه ی زیر چه کاری انجام می دهد؟</p>
+
+```
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+```
+
+<p dir='rtl'>این برنامه دو عدد را از ورودی خوانده و با هم ضرب می کند.</p>
+
+<p dir='rtl'>ابتدا دو عدد از ورودی خوانده می شوند. سپس حلقه ی بیرونی بر روی خانه شماره یک شروع میشود.</p>
+<p dir='rtl'>و درون آن حلقه ی دیگری بر روی خانه ی دوم شروع میشود که خانه ی 3 را زیاد میکند.</p>
+<p dir='rtl'>ولی مشکلی که در اینجا به وجود می آید اینست که در پایان حلقه ی دوم مقدار خانه ی 2 صفر شده</p>
+<p dir='rtl'>و مقدار اولیه ی آن از دست رفته است. برای حل این مشکل خانه ی شماره چهار هم زیاد میشود</p>
+<p dir='rtl'>و در پایان حلقه مقدار آن به خانه 2 کپی میشود.</p>
+<p dir='rtl'>در پایان خانه ی شماره 2 حاوی حاصلضرب خواهد بود.</p>
+
+<hr>
+
+<p dir='rtl'>و این همه ی برین فاک بود! خیلی ساده برای یادگیری ولی سنگین برای به کار بردن.</p>
+<p dir='rtl'>حال می توانید برای تفریح مشغول نوشتن برنامه ی های مختلف با آن شوید.</p>
+<p dir='rtl'>و یا یک اجرا کننده برین فاک را با یک زبان دیگر پیاده سازی کنید.</p>
+<p dir='rtl'>و یا اگر خیلی دوست داشتید یک اجرا کننده ی برین فاک با برین فاک بنویسید!!</p>
diff --git a/fa-ir/javascript.html.markdown b/fa-ir/javascript.html.markdown
new file mode 100644
index 00000000..922fe416
--- /dev/null
+++ b/fa-ir/javascript.html.markdown
@@ -0,0 +1,556 @@
+---
+language: javascript
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+translators:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+filename: javascript-fa.js
+lang: fa-ir
+---
+
+<p dir='rtl'>
+جاوااسکریپت توسط برندن ایش از شرکت NetScape در سال 1995 ساخته شد. در ابتدا به عنوان یک زبان اسکریپت‌نویسی در کنار جاوا (که برای موارد پیچیده تر در طراحی وب در نظر گرفته میشد) مورد استفاده بود، ولی در پی نفوذ بسیار گسترده آن در وب و همچنین پشتیبانی پیش-ساخته آن در مرورگر ها، امروزه به مراتب بیشتر از جاوا در برنامه نویسی سمت-کاربر در وب به کار برده میشود.
+با این حال جاوااسکریپت فقط محدود به مرورگر های وب نمیشود. Node.js پروژه ایست که یک نسخه ی مستقل از اجراکننده ی موتور جاوااسکریپت V8 از گوگل کروم را در اختیار قرار میده که هر روزه درحال محبوب تر شدن نیز هست.
+</p>
+
+<p dir='rtl'>
+قدر دان نظرات سازنده شما هستم! شما میتوانید از طریق زیر با من تماس بگیرید:
+</p>
+
+[@adambrenecki](https://twitter.com/adambrenecki), or
+[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+
+<p dir='rtl'>
+// توضیحات همانند C هستند. توضیحات یک خطی با دو خط مورب شروع میشوند.,
+</p>
+
+<p dir='rtl'>
+/* و توضیحات چند خطی با خط مورب-ستاره شروع،
+ و با ستاره-خط مورب ختم میشوند */
+</p>
+
+```js
+// Comments are like C. Single-line comments start with two slashes,
+/* and multiline comments start with slash-star
+ and end with star-slash */
+```
+<p dir='rtl'>
+گزاره ها را میتوانید با نقطه ویرگول پایان دهید ;
+</p>
+```js
+doStuff();
+```
+<p dir='rtl'>
+ولی لزومی به این کار نیست. نقطه ویرگول به صورت خودکار در نظر گرفته میشوند.
+</p>
+<p dir='rtl'>
+وقتی که خط جدیدی شروع میشود. مگر در موارد خاص.
+</p>
+```js
+doStuff()
+```
+<p dir='rtl'>برای اینگه درگیر آن موارد خاص نشویم، در اینجا از اون ها </p>
+<p dir='rtl'>صرف نظر میکنیم.</p>
+
+<h2 dir='rtl'>1. اعداد، رشته ها و عملگرها</h2>
+
+<p dir='rtl'>جاوااسکریپت فقط یک نوع عدد دارد و آن عدد اعشاری 64 بیتی IEEE 754 است.</p>
+<p dir='rtl'>نترسید! و نگران اعداد صحیح نباشید! این اعداد اعشاری دارای 54 بیت مانتیس هستند که قابلیت ذخیره ی </p>
+<p dir='rtl'>دقیق اعداد صحیح تا مقدار تقریبی 9x10¹⁵ را دارند.</p>
+```js
+3; // = 3
+1.5; // = 1.5
+```
+<p dir='rtl'>
+تمامی عملگر های محاسباتی آن طوری که انتظارش را دارید عمل خواهند کرد.
+</p>
+```js
+1 + 1; // = 2
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+```
+<p dir='rtl'>و این حتی شامل تقسیم هم میشود.</p>
+```js
+5 / 2; // = 2.5
+```
+<p dir='rtl'>عملگر های بیتی هم به همین شکل. وقتی از یک عملگر بیتی استفاده میکنید، عدد اعشاری شما</p>
+<p dir='rtl'>به عدد صحیح علامت دار *تا 32 بیت* تبدیل میشود.</p>
+```js
+1 << 2; // = 4
+```
+<p dir='rtl'>عملیات داخل پرانتز تقدم بالاتری دارند.</p>
+```js
+(1 + 3) * 2; // = 8
+```
+<p dir='rtl'>سه مقدار خاص وجود دارند که در واقع مقادیر عددی نیستند:</p>
+```js
+Infinity; // result of e.g. 1/0
+-Infinity; // result of e.g. -1/0
+NaN; // result of e.g. 0/0
+```
+<p dir='rtl'>مقادیر بولی هم تعریف شده هستند:</p>
+```js
+true;
+false;
+```
+<p dir='rtl'>رشته ها با آپستروف و یا گیومه تعریف میشوند.</p>
+```js
+'abc';
+"Hello, world";
+```
+<p dir='rtl'>و منفی کردن شرط با علامت تعجب</p>
+```js
+!true; // = false
+!false; // = true
+```
+<p dir='rtl'>تساوی دو مقدار با ==</p>
+```js
+1 == 1; // = true
+2 == 1; // = false
+```
+<p dir='rtl'>و عدم تساوی با !=</p>
+```js
+1 != 1; // = false
+2 != 1; // = true
+```
+<p dir='rtl'>و سایر عمیلات های مقایسه</p>
+```js
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
+```
+<p dir='rtl'>رشته ها با علامت جمع به یکدیگر متصل میشوند</p>
+```js
+"Hello " + "world!"; // = "Hello world!"
+```
+<p dir='rtl'>و با علامت برگتر و یا کوچکتر با یکدیگر مقایسه میشوند.</p>
+```js
+"a" < "b"; // = true
+```
+<p dir='rtl'>نوع متغیر برای عملیات مقایسه تطبیق داده میشود</p>
+```js
+"5" == 5; // = true
+```
+<p dir='rtl'>مگر اینکه از سه مساوی استفاده شود!</p>
+```js
+"5" === 5; // = false
+```
+<p dir='rtl'>با استفاده از charAt میتوانید به کارکتر های یک رشته دسترسی پیدا کنید.</p>
+```js
+"This is a string".charAt(0);
+```
+<p dir='rtl'>از null برای نشان دادن عمدی مقدار هیج استفاده میشود.</p>
+<p dir='rtl'>و از undefined برای نشان دادن اینکه در حال حاظر مقدار موجود نمی باشد، هرچند خود undefined یک مقدار محسوب میشود.</p>
+```js
+null; // used to indicate a deliberate non-value
+undefined; // used to indicate a value is not currently present (although undefined
+ // is actually a value itself)
+```
+<p dir='rtl'>false, null, undefined, NaN, 0 و "" مقدار نادرست و هر چیز دیگر مقدار درست طلقی میشوند.</p>
+<p dir='rtl'>توجه داشته باشید که 0 نادرست و "0" درست طلقی میشوند حتی در عبارت 0=="0".</p>
+
+<h2 dir='rtl'> 2. متغیر ها، آرایه ها و شئ ها </h2>
+
+<p dir='rtl'>متغیر ها با کلید واژه var تعریف میشوند. اشیا در جاوااسکریپت دارای نوع پویا هستند، </p>
+<p dir='rtl'>بدین شکل که برای تعریف نیازی به مشخص کردن نوع متعیر نیست. </p>
+<p dir='rtl'>برای مقدار دهی از علامت مساوی استفاده میشود. </p>
+```js
+var someVar = 5;
+```
+
+<p dir='rtl'>اگر کلید واژه var را قرار ندهید، هیچ خطایی دریافت نخواهید کرد... </p>
+```js
+someOtherVar = 10;
+```
+
+<p dir='rtl'>در عوض متغیر شما در گستره ی کل برنامه تعریف شده خواهد بود. </p>
+
+<p dir='rtl'>متغیر هایی که تعریف شده ولی مقدار دهی نشوند، دارای مقدار undefined خواهند بود. </p>
+```js
+var someThirdVar; // = undefined
+```
+
+<p dir='rtl'>برای اعمال عملگر های محاسباتی، میانبر هایی وجود دارند: </p>
+```js
+someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now
+someVar *= 10; // now someVar is 100
+```
+
+<p dir='rtl'>حتی از این هم کوتاهتر برای اضافه یا کم کردن یک عدد با مقدار یک. </p>
+```js
+someVar++; // now someVar is 101
+someVar--; // back to 100
+```
+
+<p dir='rtl'>آرایه ها در واقع لیستی مرتب شده از مقادیر مختلف از هر نوعی هستند. </p>
+```js
+var myArray = ["Hello", 45, true];
+```
+
+<p dir='rtl'>به اعضای یک آرایه میتوان از طریق قرار دادن کروشه در جلوی نام آن دسترسی پیدا کرد. </p>
+<p dir='rtl'>نمایه ی آرایه از صفر شروع میشود. </p>
+```js
+myArray[1]; // = 45
+```
+
+<p dir='rtl'>آرایه ها ناپایدار و دارای طول قابل تغییر هستند </p>
+```js
+myArray.push("World");
+myArray.length; // = 4
+```
+
+<p dir='rtl'>در جاوااسکریپت، اشیاء چیزی شبیه دیکشنری و یا نقشه در زبان های دیگر هستند: </p>
+<p dir='rtl'>یک مجموعه ی نامرتب از جفت های کلید-مقدار. </p>
+```js
+var myObj = {key1: "Hello", key2: "World"};
+```
+
+<p dir='rtl'>کلید ها از نوع رشته هستند ولی در صورتی که مقدار معتبری برای اسم گزاری باشند نیازی به آوردن آنها درون گیومه نیست. </p>
+```js
+var myObj = {myKey: "myValue", "my other key": 4};
+```
+
+<p dir='rtl'>اعضای یک شئ را نیز میتوانید با استفاده از کروشه در مقابل نام آنها استخراج کنید. </p>
+```js
+myObj["my other key"]; // = 4
+```
+
+<p dir='rtl'>...و یا از طریق نقطه در صورتی که اسم عضو مورد نظر اسم معتبری برای اسم گزاری باشد.</p>
+```js
+myObj.myKey; // = "myValue"
+```
+
+<p dir='rtl'>اشیاء ناپایدار و قابل اضافه کردن عضو جدید هستند.</p>
+```js
+myObj.myThirdKey = true;
+```
+
+<p dir='rtl'>اگر سعی کنید عضوی را که وجود ندارد استخراج کنید، مقدار undefined را دریافت خواهید کرد. </p>
+```js
+myObj.myFourthKey; // = undefined
+```
+
+<h2 dir='rtl'>3. منطق و ساختار کنترل</h2>
+
+<p dir='rtl'>ساختار if به شکلی که انتظارش را دارید کار میکند.</p>
+```js
+var count = 1;
+if (count == 3){
+ // evaluated if count is 3
+} else if (count == 4) {
+ // evaluated if count is 4
+} else {
+ // evaluated if it's not either 3 or 4
+}
+```
+
+<p dir='rtl'>و همینطور حلقه while</p>
+```js
+while (true) {
+ // An infinite loop!
+}
+```
+
+<p dir='rtl'>حلقه do-while شبیه while است با این تفاوت که حداقل یکبار اجرا میشود.</p>
+```js
+var input
+do {
+ input = getInput();
+} while (!isValid(input))
+```
+
+<p dir='rtl'>حلقه for همانند زبان C و جاوا کار می کند.</p>
+<p dir='rtl'>مقدار دهی اولیه; شرط ادامه; چرخش حلقه</p>
+```js
+for (var i = 0; i < 5; i++){
+ // will run 5 times
+}
+```
+
+<p dir='rtl'>عملگر && و || به ترتیب "و" و "یا" ی منطقی هستند.</p>
+```js
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear";
+}
+if (colour == "red" || colour == "blue"){
+ // colour is either red or blue
+}
+```
+
+<p dir='rtl'>از || همچنین میتوان برای تعیین مقدار پیشفرض استفاده کرد.</p>
+```js
+var name = otherName || "default";
+```
+
+<h2 dir='rtl'>4. توابع و مفاهیم گستره و بستار</h2>
+
+<p dir='rtl'>توابع در جاوااسکریپت با استفاده از کلیدواژه ی function تعریف میشوند.</p>
+```js
+function myFunction(thing){
+ return thing.toUpperCase();
+}
+myFunction("foo"); // = "FOO"
+```
+
+<p dir='rtl'>توابع در جاوااسکریپت نوعی شئ پایه محسوب میشوند، بنابر این می توانید آنها را به اشیاء مختلف</p>
+<p dir='rtl'>اضافه کنید و یا به عنوان پارامتر به توابع دیگر ارسال کنید.</p>
+<p dir='rtl'>- برای مثال وقتی که با یک رویداد کار میکنید.</p>
+```js
+function myFunction(){
+ // this code will be called in 5 seconds' time
+}
+setTimeout(myFunction, 5000);
+```
+
+<p dir='rtl'>توجه کنید که setTimeout تابعی تعریف شده در جاوااسکریپت نیست، ولی مرورگر ها و node.js از آن پشتیبانی میکنند.</p>
+
+
+<p dir='rtl'>توابع نیازی به داشتن اسم ندارند. برای مثال وقتی تابعی را به تابعی دیگر ارسال میکنید</p>
+<p dir='rtl'>میتوانید آنرا به صورت بینام تعریف کنید.</p>
+```js
+setTimeout(function(){
+ // this code will be called in 5 seconds' time
+}, 5000);
+```
+
+<p dir='rtl'>توابع دارای محدوده ی متغیر های خود هستند.</p>
+<p dir='rtl'>بر خلاف دیگر ساختار ها - مانند if</p>
+```js
+if (true){
+ var i = 5;
+}
+i; // = 5 - not undefined as you'd expect in a block-scoped language
+```
+
+<p dir='rtl'>به همین دلیل الگوی خاصی به نام "تابعی که بلافاصله صدا زده میشود" پدید آمده </p>
+<p dir='rtl'>تا از اضافه شدن متغیر های قسمتی از برنامه به گستره ی کلی برنامه جلوگیری شود.</p>
+```js
+(function(){
+ var temporary = 5;
+ // We can access the global scope by assiging to the 'global object', which
+ // in a web browser is always 'window'. The global object may have a
+ // different name in non-browser environments such as Node.js.
+ window.permanent = 10;
+})();
+temporary; // raises ReferenceError
+permanent; // = 10
+```
+
+<p dir='rtl'>یکی از برترین ویژگی های جاوااسکریپت مفهومی با نام بستار است</p>
+<p dir='rtl'>بدین شکل که اگر تابعی درون تابع دیگری تعریف شود، تابع درونی به تمام متغیر های تابع خارجی دسترسی</p>
+<p dir='rtl'>خواهد داشت، حتی بعد از اینکه تابع خارجی به اتمام رسیده باشد.</p>
+```js
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!";
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout is asynchronous, so the sayHelloInFiveSeconds function will
+ // exit immediately, and setTimeout will call inner afterwards. However,
+ // because inner is "closed over" sayHelloInFiveSeconds, inner still has
+ // access to the 'prompt' variable when it is finally called.
+}
+sayHelloInFiveSeconds("Adam"); // will open a popup with "Hello, Adam!" in 5s
+```
+
+<h2 dir='rtl'>5. دیگر اشیاء، سازنده ها و پیش‌نمونه ها</h2>
+
+<p dir='rtl'>اشیاء میتوانند تابع داشته باشند.</p>
+```js
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+```
+
+<p dir='rtl'>وقتی تابع یک شی صدا زده می شود، تابع میتواند به سایر مقادیر درون آن شی </p>
+<p dir='rtl'>از طریق کلید واژه ی this دسترسی داشته باشد.</p>
+```js
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+```
+
+
+<p dir='rtl'>اینکه مقدار this چه باشد بستگی به این دارد که تابع چگونه صدا زده شود</p>
+<p dir='rtl'>نه اینکه تابع کجا تعریف شده است.</p>
+<p dir='rtl'>بنابر این تابع بالا اگر بدین شکل صدا زده شود کار نخواهد کرد</p>
+```js
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+```
+
+
+<p dir='rtl'>به همین شکل، تابعی که در جای دیگر تعریف شده را میتوانید به یک شی الحاق کنید</p>
+<p dir='rtl'>و بدین ترتیب تابع میتواند به مقادیر درون شی از طریق this دسترسی پیدا کند.</p>
+```js
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+}
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+```
+
+
+<p dir='rtl'>اگر تابعی با کلید new صدا زده شوند، شی جدیدی ایجاد شده و تابع در گستره ی آن صدا زده میشود.</p>
+<p dir='rtl'>توابعی که بدین شکل صدا زده شوند در واقع نقش سازنده را ایفا می کنند.</p>
+```js
+var MyConstructor = function(){
+ this.myNumber = 5;
+}
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+```
+
+
+<p dir='rtl'>تمامی اشیاء در جاوااسکریپت دارای یک پیش نمونه هستند</p>
+<p dir='rtl'>به شکلی که اگر تابع صدا زده شده بر روی شی مستقیما روی آن تعریف نشده باشد</p>
+<p dir='rtl'>اجرا کننده ی برنامه در لیست پیش نمونه به دنبال آن تابع خواهد گشت</p>
+
+<p dir='rtl'>برخی اجرا کننده های جاوااسکریپت به شما اجازه ی دسترسی به پیش نمونه های یک شی را از</p>
+<p dir='rtl'>طریق عضو جادویی __proto__ میدهند.</p>
+<p dir='rtl'>هرچند این به شناخت پیش نمونه ها کمک میکند ولی در حیطه ی جاوااسکریپت استاندارد قرار نمیگیرد.</p>
+<p dir='rtl'>در ادامه شکل استاندارد پیش نمونه ها مورد بررسی قرار میگیرند.</p>
+```js
+var myObj = {
+ myString: "Hello world!",
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+};
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+```
+
+<p dir='rtl'>این موضوع در مورد توابع نیز صدق میکند.</p>
+```js
+myObj.myFunc(); // = "hello world!"
+```
+
+
+<p dir='rtl'>اگر عضو مورد نظر در پیش نمونه ی شی یافت نشود، پیش نمونه ی پیش نمونه جستجو شده و الی آخر</p>
+```js
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+```
+
+
+<p dir='rtl'>توجه داشته باشید که پیش نمونه ها کپی نمی شوند و هر شی جدید به پیش نمونه موجود اشاره میکند</p>
+<p dir='rtl'>بدین ترتیب اگر تابعی به پیش نمونه اضافه شود تمامی اشیاء میتوانند به آن دسترسی پیدا کنند.</p>
+```js
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+```
+
+<p dir='rtl'>پیش تر اشاره شد که __proto__ راه استانداردی برای دسترسی به پیش نمونه نیست و هیچ استانداردی نیز برای دسترسی به پیش نمونه ی یک شی موجود پیش بینی نشده است</p>
+<p dir='rtl'>ولی دو راه برای ارائه پیش نمونه برای اشیاء جدید وجود دارد.</p>
+
+<p dir='rtl'>اولی وقتیست که از تابع Object.create استفاده میشود - که اخیرا به زبان اضافه شده است و بنابراین بر روی همه ی پیاده سازی های آن وجود ندارد.</p>
+```js
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+```
+
+
+<p dir='rtl'>راه دوم - که همه جا قابل استفاده است - مربوط به سازنده ها می شود.</p>
+<p dir='rtl'>سازنده ها دارای عضوی با نام prototype هستند. این پیش نمونه ی خود سازنده نیست</p>
+<p dir='rtl'>بلکه پیش نمونه ایست که به تمامی اشیاء ساخته شده توسط این سازنده الحاق میشود.</p>
+```js
+MyConstructor.prototype = {
+ myNumber: 5,
+ getMyNumber: function(){
+ return this.myNumber;
+ }
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6
+myNewObj2.getMyNumber(); // = 6
+```
+
+
+<p dir='rtl'>رشته ها و سایر سازنده های پیش ساخته ی زبان نیز دارای این ویژگی هستند.</p>
+```js
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+```
+
+
+<p dir='rtl'>به جز این که این سازنده ها دقیقا مانند سازنده های دیگر نیستند.</p>
+```js
+typeof(myNumber); // = 'number'
+typeof(myNumberObj); // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // This code won't execute, because 0 is falsy.
+}
+if (Number(0)){
+ // This code *will* execute, because Number(0) is truthy.
+}
+```
+
+
+<p dir='rtl'>ولی به هر حال هم اشیاء عادی و هم اشیاء پیش ساخته هر دو در داشتن پیش نمونه مشترک هستند</p>
+<p dir='rtl'>بنابر این شما میتوانید ویژگی و تابع جدیدی به رشته ها - به عنوان مثال - اضافه کنید.</p>
+
+
+<p dir='rtl'>گاها به از این خاصیت با عنوان پلی فیل و برای اضافه کردن ویژگی های جدید به مجموعه ای از اشیاء فعلی زبان استفاده میشود </p>
+<p dir='rtl'>که کاربرد فراوانی در پشتیبانی از نسخه های قدیمیتر مرورگر ها دارد.</p>
+```js
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+}
+"abc".firstCharacter(); // = "a"
+```
+
+
+<p dir='rtl'>برای مثال، پیشتر اشاره کردیم که Object.create در نسخه های جدید پشتیبانی نشده است</p>
+<p dir='rtl'>ولی میتوان آن را به صورت پلی فیل استفاده کرد.</p>
+```js
+if (Object.create === undefined){ // don't overwrite it if it exists
+ Object.create = function(proto){
+ // make a temporary constructor with the right prototype
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // then use it to create a new, appropriately-prototyped object
+ return new Constructor();
+ }
+}
+```
+
+<h2 dir='rtl'> منابع دیگر </h2>
+
+The [Mozilla Developer
+Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
+<p dir='rtl'>مرجعی بسیار خوب برای جاوااسکریپت به شکلی که در مرورگر ها مورد استفاده قرار گرفته است.</p>
+<p dir='rtl'>از آنجایی که این منبع یک ویکی میباشد همانطور که مطالب بیشتری یاد میگیرید میتوانید به دیگران نیز در یادگیری آن کمک کنید.</p>
+
+MDN's [A re-introduction to
+JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+<p dir='rtl'>مشابه مطالبی که اینجا مطرح شده با جزییات بیشتر. در اینجا به شکل عمدی جاوااسکریپت فقط از دیدگاه زبان برنامه نویسی مورد بررسی قرار گرفته</p>
+<p dir='rtl'>در حالی که در این منبع میتوانید بیشتر از کاربرد آن در صفحات وب آشنایی پیدا کنید.</p>
+[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/)
+<p dir='rtl'>راهنمای دقیقی از قسمت های غیر ملموس زبان.</p>
+
+<p dir='rtl'>اضافه بر این در ویرایش این مقاله، قسمت هایی از سایت زیر مورد استفاده قرار گرفته است.</p>
+Louie Dinh's Python tutorial on this site, and the [JS
+Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+on the Mozilla Developer Network.
diff --git a/fr-fr/clojure-fr.html.markdown b/fr-fr/clojure-fr.html.markdown
new file mode 100644
index 00000000..d3c5a67b
--- /dev/null
+++ b/fr-fr/clojure-fr.html.markdown
@@ -0,0 +1,398 @@
+---
+language: clojure
+filename: learnclojure-fr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Bastien Guerry", "https://github.com/bzg"]
+lang: fr-fr
+---
+
+Clojure est un langage de la famille des Lisp développé pour la machine
+virtuelle Java. Ce langage insiste beaucoup plus sur la [programmation
+fonctionnelle](https://fr.wikipedia.org/wiki/Programmation_fonctionnelle) pure
+que Common Lisp, mais comprend plusieurs outils de gestion de la mémoire
+transactionnelle
+[STM](https://en.wikipedia.org/wiki/Software_transactional_memory) pour gérer
+les changements d'états si besoin.
+
+Cette combinaison permet de gérer le parallélisme très simplement, et
+souvent de façon automatique.
+
+(Vous avez besoin de Clojure 1.2 ou plus récent pour ce tutoriel.)
+
+```clojure
+; Les commentaires commencent avec un point-virgule.
+
+; Clojure est composé de « formes », qui sont simplement des listes
+; d'expressions entre parenthèses, séparées par une ou des espaces.
+;
+; L'interpréteur Clojure suppose que le premier élément est une fonction
+; ou une macro, et que le reste contient des arguments.
+
+; Le premier appel dans un fichier doit être ns, pour définir
+; l'espace de nom
+(ns learnclojure)
+
+; D'autres d'exemples basiques:
+
+; str va créer une chaîne de caractères à partir de tous ses arguments
+(str "Hello" " " "World") ; => "Hello World"
+
+; Les opérations mathématiques sont simples
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; L'égalité est =
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; Vous avez aussi besoin de not pour la négation logique
+(not true) ; => false
+
+; Les formes imbriquées fonctionnent comme on s'y attend
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Types
+;;;;;;;;;;;;;
+
+; Clojure utilise les types d'objets Java pour les booléens, les chaînes de
+; caractères et les nombres.
+; Utilisez `class` pour inspecter les types.
+(class 1) ; Les nombres entiers littéraux sont java.lang.Long par défaut
+(class 1.); Les flottants littéraux sont java.lang.Double
+(class ""); Les chaînes sont toujours entourées de guillemets doubles, et sont java.lang.String
+(class false) ; Les booléens sont java.lang.Boolean
+(class nil); La valeur "null" est appelée nil
+
+; Si vous voulez créer une liste littérale de données, utilisez ' pour en
+; empêcher son évaluation
+'(+ 1 2) ; => (+ 1 2)
+; (qui est un raccourci pour (quote (+ 1 2)))
+
+; Vous pouvez évaluer une liste "quotée":
+(eval '(+ 1 2)) ; => 3
+
+; Collections & séquences
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Les listes sont des structures de données en listes chaînées, alors que les
+; vecteurs reposent sur des tableaux.
+; Les vecteurs et les listes sont des classes Java aussi !
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; Une liste serait écrite comme (1 2 3), mais nous devons la quoter
+; pour empêcher l'interpréteur de penser que c'est une fonction.
+; Et (list 1 2 3) est la même chose que '(1 2 3)
+
+; Les "Collections" sont juste des groupes de données
+; Les listes et les vecteurs sont tous deux des collections:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; Les "séquences" (seqs) sont des abstractions à partir de listes de données.
+; Seules les listes sont elles-mêmes des séquences.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Une séquence n'a besoin de fournir une entrée que lorsqu'on y accède.
+; Donc, les séquences peuvent être "lazy" -- et définir une série infinie:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (une série infinie)
+(take 4 (range)) ; (0 1 2 3)
+
+; Utilisez cons pour ajouter un item au début d'une liste ou d'un vecteur
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; Conj ajoutera un item à une collection de la manière la plus efficace
+; Pour les listes, conj ajoute l'item au début; pour les vecteurs, à la fin.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; Utilisez concat pour ajouter des listes ou vecteurs:
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; Utilisez filter, map pour interagir avec des collections
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Utilisez reduce pour les réduire
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; Reduce peut aussi prendre un argument pour la valeur initiale
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Fonctions
+;;;;;;;;;;;;;;;;;;;;;
+
+; Utilisez fn pour créer de nouvelles fonctions.
+; Une fonction renvoie toujours sa dernière expression.
+(fn [] "Hello World") ; => fn
+
+; (Vous devez ajouter des parenthèses pour l'appeler)
+((fn [] "Hello World")) ; => "Hello World"
+
+; Vous pouvez créer une variable en utilisant def
+(def x 1)
+x ; => 1
+
+; Assignez une fonction à une variable
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; Vous pouvez raccourcir le procédé en utilisant defn
+(defn hello-world [] "Hello World")
+
+; [] contient la liste des arguments de la fonction
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; Vous pouvez aussi utiliser ce raccourci pour créer des fonctions
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; Vous pouvez avoir des fonctions multi-variadiques
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; Les fonctions peuvent inclure des arguments supplémentaires dans une séquence
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "Vous avez passé 3 args: (1 2 3)"
+
+; Vous pouvez combiner les arguments normaux et supplémentaires
+(defn hello-count [name & args]
+ (str "Hello " name ", vous avez passé " (count args) " args supplémentaires"))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, vous avez passé 3 args supplémentaires"
+
+
+; Maps
+;;;;;;;;;;;;;;;
+
+; Les hashmaps et les arraymaps partagent une interface. Les hashmaps
+; sont interrogés plus rapidement mais ne retiennent pas l'ordre des clefs.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Les array maps deviennent automatiquement des hashmaps pour la
+; plupart des opérations si elles deviennent assez larges, donc vous
+; n'avez pas à vous en faire.
+
+; Tous les types "hashables" sont acceptés comme clefs, mais en
+; général on utilise des mots-clefs ("keywords")
+; Les mots-clefs sont comme les chaînes de caractères mais en plus efficaces
+(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}
+
+; Au passage, les virgules sont toujours traitées comme des espaces et
+; ne font rien.
+
+; Sélectionnez une valeur dans une map en l'appelant comme fonction
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; Les mots-clefs peuvent aussi être utilisés pour sélectionner leur
+; valeur dans une map !
+(:b keymap) ; => 2
+
+; N'essayez pas ça avec les chaînes de caractères
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Sélectionner une clef absente renvoie nil
+(stringmap "d") ; => nil
+
+; Use assoc to add new keys to hash-maps
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Mais souvenez-vous, les types en Clojure sont immuables !
+keymap ; => {:a 1, :b 2, :c 3}
+
+; Utilisez dissoc pour retirer des clefs
+(dissoc keymap :a :b) ; => {:c 3}
+
+; Ensembles
+;;;;;;;;;;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; Ajoutez un élément avec conj
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; Retirez-en un avec disj
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Testez la présence en utilisant l'ensemble comme une fonction
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets.
+
+; Formes utiles
+;;;;;;;;;;;;;;;
+
+; Les constructions logiques en Clojure sont juste des macros, et
+ressemblent à toutes les autres formes:
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; Utilisez let pour créer des assignations temporaires
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; Groupez les énoncés ensemble avec do
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; Les fonctions ont un do implicit
+(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")
+
+; De même pour let
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+; Modules
+;;;;;;;;;;;;;;;
+
+; Utilisez "use" pour obtenir toutes les fonctions d'un module
+(use 'clojure.set)
+
+; Maintenant nous pouvons utiliser les opération de set
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Vous pouvez aussi choisir un sous-ensemble de fonctions à importer
+(use '[clojure.set :only [intersection]])
+
+; Utilisez require pour importer un module
+(require 'clojure.string)
+
+; Utilisez / pour appeler les fonctions d'un module
+; Ici, le module est clojure.string et la fonction est blank?
+(clojure.string/blank? "") ; => true
+
+; Vous pouvez associer un nom plus court au module au moment de l'importer
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#"" dénote une expression régulière)
+
+; Vous pouvez utiliser require (et use, mais ne le faites pas) en
+; appelant :require depuis un espace de noms.
+; Dans ce cas-là, vous n'avez pas besoin de "quoter" vos modules:
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java a une librairie standard énorme, donc vous voudrez apprendre à
+; vous familiariser avec.
+
+; Utilisez import pour charger un module java
+(import java.util.Date)
+
+; Vous pouvez importer depuis un ns aussi.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Utilisez les noms de classes avec "." à la fin pour créer une instance
+(Date.) ; <un objet date>
+
+; Utilisez . pour invoquer des méthodes. Ou utilisez le raccourci ".method"
+(. (Date.) getTime) ; <un timestamp>
+(.getTime (Date.)) ; exactement la même chose
+
+; Utilisez / pour appeler des méthodes statiques
+(System/currentTimeMillis) ; <un timestamp> (system est toujours présent)
+
+; Utilisez doto to rendre plus tolérable l'interaction avec des
+; classes (mutables)
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0)
+ .getTime) ; => Une classe Date. définie comme 2000-01-01 00:00:00
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; La mémoire logiciel transactionnelle ("Software Transactional Memory")
+; est le mécanisme que Clojure utilise pour gérer les états persistents.
+; Il y a plusieurs formes en Clojure qui utilisent cela.
+
+; L'atome est la plus simple. Passez-lui une valeur initiale
+(def my-atom (atom {}))
+
+; Mettez à jour un atome avec swap!.
+; swap! prend une fonction en argument et l'appelle avec la valeur
+; actuelle de l'atome comme premier argument, et les autres arguments
+; comme second argument.
+(swap! my-atom assoc :a 1) ; Définit my-atom comme le résultat de (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Définit my-atom comme le résultat de (assoc {:a 1} :b 2)
+
+; Use '@' to dereference the atom and get the value
+my-atom ;=> Atom<#...> (Renvoie l'objet Atom)
+@my-atom ; => {:a 1 :b 2}
+
+; Voici un simple compteur utilisant un atome
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; Les autres formes STM sont les refs et les agents.
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+```
+
+### Lectures complémentaires
+
+C'est loin d'être exhaustif, mais assez pour vous permettre de continuer.
+
+Clojure.org propose de nombreux articles:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org a de la documentation avec des exemples pour la
+plupart des fonctions principales :
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure est une super manière d'augmenter vos compétences en Clojure et
+en programmation fonctionnelle :
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org a pas mal d'article pour débuter :
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/fr-fr/coffeescript-fr.html.markdown b/fr-fr/coffeescript-fr.html.markdown
new file mode 100644
index 00000000..c66b7be0
--- /dev/null
+++ b/fr-fr/coffeescript-fr.html.markdown
@@ -0,0 +1,58 @@
+---
+language: coffeescript
+contributors:
+ - ["Tenor Biel", "http://github.com/L8D"]
+translators:
+ - ["Geoffrey Roguelon", "https://github.com/GRoguelon"]
+lang: fr-fr
+filename: coffeescript-fr.coffee
+---
+
+``` coffeescript
+# CoffeeScript est un langage préprocesseur, il permet de générer du Javascript.
+# Il suit les tendances de certains langages récents.
+# Par exemple, les commentaires se définissent comme en Ruby ou en Python.
+
+###
+Ceci est un bloc de commentaires
+il est converti directement avec '/ *' et '* /'
+pour correspondre aux commentaires Javascript
+
+Vous devez comprendre la syntaxe du langage JavaScript pour continuer.
+###
+
+# Affectation :
+number = 42 #=> var number = 42;
+opposite = true #=> var opposite = true;
+
+# Structures de contrôle :
+number = -42 if opposite #=> if(opposite) { number = -42; }
+
+# Fonctions :
+square = (x) -> x * x #=> var square = function(x) { return x * x; }
+
+# Intervals :
+list = [1..5] #=> var list = [1, 2, 3, 4, 5];
+
+# Objets :
+math =
+ root: Math.sqrt
+ square: square
+ cube: (x) -> x * square x
+#=> var math = {
+# "root": Math.sqrt,
+# "square": square,
+# "cube": function(x) { return x * square(x); }
+#}
+
+# Liste d'arguments variables :
+race = (winner, runners...) ->
+ print winner, runners
+
+# Existance :
+alert "I knew it!" if elvis?
+#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
+
+# Lecture d'un tableau :
+cubes = (math.cube num for num in list) #=> ...
+```
diff --git a/fr-fr/csharp-fr.html.markdown b/fr-fr/csharp-fr.html.markdown
new file mode 100644
index 00000000..c1641716
--- /dev/null
+++ b/fr-fr/csharp-fr.html.markdown
@@ -0,0 +1,812 @@
+---
+language: c#
+contributors:
+ - ["Irfan Charania", "https://github.com/irfancharania"]
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Melvyn Laïly", "http://x2a.yt"]
+ - ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
+translators:
+ - ["Olivier Hoarau", "https://github.com/Olwaro"]
+filename: LearnCSharp.cs
+lang: fr-fr
+---
+
+C# est un langage de programmation orienté objet à typage fort qui permet aux développeurs de créer une grande variété d'applications fiables et robustes s'appuyant sur le framework .NET.
+
+[Plus d'infos](http://msdn.microsoft.com/fr-fr/library/67ef8sbd.aspx)
+
+```c#
+// Les commentaires sur une seule ligne commencent par //
+/*
+Les
+commentaires
+multi-lignes
+ressemblent
+ceci
+*/
+/// <summary>
+/// Ceci est un commentaire de documentation XML
+/// </summary>
+
+// Importez des namespaces avec l'instruction 'using'
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Net;
+using System.Threading.Tasks;
+
+// Définit la portée du code pour une meilleure organisation
+namespace Learning
+{
+ // Chaque fichier .cs devrait au moins contenir une classe avec le même nom
+ // que celui du fichier. Ce n'est pas une obligation mais c'est mieux !
+ public class LearnCSharp
+ {
+ // LES BASES - si vous avez déjà de l'expérience en Java ou C++
+ // passez directement à la partie FONCTIONNALITÉS INTERÉSSANTES
+ public static void Syntax()
+ {
+ // Utilisez Console.WriteLine pour écrire sur la sortie
+ Console.WriteLine("Hello World");
+ Console.WriteLine(
+ "Entier: " + 10 +
+ " Double: " + 3.14 +
+ " Booleen: " + true);
+
+ // Pour omettre le retour à la ligne : Console.Write
+ Console.Write("Hello ");
+ Console.Write("World");
+
+ ///////////////////////////////////////////////////
+ // Types et Variables
+ // Déclarez une variable avec la syntaxe <type> <nom>
+ ///////////////////////////////////////////////////
+
+ // Sbyte - Entier signé sur 8 bits
+ // (-128 <= sbyte <= 127)
+ sbyte fooSbyte = 100;
+
+ // Byte - Entier non-signé sur 8 bits
+ // (0 <= byte <= 255)
+ byte fooByte = 100;
+
+ // Short - Entier sur 16 bits
+ // Signé - (-32,768 <= short <= 32,767)
+ // Non-signé - (0 <= ushort <= 65,535)
+ short fooShort = 10000;
+ ushort fooUshort = 10000;
+
+ // Int - Entier sur 32 bits
+ int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
+ uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
+
+ // Long - Entier sur 64 bits
+ long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
+ // Par défaut le type d'un littéral entier est int ou uint
+ // on ajoute 'L' pour spécifier la création d'un long
+
+ // Double - Réel sur 64 bits en virgule flottante (norme IEEE 754)
+ double fooDouble = 123.4; // Precision : 15-16 chiffres
+
+ // Float - Réel sur 32 bits en virgule flottante (norme IEEE 754)
+ float fooFloat = 234.5f; // Precision : 7 chiffres
+ // Par défaut le type d'un littéral réel est double
+ // on ajoute 'f' pour spécifier la création d'un float
+
+ // Decimal - Type de donnée numérique sur 128 bits, fournit une plus
+ // grande précision et une plage de valeurs réduite.
+ // Approprié aux calculs financiers et monétaires
+ decimal fooDecimal = 150.3m;
+
+ // Booléen - vrai / faux
+ bool fooBoolean = true; // ou false
+
+ // Char - Un unique caractère Unicode sur 16 bits
+ char fooChar = 'A';
+
+ // String -- contrairement aux types précédents qui sont des types valeurs,
+ // string est un type référence. Il peut donc avoir la valeur null
+ string fooString = "\"échappement\" de guillemets et ajout de \n (nouvelle ligne) et de \t (tabulation)";
+ Console.WriteLine(fooString);
+
+ // Il est possible d'accéder à chaque caractère d'une chaîne de caractères via son index
+ char charFromString = fooString[1]; // 'é'
+ // une chaîne de caractères est immuable : impossible de faire fooString[1] = 'X';
+
+ // Comparaison de chaînes de caractères avec la culture courrante en ignorant la casse
+ string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
+
+ // Formatage
+ string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
+
+ // Dates et formatage
+ DateTime fooDate = DateTime.Now;
+ Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+
+ // Il est possible d'étaler une chaîne de caractères sur plusieurs lignes avec le symbole @.
+ // Pour échapper " utilisez ""
+ string bazString = @"Voici quelques trucs
+sur une nouvelle ligne! ""Wow!"", quel style";
+
+ // Utilisez const ou read-only pour rendre une variable immuable.
+ // Les valeurs constantes sont calculées au moment de la compilation
+ const int HOURS_I_WORK_PER_WEEK = 9001;
+
+ ///////////////////////////////////////////////////
+ // Structures de données
+ ///////////////////////////////////////////////////
+
+ // Tableaux - indexé à partir de zéro
+ // La taille d'un tableau doit être décidée à la déclaration
+ // La syntaxe pour déclarer un tableau est la suivante :
+ // <type>[] <nom> = new <type>[<taille>]
+ int[] intArray = new int[10];
+
+ // Une autre méthode de déclaration et d'initialisation
+ int[] y = { 9000, 1000, 1337 };
+
+ // Indexer un tableau - Accéder à un élément
+ Console.WriteLine("intArray à 0: " + intArray[0]);
+ // Les tableaux sont muables.
+ intArray[1] = 1;
+
+ // Listes
+ // Elles sont plus souvent utilisées que les tableaux car plus souples
+ // La syntaxe pour déclarer une liste est la suivante :
+ // List<type> <nom> = new List<type>();
+ List<int> intList = new List<int>();
+ List<string> stringList = new List<string>();
+ List<int> z = new List<int> { 9000, 1000, 1337 }; // intialisation
+ // Les <> indiquent un type générique
+ // Pus d'info dans la partie FONCTIONNALITÉS INTERÉSSANTES
+
+ // Les éléments d'une liste ne sont pas null par défaut
+ // Il faut ajouter une valeur avant d'y accéder par index
+ intList.Add(1);
+ Console.WriteLine("intList à 0: " + intList[0]);
+
+ // Autres structures de données à étudier :
+ // Stack/Queue (Pile/File)
+ // Dictionary (une implémentation de hash map)
+ // HashSet (représente un ensemble)
+ // Collections en lecture seule
+ // Tuple (.Net 4+)
+
+ ///////////////////////////////////////
+ // Opérateurs
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Opérateurs");
+
+ int i1 = 1, i2 = 2; // Raccourci pour des déclarations multiples
+
+ // Arithmétique classique
+ Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
+
+ // Modulo
+ Console.WriteLine("11%3 = " + (11 % 3)); // => 2
+
+ // Opérateurs de comparaison
+ Console.WriteLine("3 == 2? " + (3 == 2)); // => False
+ Console.WriteLine("3 != 2? " + (3 != 2)); // => True
+ Console.WriteLine("3 > 2? " + (3 > 2)); // => True
+ Console.WriteLine("3 < 2? " + (3 < 2)); // => False
+ Console.WriteLine("2 <= 2? " + (2 <= 2)); // => True
+ Console.WriteLine("2 >= 2? " + (2 >= 2)); // => True
+
+ // Opérateurs bit à bit !
+ /*
+ ~ Compément unaire
+ << Décalage à gauche
+ >> Décalage à droite
+ & ET logique
+ ^ OU exclusif
+ | OU inclusif
+ */
+
+ // Incrémentations
+ int i = 0;
+ Console.WriteLine("\n->Inc/Dec-rementation");
+ Console.WriteLine(i++); //i = 1. Post-Incrémentation
+ Console.WriteLine(++i); //i = 2. Pre-Incrémentation
+ Console.WriteLine(i--); //i = 1. Post-Decrémentation
+ Console.WriteLine(--i); //i = 0. Pre-Decrémentation
+
+ ///////////////////////////////////////
+ // Structures de contrôle
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Structures de contrôle");
+
+ // Structure conditionnelle
+ int j = 10;
+ if (j == 10)
+ {
+ Console.WriteLine("Je serai affiché");
+ }
+ else if (j > 10)
+ {
+ Console.WriteLine("Pas moi");
+ }
+ else
+ {
+ Console.WriteLine("Moi non plus");
+ }
+
+ // Opérateur ternaire
+ // Un simple if/else peut s'écrire :
+ // <condition> ? <valeur si true> : <valeur si false>
+ string isTrue = (true) ? "True" : "False";
+
+ // Boucle while
+ int fooWhile = 0;
+ while (fooWhile < 100)
+ {
+ // 100 passages, de 0 à 99
+ fooWhile++;
+ }
+
+ // Boucle Do While
+ int fooDoWhile = 0;
+ do
+ {
+ // 100 passages, de 0 à 99
+ fooDoWhile++;
+ } while (fooDoWhile < 100);
+
+ // Boucle for
+ // Structure : for(<etat_initial>; <condition>; <pas>)
+ for (int fooFor = 0; fooFor < 10; fooFor++)
+ {
+ // 10 passages, de 0 à 9
+ }
+
+ // La boucle foreach
+ // Structure : foreach(<type_iterateur> <nom_iterateur> in <enumerable>)
+ // Cette boucle est utilisable sur des objets implémentant IEnumerable ou IEnumerable<T>
+ // Toutes les collections du framework .NET (Tableaux, Listes, ...) implémentent ces interfaces.
+ // (Notez que dans l'exemple suivant .ToCharArray() peut être omit car
+ // string implémente IEnumerable)
+ foreach (char character in "Hello World".ToCharArray())
+ {
+ //Itération sur chaque caractère
+ }
+
+ // La structure Switch Case
+ // Un switch fonctionne avec les types : byte, short, char et int.
+ // Les enums sont aussi supportés ainsi que les chaînes de caractères et quelques
+ // classes spéciales basées sur les types primitifs : Character, Byte, Short et Integer.
+ int mois = 3;
+ string moisString;
+ switch (mois)
+ {
+ case 1:
+ moisString = "Janvier";
+ break;
+ case 2:
+ moisString = "Février";
+ break;
+ case 3:
+ moisString = "Mars";
+ break;
+
+ // Vous pouvez assigner plus d'un 'case' à une action
+ // Mais vous ne pouvez pas ajouter une action sans 'break' avant un 'case'
+ // (pour ce faire, il faudrait ajouter explicitement un 'goto case x')
+ case 6:
+ case 7:
+ case 8:
+ moisString = "C'est l'été!";
+ break;
+ default:
+ moisString = "Un autre mois oO";
+ break;
+ }
+
+ ///////////////////////////////////////
+ // conversion de type de donnée et transtypage
+ ///////////////////////////////////////
+
+ // conversion de string vers int
+ // lève une exception en cas d'erreur
+ int.Parse("123"); //retourne la valeur entière de "123"
+
+ // TryParse affecte la valeur par défaut du type en cas d'erreur
+ // dans ce cas : 0
+ int tryInt;
+ if (int.TryParse("123", out tryInt)) // La fonction retourne un booléen
+ Console.WriteLine(tryInt); // => 123
+
+ // conversion d'un entier vers une chaîne de caractères
+ // La classe Convert possède plusieurs méthodes pour faciliter la conversion
+ Convert.ToString(123);
+ // ou
+ tryInt.ToString();
+ }
+
+ ///////////////////////////////////////
+ // CLASSES - voir les définitions à la fin du fichier
+ ///////////////////////////////////////
+
+ public static void Classes()
+ {
+ // voir les déclarations à la fin du fichier
+
+ // Utilisez 'new' pour instancier une classe
+ Bicycle trek = new Bicycle();
+
+ // Appel des méthodes de l'objet
+ trek.SpeedUp(3); // Il est toujours bon d'utiliser des accesseurs
+ trek.Cadence = 100;
+
+ // Affichage de la valeur de retour d'une méthode.
+ Console.WriteLine("trek info: " + trek.Info());
+
+ // Instanciation d'un nouveau PennyFarthing
+ PennyFarthing funbike = new PennyFarthing(1, 10);
+ Console.WriteLine("funbike info: " + funbike.Info());
+
+ Console.Read();
+ }
+
+ // POINT D'ENTRÉE - Une application console doit avoir une méthode main comme point d'entrée
+ public static void Main(string[] args)
+ {
+ OtherInterestingFeatures();
+ }
+
+ //
+ // FONCTIONNALITÉS INTÉRÉSSANTES
+ //
+
+ // SIGNATURE DE METHODE
+ public // Visibilité
+ static // Permet un appel direct par la classe (sans instanciation)
+ int // Type de retour,
+ MethodSignatures(
+ int maxCount, // Premier paramètre, de type int
+ int count = 0, // Valeur par défaut si aucun argument n'est passé
+ int another = 3,
+ params string[] otherParams // Capture tous les arguments passés à la méthode
+ )
+ {
+ return -1;
+ }
+
+ // Des méthodes peuvent avoir le même nom tant que leur signature est unique
+ public static void MethodSignature(string maxCount)
+ {
+ }
+
+ // TYPE GÉNÉRIQUE
+
+ // Les types TKey et TValue sont spécifiés par l'utilisateur lors de l'appel de la fonction
+ // Cette méthode émule SetDefaut de Python
+ public static TValue SetDefault<TKey, TValue>(
+ IDictionary<TKey, TValue> dictionary,
+ TKey key,
+ TValue defaultItem)
+ {
+ TValue result;
+ if (!dictionary.TryGetValue(key, out result))
+ return dictionary[key] = defaultItem;
+ return result;
+ }
+
+ // Vous pouvez limiter les types autorisés
+ public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
+ {
+ // Nous sommes sûrs de pouvoir itérer, car T implémente IEnumerable<int>
+ foreach (var item in toPrint)
+ // Item sera de type int
+ Console.WriteLine(item.ToString());
+ }
+
+ public static void OtherInterestingFeatures()
+ {
+ // PARAMÈTERES OPTIONNELS
+ MethodSignatures(3, 1, 3, "Des", "Paramètres", "En plus");
+ MethodSignatures(3, another: 3); // affectation explicite, les autres
+ // paramètres ont la valeur par défaut
+
+ // MÉTHODE D'EXTENSION
+ int i = 3;
+ i.Print(); // Définit plus bas
+
+ // TYPES NULLABLE - idéal pour les interactions avec une base de données ou pour les valeurs de retour
+ // Tous les types valeurs peuvent être rendus nullable en les suffixant par '?'
+ // <type>? <nom> = <value>
+ int? nullable = null; // raccourci pour Nullable<int>
+ Console.WriteLine("Nullable variable: " + nullable);
+ bool hasValue = nullable.HasValue; // retourne vrai si la valeur n'est pas null
+
+ // ?? est un sucre syntaxique pour spécifier une valeur par défaut
+ // au cas ou une autre valeur serait nulle
+ int notNullable = nullable ?? 0; // 0
+
+ // VARIABLES IMPLICITEMENT TYPÉES - vous pouvez laisser le compilateur deviner le type d'une variable
+ var magic = "magic est de type string à la compilation. On a toujours un typage fort !";
+ // magic = 9; // ne fonctionnera pas car magic est désormais une chaîne de caractères
+
+ // TYPES GÉNÉRIQUES
+ var agenda = new Dictionary<string, string>() {
+ {"Sarah", "212 555 5555"} // Ajout d'une entrée à notre agenda
+ };
+
+ // Appel de la fonction SetDefault (définie plus haut)
+ Console.WriteLine(SetDefault<string,string>(agenda, "Shaun", "Pas de numéro")); // => Pas de numéro
+ // Notez que vous n'avez pas à spécifier TKey et TValue car le compilateur saura les inférer.
+ Console.WriteLine(SetDefault(agenda, "Sarah", "No Phone")); // => 212 555 5555
+
+ // EXPRESSION LAMBDA - permet d'écrire une fonction en tant qu'expression
+ Func<int, int> square = (x) => x * x; // La dernière expression est la valeur de retour
+ Console.WriteLine(square(3)); // => 9
+
+ // GESTION AUTOMATIQUE DES RESSOURCES - vous permet de manipuler facilement des resources non-managées
+ // La plus part des objets qui accèdent à des ressources non-managées (handle de fichier, périphérique, etc.)
+ // implémentent l'interface IDisposable. L'instruction using prend soin
+ // de libérer les objets IDisposable proprement à votre place.
+ using (StreamWriter writer = new StreamWriter("log.txt"))
+ {
+ writer.WriteLine("Rien à signaler");
+ // À la fin de cette portée les ressources seront libérées.
+ // Même si une exception est levée.
+ }
+
+ // BIBLIOTHÈQUE DE TÂCHES PARALLÈLES (TPL)
+ // http://msdn.microsoft.com/fr-fr/library/dd460717.aspx
+ var websites = new string[] {
+ "http://www.google.com", "http://www.reddit.com",
+ "http://www.shaunmccarthy.com"
+ };
+ var responses = new Dictionary<string, string>();
+
+ // L'exemple suivant exécutera chaque requête dans un thread séparé,
+ // et attendra la fin de chacun d'entre eux avant de continuer
+ Parallel.ForEach(websites,
+ new ParallelOptions() {MaxDegreeOfParallelism = 3}, // maximum de 3 threads
+ website =>
+ {
+ // Fait quelque chose de long
+ using (var r = WebRequest.Create(new Uri(website)).GetResponse())
+ {
+ responses[website] = r.ContentType;
+ }
+ });
+
+ // Ceci ne s'exécutera pas tant que les threads n'auront pas fini leur travail
+ foreach (var key in responses.Keys)
+ Console.WriteLine("{0}:{1}", key, responses[key]);
+
+ // TYPE DYNAMIQUE - idéal pour travailler avec d'autres langages
+ dynamic student = new ExpandoObject();
+ student.FirstName = "Mon prénom"; // Pas besoin de définir l'objet
+
+ // Vous pouvez même ajouter des méthodes (dans cet exemple : la méthode prend une chaîne de caractères et retourne une chaîne de caractères)
+ student.Introduce = new Func<string, string>(
+ (introduceTo) => string.Format("Hey {0}, c'est {1}", student.FirstName, introduceTo));
+ Console.WriteLine(student.Introduce("Beth"));
+
+ // IQUERYABLE<T> - quasiment toutes les collections implémentent cette interface
+ // ce qui permet d'utiliser des méthodes de style 'Filter' / 'Map' / 'Reduce'
+ var bikes = new List<Bicycle>();
+ bikes.Sort(); // Trie le tableau sur place
+ bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Trie en se basant sur la propriété Wheels
+ var result = bikes
+ .Where(b => b.Wheels > 3) // 'Filter' - enchaînable (retourne un IQueryable du type précédent)
+ .Where(b => b.IsBroken && b.HasTassles)
+ .Select(b => b.ToString()); // 'Map' - on retourne le .ToString() de chaque élément filtré,
+ // le résultat est un IQueryable<string>
+
+ var sum = bikes.Sum(b => b.Wheels); // 'Reduce' - fait la somme de tous les Wheels de la liste
+
+ // Creation d'une liste d'objet anonymes basés sur des paramètres de la classe Bike
+ var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
+ // Le compilateur peut inférer le type de ces objets anonymes, permettant à certains IDE d'effectuer
+ // des autos-complétion.
+ foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
+ Console.WriteLine(bikeSummary.Name);
+
+
+ // ASPARALLEL
+ // C'est ici que les choses se compliquent - un mélange de LINQ et de TPL
+ var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
+ // La ligne précédente s'exécute en parallèle ! Des threads seront gérés automatiquement
+ // et les données y seront réparties. Idéal sur de grosses données (et si votre
+ // machine dispose de plusieurs coeurs)
+
+
+ // LINQ - lie une source de données à des objets IQueryable<T>
+ // ex : LindToSql => liaison avec une base de données, LinqToXml => liaison avec un document xml
+ var db = new BikeRespository();
+
+ // l'exécution est décalée, ce qui est préférable quand on travaille sur une base données
+ var filter = db.Bikes.Where(b => b.HasTassles); // pas de requête exécutée
+ if (42 > 6) // Vous pouvez continuer à affiner la recherche
+ filter = filter.Where(b => b.IsBroken); // pas de requête exécutée
+
+ var query = filter
+ .OrderBy(b => b.Wheels)
+ .ThenBy(b => b.Name)
+ .Select(b => b.Name); // toujours pas de requête exécutée
+
+ // Maintenant la requête est exécutée, mais retourne des données uniquement au fil de l'itération
+ foreach (string bike in query)
+ Console.WriteLine(result);
+
+ }
+
+ } // Fin de la classe LearnCSharp
+
+ // Il est possible d'inclure plusieurs classes dans un fichier .cs
+
+ public static class Extensions
+ {
+ // EXTENSION DE FONCTIONS
+ public static void Print(this object obj)
+ {
+ Console.WriteLine(obj.ToString());
+ }
+ }
+
+ // Syntaxe de déclaration de classe :
+ // <public/private/protected/internal> class <class name>{
+ // // champs, constructeurs, fonctions
+ // // tout est déclaré et implémenté à l'intérieur
+ // }
+
+ public class Bicycle
+ {
+ // Propriétés et variable de la classe
+ public int Cadence // Public : peut être accédé de partout
+ {
+ get // get - définit une méthode pour lire la propriété
+ {
+ return _cadence;
+ }
+ set // set - définit une méthode pour affecter une valeur à la propriété
+ {
+ _cadence = value; // 'value' est la valeur passée en argument au setteur
+ }
+ }
+ private int _cadence;
+
+ protected virtual int Gear // Protected : accessible depuis la classe et ses classes filles
+ {
+ get; // crée une propriété automatique, pas besoin de créer une variable de stockage
+ set;
+ }
+
+ internal int Wheels // Internal : accessible depuis l'assembly
+ {
+ get;
+ private set; // Il est possible de choisir la portée d'un accesseur
+ }
+
+ int _speed; // Par défaut tout est privé au sein d'une classe : accessible uniquement depuis la classe
+ // on peut ajouter explicitement le mot clé 'private'
+
+ public string Name { get; set; }
+
+
+ // Enum est un type valeur formé par un ensemble de constantes nommées
+ // C'est simplement une manière de mettre un nom sur une valeur (int par défaut).
+ // Les types compatibles pour un enum sont : byte, sbyte, short, ushort, int, uint, long et ulong.
+ // Un enum ne peut pas contenir deux fois la même valeur
+ public enum BikeBrand
+ {
+ AIST,
+ BMC,
+ Electra = 42, // il est possible de donner explicitement une valeur
+ Gitane // 43
+ }
+ // Nous avons défini cet enum à l'intérieur de la classe Bicycle, c'est donc un type imbriqué
+ // Pour le référencer à l'extérieur, il faudra utiliser Bicycle.BikeBrand
+
+ public BikeBrand Brand; // Après avoir déclaré notre type enum, on peut créer un champ de ce type
+
+ // Les membres statiques appartiennent à une classe plutôt qu'à une instance particulière
+ // Il est possible d'y accéder sans passer par un objet :
+ // ex : Console.WriteLine("Bicycles créés : " + Bicycle.bicyclesCreated);
+ static public int BicyclesCreated = 0;
+
+ // Les valeurs en lecture seule sont affectées lors de l'exécution
+ // Elles ne peuvent être assignées que lors de leur déclaration ou dans un constructeur
+ readonly bool _hasCardsInSpokes = false; // variable en lecture et privée
+
+ // Les constructeurs sont un moyen de créer des objets
+ // Voici un constructeur par défaut (pas d'arguments)
+ public Bicycle()
+ {
+ this.Gear = 1; // accès aux membres de la classe via le mot clé this
+ Cadence = 50; // qui est souvent implicite
+ _speed = 5;
+ Name = "Bontrager";
+ Brand = BikeBrand.AIST;
+ BicyclesCreated++;
+ }
+
+ // Voici un constructeur spécifique (qui prend des arguments)
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ string name, bool hasCardsInSpokes, BikeBrand brand)
+ : base() // possibilité d'appeler le constructeur de la classe mère (ici Object)
+ {
+ Gear = startGear;
+ Cadence = startCadence;
+ _speed = startSpeed;
+ Name = name;
+ _hasCardsInSpokes = hasCardsInSpokes;
+ Brand = brand;
+ }
+
+ // Les constructeurs peuvent s'enchaîner
+ public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
+ this(startCadence, startSpeed, 0, "big wheels", true, brand)
+ {
+ }
+
+ // Syntaxe de méthode :
+ // <public/private/protected> <type de retour> <nom de methode>(<args>)
+
+ // Les classes peuvent implémenter des accesseurs pour leurs champs
+ // ou implémenter des propriétés (c'est la méthode dominante en C#)
+
+ // Les paramètres de méthodes peuvent avoir des valeurs par défaut
+ // Dans ce cas, la méthode peut être appelée sans arguments
+ public void SpeedUp(int increment = 1)
+ {
+ _speed += increment;
+ }
+
+ public void SlowDown(int decrement = 1)
+ {
+ _speed -= decrement;
+ }
+
+ // Les propriétés se chargent de lire/modifier des valeurs
+ // elles peuvent être en lecture(get), en écriture(set) ou les deux
+ private bool _hasTassles; // variable privée
+ public bool HasTassles // propriété publique
+ {
+ get { return _hasTassles; }
+ set { _hasTassles = value; }
+ }
+
+ // Il est possible de définir une propriété automatique sur une ligne
+ // cette syntaxe créera une variable de stockage automatiquement.
+ // Il est possible de modifier l'accèsibilité des getter/setter pour limiter leur utilisation
+ public bool IsBroken { get; private set; }
+
+ // La même chose sur plusieurs lignes
+ public int FrameSize
+ {
+ get;
+ // Notez que seule la classe Bicycle peut changer la valeur de FrameSize
+ private set;
+ }
+
+ // Méthode qui affiche la valeur des champs de cet objet
+ public virtual string Info()
+ {
+ return "Gear: " + Gear +
+ " Cadence: " + Cadence +
+ " Speed: " + _speed +
+ " Name: " + Name +
+ " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
+ "\n------------------------------\n"
+ ;
+ }
+
+ // Les méthodes peuvent aussi être statiques. Utile pour les méthodes d'aide.
+ public static bool DidWeCreateEnoughBycles()
+ {
+ // À l'intérieur d'une méthode statique on ne peut que référencer des membres statiques !
+ return BicyclesCreated > 9000;
+ } // Si votre classe n'a que des membres statiques, marquez la comme statique
+
+ } // fin de la classe Bicycle
+
+ // PennyFarthing est une classe dérivée de Bicycle
+ class PennyFarthing : Bicycle
+ {
+ // Appel au constructeur de la classe mère
+ public PennyFarthing(int startCadence, int startSpeed) :
+ base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
+ {
+ }
+
+ protected override int Gear
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ // Lève une exception
+ throw new ArgumentException("Impossible de modifier Gear sur un PennyFarthing");
+ }
+ }
+
+ public override string Info()
+ {
+ string result = "PennyFarthing bicycle ";
+ result += base.ToString(); // Appel à la version de base de cette méthode
+ return result;
+ }
+ }
+
+ // Les interfaces contiennent uniquement la signature de leurs membres, sans implémentation.
+ interface IJumpable
+ {
+ void Jump(int meters); // Tous les membres d'interface sont publics par défaut
+ }
+
+ interface IBreakable
+ {
+ bool Broken { get; } // Les interfaces peuvent contenir des propriétés,
+ // des méthodes et des évènements
+ }
+
+ // Une classe ne peut hériter que d'une seule autre classe, mais peut implémenter plusieurs interfaces
+ class MountainBike : Bicycle, IJumpable, IBreakable
+ {
+ int damage = 0;
+
+ public void Jump(int meters)
+ {
+ damage += meters;
+ }
+
+ public bool Broken
+ {
+ get
+ {
+ return damage > 100;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Utilisé pour illustrer la connexion à une base donnée dans l'exemple LinqToSql
+ /// L'approche code first d'EntityFramework est très pratique (un peu comme ActiveRecord de Ruby)
+ /// http://msdn.microsoft.com/fr-fr/data/jj193542.aspx
+ /// </summary>
+ public class BikeRespository : DbSet
+ {
+ public BikeRespository()
+ : base()
+ {
+ }
+
+ public DbSet<Bicycle> Bikes { get; set; }
+ }
+} // Fin du namespace
+```
+
+## Sujets non-abordés
+
+ * Flags
+ * Attribus
+ * Propriétés statiques
+ * Exceptions, Abstraction
+ * ASP.NET (Web Forms/MVC/WebMatrix)
+ * Winforms
+ * Windows Presentation Foundation (WPF)
+
+## Lectures Complémentaires
+
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
+ * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
+ * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
+ * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
+ * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+
+[Convention de codage C#](http://msdn.microsoft.com/library/vstudio/ff926074)
diff --git a/fr-fr/haskell.html.markdown b/fr-fr/haskell.html.markdown
new file mode 100644
index 00000000..989db1d5
--- /dev/null
+++ b/fr-fr/haskell.html.markdown
@@ -0,0 +1,431 @@
+---
+language: haskell
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
+translators:
+ - ["David Baumgartner", "http://davidbaumgartner.ch"]
+lang: fr-fr
+filename: learnhaskell-fr.hs
+---
+
+Haskell a été conçu pour être un langage fonctionnel pur et maniable. Il est connu pour ses monades et son système de types, mais je n'ai cesse d'y revenir pour son élégance. Pour moi, Haskell fait de la programmation une joie.
+
+```haskell
+-- Un commentaire en une ligne commence avec deux tirets.
+{- Un commentaire sur plusieurs lignes peut être contenu dans
+un bloc de cette façon.
+-}
+
+----------------------------------------------------
+-- 1. Types de données primitifs et opérateurs
+----------------------------------------------------
+
+-- Vous avez les nombres
+3 -- 3
+
+-- Les maths sont comme vous vous y attendez
+1 + 1 -- 2
+8 - 1 -- 7
+10 * 2 -- 20
+35 / 5 -- 7.0
+
+-- La division n'est pas entière par défaut
+35 / 4 -- 8.75
+
+-- division entière
+35 `div` 4 -- 8
+
+-- Les booléens sont primitifs
+True
+False
+
+-- Opérations avec les booléens
+not True -- False
+not False -- True
+1 == 1 -- True
+1 /= 1 -- False
+1 < 10 -- True
+
+-- Dans les exemples plus hauts, `not` est une fonction qui prend une valeur.
+-- Haskell n'a pas besoin de parenthèses pour appeler une fonction... tous
+-- les arguments sont juste listés après la fonction. Le schéma général est
+-- donc :
+-- func arg1 arg2 arg3...
+-- Voyez la section sur les fonctions pour savoir comment écrire les vôtres.
+
+-- Caractères et chaînes de caractère
+"Ceci est une chaîne de caractère."
+'a' -- caractère
+'Vous ne pouvez pas utiliser des apostrophes pour les chaînes de caractère.' -- erreur !
+
+-- Les chaînes peuvent être concaténées
+"Hello " ++ "world!" -- "Hello world!"
+
+-- Une chaîne de caractère est *réellement* une liste
+"Ceci est une chaîne." !! 0 -- 'C'
+
+
+----------------------------------------------------
+-- Listes et tuples
+----------------------------------------------------
+
+-- Tous les éléments d'une liste doit avoir le même type.
+-- les deux lignes suivantes sont semblables
+[1, 2, 3, 4, 5]
+[1..5]
+
+-- Il y a aussi des listes infinies en Haskell !
+[1..] -- une liste de tous les nombres naturels
+
+-- Les listes infinies fonctionnent parce que Haskell est « paresseux »:
+-- ça veut dire qu'il n'évalue que ce qui a besoin de l'être. Vous pouvez
+-- donc vous demander le 1000e élément de votre liste et il vous le donnera :
+
+[1..] !! 999 -- 1000
+
+-- Et là, Haskell a évalué les éléments 1 à 1000 de la liste... mais le reste
+-- de cette liste « infinie » n'existe pas encore ! En fait, Haskell ne va jamais
+-- le faire à moins qu'il ne le doive.
+
+-- Adjoindre deux listes
+[1..5] ++ [6..10]
+
+-- ajouter au début de la liste
+0:[1..5] -- [0, 1, 2, 3, 4, 5]
+
+-- l'indice d'une liste
+[0..] !! 5 -- 5
+
+-- d'autres opérations sur les listes
+head [1..5] -- 1
+tail [1..5] -- [2, 3, 4, 5]
+init [1..5] -- [1, 2, 3, 4]
+last [1..5] -- 5
+
+--liste en compréhension
+[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
+
+--avec un conditionnel
+[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
+
+-- Chaque élément d'un tuple peut être d'un type différent, mais un
+-- tuple a une longueur fixée.
+-- Un tuple :
+("haskell", 1)
+
+-- accéder aux éléments d'un tuple
+fst ("haskell", 1) -- "haskell"
+snd ("haskell", 1) -- 1
+
+----------------------------------------------------
+-- 3. Functions
+----------------------------------------------------
+-- Une simple fonction qui prend deux paramètres
+add a b = a + b
+
+-- Notez que si vous utilisez ghci (l'interpréteur Haskell)
+-- vous devrez utiliser `let`. Par exemple :
+-- let add a b = a + b
+
+-- Utiliser une fonction
+add 1 2 -- 3
+
+-- Vous pouvez également mettre le nom de la fonction entre les
+-- deux arguments avec des accents graves :
+1 `add` 2 -- 3
+
+-- Vous pouvez également définir des fonctions qui n'ont pas de
+-- lettres ! Ça vous laisse créer vos propres opérateurs ! Voilà
+-- un opérateur qui fait une division entière :
+(//) a b = a `div` b
+35 // 4 -- 8
+
+-- Gardes : Une façon de gérer la valeur de vos arguments en amont
+fib x
+ | x < 2 = x
+ | otherwise = fib (x - 1) + fib (x - 2)
+
+-- Le filtrage par motif est similaire. Là, on a donné trois
+-- définitions différentes de `fib`. Haskell appellera automatiquement
+-- la première fonction qui correspond au motif de la valeur.
+fib 1 = 1
+fib 2 = 2
+fib x = fib (x - 1) + fib (x - 2)
+
+-- Filtrage par motif sur un tuple.
+foo (x, y) = (x + 1, y + 2)
+
+-- Filtrage par motif sur des listes. Ici, `x` est le premier
+-- élément de la liste, et `xs` le reste. On peut écrire notre
+-- propre fonction `map` :
+myMap func [] = []
+myMap func (x:xs) = func x:(myMap func xs)
+
+-- Les fonctions anonymes sont créées avec des barres obliques
+-- inverses, suivies de tous les arguments.
+myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
+
+-- Une utilisation de fold (appelée `inject` dans quelques autres
+-- langages) avec comme paramètre une fonction anonyme.
+-- `foldl1` veut dire fold left -- soit littéralement pli gauche --
+-- et utilise la première valeur de la liste comme accumulateur.
+foldl1 (\acc x -> acc + x) [1..5] -- 15
+
+----------------------------------------------------
+-- 4. Plus de fonctions
+----------------------------------------------------
+
+-- curryfication : si vous n'appliquez pas tous les arguments à une
+-- fonction, elle devient « curryfiée ». Ça veut dire qu'elle retourne
+-- une fonction qui prend le reste des arguments.
+
+add a b = a + b
+foo = add 10 -- foo est une fonction qui prend un nombre et y ajoute 10
+foo 5 -- 15
+
+-- Une autre façon de l'écrire
+foo = (+10)
+foo 5 -- 15
+
+-- Composition de fonctions
+-- la fonction (.) enchaîne deux fonctions.
+-- Par exemple, on a foo qui est une fonction qui prend une valeur, y ajoute
+-- 10 et multiplie ce résultat par 5, et ensuite retourne la valeur finale.
+foo = (*5) . (+10)
+
+-- (5 + 10) * 5 = 75
+foo 5 -- 75
+
+-- fixation de priorité
+-- Haskell a une autre fonction appelée `$`. Elle peut changer la priorité
+-- de sorte que tout ce qu'il y a à sa gauche est calculé d'abord et ensuite
+-- appliqué à tout ce qu'il y a à droite. Vous pouvez utiliser `.` et `$`
+-- pour vous débarrasser de beaucoup de parenthèses :
+
+-- avant
+(even (fib 7)) -- False
+
+-- ensuite
+even . fib $ 7 -- False
+
+----------------------------------------------------
+-- 5. Signature de type
+----------------------------------------------------
+
+-- Haskell a un système de types très strict : par exemple, tout a un type.
+
+-- Quelques types simples :
+5 :: Integer
+"hello" :: String
+True :: Bool
+
+-- Les fonctions ont également des types.
+-- `not` prend un booléen et retourne un booléen.
+-- not :: Bool -> Bool
+
+-- Voilà une fonction qui prend deux paramètres.
+-- add :: Integer -> Integer -> Integer
+
+-- Quand vous définissez une valeur (souvenez-vous, tout est valeur en
+-- Haskell), une bonne pratique est d'écrire son type explicitement
+double :: Integer -> Integer
+double x = x * 2
+
+----------------------------------------------------
+-- 6. Flux de contrôle et structures conditionnelles
+----------------------------------------------------
+
+-- structure conditionnelle if
+haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
+
+-- les structures if peuvent être écrites sur plusieurs lignes
+haskell = if 1 == 1
+ then "awesome"
+ else "awful"
+
+-- les structures case : voilà comment vous pourriez analyser les arguments de
+-- ligne de commande
+case args of
+ "help" -> printHelp
+ "start" -> startProgram
+ _ -> putStrLn "bad args"
+
+
+-- Haskell n'a pas de boucles parce qu'il utilise la récursion.
+-- `map` applique une fonction sur chaque élément d'une liste
+
+map (*2) [1..5] -- [2, 4, 6, 8, 10]
+
+-- vous pouvez créer une fonction `for` en utilisant `map`
+for array func = map func array
+
+-- et l'utiliser
+for [0..5] $ \i -> show i
+
+-- nous aurions pu l'écrire également ainsi
+for [0..5] show
+
+-- vous pouvez utiliser foldl et foldr pour
+-- réduire une liste
+-- foldl <fonction> <valeur initiale> <liste>
+foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
+
+-- C'est donc la même chose que
+(2 * (2 * (2 * 4 + 1) + 2) + 3)
+
+-- foldl évalue de gauche à droite, foldr
+-- de droite à gauche
+foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
+
+-- Et c'est équivalent à
+(2 * 3 + (2 * 2 + (2 * 1 + 4)))
+
+----------------------------------------------------
+-- 7. Types de données
+----------------------------------------------------
+
+-- Vous pouvez écrire vos propres types de données en Haskell
+
+data Couleur = Rouge | Bleu | Vert
+
+-- Et maintenant l'utiliser dans une fonction
+
+
+say :: Couleur -> String
+say Rouge = "Vous êtes Rouge !"
+say Bleu = "Vous êtes Bleu !"
+say Vert = "Vous êtes Vert !"
+
+-- Vos types peuvent également avoir des paramètres
+
+data Maybe a = Nothing | Just a
+
+-- Tous les exemples ci-dessous sont issus du type Maybe
+Just "hello" -- of type `Maybe String`
+Just 1 -- of type `Maybe Int`
+Nothing -- of type `Maybe a` for any `a`
+
+----------------------------------------------------
+-- 8. Haskell IO
+----------------------------------------------------
+
+-- Tandis que l'IO ne peut pas être totalement expliqué pleinement
+-- sans que les monades ne le soient, il n'est pas difficile
+-- d'expliquer suffisamment pour commencer.
+
+-- Quand un programme en Haskell est exécuté, la fonction `main`
+-- est appelée. Il doit retourner une valeur de type `IO ()`.
+-- Par exemple :
+
+main :: IO ()
+main = putStrLn $ "Bonjour, le ciel ! " ++ (say Blue)
+-- putStrLn a comme type String -> IO ()
+
+-- La façon la plus simple pour faire de l'IO est de faire un programme
+-- fonction de String vers String. La fonction
+-- interact :: (String -> String) -> IO ()
+-- prend un texte, applique une fonction et affiche le résultat.
+
+countLines :: String -> String
+countLines = show . length . lines
+
+main' = interact countLines
+
+-- Vous pouvez considérer qu'une valeur de type `IO ()` représente
+-- une séquence d'actions que l'ordinateur exécute, un peu comme
+-- dans un langage impératif. On peut utiliser la structure `do`
+-- pour enchaîner des actions. Par exemple :
+
+sayHello :: IO ()
+sayHello = do
+ putStrLn "Quel est ton nom ?"
+ name <- getLine -- prend une ligne et assigne sa valeur à `name`
+ putStrLn $ "Salut, " ++ name
+
+-- Exercice : écrire votre propre version d'`interact` qui ne fait
+-- que de lire une ligne d'entrée.
+
+-- Le code de `sayHello` ne sera jamais exécuté, cependant. La seule
+-- action qui sera exécutée est la valeur de `main`.
+-- Pour lancer `sayHello`, commentez l'ancienne définition de `main`
+-- et remplacez-le par :
+-- main = sayHello
+
+-- Essaions de mieux comprendre comment la fonction `getLine` que
+-- nous venons d'utiliser. Son type est :
+-- getLine :: IO String
+-- vous pouvez considérer le type `IO a` comme un programme que
+-- le programme va générer comme une valeur de type `a` quand
+-- il sera exécuté. On peut l'enregistrer et la réutiliser en
+-- utilisant `<-`. On peut aussi faire nos propres actions
+-- de type `IO String` :
+
+action :: IO String
+action = do
+ putStrLn "C'est une ligne. Heu"
+ input1 <- getLine
+ input2 <- getLine
+ -- Le type de la structure `do` est celui de sa dernière ligne.
+ -- `return` n'est pas un mot clef, mais simplement une fonction.
+ return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
+
+-- On peut maintenant l'utiliser comme on a utilisé `getLine`
+-- tout à l'heure
+
+main'' = do
+ putStrLn "Je vais afficher deux lignes !"
+ result <- action
+ putStrLn result
+ putStrLn "C'était tout !"
+
+-- Le type `IO` est un exemple de « monade ». La façon dont Haskell utilise
+-- une monade pour faire de l'IO lui permet d'être purement fonctionnel. N'importe
+-- quelle fonction qui interagit avec le « monde extérieur » (c'est à dire fait de l'IO)
+-- devient marqué comme `IO` dans la signature de son type. Ça nous montre
+-- quelles fonctions sont « pures » (n'interagissent pas avec le monde extérieur
+-- ou ne changent pas d'état) et quelles fonctions ne le sont pas.
+
+-- C'est une fonctionnalité très puissante, car il est facile d'exécuter
+-- des fonctions pures simultanément, et donc la concurrence en Haskell
+-- est très facile.
+
+
+----------------------------------------------------
+-- 9. Le REPL de Haskell
+----------------------------------------------------
+
+-- Lancer le REPL en tapant `ghci`.
+-- Vous pouvez maintenant taper du code Haskell.
+-- Toutes les nouvelles valeurs peuvent être crées
+-- avec `let` :
+
+let foo = 5
+
+-- Vous pouvez voir le type de n'importe quelle valeur avec `:t` :
+
+>:t foo
+foo :: Integer
+
+-- Vous pouvez également lancer des actions de type `IO ()`
+
+> sayHello
+Quel est ton nom ?
+Ami
+Salut, Ami !
+
+```
+
+Et Haskell ne se limite pas à ça, on trouve encore par exemple les classes de types et les monades. Il y a beaucoup de raisons qui font que coder en Haskell est si *fun*. Je vous laisse avec un dernier exemple : une implémentation de quicksort :
+
+```haskell
+qsort [] = []
+qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
+ where lesser = filter (< p) xs
+ greater = filter (>= p) xs
+```
+
+Haskell facile à installer. Téléchargez-le [ici](http://www.haskell.org/platform/).
+
+Vous pouvez trouver une approche beaucoup plus douce avec les excellents
+[Learn you a Haskell](http://lyah.haskell.fr/) ou
+[Real World Haskell (en)](http://book.realworldhaskell.org/).
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..b98d161e
--- /dev/null
+++ b/fr-fr/objective-c-fr.html.markdown
@@ -0,0 +1,528 @@
+---
+
+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-fr.m
+lang: fr-fr
+
+---
+
+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.
+
+```cpp
+// 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)
diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
new file mode 100644
index 00000000..58a036ba
--- /dev/null
+++ b/fr-fr/python-fr.html.markdown
@@ -0,0 +1,489 @@
+---
+language: python
+filename: learnpython-fr.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Sylvain Zyssman", "https://github.com/sylzys"]
+ - ["Nami-Doc", "https://github.com/Nami-Doc"]
+lang: fr-fr
+---
+
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
+Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+
+Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+
+NB: Cet artice s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x
+Vous pourrez bientôt trouver un article pour Python 3!
+
+```python
+# Une ligne simple de commentaire commence par un dièse
+""" Les lignes de commenatires multipes peuvent être écrites
+ en utilisant 3 guillemets ("), et sont souvent utilisées
+ pour les commentaires
+"""
+
+####################################################
+## 1. Types Primaires et Opérateurs
+####################################################
+
+# Les nombres
+3 #=> 3
+
+# Les calculs produisent les résultats mathématiques escomptés
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
+5 / 2 #=> 2
+
+# Pour corriger ce problème, on utilise les float.
+2.0 # Voici un float
+11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
+
+# Forcer la priorité avec les parenthèses
+(1 + 3) * 2 #=> 8
+
+# Les valeurs booléenes sont de type primitif
+True
+False
+
+# Pour la négation, on utilise "not"
+not True #=> False
+not False #=> True
+
+# Pour l'égalité, ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# L'inégalité est symbolisée par !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# D'autres comparateurs
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# On peut enchaîner les comparateurs !
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Les chaînes de caractères sont créées avec " ou '
+"C'est une chaîne."
+'C\'est aussi une chaîne.'
+
+# On peut aussi les "additioner" !
+"Hello " + "world!" #=> "Hello world!"
+
+# Une chaîne peut être traitée comme une liste de caractères
+"C'est une chaîne"[0] #=> 'C'
+
+# % peut être utilisé pour formatter des chaîne, comme ceci:
+"%s can be %s" % ("strings", "interpolated")
+
+# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
+# C'est la méthode à privilégier
+"{0} peut être {1}".format("La chaîne", "formattée")
+# On peut utiliser des mot-clés au lieu des chiffres.
+"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
+
+# None est un objet
+None #=> None
+
+# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
+# Il faut utiliser "is"
+"etc" is None #=> False
+None is None #=> True
+
+# L'opérateur 'is' teste l'identité de l'objet.
+# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
+# lorsque l'on utilise des objets.
+
+# None, 0, et les chaînes de caractères vides valent False.
+# Toutes les autres valeurs valent True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variables et Collections
+####################################################
+
+# Afficher du texte, c'est facile
+print "Je suis Python. Enchanté!"
+
+
+# Il n'y a pas besoin de déclarer les variables avant de les assigner.
+some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
+some_var #=> 5
+
+# Accéder à une variable non assignée lève une exception
+# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
+some_other_var # Lève une exception
+
+# 'if' peut être utilisé comme expression
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listes
+li = []
+# On peut remplir liste dès l'instanciation
+other_li = [4, 5, 6]
+
+# On ajoute des éléments avec 'append'
+li.append(1) #li contient [1]
+li.append(2) #li contient [1, 2]
+li.append(4) #li contient [1, 2, 4]
+li.append(3) #li contient [1, 2, 4, 3]
+
+# Et on les supprime avec 'pop'
+li.pop() #=> 3 et li contient [1, 2, 4]
+# Remettons-le dans la liste
+li.append(3) # li contient [1, 2, 4, 3] de nouveau.
+
+# On accède aux éléments d'une liste comme à ceux un tableau.
+li[0] #=> 1
+# Le dernier élément
+li[-1] #=> 3
+
+# Accèder aux indices hors limite lève une exception
+li[4] # Lève un 'IndexError'
+
+# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
+# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
+li[1:3] #=> [2, 4]
+# Sans spécifier de fin de rang, on "saute" le début de la liste
+li[2:] #=> [4, 3]
+# Sans spécifier de début de rang, on "saute" la fin de la liste
+li[:3] #=> [1, 2, 4]
+
+# Retirer un élément spécifique dee la liste avec "del"
+del li[2] # li contient [1, 2, 3]
+
+# On peut additionner des listes entre elles
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+
+# Concaténer des listes avec "extend()"
+li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+
+# Vérifier l'existence d'un élément dans une liste avec "in"
+1 in li #=> True
+
+# Récupérer la longueur avec "len()"
+len(li) #=> 6
+
+
+# Les "tuples" sont comme des listes, mais sont immuables.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Lève un 'TypeError'
+
+# Mais vous pouvez faire tout ceci sur les tuples:
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
+# Sans parenthèses, un tuple est créé par défaut
+d, e, f = 4, 5, 6
+# Voyez maintenant comme il est facile d'inverser 2 valeurs
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionnaires
+empty_dict = {}
+# Un dictionnaire pré-rempli
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Trouver des valeurs avec []
+filled_dict["one"] #=> 1
+
+# Récupérer toutes les clés sous forme de liste avec "keys()"
+filled_dict.keys() #=> ["three", "two", "one"]
+# Note - l'ordre des clés du dictionnaire n'est pas garanti.
+# Vos résultats peuvent différer de ceux ci-dessus.
+
+# Récupérer toutes les valeurs sous forme de liste avec "values()"
+filled_dict.values() #=> [3, 2, 1]
+# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+
+# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Chercher une clé non existante lève une 'KeyError'
+filled_dict["four"] # KeyError
+
+# Utiliser la méthode "get()" pour éviter 'KeyError'
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# La méthode get() prend un argument par défaut quand la valeur est inexistante
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
+filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+
+
+# Les sets stockent ... des sets
+empty_set = set()
+# On initialise un "set()" avec tout un tas de valeurs
+some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+
+# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Ajouter plus d'éléments au set
+filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+
+# Intersection de sets avec &
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Union de sets avec |
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Différence de sets avec -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Vérifier l'existence d'une valeur dans un set avec "in"
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Structure de contrôle
+####################################################
+
+# Initialisons une variable
+some_var = 5
+
+# Voici une condition 'if'. L'indentation est significative en Python !
+# Affiche "some_var est inférieur à 10"
+if some_var > 10:
+ print "some_var est supérieur à 10."
+elif some_var < 10: # La clause elif est optionnelle
+ print "some_var iinférieur à 10."
+else: # La clause else également
+ print "some_var vaut 10."
+
+
+"""
+Les boucles "for" permettent d'itérer sur les listes
+Affiche:
+ chien : mammifère
+ chat : mammifère
+ souris : mammifère
+"""
+for animal in ["chien", "chat", "souris"]:
+ # On peut utiliser % pour l'interpolation des chaînes formattées
+ print "%s : mammifère" % animal
+
+"""
+"range(number)" retourne une liste de nombres
+de 0 au nombre donné
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Raccourci pour x = x + 1
+
+# Gérer les exceptions avec un bloc try/except
+
+# Fonctionne pour Python 2.6 et ultérieur:
+try:
+ # Utiliser "raise" pour lever une exception
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+
+
+####################################################
+## 4. Fonctions
+####################################################
+
+# Utiliser "def" pour créer une nouvelle fonction
+def add(x, y):
+ print "x vaut %s et y vaur %s" % (x, y)
+ return x + y # Renvoi de valeur avec 'return'
+
+# Appeller une fonction avec des paramètres
+add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+
+# Une autre manière d'appeller une fonction, avec les arguments
+add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+
+# On peut définir une foncion qui prend un nombre variable de paramètres
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# On peut également définir une fonction qui prend un nombre
+# variable d'arguments
+def keyword_args(**kwargs):
+ return kwargs
+
+# Appelons-là et voyons ce qu'il se passe
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# On peut faire les deux à la fois si on le souhaite
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) affiche:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
+# Utiliser * pour développer les paramètres, et ** pour développer les arguments
+params = (1, 2, 3, 4)
+args = {"a": 3, "b": 4}
+all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+
+# Python a des fonctions de première classe
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Mais également des fonctions anonymes
+(lambda x: x > 2)(3) #=> True
+
+# On trouve aussi des fonctions intégrées plus évoluées
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters"
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. Classes
+####################################################
+
+# Une classe est un objet
+class Human(object):
+
+ # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+ species = "H. sapiens"
+
+ # Initialiseur basique
+ def __init__(self, name):
+ # Assigne le paramètre à l'attribut de l'instance de classe.
+ self.name = name
+
+ # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Une méthode de classe est partagée par toutes les instances.
+ # On les appelle avec le nom de la classe en premier paramètre
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Une méthode statique est appellée sans référence à une classe ou à une instance
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instancier une classe
+i = Human(name="Ian")
+print i.say("hi") # Affiche "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") #Affiche "Joel: hello"
+
+# Appeller notre méthode de classe
+i.get_species() #=> "H. sapiens"
+
+# Changer les attributs partagés
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Appeller la méthode statique
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modules
+####################################################
+
+# On peut importer des modules
+import math
+print math.sqrt(16) #=> 4
+
+# Et récupérer des fonctions spécifiques d'un module
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Récuperer toutes les fonctions d'un module
+# Attention, ce n'est pas recommandé.
+from math import *
+
+# On peut raccourcir le nom d'un module
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Les modules Python sont juste des fichiers Python ordinaires.
+# On peut écrire ses propres modules et les importer.
+# Le nom du module doit être le même que le nom du fichier.
+
+# On peut trouver quelle fonction et attributs déterminent un module
+import math
+dir(math)
+
+
+```
+
+## Prêt à aller plus loin?
+
+### En ligne gratuitement
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Format papier
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/fr-fr/racket-fr.html.markdown b/fr-fr/racket-fr.html.markdown
new file mode 100644
index 00000000..8b2420f8
--- /dev/null
+++ b/fr-fr/racket-fr.html.markdown
@@ -0,0 +1,628 @@
+---
+language: racket
+filename: learnracket-fr.rkt
+contributors:
+ - ["th3rac25", "https://github.com/voila"]
+ - ["Eli Barzilay", "https://github.com/elibarzilay"]
+ - ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
+translators:
+ - ["Xavier Nayrac", "https://github.com/lkdjiin"]
+lang: fr-fr
+---
+
+Racket est un langage de programmation généraliste, multi-paradigme,
+descendant de Lisp/Scheme.
+
+Les retours et commentaires sont appréciés ! Vous pouvez joindre l'auteur
+original ici :
+[@th3rac25](http://twitter.com/th3rac25) ou là : th3rac25 [at] [google's email
+service]. Vous pouvez joindre le traducteur de ce document ici :
+[@lkdjiin](http://twitter.com/lkdjiin).
+
+```racket
+#lang racket ; défini le dialecte à utiliser.
+
+;;; Commentaires
+
+;; Une ligne de commentaire commence par un point-virgule.
+
+#| Un bloc de commentaires
+ peut tenir sur plusieurs lignes…
+ #|
+ et on peut les imbriquer !
+ |#
+|#
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. Types de données et opérateurs primitifs
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Nombres
+9999999999999999999999 ; entier
+#b111 ; binaire => 7
+#o111 ; octal => 73
+#x111 ; hexadécimal => 273
+3.14 ; réel
+6.02e+23
+1/2 ; rationnel
+1+2i ; complexe
+
+;; Un appel de fonction s'écrit (f x y z ...)
+;; où f est une fonction et x, y, z, ... sont des arguments.
+;; Si vous voulez créer une liste littérales, utilisez ' pour
+;; empécher l'évaluation de la liste.
+'(+ 1 2) ; => (+ 1 2)
+;; Et maintenant, un peu d'arithmétique
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(quotient 5 2) ; => 2
+(remainder 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(exact->inexact 1/3) ; => 0.3333333333333333
+(+ 1+2i 2-3i) ; => 3-1i
+
+;;; Booléens
+#t ; pour vrai
+#f ; pour faux -- Toute autre valeur que #f est vraie
+(not #t) ; => #f
+(and 0 #f (error "doesn't get here")) ; => #f
+(or #f 0 (error "doesn't get here")) ; => 0
+
+;;; Caractères
+#\A ; => #\A
+#\λ ; => #\λ
+#\u03BB ; => #\λ
+
+;;; Une chaîne de caractères est un tableau de caractères de longueur
+;;; fixe.
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; Le backslash est le caractère d'échappement
+"Foo\tbar\41\x21\u0021\a\r\n" ; Sont inclus les échappements de type C
+ ; et unicode
+"λx:(μα.α→α).xx" ; une chaîne peut inclure de l'unicode
+
+;; On peut ajouter une chaîne à une autre
+(string-append "Hello " "world!") ; => "Hello world!"
+
+;; Une chaîne peut être traitée comme une liste de caractères
+(string-ref "Apple" 0) ; => #\A
+
+;; format est utilisé pour formatter une chaîne
+(format "~a can be ~a" "strings" "formatted")
+
+;; L'affichage est tout simple
+(printf "I'm Racket. Nice to meet you!\n")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Variables
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Vous pouvez créer une variable à l'aide de define
+;; Une variable peut contenir n'importe quel caractères, à l'exception
+;; de : ()[]{}",'`;#|\
+(define some-var 5)
+some-var ; => 5
+
+;; Vous pouvez aussi utiliser des caractères unicode
+(define ⊆ subset?)
+(⊆ (set 3 2) (set 1 2 3)) ; => #t
+
+;; Accéder à une variable non-initialisée provoque une exception
+; x ; => x: indéfini ...
+
+;; Déclaration locale : `me` est attaché à "Bob" seulement à l'intérieur
+;; de (let ...)
+(let ([me "Bob"])
+ "Alice"
+ me) ; => "Bob"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Structures and Collections
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Structures
+(struct dog (name breed age))
+(define my-pet
+ (dog "lassie" "collie" 5))
+my-pet ; => #<dog>
+(dog? my-pet) ; => #t
+(dog-name my-pet) ; => "lassie"
+
+;;; Paires (non mutable)
+;; `cons` construit une paire, `car` et `cdr` extraient respectivement le
+;; premier et le second élément.
+(cons 1 2) ; => '(1 . 2)
+(car (cons 1 2)) ; => 1
+(cdr (cons 1 2)) ; => 2
+
+;;; Listes
+
+;; Les listes en Racket sont des structures de données de type *linked-list*,
+;; produites avec des paires assemblées avec `cons` et terminée par `null`
+;; (ou '()).
+(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
+;; `list` est un constructeur variadique plus commode à utiliser
+(list 1 2 3) ; => '(1 2 3)
+;; et un guillemet simple peut aussi être utilisé pour une liste littérale
+'(1 2 3) ; => '(1 2 3)
+
+;; On peut toujours utiliser `cons` pour ajouter un élément au début
+;; d'une liste
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; Utilisez `append` pour ajouter une liste à une autre
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; Une liste est un type très basique, il y a donc *beaucoup* de
+;; fonctionnalités qui leur sont dédiées, quelques exemples :
+(map add1 '(1 2 3)) ; => '(2 3 4)
+(map + '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(filter even? '(1 2 3 4)) ; => '(2 4)
+(count even? '(1 2 3 4)) ; => 2
+(take '(1 2 3 4) 2) ; => '(1 2)
+(drop '(1 2 3 4) 2) ; => '(3 4)
+
+;;; Vecteurs
+
+;; Un vecteur est un tableau de taille fixe
+#(1 2 3) ; => '#(1 2 3)
+
+;; Utilisez `vector-append` pour additionner des vecteurs entre eux
+(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; Sets
+
+;; Créez un set à partir d'une liste
+(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
+
+;; Ajoutez un membre avec `set-add`
+;; (Fonctionnel: renvoit le set étendu, plutôt que de muter le set en entrée)
+(set-add (set 1 2 3) 4) ; => (set 1 2 3 4)
+
+;; Retirez un membre avec `set-remove`
+(set-remove (set 1 2 3) 1) ; => (set 2 3)
+
+;; Testez l'existence d'un membre avec `set-member?`
+(set-member? (set 1 2 3) 1) ; => #t
+(set-member? (set 1 2 3) 4) ; => #f
+
+;;; Tables de hashage
+
+;; Créer une table de hashage non-mutable (un exemple mutable plus loin)
+(define m (hash 'a 1 'b 2 'c 3))
+
+;; Retrouver une valeur
+(hash-ref m 'a) ; => 1
+
+;; Chercher une valeur inexistante provoque une exceptions
+; (hash-ref m 'd) => no value found
+
+;; Vous pouvez fournir une valeur par défaut pour les clés manquantes
+(hash-ref m 'd 0) ; => 0
+
+;; Utilisez `hash-set` pour étendre une table de hashage non-mutable
+;; (Renvoit la table étendu, plutôt que de la muter)
+(define m2 (hash-set m 'd 4))
+m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
+
+;; Rappelez-vous, ces tables de hashage sont non-mutables !
+m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
+
+;; Utilisez `hash-remove` pour supprimer des clés (également fonctionnel)
+(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Fonctions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Utilisez `lambda` pour créer des fonctions.
+;; Une fonction renvoie toujours la valeur de sa dernière expression.
+(lambda () "Hello World") ; => #<procedure>
+;; On peut aussi utiliser le caractère unicode `λ'
+(λ () "Hello World") ; => même fonction
+
+;; Utilisez des parenthèses pour appeler toutes les fonctions, ce qui
+;; inclus aussi les expressions lambda
+((lambda () "Hello World")) ; => "Hello World"
+((λ () "Hello World")) ; => "Hello World"
+
+;; Assignez une fonction à une variable
+(define hello-world (lambda () "Hello World"))
+(hello-world) ; => "Hello World"
+
+;; Vous pouvez raccourcir ceci en utilisant le sucre syntaxique pour la
+;; définition de fonction :
+(define (hello-world2) "Hello World")
+
+;; Entre les () après lambda, vous déclarez la liste des arguments de la
+;; fonction
+(define hello
+ (lambda (name)
+ (string-append "Hello " name)))
+(hello "Steve") ; => "Hello Steve"
+;; … ou alors, en utilisant le sucre syntaxique, ce qui suit est équivalent
+(define (hello2 name)
+ (string-append "Hello " name))
+
+;; Vous pouvez obtenir des fonctions variadique en utilisant `case-lambda`
+(define hello3
+ (case-lambda
+ [() "Hello World"]
+ [(name) (string-append "Hello " name)]))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+;; … ou spécifier des arguments optionnels avec une valeur par défaut
+(define (hello4 [name "World"])
+ (string-append "Hello " name))
+
+;; Les fonctions peuvent rassembler des arguments supplémentaires dans une
+;; liste
+(define (count-args . args)
+ (format "You passed ~a args: ~a" (length args) args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+;; … ou bien avec `lambda`, sans sucre syntaxique
+(define count-args2
+ (lambda args
+ (format "You passed ~a args: ~a" (length args) args)))
+
+;; Vous pouvez mixer arguments réguliers et supplémentaires
+(define (hello-count name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args)))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+;; … sans sucre syntaxique
+(define hello-count2
+ (lambda (name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args))))
+
+;; Avec des mot-clés cette fois
+(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
+ (format "~a ~a, ~a extra args" g name (length args)))
+(hello-k) ; => "Hello World, 0 extra args"
+(hello-k 1 2 3) ; => "Hello World, 3 extra args"
+(hello-k #:greeting "Hi") ; => "Hi World, 0 extra args"
+(hello-k #:name "Finn" #:greeting "Hey") ; => "Hey Finn, 0 extra args"
+(hello-k 1 2 3 #:greeting "Hi" #:name "Finn" 4 5 6)
+ ; => "Hi Finn, 6 extra args"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Égalité
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Pour les nombres, utilisez `=`
+(= 3 3.0) ; => #t
+(= 2 1) ; => #f
+
+;; Pour tester l'identité des objets, utilisez `eq?`
+(eq? 3 3) ; => #t
+(eq? 3 3.0) ; => #f
+(eq? (list 3) (list 3)) ; => #f
+
+;; Pour les collections, utilisez `equal?`
+(equal? (list 'a 'b) (list 'a 'b)) ; => #t
+(equal? (list 'a 'b) (list 'b 'a)) ; => #f
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Structures de contrôle
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Conditions
+
+(if #t ; expression pour le test
+ "this is true" ; expression si vrai
+ "this is false") ; expression si faux
+; => "this is true"
+
+;; Dans les condition, toutes les valeurs non-fausses sont traitées commentaires
+;; étant vraies (c'est à dire toutes sauf #f)
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(Groucho Zeppo)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'yep
+
+;; `cond` permet d'enchaîner une série de tests afin d'obtenir un résultat
+(cond [(> 2 2) (error "wrong!")]
+ [(< 2 2) (error "wrong again!")]
+ [else 'ok]) ; => 'ok
+
+;;; Filtrage par motif (*pattern matching*)
+
+(define (fizzbuzz? n)
+ (match (list (remainder n 3) (remainder n 5))
+ [(list 0 0) 'fizzbuzz]
+ [(list 0 _) 'fizz]
+ [(list _ 0) 'buzz]
+ [_ #f]))
+
+(fizzbuzz? 15) ; => 'fizzbuzz
+(fizzbuzz? 37) ; => #f
+
+;;; Les boucles
+
+;; On peut boucler en utilisant la récursion (terminale)
+(define (loop i)
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i))))
+(loop 5) ; => i=5, i=6, ...
+
+;; D'une manière similaire, avec un `let` nommé
+(let loop ((i 0))
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i)))) ; => i=0, i=1, ...
+
+;; Voir plus loin pour l'ajout d'une nouvelle forme `loop`, mais Racket
+;; possède déjà une forme `for` flexible et élaborée pour les itérations
+(for ([i 10])
+ (printf "i=~a\n" i)) ; => i=0, i=1, ...
+(for ([i (in-range 5 10)])
+ (printf "i=~a\n" i)) ; => i=5, i=6, ...
+
+;;; Itérer sur autre chose que des nombres
+;; `for` permet d'itérer sur plein de type de séquences:
+;; listes, vecteurs, chaînes de caractères, sets, tables de hashage, etc
+
+(for ([i (in-list '(l i s t))])
+ (displayln i))
+
+(for ([i (in-vector #(v e c t o r))])
+ (displayln i))
+
+(for ([i (in-string "string")])
+ (displayln i))
+
+(for ([i (in-set (set 'x 'y 'z))])
+ (displayln i))
+
+(for ([(k v) (in-hash (hash 'a 1 'b 2 'c 3 ))])
+ (printf "key:~a value:~a\n" k v))
+
+;;; Itérations plus complexes
+
+;; Balayage parallèle de plusieurs séquences (on stoppe sur la plus petite)
+(for ([i 10] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x 1:y 2:z
+
+;; Boucles imbriquées
+(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z
+
+;; Conditions dans les boucles
+(for ([i 1000]
+ #:when (> i 5)
+ #:unless (odd? i)
+ #:break (> i 10))
+ (printf "i=~a\n" i))
+; => i=6, i=8, i=10
+
+;;; Compréhensions de liste
+;; Très similaires aux boucles `for` -- renvoient en plus une collection
+
+(for/list ([i '(1 2 3)])
+ (add1 i)) ; => '(2 3 4)
+
+(for/list ([i '(1 2 3)] #:when (even? i))
+ i) ; => '(2)
+
+(for/list ([i 10] [j '(x y z)])
+ (list i j)) ; => '((0 x) (1 y) (2 z))
+
+(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10))
+ i) ; => '(6 8 10)
+
+(for/hash ([i '(1 2 3)])
+ (values i (number->string i)))
+; => '#hash((1 . "1") (2 . "2") (3 . "3"))
+
+;; Il y a plein d'autres fonctions natives pour collecter des données à
+;; l'aide de boucles
+(for/sum ([i 10]) (* i i)) ; => 285
+(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000
+(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
+(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
+;; Et pour n'importe quell combinaison arbitraire, utilisez `for/fold`
+(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
+;; (Ceci peut souvent remplacer des boucles communes de style impératif)
+
+;;; Exceptions
+
+;; Pour capturer une exception, utilisez la forme `with-handlers`
+(with-handlers ([exn:fail? (lambda (exn) 999)])
+ (+ 1 "2")) ; => 999
+(with-handlers ([exn:break? (lambda (exn) "no time")])
+ (sleep 3)
+ "phew") ; => "phew", but if you break it => "no time"
+
+;; Utilisez `raise` pour soulever une exception, ou encore n'importe quelle
+;; autre valeur
+(with-handlers ([number? ; capturer la valeur numérique soulevée
+ identity]) ; la renvoyer en tant que valeur simple
+ (+ 1 (raise 2))) ; => 2
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Mutabilité
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Utilisez `set!` pour réassigner une valeur à une variable existante
+(define n 5)
+(set! n (add1 n))
+n ; => 6
+
+;; Utilisez le mécanisme des boites (*box*) pour les valeurs explicitement
+;; mutables (similaire aux pointeurs ou références dans d'autres langages)
+(define n* (box 5))
+(set-box! n* (add1 (unbox n*)))
+(unbox n*) ; => 6
+
+;; Beaucoup de types de données en Racket sont non-mutables (paires, listes,
+;; etc), certains ont à la fois une version mutable et une version
+;; non-mutable (chaînes, vecteurs, tables de hashage, etc)
+
+;; Utilisez `vector` ou `make-vector` pour créer des vecteurs mutables
+(define vec (vector 2 2 3 4))
+(define wall (make-vector 100 'bottle-of-beer))
+;; Utilisez `vector-set!` pour mettre à jour un emplacement
+(vector-set! vec 0 1)
+(vector-set! wall 99 'down)
+vec ; => #(1 2 3 4)
+
+;; Créer une table de hashage mutable vide et la manipuler
+(define m3 (make-hash))
+(hash-set! m3 'a 1)
+(hash-set! m3 'b 2)
+(hash-set! m3 'c 3)
+(hash-ref m3 'a) ; => 1
+(hash-ref m3 'd 0) ; => 0
+(hash-remove! m3 'a)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Modules
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Les modules permettent d'organiser le code en plusieurs fichiers
+;; et bibliothèques réutilisables. Ici, nous utiliserons des sous-modules,
+;; imbriqués dans le grand module que forme ce texte (qui démarre à la
+;; ligne `#lang`).
+
+(module cake racket/base ; défini un module `cake', basé sur racket/base
+
+ (provide print-cake) ; fonction exportée par le module (publique)
+
+ (define (print-cake n)
+ (show " ~a " n #\.)
+ (show " .-~a-. " n #\|)
+ (show " | ~a | " n #\space)
+ (show "---~a---" n #\-))
+
+ (define (show fmt n ch) ; fonction interne/privée
+ (printf fmt (make-string n ch))
+ (newline)))
+
+;; Utilisez `require` pour importer les fonctions fournies par un
+;; module (provide)
+(require 'cake) ; le ' est pour un sous-module local
+(print-cake 3)
+; (show "~a" 1 #\A) ; => erreur, `show` n'est pas exportée
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. Classes et objets
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Créer une classe fish% (% est idiomatique pour les noms de classes)
+(define fish%
+ (class object%
+ (init size) ; argument pour l'initialisation
+ (super-new) ; initialisation de la super-classe
+ ;; Les champs/membres/variables de classe
+ (define current-size size)
+ ;; Méthodes publiques
+ (define/public (get-size)
+ current-size)
+ (define/public (grow amt)
+ (set! current-size (+ amt current-size)))
+ (define/public (eat other-fish)
+ (grow (send other-fish get-size)))))
+
+;; Créer une instance de fish%
+(define charlie
+ (new fish% [size 10]))
+
+;; Utilisez `send` pour appeler une méthode d'un objet
+(send charlie get-size) ; => 10
+(send charlie grow 6)
+(send charlie get-size) ; => 16
+
+;; `fish%` est une simple valeur de «première classe», ce qui va permettre
+;; la composition (*mixins*)
+(define (add-color c%)
+ (class c%
+ (init color)
+ (super-new)
+ (define my-color color)
+ (define/public (get-color) my-color)))
+(define colored-fish% (add-color fish%))
+(define charlie2 (new colored-fish% [size 10] [color 'red]))
+(send charlie2 get-color)
+;; ou, sans les noms:
+(send (new (add-color fish%) [size 10] [color 'red]) get-color)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 9. Macros
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Les macros permettent d'étendre la syntaxe du langage
+
+;; Ajoutons une boucle `loop`
+(define-syntax-rule (while condition body ...)
+ (let loop ()
+ (when condition
+ body ...
+ (loop))))
+
+(let ([i 0])
+ (while (< i 10)
+ (displayln i)
+ (set! i (add1 i))))
+
+;; Les macros sont hygiéniques, vous ne pouvez pas *clasher* avec les
+;; variables existantes !
+(define-syntax-rule (swap! x y) ; ! est idiomatique pour la mutation
+ (let ([tmp x])
+ (set! x y)
+ (set! y tmp)))
+
+(define tmp 2)
+(define other 3)
+(swap! tmp other)
+(printf "tmp = ~a; other = ~a\n" tmp other)
+;; La variable `tmp` est renommée en `tmp_1`
+;; dans le but d'éviter un conflit de nom
+;; (let ([tmp_1 tmp])
+;; (set! tmp other)
+;; (set! other tmp_1))
+
+;; Mais il faut quand même faire bien attention avec les macros, par exemple:
+(define-syntax-rule (bad-while condition body ...)
+ (when condition
+ body ...
+ (bad-while condition body ...)))
+;; cette macro est cassée : ell génère un code infini, si vous l'essayez
+;; le compilateur va entrer dans une boucle infinie.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 10. Contrats
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Les contrats imposent des contraintes aux valeurs exportées depuis
+;; les modules
+
+(module bank-account racket
+ (provide (contract-out
+ [deposit (-> positive? any)] ; un dépot est toujours positif
+ [balance (-> positive?)]))
+
+ (define amount 0)
+ (define (deposit a) (set! amount (+ amount a)))
+ (define (balance) amount)
+ )
+
+(require 'bank-account)
+(deposit 5)
+
+(balance) ; => 5
+
+;; Les clients qui essaient de déposer un montant non-positif sont blamés
+;; (deposit -5) ; => deposit: contract violation
+;; expected: positive?
+;; given: -5
+;; more details....
+```
+
+## Pour aller plus loin
+
+Vous en voulez plus ? Essayez
+[Getting Started with Racket](http://docs.racket-lang.org/getting-started/)
diff --git a/fr-fr/ruby-fr.html.markdown b/fr-fr/ruby-fr.html.markdown
new file mode 100644
index 00000000..3060bd75
--- /dev/null
+++ b/fr-fr/ruby-fr.html.markdown
@@ -0,0 +1,411 @@
+---
+language: ruby
+filename: learnruby-fr.rb
+contributors:
+ - ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
+ - ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+translators:
+ - ["Geoffrey Roguelon", "https://github.com/GRoguelon"]
+ - ["Nami-Doc", "https://github.com/Nami-Doc"]
+lang: fr-fr
+---
+
+```ruby
+# Ceci est un commentaire
+
+=begin
+Ceci est un commentaire multiligne
+Personne ne les utilise
+Vous devriez en faire de même
+=end
+
+# Tout d'abord : Tout est un objet.
+
+# Les nombres sont des objets
+
+3.class #=> Fixnum
+
+3.to_s #=> "3"
+
+# Les opérateurs de base
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Les opérateurs sont juste des raccourcis
+# pour appeler une méthode sur un objet
+1.+(3) #=> 4
+10.* 5 #=> 50
+
+# Les valeurs spéciales sont des objets
+nil # Nul
+true # Vrai
+false # Faux
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Égalité
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Inégalité
+1 != 1 #=> false
+2 != 1 #=> true
+!true #=> false
+!false #=> true
+
+# à part false lui-même, nil est la seule autre valeur 'false'
+
+!nil #=> true
+!false #=> true
+!0 #=> false
+
+# Plus de comparaisons
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Les chaînes de caractères sont des objets
+
+'Je suis une chaîne de caractères'.class #=> String
+"Je suis également une chaîne de caractères".class #=> String
+
+placeholder = "utiliser l'interpolation de chaîne de caractères"
+"Je peux #{placeholder} quand j'utilise les guillemets"
+#=> "Je peux utiliser l'interpolation de chaîne de caractères quand j'utilise les guillemets"
+
+# Affichez un message
+puts "J'affiche à l'écran!"
+
+# Variables
+x = 25 #=> 25
+x #=> 25
+
+# Notez que l'affectation retourne la valeur affectée.
+# Cela signifie que vous pouvez affecter plusieurs fois de suite :
+
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# Par convention, utilisez la notation underscore
+# pour nommer les variables
+snake_case = true
+
+# Utilisez des noms de variable explicites
+path_to_project_root = '/nom/correct/'
+path = '/mauvais/nom/'
+
+# Symboles (aussi des objets)
+# Les symboles sont immuables, constants,
+# réutilisables et représentés en interne
+# par une valeur entière. Ils sont souvent
+# utilisés à la place des chaînes de caractères
+# pour transmettre efficacement des valeurs
+# spécifiques ou significatives
+
+:pending.class #=> Symbol
+
+status = :pending
+
+status == :pending #=> true
+
+status == 'pending' #=> false
+
+status == :approved #=> false
+
+# Tableaux
+
+# Ceci est un tableau
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# Les tableaux contiennent différents types d'élément.
+
+[1, "hello", false] #=> [1, "hello", false]
+
+# Les tableaux peuvent être indexés
+# Du début
+array[0] #=> 1
+array[12] #=> nil
+
+# Comme les opérateurs, la syntaxe [var] est juste un raccourci
+# pour appeler la méthode [] d'un objet
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# Depuis la fin
+array[-1] #=> 5
+
+# Avec un index de début et de fin
+array[2, 4] #=> [3, 4, 5]
+
+# Ou avec un intervalle
+array[1..3] #=> [2, 3, 4]
+
+# Ajoutez un élément au tableau comme ceci
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Les Hash sont des dictionnaires Ruby contenant des paires de clé/valeur.
+# Les Hash sont délimitées par des accolades :
+hash = {'color' => 'green', 'number' => 5}
+
+hash.keys #=> ['color', 'number']
+
+# Les Hash retournent la valeur
+# en utilisant la clé associée à la valeur :
+hash['color'] #=> 'green'
+hash['number'] #=> 5
+
+# Recherchez une clé inexistante dans une Hash retourne nil :
+hash['nothing here'] #=> nil
+
+# Depuis Ruby 1.9, Une syntaxe spécifique est apparue
+# en utilisant les symboles comme clés :
+
+new_hash = { defcon: 3, action: true}
+
+new_hash.keys #=> [:defcon, :action]
+
+# Astuce : Les tableaux et les Hash sont dénombrables
+# Ils partagent un certain nombre de méthodes pratiques
+# telle que each, map, count, etc...
+
+# Structures de contrôle
+
+if true
+ "si instruction"
+elsif false
+ "autrement si, facultatif"
+else
+ "autrement, également facultatif"
+end
+
+for compteur in 1..5
+ puts "itération #{compteur}"
+end
+#=> itération 1
+#=> itération 2
+#=> itération 3
+#=> itération 4
+#=> itération 5
+
+# CEPENDANT, l'usage de la boucle for est très rare.
+# À la place, utilisez la méthode "each"
+# et passez lui un bloc de code.
+# Un bloc de code est un ensemble d'instructions
+# que vous pouvez passer à une methode comme "each".
+# Les blocs sont similaires aux lambdas, aux fonctions anonymes
+# ou encore aux closures dans d'autres langages.
+#
+# La méthode "each" exécute le bloc de code
+# pour chaque élément de l'intervalle d'éléments.
+# Le bloc de code passe un paramètre compteur.
+# Appelez la méthode "each" avec un bloc de code comme ceci :
+
+(1..5).each do |compteur|
+ puts "itération #{compteur}"
+end
+#=> itération 1
+#=> itération 2
+#=> itération 3
+#=> itération 4
+#=> itération 5
+
+# Vous pouvez également mettre un bloc de code entre accolades :
+(1..5).each {|compteur| puts "itération #{compteur}"}
+
+# Le contenu des structures de données peut être parcouru
+# en utilisant la méthode each.
+array.each do |element|
+ puts "#{element} est une partie du tableau"
+end
+hash.each do |cle, valeur|
+ puts "#{cle} est #{valeur}"
+end
+
+compteur = 1
+while compteur <= 5 do
+ puts "itération #{compteur}"
+ compteur += 1
+end
+#=> itération 1
+#=> itération 2
+#=> itération 3
+#=> itération 4
+#=> itération 5
+
+grade = 'B'
+
+case grade
+when 'A'
+ puts "Excellent"
+when 'B'
+ puts "Plus de chance la prochaine fois"
+when 'C'
+ puts "Vous pouvez faire mieux"
+when 'D'
+ puts "C'est pas terrible"
+when 'F'
+ puts "Vous avez échoué!"
+else
+ puts "Sytème de notation alternatif"
+end
+
+# Fonctions
+
+def double(x)
+ x * 2
+end
+
+# Les fonctions (et tous les blocs de code) retournent
+# implicitement la valeur de la dernière instruction évaluée
+double(2) #=> 4
+
+# Les paranthèses sont facultative
+# lorsqu'il n'y a pas d'ambiguïté sur le résultat
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x,y)
+ x + y
+end
+
+# Les paramètres de méthode sont séparés par des virgules
+sum 3, 4 #=> 7
+
+sum sum(3,4), 5 #=> 12
+
+# yield
+# Toutes les méthodes ont un argument facultatif et implicite
+# de type bloc de code
+# il peut être appelé avec le mot clé 'yield'
+
+def surround
+ puts "{"
+ yield
+ puts "}"
+end
+
+surround { puts 'Bonjour tout le monde' }
+
+# {
+# Bonjour tout le monde
+# }
+
+
+# Définissez une classe avec le mot clé 'class'
+class Humain
+
+ # Une variable de classe
+ # est partagée par toutes les instances de cette classe.
+ @@espece = "H. sapiens"
+
+ # Constructeur de classe
+ def initialize(nom, age = 0)
+ # Affectez l'argument à la variable d'instance 'nom'
+ # pour la durée de vie de l'instance de cette classe
+ @nom = nom
+ # Si le paramètre 'age' est absent,
+ # la valeur par défaut définie dans la liste des arguments sera utilisée.
+ @age = age
+ end
+
+ # Une simple méthode setter
+ def nom=(nom)
+ @nom = nom
+ end
+
+ # Une simple méthode getter
+ def nom
+ @nom
+ end
+
+ # Une méthode de classe utilise le mot clé 'self'
+ # pour se distinguer de la méthode d'instance.
+ # La méthode sera alors accessible à partir de la classe
+ # et non pas de l'instance.
+ def self.say(msg)
+ puts "#{msg}"
+ end
+
+ def species
+ @@species
+ end
+
+end
+
+
+# Instanciez une classe
+jim = Humain.new("Jim Halpert")
+
+dwight = Humain.new("Dwight K. Schrute")
+
+# Appelez quelques méthodes
+jim.espece #=> "H. sapiens"
+jim.nom #=> "Jim Halpert"
+jim.nom = "Jim Halpert II" #=> "Jim Halpert II"
+jim.nom #=> "Jim Halpert II"
+dwight.espece #=> "H. sapiens"
+dwight.nom #=> "Dwight K. Schrute"
+
+# Appelez la méthode de classe
+Humain.say("Hi") #=> "Hi"
+
+# Les classes sont également des objets en Ruby.
+# Par conséquent, les classes peuvent avoir des variables d'instance.
+# Les variables de classe sont partagées parmi
+# la classe et ses descendants.
+
+# Classe parente
+class Humain
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(valeur)
+ @@foo = valeur
+ end
+end
+
+# Classe fille
+class Travailleur < Humain
+end
+
+Humain.foo # 0
+Travailleur.foo # 0
+
+Humain.foo = 2 # 2
+Travailleur.foo # 2
+
+# Les variables d'instance de classe ne sont pas partagées
+# avec les classes héritées.
+
+class Humain
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(valeur)
+ @bar = valeur
+ end
+end
+
+class Docteur < Humain
+end
+
+Humain.bar # 0
+Docteur.bar # nil
+
+```
diff --git a/git.html.markdown b/git.html.markdown
index d8537300..4b5e466e 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -2,9 +2,8 @@
category: tool
tool: git
contributors:
- - ["Jake Prather", "http:#github.com/JakeHP"]
+ - ["Jake Prather", "http://github.com/JakeHP"]
filename: LearnGit.txt
-
---
Git is a distributed version control and source code management system.
@@ -41,7 +40,7 @@ Version control is a system that records changes to a file, or set of files, ove
### Repository
-A set of files, directories, historical records, commits, and heads. Imagine it as a source code datastructure,
+A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
with the attribute that each source code "element" gives you access to its revision history, among other things.
A git repository is comprised of the .git directory & working tree.
diff --git a/go.html.markdown b/go.html.markdown
new file mode 100644
index 00000000..fa4c8d0b
--- /dev/null
+++ b/go.html.markdown
@@ -0,0 +1,331 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+---
+
+Go was created out of the need to get work done. It's not the latest trend
+in computer science, but it is the newest fastest way to solve real-world
+problems.
+
+It has familiar concepts of imperative languages with static typing.
+It's fast to compile and fast to execute, it adds easy-to-understand
+concurrency to leverage today's multi-core CPUs, and has features to
+help with large-scale programming.
+
+Go comes with a great standard library and an enthusiastic community.
+
+```go
+// Single line comment
+/* Multi-
+ line comment */
+
+// A package clause starts every source file.
+// Main is a special name declaring an executable rather than a library.
+package main
+
+// Import declaration declares library packages referenced in this file.
+import (
+ "fmt" // A package in the Go standard library.
+ "net/http" // Yes, a web server!
+ "strconv" // String conversions.
+ m "math" // Math library with local alias m.
+)
+
+// A function definition. Main is special. It is the entry point for the
+// executable program. Love it or hate it, Go uses brace brackets.
+func main() {
+ // Println outputs a line to stdout.
+ // Qualify it with the package name, fmt.
+ fmt.Println("Hello world!")
+
+ // Call another function within this package.
+ beyondHello()
+}
+
+// Functions have parameters in parentheses.
+// If there are no parameters, empty parentheses are still required.
+func beyondHello() {
+ var x int // Variable declaration. Variables must be declared before use.
+ x = 3 // Variable assignment.
+ // "Short" declarations use := to infer the type, declare, and assign.
+ y := 4
+ sum, prod := learnMultiple(x, y) // Function returns two values.
+ fmt.Println("sum:", sum, "prod:", prod) // Simple output.
+ learnTypes() // < y minutes, learn more!
+}
+
+// Functions can have parameters and (multiple!) return values.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Return two values.
+}
+
+// Some built-in types and literals.
+func learnTypes() {
+ // Short declaration usually gives you what you want.
+ s := "Learn Go!" // string type.
+
+ s2 := `A "raw" string literal
+can include line breaks.` // Same string type.
+
+ // Non-ASCII literal. Go source is UTF-8.
+ g := 'Σ' // rune type, an alias for uint32, holds a unicode code point.
+
+ f := 3.14195 // float64, an IEEE-754 64-bit floating point number.
+ c := 3 + 4i // complex128, represented internally with two float64's.
+
+ // Var syntax with an initializers.
+ var u uint = 7 // Unsigned, but implementation dependent size as with int.
+ var pi float32 = 22. / 7
+
+ // Conversion syntax with a short declaration.
+ n := byte('\n') // byte is an alias for uint8.
+
+ // Arrays have size fixed at compile time.
+ var a4 [4]int // An array of 4 ints, initialized to all 0.
+ a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown.
+
+ // Slices have dynamic size. Arrays and slices each have advantages
+ // but use cases for slices are much more common.
+ s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here.
+ s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0.
+ var d2 [][]float64 // Declaration only, nothing allocated here.
+ bs := []byte("a slice") // Type conversion syntax.
+
+ p, q := learnMemory() // Declares p, q to be type pointer to int.
+ fmt.Println(*p, *q) // * follows a pointer. This prints two ints.
+
+ // Maps are a dynamically growable associative array type, like the
+ // hash or dictionary types of some other languages.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // Unused variables are an error in Go.
+ // The underbar lets you "use" a variable but discard its value.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Output of course counts as using a variable.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // Back in the flow.
+}
+
+// Go is fully garbage collected. It has pointers but no pointer arithmetic.
+// You can make a mistake with a nil pointer, but not by incrementing a pointer.
+func learnMemory() (p, q *int) {
+ // Named return values p and q have type pointer to int.
+ p = new(int) // Built-in function new allocates memory.
+ // The allocated int is initialized to 0, p is no longer nil.
+ s := make([]int, 20) // Allocate 20 ints as a single block of memory.
+ s[3] = 7 // Assign one of them.
+ r := -2 // Declare another local variable.
+ return &s[3], &r // & takes the address of an object.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // If statements require brace brackets, and do not require parens.
+ if true {
+ fmt.Println("told ya")
+ }
+ // Formatting is standardized by the command line command "go fmt."
+ if false {
+ // Pout.
+ } else {
+ // Gloat.
+ }
+ // Use switch in preference to chained if statements.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Cases don't "fall through".
+ case 43:
+ // Unreached.
+ }
+ // Like if, for doesn't use parens either.
+ // Variables declared in for and if are local to their scope.
+ for x := 0; x < 3; x++ { // ++ is a statement.
+ fmt.Println("iteration", x)
+ }
+ // x == 42 here.
+
+ // For is the only loop statement in Go, but it has alternate forms.
+ for { // Infinite loop.
+ break // Just kidding.
+ continue // Unreached.
+ }
+ // As with for, := in an if statement means to declare and assign y first,
+ // then test y > x.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Function literals are closures.
+ xBig := func() bool {
+ return x > 10000 // References x declared above switch statement.
+ }
+ fmt.Println("xBig:", xBig()) // true (we last assigned e^10 to x).
+ x = 1.3e3 // This makes x == 1300
+ fmt.Println("xBig:", xBig()) // false now.
+
+ // When you need it, you'll love it.
+ goto love
+love:
+
+ learnDefer() // A quick detour to an important keyword.
+ learnInterfaces() // Good stuff coming up!
+}
+
+func learnDefer() (ok bool) {
+ // Deferred statements are executed just before the function returns.
+ defer fmt.Println("deferred statements execute in reverse (LIFO) order.")
+ defer fmt.Println("\nThis line is being printed first because")
+ // Defer is commonly used to close a file, so the function closing the file
+ // stays close to the function opening the file
+ return true
+}
+
+// Define Stringer as an interface type with one method, String.
+type Stringer interface {
+ String() string
+}
+
+// Define pair as a struct with two fields, ints named x and y.
+type pair struct {
+ x, y int
+}
+
+// Define a method on type pair. Pair now implements Stringer.
+func (p pair) String() string { // p is called the "receiver"
+ // Sprintf is another public function in package fmt.
+ // Dot syntax references fields of p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Brace syntax is a "struct literal." It evaluates to an initialized
+ // struct. The := syntax declares and initializes p to this struct.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Call String method of p, of type pair.
+ var i Stringer // Declare i of interface type Stringer.
+ i = p // Valid because pair implements Stringer
+ // Call String method of i, of type Stringer. Output same as above.
+ fmt.Println(i.String())
+
+ // Functions in the fmt package call the String method to ask an object
+ // for a printable representation of itself.
+ fmt.Println(p) // Output same as above. Println calls String method.
+ fmt.Println(i) // Output same as above.
+
+ learnVariadicParams("great", "learning", "here!")
+}
+
+// Functions can have variadic parameters.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Iterate each value of the variadic.
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // Pass variadic value as a variadic parameter.
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" idiom used to tell if something worked or not.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map.
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // x would be the value, if it were in the map.
+ }
+ // An error value communicates not just "ok" but more about the problem.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
+ // prints 'strconv.ParseInt: parsing "non-int": invalid syntax'
+ fmt.Println(err)
+ }
+ // We'll revisit interfaces a little later. Meanwhile,
+ learnConcurrency()
+}
+
+// c is a channel, a concurrency-safe communication object.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- is the "send" operator when a channel appears on the left.
+}
+
+// We'll use inc to increment some numbers concurrently.
+func learnConcurrency() {
+ // Same make function used earlier to make a slice. Make allocates and
+ // initializes slices, maps, and channels.
+ c := make(chan int)
+ // Start three concurrent goroutines. Numbers will be incremented
+ // concurrently, perhaps in parallel if the machine is capable and
+ // properly configured. All three send to the same channel.
+ go inc(0, c) // go is a statement that starts a new goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Read three results from the channel and print them out.
+ // There is no telling in what order the results will arrive!
+ fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator.
+
+ cs := make(chan string) // Another channel, this one handles strings.
+ ccs := make(chan chan string) // A channel of string channels.
+ go func() { c <- 84 }() // Start a new goroutine just to send a value.
+ go func() { cs <- "wordy" }() // Again, for cs this time.
+ // Select has syntax like a switch statement but each case involves
+ // a channel operation. It selects a case at random out of the cases
+ // that are ready to communicate.
+ select {
+ case i := <-c: // The value received can be assigned to a variable,
+ fmt.Printf("it's a %T", i)
+ case <-cs: // or the value received can be discarded.
+ fmt.Println("it's a string")
+ case <-ccs: // Empty channel, not ready for communication.
+ fmt.Println("didn't happen.")
+ }
+ // At this point a value was taken from either c or cs. One of the two
+ // goroutines started above has completed, the other will remain blocked.
+
+ learnWebProgramming() // Go does it. You want to do it too.
+}
+
+// A single function from package http starts a web server.
+func learnWebProgramming() {
+ // First parameter of ListenAndServe is TCP address to listen to.
+ // Second parameter is an interface, specifically http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // don't ignore errors
+}
+
+// Make pair an http.Handler by implementing its only method, ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Serve data with a method of http.ResponseWriter.
+ w.Write([]byte("You learned Go in Y minutes!"))
+}
+```
+
+## Further Reading
+
+The root of all things Go is the [official Go web site](http://golang.org/).
+There you can follow the tutorial, play interactively, and read lots.
+
+The language definition itself is highly recommended. It's easy to read
+and amazingly short (as language definitions go these days.)
+
+On the reading list for students of Go is the [source code to the standard
+library](http://golang.org/src/pkg/). Comprehensively documented, it
+demonstrates the best of readable and understandable Go, Go style, and Go
+idioms. Or you can click on a function name in [the
+documentation](http://golang.org/pkg/) and the source code comes up!
+
diff --git a/groovy.html.markdown b/groovy.html.markdown
new file mode 100644
index 00000000..8fb1b346
--- /dev/null
+++ b/groovy.html.markdown
@@ -0,0 +1,427 @@
+---
+language: Groovy
+filename: learngroovy.groovy
+contributors:
+ - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
+filename: learngroovy.groovy
+---
+
+Groovy - A dynamic language for the Java platform [Read more here.](http://groovy.codehaus.org)
+
+```groovy
+
+/*
+ Set yourself up:
+
+ 1) Install GVM - http://gvmtool.net/
+ 2) Install Groovy: gvm install groovy
+ 3) Start the groovy console by typing: groovyConsole
+
+*/
+
+// Single line comments start with two forward slashes
+/*
+Multi line comments look like this.
+*/
+
+// Hello World
+println "Hello world!"
+
+/*
+ Variables:
+
+ You can assign values to variables for later use
+*/
+
+def x = 1
+println x
+
+x = new java.util.Date()
+println x
+
+x = -3.1499392
+println x
+
+x = false
+println x
+
+x = "Groovy!"
+println x
+
+/*
+ Collections and maps
+*/
+
+//Creating an empty list
+def technologies = []
+
+/*** Adding a elements to the list ***/
+
+// As with Java
+technologies.add("Grails")
+
+// Left shift adds, and returns the list
+technologies << "Groovy"
+
+// Add multiple elements
+technologies.addAll(["Gradle","Griffon"])
+
+/*** Removing elements from the list ***/
+
+// As with Java
+technologies.remove("Griffon")
+
+// Subtraction works also
+technologies = technologies - 'Grails'
+
+/*** Iterating Lists ***/
+
+// Iterate over elements of a list
+technologies.each { println "Technology: $it"}
+technologies.eachWithIndex { it, i -> println "$i: $it"}
+
+/*** Checking List contents ***/
+
+//Evaluate if a list contains element(s) (boolean)
+contained = technologies.contains( 'Groovy' )
+
+// Or
+contained = 'Groovy' in technologies
+
+// Check for multiple contents
+technologies.containsAll(['Groovy','Grails'])
+
+/*** Sorting Lists ***/
+
+// Sort a list (mutates original list)
+technologies.sort()
+
+// To sort without mutating original, you can do:
+sortedTechnologies = technologies.sort( false )
+
+/*** Manipulating Lists ***/
+
+//Replace all elements in the list
+Collections.replaceAll(technologies, 'Gradle', 'gradle')
+
+//Shuffle a list
+Collections.shuffle(technologies, new Random())
+
+//Clear a list
+technologies.clear()
+
+//Creating an empty map
+def devMap = [:]
+
+//Add values
+devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+devMap.put('lastName','Perez')
+
+//Iterate over elements of a map
+devMap.each { println "$it.key: $it.value" }
+devMap.eachWithIndex { it, i -> println "$i: $it"}
+
+//Evaluate if a map contains a key
+assert devMap.containsKey('name')
+
+//Evaluate if a map contains a value
+assert devMap.containsValue('Roberto')
+
+//Get the keys of a map
+println devMap.keySet()
+
+//Get the values of a map
+println devMap.values()
+
+/*
+ Groovy Beans
+
+ GroovyBeans are JavaBeans but using a much simpler syntax
+
+ When Groovy is compiled to bytecode, the following rules are used.
+
+ * If the name is declared with an access modifier (public, private or
+ protected) then a field is generated.
+
+ * A name declared with no access modifier generates a private field with
+ public getter and setter (i.e. a property).
+
+ * If a property is declared final the private field is created final and no
+ setter is generated.
+
+ * You can declare a property and also declare your own getter or setter.
+
+ * You can declare a property and a field of the same name, the property will
+ use that field then.
+
+ * If you want a private or protected property you have to provide your own
+ getter and setter which must be declared private or protected.
+
+ * If you access a property from within the class the property is defined in
+ at compile time with implicit or explicit this (for example this.foo, or
+ simply foo), Groovy will access the field directly instead of going though
+ the getter and setter.
+
+ * If you access a property that does not exist using the explicit or
+ implicit foo, then Groovy will access the property through the meta class,
+ which may fail at runtime.
+
+*/
+
+class Foo {
+ // read only property
+ final String name = "Roberto"
+
+ // read only property with public getter and protected setter
+ String language
+ protected void setLanguage(String language) { this.language = language }
+
+ // dynamically typed property
+ def lastName
+}
+
+/*
+ Logical Branching and Looping
+*/
+
+//Groovy supports the usual if - else syntax
+def x = 3
+
+if(x==1) {
+ println "One"
+} else if(x==2) {
+ println "Two"
+} else {
+ println "X greater than Two"
+}
+
+//Groovy also supports the ternary operator:
+def y = 10
+def x = (y > 1) ? "worked" : "failed"
+assert x == "worked"
+
+//For loop
+//Iterate over a range
+def x = 0
+for (i in 0 .. 30) {
+ x += i
+}
+
+//Iterate over a list
+x = 0
+for( i in [5,3,2,1] ) {
+ x += i
+}
+
+//Iterate over an array
+array = (0..20).toArray()
+x = 0
+for (i in array) {
+ x += i
+}
+
+//Iterate over a map
+def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+x = 0
+for ( e in map ) {
+ x += e.value
+}
+
+/*
+ Operators
+
+ Operator Overloading for a list of the common operators that Groovy supports:
+ http://groovy.codehaus.org/Operator+Overloading
+
+ Helpful groovy operators
+*/
+//Spread operator: invoke an action on all items of an aggregate object.
+def technologies = ['Groovy','Grails','Gradle']
+technologies*.toUpperCase() // = to technologies.collect { it?.toUpperCase() }
+
+//Safe navigation operator: used to avoid a NullPointerException.
+def user = User.get(1)
+def username = user?.username
+
+
+/*
+ Closures
+ A Groovy Closure is like a "code block" or a method pointer. It is a piece of
+ code that is defined and then executed at a later point.
+
+ More info at: http://groovy.codehaus.org/Closures+-+Formal+Definition
+*/
+//Example:
+def clos = { println "Hello World!" }
+
+println "Executing the Closure:"
+clos()
+
+//Passing parameters to a closure
+def sum = { a, b -> println a+b }
+sum(2,4)
+
+//Closures may refer to variables not listed in their parameter list.
+def x = 5
+def multiplyBy = { num -> num * x }
+println multiplyBy(10)
+
+// If you have a Closure that takes a single argument, you may omit the
+// parameter definition of the Closure
+def clos = { print it }
+clos( "hi" )
+
+/*
+ Groovy can memorize closure results [1][2][3]
+*/
+def cl = {a, b ->
+ sleep(3000) // simulate some time consuming processing
+ a + b
+}
+
+mem = cl.memoize()
+
+def callClosure(a, b) {
+ def start = System.currentTimeMillis()
+ mem(a, b)
+ println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
+}
+
+callClosure(1, 2)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(2, 3)
+callClosure(3, 4)
+callClosure(3, 4)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(3, 4)
+
+/*
+ Expando
+
+ The Expando class is a dynamic bean so we can add properties and we can add
+ closures as methods to an instance of this class
+
+ http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
+*/
+ def user = new Expando(name:"Roberto")
+ assert 'Roberto' == user.name
+
+ user.lastName = 'Pérez'
+ assert 'Pérez' == user.lastName
+
+ user.showInfo = { out ->
+ out << "Name: $name"
+ out << ", Last name: $lastName"
+ }
+
+ def sw = new StringWriter()
+ println user.showInfo(sw)
+
+
+/*
+ Metaprogramming (MOP)
+*/
+
+//Using ExpandoMetaClass to add behaviour
+String.metaClass.testAdd = {
+ println "we added this"
+}
+
+String x = "test"
+x?.testAdd()
+
+//Intercepting method calls
+class Test implements GroovyInterceptable {
+ def sum(Integer x, Integer y) { x + y }
+
+ def invokeMethod(String name, args) {
+ System.out.println "Invoke method $name with args: $args"
+ }
+}
+
+def test = new Test()
+test?.sum(2,3)
+test?.multiply(2,3)
+
+//Groovy supports propertyMissing for dealing with property resolution attempts.
+class Foo {
+ def propertyMissing(String name) { name }
+}
+def f = new Foo()
+
+assertEquals "boo", f.boo
+
+/*
+ TypeChecked and CompileStatic
+ Groovy, by nature, is and will always be a dynamic language but it supports
+ typechecked and compilestatic
+
+ More info: http://www.infoq.com/articles/new-groovy-20
+*/
+//TypeChecked
+import groovy.transform.TypeChecked
+
+void testMethod() {}
+
+@TypeChecked
+void test() {
+ testMeethod()
+
+ def name = "Roberto"
+
+ println naameee
+
+}
+
+//Another example:
+import groovy.transform.TypeChecked
+
+@TypeChecked
+Integer test() {
+ Integer num = "1"
+
+ Integer[] numbers = [1,2,3,4]
+
+ Date date = numbers[1]
+
+ return "Test"
+
+}
+
+//CompileStatic example:
+import groovy.transform.CompileStatic
+
+@CompileStatic
+int sum(int x, int y) {
+ x + y
+}
+
+assert sum(2,5) == 7
+
+
+```
+
+## Further resources
+
+[Groovy documentation](http://groovy.codehaus.org/Documentation)
+
+[Groovy web console](http://groovyconsole.appspot.com/)
+
+Join a [Groovy user group](http://groovy.codehaus.org/User+Groups)
+
+## Books
+
+* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
+
+* [Groovy in Action] (http://manning.com/koenig2/)
+
+* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
+
+[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
+[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
+[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
+
+
+
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 9847ef2a..e0489710 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -4,14 +4,14 @@ contributors:
- ["Adit Bhargava", "http://adit.io"]
---
-Haskell was designed as a practical, purely functional programming language. It's famous for
-its monads and its type system, but I keep coming back to it because of its elegance. Haskell
-makes coding a real joy for me.
+Haskell was designed as a practical, purely functional programming
+language. It's famous for its monads and its type system, but I keep coming back
+to it because of its elegance. Haskell makes coding a real joy for me.
```haskell
-- Single line comments start with two dashes.
{- Multiline comments can be enclosed
-en a block like this.
+in a block like this.
-}
----------------------------------------------------
@@ -84,7 +84,7 @@ not False -- True
-- rest of the elements of this "infinite" list don't exist yet! Haskell won't
-- actually evaluate them until it needs to.
-- joining two lists
+-- joining two lists
[1..5] ++ [6..10]
-- adding to the head of a list
@@ -303,7 +303,7 @@ Nothing -- of type `Maybe a` for any `a`
-- While IO can't be explained fully without explaining monads,
-- it is not hard to explain enough to get going.
--- When a Haskell program is executed, the function `main` is
+-- When a Haskell program is executed, `main` is
-- called. It must return a value of type `IO ()`. For example:
main :: IO ()
@@ -329,7 +329,7 @@ main' = interact countLines
sayHello :: IO ()
sayHello = do
putStrLn "What is your name?"
- name <- getLine -- this gets a line and gives it the name "input"
+ name <- getLine -- this gets a line and gives it the name "name"
putStrLn $ "Hello, " ++ name
-- Exercise: write your own version of `interact` that only reads
@@ -401,7 +401,9 @@ Hello, Friend!
```
-There's a lot more to Haskell, including typeclasses and monads. These are the big ideas that make Haskell such fun to code in. I'll leave you with one final Haskell example: an implementation of quicksort in Haskell:
+There's a lot more to Haskell, including typeclasses and monads. These are the
+big ideas that make Haskell such fun to code in. I'll leave you with one final
+Haskell example: an implementation of quicksort in Haskell:
```haskell
qsort [] = []
diff --git a/haxe.html.markdown b/haxe.html.markdown
new file mode 100644
index 00000000..6a868f09
--- /dev/null
+++ b/haxe.html.markdown
@@ -0,0 +1,776 @@
+---
+language: haxe
+filename: LearnHaxe3.hx
+contributors:
+ - ["Justin Donaldson", "https://github.com/jdonaldson/"]
+---
+
+Haxe is a web-oriented language that provides platform support for C++, C#,
+Swf/ActionScript, Javascript, Java, and Neko byte code (also written by the
+Haxe author). Note that this guide is for Haxe version 3. Some of the guide
+may be applicable to older versions, but it is recommended to use other
+references.
+
+```csharp
+/*
+ Welcome to Learn Haxe 3 in 15 minutes. http://www.haxe.org
+ This is an executable tutorial. You can compile and run it using the haxe
+ compiler, while in the same directory as LearnHaxe.hx:
+ $> haxe -main LearnHaxe3 -x out
+
+ Look for the slash-star marks surrounding these paragraphs. We are inside
+ a "Multiline comment". We can leave some notes here that will get ignored
+ by the compiler.
+
+ Multiline comments are also used to generate javadoc-style documentation for
+ haxedoc. They will be used for haxedoc if they immediately precede a class,
+ class function, or class variable.
+
+ */
+
+// Double slashes like this will give a single-line comment
+
+
+/*
+ This is your first actual haxe code coming up, it's declaring an empty
+ package. A package isn't necessary, but it's useful if you want to create a
+ namespace for your code (e.g. org.module.ClassName).
+ */
+package; // empty package, no namespace.
+
+/*
+ Packages define modules for your code. Each module (e.g. org.module) must
+ be lower case, and should exist as a folder structure containing the class.
+ Class (and type) names must be capitalized. E.g, the class "org.module.Foo"
+ should have the folder structure org/module/Foo.hx, as accessible from the
+ compiler's working directory or class path.
+
+ If you import code from other files, it must be declared before the rest of
+ the code. Haxe provides a lot of common default classes to get you started:
+ */
+import haxe.ds.ArraySort;
+
+// you can import many classes/modules at once with "*"
+import haxe.ds.*;
+
+/*
+ You can also import classes in a special way, enabling them to extend the
+ functionality of other classes like a "mixin". More on 'using' later.
+ */
+using StringTools;
+
+/*
+ Typedefs are like variables... for types. They must be declared before any
+ code. More on this later.
+ */
+typedef FooString = String;
+
+// Typedefs can also reference "structural" types, more on that later as well.
+typedef FooObject = { foo: String };
+
+/*
+ Here's the class definition. It's the main class for the file, since it has
+ the same name (LearnHaxe3).
+ */
+class LearnHaxe3{
+ /*
+ If you want certain code to run automatically, you need to put it in
+ a static main function, and specify the class in the compiler arguments.
+ In this case, we've specified the "LearnHaxe3" class in the compiler
+ arguments above.
+ */
+ static function main(){
+
+ /*
+ Trace is the default method of printing haxe expressions to the
+ screen. Different targets will have different methods of
+ accomplishing this. E.g., java, c++, c#, etc. will print to std
+ out. Javascript will print to console.log, and flash will print to
+ an embedded TextField. All traces come with a default newline.
+ Finally, It's possible to prevent traces from showing by using the
+ "--no-traces" argument on the compiler.
+ */
+ trace("Hello World, with trace()!");
+
+ /*
+ Trace can handle any type of value or object. It will try to print
+ a representation of the expression as best it can. You can also
+ concatenate strings with the "+" operator:
+ */
+ trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
+
+ /*
+ In Haxe, it's required to separate expressions in the same block with
+ semicolons. But, you can put two expressions on one line:
+ */
+ trace('two expressions..'); trace('one line');
+
+
+ //////////////////////////////////////////////////////////////////
+ // Types & Variables
+ //////////////////////////////////////////////////////////////////
+ trace("***Types & Variables***");
+
+ /*
+ You can save values and references to data structures using the
+ "var" keyword:
+ */
+ var an_integer:Int = 1;
+ trace(an_integer + " is the value for an_integer");
+
+
+ /*
+ Haxe is statically typed, so "an_integer" is declared to have an
+ "Int" type, and the rest of the expression assigns the value "1" to
+ it. It's not necessary to declare the type in many cases. Here,
+ the haxe compiler is inferring that the type of another_integer
+ should be "Int".
+ */
+ var another_integer = 2;
+ trace(another_integer + " is the value for another_integer");
+
+ // The $type() method prints the type that the compiler assigns:
+ $type(another_integer);
+
+ // You can also represent integers with hexadecimal:
+ var hex_integer = 0xffffff;
+
+ /*
+ Haxe uses platform precision for Int and Float sizes. It also
+ uses the platform behavior for overflow.
+ (Other numeric types and behavior are possible using special
+ libraries)
+ */
+
+ /*
+ In addition to simple values like Integers, Floats, and Booleans,
+ Haxe provides standard library implementations for common data
+ structures like strings, arrays, lists, and maps:
+ */
+
+ var a_string = "some" + 'string'; // strings can have double or single quotes
+ trace(a_string + " is the value for a_string");
+
+ /*
+ Strings can be "interpolated" by inserting variables into specific
+ positions. The string must be single quoted, and the variable must
+ be preceded with "$". Expressions can be enclosed in ${...}.
+ */
+ var x = 1;
+ var an_interpolated_string = 'the value of x is $x';
+ var another_interpolated_string = 'the value of x + 1 is ${x + 1}';
+
+ /*
+ Strings are immutable, instance methods will return a copy of
+ parts or all of the string.
+ (See also the StringBuf class).
+ */
+ var a_sub_string = a_string.substr(0,4);
+ trace(a_sub_string + " is the value for a_sub_string");
+
+ /*
+ Regexes are also supported, but there's not enough space to go into
+ much detail.
+ */
+ trace((~/foobar/.match('foo')) + " is the value for (~/foobar/.match('foo')))");
+
+ /*
+ Arrays are zero-indexed, dynamic, and mutable. Missing values are
+ defined as null.
+ */
+ var a = new Array<String>(); // an array that contains Strings
+ a[0] = 'foo';
+ trace(a.length + " is the value for a.length");
+ a[9] = 'bar';
+ trace(a.length + " is the value for a.length (after modification)");
+ trace(a[3] + " is the value for a[3]"); //null
+
+ /*
+ Arrays are *generic*, so you can indicate which values they contain
+ with a type parameter:
+ */
+ var a2 = new Array<Int>(); // an array of Ints
+ var a3 = new Array<Array<String>>(); // an Array of Arrays (of Strings).
+
+ /*
+ Maps are simple key/value data structures. The key and the value
+ can be of any type.
+ */
+ var m = new Map<String, Int>(); // The keys are strings, the values are Ints.
+ m.set('foo', 4);
+ // You can also use array notation;
+ m['bar'] = 5;
+ trace(m.exists('bar') + " is the value for m.exists('bar')");
+ trace(m.get('bar') + " is the value for m.get('bar')");
+ trace(m['bar'] + " is the value for m['bar']");
+
+ var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
+ trace(m2 + " is the value for m2");
+
+ /*
+ Remember, you can use type inference. The Haxe compiler will
+ decide the type of the variable the first time you pass an
+ argument that sets a type parameter.
+ */
+ var m3 = new Map();
+ m3.set(6, 'baz'); // m3 is now a Map<Int,String>
+ trace(m3 + " is the value for m3");
+
+ /*
+ Haxe has some more common datastructures in the haxe.ds module, such as
+ List, Stack, and BalancedTree
+ */
+
+
+ //////////////////////////////////////////////////////////////////
+ // Operators
+ //////////////////////////////////////////////////////////////////
+ trace("***OPERATORS***");
+
+ // basic arithmetic
+ trace((4 + 3) + " is the value for (4 + 3)");
+ trace((5 - 1) + " is the value for (5 - 1)");
+ trace((2 * 4) + " is the value for (2 * 4)");
+ trace((8 / 3) + " is the value for (8 / 3) (division always produces Floats)");
+ trace((12 % 4) + " is the value for (12 % 4)");
+
+
+ //basic comparison
+ trace((3 == 2) + " is the value for 3 == 2");
+ trace((3 != 2) + " is the value for 3 != 2");
+ trace((3 > 2) + " is the value for 3 > 2");
+ trace((3 < 2) + " is the value for 3 < 2");
+ trace((3 >= 2) + " is the value for 3 >= 2");
+ trace((3 <= 2) + " is the value for 3 <= 2");
+
+ // standard bitwise operators
+ /*
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed right shift
+ >>> Unsigned right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
+ */
+
+ //increments
+ var i = 0;
+ trace("Increments and decrements");
+ trace(i++); //i = 1. Post-Incrementation
+ trace(++i); //i = 2. Pre-Incrementation
+ trace(i--); //i = 1. Post-Decrementation
+ trace(--i); //i = 0. Pre-Decrementation
+
+ //////////////////////////////////////////////////////////////////
+ // Control Structures
+ //////////////////////////////////////////////////////////////////
+ trace("***CONTROL STRUCTURES***");
+
+ // if statements
+ var j = 10;
+ if (j == 10){
+ trace("this is printed");
+ } else if (j > 10){
+ trace("not greater than 10, so not printed");
+ } else {
+ trace("also not printed.");
+ }
+
+ // there is also a "ternary" if:
+ (j == 10) ? trace("equals 10") : trace("not equals 10");
+
+ /*
+ Finally, there is another form of control structures that operates
+ at compile time: conditional compilation.
+ */
+#if neko
+ trace('hello from neko');
+#elseif js
+ trace('hello from js');
+#else
+ trace('hello from another platform!');
+#end
+ /*
+ The compiled code will change depending on the platform target.
+ Since we're compiling for neko (-x or -neko), we only get the neko
+ greeting.
+ */
+
+
+ trace("Looping and Iteration");
+
+ // while loop
+ var k = 0;
+ while(k < 100){
+ // trace(counter); // will print out numbers 0-99
+ k++;
+ }
+
+ // do-while loop
+ var l = 0;
+ do{
+ trace("do statement always runs at least once");
+ } while (i > 0);
+
+ // for loop
+ /*
+ There is no c-style for loop in Haxe, because they are prone
+ to error, and not necessary. Instead, Haxe has a much simpler
+ and safer version that uses Iterators (more on those later).
+ */
+ var m = [1,2,3];
+ for (val in m){
+ trace(val + " is the value for val in the m array");
+ }
+
+ // Note that you can iterate on an index using a range
+ // (more on ranges later as well)
+ var n = ['foo', 'bar', 'baz'];
+ for (val in 0...n.length){
+ trace(val + " is the value for val (an index for m)");
+ }
+
+
+ trace("Array Comprehensions");
+
+ // Array comprehensions give you the ability to iterate over arrays
+ // while also creating filters and modifications.
+ var filtered_n = [for (val in n) if (val != "foo") val];
+ trace(filtered_n + " is the value for filtered_n");
+
+ var modified_n = [for (val in n) val += '!'];
+ trace(modified_n + " is the value for modified_n");
+
+ var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"];
+ trace(filtered_and_modified_n + " is the value for filtered_and_modified_n");
+
+ //////////////////////////////////////////////////////////////////
+ // Switch Statements (Value Type)
+ //////////////////////////////////////////////////////////////////
+ trace("***SWITCH STATEMENTS (VALUE TYPES)***");
+
+ /*
+ Switch statements in Haxe are very powerful. In addition to working
+ on basic values like strings and ints, they can also work on the
+ generalized algebraic data types in enums (more on enums later).
+ Here's some basic value examples for now:
+ */
+ var my_dog_name = "fido";
+ var favorite_thing = "";
+ switch(my_dog_name){
+ case "fido" : favorite_thing = "bone";
+ case "rex" : favorite_thing = "shoe";
+ case "spot" : favorite_thing = "tennis ball";
+ default : favorite_thing = "some unknown treat";
+ // case _ : "some unknown treat"; // same as default
+ }
+ // The "_" case above is a "wildcard" value
+ // that will match anything.
+
+ trace("My dog's name is" + my_dog_name
+ + ", and his favorite thing is a: "
+ + favorite_thing);
+
+ //////////////////////////////////////////////////////////////////
+ // Expression Statements
+ //////////////////////////////////////////////////////////////////
+ trace("***EXPRESSION STATEMENTS***");
+
+ /*
+ Haxe control statements are very powerful because every statement
+ is also an expression, consider:
+ */
+
+ // if statements
+ var k = if (true){
+ 10;
+ } else {
+ 20;
+ }
+
+ trace("K equals ", k); // outputs 10
+
+ var other_favorite_thing = switch(my_dog_name) {
+ case "fido" : "teddy";
+ case "rex" : "stick";
+ case "spot" : "football";
+ default : "some unknown treat";
+ }
+
+ trace("My dog's name is" + my_dog_name
+ + ", and his other favorite thing is a: "
+ + other_favorite_thing);
+
+ //////////////////////////////////////////////////////////////////
+ // Converting Value Types
+ //////////////////////////////////////////////////////////////////
+ trace("***CONVERTING VALUE TYPES***");
+
+ // You can convert strings to ints fairly easily.
+
+ // string to integer
+ Std.parseInt("0"); // returns 0
+ Std.parseFloat("0.4"); // returns 0.4;
+
+ // integer to string
+ Std.string(0); // returns "0";
+ // concatenation with strings will auto-convert to string.
+ 0 + ""; // returns "0";
+ true + ""; // returns "true";
+ // See documentation for parsing in Std for more details.
+
+
+ //////////////////////////////////////////////////////////////////
+ // Dealing with Types
+ //////////////////////////////////////////////////////////////////
+
+ /*
+
+ As mentioned before, Haxe is a statically typed language. All in
+ all, static typing is a wonderful thing. It enables
+ precise autocompletions, and can be used to thoroughly check the
+ correctness of a program. Plus, the Haxe compiler is super fast.
+
+ *HOWEVER*, there are times when you just wish the compiler would let
+ something slide, and not throw a type error in a given case.
+
+ To do this, Haxe has two separate keywords. The first is the
+ "Dynamic" type:
+ */
+ var dyn: Dynamic = "any type of variable, such as this string";
+
+ /*
+ All that you know for certain with a Dynamic variable is that the
+ compiler will no longer worry about what type it is. It is like a
+ wildcard variable: You can pass it instead of any variable type,
+ and you can assign any variable type you want.
+
+ The other more extreme option is the "untyped" keyword:
+ */
+
+ untyped {
+ var x:Int = 'foo'; // this can't be right!
+ var y:String = 4; // madness!
+ }
+
+ /*
+ The untyped keyword operates on entire *blocks* of code, skipping
+ any type checks that might be otherwise required. This keyword should
+ be used very sparingly, such as in limited conditionally-compiled
+ situations where type checking is a hinderance.
+
+ In general, skipping type checks is *not* recommended. Use the
+ enum, inheritance, or structural type models in order to help ensure
+ the correctness of your program. Only when you're certain that none
+ of the type models work should you resort to "Dynamic" or "untyped".
+ */
+
+ //////////////////////////////////////////////////////////////////
+ // Basic Object Oriented Programming
+ //////////////////////////////////////////////////////////////////
+ trace("***BASIC OBJECT ORIENTED PROGRAMMING***");
+
+
+ /*
+ Create an instance of FooClass. The classes for this are at the
+ end of the file.
+ */
+ var foo_instance = new FooClass(3);
+
+ // read the public variable normally
+ trace(foo_instance.public_any + " is the value for foo_instance.public_any");
+
+ // we can read this variable
+ trace(foo_instance.public_read + " is the value for foo_instance.public_read");
+ // but not write it
+ // foo_instance.public_write = 4; // this will throw an error if uncommented:
+ // trace(foo_instance.public_write); // as will this.
+
+ trace(foo_instance + " is the value for foo_instance"); // calls the toString method
+ trace(foo_instance.toString() + " is the value for foo_instance.toString()"); // same thing
+
+
+ /*
+ The foo_instance has the "FooClass" type, while acceptBarInstance
+ has the BarClass type. However, since FooClass extends BarClass, it
+ is accepted.
+ */
+ BarClass.acceptBarInstance(foo_instance);
+
+ /*
+ The classes below have some more advanced examples, the "example()"
+ method will just run them here.
+ */
+ SimpleEnumTest.example();
+ ComplexEnumTest.example();
+ TypedefsAndStructuralTypes.example();
+ UsingExample.example();
+
+ }
+
+}
+
+/*
+ This is the "child class" of the main LearnHaxe3 Class
+ */
+class FooClass extends BarClass implements BarInterface{
+ public var public_any:Int; // public variables are accessible anywhere
+ public var public_read (default,null): Int; // use this style to only enable public read
+ public var public_write (null, default): Int; // or public write
+ public var property (get, set): Int; // use this style to enable getters/setters
+
+ // private variables are not available outside the class.
+ // see @:allow for ways around this.
+ var _private:Int; // variables are private if they are not marked public
+
+ // a public constructor
+ public function new(arg:Int){
+ super(); // call the constructor of the parent object, since we extended BarClass
+
+ this.public_any= 0;
+ this._private = arg;
+
+ }
+
+ // getter for _private
+ function get_property() : Int {
+ return _private;
+ }
+
+ // setter for _private
+ function set_property(val:Int) : Int {
+ _private = val;
+ return val;
+ }
+
+ // special function that is called whenever an instance is cast to a string.
+ public function toString(){
+ return _private + " with toString() method!";
+ }
+
+ // this class needs to have this function defined, since it implements
+ // the BarInterface interface.
+ public function baseFunction(x: Int) : String{
+ // convert the int to string automatically
+ return x + " was passed into baseFunction!";
+ }
+}
+
+/*
+ A simple class to extend
+*/
+class BarClass {
+ var base_variable:Int;
+ public function new(){
+ base_variable = 4;
+ }
+ public static function acceptBarInstance(b:BarClass){
+ }
+}
+
+/*
+ A simple interface to implement
+*/
+interface BarInterface{
+ public function baseFunction(x:Int):String;
+}
+
+//////////////////////////////////////////////////////////////////
+// Enums and Switch Statements
+//////////////////////////////////////////////////////////////////
+
+/*
+ Enums in Haxe are very powerful. In their simplest form, enums
+ are a type with a limited number of states:
+ */
+
+enum SimpleEnum {
+ Foo;
+ Bar;
+ Baz;
+}
+
+// Here's a class that uses it:
+
+class SimpleEnumTest{
+ public static function example(){
+ var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name
+ var e = Foo; // but inference will work as well.
+ switch(e){
+ case Foo: trace("e was Foo");
+ case Bar: trace("e was Bar");
+ case Baz: trace("e was Baz"); // comment this line to throw an error.
+ }
+
+ /*
+ This doesn't seem so different from simple value switches on strings.
+ However, if we don't include *all* of the states, the compiler will
+ complain. You can try it by commenting out a line above.
+
+ You can also specify a default for enum switches as well:
+ */
+ switch(e){
+ case Foo: trace("e was Foo again");
+ default : trace("default works here too");
+ }
+ }
+}
+
+/*
+ Enums go much further than simple states, we can also enumerate
+ *constructors*, but we'll need a more complex enum example
+ */
+enum ComplexEnum{
+ IntEnum(i:Int);
+ MultiEnum(i:Int, j:String, k:Float);
+ SimpleEnumEnum(s:SimpleEnum);
+ ComplexEnumEnum(c:ComplexEnum);
+}
+// Note: The enum above can include *other* enums as well, including itself!
+
+class ComplexEnumTest{
+ public static function example(){
+ var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter
+ /*
+ Now we can switch on the enum, as well as extract any parameters
+ it might of had.
+ */
+ switch(e1){
+ case IntEnum(x) : trace('$x was the parameter passed to e1');
+ default: trace("Shouldn't be printed");
+ }
+
+ // another parameter here that is itself an enum... an enum enum?
+ var e2 = SimpleEnumEnum(Foo);
+ switch(e2){
+ case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
+ default: trace("Shouldn't be printed");
+ }
+
+ // enums all the way down
+ var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
+ switch(e3){
+ // You can look for certain nested enums by specifying them explicitly:
+ case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
+ trace('$i, $j, and $k were passed into this nested monster');
+ }
+ default: trace("Shouldn't be printed");
+ }
+ /*
+ Check out "generalized algebraic data types" (GADT) for more details
+ on why these are so great.
+ */
+ }
+}
+
+class TypedefsAndStructuralTypes {
+ public static function example(){
+ /*
+ Here we're going to use typedef types, instead of base types.
+ At the top we've declared the type "FooString" to mean a "String" type.
+ */
+ var t1:FooString = "some string";
+
+ /*
+ We can use typedefs for "structural types" as well. These types are
+ defined by their field structure, not by class inheritance. Here's
+ an anonymous object with a String field named "foo":
+ */
+
+ var anon_obj = { foo: 'hi' };
+
+ /*
+ The anon_obj variable doesn't have a type declared, and is an
+ anonymous object according to the compiler. However, remember back at
+ the top where we declared the FooObj typedef? Since anon_obj matches
+ that structure, we can use it anywhere that a "FooObject" type is
+ expected.
+ */
+
+ var f = function(fo:FooObject){
+ trace('$fo was passed in to this function');
+ }
+ f(anon_obj); // call the FooObject signature function with anon_obj.
+
+ /*
+ Note that typedefs can have optional fields as well, marked with "?"
+
+ typedef OptionalFooObj = {
+ ?optionalString: String,
+ requiredInt: Int
+ }
+ */
+
+ /*
+ Typedefs work well with conditional compilation. For instance,
+ we could have included this at the top of the file:
+
+#if( js )
+ typedef Surface = js.html.CanvasRenderingContext2D;
+#elseif( nme )
+ typedef Surface = nme.display.Graphics;
+#elseif( !flash9 )
+ typedef Surface = flash8.MovieClip;
+#elseif( java )
+ typedef Surface = java.awt.geom.GeneralPath;
+#end
+
+ That would give us a single "Surface" type to work with across
+ all of those platforms.
+ */
+ }
+}
+
+class UsingExample {
+ public static function example() {
+
+ /*
+ The "using" import keyword is a special type of class import that
+ alters the behavior of any static methods in the class.
+
+ In this file, we've applied "using" to "StringTools", which contains
+ a number of static methods for dealing with String types.
+ */
+ trace(StringTools.endsWith("foobar", "bar") + " should be true!");
+
+ /*
+ With a "using" import, the first argument type is extended with the
+ method. What does that mean? Well, since "endsWith" has a first
+ argument type of "String", that means all String types now have the
+ "endsWith" method:
+ */
+ trace("foobar".endsWith("bar") + " should be true!");
+
+ /*
+ This technique enables a good deal of expression for certain types,
+ while limiting the scope of modifications to a single file.
+
+ Note that the String instance is *not* modified in the run time.
+ The newly attached method is not really part of the attached
+ instance, and the compiler still generates code equivalent to a
+ static method.
+ */
+ }
+
+}
+
+```
+
+We're still only scratching the surface here of what Haxe can do. For a formal
+overiew of all Haxe features, checkout the [online
+manual](http://haxe.org/manual), the [online api](http://api.haxe.org/), and
+"haxelib", the [haxe library repo] (http://lib.haxe.org/).
+
+For more advanced topics, consider checking out:
+
+* [Abstract types](http://haxe.org/manual/abstracts)
+* [Macros](http://haxe.org/manual/macros), and [Compiler Macros](http://haxe.org/manual/macros_compiler)
+* [Tips and Tricks](http://haxe.org/manual/tips_and_tricks)
+
+
+Finally, please join us on [the mailing list](https://groups.google.com/forum/#!forum/haxelang), on IRC [#haxe on
+freenode](http://webchat.freenode.net/), or on
+[Google+](https://plus.google.com/communities/103302587329918132234).
+
+
diff --git a/hu-hu/go.html.markdown b/hu-hu/go.html.markdown
new file mode 100644
index 00000000..638c9489
--- /dev/null
+++ b/hu-hu/go.html.markdown
@@ -0,0 +1,337 @@
+---
+language: Go
+lang: hu-hu
+filename: learngo-hu.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+translators:
+ - ["Szabó Krisztián", "https://github.com/thenonameguy/"]
+ - ["Árpád Goretity", "https://github.com/H2CO3"]
+---
+
+A Go programozási nyelv az életszerű feladatok könnyebb elvégzése miatt született.
+A mai legújabb programozási trendeket elkerülve,
+praktikus megoldást nyújt a valós, üzleti problémákra.
+
+C-szerű szintaktikával és statikus típuskezeléssel rendelkezik.
+A fordító szempillantás alatt végez és egy gyorsan futó,statikus futtatható állományt hoz létre.
+A nyelv könnyen érthető, folyamatok közötti csatornákon áthaladó üzenetekkel kommunikáló konkurens programozást tesz lehetővé, így könnyen ki lehet használni
+a mai számítógépek több magos processzorait, ez nagy rendszerek építéséhez ideális.
+
+A Go alap könyvtára mindenre területre kiterjed, ennek köszönhetően a nyelvnek egyre növekvő tábora van.
+
+```go
+// Egy soros komment
+/* Több
+ soros komment */
+
+// Minden forrás fájl egy csomag-definícióval kezdődik, ez hasonlít a Python
+// csomagkezelésére
+// A main egy különleges csomagnév, ennek a fordítása futtatható állományt hoz
+// létre egy könyvtár helyett.
+package main
+
+// Az import rész meghatározza melyik csomagokat kívánjuk használni ebben a
+// forrásfájlban
+import (
+ "fmt" // A Go alap könyvtárának része
+ "net/http" // Beépített webszerver!
+ "strconv" // Stringek átalakítására szolgáló csomag
+)
+
+// Függvénydeklarálás, a main nevű függvény a program kezdőpontja.
+func main() {
+ // Println kiírja a beadott paramétereket a standard kimenetre.
+ // Ha más csomagot függvényeit akarjuk használni, akkor azt jelezni kell a
+ // csomag nevével
+ fmt.Println("Hello world!")
+
+ // Meghívunk egy másik függvényt ebből a csomagból
+ beyondHello()
+}
+
+// A függvények paraméterei zárójelek között vannak.
+// Ha nincsenek paraméterek, akkor is kötelező a zárójel-pár.
+func beyondHello() {
+ var x int // Változó deklaráció, használat előtt muszáj ezt megtenni.
+ x = 3 // Változó értékadás
+ // "Rövid" deklaráció is létezik, ez az érték alapján deklarálja,
+ // definiálja és értéket is ad a változónak
+ y := 4
+ sum, prod := learnMultiple(x, y) // a függvényeknek több
+ // visszatérési értéke is lehet
+ fmt.Println("sum:", sum, "prod:", prod) // egyszerű kiíratás
+ learnTypes()
+}
+
+// A funkcióknak elnevezett visszatérési értékük is lehet
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // visszatérünk két értékkel
+ /*
+ sum = x + y
+ prod = x * y
+ return
+ Ez ugyanezzel az eredménnyel járt volna, mint a fenti sor.
+ Üres return esetén, az elnevezett visszatérési változók
+ aktuális értékeikkel térnek vissza. */
+}
+
+// Beépített típusok
+func learnTypes() {
+ // Rövid deklarálás az esetek többségében elég lesz a változókhoz
+ s := "Tanulj Go-t!" // string típus
+
+ s2 := `A "nyers" stringekben lehetnek
+ újsorok is!` // de ettől még ez is ugyanolyan string mint az s, nincs külön
+ // típusa
+
+ // nem ASCII karakterek. Minden Go forrás UTF-8 és a stringek is azok.
+ g := 'Σ' // rúna(rune) típus, megegyezik az uint32-vel, egy UTF-8 karaktert
+ // tárol
+
+ f := 3.14195 // float64, az IEEE-754 szabványnak megfelelő 64-bites
+ // lebegőpontos szám
+ c := 3 + 4i // complex128, belsőleg két float64-gyel tárolva
+
+ // Var szintaxis változótípus-definiálással
+ var u uint = 7 // unsigned, az implementáció dönti el mekkora, akárcsak az
+ // int-nél
+ var pi float32 = 22. / 7
+
+ // Rövid deklarásnál átalakítás is lehetséges
+ n := byte('\n') // byte típus, ami megegyezik az uint8-al
+
+ // A tömböknek fordítás-időben fixált méretük van
+ var a4 [4]int // egy tömb 4 int-tel, mind 0-ra inicializálva
+ a3 := [...]int{3, 1, 5} // egy tömb 3 int-tel, láthatóan inicalizálva egyedi
+ // értékekre
+
+ // A "szeleteknek" (slices) dinamikus a méretük. A szeleteknek és a tömböknek is
+ // megvannak az előnyeik de a szeleteket sokkal gyakrabban használjuk.
+ s3 := []int{4, 5, 9} // vesd össze a3-mal, nincsenek pontok.
+ s4 := make([]int, 4) // allokál 4 int-et, mind 0-ra inicializálva
+ var d2 [][]float64 // ez csak deklaráció, semmi sincs még allokálva
+ bs := []byte("a slice") // típus konverzió szintaxisa
+
+ p, q := learnMemory() // deklarál két mutatót (p,q), két int-re
+ fmt.Println(*p, *q) // * követi a mutatót. Ez a sor kiírja a két int értékét.
+
+ // A map a dinamikusan növelhető asszociatív tömb része a nyelvnek, hasonlít
+ // a hash és dictionary típusokra más nyelvekben.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // A felhasználatlan változók fordítás-idejű hibát okoznak a Go-ban.
+ // Az aláhúzással "használod" a változókat, de eldobod az értéküket.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Kiíratás is természetesen használatnak minősül
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl()
+}
+
+// A Go nyelvben szemétgyűjtés (garbage collection) működik. Megtalálhatók benne
+// mutatók, de nincs pointeraritmetika. Ez azt jelenti, hogy üres (null) mutatóval még
+// mindig hibázhatsz, de hozzáadni/műveleteket végezni már nem lehet.
+func learnMemory() (p, q *int) {
+ // Elnevezett visszatérési változóknak int-re mutató a típusa
+ p = new(int) // a beépített "new" funkció, egy típusnak elegendő memóriát
+ // allokál, és visszaad rá egy mutatót.
+ // Az allokált int nullázva van, p többé nem üres mutató.
+ s := make([]int, 20) // allokáljunk 20 int változót egy memóriaterületen.
+ s[3] = 7 // adjunk értéket az egyiknek
+ r := -2 // hozzánk létre egy lokális változót
+ return &s[3], &r // A & megadja a memóriacímét a változónak
+}
+
+func expensiveComputation() int {
+ return 1e6
+}
+
+func learnFlowControl() {
+ // Az elágazásoknak kötelező a kapcsos zárójel, a zárójel nem szükséges.
+ if true {
+ fmt.Println("megmondtam")
+ }
+ // A kód formátumát a nyelvvel járó "go" parancssori program "go fmt"
+ // parancsa szabványosítja
+ if false {
+ // így lehet
+ } else {
+ // if/else-t csinálni
+ }
+ // Használjunk switchet a hosszabb elágazások alkalmazása helyett.
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // Az "esetek" nem "esnek át", tehát
+ case 2:
+ // ez nem fog lefutni, nincs szükség break-ekre.
+ }
+ // A for ciklus sem használ zárójeleket
+ for x := 0; x < 3; x++ {
+ fmt.Println("iteráció", x)
+ }
+ // itt az x == 1.
+
+ // A for az egyetlen ciklus fajta a Go-ban, de több formája van.
+ for { // végtelen ciklus
+ break // csak vicceltem
+ continue // soha nem fut le
+ }
+
+ //Akárcsak a for-nál, az if-nél is lehet rövid deklarálással egy lokális változót létrehozni,
+ //ami a blokk összes if/else szerkezetén keresztül érvényes marad.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Függvényeket használhatjuk closure-ként is.
+ xBig := func() bool {
+ return x > 100 // a switch felett deklarált x-et használjuk itt
+ }
+ fmt.Println("xBig:", xBig()) // igaz (utoljára 1e6 lett az értéke az x-nek)
+ x /= 1e5 // így most már x == 10
+ fmt.Println("xBig:", xBig()) // 10 pedig kisebb mint 100, tehát hamis
+
+ // Ha nagyon-nagyon szükséges, akkor használhatjuk a jó öreg goto-t.
+ goto love
+love:
+
+ learnInterfaces() // Itt kezdődnek az érdekes dolgok!
+}
+
+// Definiáljuk a Stringert egy olyan interfésznek, amelynek egy metódusa van, a
+// String, ami visszatér egy stringgel.
+type Stringer interface {
+ String() string
+}
+
+// Definiáljuk a pair-t egy olyan struktúrának amelynek két int változója van,
+// x és y.
+type pair struct {
+ x, y int
+}
+
+// Definiáljunk egy metódust a pair struktúrának, ezzel teljesítve a Stringer interfészt.
+func (p pair) String() string { // p lesz a "fogadó" (receiver)
+ // Sprintf az fmt csomag egy publikus függvénye, műkődése megegyezik a C-s
+ // megfelelőjével. A pontokkal érjük el a mindenkori p struktúra elemeit
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // A kapcsos zárójellel jelezzük, hogy egyből inicializálni
+ // szeretnénk a struktúra változóit a sorrendnek megfelelően.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // meghívjuk a p String metódusát.
+ var i Stringer // deklaráljuk i-t Stringer típusú interfésznek
+ i = p // lehetséges, mert a pair struktúra eleget tesz a
+ // Stringer interfésznek
+ // Meghívjuk i String metódusát, az eredmény ugyanaz, mint az előbb.
+ fmt.Println(i.String())
+
+ // Az fmt csomag függvényei automatikusan meghívják a String függvényt
+ // hogy megtudják egy objektum szöveges reprezentációját.
+ fmt.Println(p) // ugyan az az eredmény mint az előbb, a Println meghívja
+ // a String metódust.
+ fmt.Println(i) // dettó
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" szokásos megoldás arra, hogy jól működött-e a függvény.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok hamis lesz, mert az 1 nincs benne a map-ban.
+ fmt.Println("nincs meg")
+ } else {
+ fmt.Print(x) // x lenne az érték, ha benne lenne a map-ban.
+ }
+ // A hiba érték többet is elmond a függvény kimeneteléről, mint hogy minden
+ // "ok" volt-e
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ eldobja az értéket,
+ // úgy se lesz jó jelen
+ // esetben
+ // kiírja, hogy "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // Az interfészekre még visszatérünk, addig is jöjjön a konkurens programozás!
+ learnConcurrency()
+}
+
+// c egy csatorna, egy konkurens-biztos kommunikációs objektum.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- a "küldés" operátor, ha a bal oldalán csatorna van, így
+ // i+1-et küld be a csatornába
+}
+
+// Az inc-et fogjuk arra használni, hogy konkurensen megnöveljünk számokat
+func learnConcurrency() {
+ // Ugyanaz a make függvény, amivel korábban szeleteket hoztunk létre.
+ // A make allokál map-eket, szeleteket és csatornákat.
+ c := make(chan int)
+ // Indítsunk három konkurens goroutine-t. A számok konkurensen lesznek
+ // megnövelve, ha a számítógép képes rá és jól be van állítva, akkor pedig
+ // paralellizálva/egymás mellett. Mind a 3 ugyanabba a csatornába küldi az
+ // eredményeket.
+ go inc(0, c) // A go utasítás indít el goroutine-okat.
+ go inc(10, c)
+ go inc(-805, c)
+ // Beolvassuk 3x a csatornából az eredményeket és kiírjuk őket a kimenetre.
+ // Nem lehet tudni milyen sorrendben fognak érkezni az eredmények!
+ fmt.Println(<-c, <-c, <-c) // hogyha a jobb oldalon csatorna van, akkor a
+ // "<-" a beolvasó/kapó operátor
+
+ cs := make(chan string) // még egy csatorna, ez stringekkel kommunikál
+ cc := make(chan chan string) // egy csatorna csatornával
+ go func() { c <- 84 }() // indítsunk egy új goroutine-t, csak azért
+ // hogy küldjünk egy számot
+ go func() { cs <- "wordy" }() // ugyanez, csak a cs csatornába stringet
+ // küldünk
+ // A select olyan mint a switch, csak feltételek helyett csatorna műveletek
+ // vannak. Véletlenszerűen kiválasztja az első olyan esetet, ahol létrejöhet
+ // kommunikáció.
+ select {
+ case i := <-c: // a megkapott értéket el lehet tárolni egy változóban
+ fmt.Println("ez egy", i)
+ case <-cs: // vagy el lehet dobni az értékét
+ fmt.Println("ez egy string volt")
+ case <-cc: // üres csatorna, soha nem fog rajta semmi se érkezni
+ fmt.Println("sose futok le :'( ")
+ }
+ // Ezen a ponton vagy c vagy a cs goroutine-ja lefutott.
+ // Amelyik hamarabb végzett, annak a megfelelő case-e lefutott, a másik
+ // blokkolva vár.
+
+ learnWebProgramming() // a Go képes rá. Te is képes akarsz rá lenni.
+}
+
+// Egy függvény a http csomagból elindít egy webszervert.
+func learnWebProgramming() {
+ // A ListenAndServe első paramétre egy TCP port, amin kiszolgálunk majd.
+ // Második paramétere egy interfész, pontosabban a http.Handler interfész.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // nem felejtjük el kiírni az esetleges hibákat!
+}
+
+// Csináljunk a pair-ból egy http.Handler-t úgy, hogy implementáljuk az
+// egyetlen metódusát, a ServeHTTP-t.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Minden kapcsolatra elküldjük ezt a http.ResponseWriter-rel
+ w.Write([]byte("Megtanultad a Go-t Y perc alatt!"))
+}
+```
+
+## További olvasmányok
+
+Minden Go-val kapcsolatos megtaláható a [hivatalos Go weboldalon](http://golang.org/).
+Ott követhetsz egy tutorialt, játszhatsz a nyelvvel az interneten, és sok érdekességet olvashatsz.
+
+A nyelv specifikációját kifejezetten érdemes olvasni, viszonylag rövid és sokat tanul belőle az ember.
+
+Ha pedig jobban bele akarod vetni magad a Go-ba, akkor a legjobb praktikákat kilesheted a standard könyvtárból.
+TIPP: a dokumentációban kattints egy függvény nevére és rögtön megmutatja a hozzá tartozó kódot!
+
+Ha pedig a nyelvnek egy bizonyos részéről szeretnél hasonló leírást találni, akkor a
+[gobyexample.com](https://gobyexample.com/)-on megtalálod, amit keresel.
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/id-id/css-id.html.markdown b/id-id/css-id.html.markdown
new file mode 100644
index 00000000..456dfafe
--- /dev/null
+++ b/id-id/css-id.html.markdown
@@ -0,0 +1,246 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+translators:
+ - ["Eka Y Saputra", "http://github.com/ekajogja"]
+lang: id-id
+filename: learncss-id.css
+---
+
+Pada mulanya, web tidak memiliki elemen visual, murni teks saja.
+Tapi seiring perkembangan peramban, laman web dengan elemen visual menjadi umum.
+CSS adalah bahasa standar yang ada untuk menjaga keterpisahan antara
+konten (HTML) serta tampilan-dan-kesan laman web.
+
+Singkatnya, fungsi CSS ialah menyajikan sintaks yang memampukan kita
+untuk memilih elemen tertentu dalam sebuah laman HTML
+dan menerapkan berbagai properti visual bagi elemen tersebut.
+
+Seperti bahasa lainnya, CSS memiliki banyak versi.
+Di artikel ini, kita fokus pada CSS2.0 - yang meskipun bukan versi termutakhir
+namun paling kompatibel dan didukung secara luas.
+
+**CATATAN:** Lantaran keluaran dari CSS berwujud efek-efek visual,
+maka untuk mempelajarinya, kita perlu mencoba berbagai hal dalam dunia olah CSS
+semisal [dabblet](http://dabblet.com/).
+Fokus utama artikel ini ialah pada sintaks dan sejumlah tips umum.
+
+
+```css
+/* komentar terletak diantara sepasang tanda garis miring dan bintang,
+persis seperti larik ini! */
+
+/* ####################
+ ## SELEKTOR
+ ####################*/
+
+/* Secara garis besar, statemen utama dalam CSS sangat sederhana */
+selektor { properti: nilai; /* properti lainnya */ }
+
+/* selektor berfungsi untuk memilih suatu elemen dalam sebuah laman.
+
+Kita juga bisa memilih semua elemen di sebuah halaman! */
+* { color:red; }
+
+/*
+Dengan menentukan sebuah elemen seperti ini pada sebuah laman:
+
+<div class='suatu-class class2' id='suatuId' attr='nilai' />
+*/
+
+/* kita bisa memilih elemen berdasarkan nama class-nya */
+.suatu-class { }
+
+/*atau dengan dua class sekaligus! */
+.suatu-class.class2 { }
+
+/* atau dengan nama tag-nya */
+div { }
+
+/* atau id-nya */
+#suatuId { }
+
+/* atau - jika ada - dengan attribute-nya! */
+[attr] { font-size:smaller; }
+
+/* atau jika attribute tersebut memiliki nilai spesifik */
+[attr='nilai'] { font-size:smaller; }
+
+/* dibuka dengan sebuah nilai*/
+[attr^='nil'] { font-size:smaller; }
+
+/* atau ditutup dengan nilai */
+[attr$='ai'] { font-size:smaller; }
+
+/* atau bahkan disisipi nilai */
+[attr~='la'] { font-size:smaller; }
+
+
+/* dan yang lebih penting lagi, kita bisa mengombinasikannya sekaligus
+dengan syarat tidak ada spasi diantara selektor-selektor. sebab adanya spasi
+akan membuat selektor itu memiliki makna yang berbeda.*/
+div.suatu-class[attr$='ai'] { }
+
+/* kita juga bisa memilih sebuah elemen berdasarkan posisi elemen induknya.*/
+
+/*sebuah elemen yang merupakan anak langsung dari elemen induk (diseleksi dng
+cara yang sama) */
+div.suatu-induk > .-suatu-class {}
+
+/* atau salah satu induk elemennya dalam hirarki elemen */
+/* berikut ini dimaksudkan pada elemen manapun dengan class "class-entah" dan
+merupakan anak elemen dari suatu div dengan class "induk-entah" PADA LEVEL
+HIRARKI MANAPUN */
+div.suatu-induk .suatu-class {}
+
+/* peringatan: selektor yang sama jika tanpa ada spasi akan bermakna lain.
+misalnya? */
+div.suatu-induk.suatu-class {}
+
+/* kita juga bisa memilih sebuah elemen berdasarkan saudara elemen yang muncul
+tepat sebelumnya */
+.aku-muncul-tepat-sebelum + .elemen-ini { }
+
+/*atau saudara elemen manapun yang pernah muncul selang beberapa elemen
+sebelumnya */
+.aku-pernah-muncul-sebelum ~ .elemen-ini {}
+
+/* Ada beberapa pseudo-class yang memampukan kita memilih suatu elemen
+berdasarkan perilaku lamannya (bukan struktur lamannya) */
+
+/* semisal ketika sebuah elemen ditimpa hover (pointer mouse) */
+:hover {}
+
+/* atau link yang sudah pernah diklik*/
+:visited {}
+
+/* atau link yang belum pernah diklik*/
+:link {}
+
+/* atau elemen input yang menjadi fokus */
+:focus {}
+
+
+/* ####################
+ ## PROPERTI
+ ####################*/
+
+selektor {
+
+ /* Unit */
+ width: 50%; /* dalam persen */
+ font-size: 2em; /* angka kali jumlah font-size saat ini */
+ width: 200px; /* dalam pixel */
+ font-size: 20pt; /* dalam point */
+ width: 5cm; /* dalam centimeter */
+ width: 50mm; /* dalam milimeter */
+ width: 5in; /* dalam inci */
+
+ /* Warna */
+ background-color: #F6E; /* dalam short hex */
+ background-color: #F262E2; /* dalam format long hex */
+ background-color: tomato; /* warna yang sudah punya konvensi nama */
+ background-color: rgb(255, 255, 255); /* dalam rgb */
+ background-color: rgb(10%, 20%, 50%); /* dalam persen rgb */
+ background-color: rgba(255, 0, 0, 0.3); /* dalam rgb semi-transparan*/
+
+ /* Gambar */
+ background-image: url(/folder-gambar/image.jpg);
+
+ /* Font */
+ font-family: Arial;
+ font-family: "Courier New"; /* jika nama font memiliki spasi,
+ ia diketik dalam tanda petik ganda */
+ font-family: "Courier New", Trebuchet, Arial; /* jika font pertama tidak
+ ditemukan, peramban menggunakan font berikutnya,
+ demikian secara berturut-turut */
+}
+
+```
+
+## Penggunaan
+
+Simpan semua CSS yang hendak kita pakai dengan ekstensi `.css`.
+
+```xml
+<!-- kita harus menautkan file css itu ke laman di bagian <head>: -->
+<link rel='stylesheet' type='text/css' href='folder/namafile.css' />
+
+<!-- kita juga bisa mengetik CSS secara inline di dalam markup.
+Namun, sebisa mungkin metode ini dihindari. -->
+<style>
+ selektor { properti:nilai; }
+</style>
+
+<!-- atau langsung mengetik properti CSS pada sebuah elemen.
+Metode ini harus dihindari sebisa mungkin. -->
+<div style='properti:nilai;'>
+</div>
+
+```
+
+## Prioritas
+
+Kita tahu bahwa sebuah elemen bisa dipilih dengan lebih dari satu selektor,
+serta bisa diberi lebih dari satu properti.
+Dalam kasus seperti ini, hanya salah satu properti saja yang akan diterapkan
+pada elemen dengan prioritas tertentu.
+
+Dengan susunan CSS:
+
+```css
+
+/*A*/
+p.class1[attr='nilai']
+
+/*B*/
+p.class1 {}
+
+/*C*/
+p.class2 {}
+
+/*D*/
+p {}
+
+/*E*/
+p { properti: nilai !important; }
+
+```
+
+dan susunan markup:
+
+```xml
+<p style='/*F*/ properti:nilai;' class='class1 class2' attr='nilai'>
+</p>
+```
+
+Maka prioritas penerapan style-nya ialah sbb.:
+Ingat, penerapan ini untuk masing-masing **properti**,
+bukan keseluruhan larik.
+
+* `E` prioritas pertama sebab ada kata `!important`.
+ Dianjurkan untuk menghindari kata ini jika tidak benar-benar perlu.
+* `F` prioritas kedua sebab ia diketik secara inline.
+* `A` prioritas ketiga sebab selektor ini lebih spesifik dibanding yang lain.
+ lebih spesifik = lebih banyak unsur selektor. contoh ini punya 3 unsur:
+ 1 tagname `p` + 1 nama class `class1` + 1 attribute `attr='nilai'`
+* `C` prioritas berikutnya sebab meski sama spesifik dengan `B` namun
+ ia muncul lebih akhir.
+* Lalu `B`
+* dan terakhir baru `D`.
+
+## Kompatibilitas
+
+Sebagian besar fitur dalam CSS2 (dan lambat laun juga CSS3) kompatibel dengan
+semua peramban dan perangkat. Namun selalu vital untuk memastikan kompatibilitas
+unsur dan nilai yang kita ketikkan dalam CSS dengan peramban yang ditargetkan.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) ialah salah satu sumber terbaik untuk memeriksa kompatibilitas CSS dan peramban.
+
+## Referensi Lanjut
+
+* [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/it-it/brainfuck-it.html.markdown b/it-it/brainfuck-it.html.markdown
new file mode 100644
index 00000000..4999d7e6
--- /dev/null
+++ b/it-it/brainfuck-it.html.markdown
@@ -0,0 +1,101 @@
+---
+
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Ivan Sala", "http://slavni96.github.io/"]
+lang: it-it
+
+---
+
+Brainfuck è un linguaggio di programmazione estremamente minimale,
+ma è ingrado di rappresentare completamente una macchina di turnig,
+e sfrutta solo 8 caratteri.
+[Per saperne di più](http://it.wikipedia.org/wiki/Brainfuck)
+
+```
+
+Qualsiasi carattere che non sia "><+-.,[]" (escludendo gli apici)
+viene ignorato.
+Branfuck è caratterizzato da un array (vettore) di 30,000 celle
+inizializzare a zero, e un puntatore che punta alla cella corrente.
+
+Vi sono solo otto comando:
++ : Incrementa il valore della cella attuale di uno.
+- : Decrementa il valore della cella attuale di uno.
+> : Sposta il puntatore sulla cella seguente (prossima a destra).
+< : Sposta il puntatore sulla cella precendete (precedente a sinistra).
+. : Stampa il valore in ASCII della cella corrente. (es: 65 = 'A')
+, : Legge un singolo carattere come input per la cella corrente.
+[ : Se il valore della cella corrente è zero, conclude il ciclo
+ andando alla sua corrispondente ].
+ Altrimenti, passa alla prossima istruzione.
+] : Se il valore della cella corrente è zero, passa alla prossima istruzione.
+ Altrimenti torna indetro fino alla [ corrispondente.
+
+[ e ] creano un loop (while). Ovviamente dovranno essere bilanciati.
+Per ogni [ dovrà corrispondere una ]
+
+Alcuni semplici esempi di programmi scritti in Brainfuck:
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Questo programma stampa in output la lettera 'A'. Priam incrementa
+la cella #1 fino a 6, Quindi la cella #1 viene usata per crare un ciclo.
+Poi, entra in un loop ([) e si sposta alla cella #2.
+Incrementa la cella #2 10 volte, e torna alla cella #1, e la decrementa.
+Questo avviene 6 volte (servono che la cella #1 venga decrementata 6 volte
+per raggiungere lo 0. Quindi passa alla corrispondente ] e prosegue).
+
+A questo punto, siamo sulla cella #1, che ha valore 0,
+la cella #2 ha valore 60 (6*10). Ci spostiamo sulla cella #2, incrementiamo
+per 5 volte, e otteniamo il valore 65, quindi stampaimo il valore della cella
+#2 (.).
+65 è 'A' in ASCII, quindi alla fine viene stampata 'A'.
+
+
+, [ > + < - ] > .
+
+Questo programma legge un carattere come input dall'utente,
+quindi salva il carattere dentro la cella #1.
+In seguito, incominca a ciclare.
+Si sposta alla cella #², e increementa il valore della cella (#2).
+Quindi torna alla cella #1, e decrementa il valore della cella (#1).
+Questo continua fino a quando la cella #²1 diventa 0, e quindi la cella #2
+avrà il valore iniziale della cella #1.
+Infine, visto che ci troviamo sulla cella #1 alla fine del ciclo, si sposta
+sulla cella #2 e stampa il valore in ASCII.
+
+Gli spazi nel codice sovrastante, sono presenti solo a scopo di ottenere
+una maggiore leggibilità, si poteva anche scrivere senza:
+
+,[>+<-]>.
+
+Proviamo, adesso, a capire cosa fa invece questo programma:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Prende due numeri in input e quindi li moltiplica.
+
+Prima prende in input i due numeri (,>,<), quindi inizia un cilclo
+basandosi sulla cella #1.
+Quindi si sposta sulla cella #2, e inizia un altro ciclo condizionato
+dal valore della cella #2, incrementando la cella #3.
+Arrivati a questo punto abbiamo un problema: alla fine del ciclo interno
+la cella #2 ha valore 0. In questo caso, quando il ciclo esterno rifarà
+partire il ciclo interno, non funzionerà più perchè la cella #2 ha valore 0.
+Per ovviare a questo problema, oltre alla cella 3, incrementiamo anche la cella
+#4, e alla fine di ogni ciclo interno copiala il valore della cella #4
+nella cella #2, in modo che il ciclo interno
+possa essere eseguito una altra volta.
+Alla fine la cella #3 contiene il risultato.
+```
+
+E questo è brainfuck...Non è difficele, vero?
+Per divertimento adesso puoi scrivere i tuoi programmi in brainfuck,
+oppure puoi scrivere un interprete brainfuck in un altro linguaggio.
+L'interprete è abbastanza semplice da implementare, ma se sei veramente
+masochista prova ad implementare un interprete brainfuck in...
+brainfuck.
diff --git a/it-it/java-it.html.markdown b/it-it/java-it.html.markdown
new file mode 100644
index 00000000..6eabd61f
--- /dev/null
+++ b/it-it/java-it.html.markdown
@@ -0,0 +1,502 @@
+---
+language: java
+filename: LearnJava-it.java
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
+translators:
+ - ["Ivan Sala","http://github.com/slavni96"]
+lang: it-it
+---
+
+Java è un linguaggio di programmazione orientato ad oggetti,
+concorrente, basato su classi e adatto a svariati scopi.
+[Per saperne di più](http://docs.oracle.com/javase/tutorial/java/index.html)
+
+```java
+// I commenti su singola linea incominciano con //
+/*
+I commenti su piu' linee invece sono cosi'
+*/
+/**
+I commenti per la documentazione JavaDoc si fanno cosi'.
+Vengono usati per descrivere una classe o alcuni suoi attributi.
+*/
+
+// Per importare la classe ArrayList conenuta nel package java.util
+import java.util.ArrayList;
+// Per importare tutte le classi contenute nel package java.security
+import java.security.*;
+
+// Ogni file .java contiene una classe pubblica, con lo stesso nome del file
+public class LearnJava {
+
+ // Un programma deve avere un metodo main come punto di partenza
+ // Ma si possono creare anche file senza main, che però per essere usati
+ // devono essere richiamati da altri file.
+ public static void main (String[] args) {
+
+ // Per stampare a schermo si usa System.out.println
+ System.out.println("Ciao Mondo!");
+ System.out.println(
+ "Intero [integer]: " + 10 +
+ " Reale [double]: " + 3.14 +
+ " Booleano [boolean]: " + true);
+
+ // Se non si vuole andare a capo, si puo' usare System.out.print
+ System.out.print("Ciao ");
+ System.out.print("Mondo ");
+
+
+ ///////////////////////////////////////
+ // Tipi e Variabili
+ ///////////////////////////////////////
+ // Si dichiara una variabile usando <tipo> <nome>
+ // Byte - variabile intera da 8 bit con segno
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Short - variabile intera da 18 bit con segno
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - variabile intera da 32 bit con segno
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Long - variabile da 64 bit intera con segno
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L viene usato per specificare che il valore dalla variabile
+ // e' di tipo "Long", qualsiasi variabile che non viene contrassegnata
+ // e' trattata di base come un intero.
+
+ // Nota: Java non dispone di variabili senza segno
+
+ // Float - variabile piu' precisa, con virgola [numeri reali]
+ // di grandezza 32 bit
+ float fooFloat = 234.5f;
+ // f e' usato per specificare che la variabile e'' di tipo "float"
+ // altrimenti di default viene trattata come un "dobule"
+
+ // Double - ancora piu' precisione la si puo' ottenere con una variabile
+ // Double, con granzezza di 64 bit.
+ double fooDouble = 123.4;
+
+ // Boolean - vero & falso
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - un singolo carattere con grandezza 16 bit
+ char fooChar = 'A';
+
+ // final - Costanti, non possono essere riassegnate ad un altro oggetto
+ final int ORE_LAVORATIVE_DI_UNA_SETTIMANA = 9001;
+
+ // String - Stringhe, array di caratteri
+ String fooString = "Ecco una stringa!";
+
+ // \n e' un carattere speciale che permette di andare a capo.
+ String barString = "Andare a capo?\nNessun problema!";
+ // \t e' un carattere speciale che permette di aggiungere un 'Tab'
+ String bazString = "Vuoi inserire tab?\tNessun problema";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Vettori [array]
+ //La lunghezza del vettore deve essere decisa quando viene istanziato
+ //Si puo' dichiarare come segue:
+ //<tipodato> [] <nomevariabile> = new <tipodato>[<grandezza vettore>];
+ //<tipodato> <nomevariabile>[] = new <tipodato>[<grandezza vettore>];
+ int [] intArray = new int[10];
+ String [] stringArray = new String[1];
+ boolean boolArray [] = new boolean[100];
+
+ // Un altro modo per dichiarare & inizializzare un vettore
+ int [] y = {9000, 1000, 1337};
+ String nomi [] = {"Andrea", "Bob", "Pippo", "Susan"};
+ boolean bools[] = new boolean[] {true, false, false};
+
+ // I vettori vengono indicizzati a parire dallo 0
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // e' possibile un accesso diretto ad un elemento
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Altro da vedere:
+ // Liste di array - come i vettori ma piu' funzionali
+ // e la loro grandezza puo' variare in corso di esecuzione
+ // Liste concatenate di memoria
+
+ ///////////////////////////////////////
+ // Operatori
+ ///////////////////////////////////////
+ System.out.println("\n->Operatori");
+
+ int i1 = 1, i2 = 2; // Dichiarazone multipla in contemporanea
+
+ // L'aritmetica e' lineare.
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0
+ // (con 0.5 arrotonda per difetto)
+
+ // Modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Operatori di confronto
+ System.out.println("3 == 2? " + (3 == 2)); // => falso
+ System.out.println("3 != 2? " + (3 != 2)); // => vero
+ System.out.println("3 > 2? " + (3 > 2)); // => vero
+ System.out.println("3 < 2? " + (3 < 2)); // => falso
+ System.out.println("2 <= 2? " + (2 <= 2)); // => vero
+ System.out.println("2 >= 2? " + (2 >= 2)); // => vero
+
+ // Operatori binari orientati ai bit
+ // effettuano le operazioni logiche confrontando, i bit degli operandi:
+ /*
+ ~ complemento
+ << shift sinistro con segno
+ >> shift destro con segno
+ >>> shift destro senza segno
+ & AND Binario Bitwise AND
+ ^ OR Esclusivo
+ | OR Incusivo
+ */
+
+ // Incrementare e Decrementare
+ int i = 0;
+ System.out.println("\n->Incrementare/Decrementare");
+ // Gli operatori ++ e -- incrementano e decrementano rispettivamente di 1.
+ // Se posizionati prima della variabile, incrementano, quindi riportano.
+ // Se si trovano dopo la variabile, riporano, e quindi incrementano.
+ System.out.println(i++); //i = 1, Stampa 0 (post-incremento)
+ System.out.println(++i); //i = 2, Stampa 2 (pre-incremento)
+ System.out.println(i--); //i = 1, Stampa 2 (post-decremento)
+ System.out.println(--i); //i = 0, Stampa 0 (pre-decremento)
+
+ ///////////////////////////////////////
+ // Strutture di controllo
+ ///////////////////////////////////////
+ System.out.println("\n->Strutture di controllo");
+
+ // La dichiarazione dell'If e'' C-like.
+ int j = 10;
+ if (j == 10){
+ System.out.println("Io vengo stampato");
+ } else if (j > 10) {
+ System.out.println("Io no");
+ } else {
+ System.out.println("E io neppure");
+ }
+
+ // Struttura While
+ int fooWhile = 0;
+ while(fooWhile < 100)
+ {
+ //System.out.println(fooWhile);
+ //Incrementa il contatore
+ //Si ripete per 100 volte, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("Valore di fooWhile: " + fooWhile);
+
+ // Struttura Do While
+ int fooDoWhile = 0;
+ do
+ {
+ //System.out.println(fooDoWhile);
+ //Incrementa il contaore
+ //Si repete per 99 volte, fooDoWhile 0->99
+ fooDoWhile++;
+ }while(fooDoWhile < 100);
+ System.out.println("Valore di fooWhile: " + fooDoWhile);
+
+ // Struttura For
+ int fooFor;
+ //Struttura For => for(<Situazione iniziale>; <Condizione>; <passo>)
+ for(fooFor=0; fooFor<10; fooFor++){
+ //System.out.println(fooFor);
+ //Itera 10 volte, fooFor 0->9
+ }
+ System.out.println("Valore di fooFor: " + fooFor);
+
+ // Struttura For Each
+ // Una iterazione automatica attraverso un array o una lista di oggetti
+ int[] fooList = {1,2,3,4,5,6,7,8,9};
+ //struttura for each => for(<oggetto> : <oggetto dell'attay>)
+ //si legge: per ogni oggetto dell'array fai...
+ //Nota: il tipo dell'oggetto deve essere uguale a quello dell'array
+
+ for( int bar : fooList ){
+ //System.out.println(bar);
+ //Itera 9 volte e stampa 1-9 andando a capo.
+ }
+
+ // Struttura Switch Case
+ // La struttura switch lavora con byte, short, char e int.
+ // Se funziona con i char funzionera ovviamente anche con le stringhe.
+ int mese = 3;
+ String stringaMese;
+ switch (mese){
+ case 1:
+ stringaMese = "Genneio";
+ break;
+ case 2:
+ stringaMese = "Febbraio";
+ break;
+ case 3:
+ stringaMese = "Marzo";
+ break;
+ default:
+ stringaMese = "Altri mesi";
+ break;
+ }
+ System.out.println("Risultato del costrutto switch: " + stringaMese);
+
+ // Condizioni brevi
+ // Si puo' usare l'operatore '?' per un rapido assegnamento
+ // o per operazioni logiche.
+ // Si legge:
+ // Se (condizione) e' vera, usa <primo valore>, altrimenti usa <secondo valore>
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println("Se la condizione e' vera stampa A: "+bar);
+ // Stampa A, perche' la condizione e' vera.
+
+
+ /////////////////////////////////////////
+ // Convertire i tipi di tati e Typcasting
+ /////////////////////////////////////////
+
+ // Convertire tipi di dati
+
+ // Stringhe ad interi
+ Integer.parseInt("123");//Riporta una versione intera di "123"
+
+ // Interi a Stringhe
+ Integer.toString(123);//Riporta la stringa "123"
+ // Per altre conversioni guarda le seguenti classi
+ // Double
+ // Long
+ // String
+
+ // Typecasting
+ // Vi sono molti dettagli che non si possono spiegare qui,
+ // java dispone di una ottima documentazione
+ // Sentiti libero di leggerla
+ // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+
+ ///////////////////////////////////////
+ // Classi e funzioni
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classi & Funzioni");
+
+ // (Di seguito la definizione della classe Bicicletta)
+
+ // Instanziare una nuova classe
+ Bicicletta percorso = new Bicicletta();
+
+ // Chiamare metodi
+ percorso.accellera(3); // Si usano sempre metodi set... get...
+ percorso.setCadenza(100);
+
+ // toString riporta la rappresenzazione dell'oggetto
+ // come se fosse una stringa
+ System.out.println("percorso info: " + percorso.toString());
+
+ } // Fine metodo main
+} // Fine classe LearnJava
+
+
+// Si possono inculdere altre anche delle classi non pubbliche (private)
+// oltre a quella pubblica principale, in un file .java
+
+// Sintassi per dichiarare una classe:
+// <public/private/protected> class <Nome classe>{
+// //dati, variabili, costruttori, funzioni, tutto qua.
+// //le funzioni sono chiamate come i metodi.
+// }
+
+class Bicicletta {
+
+ // Variabili della bicicletta
+ public int cadenza;
+ // Public: Puo' essere richiamato da qualsiasi classe
+ private int velocita;
+ // Private: e'' accessibile solo dalla classe dove e'' stato inizializzato
+ protected int ingranaggi;
+ // Protected: e'' visto sia dalla classe che dalle sottoclassi
+ String nome;
+ // default: e'' accessibile sono all'interno dello stesso package
+
+ // I costruttori vengono usati per creare variabili
+ // Questo e'' un costruttore
+ public Bicicletta() {
+ ingranaggi = 1;
+ cadenza = 50;
+ velocita = 5;
+ nome = "Bontrager";
+ }
+
+ // Questo e'' un costruttore che richiede parametri
+ public Bicicletta(int cadenza, int velocita, int ingranaggi, String nome) {
+ this.ingranaggi = ingranaggi;
+ this.cadenza = cadenza;
+ this.velocita = velocita;
+ this.nome = nome;
+ }
+
+ // Sintassi delle funzioni:
+ // <public/private/protected> <tipo di ritorino> <nome della funzione>(<parametri>)
+
+ // Le classi in java spesso implementano delle funzioni o metodo
+ // 'get...' o 'set...'
+
+ // Dichiarazione di un metodo
+ // <scope> <tipo di ritorno> <nome del metodo>(<parametri>)
+ public int getCandenza() {
+ return cadenza;
+ }
+
+ // i medodi (void) non necessitano di riportare un valore
+ public void setCadenza(int nuovoValore) {
+ cadenza = nuovoValore;
+ }
+
+ public void setIngranaggi(int nuovoValore) {
+ ingranaggi = nuovoValore;
+ }
+
+ public void accellera(int incrementa) {
+ velocita += incrementa;
+ }
+
+ public void decellera(int decrementa) {
+ velocita -= decrementa;
+ }
+
+ public void setNome(String nuovoNome) {
+ nome = nuovoNome;
+ }
+
+ public String getNome() {
+ return nome;
+ }
+
+ //Medoto per visualizzare gli attributi dell'oggetto
+ @Override
+ public String toString() {
+ return "Ingranaggi: " + ingranaggi +
+ " Cadenza: " + cadenza +
+ " Velocita: " + velocita +
+ " Nome: " + nome;
+ }
+} // Fine classe bicicletta
+
+// PennyFarthing e'' una sottoclasse della bicicletta
+class PennyFarthing extends Bicicletta {
+ // (Sono quelle biciclette con un unica ruota enorme
+ // Non hanno ingranaggi.)
+
+ public PennyFarthing(int cadenzaIniziale, int velocitaIniziale){
+ // Richiamo il costruttore del padre con super
+ super(cadenzaIniziale, velocitaIniziale, 0, "PennyFarthing");
+ }
+
+ // Bisogna contrassegnre un medodo che si sta riscrivendo
+ // con una @annotazione
+ // Per saperne di piu' sulle annotazioni
+ // Vedi la guida: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setIngranaggi(int ingranaggi) {
+ ingranaggi = 0;
+ }
+
+}
+/*
+//Interfacce
+//Sintassi per dichiarare una interfaccia
+//<livello di accesso> interface <nome dell'interfaccia> extends <super-interfaccia> {
+// //Costanti
+// //Dichiarazioni dei metodi
+//}
+
+//Esempi- Cibo:
+interface Commestibile {
+ public void mangia();
+ //Ogni classe che implementa questa interfaccia
+ //deve implementare questo metodo.
+ }
+interface Digeribile {
+ public void digerisci();
+}
+
+//Possiamo quindi creare una classe che implementa entrambe le interfaccie
+class Frutta implements Commestibile, Digestibile {
+ public void mangia() {
+ //...
+ }
+
+ public void digerisci() {
+ //...
+ }
+}
+
+//In Java si puo' estendere solo una classe, ma si possono implementare
+//piu' interfaccie, per esempio:
+class ClasseEsempio extends AltraClasse implements PrimaInterfaccia, SecondaInterfaccia {
+ public void MetodoPrimaInterfaccia() {
+
+ }
+
+ public void MetodoSecondaInterfaccia() {
+
+ }
+}
+*/
+```
+## Letture future
+
+I link di seguito sono solo per capire l'argomento, cerca pure su Google degli esempi specifici
+
+
+**Guida ufficiale di Oracle [solo in inglese]**:
+
+* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
+
+* [Java Access level modifiers](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Object-Oriented Programming Concepts](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Exceptions](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html)
+
+
+**Tutorial Online [in inglese]**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+
+**Libri [in italiano]** :
+
+* [Java la guida completa](http://www.amazon.it/Java-guida-completa-Herbert-Schildt/dp/8838667667/ref=sr_1_1?ie=UTF8&qid=1393422296&sr=8-1&keywords=java)
+
+* [Thinking in java](http://www.amazon.it/Thinking-Java-1-Bruce-Eckel/dp/8871923030/ref=sr_1_8?ie=UTF8&qid=1393422296&sr=8-8&keywords=java)
+
+* [Manuale di Java 7](http://www.amazon.com/gp/product/0071606300)
diff --git a/java.html.markdown b/java.html.markdown
index b4531635..50875491 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -3,6 +3,7 @@
language: java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
filename: LearnJava.java
---
@@ -25,7 +26,8 @@ import java.util.ArrayList;
// Import all classes inside of java.security package
import java.security.*;
-// Each .java file contains one public class, with the same name as the file.
+// Each .java file contains one outer-level public class, with the same name as
+// the file.
public class LearnJava {
// A program must have a main method as an entry point
@@ -83,7 +85,7 @@ public class LearnJava {
// Char - A single 16-bit Unicode character
char fooChar = 'A';
- // Use final to make a variable immutable
+ // final variables can't be reassigned to another object
final int HOURS_I_WORK_PER_WEEK = 9001;
// Strings
@@ -98,15 +100,18 @@ public class LearnJava {
System.out.println(bazString);
// Arrays
- //The array size must be decided upon declaration
- //The format for declaring an array is follows:
+ //The array size must be decided upon instantiation
+ //The following formats work for declaring an arrow
//<datatype> [] <var name> = new <datatype>[<array size>];
+ //<datetype> <var name>[] = new <datatype>[<array size>];
int [] intArray = new int[10];
String [] stringArray = new String[1];
- boolean [] booleanArray = new boolean[100];
+ boolean boolArray [] = new boolean[100];
// Another way to declare & initialize an array
int [] y = {9000, 1000, 1337};
+ String names [] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = new boolean[] {true, false, false};
// Indexing an array - Accessing an element
System.out.println("intArray @ 0: " + intArray[0]);
@@ -160,10 +165,13 @@ public class LearnJava {
// Incrementations
int i = 0;
System.out.println("\n->Inc/Dec-rementation");
- System.out.println(i++); //i = 1. Post-Incrementation
- System.out.println(++i); //i = 2. Pre-Incrementation
- System.out.println(i--); //i = 1. Post-Decrementation
- System.out.println(--i); //i = 0. Pre-Decrementation
+ // The ++ and -- operators increment and decrement by 1 respectively.
+ // If they are placed before the variable, they increment then return;
+ // after the variable they return then increment.
+ System.out.println(i++); //i = 1, prints 0 (post-increment)
+ System.out.println(++i); //i = 2, prints 2 (pre-increment)
+ System.out.println(i--); //i = 1, prints 2 (post-decrement)
+ System.out.println(--i); //i = 0, prints 0 (pre-decrement)
///////////////////////////////////////
// Control Structures
@@ -186,7 +194,7 @@ public class LearnJava {
{
//System.out.println(fooWhile);
//Increment the counter
- //Iterated 99 times, fooWhile 0->99
+ //Iterated 100 times, fooWhile 0,1,2...99
fooWhile++;
}
System.out.println("fooWhile Value: " + fooWhile);
@@ -211,6 +219,18 @@ public class LearnJava {
}
System.out.println("fooFor Value: " + fooFor);
+ // For Each Loop
+ // An automatic iteration through an array or list of objects.
+ int[] fooList = {1,2,3,4,5,6,7,8,9};
+ //for each loop structure => for(<object> : <array_object>)
+ //reads as: for each object in the array
+ //note: the object type must match the array.
+
+ for( int bar : fooList ){
+ //System.out.println(bar);
+ //Iterates 9 times and prints 1-9 on new lines
+ }
+
// Switch Case
// A switch works with the byte, short, char, and int data types.
// It also works with enumerated types (discussed in Enum Types),
@@ -234,6 +254,13 @@ public class LearnJava {
}
System.out.println("Switch Case Result: " + monthString);
+ // Conditional Shorthand
+ // You can use the '?' operator for quick assignments or logic forks.
+ // Reads as "If (statement) is true, use <first value>, otherwise, use <second value>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println(bar); // Prints A, because the statement is true
+
///////////////////////////////////////
// Converting Data Types And Typcasting
@@ -274,14 +301,14 @@ public class LearnJava {
trek.speedUp(3); // You should always use setter and getter methods
trek.setCadence(100);
- // toString is a convention to display the value of this Object.
+ // toString returns this Object's string representation.
System.out.println("trek info: " + trek.toString());
} // End main method
} // End LearnJava class
-// You can include other, non-public classes in a .java file
+// You can include other, non-public outer-level classes in a .java file
// Class Declaration Syntax:
@@ -299,7 +326,7 @@ class Bicycle {
String name; // default: Only accessible from within this package
// Constructors are a way of creating classes
- // This is a default constructor
+ // This is a constructor
public Bicycle() {
gear = 1;
cadence = 50;
@@ -307,7 +334,7 @@ class Bicycle {
name = "Bontrager";
}
- // This is a specified constructor (it contains arguments)
+ // This is a constructor that takes arguments
public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
this.gear = startGear;
this.cadence = startCadence;
@@ -381,13 +408,53 @@ class PennyFarthing extends Bicycle {
}
+//Interfaces
+//Interface declaration syntax
+//<access-level> interface <interface-name> extends <super-interfaces> {
+// //Constants
+// //Method declarations
+//}
+
+//Example - Food:
+public interface Edible {
+ public void eat(); //Any class that implements this interface, must implement this method
+}
+
+public interface Digestible {
+ public void digest();
+}
+
+
+//We can now create a class that implements both of these interfaces
+public class Fruit implements Edible, Digestible {
+ public void eat() {
+ //...
+ }
+
+ public void digest() {
+ //...
+ }
+}
+
+//In java, you can extend only one class, but you can implement many interfaces.
+//For example:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo {
+ public void InterfaceOneMethod() {
+
+ }
+
+ public void InterfaceTwoMethod() {
+
+ }
+}
+
```
## Further Reading
The links provided here below are just to get an understanding of the topic, feel free to Google and find specific examples.
-Other Topics To Research:
+**Official Oracle Guides**:
* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
@@ -405,3 +472,20 @@ Other Topics To Research:
* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html)
+
+**Online Practice and Tutorials**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+
+**Books**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300)
+
+
diff --git a/javascript.html.markdown b/javascript.html.markdown
index cc279b9a..76017c17 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -1,10 +1,12 @@
---
language: javascript
-author: Adam Brenecki
-author_url: http://adam.brenecki.id.au
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+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
@@ -30,161 +32,179 @@ doStuff();
// wherever there's a newline, except in certain cases.
doStuff()
-// We'll leave semicolons off here; whether you do or not will depend on your
-// personal preference or your project's style guide.
+// Because those cases can cause unexpected results, we'll keep on using
+// semicolons in this guide.
///////////////////////////////////
// 1. Numbers, Strings and Operators
-// Javascript has one number type (which is a 64-bit IEEE 754 double).
-3 // = 3
-1.5 // = 1.5
+// 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
+1.5; // = 1.5
// All the basic arithmetic works as you'd expect.
-1 + 1 // = 2
-8 - 1 // = 7
-10 * 2 // = 20
-35 / 5 // = 7
+1 + 1; // = 2
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
// Including uneven division.
-5 / 2 // = 2.5
+5 / 2; // = 2.5
// Bitwise operations also work; when you perform a bitwise operation your float
// is converted to a signed int *up to* 32 bits.
-1 << 2 // = 4
+1 << 2; // = 4
// Precedence is enforced with parentheses.
-(1 + 3) * 2 // = 8
+(1 + 3) * 2; // = 8
// There are three special not-a-real-number values:
-Infinity // result of e.g. 1/0
--Infinity // result of e.g. -1/0
-NaN // result of e.g. 0/0
+Infinity; // result of e.g. 1/0
+-Infinity; // result of e.g. -1/0
+NaN; // result of e.g. 0/0
// There's also a boolean type.
-true
-false
+true;
+false;
// Strings are created with ' or ".
-'abc'
-"Hello, world"
+'abc';
+"Hello, world";
// Negation uses the ! symbol
-!true // = false
-!false // = true
+!true; // = false
+!false; // = true
// Equality is ==
-1 == 1 // = true
-2 == 1 // = false
+1 == 1; // = true
+2 == 1; // = false
// Inequality is !=
-1 != 1 // = false
-2 != 1 // = true
+1 != 1; // = false
+2 != 1; // = true
// More comparisons
-1 < 10 // = true
-1 > 10 // = false
-2 <= 2 // = true
-2 >= 2 // = true
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
// Strings are concatenated with +
-"Hello " + "world!" // = "Hello world!"
+"Hello " + "world!"; // = "Hello world!"
// and are compared with < and >
-"a" < "b" // = true
+"a" < "b"; // = true
// Type coercion is performed for comparisons...
-"5" == 5 // = true
+"5" == 5; // = true
// ...unless you use ===
-"5" === 5 // = false
+"5" === 5; // = false
// You can access characters in a string with charAt
-"This is a string".charAt(0)
+"This is a string".charAt(0); // = 'T'
+
+// ...or use substring to get larger pieces
+"Hello world".substring(0, 5); // = "Hello"
+
+// length is a property, so don't use ()
+"Hello".length; // = 5
// There's also null and undefined
-null // used to indicate a deliberate non-value
-undefined // used to indicate a value that hasn't been set yet
+null; // used to indicate a deliberate non-value
+undefined; // used to indicate a value is not currently present (although
+ // undefined is actually a value itself)
-// null, undefined, NaN, 0 and "" are falsy, and everything else is truthy.
+// false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy.
// Note that 0 is falsy and "0" is truthy, even though 0 == "0".
///////////////////////////////////
// 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
+var someVar = 5;
// if you leave the var keyword off, you won't get an error...
-someOtherVar = 10
+someOtherVar = 10;
// ...but your variable will be created in the global scope, not in the scope
// you defined it in.
// Variables declared without being assigned to are set to undefined.
-var someThirdVar // = undefined
+var someThirdVar; // = undefined
// There's shorthand for performing math operations on variables:
-someVar += 5 // equivalent to someVar = someVar + 5; someVar is 10 now
-someVar *= 10 // now someVar is 100
+someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now
+someVar *= 10; // now someVar is 100
// and an even-shorter-hand for adding or subtracting 1
-someVar++ // now someVar is 101
-someVar-- // back to 100
+someVar++; // now someVar is 101
+someVar--; // back to 100
// Arrays are ordered lists of values, of any type.
-var myArray = ["Hello", 45, true]
+var myArray = ["Hello", 45, true];
// Their members can be accessed using the square-brackets subscript syntax.
// Array indices start at zero.
-myArray[1] // = 45
+myArray[1]; // = 45
+
+// Arrays are mutable and of variable length.
+myArray.push("World");
+myArray.length; // = 4
+
+// Add/Modify at specific index
+myArray[3] = "Hello";
// JavaScript's objects are equivalent to 'dictionaries' or 'maps' in other
// languages: an unordered collection of key-value pairs.
-{key1: "Hello", key2: "World"}
+var myObj = {key1: "Hello", key2: "World"};
// Keys are strings, but quotes aren't required if they're a valid
// JavaScript identifier. Values can be any type.
-var myObj = {myKey: "myValue", "my other key": 4}
+var myObj = {myKey: "myValue", "my other key": 4};
// Object attributes can also be accessed using the subscript syntax,
-myObj["my other key"] // = 4
+myObj["my other key"]; // = 4
// ... or using the dot syntax, provided the key is a valid identifier.
-myObj.myKey // = "myValue"
+myObj.myKey; // = "myValue"
// Objects are mutable; values can be changed and new keys added.
-myObj.myThirdKey = true
+myObj.myThirdKey = true;
// If you try to access a value that's not yet set, you'll get undefined.
-myObj.myFourthKey // = undefined
+myObj.myFourthKey; // = undefined
///////////////////////////////////
// 3. Logic and Control Structures
+// The syntax for this section is almost identical to Java's.
+
// The if structure works as you'd expect.
-var count = 1
+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!
}
// Do-while loops are like while loops, except they always run at least once.
var input
do {
- input = getInput()
+ input = getInput();
} while (!isValid(input))
-// the for loop is the same as C and Java:
+// the for loop is the same as C and Java:
// initialisation; continue condition; iteration.
for (var i = 0; i < 5; i++){
// will run 5 times
@@ -192,29 +212,56 @@ for (var i = 0; i < 5; i++){
// && is logical and, || is logical or
if (house.size == "big" && house.colour == "blue"){
- house.contains = "bear"
+ house.contains = "bear";
}
if (colour == "red" || colour == "blue"){
// colour is either red or blue
}
// && and || "short circuit", which is useful for setting default values.
-var name = otherName || "default"
+var name = otherName || "default";
+
+
+// switch statement checks for equality with ===
+// use 'break' after each case
+// or the cases after the correct one will be executed too.
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
+
///////////////////////////////////
// 4. Functions, Scope and Closures
// JavaScript functions are declared with the function keyword.
function myFunction(thing){
- return thing.toUpperCase()
+ return thing.toUpperCase();
}
-myFunction("foo") // = "FOO"
-
-// Functions can also be defined "anonymously" - without a name:
-function(thing){
- return thing.toLowerCase()
+myFunction("foo"); // = "FOO"
+
+// Note that the value to be returned must start on the same line as the
+// 'return' keyword, otherwise you'll always return 'undefined' due to
+// automatic semicolon insertion. Watch out for this when using Allman style.
+function myFunction()
+{
+ return // <- semicolon automatically inserted here
+ {
+ thisIsAn: 'object literal'
+ }
}
-// (we can't call our function, since we don't have a name to refer to it with)
+myFunction(); // = undefined
// JavaScript functions are first class objects, so they can be reassigned to
// different variable names and passed to other functions as arguments - for
@@ -222,52 +269,53 @@ function(thing){
function myFunction(){
// this code will be called in 5 seconds' time
}
-setTimeout(myFunction, 5000)
-
-// You can even write the function statement directly in the call to the other
-// function.
+setTimeout(myFunction, 5000);
+// Note: setTimeout isn't part of the JS language, but is provided by browsers
+// and Node.js.
-setTimeout(function myFunction(){
+// Function objects don't even have to be declared with a name - you can write
+// an anonymous function definition directly into the arguments of another.
+setTimeout(function(){
// this code will be called in 5 seconds' time
-}, 5000)
+}, 5000);
// JavaScript has function scope; functions get their own scope but other blocks
// do not.
if (true){
- var i = 5
+ var i = 5;
}
-i // = 5 - not undefined as you'd expect in a block-scoped language
+i; // = 5 - not undefined as you'd expect in a block-scoped language
// This has led to a common pattern of "immediately-executing anonymous
// functions", which prevent temporary variables from leaking into the global
// scope.
(function(){
- var temporary = 5
+ var temporary = 5;
// We can access the global scope by assiging to the 'global object', which
// in a web browser is always 'window'. The global object may have a
// different name in non-browser environments such as Node.js.
- window.permanent = 10
- // Or, as previously mentioned, we can just leave the var keyword off.
- permanent2 = 15
-})()
-temporary // raises ReferenceError
-permanent // = 10
-permanent2 // = 15
+ window.permanent = 10;
+})();
+temporary; // raises ReferenceError
+permanent; // = 10
// One of JavaScript's most powerful features is closures. If a function is
// defined inside another function, the inner function has access to all the
-// outer function's variables.
+// outer function's variables, even after the outer function exits.
function sayHelloInFiveSeconds(name){
- var prompt = "Hello, " + name + "!"
+ var prompt = "Hello, " + name + "!";
+ // Inner functions are put in the local scope by default, as if they were
+ // declared with 'var'.
function inner(){
- alert(prompt)
+ alert(prompt);
}
- setTimeout(inner, 5000)
- // setTimeout is asynchronous, so this function will finish without waiting
- // 5 seconds. However, once the 5 seconds is up, inner will still have
- // access to the value of prompt.
+ setTimeout(inner, 5000);
+ // setTimeout is asynchronous, so the sayHelloInFiveSeconds function will
+ // exit immediately, and setTimeout will call inner afterwards. However,
+ // because inner is "closed over" sayHelloInFiveSeconds, inner still has
+ // access to the 'prompt' variable when it is finally called.
}
-sayHelloInFiveSeconds("Adam") // will open a popup with "Hello, Adam!" in 5s
+sayHelloInFiveSeconds("Adam"); // will open a popup with "Hello, Adam!" in 5s
///////////////////////////////////
// 5. More about Objects; Constructors and Prototypes
@@ -275,44 +323,75 @@ sayHelloInFiveSeconds("Adam") // will open a popup with "Hello, Adam!" in 5s
// Objects can contain functions.
var myObj = {
myFunc: function(){
- return "Hello world!"
+ return "Hello world!";
}
-}
-myObj.myFunc() // = "Hello world!"
+};
+myObj.myFunc(); // = "Hello world!"
// When functions attached to an object are called, they can access the object
// they're attached to using the this keyword.
myObj = {
myString: "Hello world!",
myFunc: function(){
- return this.myString
+ return this.myString;
}
-}
-myObj.myFunc() // = "Hello world!"
+};
+myObj.myFunc(); // = "Hello world!"
// What this is set to has to do with how the function is called, not where
// it's defined. So, our function doesn't work if it isn't called in the
// context of the object.
-var myFunc = myObj.myFunc
-myFunc() // = undefined
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
// Inversely, a function can be assigned to the object and gain access to it
// through this, even if it wasn't attached when it was defined.
var myOtherFunc = function(){
- return this.myString.toUpperCase()
+ return this.myString.toUpperCase();
}
-myObj.myOtherFunc = myOtherFunc
-myObj.myOtherFunc() // = "HELLO WORLD!"
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// We can also specify a context for a function to execute in when we invoke it
+// using 'call' or 'apply'.
+
+var anotherFunc = function(s){
+ return this.myString + 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.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// This is useful when working with a function that accepts a sequence of arguments
+// and you want to pass an array.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// But, 'call' and 'apply' are only temporary. When we want it to stick, we can use
+// bind.
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// Bind can also be used to partially apply (curry) a function.
+
+var product = function(a, b){ return a * b; }
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
// When you call a function with the new keyword, a new object is created, and
-// made available to the function via this. Functions designed to be called
-// like this are called constructors.
+// made available to the function via the this keyword. Functions designed to be
+// called like that are called constructors.
var MyConstructor = function(){
- this.myNumber = 5
+ this.myNumber = 5;
}
-myNewObj = new MyConstructor() // = {myNumber: 5}
-myNewObj.myNumber // = 5
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
// Every JavaScript object has a 'prototype'. When you go to access a property
// on an object that doesn't exist on the actual object, the interpreter will
@@ -322,64 +401,68 @@ myNewObj.myNumber // = 5
// property __proto__. While this is useful for explaining prototypes it's not
// part of the standard; we'll get to standard ways of using prototypes later.
var myObj = {
- myString: "Hello world!",
-}
+ myString: "Hello world!"
+};
var myPrototype = {
meaningOfLife: 42,
myFunc: function(){
return this.myString.toLowerCase()
}
-}
-myObj.__proto__ = myPrototype
-myObj.meaningOfLife // = 42
+};
+
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
// This works for functions, too.
-myObj.myFunc() // = "hello world!"
+myObj.myFunc(); // = "hello world!"
// Of course, if your property isn't on your prototype, the prototype's
// prototype is searched, and so on.
myPrototype.__proto__ = {
myBoolean: true
-}
-myObj.myBoolean // = true
+};
+myObj.myBoolean; // = true
// There's no copying involved here; each object stores a reference to its
// prototype. This means we can alter the prototype and our changes will be
// reflected everywhere.
-myPrototype.meaningOfLife = 43
-myObj.meaningOfLife // = 43
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
// We mentioned that __proto__ was non-standard, and there's no standard way to
-// change the prototype of an existing object. However, there's two ways to
+// change the prototype of an existing object. However, there are two ways to
// create a new object with a given prototype.
// The first is Object.create, which is a recent addition to JS, and therefore
// not available in all implementations yet.
-var myObj = Object.create(myPrototype)
-myObj.meaningOfLife // = 43
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
// The second way, which works anywhere, has to do with constructors.
// Constructors have a property called prototype. This is *not* the prototype of
// the constructor function itself; instead, it's the prototype that new objects
// are given when they're created with that constructor and the new keyword.
-myConstructor.prototype = {
+MyConstructor.prototype = {
+ myNumber: 5,
getMyNumber: function(){
- return this.myNumber
+ return this.myNumber;
}
-}
-var myNewObj2 = new myConstructor()
-myNewObj2.getMyNumber() // = 5
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6
+myNewObj2.getMyNumber(); // = 6
// Built-in types like strings and numbers also have constructors that create
// equivalent wrapper objects.
-var myNumber = 12
-var myNumberObj = new Number(12)
-myNumber == myNumberObj // = true
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
// Except, they aren't exactly equivalent.
-typeof(myNumber) // = 'number'
-typeof(myNumberObj) // = 'object'
-myNumber === myNumberObj // = false
+typeof(myNumber); // = 'number'
+typeof(myNumberObj); // = 'object'
+myNumber === myNumberObj; // = false
if (0){
// This code won't execute, because 0 is falsy.
}
@@ -390,9 +473,9 @@ if (Number(0)){
// However, the wrapper objects and the regular builtins share a prototype, so
// you can actually add functionality to a string, for instance.
String.prototype.firstCharacter = function(){
- return this.charAt(0)
+ return this.charAt(0);
}
-"abc".firstCharacter() // = "a"
+"abc".firstCharacter(); // = "a"
// This fact is often used in "polyfilling", which is implementing newer
// features of JavaScript in an older subset of JavaScript, so that they can be
@@ -403,10 +486,10 @@ String.prototype.firstCharacter = function(){
if (Object.create === undefined){ // don't overwrite it if it exists
Object.create = function(proto){
// make a temporary constructor with the right prototype
- var Constructor = function(){}
- Constructor.prototype = proto
+ var Constructor = function(){};
+ Constructor.prototype = proto;
// then use it to create a new, appropriately-prototyped object
- return new Constructor()
+ return new Constructor();
}
}
```
@@ -427,9 +510,13 @@ 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
+[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) is a variant of this reference with built-in challenges.
+
+[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
guide of all the counter-intuitive parts of the language.
+[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) is a classic guide / reference book.
+
In addition to direct contributors to this article, some content is adapted
from Louie Dinh's Python tutorial on this site, and the [JS
Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
diff --git a/json.html.markdown b/json.html.markdown
new file mode 100644
index 00000000..f86f0ae9
--- /dev/null
+++ b/json.html.markdown
@@ -0,0 +1,48 @@
+---
+language: json
+filename: learnjson.json
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+---
+
+As JSON is an extremely simple data-interchange format, this is most likely going
+to be the simplest Learn X in Y Minutes ever.
+
+JSON in its purest form has no actual comments, but most parsers will accept
+C-style (//, /\* \*/) comments. For the purposes of this, however, everything is
+going to be 100% valid JSON. Luckily, it kind of speaks for itself.
+
+```json
+{
+ "numbers": 0,
+ "strings": "Hellø, wørld. All unicode is allowed, along with \"escaping\".",
+ "has bools?": true,
+ "nothingness": null,
+
+ "big number": 1.2e+100,
+
+ "objects": {
+ "comment": "Most of your structure will come from objects.",
+
+ "array": [0, 1, 2, 3, "Arrays can have anything in them.", 5],
+
+ "another object": {
+ "comment": "These things can be nested, very useful."
+ }
+ },
+
+ "silliness": [
+ {
+ "sources of potassium": ["bananas"]
+ },
+ [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, "neo"],
+ [0, 0, 0, 1]
+ ]
+ ],
+
+ "that was short": "And, you're done. You know know everything JSON has to offer."
+}
+```
diff --git a/julia.html.markdown b/julia.html.markdown
index 1023e303..15b4be90 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -8,11 +8,15 @@ filename: learnjulia.jl
Julia is a new homoiconic functional language focused on technical computing.
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
-This is based on the current development version of Julia, as of June 29th, 2013.
+This is based on the current development version of Julia, as of October 18th, 2013.
```ruby
-# Single line comments start with a hash.
+# Single line comments start with a number symbol.
+#= Multiline comments can be written
+ by putting '#=' before the text and '=#'
+ after the text. They can also be nested.
+=#
####################################################
## 1. Primitive Datatypes and Operators
@@ -20,100 +24,104 @@ This is based on the current development version of Julia, as of June 29th, 2013
# Everything in Julia is a expression.
-# You have numbers
-3 #=> 3 (Int64)
-3.2 #=> 3.2 (Float64)
-2 + 1im #=> 2 + 1im (Complex{Int64})
-2//3 #=> 2//3 (Rational{Int64})
-
-# Math is what you would expect
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7.0
-5 \ 35 #=> 7.0
-5 / 2 #=> 2.5
-div(5, 2) #=> 2
-2 ^ 2 #=> 4 # power, not bitwise xor
-12 % 10 #=> 2
+# There are several basic types of numbers.
+3 # => 3 (Int64)
+3.2 # => 3.2 (Float64)
+2 + 1im # => 2 + 1im (Complex{Int64})
+2//3 # => 2//3 (Rational{Int64})
+
+# All of the normal infix operators are available.
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+5 / 2 # => 2.5 # dividing an Int by an Int always results in a Float
+div(5, 2) # => 2 # for a truncated result, use div
+5 \ 35 # => 7.0
+2 ^ 2 # => 4 # power, not bitwise xor
+12 % 10 # => 2
# Enforce precedence with parentheses
-(1 + 3) * 2 #=> 8
+(1 + 3) * 2 # => 8
# Bitwise Operators
-~2 #=> -3 # bitwise not
-3 & 5 #=> 1 # bitwise and
-2 | 4 #=> 6 # bitwise or
-2 $ 4 #=> 6 # bitwise xor
-2 >>> 1 #=> 1 # logical shift right
-2 >> 1 #=> 1 # arithmetic shift right
-2 << 1 #=> 4 # logical/arithmetic shift left
+~2 # => -3 # bitwise not
+3 & 5 # => 1 # bitwise and
+2 | 4 # => 6 # bitwise or
+2 $ 4 # => 6 # bitwise xor
+2 >>> 1 # => 1 # logical shift right
+2 >> 1 # => 1 # arithmetic shift right
+2 << 1 # => 4 # logical/arithmetic shift left
# You can use the bits function to see the binary representation of a number.
bits(12345)
-#=> "0000000000000000000000000000000000000000000000000011000000111001"
+# => "0000000000000000000000000000000000000000000000000011000000111001"
bits(12345.0)
-#=> "0100000011001000000111001000000000000000000000000000000000000000"
+# => "0100000011001000000111001000000000000000000000000000000000000000"
# Boolean values are primitives
true
false
# Boolean operators
-!true #=> false
-!false #=> true
-1 == 1 #=> true
-2 == 1 #=> false
-1 != 1 #=> false
-2 != 1 #=> true
-1 < 10 #=> true
-1 > 10 #=> false
-2 <= 2 #=> true
-2 >= 2 #=> true
+!true # => false
+!false # => true
+1 == 1 # => true
+2 == 1 # => false
+1 != 1 # => false
+2 != 1 # => true
+1 < 10 # => true
+1 > 10 # => false
+2 <= 2 # => true
+2 >= 2 # => true
# Comparisons can be chained
-1 < 2 < 3 #=> true
-2 < 3 < 2 #=> false
+1 < 2 < 3 # => true
+2 < 3 < 2 # => false
# Strings are created with "
"This is a string."
-# Character literals written with '
+# Character literals are written with '
'a'
-# A string can be treated like a list of characters
-"This is a string"[1] #=> 'T' # Julia indexes from 1
+# A string can be indexed like an array of characters
+"This is a string"[1] # => 'T' # Julia indexes from 1
+# However, this is will not work well for UTF8 strings,
+# so iterating over strings is recommended (map, for loops, etc).
# $ can be used for string interpolation:
-"2 + 2 = $(2 + 2)" #=> "2 + 2 = 4"
+"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# You can put any Julia expression inside the parenthesis.
# Another way to format strings is the printf macro.
@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
+# Printing is easy
+println("I'm Julia. Nice to meet you!")
+
####################################################
## 2. Variables and Collections
####################################################
-# Printing is pretty easy
-println("I'm Julia. Nice to meet you!")
-
-# No need to declare variables before assigning to them.
-some_var = 5 #=> 5
-some_var #=> 5
+# You don't declare variables before assigning to them.
+some_var = 5 # => 5
+some_var # => 5
# Accessing a previously unassigned variable is an error
try
- some_other_var #=> ERROR: some_other_var not defined
+ some_other_var # => ERROR: some_other_var not defined
catch e
println(e)
end
-# Variable name start with a letter. You can use uppercase letters, digits,
-# and exclamation points as well after the initial alphabetic character.
-SomeOtherVar123! = 6 #=> 6
+# Variable names start with a letter.
+# After that, you can use letters, digits, underscores, and exclamation points.
+SomeOtherVar123! = 6 # => 6
# You can also use unicode characters
-☃ = 8 #=> 8
+☃ = 8 # => 8
+# These are especially handy for mathematical notation
+2 * π # => 6.283185307179586
# A note on naming conventions in Julia:
#
@@ -129,45 +137,49 @@ SomeOtherVar123! = 6 #=> 6
# functions are sometimes called mutating functions or in-place functions.
# Arrays store a sequence of values indexed by integers 1 through n:
-a = Int64[] #=> 0-element Int64 Array
+a = Int64[] # => 0-element Int64 Array
# 1-dimensional array literals can be written with comma-separated values.
-b = [4, 5, 6] #=> 3-element Int64 Array: [4, 5, 6]
-b[1] #=> 4
-b[end] #=> 6
+b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
+b[1] # => 4
+b[end] # => 6
# 2-dimentional arrays use space-separated values and semicolon-separated rows.
-matrix = [1 2; 3 4] #=> 2x2 Int64 Array: [1 2; 3 4]
+matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
# Add stuff to the end of a list with push! and append!
-push!(a,1) #=> [1]
-push!(a,2) #=> [1,2]
-push!(a,4) #=> [1,2,4]
-push!(a,3) #=> [1,2,4,3]
-append!(a,b) #=> [1,2,4,3,4,5,6]
+push!(a,1) # => [1]
+push!(a,2) # => [1,2]
+push!(a,4) # => [1,2,4]
+push!(a,3) # => [1,2,4,3]
+append!(a,b) # => [1,2,4,3,4,5,6]
# Remove from the end with pop
-pop!(a) #=> 6 and b is now [4,5]
+pop!(b) # => 6 and b is now [4,5]
# Let's put it back
push!(b,6) # b is now [4,5,6] again.
-a[1] #=> 1 # remember that Julia indexes from 1, not 0!
+a[1] # => 1 # remember that Julia indexes from 1, not 0!
# end is a shorthand for the last index. It can be used in any
# indexing expression
-a[end] #=> 6
+a[end] # => 6
+
+# we also have shift and unshift
+shift!(a) # => 1 and a is now [2,4,3,4,5,6]
+unshift!(a,7) # => [7,2,4,3,4,5,6]
# Function names that end in exclamations points indicate that they modify
# their argument.
-arr = [5,4,6] #=> 3-element Int64 Array: [5,4,6]
-sort(arr) #=> [4,5,6]; arr is still [5,4,6]
-sort!(arr) #=> [4,5,6]; arr is now [4,5,6]
+arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
+sort(arr) # => [4,5,6]; arr is still [5,4,6]
+sort!(arr) # => [4,5,6]; arr is now [4,5,6]
# Looking out of bounds is a BoundsError
try
- a[0] #=> ERROR: BoundsError() in getindex at array.jl:270
- a[end+1] #=> ERROR: BoundsError() in getindex at array.jl:270
+ a[0] # => ERROR: BoundsError() in getindex at array.jl:270
+ a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
catch e
println(e)
end
@@ -177,105 +189,109 @@ end
# inside the julia folder to find these files.
# You can initialize arrays from ranges
-a = [1:5] #=> 5-element Int64 Array: [1,2,3,4,5]
+a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
# You can look at ranges with slice syntax.
-a[1:3] #=> [1, 2, 3]
-a[2:] #=> [2, 3, 4, 5]
+a[1:3] # => [1, 2, 3]
+a[2:end] # => [2, 3, 4, 5]
-# Remove arbitrary elements from a list with splice!
+# Remove elements from an array by index with splice!
arr = [3,4,5]
-splice!(arr,2) #=> 4 ; arr is now [3,5]
+splice!(arr,2) # => 4 ; arr is now [3,5]
# Concatenate lists with append!
b = [1,2,3]
-append!(a,b) # Now a is [1, 3, 4, 5, 1, 2, 3]
+append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
-# Check for existence in a list with contains
-contains(a,1) #=> true
+# Check for existence in a list with in
+in(1, a) # => true
# Examine the length with length
-length(a) #=> 7
+length(a) # => 8
# Tuples are immutable.
-tup = (1, 2, 3) #=>(1,2,3) # an (Int64,Int64,Int64) tuple.
-tup[1] #=> 1
+tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
+tup[1] # => 1
try:
- tup[0] = 3 #=> ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
+ tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
catch e
println(e)
end
# Many list functions also work on tuples
-length(tup) #=> 3
-tup[1:2] #=> (1,2)
-contains(tup,2) #=> true
+length(tup) # => 3
+tup[1:2] # => (1,2)
+in(2, tup) # => true
# You can unpack tuples into variables
-a, b, c = (1, 2, 3) #=> (1,2,3) # a is now 1, b is now 2 and c is now 3
+a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
+
+# Tuples are created even if you leave out the parentheses
+d, e, f = 4, 5, 6 # => (4,5,6)
-# Tuples are created by default if you leave out the parentheses
-d, e, f = 4, 5, 6 #=> (4,5,6)
+# A 1-element tuple is distinct from the value it contains
+(1,) == 1 # => false
+(1) == 1 # => true
-# Now look how easy it is to swap two values
-e, d = d, e #=> (5,4) # d is now 5 and e is now 4
+# Look how easy it is to swap two values
+e, d = d, e # => (5,4) # d is now 5 and e is now 4
# Dictionaries store mappings
-empty_dict = Dict() #=> Dict{Any,Any}()
+empty_dict = Dict() # => Dict{Any,Any}()
-# Here is a prefilled dictionary
+# You can create a dictionary using a literal
filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
# => Dict{ASCIIString,Int64}
# Look up values with []
-filled_dict["one"] #=> 1
+filled_dict["one"] # => 1
# Get all keys
keys(filled_dict)
-#=> KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
# Note - dictionary keys are not sorted or in the order you inserted them.
-# Get all values
+# Get all values
values(filled_dict)
-#=> ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
# Note - Same as above regarding key ordering.
-# Check for existence of keys in a dictionary with contains, haskey
-contains(filled_dict, ("one", 1)) #=> true
-contains(filled_dict, ("two", 3)) #=> false
-haskey(filled_dict, "one") #=> true
-haskey(filled_dict, 1) #=> false
+# Check for existence of keys in a dictionary with in, haskey
+in(("one", 1), filled_dict) # => true
+in(("two", 3), filled_dict) # => false
+haskey(filled_dict, "one") # => true
+haskey(filled_dict, 1) # => false
-# Trying to look up a non-existing key will raise an error
+# Trying to look up a non-existant key will raise an error
try
- filled_dict["four"] #=> ERROR: key not found: four in getindex at dict.jl:489
+ filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
catch e
println(e)
end
-# Use get method to avoid the error
+# Use the get method to avoid that error by providing a default value
# get(dictionary,key,default_value)
-get(filled_dict,"one",4) #=> 1
-get(filled_dict,"four",4) #=> 4
+get(filled_dict,"one",4) # => 1
+get(filled_dict,"four",4) # => 4
-# Sets store sets
-empty_set = Set() #=> Set{Any}()
-# Initialize a set with a bunch of values
-filled_set = Set(1,2,2,3,4) #=> Set{Int64}(1,2,3,4)
+# Use Sets to represent collections of unordered, unique values
+empty_set = Set() # => Set{Any}()
+# Initialize a set with values
+filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
-# Add more items to a set
-add!(filled_set,5) #=> Set{Int64}(5,4,2,3,1)
+# Add more values to a set
+push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
-# There are functions for set intersection, union, and difference.
-other_set = Set(3, 4, 5, 6) #=> Set{Int64}(6,4,5,3)
-intersect(filled_set, other_set) #=> Set{Int64}(3,4,5)
-union(filled_set, other_set) #=> Set{Int64}(1,2,3,4,5,6)
-setdiff(Set(1,2,3,4),Set(2,3,5)) #=> Set{Int64}(1,4)
+# Check if the values are in the set
+in(2, filled_set) # => true
+in(10, filled_set) # => false
-# Check for existence in a set with contains
-contains(filled_set,2) #=> true
-contains(filled_set,10) #=> false
+# There are functions for set intersection, union, and difference.
+other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
+intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
+union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
+setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
####################################################
@@ -285,8 +301,7 @@ contains(filled_set,10) #=> false
# Let's make a variable
some_var = 5
-# Here is an if statement. Indentation is NOT meaningful in Julia.
-# prints "some var is smaller than 10"
+# Here is an if statement. Indentation is not meaningful in Julia.
if some_var > 10
println("some_var is totally bigger than 10.")
elseif some_var < 10 # This elseif clause is optional.
@@ -294,85 +309,103 @@ elseif some_var < 10 # This elseif clause is optional.
else # The else clause is optional too.
println("some_var is indeed 10.")
end
+# => prints "some var is smaller than 10"
-# For loops iterate over iterables, such as ranges, lists, sets, dicts, strings.
-
+# For loops iterate over iterables.
+# Iterable types include Range, Array, Set, Dict, and String.
for animal=["dog", "cat", "mouse"]
- # You can use $ to interpolate into strings
println("$animal is a mammal")
+ # You can use $ to interpolate variables or expression into strings
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
-# You can use in instead of =, if you want.
+# You can use 'in' instead of '='.
for animal in ["dog", "cat", "mouse"]
println("$animal is a mammal")
end
+# prints:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
- println("$(a[1]) is $(a[2])")
+ println("$(a[1]) is a $(a[2])")
end
+# prints:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
- println("$k is $v")
+ println("$k is a $v")
end
-
-
-# While loops go until a condition is no longer met.
# prints:
-# 0
-# 1
-# 2
-# 3
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
+
+# While loops loop while a condition is true
x = 0
while x < 4
println(x)
x += 1 # Shorthand for x = x + 1
end
+# prints:
+# 0
+# 1
+# 2
+# 3
-# Handle exceptions with a try/except block
+# Handle exceptions with a try/catch block
try
error("help")
catch e
println("caught it $e")
end
-#=> caught it ErrorException("help")
+# => caught it ErrorException("help")
####################################################
## 4. Functions
####################################################
-# Use the keyword function to create new functions
+# The keyword 'function' creates new functions
+#function name(arglist)
+# body...
+#end
function add(x, y)
println("x is $x and y is $y")
- # Functions implicitly return the value of their last statement
+ # Functions return the value of their last statement
x + y
end
-add(5, 6) #=> 11 after printing out "x is 5 and y is 6"
+add(5, 6) # => 11 after printing out "x is 5 and y is 6"
# You can define functions that take a variable number of
# positional arguments
function varargs(args...)
return args
+ # use the keyword return to return anywhere in the function
end
+# => varargs (generic function with 1 method)
-varargs(1,2,3) #=> (1,2,3)
+varargs(1,2,3) # => (1,2,3)
# The ... is called a splat.
-# It can also be used in a fuction call
-# to splat a list or tuple out to be the arguments
-Set([1,2,3]) #=> Set{Array{Int64,1}}([1,2,3]) # produces a Set of Arrays
-Set([1,2,3]...) #=> Set{Int64}(1,2,3) # this is equivalent to Set(1,2,3)
+# We just used it in a function definition.
+# It can also be used in a fuction call,
+# where it will splat an Array or Tuple's contents into the argument list.
+Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # produces a Set of Arrays
+Set([1,2,3]...) # => Set{Int64}(1,2,3) # this is equivalent to Set(1,2,3)
-x = (1,2,3) #=> (1,2,3)
-Set(x) #=> Set{(Int64,Int64,Int64)}((1,2,3)) # a Set of Tuples
-Set(x...) #=> Set{Int64}(2,3,1)
+x = (1,2,3) # => (1,2,3)
+Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # a Set of Tuples
+Set(x...) # => Set{Int64}(2,3,1)
# You can define functions with optional positional arguments
@@ -380,26 +413,26 @@ function defaults(a,b,x=5,y=6)
return "$a $b and $x $y"
end
-defaults('h','g') #=> "h g and 5 6"
-defaults('h','g','j') #=> "h g and j 6"
-defaults('h','g','j','k') #=> "h g and j k"
+defaults('h','g') # => "h g and 5 6"
+defaults('h','g','j') # => "h g and j 6"
+defaults('h','g','j','k') # => "h g and j k"
try
- defaults('h') #=> ERROR: no method defaults(Char,)
- defaults() #=> ERROR: no methods defaults()
+ defaults('h') # => ERROR: no method defaults(Char,)
+ defaults() # => ERROR: no methods defaults()
catch e
-println(e)
+ println(e)
end
# You can define functions that take keyword arguments
function keyword_args(;k1=4,name2="hello") # note the ;
return ["k1"=>k1,"name2"=>name2]
-end
+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="ness") # => ["name2"=>"ness","k1"=>4]
+keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
+keyword_args() # => ["name2"=>"hello","k1"=>4]
-# You can also do both at once
+# You can combine all kinds of arguments in the same function
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
println("normal arg: $normal_arg")
println("optional arg: $optional_positional_arg")
@@ -420,12 +453,15 @@ function create_adder(x)
return adder
end
-# or equivalently
+# This is "stabby lambda syntax" for creating anonymous functions
+(x -> x > 2)(3) # => true
+
+# This function is identical to create_adder implementation above.
function create_adder(x)
y -> x + y
end
-# you can also name the internal function, if you want
+# You can also name the internal function, if you want
function create_adder(x)
function adder(y)
x + y
@@ -434,92 +470,277 @@ function create_adder(x)
end
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
-# The first two inner functions above are anonymous functions
-(x -> x > 2)(3) #=> true
# There are built-in higher order functions
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(x -> x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+map(add_10, [1,2,3]) # => [11, 12, 13]
+filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-# We can use list comprehensions for nice maps and filters
-[add_10(i) for i=[1, 2, 3]] #=> [11, 12, 13]
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+# We can use list comprehensions for nicer maps
+[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
####################################################
-## 5. Types and Multiple-Dispatch
+## 5. Types
####################################################
-# Type definition
+# Julia has a type system.
+# Every value has a type; variables do not have types themselves.
+# You can use the `typeof` function to get the type of a value.
+typeof(5) # => Int64
+
+# Types are first-class values
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
+# DataType is the type that represents types, including itself.
+
+# Types are used for documentation, optimizations, and dispatch.
+# They are not statically checked.
+
+# Users can define types
+# They are like records or structs in other languages.
+# New types are defined used the `type` keyword.
+
+# type Name
+# field::OptionalType
+# ...
+# end
type Tiger
taillength::Float64
- coatcolor # no type annotation is implicitly Any
+ coatcolor # not including a type annotation is the same as `::Any`
end
-# default constructor is the properties in order
-# so, Tiger(taillength,coatcolor)
-# Type instantiation
-tigger = Tiger(3.5,"orange") # the type doubles as the constructor function
+# The default constructor's arguments are the properties
+# of the type, in the order they are listed in the definition
+tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
-# Abtract Types
-abstract Cat # just a name and point in the type hierarchy
+# The type doubles as the constructor function for values of that type
+sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
-# * types defined with the type keyword are concrete types; they can be
-# instantiated
-#
-# * types defined with the abstract keyword are abstract types; they can
-# have subtypes.
-#
-# * each type has one supertype; a supertype can have zero or more subtypes.
+# These struct-style types are called concrete types
+# They can be instantiated, but cannot have subtypes.
+# The other kind of types is abstract types.
+# abstract Name
+abstract Cat # just a name and point in the type hierarchy
+
+# Abstract types cannot be instantiated, but can have subtypes.
+# For example, Number is an abstract type
+subtypes(Number) # => 6-element Array{Any,1}:
+ # Complex{Float16}
+ # Complex{Float32}
+ # Complex{Float64}
+ # Complex{T<:Real}
+ # ImaginaryUnit
+ # Real
+subtypes(Cat) # => 0-element Array{Any,1}
+
+# Every type has a super type; use the `super` function to get it.
+typeof(5) # => Int64
+super(Int64) # => Signed
+super(Signed) # => Real
+super(Real) # => Number
+super(Number) # => Any
+super(super(Signed)) # => Number
+super(Any) # => Any
+# All of these type, except for Int64, are abstract.
+
+# <: is the subtyping operator
type Lion <: Cat # Lion is a subtype of Cat
mane_color
roar::String
end
+# You can define more constructors for your type
+# Just define a function of the same name as the type
+# and call an existing constructor to get a value of the correct type
+Lion(roar::String) = Lion("green",roar)
+# This is an outer constructor because it's outside the type definition
+
type Panther <: Cat # Panther is also a subtype of Cat
eye_color
Panther() = new("green")
# Panthers will only have this constructor, and no default constructor.
end
+# 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.
-# Multiple Dispatch
+####################################################
+## 6. Multiple-Dispatch
+####################################################
# In Julia, all named functions are generic functions
# This means that they are built up from many small methods
-# For example, let's make a function meow:
-function meow(cat::Lion)
- cat.roar # access properties using dot notation
+# Each constructor for Lion is a method of the generic function Lion.
+
+# For a non-constructor example, let's make a function meow:
+
+# Definitions for Lion, Panther, Tiger
+function meow(animal::Lion)
+ animal.roar # access type properties using dot notation
end
-function meow(cat::Panther)
+function meow(animal::Panther)
"grrr"
end
-function meow(cat::Tiger)
+function meow(animal::Tiger)
"rawwwr"
end
-meow(tigger) #=> "rawwr"
-meow(Lion("brown","ROAAR")) #=> "ROAAR"
-meow(Panther()) #=> "grrr"
+# Testing the meow function
+meow(tigger) # => "rawwr"
+meow(Lion("brown","ROAAR")) # => "ROAAR"
+meow(Panther()) # => "grrr"
+# Review the local type hierarchy
+issubtype(Tiger,Cat) # => false
+issubtype(Lion,Cat) # => true
+issubtype(Panther,Cat) # => true
+
+# Defining a function that takes Cats
function pet_cat(cat::Cat)
println("The cat says $(meow(cat))")
end
+pet_cat(Lion("42")) # => prints "The cat says 42"
try
- pet_cat(tigger) #=> ERROR: no method pet_cat(Tiger,)
+ pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
catch e
println(e)
end
-pet_cat(Lion(Panther(),"42")) #=> prints "The cat says 42"
+# In OO languages, single dispatch is common;
+# this means that the method is picked based on the type of the first argument.
+# In Julia, all of the argument types contribute to selecting the best method.
+
+# Let's define a function with more arguments, so we can see the difference
+function fight(t::Tiger,c::Cat)
+ println("The $(t.coatcolor) tiger wins!")
+end
+# => fight (generic function with 1 method)
+
+fight(tigger,Panther()) # => prints The orange tiger wins!
+fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
+
+# Let's change the behavior when the Cat is specifically a Lion
+fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
+# => fight (generic function with 2 methods)
+
+fight(tigger,Panther()) # => prints The orange tiger wins!
+fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
+
+# We don't need a Tiger in order to fight
+fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
+# => fight (generic function with 3 methods)
+
+fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
+try
+ fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
+catch
+end
+# Also let the cat go first
+fight(c::Cat,l::Lion) = println("The cat beats the Lion")
+# => Warning: New definition
+# fight(Cat,Lion) at none:1
+# is ambiguous with
+# fight(Lion,Cat) at none:2.
+# Make sure
+# fight(Lion,Lion)
+# is defined first.
+#fight (generic function with 4 methods)
+
+# This warning is because it's unclear which fight will be called in:
+fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
+# The result may be different in other versions of Julia
+
+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
You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/manual/)
+The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users).
diff --git a/ko-kr/brainfuck-kr.html.markdown b/ko-kr/brainfuck-kr.html.markdown
new file mode 100644
index 00000000..c2e4341f
--- /dev/null
+++ b/ko-kr/brainfuck-kr.html.markdown
@@ -0,0 +1,84 @@
+---
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["JongChan Choi", "http://0xABCDEF.com/"]
+ - ["Peter Lee", "http://peterjlee.com/"]
+lang: ko-kr
+---
+
+Brainfuck(문장을 시작하는 단어가 아닌이상 첫글자는 대문자를 사용하지 않습니다)은
+여덟가지 명령어만으로 튜링-완전한 최소주의 프로그래밍 언어입니다.
+
+```
+"><+-.,[]" 이외의 문자들은 무시됩니다. (쌍따옴표는 제외)
+
+브레인퍽은 30,000 칸 짜리의 0으로 초기화된 배열과,
+현재 칸을 가르키는 포인터로 표현됩니다.
+
+여덟가지의 명령어는 다음과 같습니다:
++ : 포인터가 가르키는 현재 칸의 값을 1 증가시킵니다.
+- : 포인터가 가르키는 현재 칸의 값을 1 감소시킵니다.
+> : 포인터가 다음 칸(오른쪽 칸)을 가르키도록 이동시킵니다.
+< : 포인터가 이전 칸(왼쪽 칸)을 가르키도록 이동시킵니다.
+. : 현재 칸의 값을 ASCII 문자로 출력합니다. (즉, 65 = 'A')
+, : 하나의 문자를 입력받고 그 값을 현재 칸에 대입합니다.
+[ : 현재 칸의 값이 0이면 짝이 맞는 ] 명령으로 넘어갑니다.
+ 0이 아니면 다음 명령어로 넘어갑니다.
+] : 현재 칸의 값이 0이면 다음 명령어로 넘어갑니다.
+ 0이 아니면 짝이 맞는 [ 명령으로 다시 돌아갑니다.
+
+[이랑 ]은 while 루프를 만들어냅니다. 무조건, 짝이 맞아야 합니다.
+
+몇가지 간단한 브레인퍽 프로그램을 보겠습니다.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+이 프로그램은 문자 'A'를 출력합니다. 처음에는, 반복할 횟수를 정하기 위한 값을
+만들기 위해 첫번째 칸의 값을 6으로 증가시킵니다. 그리고 루프로 들어가서([)
+두번째 칸으로 넘어갑니다. 루프 안에서는 두번째 칸의 값을 10 증가시키고,
+다시 첫번째 칸으로 넘어가서 값을 1 감소시킵니다. 이 루프는 여섯번 돕니다.
+(첫번째 칸의 값을 6번 감소시켜서 0이 될 때 까지는 ] 명령을 만날 때마다
+루프의 시작 지점으로 돌아갑니다)
+
+이 시점에서, 두번째 칸의 값은 60이고, 포인터는 값이 0인 첫번째 칸에 위치합니다.
+여기서 두번째 칸으로 넘어간 다음 값을 5 증가시키면 두번째 칸의 값이 65가 되고,
+65는 문자 'A'에 대응하는 아스키 코드이기 때문에, 두번째 칸의 값을 출력하면
+터미널에 'A'가 출력됩니다.
+
+, [ > + < - ] > .
+
+이 프로그램은 사용자로부터 문자 하나를 입력받아 첫번째 칸에 집어넣습니다.
+그리고 루프에 들어가서, 두번째 칸으로 넘어가 값을 한 번 증가시킨 다음,
+다시 첫번째 칸으로 넘어가서 값을 한 번 감소시킵니다.
+이는 첫번째 칸의 값이 0이 될 때까지 지속되며,
+두번째 칸은 첫번째 칸이 갖고있던 값을 가지게 됩니다.
+루프가 종료되면 포인터는 첫번째 칸을 가르키기 때문에 두번째 칸으로 넘어가고,
+해당 아스키 코드에 대응하는 문자를 출력합니다.
+
+또한 공백문자는 순전히 가독성을 위해서 작성되었다는 것을 기억하세요.
+다음과 같이 작성해도 똑같이 돌아갑니다:
+
+,[>+<-]>.
+
+한 번 돌려보고 아래의 프로그램이 실제로 무슨 일을 하는지 맞춰보세요:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+이 프로그램은 두 개의 숫자를 입력받은 뒤, 그 둘을 곱합니다.
+
+위 코드는 일단 두 번의 입력을 받고, 첫번째 칸의 값만큼 바깥 루프를 돕니다.
+그리고 루프 안에서 다시 두번째 칸의 값만큼 안쪽의 루프를 돕니다.
+그리고 그 루프에서는 세번째 칸의 값을 증가시키는데, 문제가 하나 있습니다:
+내부 루프가 한 번 끝나게 되면 두번째 칸의 값은 0이 됩니다.
+그럼 다시 바깥 루프를 돌 때에 안쪽의 루프를 돌지 않게 되는데, 이를 해결하려면
+네번째 칸의 값도 같이 증가시킨 다음, 그 값을 두번째 칸으로 옮기면 됩니다.
+그러면 세번째 칸에 곱셈의 결과가 남습니다.
+```
+
+여기까지 브레인퍽이었습니다. 참 쉽죠?
+재미삼아 브레인퍽 프로그램이나 다른 언어로 브레인퍽 인터프리터를 작성해보세요.
+인터프리터 구현은 간단한 편인데,
+사서 고생하는 것을 즐기는 편이라면 한 번 작성해보세요… 브레인퍽으로.
diff --git a/ko-kr/clojure-kr.html.markdown b/ko-kr/clojure-kr.html.markdown
new file mode 100644
index 00000000..1d9e53cd
--- /dev/null
+++ b/ko-kr/clojure-kr.html.markdown
@@ -0,0 +1,383 @@
+---
+language: clojure
+filename: learnclojure-kr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["netpyoung", "http://netpyoung.github.io/"]
+lang: ko-kr
+---
+
+Clojure는 Java 가상머신을 위해 개발된 Lisp 계통의 언어입니다
+이는 Common Lisp보다 순수 [함수형 프로그래밍](https://en.wikipedia.org/wiki/Functional_programming)을 더욱 강조했으며,
+상태를 있는 그대로 다루기 위해 다양한 [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) 을 지원하는 프로그램들을 갖췄습니다.
+
+이를 조합하여, 병행처리(concurrent processing)를 매우 단순하게 처리할 수 있으며,
+대게 자동으로 처리될 수 있도록 만들 수 있습니다.
+
+(Clojure 1.2 이상의 버전이 필요로 합니다.)
+
+
+```clojure
+; 주석은 세미콜론(;)으로 시작합니다.
+
+; Clojure는 "폼(forms)"으로 구성되었으며,
+; 폼은 괄호로 감싸져있으며, 공백으로 구분된 것들이 나열된 것입니다.
+;
+; clojure의 reader는 첫번째로 오는 것을
+; 함수 혹은 매크로를 호출하는 것, 그리고 나머지를 인자라고 가정합니다.
+
+; namespace를 지정하기 위해, 파일에서 우선적으로 호출해야될 것은 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 역시 필요합니다.
+(not true) ; => false
+
+; 중첩된 폼(forms)은 기대한대로 동작합니다.
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; 타입
+;;;;;;;;;;;;;
+
+; Clojure는 부울(boolean), 문자열, 숫자를 위해 Java의 object 타입을 이용합니다.
+; `class` 를 이용하여 이를 확인할 수 있습니다.
+(class 1) ; 정수는 기본적으로 java.lang.Long입니다.
+(class 1.); 소수는 java.lang.Double입니다.
+(class ""); 문자열은 쌍따옴표로 감싸져 있으며, java.lang.String입니다.
+(class false) ; 부울값은 java.lang.Boolean입니다.
+(class nil); nil은 "null"값입니다.
+
+; 데이터 리스트 자체를 만들고자 한다면,
+; '를 이용하여 평가(evaluate)되지 않도록 막아야 합니다.
+'(+ 1 2) ; => (+ 1 2)
+; (quote (+ 1 2)) 를 줄여서 쓴것
+
+; quote 가 된 리스트를 평가할 수 도 있습니다.
+(eval '(+ 1 2)) ; => 3
+
+; 컬렉션(Collections) & 시퀀스(Sequences)
+;;;;;;;;;;;;;;;;;;;
+
+; 리스트(List)는 연결된(linked-list) 자료구조이며, 벡터(Vector)는 배열이 뒤로붙는(array-backed) 자료구조입니다.
+; 리스트와 벡터 모두 java 클래스입니다!
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; 간단하게 (1 2 3)로 리스트를 나타낼 수 있지만,
+; reader가 함수라고 여기지 못하게 quote(')를 해줘야 합니다.
+; 따라서, (list 1 2 3)는 '(1 2 3)와 같습니다.
+
+; "컬렉션"은 단순하게 데이터의 그룹입니다.
+; 리스트와 벡터 모두 컬렉션입니다:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; "시퀀스" (seq) 는 데이터 리스트를 추상적으로 기술한 것입니다.
+; 리스트는 시퀀스입니다.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; 시퀀스는 접근하고자 하는 항목만 제공해주면 됩니다.
+; 따라서, 시퀀스는 lazy 할 수 있습니다 -- 무한하게 늘어나는 것을 정의할 수 있습니다:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (an infinite series)
+(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)
+
+; reduce 를 이용하여 줄여나갈 수 있습니다.
+(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"
+
+; 약자(shorthand)를 써서 함수를 만들 수 도 있습니다:
+(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"
+
+
+; 맵(Maps)
+;;;;;;;;;;
+
+; 해쉬맵(hash map)과 배열맵(array map)은 공통된 인터페이스를 공유합니다.
+; 해쉬맵은 찾기가 빠르지만, 키의 순서가 유지되지 않습니다.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; 배열맵은 여러 연산을 거쳐 자연스레 해쉬맵이 됩니다.
+; 만일 이게 커진다 하더라도, 걱정할 필요가 없습니다.
+
+; 맵은 해쉬가 가능한 타입이라면 어떠한 것이든 키로써 활용이 가능하지만, 보통 키워드를 이용하는 것이 가장 좋습니다.
+; 키워드(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}
+
+; 여기서, 쉽표가 공백으로 취급되며, 아무 일도 하지 않는다는 것을 주목하시기 바랍니다.
+
+; 맵에서 값을 얻어오기 위해선, 함수로써 맵을 호출해야 합니다.
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; 키워드 역시 맵에서 함수를 얻어올 때 사용할 수 있습니다!
+(:b keymap) ; => 2
+
+; 하지만, 문자열로는 하면 안됩니다.
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; 없는 값을 얻어오고자 하면, nil이 반환됩니다.
+(stringmap "d") ; => nil
+
+; assoc 를 이용하여 해쉬맵에 새로운 키를 추가할 수 있습니다.
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; 하지만, 변경할 수 없는(immutable) 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 네임스페이스(namespace)에는 더 많은 함수들이 있습니다.
+
+; 유용한 폼(forms)
+;;;;;;;;;;;;;;;;;
+
+; clojure에선, if 와 매크로(macro)를 가지고,
+; 다른 여러 논리 연산들을 만들 수 있습니다.
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; let 을 이용하여 임시적으로 바인딩(binding)을 구축할 수 있습니다.
+(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")
+
+; 모듈(Modules)
+;;;;;;;;;;;;;;;
+
+; "use" 를 이용하여 module에 있는 모든 함수들을 얻어올 수 있습니다.
+(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 를 이용하여 모듈을 import할 수 있습니다.
+(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."
+; (#"" denotes a regular expression literal)
+
+; :require 를 이용하여, 네임스페이스에서 require 를 사용할 수 있습니다.
+; 아레와 같은 방법을 이용하면, 모듈을 quote하지 않아도 됩니다.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java는 유용한 많은 표준 라이브러리를 가지고 있으며,
+; 이를 어떻게 활용할 수 있는지 알아보도록 하겠습니다.
+
+; import 로 java 모듈을 불러올 수 있습니다.
+(import java.util.Date)
+
+; ns 와 함께 import 를 할 수 도 있습니다.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; 새로운 인스턴스를 만들기 위해선, 클래스 이름 끝에 "."을 찍습니다.
+(Date.) ; <a date object>
+
+; . 을 이용하여 메소드를 호출할 수 있습니다.
+; 아니면, 줄여서 ".메소드"로도 호출 할 수 있습니다.
+(. (Date.) getTime) ; <a timestamp>
+(.getTime (Date.)) ; exactly the same thing.
+
+; / 를 이용하여 정적메소드를 호출 할 수 있습니다.
+(System/currentTimeMillis) ; <a timestamp> (system is always present)
+
+; doto 를 이용하여 상태가 변하는(mutable) 클래스들을 좀 더 편하게(tolerable) 다룰 수 있습니다.
+(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가 영구적인(persistent) 상태를 다루는 방식입니다.
+; clojure가 이용하는 몇몇 자료형(construct)이 있습니다.
+
+; 가장 단순한 것은 atom 입니다. 초기 값을 넣어보도록 하겠습니다.
+(def my-atom (atom {}))
+
+; swap! 으로 atom을 갱신(update)할 수 있습니다!
+; swap! 은 함수를 인자로 받아, 그 함수에 대해 현재 atom에 들어있는 값을 첫번째 인자로,
+; 나머지를 두번째 인자로 하여 호출합니다.
+(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을 역참조(dereference)하여 값을 얻을 수 있습니다.
+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.org에 많은 문서들이 보관되어 있습니다:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org는 core 함수들에 대해 다양한 예제와 문서를 보유하고 있습니다:
+[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/ko-kr/coffeescript-kr.html.markdown b/ko-kr/coffeescript-kr.html.markdown
new file mode 100644
index 00000000..f8ac8069
--- /dev/null
+++ b/ko-kr/coffeescript-kr.html.markdown
@@ -0,0 +1,58 @@
+---
+language: coffeescript
+category: language
+contributors:
+ - ["Tenor Biel", "http://github.com/L8D"]
+filename: coffeescript-kr.coffee
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+lang: ko-kr
+---
+
+``` coffeescript
+# 커피스크립트(CoffeeScript)는 최신 유행을 따르는 언어입니다.
+# 커피스크립트는 여러 현대 언어의 트렌드를 따르는데,
+# 그래서 주석을 작성할 때는 루비나 파이썬과 같이 해시를 씁니다.
+
+###
+블록 주석은 이처럼 작성하며, 자바스크립트 코드로 만들어지도록
+'/ *'와 '* /'로 직접적으로 변환됩니다.
+
+계속하기에 앞서 자바스크립트 시맨틱을 대부분 이해하고 있어야 합니다.
+###
+
+# 할당:
+number = 42 #=> var number = 42;
+opposite = true #=> var opposite = true;
+
+# 조건문:
+number = -42 if opposite #=> if(opposite) { number = -42; }
+
+# 함수:
+square = (x) -> x * x #=> var square = function(x) { return x * x; }
+
+# 범위:
+list = [1..5] #=> var list = [1, 2, 3, 4, 5];
+
+# 객체:
+math =
+ root: Math.sqrt
+ square: square
+ cube: (x) -> x * square x
+#=> var math = {
+# "root": Math.sqrt,
+# "square": square,
+# "cube": function(x) { return x * square(x); }
+#}
+
+# 가변 인자(splat):
+race = (winner, runners...) ->
+ print winner, runners
+
+# 존재 여부 확인:
+alert "I knew it!" if elvis?
+#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
+
+# 배열 조건 제시법(comprehensions):
+cubes = (math.cube num for num in list) #=> ...
+```
diff --git a/ko-kr/go-kr.html.markdown b/ko-kr/go-kr.html.markdown
new file mode 100644
index 00000000..e6ebe097
--- /dev/null
+++ b/ko-kr/go-kr.html.markdown
@@ -0,0 +1,314 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo-kr.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/ko-kr/java-kr.html.markdown b/ko-kr/java-kr.html.markdown
new file mode 100644
index 00000000..dc7a356f
--- /dev/null
+++ b/ko-kr/java-kr.html.markdown
@@ -0,0 +1,408 @@
+---
+language: java
+filename: java-kr.java
+category: language
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+lang: ko-kr
+---
+
+자바는 일반 목적으로 사용할 수 있고 동시성을 지원하며, 클래스 기반의 객체지향 컴퓨터 프로그래밍 언어입니다.
+[더 자세한 사항](http://docs.oracle.com/javase/tutorial/java/index.html)
+
+```java
+// 한 줄짜리 주석은 //로 시작합니다.
+/*
+여러 줄 주석은 다음과 같은 형태입니다.
+*/
+/**
+자바독(JavaDoc) 주석은 이렇게 생겼습니다. 자바독 주석은 클래스나 클래스의
+다양한 속성을 기술하는 데 사용됩니다.
+*/
+
+// java.util 패키지 안에 있는 ArrayList 클래스를 임포트합니다.
+import java.util.ArrayList;
+// java.security 패키지 안에 있는 모든 클래스를 임포트합니다.
+import java.security.*;
+
+// 각 .java 파일에는 공용(public) 클래스가 들어 있으며, 클래스의 이름은
+// 파일명과 동일합니다.
+public class LearnJava {
+
+ // 프로그램에는 반드시 진입점 역할을 하는 main 메서드가 하나 있어야 합니다.
+ public static void main (String[] args) {
+
+ // System.out.println을 이용해 한 줄을 출력합니다.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // 줄바꿈 없이 뭔가를 출력하려면 System.out.print를 사용합니다.
+ System.out.print("Hello ");
+ System.out.print("World");
+
+
+ ///////////////////////////////////////
+ // 타입 & 변수
+ ///////////////////////////////////////
+
+ // <타입> <이름>과 같은 형태로 변수를 선언합니다.
+ // Byte - 부호가 있는 8비트 2의 보수 정수
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Short - 부호가 있는 16비트 2의 보수 정수
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 부호가 있는 32비트 2의 보수 정수
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Long - 부호가 있는 64비트 2의 보수 정수
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L은 이 변수의 값이 Long 타입임을 나타내는 데 사용됩니다.
+ // L이 없는 것들은 기본적으로 정수로 간주됩니다.
+
+ // 참고: 자바에는 부호 없는(unsigned) 타입이 없습니다.
+
+ // Float - 단정도 32비트 IEEE 754 부동 소수점 수
+ float fooFloat = 234.5f;
+ // f는 이 변수의 값이 float 타입임을 나타내는 데 사용됩니다.
+ // f를 지정하지 않으면 double로 간주됩니다.
+
+ // Double - 배정도 64비트 IEEE 754 부동 소수점 수
+ double fooDouble = 123.4;
+
+ // Boolean - 참(true) & 거짓(false)
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - 단일 16비트 유니코드 문자
+ char fooChar = 'A';
+
+ // 변수를 변경할 수 없게 만들려면 final을 지정합니다.
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+
+ // 문자열
+ String fooString = "My String Is Here!";
+
+ // \n은 새로운 줄을 시작하는 이스케이프 문자입니다.
+ String barString = "Printing on a new line?\nNo Problem!";
+ // \t는 탭 문자를 추가하는 이스케이프 문자입니다.
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // 배열
+ // 배열의 크기는 반드시 선언할 때 결정해야 합니다.
+ // 배열을 선언하는 형식은 다음과 같습니다.
+ //<자료형> [] <변수명> = new <자료형>[<배열 크기>];
+ int [] intArray = new int[10];
+ String [] stringArray = new String[1];
+ boolean [] booleanArray = new boolean[100];
+
+ // 배열을 선언하고 초기화하는 또 다른 방법
+ int [] y = {9000, 1000, 1337};
+
+ // 배열 인덱스 - 요소에 접근
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // 배열의 인덱스는 0에서부터 시작하며 변경 가능합니다.
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // 기타 참고할 만한 자료구조
+ // ArrayLists - 좀 더 많은 기능을 제공하고 크기를 변경 가능하다는 점을
+ // 제외하면 배열과 비슷합니다.
+ // LinkedLists
+ // Maps
+ // HashMaps
+
+ ///////////////////////////////////////
+ // 연산자
+ ///////////////////////////////////////
+ System.out.println("\n->Operators");
+
+ int i1 = 1, i2 = 2; // 다중 선언의 축약형
+
+ // 산술 연산은 이해하기 어렵지 않습니다.
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5를 잘라 버립니다)
+
+ // 나눗셈
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // 비교 연산자
+ System.out.println("3 == 2? " + (3 == 2)); // => false
+ System.out.println("3 != 2? " + (3 != 2)); // => true
+ System.out.println("3 > 2? " + (3 > 2)); // => true
+ System.out.println("3 < 2? " + (3 < 2)); // => false
+ System.out.println("2 <= 2? " + (2 <= 2)); // => true
+ System.out.println("2 >= 2? " + (2 >= 2)); // => true
+
+ // 비트 연산자!
+ /*
+ ~ 단항 보수 연산
+ << 산술적 왼쪽 시프트
+ >> 산술적 오른쪽 시프트
+ >>> 논리적 오른쪽 시프트
+ & 비트 단위 논리곱(AND)
+ ^ 비트 단위 배타적 논리합(OR)
+ | 비트 단위 논리합(OR)
+ */
+
+ // 증감 연산자
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ System.out.println(i++); //i = 1. 후치 증가 연산
+ System.out.println(++i); //i = 2. 전치 증가 연산
+ System.out.println(i--); //i = 1. 후치 감소 연산
+ System.out.println(--i); //i = 0. 전치 감소 연산
+
+ ///////////////////////////////////////
+ // 제어 구조
+ ///////////////////////////////////////
+ System.out.println("\n->Control Structures");
+
+ // if 문은 C 언어와 비슷합니다.
+ int j = 10;
+ if (j == 10){
+ System.out.println("I get printed");
+ } else if (j > 10) {
+ System.out.println("I don't");
+ } else {
+ System.out.println("I also don't");
+ }
+
+ // while 루프
+ int fooWhile = 0;
+ while(fooWhile < 100)
+ {
+ // System.out.println(fooWhile);
+ // 카운터를 증가
+ // 99번 반복, fooWhile 0->99
+ fooWhile++;
+ }
+ System.out.println("fooWhile Value: " + fooWhile);
+
+ // do-while 루프
+ int fooDoWhile = 0;
+ do
+ {
+ // System.out.println(fooDoWhile);
+ // 카운터를 증가
+ // 99번 반복, fooDoWhile 0->99
+ fooDoWhile++;
+ }while(fooDoWhile < 100);
+ System.out.println("fooDoWhile Value: " + fooDoWhile);
+
+ // for 루프
+ int fooFor;
+ // for 루프 구조 => for(<초기식>; <조건식>; <증감식>)
+ for(fooFor=0; fooFor<10; fooFor++){
+ // System.out.println(fooFor);
+ // 10번 반복, fooFor 0->9
+ }
+ System.out.println("fooFor Value: " + fooFor);
+
+ // switch-case 문
+ // switch는 byte, short, char, int 자료형을 대상으로 동작합니다.
+ // 아울러 열거형을 비롯해 String 클래스 및 원시 타입을 감싼 Character,
+ // Byte, Short, Integer와 같은 몇 가지 특별한 클래스에 대해서도 동작합니다.
+ int month = 3;
+ String monthString;
+ switch (month){
+ case 1:
+ monthString = "January";
+ break;
+ case 2:
+ monthString = "February";
+ break;
+ case 3:
+ monthString = "March";
+ break;
+ default:
+ monthString = "Some other month";
+ break;
+ }
+ System.out.println("Switch Case Result: " + monthString);
+
+
+ ///////////////////////////////////////
+ // 자료형 변환과 형변환
+ ///////////////////////////////////////
+
+ // 데이터 변환
+
+ // 문자열에서 정수로 변환
+ Integer.parseInt("123");// 정수 버전의 "123"을 반환
+
+ // 정수를 문자열로 변환
+ Integer.toString(123);// 문자열 버전의 123을 반환
+
+ // 다른 변환에 대해서는 아래 클래스를 확인해 보세요.
+ // Double
+ // Long
+ // String
+
+ // 형변환
+ // 자바 객체 또한 형변환할 수 있으며, 이와 관련해서 알아야 할 세부사항이
+ // 많을뿐더러 다소 중급 수준에 해당하는 개념들도 다뤄야 합니다.
+ // 이와 관련된 사항은 아래 링크를 참고하세요.
+ // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+
+ ///////////////////////////////////////
+ // 클래스와 함수
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes & Functions");
+
+ // (Bicycle 클래스의 정의)
+
+ // 클래스를 인스턴스화하려면 new를 사용합니다.
+ Bicycle trek = new Bicycle();
+
+ // 객체의 메서드를 호출합니다.
+ trek.speedUp(3); // 항상 설정자 메서드와 접근자 메서드를 사용해야 합니다.
+ trek.setCadence(100);
+
+ // 현재 객체의 값을 표시할 때는 관례적으로 toString을 사용합니다.
+ System.out.println("trek info: " + trek.toString());
+
+ } // main 메서드 끝
+} // LearnJava 클래스 끝
+
+
+// .java 파일 안에 다른 비공개 클래스를 포함할 수 있습니다.
+
+
+// 클래스 선언 문법:
+// <public/private/protected> class <클래스명>{
+// // 데이터 필드, 생성자, 함수가 모두 이곳에 들어갑니다.
+// // 자바에서는 함수를 메서드라고 부릅니다.
+// }
+
+class Bicycle {
+
+ // Bicycle의 필드와 변수
+ public int cadence; // Public: 어느 곳에서도 접근할 수 있습니다.
+ private int speed; // Private: 클래스 안에서만 접근할 수 있습니다.
+ protected int gear; // Protected: 현재 클래스와 하위 클래스에서 접근할 수 있습니다.
+ String name; // default: 현재 패키지 안에서만 접근할 수 있습니다.
+
+ // 생성자는 클래스를 생성하는 방법 중 하나입니다.
+ // 다음은 기본 생성자입니다.
+ public Bicycle() {
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+
+ // 다음은 구체화된 생성자입니다(인자를 담고 있습니다)
+ public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // 함수 문법:
+ // <public/private/protected> <반환형> <함수명>(<인자>)
+
+ // 자바 클래스는 필드에 대해 접근자 메서드와 설정자 메서드를 구현할 때가 많습니다.
+
+ // 메서드 선언 문법:
+ // <유효범위> <반환형> <메서드명>(<인자>)
+ public int getCadence() {
+ return cadence;
+ }
+
+ // void 메서드는 반환형이 필요하지 않습니다.
+ public void setCadence(int newValue) {
+ cadence = newValue;
+ }
+
+ public void setGear(int newValue) {
+ gear = newValue;
+ }
+
+ public void speedUp(int increment) {
+ speed += increment;
+ }
+
+ public void slowDown(int decrement) {
+ speed -= decrement;
+ }
+
+ public void setName(String newName) {
+ name = newName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // 현재 객체의 속성값을 표시하는 메서드
+ @Override
+ public String toString() {
+ return "gear: " + gear +
+ " cadence: " + cadence +
+ " speed: " + speed +
+ " name: " + name;
+ }
+} // Bicycle 클래스의 끝
+
+// PennyFarthing은 Bicycle의 하위 클래스입니다.
+class PennyFarthing extends Bicycle {
+ // (페니 파딩은 앞바퀴가 굉장히 큰 자전거입니다. 기어가 없죠.)
+
+ public PennyFarthing(int startCadence, int startSpeed){
+ // super를 이용해 부모 생성자를 호출합니다.
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // @annotation을 이용해 재정의하는 메서드를 표시해야 합니다.
+ // 애노테이션과 애노테이션의 용도에 관한 자세한 내용은 아래 링크를 참고하세요.
+ // 애노테이션: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ gear = 0;
+ }
+
+}
+
+```
+
+## 기타 참고자료
+
+다음 링크를 통해 다양한 주제를 이해하고 구글을 통해 구체적인 예제들을 찾아보세요.
+
+공부할 만한 기타 주제:
+
+* [썬/오라클의 자바 자습서](http://docs.oracle.com/javase/tutorial/index.html)
+
+* [자바 접근 제한자](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [객체 지향 프로그래밍 개념](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [상속(Inheritance)](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [다형성(Polymorphism)](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [추상화(Abstraction)](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [예외(Exceptions)](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [인터페이스(Interfaces)](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [제네릭(Generics)](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [자바 코딩 관례(Java Code Conventions)](http://www.oracle.com/technetwork/java/codeconv-138413.html)
diff --git a/ko-kr/javascript-kr.html.markdown b/ko-kr/javascript-kr.html.markdown
new file mode 100644
index 00000000..f651fbe7
--- /dev/null
+++ b/ko-kr/javascript-kr.html.markdown
@@ -0,0 +1,436 @@
+---
+language: javascript
+category: language
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+filename: javascript-kr.js
+lang: ko-kr
+---
+
+자바스크립트는 넷스케이프의 브렌던 아이크(Brendan Eich)가 1995년에 만들었습니다.
+원래 자바스크립트는 웹사이트를 위한 단순한 스크립트 언어를 목표로 만들어졌는데,
+좀 더 복잡한 웹 애플리케이션을 만들기 위해 자바를 보완하는 역할이었지만
+웹 페이지와의 긴밀한 상호작용과 브라우저에 대한 지원 기능 덕분에 웹 프론트엔드에서
+자바보다 훨씬 더 보편적으로 쓰이게 됐습니다.
+
+그렇지만 자바스크립트는 웹 브라우저에만 국한되지 않습니다. 구글 크롬의 V8 자바스크립트
+엔진을 위한 독립형 런타임을 제공하는 Node.js는 점점 인기를 얻고 있습니다.
+
+피드백 주시면 대단히 감사하겠습니다! [@adambrenecki](https://twitter.com/adambrenecki)나
+[adam@brenecki.id.au](mailto:adam@brenecki.id.au)를 통해 저와 만나실 수 있습니다.
+
+```js
+// 주석은 C와 비슷합니다. 한 줄짜리 주석은 두 개의 슬래시로 시작하고,
+/* 여러 줄 주석은 슬래시 별표로 시작해서
+ 별표 슬래시로 끝납니다. */
+
+// 구문은 세미콜론(;)으로 끝낼 수 있습니다.
+doStuff();
+
+// 하지만 꼭 그럴 필요는 없는데, 특정 경우를 제외하고
+// 새 줄이 시작할 때마다 세미콜론이 자동으로 삽입되기 때문입니다.
+doStuff()
+
+// 여기서는 세미콜론을 생략하겠습니다. 세미콜론을 생략할지 여부는
+// 개인적인 취향이나 프로젝트의 스타일 가이드를 따릅니다.
+
+///////////////////////////////////
+// 1. 숫자, 문자열, 연산자
+
+// 자바스크립트에는 단 하나의 숫자 타입(64비트 IEEE 754 배정도 숫자)만이
+// 있습니다.
+3 // = 3
+1.5 // = 1.5
+
+// 모든 기초 산술 연산은 기대한 대로 동작합니다.
+1 + 1 // = 2
+8 - 1 // = 7
+10 * 2 // = 20
+35 / 5 // = 7
+
+// 나누어 떨어지지 않는 나눗셈도 포함됩니다.
+5 / 2 // = 2.5
+
+// 비트 연산도 지원됩니다. float을 대상으로 비트 연산을 수행하면
+// 32비트까지 부호가 있는 int로 변환됩니다.
+1 << 2 // = 4
+
+// 괄호를 이용하면 우선순위를 지정할 수 있습니다.
+(1 + 3) * 2 // = 8
+
+// 실제 숫자가 아닌 특별한 세 가지 값이 있습니다.
+Infinity // 1/0 1/0과 같은 연산의 결과
+-Infinity // -1/0과 같은 연산의 결과
+NaN // 0/0과 같은 연산의 결과
+
+// 불린 타입도 있습니다.
+true
+false
+
+// 문자열은 '나 "로 생성합니다.
+'abc'
+"Hello, world"
+
+// 부정 연산에는 ! 기호를 이용합니다.
+!true // = false
+!false // = true
+
+// 동일성 연산은 ==
+1 == 1 // = true
+2 == 1 // = false
+
+// 불일치 연산은 !=
+1 != 1 // = false
+2 != 1 // = true
+
+// 그 밖의 비교 연산
+1 < 10 // = true
+1 > 10 // = false
+2 <= 2 // = true
+2 >= 2 // = true
+
+// 문자열은 +로 연결할 수 있습니다.
+"Hello " + "world!" // = "Hello world!"
+
+// 그리고 <와 >로 비교할 수 있습니다.
+"a" < "b" // = true
+
+// 비교 시 타입 강제변환이 수행됩니다.
+"5" == 5 // = true
+
+// ===를 쓰지 않는다면 말이죠.
+"5" === 5 // = false
+
+// charAt을 이용하면 문자열 내의 문자에 접근할 수 있습니다.
+"This is a string".charAt(0)
+
+// null과 undefined도 있습니다.
+null // 의도적으로 값이 아님을 나타내는 데 사용합니다.
+undefined // 값이 아직 설정되지 않음을 나타내는 데 사용합니다.
+
+// null, undefinded, NaN, 0, ""은 거짓이며, 그 밖의 다른 모든 값은 참입니다.
+// 참고로 0은 거짓이며, "0"은 참입니다(심지어 0 == "0"이더라도).
+
+///////////////////////////////////
+// 2. 변수, 배열, 객체
+
+// 변수는 var 키워드로 선언합니다. 자바스크립트는 동적 타입 언어라서
+// 타입을 지정할 필요가 없습니다. 값을 할당할 때는 = 문자 하나를 사용합니다.
+var someVar = 5
+
+// var 키워드를 지정하지 않아도 오류는 발생하지 않습니다.
+someOtherVar = 10
+
+// 그렇지만 변수가 여러분이 정의한 유효범위가 아니라
+// 전역 유효범위에 생성됩니다.
+
+// 값을 할당하지 않은 채로 선언한 변수는 undefined로 설정됩니다.
+var someThirdVar // = undefined
+
+// 변수에 수학 연산을 수행하는 축약형 표현은 다음과 같습니다.
+someVar += 5 // someVar = someVar + 5;와 같음. 이제 someVar는 10.
+someVar *= 10 // somVar는 100
+
+// 1을 더하거나 빼는 훨씬 더 짧은 표현도 있습니다.
+someVar++ // 이제 someVar는 101
+someVar-- // 다시 100으로 되돌아감
+
+// 배열은 순차적인 임의 타입 값의 목록입니다.
+var myArray = ["Hello", 45, true]
+
+// 배열의 멤버는 대괄호로 둘러싼 인덱스를 이용해 접근할 수 있습니다.
+// 배열의 인덱스는 0부터 시작합니다.
+myArray[1] // = 45
+
+// 자바스크립트의 객체는 다른 언어의 '사전'이나 '맵'과 같습니다.
+// 즉, 키-값 쌍으로 구성된 비순차 컬렉션입니다.
+{key1: "Hello", key2: "World"}
+
+// 키는 문자열이지만 유효한 자바스크립트 식별자일 경우
+// 작은따옴표는 필요하지 않습니다. 값은 어떤 타입이든 사용할 수 있습니다.
+var myObj = {myKey: "myValue", "my other key": 4}
+
+// 객체 속성에도 인덱스를 이용해 접근할 수 있습니다.
+myObj["my other key"] // = 4
+
+// 또는 키가 유효한 식별자일 경우 점 표기법을 이용해 접근할 수 있습니다.
+myObj.myKey // = "myValue"
+
+// 객체는 변경 가능합니다. 즉, 값을 변경하거나 새 키를 추가할 수 있습니다.
+myObj.myThirdKey = true
+
+// 설정되지 않은 값에 접근하려고 하면 undefined가 반환됩니다.
+myObj.myFourthKey // = undefined
+
+///////////////////////////////////
+// 3. 로직과 제어 구조
+
+// if 구조는 여러분이 예상한 대로 동작합니다.
+var count = 1
+if (count == 3){
+ // count가 3일 경우 평가됨
+} else if (count == 4) {
+ // count가 4일 경우 평가됨
+} else {
+ // count가 3이나 4가 아닌 경우에 평가됨
+}
+
+// while도 마찬가지입니다.
+while (true) {
+ // 무한 루프!
+}
+
+// do-while 문은 항상 최소 한 번은 실행된다는 점을 제외하면
+// while 문과 비슷합니다.
+var input
+do {
+ input = getInput()
+} while (!isValid(input))
+
+// for 문은 C와 자바의 for 문과 같습니다.
+// 초기화식; 지속 조건; 증감식
+for (var i = 0; i < 5; i++){
+ // 5번 실행됨
+}
+
+// &&는 논리 and이고 ||는 논리 or입니다.
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear"
+}
+if (colour == "red" || colour == "blue"){
+ // 색은 빨강이거나 파랑
+}
+
+// &&와 ||은 "단축 평가"를 수행하는데, 기본값을 설정할 때 유용합니다.
+var name = otherName || "default"
+
+///////////////////////////////////
+// 4. 함수, 유효범위, 클로저
+
+// 자바스크립트 함수는 function 키워드로 선언합니다.
+function myFunction(thing){
+ return thing.toUpperCase()
+}
+myFunction("foo") // = "FOO"
+
+// 함수는 "익명"으로, 즉 이름 없이 정의할 수도 있습니다.
+function(thing){
+ return thing.toLowerCase()
+}
+// (함수를 가리키는 이름이 없기 때문에 함수를 호출할 수 없습니다)
+
+// 자바스크립트 함수는 일급 객체이므로 다른 변수에 재할당하고
+// 다른 함수에 인자로 전달할 수 있습니다. 가령, 이벤트 핸들러를 만들 경우
+function myFunction(){
+ // 이 코드는 5초 내에 호출됨
+}
+setTimeout(myFunction, 5000)
+
+// 다른 함수를 호출할 때 직접적으로 함수 구문을 작성할 수도 있습니다.
+
+setTimeout(function myFunction(){
+ // 이 코드는 5초 내에 호출됨
+}, 5000)
+
+// 자바스크립트에는 함수 유효범위가 있습니다.
+// 함수는 자체적인 유효범위를 가지지만 다른 블록은 유효범위를 가지지 않습니다.
+if (true){
+ var i = 5
+}
+i // = 5 - 블록 유효범위를 지원하는 언어에서는 undefined가 아닙니다.
+
+// 이것은 "즉시 실행되는 익명 함수"라는 공통 패턴으로 이어지는데,
+// 이 패턴은 임시 변수가 전역 유효범위로 유출되는 것을 방지합니다.
+(function(){
+ var temporary = 5
+ // '전역 객체'에 할당하는 식으로 전역 유효범위에 접근할 수 있는데,
+ // 브라우저에서 전역 객체는 항상 'window'입니다. 전역 객체는
+ // Node.js와 같은 브라우저가 아닌 환경에서는 다른 이름일 수도 있습니다.
+ window.permanent = 10
+ // 또는 앞에서 언급했다시피 var 키워드를 뺄 수도 있습니다.
+ permanent2 = 15
+})()
+temporary // ReferenceError 발생
+permanent // = 10
+permanent2 // = 15
+
+// 자바스크립트의 강력한 기능 중 하나는 클로저(closure)입니다.
+// 함수가 다른 함수 안에서 정의되면 안쪽에 정의된 함수는 바깥 함수의
+// 모든 변수에 접근할 수 있습니다.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!"
+ function inner(){
+ alert(prompt)
+ }
+ setTimeout(inner, 5000)
+ // setTimeout은 비동기적으로 동작하므로 이 함수는 5초 동안
+ // 기다리지 않고 실행을 마칩니다. 하지만 5초가 지나면 inner에서도
+ // prompt의 값에 접근할 수 있습니다.
+}
+sayHelloInFiveSeconds("Adam") // 5초 내로 "Hello, Adam!"이라고 적힌 팝업이 표시됨
+
+///////////////////////////////////
+// 5. 객체 심화; 생성자와 프로토타입
+
+// 객체는 함수를 포함할 수 있습니다.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!"
+ }
+}
+myObj.myFunc() // = "Hello world!"
+
+// 객체에 포함된 함수가 호출되면 함수에서는 this 키워드를 이용해
+// 해당 함수가 포함된 객체에 접근할 수 있습니다.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString
+ }
+}
+myObj.myFunc() // = "Hello world!"
+
+// 여기서 설정한 것은 함수가 정의된 곳이 아닌 함수가 호출되는
+// 방식과 관련이 있습니다. 그래서 아래 함수는 객체 컨텍스트에서
+// 호출되지 않으면 동작하지 않습니다.
+var myFunc = myObj.myFunc
+myFunc() // = undefined
+
+// 반대로 함수는 객체에 할당하고 this를 통해 해당 객체에 접근할 수 있습니다.
+// 함수를 정의할 때 객체에 추가되지 않았더라도 마찬가지입니다.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase()
+}
+myObj.myOtherFunc = myOtherFunc
+myObj.myOtherFunc() // = "HELLO WORLD!"
+
+// new 키워드로 함수를 호출하면 새로운 객체가 생성되고 this를 통해
+// 함수에서 사용할 수 있게 됩니다. 이런 식으로 설계된 함수를 생성자라 합니다.
+
+var MyConstructor = function(){
+ this.myNumber = 5
+}
+myNewObj = new MyConstructor() // = {myNumber: 5}
+myNewObj.myNumber // = 5
+
+// 모든 자바스크립트 객체는 'prototype'을 가지고 있습니다. 어떤 객체에 대해
+// 실제 객체에는 존재하지 않는 프로퍼티에 접근하면 인터프리터는 프로로타입에서
+// 해당 프로퍼티를 찾습니다.
+
+// 일부 자바스크립트 구현체에서는 __proto__라는 마법의 프로퍼티로
+// 객체의 프로토타입에 접근하는 것을 허용하기도 합니다. 프로토타입을
+// 설명하기에는 이런 내용도 도움되겠지만 __proto__는 표준에 포함돼
+// 있지 않습니다. 나중에 프로토타입을 사용하는 표준 방법을 살펴보겠습니다.
+var myObj = {
+ myString: "Hello world!",
+}
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+}
+myObj.__proto__ = myPrototype
+myObj.meaningOfLife // = 42
+
+// 이 방법은 함수에도 통합니다.
+myObj.myFunc() // = "hello world!"
+
+// 물론 프로퍼티가 프로토타입에 존재하지 않으면
+// 프로토타입의 프로토타입을 찾는 식으로 진행됩니다.
+myPrototype.__proto__ = {
+ myBoolean: true
+}
+myObj.myBoolean // = true
+
+// 여기서 복사는 일어나지 않습니다. 각 객체에는 프로토타입에 대한
+// 참조가 보관돼 있습니다. 이는 프로토타입을 변경하면 변경사항이
+// 모든 곳에 반영된다는 의미입니다.
+myPrototype.meaningOfLife = 43
+myObj.meaningOfLife // = 43
+
+// 앞에서 __proto__가 표준에 포함돼 있지 않다고 이야기했는데,
+// 기존 객체의 프로토타입을 변경하는 표준 방법은 없습니다.
+// 하지만 특정 프로토타입을 가지고 새로운 객체를 생성하는 두 가지
+// 방법이 있습니다.
+
+// 첫 번째 방법은 Object.create를 이용하는 것인데,
+// Object.create는 최근에 자바스크립트에 추가된 것이라서 아직까지
+// 모든 구현체에서 이용할 수 있는 것은 아닙니다.
+var myObj = Object.create(myPrototype)
+myObj.meaningOfLife // = 43
+
+// 두 번째 방법은 어디서나 통하는 방법인데, 생성자와 관련이 있습니다.
+// 생성자에는 prototype이라는 프로퍼티가 있습니다. 이 프로퍼티는
+// 생성자 함수 자체의 프로토타입이 *아니고* 생성자와 new 키워드를 이용해
+// 객체가 생성될 때 새로운 객체가 받는 프로토타입입니다.
+myConstructor.prototype = {
+ getMyNumber: function(){
+ return this.myNumber
+ }
+}
+var myNewObj2 = new myConstructor()
+myNewObj2.getMyNumber() // = 5
+
+// 문자열과 숫자와 같은 내장 타입에도 동등한 래퍼 객체를
+// 생성하는 생성자가 있습니다.
+var myNumber = 12
+var myNumberObj = new Number(12)
+myNumber == myNumberObj // = true
+
+// 하지만 정확히 같지는 않습니다.
+typeof(myNumber) // = 'number'
+typeof(myNumberObj) // = 'object'
+myNumber === myNumberObj // = false
+if (0){
+ // 0은 거짓이라서 이 코드는 실행되지 않습니다.
+}
+if (Number(0)){
+ // Number(0)은 참이라서 이 코드는 *실행됩니다*.
+}
+
+// 하지만 래퍼 객체와 일반 내장 함수는 프로토타입을 공유하기 때문에
+// 가령 문자열에 실제로 기능을 추가할 수 있습니다.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0)
+}
+"abc".firstCharacter() // = "a"
+
+// 이러한 사실은 기존 자바스크립트 버전에서 자바스크립트의
+// 새로운 기능을 구현하는 "폴리필(polyfilling)"에 자주 이용되므로
+// 오래된 버전의 브라우저와 같이 기존 환경에서 사용될 수 있습니다.
+
+// 예를 들어, Object.create가 모든 구현체에서 사용 가능한 것은 아니라고
+// 했지만 아래의 폴리필을 이용해 Object.create를 여전히 사용할 수 있습니다.
+if (Object.create === undefined){ // 이미 존재하면 덮어쓰지 않음
+ Object.create = function(proto){
+ // 올바른 프로토타입을 가지고 임시 생성자를 만듬
+ var Constructor = function(){}
+ Constructor.prototype = proto
+ // 그런 다음 임시 생성자를 이용해 새로운 적절한 프로토타입을
+ // 포함한 객체를 생성
+ return new Constructor()
+ }
+}
+```
+
+## 기타 참고 자료
+
+[모질라 개발자 네트워크](https://developer.mozilla.org/en-US/docs/Web/JavaScript)에서는
+자바스크립트에 대한 훌륭한 문서를 제공합니다. 더불어 위키 형식이라서 좀 더 많은 사항을
+배우게 되면 여러분만의 지식을 공유함으로써 다른 사람들에게 도움을 줄 수도 있습니다.
+
+MDN의 ['자바스크립트 재입문'](https://developer.mozilla.org/ko/docs/A_re-introduction_to_JavaScript)에서는
+여기서 다룬 개념의 상당수를 더욱 자세히 다루고 있습니다. 이 자료에서는 자바스크립트 언어 자체에
+대해서만 상당히 신중하게 다뤘습니다. 웹 페이지에서 자바스크립트를 사용하는 방법을 배우고 싶다면
+[문서 객체 모델(Document Object Model)](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)에
+관해 배우는 것으로 시작하길 바랍니다.
+
+[자바스크립트 가든](http://bonsaiden.github.io/JavaScript-Garden/)에서는 자바스크립트 언어에서
+직관에 어긋나는 모든 부분들을 심도 있게 다룹니다.
+
+더불어 이 글에 직접적으로 기여한 분들로, 내용 중 일부는 이 사이트에 있는
+루이 딘(Louie Dihn)의 파이썬 튜토리얼과 모질라 개발자 네트워크에 있는
+[자바스크립트 튜토리얼](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)을 참고했습니다.
diff --git a/ko-kr/lua-kr.html.markdown b/ko-kr/lua-kr.html.markdown
new file mode 100644
index 00000000..850587a0
--- /dev/null
+++ b/ko-kr/lua-kr.html.markdown
@@ -0,0 +1,422 @@
+---
+language: lua
+category: language
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+lang: ko-kr
+filename: learnlua-kr.lua
+---
+
+```lua
+-- 대시 두 개는 한 줄짜리 주석을 의미합니다.
+
+--[[
+ [와 ]를 두 개씩 추가하면 여러 줄 주석이 됩니다.
+--]]
+
+----------------------------------------------------
+-- 1. 변수와 흐름 제어
+----------------------------------------------------
+
+num = 42 -- 모든 숫자는 double입니다.
+-- 놀랄 필요는 없습니다. 64비트 double은
+-- 정확한 int 값을 저장하기 위해 52비트로 구성돼
+-- 있습니다. 52비트 이하의 int 값에 대해서는
+-- 장비 정밀도와 관련된 문제가 생기지 않습니다.
+
+s = 'walternate' -- 파이썬과 같은 불변 문자열
+t = "큰따옴표를 써도 됩니다"
+u = [[ 이중 대괄호는
+ 여러 줄 문자열을
+ 나타냅니다.]]
+t = nil -- 미정의 t. 루아는 가비지 컬렉션을 지원합니다.
+
+-- 블록은 do/end와 같은 키워드로 나타냅니다:
+while num < 50 do
+ num = num + 1 -- ++나 += 유형의 연산자는 쓸 수 없습니다.
+end
+
+-- If 절:
+if num > 40 then
+ print('40 이상')
+elseif s ~= 'walternate' then -- ~=은 '같지 않다'입니다.
+ -- 동일성 검사는 파이썬과 마찬가지로 ==입니다.
+ -- 문자열에도 쓸 수 있습니다.
+ io.write('not over 40\n') -- 기본적으로 stdout에 씁니다.
+else
+ -- 변수는 기본적으로 전역 변수입니다.
+ thisIsGlobal = 5 -- 낙타 표기법이 일반적입니다.
+
+ -- 변수를 지역 변수로 만드는 방법은 다음과 같습니다:
+ local line = io.read() -- 다음 stdin 줄을 읽습니다
+
+ -- 문자열 연결에는 .. 연산자를 씁니다:
+ print('겨울이 오고 있습니다, ' .. line)
+end
+
+-- 미정의 변수는 nil을 반환합니다.
+-- 다음 코드를 실행해도 오류가 나지 않습니다:
+foo = anUnknownVariable -- 이제 foo는 nil입니다.
+
+aBoolValue = false
+
+-- nil과 false만이 거짓값입니다; 0과 ''은 참입니다!
+if not aBoolValue then print('twas false') end
+
+-- 'or'와 'and'는 단축 평가(short-circuit)됩니다.
+-- 다음 코드는 C/자바스크립트의 a?b:c 연산자와 비슷합니다:
+ans = aBoolValue and 'yes' or 'no' --> 'no'
+
+karlSum = 0
+for i = 1, 100 do -- 범위에는 마지막 요소도 포함됩니다.
+ karlSum = karlSum + i
+end
+
+-- 카운트 다운을 할 때는 "100, 1, -1"을 범위로 씁니다.
+fredSum = 0
+for j = 100, 1, -1 do fredSum = fredSum + j end
+
+-- 일반적으로 범위는 begin, end[, step]입니다.
+
+-- 또 다른 반복문 구문은 다음과 같습니다:
+repeat
+ print('미래의 방식')
+ num = num - 1
+until num == 0
+
+
+----------------------------------------------------
+-- 2. 함수
+----------------------------------------------------
+
+function fib(n)
+ if n < 2 then return n end
+ return fib(n - 2) + fib(n - 1)
+end
+
+-- 클로저와 익명 함수도 사용할 수 있습니다:
+function adder(x)
+ -- 반환된 함수는 adder가 호출될 때 생성되고 x의
+ -- 값이 유지됩니다:
+ return function (y) return x + y end
+end
+a1 = adder(9)
+a2 = adder(36)
+print(a1(16)) --> 25
+print(a2(64)) --> 100
+
+-- 반환문, 함수 호출, 할당문은 길이가 다른
+-- 값의 리스트에 대해서도 모두 동작합니다.
+-- 리스트에 값이 더 적을 때는 nil이 할당/반환되고
+-- 리스트에 값이 더 많을 때는 나머지 값은 버려집니다.
+
+x, y, z = 1, 2, 3, 4
+-- 이제 x = 1, y = 2, z = 3이고 4는 버려집니다.
+
+function bar(a, b, c)
+ print(a, b, c)
+ return 4, 8, 15, 16, 23, 42
+end
+
+x, y = bar('zaphod') --> "zaphod nil nil"가 출력
+-- 이제 x = 4, y = 8이고 15~42의 값은 버려집니다.
+
+-- 함수는 일급 객체이고, 지역/전역 유효범위를 가질
+-- 수 있습니다. 아래의 두 함수는 같습니다:
+function f(x) return x * x end
+f = function (x) return x * x end
+
+-- 그리고 아래의 두 함수도 마찬가지입니다:
+local function g(x) return math.sin(x) end
+local g; g = function (x) return math.sin(x) end
+-- 'local g'라고 선언하면 g를 지역 함수로 만듭니다.
+
+-- 그나저나 삼각 함수는 라디안 단위로 동작합니다.
+
+-- 함수를 호출할 때 문자열 매개변수를 하나만 전달한다면
+-- 괄호를 쓰지 않아도 됩니다:
+print 'hello' -- 잘 동작합니다.
+
+
+----------------------------------------------------
+-- 3. 테이블
+----------------------------------------------------
+
+-- 테이블 = 루아의 유일한 복합 자료구조로서, 연관 배열입니다.
+-- PHP의 배열이나 자바스크립트의 객체와 비슷하며,
+-- 리스트로도 사용할 수 있는 해시 기반의 딕셔너리입니다.
+
+-- 테이블을 딕셔너리/맵으로 사용하기:
+
+-- 딕셔너리 리터럴은 기본적으로 문자열 키를 가집니다:
+t = {key1 = 'value1', key2 = false}
+
+-- 문자열 키에는 자바스크립트와 유사한 점 표기법을 쓸 수 있습니다:
+print(t.key1) -- 'value1'을 출력.
+t.newKey = {} -- 새 키/값 쌍을 추가.
+t.key2 = nil -- 테이블에서 key2를 제거.
+
+-- (nil이 아닌) 값을 키로 사용하는 리터럴 표기법:
+u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
+print(u[6.28]) -- "tau"가 출력
+
+-- 키 매칭은 기본적으로 숫자와 문자열에 대해서는 값으로 하지만
+-- 테이블에 대해서는 식별자로 합니다.
+a = u['@!#'] -- Now a = 'qbert'.
+b = u[{}] -- We might expect 1729, but it's nil:
+a = u['@!#'] -- 이제 a는 'qbert'입니다.
+b = u[{}] -- 1729를 예상했겠지만 nil입니다:
+-- 탐색이 실패하기 때문에 b는 nil입니다. 탐색이 실패하는 이유는
+-- 사용된 키가 원본 값을 저장할 때 사용한 키와 동일한 객체가 아니기
+-- 때문입니다. 따라서 문자열 및 숫자가 좀 더 이식성 있는 키입니다.
+
+-- 테이블 하나를 매개변수로 취하는 함수를 호출할 때는 괄호가 필요하지 않습니다:
+function h(x) print(x.key1) end
+h{key1 = 'Sonmi~451'} -- 'Sonmi~451'를 출력.
+
+for key, val in pairs(u) do -- 테이블 순회
+ print(key, val)
+end
+
+-- _G는 모든 전역 멤버에 대한 특별한 테이블입니다.
+print(_G['_G'] == _G) -- 'true'가 출력
+
+-- 테이블을 리스트/배열로 사용하기:
+
+-- 리스트 리터럴은 암묵적으로 int 키로 설정됩니다:
+v = {'value1', 'value2', 1.21, 'gigawatts'}
+for i = 1, #v do -- #v는 리스트 v의 크기입니다.
+ print(v[i]) -- 인덱스가 1에서 시작합니다!! 제정신이 아닙니다!
+end
+-- 'list'는 실제 타입이 아닙니다. v는 연속된 정수형 키가 포함된
+-- 테이블이고 리스트로 취급될 뿐입니다.
+
+----------------------------------------------------
+-- 3.1 메타테이블과 메타메서드
+----------------------------------------------------
+
+-- 테이블은 테이블에 연산자 오버로딩을 가능하게 하는 메타테이블을
+-- 가질 수 있습니다. 나중에 메타테이블이 어떻게 자바스크립트
+-- 프로토타입과 같은 행위를 지원하는지 살펴보겠습니다.
+
+f1 = {a = 1, b = 2} -- 분수 a/b를 표현
+f2 = {a = 2, b = 3}
+
+-- 다음 코드는 실패합니다:
+-- s = f1 + f2
+
+metafraction = {}
+function metafraction.__add(f1, f2)
+ 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 -- f1의 메타테이블을 대상으로 __add(f1, f2)를 호출
+
+-- f1과 f2는 자바스크립트의 프로토타입과 달리 각 메타테이블에 대한
+-- 키가 없어서 getmetatable(f1)과 같이 받아와야 합니다.
+-- 메타테이블은 __add 같은 루아가 알고 있는 키가 지정된 일반 테이블입니다.
+
+-- 그렇지만 다음 줄은 s가 메타테이블을 가지고 있지 않기 때문에 실패합니다.
+-- t = s + s
+-- 아래와 같이 클래스와 유사한 패턴은 이러한 문제가 발생하지 않습니다.
+
+-- 메타테이블에 대한 __index는 점을 이용한 탐색을 오버로드합니다:
+defaultFavs = {animal = 'gru', food = 'donuts'}
+myFavs = {food = 'pizza'}
+setmetatable(myFavs, {__index = defaultFavs})
+eatenBy = myFavs.animal -- 동작합니다! 고마워요, 메타테이블!
+
+-- 직접적인 메타테이블 탐색이 실패할 경우 메타테이블의 __index 값을 이용해
+-- 재시도하고, 이런 과정이 반복됩니다.
+
+-- __index 값은 좀 더 세분화된 탐색을 위해 function(tbl, key)가
+-- 될 수도 있습니다.
+
+-- __index, __add, ...의 값을 메타메서드라고 합니다.
+-- 다음은 메타메서드를 가진 테이블의 전체 목록입니다.
+
+-- __add(a, b) for a + b
+-- __sub(a, b) for a - b
+-- __mul(a, b) for a * b
+-- __div(a, b) for a / b
+-- __mod(a, b) for a % b
+-- __pow(a, b) for a ^ b
+-- __unm(a) for -a
+-- __concat(a, b) for a .. b
+-- __len(a) for #a
+-- __eq(a, b) for a == b
+-- __lt(a, b) for a < b
+-- __le(a, b) for a <= b
+-- __index(a, b) <fn이나 테이블> for a.b
+-- __newindex(a, b, c) for a.b = c
+-- __call(a, ...) for a(...)
+
+----------------------------------------------------
+-- 3.2 클래스 형태의 테이블과 상속
+----------------------------------------------------
+
+-- 루아에는 클래스가 내장돼 있지 않으며, 테이블과 메타테이블을
+-- 이용해 클래스를 만드는 다양한 방법이 있습니다.
+
+-- 다음 예제에 대한 설명은 하단을 참조합니다.
+
+Dog = {} -- 1.
+
+function Dog:new() -- 2.
+ newObj = {sound = 'woof'} -- 3.
+ self.__index = self -- 4.
+ return setmetatable(newObj, self) -- 5.
+end
+
+function Dog:makeSound() -- 6.
+ print('I say ' .. self.sound)
+end
+
+mrDog = Dog:new() -- 7.
+mrDog:makeSound() -- 'I say woof' -- 8.
+
+-- 1. Dog는 클래스처럼 동작합니다. 실제로는 테이블입니다.
+-- 2. function 테이블명:fn(...)은
+-- function 테이블명.fn(self, ...)과 같습니다.
+-- :는 self라는 첫 번째 인자를 추가할 뿐입니다.
+-- self가 값을 어떻게 얻는지 궁금하다면 아래의 7과 8을 읽어보세요.
+-- 3. newObj는 Dog 클래스의 인스턴스가 됩니다.
+-- 4. self = 인스턴스화되는 클래스.
+-- 주로 self = Dog이지만 상속을 이용하면 이것을 바꿀 수 있습니다.
+-- newObj의 메타테이블과 self의 __index를 모두 self에 설정하면
+-- newObj가 self의 함수를 갖게 됩니다.
+-- 5. 참고: setmetatable은 첫 번째 인자를 반환합니다.
+-- 6. :는 2에서 설명한 것과 같이 동작하지만 이번에는 self가
+-- 클래스가 아닌 인스턴스라고 예상할 수 있습니다.
+-- 7. Dog.new(Dog)과 같으므로 new()에서는 self = Dog입니다.
+-- 8. mrDog.makeSound(mrDog)과 같으므로 self = mrDog입니다.
+
+----------------------------------------------------
+
+-- 상속 예제:
+
+LoudDog = Dog:new() -- 1.
+
+function LoudDog:makeSound()
+ s = self.sound .. ' ' -- 2.
+ print(s .. s .. s)
+end
+
+seymour = LoudDog:new() -- 3.
+seymour:makeSound() -- 'woof woof woof' -- 4.
+
+-- 1. LoudDog은 Dog의 메서드와 변수를 갖게 됩니다.
+-- 2. self는 new()에서 'sound' 키를 가집니다. 3을 참고하세요.
+-- 3. LoudDog.new(LoudDog)과 같고, LoudDog은 'new' 키가 없지만
+-- 메타테이블에서 __index = Dog이기 때문에 Dog.new(LoudDog)으로
+-- 변환됩니다.
+-- 결과: seymour의 메타테이블은 LoudDog이고 LoudDog.__index는
+-- LoudDog입니다. 따라서 seymour.key는 seymour.key,
+-- LoudDog.key, Dog.key와 같을 것이며, 지정한 키에 어떤 테이블이
+-- 오든 상관없을 것입니다.
+-- 4. 'makeSound' 키는 LoudDog에서 발견할 수 있습니다.
+-- 이것은 LoudDog.makeSound(seymour)와 같습니다.
+
+-- 필요할 경우, 하위 클래스의 new()는 기반 클래스의 new()와 유사합니다.
+function LoudDog:new()
+ newObj = {}
+ -- newObj를 구성
+ self.__index = self
+ return setmetatable(newObj, self)
+end
+
+----------------------------------------------------
+-- 4. 모듈
+----------------------------------------------------
+
+
+--[[ 여기서 주석을 제거하면 이 스크립트의 나머지 부분은
+-- 실행 가능한 상태가 됩니다.
+```
+
+```lua
+-- mod.lua 파일의 내용이 다음과 같다고 가정해 봅시다.
+local M = {}
+
+local function sayMyName()
+ print('이소룡')
+end
+
+function M.sayHello()
+ print('안녕하세요')
+ sayMyName()
+end
+
+return M
+
+-- 또 다른 파일에서는 mod.lua의 기능을 이용할 수 있습니다.
+local mod = require('mod') -- mod.lua 파일을 실행
+
+-- require는 모듈을 포함시키는 표준화된 방법입니다.
+-- require는 다음과 같이 동작합니다: (캐싱돼 있지 않을 경우. 하단 참조)
+-- mod.lua가 함수의 본문처럼 되므로 mod.lua 안의 지역 멤버는
+-- 밖에서 볼 수 없습니다.
+
+-- 다음 코드가 동작하는 것은 mod가 mod.lua의 M과 같기 때문입니다.
+mod.sayHello() -- 이소룡 씨에게 인사를 건넵니다.
+
+-- 다음 코드를 실행하면 오류가 발생합니다.
+-- sayMyName는 mod.lua 안에서만 존재하기 때문입니다:
+mod.sayMyName() -- 오류
+
+-- require의 반환값은 캐싱되므로 require를 여러 번 실행해도
+-- 파일은 최대 한 번만 실행됩니다.
+
+-- mod2.lua에 "print('Hi')"가 들어 있다고 가정해 봅시다.
+local a = require('mod2') -- Hi!를 출력
+local b = require('mod2') -- print를 실행하지 않음. a=b
+
+-- dofile은 require와 비슷하지만 캐싱을 하지 않습니다:
+dofile('mod2') --> Hi!
+dofile('mod2') --> Hi! (require와 달리 다시 한번 실행됨)
+
+-- loadfile은 루아 파일을 읽어들이지만 실행하지는 않습니다
+f = loadfile('mod2') -- f()를 호출해야 mod2.lua가 실행됩니다.
+
+-- loadstring은 문자열에 대한 loadfile입니다.
+g = loadstring('print(343)') -- 함수를 반환합니다.
+g() -- 343이 출력됩니다. 그전까지는 아무것도 출력되지 않습니다.
+
+--]]
+
+```
+
+## 참고자료
+
+루아를 배우는 일이 흥미진진했던 이유는 <a href="http://love2d.org/">Love 2D 게임 엔진</a>을 이용해
+게임을 만들 수 있었기 때문입니다. 이것이 제가 루아를 배운 이유입니다.
+
+저는 <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV의 "프로그래머를 위한 루아"</a>로
+시작했습니다. 그다음으로 공식 <a href="http://www.lua.org/pil/contents.html">"프로그래밍 루아"</a> 책을 읽었습니다.
+그렇게 루아를 배웠습니다.
+
+lua-users.org에 있는 <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">짧은 루아 레퍼런스</a>를
+읽어두면 도움될지도 모르겠습니다.
+
+여기서는 표준 라이브러리에 관해서는 다루지 않았습니다.
+
+* <a href="http://lua-users.org/wiki/StringLibraryTutorial">string 라이브러리</a>
+* <a href="http://lua-users.org/wiki/TableLibraryTutorial">table 라이브러리</a>
+* <a href="http://lua-users.org/wiki/MathLibraryTutorial">math 라이브러리</a>
+* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io 라이브러리</a>
+* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os 라이브러리</a>
+
+그나저나 이 파일 전체는 유효한 루아 프로그램입니다. 이 파일을
+learn.lua로 저장한 후 "lua learn.lua"를 실행해 보세요!
+
+이 글은 tylerneylon.com에 처음으로 써본 글이며,
+<a href="https://gist.github.com/tylerneylon/5853042">Github의 Gist</a>에서도 확인할 수 있습니다.
+루아로 즐거운 시간을 보내세요!
diff --git a/ko-kr/php-kr.html.markdown b/ko-kr/php-kr.html.markdown
new file mode 100644
index 00000000..80f324f3
--- /dev/null
+++ b/ko-kr/php-kr.html.markdown
@@ -0,0 +1,662 @@
+---
+language: php
+category: language
+contributors:
+ - ["Malcolm Fell", "http://emarref.net/"]
+ - ["Trismegiste", "https://github.com/Trismegiste"]
+filename: learnphp-kr.php
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+lang: ko-kr
+---
+
+이 문서에서는 PHP 5+를 설명합니다.
+
+
+```php
+<?php // PHP 코드는 반드시 <?php 태그로 감싸야 합니다.
+
+// php 파일에 PHP 코드만 들어 있다면 닫는 태그를 생략하는 것이 관례입니다.
+
+// 슬래시 두 개는 한 줄 주석을 의미합니다.
+
+# 해시(파운드 기호로도 알려진)도 같은 역할을 하지만 //이 더 일반적으로 쓰입니다.
+
+/*
+ 텍스트를 슬래시-별표와 별표-슬래시로 감싸면
+ 여러 줄 주석이 만들어집니다.
+*/
+
+// 출력결과를 표시하려면 "echo"나 "print"를 사용합니다.
+print('Hello '); // 줄바꿈 없이 "Hello "를 출력합니다.
+
+// ()는 print와 echo를 사용할 때 선택적으로 사용할 수 있습니다.
+echo "World\n"; // "World"를 출력한 후 줄바꿈합니다.
+// (모든 구문은 반드시 세미콜론으로 끝나야 합니다.)
+
+// <?php 태그 밖의 내용은 모두 자동으로 출력됩니다.
+?>
+Hello World Again!
+<?php
+
+
+/************************************
+ * 타입과 변수
+ */
+
+// 변수명은 $ 기호로 시작합니다.
+// 유효한 변수명은 문자나 밑줄(_)로 시작하고,
+// 이어서 임의 개수의 숫자나 문자, 밑줄이 옵니다.
+
+// 불린값은 대소문자를 구분합니다.
+$boolean = true; // 또는 TRUE나 True
+$boolean = false; // 또는 FALSE나 False
+
+// Integer
+$int1 = 12; // => 12
+$int2 = -12; // => -12
+$int3 = 012; // => 10 (a leading 0 denotes an octal number)
+$int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal)
+
+// Float (doubles로도 알려짐)
+$float = 1.234;
+$float = 1.2e3;
+$float = 7E-10;
+
+// 산술 연산
+$sum = 1 + 1; // 2
+$difference = 2 - 1; // 1
+$product = 2 * 2; // 4
+$quotient = 2 / 1; // 2
+
+// 축약형 산술 연산
+$number = 0;
+$number += 1; // $number를 1만큼 증가
+echo $number++; // 1을 출력(평가 후 증가)
+echo ++$number; // 3 (평가 전 증가)
+$number /= $float; // 나눗셈 후 몫을 $number에 할당
+
+// 문자열은 작은따옴표로 감싸야 합니다.
+$sgl_quotes = '$String'; // => '$String'
+
+// 다른 변수를 포함할 때를 제외하면 큰따옴표 사용을 자제합니다.
+$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
+
+// 특수 문자는 큰따옴표에서만 이스케이프됩니다.
+$escaped = "This contains a \t tab character.";
+$unescaped = 'This just contains a slash and a t: \t';
+
+// 필요할 경우 변수를 중괄호로 감쌉니다.
+$money = "I have $${number} in the bank.";
+
+// PHP 5.3부터는 여러 줄 문자열을 생성하는 데 나우닥(nowdoc)을 사용할 수 있습니다.
+$nowdoc = <<<'END'
+Multi line
+string
+END;
+
+// 히어닥(heredoc)에서는 문자열 치환을 지원합니다.
+$heredoc = <<<END
+Multi line
+$sgl_quotes
+END;
+
+// 문자열을 연결할 때는 .을 이용합니다.
+echo 'This string ' . 'is concatenated';
+
+
+/********************************
+ * 상수
+ */
+
+// 상수는 define()을 이용해 정의되며,
+// 런타임 동안 절대 변경될 수 없습니다!
+
+// 유효한 상수명은 문자나 밑줄로 시작하고,
+// 이어서 임의 개수의 숫자나 문자, 밑줄이 옵니다.
+define("FOO", "something");
+
+// 상수명을 이용해 직접 상수에 접근할 수 있습니다.
+echo 'This outputs '.FOO;
+
+
+/********************************
+ * 배열
+ */
+
+// PHP의 모든 배열은 연관 배열(associative array, 해시맵)입니다.
+
+// 일부 언어에서 해시맵으로도 알려진 연관 배열은
+
+// 모든 PHP 버전에서 동작합니다.
+$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
+
+// PHP 5.4에서는 새로운 문법이 도입됐습니다.
+$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
+
+echo $associative['One']; // 1을 출력
+
+// 리스트 리터럴은 암시적으로 정수형 키를 할당합니다.
+$array = ['One', 'Two', 'Three'];
+echo $array[0]; // => "One"
+
+
+/********************************
+ * 출력
+ */
+
+echo('Hello World!');
+// 표준출력(stdout)에 Hello World!를 출력합니다.
+// 브라우저에서 실행할 경우 표준출력은 웹 페이지입니다.
+
+print('Hello World!'); // echo과 동일
+
+// echo는 실제로 언어 구성물에 해당하므로, 괄호를 생략할 수 있습니다.
+echo 'Hello World!';
+print 'Hello World!'; // 똑같이 출력됩니다.
+
+$paragraph = 'paragraph';
+
+echo 100; // 스칼라 변수는 곧바로 출력합니다.
+echo $paragraph; // 또는 변수의 값을 출력합니다.
+
+// 축약형 여는 태그를 설정하거나 PHP 버전이 5.4.0 이상이면
+// 축약된 echo 문법을 사용할 수 있습니다.
+?>
+<p><?= $paragraph ?></p>
+<?php
+
+$x = 1;
+$y = 2;
+$x = $y; // 이제 $x의 값은 $y의 값과 같습니다.
+$z = &$y;
+// $z는 이제 $y에 대한 참조를 담고 있습니다. $z의 값을 변경하면
+// $y의 값도 함께 변경되며, 그 반대도 마찬가지입니다.
+// $x는 $y의 원래 값을 그대로 유지합니다.
+
+echo $x; // => 2
+echo $z; // => 2
+$y = 0;
+echo $x; // => 2
+echo $z; // => 0
+
+
+/********************************
+ * 로직
+ */
+$a = 0;
+$b = '0';
+$c = '1';
+$d = '1';
+
+// assert는 인자가 참이 아닌 경우 경고를 출력합니다.
+
+// 다음과 같은 비교는 항상 참이며, 타입이 같지 않더라도 마찬가지입니다.
+assert($a == $b); // 동일성 검사
+assert($c != $a); // 불일치성 검사
+assert($c <> $a); // 또 다른 불일치성 검사
+assert($a < $c);
+assert($c > $b);
+assert($a <= $b);
+assert($c >= $d);
+
+// 다음과 같은 코드는 값과 타입이 모두 일치하는 경우에만 참입니다.
+assert($c === $d);
+assert($a !== $d);
+assert(1 == '1');
+assert(1 !== '1');
+
+// 변수는 어떻게 사용하느냐 따라 다른 타입으로 변환될 수 있습니다.
+
+$integer = 1;
+echo $integer + $integer; // => 2
+
+$string = '1';
+echo $string + $string; // => 2 (문자열이 강제로 정수로 변환됩니다)
+
+$string = 'one';
+echo $string + $string; // => 0
+// + 연산자는 'one'이라는 문자열을 숫자로 형변환할 수 없기 때문에 0이 출력됩니다.
+
+// 한 변수를 다른 타입으로 처리하는 데 형변환을 사용할 수 있습니다.
+
+$boolean = (boolean) 1; // => true
+
+$zero = 0;
+$boolean = (boolean) $zero; // => false
+
+// 대다수의 타입을 형변환하는 데 사용하는 전용 함수도 있습니다.
+$integer = 5;
+$string = strval($integer);
+
+$var = null; // 널 타입
+
+
+/********************************
+ * 제어 구조
+ */
+
+if (true) {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'I don\'t';
+} else {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'Does not get printed';
+} elseif(true) {
+ print 'Does';
+}
+
+// 사항 연산자
+print (false ? 'Does not get printed' : 'Does');
+
+$x = 0;
+if ($x === '0') {
+ print 'Does not print';
+} elseif($x == '1') {
+ print 'Does not print';
+} else {
+ print 'Does print';
+}
+
+
+
+// 다음과 같은 문법은 템플릿에 유용합니다.
+?>
+
+<?php if ($x): ?>
+This is displayed if the test is truthy.
+<?php else: ?>
+This is displayed otherwise.
+<?php endif; ?>
+
+<?php
+
+// 특정 로직을 표현할 때는 switch를 사용합니다.
+switch ($x) {
+ case '0':
+ print 'Switch does type coercion';
+ break; // break을 반드시 포함해야 하며, break를 생략하면
+ // 'two'와 'three' 케이스로 넘어갑니다.
+ case 'two':
+ case 'three':
+ // 변수가 'two'나 'three'인 경우에 실행될 코드를 작성합니다.
+ break;
+ default:
+ // 기본값으로 실행될 코드를 작성
+}
+
+// while과 do...while, for 문이 아마 더 친숙할 것입니다.
+$i = 0;
+while ($i < 5) {
+ echo $i++;
+}; // "01234"를 출력
+
+echo "\n";
+
+$i = 0;
+do {
+ echo $i++;
+} while ($i < 5); // "01234"를 출력
+
+echo "\n";
+
+for ($x = 0; $x < 10; $x++) {
+ echo $x;
+} // "0123456789"를 출력
+
+echo "\n";
+
+$wheels = ['bicycle' => 2, 'car' => 4];
+
+// foreach 문은 배영를 순회할 수 있습니다.
+foreach ($wheels as $wheel_count) {
+ echo $wheel_count;
+} // "24"를 출력
+
+echo "\n";
+
+// 키와 값을 동시에 순회할 수 있습니다.
+foreach ($wheels as $vehicle => $wheel_count) {
+ echo "A $vehicle has $wheel_count wheels";
+}
+
+echo "\n";
+
+$i = 0;
+while ($i < 5) {
+ if ($i === 3) {
+ break; // while 문을 빠져나옴
+ }
+ echo $i++;
+} // "012"를 출력
+
+for ($i = 0; $i < 5; $i++) {
+ if ($i === 3) {
+ continue; // 이번 순회를 생략
+ }
+ echo $i;
+} // "0124"를 출력
+
+
+/********************************
+ * 함수
+ */
+
+// "function"으로 함수를 정의합니다.
+function my_function () {
+ return 'Hello';
+}
+
+echo my_function(); // => "Hello"
+
+// 유효한 함수명은 문자나 밑줄로 시작하고, 이어서
+// 임의 개수의 문자나 숫자, 밑줄이 옵니다.
+
+function add ($x, $y = 1) { // $y는 선택사항이고 기본값은 1입니다.
+ $result = $x + $y;
+ return $result;
+}
+
+echo add(4); // => 5
+echo add(4, 2); // => 6
+
+// 함수 밖에서는 $result에 접근할 수 없습니다.
+// print $result; // 이 코드를 실행하면 경고가 출력됩니다.
+
+// PHP 5.3부터는 익명 함수를 선언할 수 있습니다.
+$inc = function ($x) {
+ return $x + 1;
+};
+
+echo $inc(2); // => 3
+
+function foo ($x, $y, $z) {
+ echo "$x - $y - $z";
+}
+
+// 함수에서는 함수를 반환할 수 있습니다.
+function bar ($x, $y) {
+ // 'use'를 이용해 바깥 함수의 변수를 전달합니다.
+ return function ($z) use ($x, $y) {
+ foo($x, $y, $z);
+ };
+}
+
+$bar = bar('A', 'B');
+$bar('C'); // "A - B - C"를 출력
+
+// 문자열을 이용해 이름이 지정된 함수를 호출할 수 있습니다.
+$function_name = 'add';
+echo $function_name(1, 2); // => 3
+// 프로그램 방식으로 어느 함수를 실행할지 결정할 때 유용합니다.
+// 아니면 call_user_func(callable $callback [, $parameter [, ... ]]);를 사용해도 됩니다.
+
+/********************************
+ * 인클루드
+ */
+
+<?php
+// 인클루드된 파일 내의 PHP 코드도 반드시 PHP 여는 태그로 시작해야 합니다.
+
+include 'my-file.php';
+// my-file.php 안의 코드는 이제 현재 유효범위에서 이용할 수 있습니다.
+// 파일을 인클루드할 수 없으면(예: 파일을 찾을 수 없음) 경고가 출력됩니다.
+
+include_once 'my-file.php';
+// my-file.php 안의 코드가 다른 곳에 인클루드됐다면 다시 인클루드되지는 않습니다.
+// 따라서 클래스 선언이 여러 번 되어 발생하는 문제가 일어나지 않습니다.
+
+require 'my-file.php';
+require_once 'my-file.php';
+// require()는 include()와 같지만 파일을 인클루드할 수 없을 경우
+// 치명적인 오류가 발생한다는 점이 다릅니다.
+
+// my-include.php의 내용
+<?php
+
+return 'Anything you like.';
+// 파일의 끝
+
+// include와 require는 값을 반환할 수도 있습니다.
+$value = include 'my-include.php';
+
+// 파일은 지정된 파일 경로를 토대로 인클루드되거나, 혹은 아무것도 명시하지 않은 경우
+// include_path라는 설정 지시지를 따릅니다. include_path에서 파일을 발견할 수 없으면
+// include는 마지막으로 실패하기 전에 호출 스크립트 자체의 디렉터리와 현재 작업 디렉터리를 확인합니다.
+/* */
+
+/********************************
+ * 클래스
+ */
+
+// 클래스는 class라는 키워드로 정의합니다.
+
+class MyClass
+{
+ const MY_CONST = 'value'; // 상수
+
+ static $staticVar = 'static';
+
+ // 프로퍼티에는 반드시 가시성을 선언해야 합니다.
+ public $property = 'public';
+ public $instanceProp;
+ protected $prot = 'protected'; // 이 클래스와 하위 클래스에서 접근할 수 있음
+ private $priv = 'private'; // 이 클래스 내에서만 접근 가능
+
+ // __construct로 생성자를 만듭니다.
+ public function __construct($instanceProp) {
+ // $this로 인스턴스 변수에 접근합니다.
+ $this->instanceProp = $instanceProp;
+ }
+
+ // 메서드는 클래스 안의 함수로서 선언됩니다.
+ public function myMethod()
+ {
+ print 'MyClass';
+ }
+
+ final function youCannotOverrideMe()
+ {
+ }
+
+ public static function myStaticMethod()
+ {
+ print 'I am static';
+ }
+}
+
+echo MyClass::MY_CONST; // 'value' 출력
+echo MyClass::$staticVar; // 'static' 출력
+MyClass::myStaticMethod(); // 'I am static' 출력
+
+// new를 사용해 클래스를 인스턴스화합니다.
+$my_class = new MyClass('An instance property');
+// 인자를 전달하지 않을 경우 괄호를 생략할 수 있습니다.
+
+// ->를 이용해 클래스 멤버에 접근합니다
+echo $my_class->property; // => "public"
+echo $my_class->instanceProp; // => "An instance property"
+$my_class->myMethod(); // => "MyClass"
+
+
+// "extends"를 이용해 클래스를 확장합니다.
+class MyOtherClass extends MyClass
+{
+ function printProtectedProperty()
+ {
+ echo $this->prot;
+ }
+
+ // 메서드 재정의
+ function myMethod()
+ {
+ parent::myMethod();
+ print ' > MyOtherClass';
+ }
+}
+
+$my_other_class = new MyOtherClass('Instance prop');
+$my_other_class->printProtectedProperty(); // => "protected" 출력
+$my_other_class->myMethod(); // "MyClass > MyOtherClass" 출력
+
+final class YouCannotExtendMe
+{
+}
+
+// "마법 메서드(magic method)"로 설정자 메서드와 접근자 메서드를 만들 수 있습니다.
+class MyMapClass
+{
+ private $property;
+
+ public function __get($key)
+ {
+ return $this->$key;
+ }
+
+ public function __set($key, $value)
+ {
+ $this->$key = $value;
+ }
+}
+
+$x = new MyMapClass();
+echo $x->property; // __get() 메서드를 사용
+$x->property = 'Something'; // __set() 메서드를 사용
+
+// 클래스는 추상화하거나(abstract 키워드를 사용해)
+// 인터페이스를 구현할 수 있습니다(implments 키워드를 사용해).
+// 인터페이스는 interface 키워드로 선언합니다.
+
+interface InterfaceOne
+{
+ public function doSomething();
+}
+
+interface InterfaceTwo
+{
+ public function doSomethingElse();
+}
+
+// 인터페이스는 확장할 수 있습니다.
+interface InterfaceThree extends InterfaceTwo
+{
+ public function doAnotherContract();
+}
+
+abstract class MyAbstractClass implements InterfaceOne
+{
+ public $x = 'doSomething';
+}
+
+class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo $x;
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+
+// 클래스에서는 하나 이상의 인터페이스를 구현할 수 있습니다.
+class SomeOtherClass implements InterfaceOne, InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo 'doSomething';
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+
+/********************************
+ * 특성
+ */
+
+// 특성(trait)은 PHP 5.4.0부터 사용 가능하며, "trait"으로 선언합니다.
+
+trait MyTrait
+{
+ public function myTraitMethod()
+ {
+ print 'I have MyTrait';
+ }
+}
+
+class MyTraitfulClass
+{
+ use MyTrait;
+}
+
+$cls = new MyTraitfulClass();
+$cls->myTraitMethod(); // "I have MyTrait"을 출력
+
+
+/********************************
+ * 네임스페이스
+ */
+
+// 이 부분은 별도의 영역인데, 파일에서 처음으로 나타나는 문장은
+// 네임스페이스 선언이어야 하기 때문입니다. 여기서는 그런 경우가 아니라고 가정합니다.
+
+<?php
+
+// 기본적으로 클래스는 전역 네임스페이스에 존재하며,
+// 백슬래시를 이용해 명시적으로 호출할 수 있습니다.
+
+$cls = new \MyClass();
+
+
+
+// 파일에 대한 네임스페이스를 설정합니다.
+namespace My\Namespace;
+
+class MyClass
+{
+}
+
+// (다른 파일에 들어 있는 코드)
+$cls = new My\Namespace\MyClass;
+
+// 또는 다른 네임스페이스 내에서 접근하는 경우
+namespace My\Other\Namespace;
+
+use My\Namespace\MyClass;
+
+$cls = new MyClass();
+
+// 혹은 네임스페이스에 별칭을 붙일 수도 있습니다.
+
+namespace My\Other\Namespace;
+
+use My\Namespace as SomeOtherNamespace;
+
+$cls = new SomeOtherNamespace\MyClass();
+
+*/
+
+```
+
+## 더 자세한 정보
+
+레퍼런스와 커뮤니티 관련 내용은 [공식 PHP 문서](http://www.php.net/manual/)를 참고하세요.
+
+최신 모범 사례에 관심이 있다면 [PHP The Right Way](http://www.phptherightway.com/)를 참고하세요.
+
+PHP를 익히기 전에 다른 훌륭한 패키지 관리자를 지원하는 언어를 사용해본 적이 있다면 [컴포저(Composer)](http://getcomposer.org/)를 확인해 보세요.
+
+공통 표준이 궁금하다면 PHP 프레임워크 상호운용성 그룹의 [PSR 표준](https://github.com/php-fig/fig-standards)을 참고하세요.
diff --git a/ko-kr/python-kr.html.markdown b/ko-kr/python-kr.html.markdown
new file mode 100644
index 00000000..ed377a99
--- /dev/null
+++ b/ko-kr/python-kr.html.markdown
@@ -0,0 +1,484 @@
+---
+language: python
+category: language
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+filename: learnpython-ko.py
+translators:
+ - ["wikibook", "http://wikibook.co.kr"]
+lang: ko-kr
+---
+
+파이썬은 귀도 반 로섬이 90년대에 만들었습니다. 파이썬은 현존하는 널리 사용되는 언어 중 하나입니다.
+저는 문법적 명료함에 반해 파이썬을 사랑하게 됐습니다. 파이썬은 기본적으로 실행 가능한 의사코드입니다.
+
+피드백 주시면 정말 감사하겠습니다! [@louiedinh](http://twitter.com/louiedinh)나
+louiedinh [at] [구글의 이메일 서비스]를 통해 저에게 연락하시면 됩니다.
+
+참고: 이 글은 구체적으로 파이썬 2.7에 해당하는 내용을 담고 있습니다만
+파이썬 2.x에도 적용할 수 있을 것입니다. 파이썬 3을 다룬 튜토리얼도 곧 나올 테니 기대하세요!
+
+```python
+# 한 줄짜리 주석은 해시로 시작합니다.
+""" 여러 줄 문자열은 "를 세 개 써서 시작할 수 있고,
+ 주석으로 자주 사용됩니다.
+"""
+
+####################################################
+## 1. 기본 자료형과 연산자
+####################################################
+
+# 숫자
+3 #=> 3
+
+# 수학 연산은 예상하신 대로입니다.
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# 나눗셈은 약간 까다롭습니다. 정수로 나눈 다음 결과값을 자동으로 내림합니다.
+5 / 2 #=> 2
+
+# 나눗셈 문제를 해결하려면 float에 대해 알아야 합니다.
+2.0 # 이것이 float입니다.
+11.0 / 4.0 #=> 2.75 훨씬 낫네요
+
+# 괄호를 이용해 연산자 우선순위를 지정합니다.
+(1 + 3) * 2 #=> 8
+
+# 불린(Boolean) 값은 기본형입니다.
+True
+False
+
+# not을 이용해 부정합니다.
+not True #=> False
+not False #=> True
+
+# 동일성 연산자는 ==입니다.
+1 == 1 #=> True
+2 == 1 #=> False
+
+# 불일치 연산자는 !=입니다.
+1 != 1 #=> False
+2 != 1 #=> True
+
+# 그밖의 비교 연산자는 다음과 같습니다.
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# 비교 연산을 연결할 수도 있습니다!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# 문자열은 "나 '로 생성합니다.
+"This is a string."
+'This is also a string.'
+
+# 문자열도 연결할 수 있습니다!
+"Hello " + "world!" #=> "Hello world!"
+
+# 문자열은 문자로 구성된 리스트로 간주할 수 있습니다.
+"This is a string"[0] #=> 'T'
+
+# %는 다음과 같이 문자열을 형식화하는 데 사용할 수 있습니다:
+"%s can be %s" % ("strings", "interpolated")
+
+# 문자열을 형식화하는 새로운 방법은 format 메서드를 이용하는 것입니다.
+# 이 메서드를 이용하는 방법이 더 선호됩니다.
+"{0} can be {1}".format("strings", "formatted")
+# 자릿수를 세기 싫다면 키워드를 이용해도 됩니다.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+
+# None은 객체입니다.
+None #=> None
+
+# 객체와 None을 비교할 때는 동일성 연산자인 `==`를 사용해서는 안 됩니다.
+# 대신 `is`를 사용하세요.
+"etc" is None #=> False
+None is None #=> True
+
+# 'is' 연산자는 객체의 식별자를 검사합니다.
+# 기본형 값을 다룰 때는 이 연산자가 그다지 유용하지 않지만
+# 객체를 다룰 때는 매우 유용합니다.
+
+# None, 0, 빈 문자열/리스트는 모두 False로 평가됩니다.
+# 그밖의 다른 값은 모두 True입니다
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. 변수와 컬렉션
+####################################################
+
+# 뭔가를 출력하는 것은 상당히 쉽습니다.
+print "I'm Python. Nice to meet you!"
+
+
+# 변수에 값을 할당하기 전에 변수를 반드시 선언하지 않아도 됩니다.
+some_var = 5 # 명명관례는 '밑줄이_포함된_소문자'입니다.
+some_var #=> 5
+
+# 미할당된 변수에 접근하면 예외가 발생합니다.
+# 예외 처리에 관해서는 '제어 흐름'을 참고하세요.
+some_other_var # 이름 오류가 발생
+
+# 표현식으로도 사용할 수 있습니다.
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# 리스트는 순차 항목을 저장합니다.
+li = []
+# 미리 채워진 리스트로 시작할 수도 있습니다.
+other_li = [4, 5, 6]
+
+# append를 이용해 리스트 끝에 항목을 추가합니다.
+li.append(1) #li는 이제 [1]입니다.
+li.append(2) #li는 이제 [1, 2]입니다.
+li.append(4) #li는 이제 [1, 2, 4]입니다.
+li.append(3) #li는 이제 [1, 2, 4, 3]입니다.
+# pop을 이용해 끝에서부터 항목을 제거합니다.
+li.pop() #=> 3이 반환되고 li는 이제 [1, 2, 4]입니다.
+# 다시 넣어봅시다
+li.append(3) # li는 이제 다시 [1, 2, 4, 3]가 됩니다.
+
+# 배열에서 했던 것처럼 리스트에도 접근할 수 있습니다.
+li[0] #=> 1
+# 마지막 요소를 봅시다.
+li[-1] #=> 3
+
+# 범위를 벗어나서 접근하면 IndexError가 발생합니다.
+li[4] # IndexError가 발생
+
+# 슬라이스 문법을 통해 범위를 지정해서 값을 조회할 수 있습니다.
+# (이 문법을 통해 간편하게 범위를 지정할 수 있습니다.)
+li[1:3] #=> [2, 4]
+# 앞부분을 생략합니다.
+li[2:] #=> [4, 3]
+# 끝부분을 생략합니다.
+li[:3] #=> [1, 2, 4]
+
+# del로 임의의 요소를 제거할 수 있습니다.
+del li[2] # li is now [1, 2, 3]
+
+# 리스트를 추가할 수도 있습니다.
+li + other_li #=> [1, 2, 3, 4, 5, 6] - 참고: li와 other_li는 그대로 유지됩니다.
+
+# extend로 리스트를 연결합니다.
+li.extend(other_li) # 이제 li는 [1, 2, 3, 4, 5, 6]입니다.
+
+# in으로 리스트 안에서 특정 요소가 존재하는지 확인합니다.
+1 in li #=> True
+
+# len으로 길이를 검사합니다.
+len(li) #=> 6
+
+# 튜플은 리스트와 비슷하지만 불변성을 띱니다.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # TypeError가 발생
+
+# 튜플에 대해서도 리스트에서 할 수 있는 일들을 모두 할 수 있습니다.
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# 튜플(또는 리스트)을 변수로 풀 수 있습니다.
+a, b, c = (1, 2, 3) # 이제 a는 1, b는 2, c는 3입니다
+# 괄호를 빼면 기본적으로 튜플이 만들어집니다.
+d, e, f = 4, 5, 6
+# 이제 두 값을 바꾸는 게 얼마나 쉬운지 확인해 보세요.
+e, d = d, e # 이제 d는 5이고 e는 4입니다.
+
+# 딕셔너리는 매핑을 저장합니다.
+empty_dict = {}
+# 다음은 값을 미리 채운 딕셔너리입니다.
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# []를 이용해 값을 조회합니다.
+filled_dict["one"] #=> 1
+
+# 모든 키를 리스트로 구합니다.
+filled_dict.keys() #=> ["three", "two", "one"]
+# 참고 - 딕셔너리 키의 순서는 보장되지 않습니다.
+# 따라서 결과가 이와 정확히 일치하지 않을 수도 있습니다.
+
+# 모든 값을 리스트로 구합니다.
+filled_dict.values() #=> [3, 2, 1]
+# 참고 - 키 순서와 관련해서 위에서 설명한 내용과 같습니다.
+
+# in으로 딕셔너리 안에 특정 키가 존재하는지 확인합니다.
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# 존재하지 않는 키를 조회하면 KeyError가 발생합니다.
+filled_dict["four"] # KeyError
+
+# get 메서드를 이용하면 KeyError가 발생하지 않습니다.
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# get 메서드는 값이 누락된 경우 기본 인자를 지원합니다.
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# setdefault 메서드는 딕셔너리에 새 키-값 쌍을 추가하는 안전한 방법입니다.
+filled_dict.setdefault("five", 5) #filled_dict["five"]는 5로 설정됩니다.
+filled_dict.setdefault("five", 6) #filled_dict["five"]는 여전히 5입니다.
+
+
+# 세트는 집합을 저장합니다.
+empty_set = set()
+# 다수의 값으로 세트를 초기화합니다.
+some_set = set([1,2,2,3,4]) # 이제 some_set는 set([1, 2, 3, 4])입니다.
+
+# 파이썬 2.7부터는 {}를 세트를 선언하는 데 사용할 수 있습니다.
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# 세트에 항목을 추가합니다.
+filled_set.add(5) # 이제 filled_set는 {1, 2, 3, 4, 5}입니다.
+
+# &을 이용해 교집합을 만듭니다.
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# |를 이용해 합집합을 만듭니다.
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# -를 이용해 차집합을 만듭니다.
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# in으로 세트 안에 특정 요소가 존재하는지 검사합니다.
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. 제어 흐름
+####################################################
+
+# 변수를 만들어 봅시다.
+some_var = 5
+
+# 다음은 if 문입니다. 파이썬에서는 들여쓰기가 대단히 중요합니다!
+# 다음 코드를 실행하면 "some_var is smaller than 10"가 출력됩니다.
+if some_var > 10:
+ print "some_var is totally bigger than 10."
+elif some_var < 10: # elif 절은 선택사항입니다.
+ print "some_var is smaller than 10."
+else: # 이 부분 역시 선택사항입니다.
+ print "some_var is indeed 10."
+
+
+"""
+for 루프는 리스트를 순회합니다.
+아래 코드는 다음과 같은 내용을 출력합니다:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # %로 형식화된 문자열에 값을 채워넣을 수 있습니다.
+ print "%s is a mammal" % animal
+
+"""
+`range(number)`는 숫자 리스트를 반환합니다.
+이때 숫자 리스트의 범위는 0에서 지정한 숫자까지입니다.
+아래 코드는 다음과 같은 내용을 출력합니다:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+while 루프는 조건이 더는 충족되지 않을 때까지 진행됩니다.
+prints:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # x = x + 1의 축약형
+
+# try/except 블록을 이용한 예외 처리
+
+# 파이썬 2.6 및 상위 버전에서 동작하는 코드
+try:
+ # raise를 이용해 오류를 발생시킵니다
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # pass는 단순 no-op 연산입니다. 보통 이곳에 복구 코드를 작성합니다.
+
+
+####################################################
+## 4. 함수
+####################################################
+
+# 새 함수를 만들 때 def를 사용합니다.
+def add(x, y):
+ print "x is %s and y is %s" % (x, y)
+ return x + y # return 문을 이용해 값을 반환합니다.
+
+# 매개변수를 전달하면서 함수를 호출
+add(5, 6) #=> "x is 5 and y is 6"가 출력되고 11이 반환됨
+
+# 함수를 호출하는 또 다른 방법은 키워드 인자를 지정하는 방법입니다.
+add(y=6, x=5) # 키워드 인자는 순서에 구애받지 않습니다.
+
+# 위치 기반 인자를 임의 개수만큼 받는 함수를 정의할 수 있습니다.
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# 키워드 인자를 임의 개수만큼 받는 함수 또한 정의할 수 있습니다.
+def keyword_args(**kwargs):
+ return kwargs
+
+# 이 함수를 호출해서 어떤 일이 일어나는지 확인해 봅시다.
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# 원한다면 한 번에 두 가지 종류의 인자를 모두 받는 함수를 정의할 수도 있습니다.
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4)를 실행하면 다음과 같은 내용이 출력됩니다:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# 함수를 호출할 때 varargs/kwargs와 반대되는 일을 할 수 있습니다!
+# *를 이용해 튜플을 확장하고 **를 이용해 kwargs를 확장합니다.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # foo(1, 2, 3, 4)와 같음
+all_the_args(**kwargs) # foo(a=3, b=4)와 같음
+all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4)와 같음
+
+# 파이썬에는 일급 함수가 있습니다
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# 게다가 익명 함수도 있습니다.
+(lambda x: x > 2)(3) #=> True
+
+# 내장된 고차 함수(high order function)도 있습니다.
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# 맵과 필터에 리스트 조건 제시법(list comprehensions)을 사용할 수 있습니다.
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. 클래스
+####################################################
+
+# 클래스를 하나 만들기 위해 특정 객체의 하위 클래스를 만들 수 있습니다.
+class Human(object):
+
+ # 클래스 속성은 이 클래스의 모든 인스턴스에서 공유합니다.
+ species = "H. sapiens"
+
+ # 기본 초기화자
+ def __init__(self, name):
+ # 인자를 인스턴스의 name 속성에 할당합니다.
+ self.name = name
+
+ # 모든 인스턴스 메서드에서는 self를 첫 번째 인자로 받습니다.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # 클래스 메서드는 모든 인스턴스에서 공유합니다.
+ # 클래스 메서드는 호출하는 클래스를 첫 번째 인자로 호출됩니다.
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # 정적 메서드는 클래스나 인스턴스 참조 없이도 호출할 수 있습니다.
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# 클래스 인스턴스화
+i = Human(name="Ian")
+print i.say("hi") # "Ian: hi"가 출력됨
+
+j = Human("Joel")
+print j.say("hello") # "Joel: hello"가 출력됨
+
+# 클래스 메서드를 호출
+i.get_species() #=> "H. sapiens"
+
+# 공유 속성을 변경
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# 정적 메서드를 호출
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. 모듈
+####################################################
+
+# 다음과 같이 모듈을 임포트할 수 있습니다.
+import math
+print math.sqrt(16) #=> 4
+
+# 모듈의 특정 함수를 호출할 수 있습니다.
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# 모듈의 모든 함수를 임포트할 수 있습니다.
+# Warning: this is not recommended
+from math import *
+
+# 모듈 이름을 축약해서 쓸 수 있습니다.
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# 파이썬 모듈은 평범한 파이썬 파일에 불과합니다.
+# 직접 모듈을 작성해서 그것들을 임포트할 수 있습니다.
+# 모듈의 이름은 파일의 이름과 같습니다.
+
+# 다음과 같은 코드로 모듈을 구성하는 함수와 속성을 확인할 수 있습니다.
+import math
+dir(math)
+
+
+```
+
+## 더 배울 준비가 되셨습니까?
+
+### 무료 온라인 참고자료
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### 파이썬 관련 도서
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/livescript.html.markdown b/livescript.html.markdown
index 8e11439b..429b91cb 100644
--- a/livescript.html.markdown
+++ b/livescript.html.markdown
@@ -23,7 +23,7 @@ Feedback is always welcome, so feel free to reach me over at
```coffeescript
-# Just like its CoffeeScript cousin, LiveScript uses hash symbols for
+# Just like its CoffeeScript cousin, LiveScript uses number symbols for
# single-line comments.
/*
@@ -135,11 +135,19 @@ funRE = //
3 % 2 # => 1
-# Comparisons are mostly the same too, except that `==` and `===` are
-# inverted.
+# Comparisons are mostly the same too, except that `==` is the same as
+# JS's `===`, where JS's `==` in LiveScript is `~=`, and `===` enables
+# object and array comparisons, and also stricter comparisons:
2 == 2 # => true
2 == "2" # => false
-2 === "2" # => true
+2 ~= "2" # => true
+2 === "2" # => false
+
+[1,2,3] == [1,2,3] # => false
+[1,2,3] === [1,2,3] # => true
+
++0 == -0 # => true
++0 === -0 # => false
# Other relational operators include <, <=, > and >=
diff --git a/lua.html.markdown b/lua.html.markdown
index 7325a1cf..be9f3141 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -12,15 +12,13 @@ filename: learnlua.lua
Adding two ['s and ]'s makes it a
multi-line comment.
--]]
-
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 1. Variables and flow control.
-----------------------------------------------------
+--------------------------------------------------------------------------------
num = 42 -- All numbers are doubles.
--- Don't freak out, 64-bit doubles have 52 bits for
--- storing exact int values; machine precision is
--- not a problem for ints that need < 52 bits.
+-- Don't freak out, 64-bit doubles have 52 bits for storing exact int
+-- values; machine precision is not a problem for ints that need < 52 bits.
s = 'walternate' -- Immutable strings like Python.
t = "double-quotes are also fine"
@@ -60,8 +58,8 @@ aBoolValue = false
-- Only nil and false are falsy; 0 and '' are true!
if not aBoolValue then print('twas false') end
--- 'or' and 'and' are short-circuited.
--- This is similar to the a?b:c operator in C/js:
+-- 'or' and 'and' are short-circuited. This is similar to the a?b:c operator
+-- in C/js:
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
@@ -81,10 +79,9 @@ repeat
num = num - 1
until num == 0
-
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 2. Functions.
-----------------------------------------------------
+--------------------------------------------------------------------------------
function fib(n)
if n < 2 then return n end
@@ -93,8 +90,8 @@ end
-- Closures and anonymous functions are ok:
function adder(x)
- -- The returned function is created when adder is
- -- called, and remembers the value of x:
+ -- The returned function is created when adder is called, and remembers the
+ -- value of x:
return function (y) return x + y end
end
a1 = adder(9)
@@ -102,10 +99,9 @@ a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
--- Returns, func calls, and assignments all work
--- with lists that may be mismatched in length.
--- Unmatched receivers are nil;
--- unmatched senders are discarded.
+-- Returns, func calls, and assignments all work with lists that may be
+-- mismatched in length. Unmatched receivers are nil; unmatched senders are
+-- discarded.
x, y, z = 1, 2, 3, 4
-- Now x = 1, y = 2, z = 3, and 4 is thrown away.
@@ -118,13 +114,15 @@ end
x, y = bar('zaphod') --> prints "zaphod nil nil"
-- Now x = 4, y = 8, values 15..42 are discarded.
--- Functions are first-class, may be local/global.
--- These are the same:
+-- Functions are first-class, may be local/global. These are the same:
function f(x) return x * x end
f = function (x) return x * x end
-- And so are these:
local function g(x) return math.sin(x) end
+local g = function(x) return math.sin(x) end
+-- Equivalent to local function g(x)..., except referring to g in the function
+-- body won't work as expected.
local g; g = function (x) return math.sin(x) end
-- the 'local g' decl makes g-self-references ok.
@@ -133,15 +131,16 @@ local g; g = function (x) return math.sin(x) end
-- Calls with one string param don't need parens:
print 'hello' -- Works fine.
+-- Calls with one table param don't need parens either (more on tables below):
+print {} -- Works fine too.
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 3. Tables.
-----------------------------------------------------
+--------------------------------------------------------------------------------
--- Tables = Lua's only compound data structure;
--- they are associative arrays.
--- Similar to php arrays or js objects, they are
--- hash-lookup dicts that can also be used as lists.
+-- Tables = Lua's only compound data structure; they are associative arrays.
+-- Similar to php arrays or js objects, they are hash-lookup dicts that can
+-- also be used as lists.
-- Using tables as dictionaries / maps:
@@ -157,14 +156,13 @@ t.key2 = nil -- Removes key2 from the table.
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- prints "tau"
--- Key matching is basically by value for numbers
--- and strings, but by identity for tables.
+-- Key matching is basically by value for numbers and strings, but by identity
+-- for tables.
a = u['@!#'] -- Now a = 'qbert'.
b = u[{}] -- We might expect 1729, but it's nil:
--- b = nil since the lookup fails. It fails
--- because the key we used is not the same object
--- as the one used to store the original value. So
--- strings & numbers are more portable keys.
+-- b = nil since the lookup fails. It fails because the key we used is not the
+-- same object as the one used to store the original value. So strings &
+-- numbers are more portable keys.
-- A one-table-param function call needs no parens:
function h(x) print(x.key1) end
@@ -184,16 +182,15 @@ v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v is the size of v for lists.
print(v[i]) -- Indices start at 1 !! SO CRAZY!
end
--- A 'list' is not a real type. v is just a table
--- with consecutive integer keys, treated as a list.
+-- A 'list' is not a real type. v is just a table with consecutive integer
+-- keys, treated as a list.
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 3.1 Metatables and metamethods.
-----------------------------------------------------
+--------------------------------------------------------------------------------
--- A table can have a metatable that gives the table
--- operator-overloadish behavior. Later we'll see
--- how metatables support js-prototypey behavior.
+-- A table can have a metatable that gives the table operator-overloadish
+-- behavior. Later we'll see how metatables support js-prototypey behavior.
f1 = {a = 1, b = 2} -- Represents the fraction a/b.
f2 = {a = 2, b = 3}
@@ -203,7 +200,7 @@ f2 = {a = 2, b = 3}
metafraction = {}
function metafraction.__add(f1, f2)
- sum = {}
+ local sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
@@ -214,10 +211,9 @@ setmetatable(f2, metafraction)
s = f1 + f2 -- call __add(f1, f2) on f1's metatable
--- f1, f2 have no key for their metatable, unlike
--- prototypes in js, so you must retrieve it as in
--- getmetatable(f1). The metatable is a normal table
--- with keys that Lua knows about, like __add.
+-- f1, f2 have no key for their metatable, unlike prototypes in js, so you must
+-- retrieve it as in getmetatable(f1). The metatable is a normal table with
+-- keys that Lua knows about, like __add.
-- But the next line fails since s has no metatable:
-- t = s + s
@@ -229,11 +225,12 @@ myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- works! thanks, metatable
--- Direct table lookups that fail will retry using
--- the metatable's __index value, and this recurses.
+--------------------------------------------------------------------------------
+-- Direct table lookups that fail will retry using the metatable's __index
+-- value, and this recurses.
--- An __index value can also be a function(tbl, key)
--- for more customized lookups.
+-- An __index value can also be a function(tbl, key) for more customized
+-- lookups.
-- Values of __index,add, .. are called metamethods.
-- Full list. Here a is a table with the metamethod.
@@ -254,19 +251,19 @@ eatenBy = myFavs.animal -- works! thanks, metatable
-- __newindex(a, b, c) for a.b = c
-- __call(a, ...) for a(...)
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 3.2 Class-like tables and inheritance.
-----------------------------------------------------
+--------------------------------------------------------------------------------
--- Classes aren't built in; there are different ways
--- to make them using tables and metatables.
+-- Classes aren't built in; there are different ways to make them using
+-- tables and metatables.
-- Explanation for this example is below it.
Dog = {} -- 1.
function Dog:new() -- 2.
- newObj = {sound = 'woof'} -- 3.
+ local newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
@@ -279,62 +276,59 @@ mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
-- 1. Dog acts like a class; it's really a table.
--- 2. function tablename:fn(...) is the same as
--- function tablename.fn(self, ...)
--- The : just adds a first arg called self.
--- Read 7 & 8 below for how self gets its value.
+-- 2. "function tablename:fn(...)" is the same as
+-- "function tablename.fn(self, ...)", The : just adds a first arg called
+-- self. Read 7 & 8 below for how self gets its value.
-- 3. newObj will be an instance of class Dog.
--- 4. self = the class being instantiated. Often
--- self = Dog, but inheritance can change it.
--- newObj gets self's functions when we set both
--- newObj's metatable and self's __index to self.
+-- 4. "self" is the class being instantiated. Often self = Dog, but inheritance
+-- can change it. newObj gets self's functions when we set both newObj's
+-- metatable and self's __index to self.
-- 5. Reminder: setmetatable returns its first arg.
--- 6. The : works as in 2, but this time we expect
--- self to be an instance instead of a class.
+-- 6. The : works as in 2, but this time we expect self to be an instance
+-- instead of a class.
-- 7. Same as Dog.new(Dog), so self = Dog in new().
-- 8. Same as mrDog.makeSound(mrDog); self = mrDog.
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- Inheritance example:
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
- s = self.sound .. ' ' -- 2.
+ local s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
seymour = LoudDog:new() -- 3.
seymour:makeSound() -- 'woof woof woof' -- 4.
+--------------------------------------------------------------------------------
-- 1. LoudDog gets Dog's methods and variables.
-- 2. self has a 'sound' key from new(), see 3.
--- 3. Same as LoudDog.new(LoudDog), and converted to
--- Dog.new(LoudDog) as LoudDog has no 'new' key,
--- but does have __index = Dog on its metatable.
--- Result: seymour's metatable is LoudDog, and
--- LoudDog.__index = LoudDog. So seymour.key will
--- = seymour.key, LoudDog.key, Dog.key, whichever
+-- 3. Same as "LoudDog.new(LoudDog)", and converted to "Dog.new(LoudDog)" as
+-- LoudDog has no 'new' key, but does have "__index = Dog" on its metatable.
+-- Result: seymour's metatable is LoudDog, and "LoudDog.__index = Dog". So
+-- seymour.key will equal seymour.key, LoudDog.key, Dog.key, whichever
-- table is the first with the given key.
--- 4. The 'makeSound' key is found in LoudDog; this
--- is the same as LoudDog.makeSound(seymour).
+-- 4. The 'makeSound' key is found in LoudDog; this is the same as
+-- "LoudDog.makeSound(seymour)".
-- If needed, a subclass's new() is like the base's:
function LoudDog:new()
- newObj = {}
+ local newObj = {}
-- set up newObj
self.__index = self
return setmetatable(newObj, self)
end
-----------------------------------------------------
+--------------------------------------------------------------------------------
-- 4. Modules.
-----------------------------------------------------
+--------------------------------------------------------------------------------
---[[ I'm commenting out this section so the rest of
--- this script remains runnable.
+--[[ I'm commenting out this section so the rest of this script remains
+-- runnable.
```
```lua
@@ -360,8 +354,8 @@ local mod = require('mod') -- Run the file mod.lua.
local mod = (function ()
<contents of mod.lua>
end)()
--- It's like mod.lua is a function body, so that
--- locals inside mod.lua are invisible outside it.
+-- It's like mod.lua is a function body, so that locals inside mod.lua are
+-- invisible outside it.
-- This works because mod here = M in mod.lua:
mod.sayHello() -- Says hello to Hrunkner.
@@ -369,8 +363,8 @@ mod.sayHello() -- Says hello to Hrunkner.
-- This is wrong; sayMyName only exists in mod.lua:
mod.sayMyName() -- error
--- require's return values are cached so a file is
--- run at most once, even when require'd many times.
+-- require's return values are cached so a file is run at most once, even when
+-- require'd many times.
-- Suppose mod2.lua contains "print('Hi!')".
local a = require('mod2') -- Prints Hi!
diff --git a/matlab.html.markdown b/matlab.html.markdown
new file mode 100644
index 00000000..9baefe68
--- /dev/null
+++ b/matlab.html.markdown
@@ -0,0 +1,452 @@
+---
+language: Matlab
+contributors:
+ - ["mendozao", "http://github.com/mendozao"]
+ - ["jamesscottbrown", "http://jamesscottbrown.com"]
+
+---
+
+MATLAB stands for MATrix LABoratory. It is a powerful numerical computing language commonly used in engineering and mathematics.
+
+If you have any feedback please feel free to reach me at
+[@the_ozzinator](https://twitter.com/the_ozzinator), or
+[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com).
+
+```matlab
+% Comments start with a percent sign.
+
+%{ Multi line comments look
+something
+like
+this %}
+
+% commands can span multiple lines, using '...':
+ a = 1 + 2 + ...
+ + 4
+
+% commands can be passed to the operating system
+!ping google.com
+
+who % Displays all variables in memory
+whos % Displays all variables in memory, with their types
+clear % Erases all your variables from memory
+clear('A') % Erases a particular variable
+openvar('A') % Open variable in variable editor
+
+clc % Erases the writing on your Command Window
+diary % Toggle writing Command Window text to file
+ctrl-c % Abort current computation
+
+edit('myfunction.m') % Open function/script in editor
+type('myfunction.m') % Print the source of function/script to Command Window
+
+profile viewer % Open profiler
+
+help command % Displays documentation for command in Command Window
+doc command % Displays documentation for command in Help Window
+lookfor command % Searches for a given command
+
+
+% Output formatting
+format short % 4 decimals in a floating number
+format long % 15 decimals
+format bank % only two digits after decimal point - for financial calculations
+fprintf
+
+% Variables & Expressions
+myVariable = 4 % Notice Workspace pane shows newly created variable
+myVariable = 4; % Semi colon suppresses output to the Command Window
+4 + 6 % ans = 10
+8 * myVariable % ans = 32
+2 ^ 3 % ans = 8
+a = 2; b = 3;
+c = exp(a)*sin(pi/2) % c = 7.3891
+
+% Calling functions can be done in either of two ways:
+% Standard function syntax:
+load('myFile.mat', 'y')
+% Command syntax:
+load myFile.mat y % no parentheses, and spaces instead of commas
+% Note the lack of quote marks in command form: inputs are always passed as
+% literal text - cannot pass variable values. Also, can't receive output:
+[V,D] = eig(A) % this has no equivalent in command form
+
+
+
+% Logicals
+1 > 5 % ans = 0
+10 >= 10 % ans = 1
+3 ~= 4 % Not equal to -> ans = 1
+3 == 3 % equal to -> ans = 1
+3 > 1 && 4 > 1 % AND -> ans = 1
+3 > 1 || 4 > 1 % OR -> ans = 1
+~1 % NOT -> ans = 0
+
+% Logicals can be applied to matrices:
+A > 5
+% for each element, if condition is true, that element is 1 in returned matrix
+A[ A > 5 ]
+% returns a vector containing the elements in A for which condition is true
+
+% Strings
+a = 'MyString'
+length(a) % ans = 8
+a(2) % ans = y
+[a,a] % ans = MyStringMyString
+
+
+% Cells
+a = {'one', 'two', 'three'}
+a(1) % ans = 'one' - returns a cell
+char(a(1)) % ans = one - returns a string
+
+
+% Vectors
+x = [4 32 53 7 1]
+x(2) % ans = 32, indices in Matlab start 1, not 0
+x(2:3) % ans = 32 53
+x(2:end) % ans = 32 53 7 1
+
+x = [4; 32; 53; 7; 1] % Column vector
+
+x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
+
+% Matrices
+A = [1 2 3; 4 5 6; 7 8 9]
+% Rows are separated by a semicolon; elements are separated with space or comma
+% A =
+
+% 1 2 3
+% 4 5 6
+% 7 8 9
+
+A(2,3) % ans = 6, A(row, column)
+A(6) % ans = 8
+% (implicitly concatenates columns into vector, then indexes into that)
+
+
+A(2,3) = 42 % Update row 2 col 3 with 42
+% A =
+
+% 1 2 3
+% 4 5 42
+% 7 8 9
+
+A(2:3,2:3) % Creates a new matrix from the old one
+%ans =
+
+% 5 42
+% 8 9
+
+A(:,1) % All rows in column 1
+%ans =
+
+% 1
+% 4
+% 7
+
+A(1,:) % All columns in row 1
+%ans =
+
+% 1 2 3
+
+[A ; A] % Concatenation of matrices (vertically)
+%ans =
+
+% 1 2 3
+% 4 5 42
+% 7 8 9
+% 1 2 3
+% 4 5 42
+% 7 8 9
+
+[A , A] % Concatenation of matrices (horizontally)
+
+%ans =
+
+% 1 2 3 1 2 3
+% 4 5 42 4 5 42
+% 7 8 9 7 8 9
+
+
+
+A(:, [3 1 2]) % Rearrange the columns of original matrix
+%ans =
+
+% 3 1 2
+% 42 4 5
+% 9 7 8
+
+size(A) % ans = 3 3
+
+A(1, :) =[] % Delete the first row of the matrix
+
+ctranspose(A) % Hermitian transpose the matrix
+% (the transpose, followed by taking complex conjugate of each element)
+transpose(A) % Transpose the matrix, without taking complex conjugate
+
+
+
+% Element by Element Arithmetic vs. Matrix Arithmetic
+% On their own, the arithmetic operators act on whole matrices. When preceded
+% by a period, they act on each element instead. For example:
+A * B % Matrix multiplication
+A .* B % Multiple each element in A by its corresponding element in B
+
+% There are several pairs of functions, where one acts on each element, and
+% the other (whose name ends in m) acts on the whole matrix.
+exp(A) % exponentiate each element
+expm(A) % calculate the matrix exponential
+sqrt(A) % take the square root of each element
+sqrtm(A) % find the matrix whose square is A
+
+
+% Plotting
+x = 0:.10:2*pi; % Creates a vector that starts at 0 and ends at 2*pi with increments of .1
+y = sin(x);
+plot(x,y)
+xlabel('x axis')
+ylabel('y axis')
+title('Plot of y = sin(x)')
+axis([0 2*pi -1 1]) % x range from 0 to 2*pi, y range from -1 to 1
+
+plot(x,y1,'-',x,y2,'--',x,y3,':') % For multiple functions on one plot
+legend('Line 1 label', 'Line 2 label') % Label curves with a legend
+
+% Alternative method to plot multiple functions in one plot.
+% while 'hold' is on, commands add to existing graph rather than replacing it
+plot(x, y)
+hold on
+plot(x, z)
+hold off
+
+loglog(x, y) % A log-log plot
+semilogx(x, y) % A plot with logarithmic x-axis
+semilogy(x, y) % A plot with logarithmic y-axis
+
+fplot (@(x) x^2, [2,5]) % plot the function x^2 from x=2 to x=5
+
+grid on % Show grid; turn off with 'grid off'
+axis square % Makes the current axes region square
+axis equal % Set aspect ratio so data units are the same in every direction
+
+scatter(x, y); % Scatter-plot
+hist(x); % Histogram
+
+z = sin(x);
+plot3(x,y,z); % 3D line plot
+
+pcolor(A) % Heat-map of matrix: plot as grid of rectangles, coloured by value
+contour(A) % Contour plot of matrix
+mesh(A) % Plot as a mesh surface
+
+h = figure % Create new figure object, with handle f
+figure(h) % Makes the figure corresponding to handle h the current figure
+close(h) % close figure with handle h
+close all % close all open figure windows
+close % close current figure window
+
+shg % bring an existing graphics window forward, or create new one if needed
+clf clear % clear current figure window, and reset most figure properties
+
+% Properties can be set and changed through a figure handle.
+% You can save a handle to a figure when you create it.
+% The function gcf returns a handle to the current figure
+h = plot(x, y); % you can save a handle to a figure when you create it
+set(h, 'Color', 'r')
+% 'y' yellow; 'm' magenta, 'c' cyan, 'r' red, 'g' green, 'b' blue, 'w' white, 'k' black
+set(h, 'LineStyle', '--')
+ % '--' is solid line, '---' dashed, ':' dotted, '-.' dash-dot, 'none' is no line
+get(h, 'LineStyle')
+
+
+% The function gca returns a handle to the axes for the current figure
+set(gca, 'XDir', 'reverse'); % reverse the direction of the x-axis
+
+% To create a figure that contains several axes in tiled positions, use subplot
+subplot(2,3,1); % select the first position in a 2-by-3 grid of subplots
+plot(x1); title('First Plot') % plot something in this position
+subplot(2,3,2); % select second position in the grid
+plot(x2); title('Second Plot') % plot something there
+
+
+% To use functions or scripts, they must be on your path or current directory
+path % display current path
+addpath /path/to/dir % add to path
+rmpath /path/to/dir % remove from path
+cd /path/to/move/into % change directory
+
+
+% Variables can be saved to .mat files
+save('myFileName.mat') % Save the variables in your Workspace
+load('myFileName.mat') % Load saved variables into Workspace
+
+% M-file Scripts
+% A script file is an external file that contains a sequence of statements.
+% They let you avoid repeatedly typing the same code in the Command Window
+% Have .m extensions
+
+% M-file Functions
+% Like scripts, and have the same .m extension
+% But can accept input arguments and return an output
+% Also, they have their own workspace (ie. different variable scope).
+% Function name should match file name (so save this example as double_input.m).
+% 'help double_input.m' returns the comments under line beginning function
+function output = double_input(x)
+ %double_input(x) returns twice the value of x
+ output = 2*x;
+end
+double_input(6) % ans = 12
+
+
+% You can also have subfunctions and nested functions.
+% Subfunctions are in the same file as the primary function, and can only be
+% called by functions in the file. Nested functions are defined within another
+% functions, and have access to both its workspace and their own workspace.
+
+% If you want to create a function without creating a new file you can use an
+% anonymous function. Useful when quickly defining a function to pass to
+% another function (eg. plot with fplot, evaluate an indefinite integral
+% with quad, find roots with fzero, or find minimum with fminsearch).
+% Example that returns the square of it's input, assigned to to the handle sqr:
+sqr = @(x) x.^2;
+sqr(10) % ans = 100
+doc function_handle % find out more
+
+% User input
+a = input('Enter the value: ')
+
+% Stops execution of file and gives control to the keyboard: user can examine
+% or change variables. Type 'return' to continue execution, or 'dbquit' to exit
+keyboard
+
+% Reading in data (also xlsread/importdata/imread for excel/CSV/image files)
+fopen(filename)
+
+% Output
+disp(a) % Print out the value of variable a
+disp('Hello World') % Print out a string
+fprintf % Print to Command Window with more control
+
+% Conditional statements (the parentheses are optional, but good style)
+if (a > 15)
+ disp('Greater than 15')
+elseif (a == 23)
+ disp('a is 23')
+else
+ disp('neither condition met')
+end
+
+% Looping
+% NB. looping over elements of a vector/matrix is slow!
+% Where possible, use functions that act on whole vector/matrix at once
+for k = 1:5
+ disp(k)
+end
+
+k = 0;
+while (k < 5)
+ k = k + 1;
+end
+
+% Timing code execution: 'toc' prints the time since 'tic' was called
+tic
+A = rand(1000);
+A*A*A*A*A*A*A;
+toc
+
+% Connecting to a MySQL Database
+dbname = 'database_name';
+username = 'root';
+password = 'root';
+driver = 'com.mysql.jdbc.Driver';
+dburl = ['jdbc:mysql://localhost:8889/' dbname];
+javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); %xx depends on version, download available at http://dev.mysql.com/downloads/connector/j/
+conn = database(dbname, username, password, driver, dburl);
+sql = ['SELECT * from table_name where id = 22'] % Example sql statement
+a = fetch(conn, sql) %a will contain your data
+
+
+% Common math functions
+sin(x)
+cos(x)
+tan(x)
+asin(x)
+acos(x)
+atan(x)
+exp(x)
+sqrt(x)
+log(x)
+log10(x)
+abs(x)
+min(x)
+max(x)
+ceil(x)
+floor(x)
+round(x)
+rem(x)
+rand % Uniformly distributed pseudorandom numbers
+randi % Uniformly distributed pseudorandom integers
+randn % Normally distributed pseudorandom numbers
+
+% Common constants
+pi
+NaN
+inf
+
+% Solving matrix equations (if no solution, returns a least squares solution)
+% The \ and / operators are equivalent to the functions mldivide and mrdivide
+x=A\b % Solves Ax=b. Faster and more numerically accurate than using inv(A)*b.
+x=b/A % Solves xA=b
+
+inv(A) % calculate the inverse matrix
+pinv(A) % calculate the pseudo-inverse
+
+% Common matrix functions
+zeros(m,n) % m x n matrix of 0's
+ones(m,n) % m x n matrix of 1's
+diag(A) % Extracts the diagonal elements of a matrix A
+diag(x) % Construct a matrix with diagonal elements listed in x, and zeroes elsewhere
+eye(m,n) % Identity matrix
+linspace(x1, x2, n) % Return n equally spaced points, with min x1 and max x2
+inv(A) % Inverse of matrix A
+det(A) % Determinant of A
+eig(A) % Eigenvalues and eigenvectors of A
+trace(A) % Trace of matrix - equivalent to sum(diag(A))
+isempty(A) % Tests if array is empty
+all(A) % Tests if all elements are nonzero or true
+any(A) % Tests if any elements are nonzero or true
+isequal(A, B) % Tests equality of two arrays
+numel(A) % Number of elements in matrix
+triu(x) % Returns the upper triangular part of x
+tril(x) % Returns the lower triangular part of x
+cross(A,B) % Returns the cross product of the vectors A and B
+dot(A,B) % Returns scalar product of two vectors (must have the same length)
+transpose(A) % Returns the transpose of A
+flipl(A) % Flip matrix left to right
+
+% Matrix Factorisations
+[L, U, P] = lu(A) % LU decomposition: PA = LU,L is lower triangular, U is upper triangular, P is permutation matrix
+[P, D] = eig(A) % eigen-decomposition: AP = PD, P's columns are eigenvectors and D's diagonals are eigenvalues
+[U,S,V] = svd(X) % SVD: XV = US, U and V are unitary matrices, S has non-negative diagonal elements in decreasing order
+
+% Common vector functions
+max % largest component
+min % smallest component
+length % length of a vector
+sort % sort in ascending order
+sum % sum of elements
+prod % product of elements
+mode % modal value
+median % median value
+mean % mean value
+std % standard deviation
+perms(x) % list all permutations of elements of x
+
+```
+
+## More on Matlab
+
+* The official website [http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
+* The official MATLAB Answers forum: [http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
+
diff --git a/neat.html.markdown b/neat.html.markdown
new file mode 100644
index 00000000..e99d1e0e
--- /dev/null
+++ b/neat.html.markdown
@@ -0,0 +1,297 @@
+---
+language: neat
+contributors:
+ - ["Feep", "https://github.com/FeepingCreature"]
+filename: LearnNeat.nt
+---
+
+Neat is basically a smaller version of D1 with some experimental syntax and a focus on terseness without losing the basic C-like syntax.
+
+[Read more here.](https://github.com/FeepingCreature/fcc/wiki)
+
+```c
+// single line comments start with //
+/*
+ multiline comments look like this
+*/
+/+
+ or this
+ /+ these can be nested too, same as D +/
++/
+
+// Module name. This has to match the filename/directory.
+module LearnNeat;
+
+// Make names from another module visible in this one.
+import std.file;
+// You can import multiple things at once.
+import std.math, std.util;
+// You can even group up imports!
+import std.(process, socket);
+
+// Global functions!
+void foo() { }
+
+// Main function, same as in C.
+// string[] == "array of strings".
+// "string" is just an alias for char[],
+void main(string[] args) {
+ // Call functions with "function expression".
+ writeln "Hello World";
+ // You can do it like in C too... if you really want.
+ writeln ("Hello World");
+ // Declare a variable with "type identifier"
+ string arg = ("Hello World");
+ writeln arg;
+ // (expression, expression) forms a tuple.
+ // There are no one-value tuples though.
+ // So you can always use () in the mathematical sense.
+ // (string) arg; <- is an error
+
+ /*
+ byte: 8 bit signed integer
+ char: 8 bit UTF-8 byte component.
+ short: 16 bit signed integer
+ int: 32 bit signed integer
+ long: 64 bit signed integer
+
+ float: 32 bit floating point
+ double: 64 bit floating point
+ real: biggest native size floating point (80 bit on x86).
+
+ bool: true or false
+ */
+ int a = 5;
+ bool b = true;
+ // as in C, && and || are short-circuit evaluating.
+ b = b && false;
+ assert(b == false);
+ // "" are "format strings". So $variable will be substituted at runtime
+ // with a formatted version of the variable.
+ writeln "$a";
+ // This will just print $a.
+ writeln `$a`;
+ // you can format expressions with $()
+ writeln "$(2+2)";
+ // Note: there is no special syntax for characters.
+ char c = "a";
+ // Cast values by using type: expression.
+ // There are three kinds of casts:
+ // casts that just specify conversions that would be happening automatically
+ // (implicit casts)
+ float f = float:5;
+ float f2 = 5; // would also work
+ // casts that require throwing away information or complicated computation -
+ // those must always be done explicitly
+ // (conversion casts)
+ int i = int:f;
+ // int i = f; // would not work!
+ // and, as a last attempt, casts that just reinterpret the raw data.
+ // Those only work if the types have the same size.
+ string s = "Hello World";
+ // Arrays are (length, pointer) pairs.
+ // This is a tuple type. Tuple types are (type, type, type).
+ // The type of a tuple expression is a tuple type. (duh)
+ (int, char*) array = (int, char*): s;
+ // You can index arrays and tuples using the expression[index] syntax.
+ writeln "pointer is $(array[1]) and length is $(array[0])";
+ // You can slice them using the expression[from .. to] syntax.
+ // Slicing an array makes another array.
+ writeln "$(s[0..5]) World";
+ // Alias name = expression gives the expression a name.
+ // As opposed to a variable, aliases do not have an address
+ // and can not be assigned to. (Unless the expression is assignable)
+ alias range = 0 .. 5;
+ writeln "$(s[range]) World";
+ // You can iterate over ranges.
+ for int i <- range {
+ write "$(s[i])";
+ }
+ writeln " World";
+ // Note that if "range" had been a variable, it would be 'empty' now!
+ // Range variables can only be iterated once.
+ // The syntax for iteration is "expression <- iterable".
+ // Lots of things are iterable.
+ for char c <- "Hello" { write "$c"; }
+ writeln " World";
+ // For loops are "for test statement";
+ alias test = char d <- "Hello";
+ for test write "$d";
+ writeln " World\t\x05"; // note: escapes work
+ // Pointers: function the same as in C, btw. The usual.
+ // Do note: the pointer star sticks with the TYPE, not the VARIABLE!
+ string* p;
+ assert(p == null); // default initializer
+ p = &s;
+ writeln "$(*p)";
+ // Math operators are (almost) standard.
+ int x = 2 + 3 * 4 << 5;
+ // Note: XOR is "xor". ^ is reserved for exponentiation (once I implement that).
+ int y = 3 xor 5;
+ int z = 5;
+ assert(z++ == 5);
+ assert(++z == 7);
+ writeln "x $x y $y z $z";
+ // As in D, ~ concatenates.
+ string hewo = "Hello " ~ "World";
+ // == tests for equality, "is" tests for identity.
+ assert (hewo == s);
+ assert !(hewo is s);
+ // same as
+ assert (hewo !is s);
+
+ // Allocate arrays using "new array length"
+ int[] integers = new int[] 10;
+ assert(integers.length == 10);
+ assert(integers[0] == 0); // zero is default initializer
+ integers = integers ~ 5; // This allocates a new array!
+ assert(integers.length == 11);
+
+ // This is an appender array.
+ // Instead of (length, pointer), it tracks (capacity, length, pointer).
+ // When you append to it, it will use the free capacity if it can.
+ // If it runs out of space, it reallocates - but it will free the old array automatically.
+ // This makes it convenient for building arrays.
+ int[auto~] appender;
+ appender ~= 2;
+ appender ~= 3;
+ appender.free(); // same as {mem.free(appender.ptr); appender = null;}
+
+ // Scope variables are automatically freed at the end of the current scope.
+ scope int[auto~] someOtherAppender;
+ // This is the same as:
+ int[auto~] someOtherAppender2;
+ onExit { someOtherAppender2.free; }
+
+ // You can do a C for loop too
+ // - but why would you want to?
+ for (int i = 0; i < 5; ++i) { }
+ // Otherwise, for and while are the same.
+ while int i <- 0..4 {
+ assert(i == 0);
+ break; // continue works too
+ } then assert(false); // if we hadn't break'd, this would run at the end
+ // This is the height of loopdom - the produce-test-consume loop.
+ do {
+ int i = 5;
+ } while (i == 5) {
+ assert(i == 5);
+ break; // otherwise we'd go back up to do {
+ }
+
+ // This is a nested function.
+ // Nested functions can access the surrounding function.
+ string returnS() { return s; }
+ writeln returnS();
+
+ // Take the address of a function using &
+ // The type of a global function is ReturnType function(ParameterTypeTuple).
+ void function() foop = &foo;
+
+ // Similarly, the type of a nested function is ReturnType delegate(ParameterTypeTuple).
+ string delegate() returnSp = &returnS;
+ writeln returnSp();
+ // Class member functions and struct member functions also fit into delegate variables.
+ // In general, delegates are functions that carry an additional context pointer.
+ // ("fat pointers" in C)
+
+ // Allocate a "snapshot" with "new delegate".
+ // Snapshots are not closures! I used to call them closures too,
+ // but then my Haskell-using friends yelled at me so I had to stop.
+ // The difference is that snapshots "capture" their surrounding context
+ // when "new" is used.
+ // This allows things like this
+ int delegate(int) add(int a) {
+ int add_a(int b) { return a + b; }
+ // This does not work - the context of add_a becomes invalid
+ // when add returns.
+ // return &add_a;
+ // Instead:
+ return new &add_a;
+ }
+ int delegate(int) dg = add 2;
+ assert (dg(3) == 5);
+ // or
+ assert (((add 2) 3) == 5);
+ // or
+ assert (add 2 3 == 5);
+ // add can also be written as
+ int delegate(int) add2(int a) {
+ // this is an implicit, nameless nested function.
+ return new λ(int b) { return a + b; }
+ }
+ // or even
+ auto add3(int a) { return new λ(int b) -> a + b; }
+ // hahahaaa
+ auto add4 = λ(int a) -> new λ(int b) -> a + b;
+ assert(add4 2 3 == 5);
+ // If your keyboard doesn't have a λ (you poor sod)
+ // you can use \ too.
+ auto add5 = \(int a) -> new \(int b) -> a + b;
+ // Note!
+ auto nestfun = λ() { } // There is NO semicolon needed here!
+ // "}" can always substitute for "};".
+ // This provides syntactic consistency with built-in statements.
+
+
+ // This is a class.
+ // Note: almost all elements of Neat can be used on the module level
+ // or just as well inside a function.
+ class C {
+ int a;
+ void writeA() { writeln "$a"; }
+ // It's a nested class - it exists in the context of main().
+ // so if you leave main(), any instances of C become invalid.
+ void writeS() { writeln "$s"; }
+ }
+ C cc = new C;
+ // cc is a *reference* to C. Classes are always references.
+ cc.a = 5; // Always used for property access.
+ auto ccp = &cc;
+ (*ccp).a = 6;
+ // or just
+ ccp.a = 7;
+ cc.writeA();
+ cc.writeS(); // to prove I'm not making things up
+ // Interfaces work same as in D, basically. Or Java.
+ interface E { void doE(); }
+ // Inheritance works same as in D, basically. Or Java.
+ class D : C, E {
+ override void writeA() { writeln "hahahahaha no"; }
+ override void doE() { writeln "eeeee"; }
+ // all classes inherit from Object. (toString is defined in Object)
+ override string toString() { return "I am a D"; }
+ }
+ C cd = new D;
+ // all methods are always virtual.
+ cd.writeA();
+ E e = E:cd; // dynamic class cast!
+ e.doE();
+ writeln "$e"; // all interfaces convert to Object implicitly.
+
+ // Templates!
+ // Templates are parameterized namespaces, taking a type as a parameter.
+ template Templ(T) {
+ alias hi = 5, hii = 8;
+ // Templates always have to include something with the same name as the template
+ // - this will become the template's _value_.
+ // Static ifs are evaluated statically, at compile-time.
+ // Because of this, the test has to be a constant expression,
+ // or something that can be optimized to a constant.
+ static if (types-equal (T, int)) {
+ alias Templ = hi;
+ } else {
+ alias Templ = hii;
+ }
+ }
+ assert(Templ!int == 5);
+ assert(Templ!float == 8);
+}
+```
+
+## Topics Not Covered
+
+ * Extended iterator types and expressions
+ * Standard library
+ * Conditions (error handling)
+ * Macros
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
new file mode 100644
index 00000000..772e72ca
--- /dev/null
+++ b/objective-c.html.markdown
@@ -0,0 +1,749 @@
+---
+
+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
+
+---
+
+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
+// Single-line comments start with //
+
+/*
+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
+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!"
+
+ ///////////////////////////////////////
+ // Types & Variables
+ ///////////////////////////////////////
+
+ // Primitive declarations
+ int myPrimitive1 = 1;
+ long myPrimitive2 = 234554664565;
+
+ // Object declarations
+ // Put the * in front of the variable names for strongly-typed object declarations
+ MyClass *myObject1 = nil; // Strong typing
+ id myObject2 = nil; // Weak typing
+ // %@ is an object
+ // 'description' is a convention to display the value of the Objects
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]); // Print "(null) and (null)"
+
+ // String
+ NSString *worldString = @"World";
+ NSLog(@"Hello %@!", worldString); // prints => "Hello World!"
+ // NSMutableString is a mutable version of the NSString object
+ NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
+ [mutableString appendString:@" World!"];
+ NSLog(@"%@", mutableString); // prints => "Hello World!"
+
+ // Character literals
+ NSNumber *theLetterZNumber = @'Z';
+ char theLetterZ = [theLetterZNumber charValue]; // or 'Z'
+ NSLog(@"%c", theLetterZ);
+
+ // Integral literals
+ NSNumber *fortyTwoNumber = @42;
+ int fortyTwo = [fortyTwoNumber intValue]; // or 42
+ NSLog(@"%i", fortyTwo);
+
+ NSNumber *fortyTwoUnsignedNumber = @42U;
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // or 42
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue]; // or 42
+ NSLog(@"%hi", fortyTwoShort);
+
+ 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 *fiftyThreeLongNumber = @53L;
+ unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // or 53
+ NSLog(@"%lu", fiftyThreeUnsigned);
+
+ // Floating point literals
+ NSNumber *piFloatNumber = @3.141592654F;
+ float piFloat = [piFloatNumber floatValue]; // or 3.141592654f
+ NSLog(@"%f", piFloat); // prints => 3.141592654
+ NSLog(@"%5.2f", piFloat); // prints => " 3.14"
+
+ NSNumber *piDoubleNumber = @3.1415926535;
+ double piDouble = [piDoubleNumber doubleValue]; // or 3.1415926535
+ NSLog(@"%f", piDouble);
+ NSLog(@"%4.2f", piDouble); // prints => "3.14"
+
+ // NSDecimalNumber is a fixed-point class that's more precise then float or double
+ NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"];
+ NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"];
+ // NSDecimalNumber isn't able to use standard +, -, *, / operators so it provides its own:
+ [oneDecNum decimalNumberByAdding:twoDecNum];
+ [oneDecNum decimalNumberBySubtracting:twoDecNum];
+ [oneDecNum decimalNumberByMultiplyingBy:twoDecNum];
+ [oneDecNum decimalNumberByDividingBy:twoDecNum];
+ NSLog(@"%@", oneDecNum); // prints => 10.99 as NSDecimalNumber is immutable
+
+ // BOOL literals
+ NSNumber *yesNumber = @YES;
+ NSNumber *noNumber = @NO;
+ // or
+ BOOL yesBool = YES;
+ BOOL noBool = NO;
+ 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
+ NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
+ [mutableArray addObject:@"Hello"];
+ [mutableArray addObject:@"World"];
+ [mutableArray removeObjectAtIndex:0];
+ NSLog(@"%@", [mutableArray objectAtIndex:0]); // prints => "World"
+
+ // Dictionary object
+ 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 *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+ [mutableDictionary setObject:@"value1" forKey:@"key1"];
+ [mutableDictionary setObject:@"value2" forKey:@"key2"];
+ [mutableDictionary removeObjectForKey:@"key1"];
+
+ // 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 *mutableSet = [NSMutableSet setWithCapacity:2];
+ [mutableSet addObject:@"Hello"];
+ [mutableSet addObject:@"Hello"];
+ NSLog(@"%@", mutableSet); // prints => {(Hello)}
+
+ ///////////////////////////////////////
+ // Operators
+ ///////////////////////////////////////
+
+ // The operators works like in the C language
+ // For example:
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (NO)
+ 3 != 2; // => 1 (YES)
+ 1 && 1; // => 1 (Logical and)
+ 0 || 1; // => 1 (Logical or)
+ ~0x0F; // => 0xF0 (bitwise negation)
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x01 << 1; // => 0x02 (bitwise left shift (by 1))
+
+ ///////////////////////////////////////
+ // Control Structures
+ ///////////////////////////////////////
+
+ // If-Else statement
+ if (NO)
+ {
+ NSLog(@"I am never run");
+ } else if (0)
+ {
+ NSLog(@"I am also never run");
+ } else
+ {
+ NSLog(@"I print");
+ }
+
+ // Switch statement
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"I am never run");
+ } break;
+ case 1:
+ {
+ NSLog(@"I am also never run");
+ } break;
+ default:
+ {
+ NSLog(@"I print");
+ } break;
+ }
+
+ // While loops statements
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++ increments ii in-place, after using its value
+ } // => prints "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // For loops statements
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj);
+ } // => prints "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Foreach statements
+ NSArray *values = @[@0, @1, @2, @3];
+ for (NSNumber *value in values)
+ {
+ NSLog(@"%@,", value);
+ } // => prints "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Object for loop statement. Can be used with any Objective-C object type
+ for (id item in values) {
+ NSLog(@"%@,", item);
+ } // => prints "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Try-Catch-Finally statements
+ @try
+ {
+ // Your statements here
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"File Not Found on System" userInfo:nil];
+ } @catch (NSException * e) // use: @catch (id exceptionName) to catch all objects.
+ {
+ NSLog(@"Exception: %@", e);
+ } @finally
+ {
+ NSLog(@"Finally. Time to clean up.");
+ } // => prints "Exception: File Not Found on System"
+ // "Finally. Time to clean up."
+
+ // NSError objects are useful for function arguments to populate on user mistakes.
+ NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil];
+
+ ///////////////////////////////////////
+ // Objects
+ ///////////////////////////////////////
+
+ // 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
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Clean up the memory you used into your program
+ [pool drain];
+
+ // End of @autoreleasepool
+ }
+
+ // End the program
+ return 0;
+}
+
+///////////////////////////////////////
+// Classes And Functions
+///////////////////////////////////////
+
+// Declare your class in a header file (MyClass.h):
+// Class declaration syntax:
+// @interface ClassName : ParentClassName <ImplementedProtocols>
+// {
+// type name; <= variable declarations;
+// }
+// @property type name; <= property declarations
+// -/+ (type) Method declarations; <= Method declarations
+// @end
+@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)
+ NSString *name;
+}
+// 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=lengthGet, setter=lengthSet:) int length;
+
+// Methods
++/- (return type)methodSignature:(Parameter Type *)parameterName;
+
+// + for class methods:
++ (NSString *)classMethod;
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight;
+
+// - for instance methods:
+- (NSString *)instanceMethodWithParameter:(NSString *)string;
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
+
+// 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 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;
+ }
+}
+
+// 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 instances of a class
+// This is a default constructor which is called when the object is initialized.
+- (id)init
+{
+ if ((self = [super init])) // 'super' used to access methods from parent class
+ {
+ 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";
+}
+
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
+{
+ return @42;
+}
+
+// Objective-C does not have private method declarations, but you can simulate them.
+// To simulate 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 // States the end of the implementation
+
+///////////////////////////////////////
+// Categories
+///////////////////////////////////////
+// A category is a group of methods designed to extend a class. They allow you to add new methods
+// to an existing class for organizational purposes. This is not to be mistaken with subclasses.
+// Subclasses are meant to CHANGE functionality of an object while categories instead ADD
+// functionality to an object.
+// Categories allow you to:
+// -- Add methods to an existing class for organizational purposes.
+// -- Allow you to extend Objective-C object classes (ex: NSString) to add your own methods.
+// -- Add ability to create protected and private methods to classes.
+// NOTE: Do not override methods of the base class in a category even though you have the ability
+// to. Overriding methods may cause compiler errors later between different categories and it
+// ruins the purpose of categories to only ADD functionality. Subclass instead to override methods.
+
+// Here is a simple Car base class.
+@interface Car : NSObject
+
+@property NSString *make;
+@property NSString *color;
+
+- (void)turnOn;
+- (void)accelerate;
+
+@end
+
+// And the simple Car base class implementation:
+#import "Car.h"
+
+@implementation Car
+
+@synthesize make = _make;
+@synthesize color = _color;
+
+- (void)turnOn {
+ NSLog(@"Car is on.");
+}
+- (void)accelerate {
+ NSLog(@"Accelerating.");
+}
+
+@end
+
+// Now, if we wanted to create a Truck object, we would instead create a subclass of Car as it would
+// be changing the functionality of the Car to behave like a truck. But lets say we want to just add
+// functionality to this existing Car. A good example would be to clean the car. So we would create
+// a category to add these cleaning methods:
+// @interface filename: Car+Clean.h (BaseClassName+CategoryName.h)
+#import "Car.h" // Make sure to import base class to extend.
+
+@interface Car (Clean) // The category name is inside () following the name of the base class.
+
+- (void)washWindows; // Names of the new methods we are adding to our Car object.
+- (void)wax;
+
+@end
+
+// @implementation filename: Car+Clean.m (BaseClassName+CategoryName.m)
+#import "Car+Clean.h" // Import the Clean category's @interface file.
+
+@implementation Car (Clean)
+
+- (void)washWindows {
+ NSLog(@"Windows washed.");
+}
+- (void)wax {
+ NSLog(@"Waxed.");
+}
+
+@end
+
+// Any Car object instance has the ability to use a category. All they need to do is import it:
+#import "Car+Clean.h" // Import as many different categories as you want to use.
+#import "Car.h" // Also need to import base class to use it's original functionality.
+
+int main (int argc, const char * argv[]) {
+ @autoreleasepool {
+ Car *mustang = [[Car alloc] init];
+ mustang.color = @"Red";
+ mustang.make = @"Ford";
+
+ [mustang turnOn]; // Use methods from base Car class.
+ [mustang washWindows]; // Use methods from Car's Clean category.
+ }
+ return 0;
+}
+
+// Objective-C does not have protected method declarations but you can simulate them.
+// Create a category containing all of the protected methods, then import it ONLY into the
+// @implementation file of a class belonging to the Car class:
+@interface Car (Protected) // Naming category 'Protected' to remember methods are protected.
+
+- (void)lockCar; // Methods listed here may only be created by Car objects.
+
+@end
+//To use protected methods, import the category, then implement the methods:
+#import "Car+Protected.h" // Remember, import in the @implementation file only.
+
+@implementation Car
+
+- (void)lockCar {
+ NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface.
+}
+
+@end
+
+///////////////////////////////////////
+// Extensions
+///////////////////////////////////////
+// Extensions allow you to override public access property attributes and methods of an @interface.
+// @interface filename: Shape.h
+@interface Shape : NSObject // Base Shape class extension overrides below.
+
+@property (readonly) NSNumber *numOfSides;
+
+- (int)getNumOfSides;
+
+@end
+// You can override numOfSides variable or getNumOfSides method to edit them with an extension:
+// @implementation filename: Shape.m
+#import "Shape.h"
+// Extensions live in the same file as the class @implementation.
+@interface Shape () // () after base class name declares an extension.
+
+@property (copy) NSNumber *numOfSides; // Make numOfSides copy instead of readonly.
+-(NSNumber)getNumOfSides; // Make getNumOfSides return a NSNumber instead of an int.
+-(void)privateMethod; // You can also create new private methods inside of extensions.
+
+@end
+// The main @implementation:
+@implementation Shape
+
+@synthesize numOfSides = _numOfSides;
+
+-(NSNumber)getNumOfSides { // All statements inside of extension must be in the @implementation.
+ return _numOfSides;
+}
+-(void)privateMethod {
+ NSLog(@"Private method created by extension. Shape instances cannot call me.");
+}
+
+@end
+
+///////////////////////////////////////
+// Protocols
+///////////////////////////////////////
+// A protocol declares methods that can be implemented by any class.
+// Protocols are not classes themselves. They simply define an interface
+// that other objects are responsible for implementing.
+// @protocol filename: "CarUtilities.h"
+@protocol CarUtilities <NSObject> // <NSObject> => Name of another protocol this protocol includes.
+ @property BOOL engineOn; // Adopting class must @synthesize all defined @properties and
+ - (void)turnOnEngine; // all defined methods.
+@end
+// Below is an example class implementing the protocol.
+#import "CarUtilities.h" // Import the @protocol file.
+
+@interface Car : NSObject <CarUtilities> // Name of protocol goes inside <>
+ // You don't need the @property or method names here for CarUtilities. Only @implementation does.
+- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // You can use protocols as data too.
+@end
+// The @implementation needs to implement the @properties and methods for the protocol.
+@implementation Car : NSObject <CarUtilities>
+
+@synthesize engineOn = _engineOn; // Create a @synthesize statement for the engineOn @property.
+
+- (void)turnOnEngine { // Implement turnOnEngine however you would like. Protocols do not define
+ _engineOn = YES; // how you implement a method, it just requires that you do implement it.
+}
+// You may use a protocol as data as you know what methods and variables it has implemented.
+- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
+ [objectOfSomeKind engineOn]; // You have access to object variables
+ [objectOfSomeKind turnOnEngine]; // and the methods inside.
+ [objectOfSomeKind engineOn]; // May or may not be YES. Class implements it however it wants.
+}
+
+@end
+// Instances of Car now have access to the protocol.
+Car *carInstance = [[Car alloc] init];
+[[carInstance setEngineOn:NO];
+[carInstance turnOnEngine];
+if ([carInstance engineOn]) {
+ NSLog(@"Car engine is on."); // prints => "Car engine is on."
+}
+// Make sure to check if an object of type 'id' implements a protocol before calling protocol methods:
+if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol.");
+} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"This does run as the Car class implements the CarUtilities protocol.");
+}
+// Categories may implement protocols as well: @interface Car (CarCategory) <CarUtilities>
+// You may implement many protocols: @interface Car : NSObject <CarUtilities, CarCleaning>
+// NOTE: If two or more protocols rely on each other, make sure to forward-declare them:
+#import "Brother.h"
+
+@protocol Brother; // Forward-declare statement. Without it, compiler would through error.
+
+@protocol Sister <NSObject>
+
+- (void)beNiceToBrother:(id <Brother>)brother;
+
+@end
+
+// See the problem is that Sister relies on Brother, and Brother relies on Sister.
+#import "Sister.h"
+
+@protocol Sister; // These lines stop the recursion, resolving the issue.
+
+@protocol Brother <NSObject>
+
+- (void)beNiceToSister:(id <Sister>)sister;
+
+@end
+
+
+///////////////////////////////////////
+// Blocks
+///////////////////////////////////////
+// Blocks are statements of code, just like a function, that are able to be used as data.
+// Below is a simple block with an integer argument that returns the argument plus 4.
+int (^addUp)(int n); // Declare a variable to store the block.
+void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments.
+// Blocks have access to variables in the same scope. But the variables are readonly and the
+// value passed to the block is the value of the variable when the block is created.
+int outsideVar = 17; // If we edit outsideVar after declaring addUp, outsideVar is STILL 17.
+__block long mutableVar = 3; // __block makes variables writable to blocks, unlike outsideVar.
+addUp = ^(int n) { // Remove (int n) to have a block that doesn't take in any parameters.
+ NSLog(@"You may have as many lines in a block as you would like.");
+ NSSet *blockSet; // Also, you can declare local variables.
+ mutableVar = 32; // Assigning new value to __block variable.
+ return n + outsideVar; // Return statements are optional.
+}
+int addUp = add(10 + 16); // Calls block code with arguments.
+// Blocks are often used as arguments to functions to be called later, or for callbacks.
+@implementation BlockExample : NSObject
+
+ - (void)runBlock:(void (^)(NSString))block {
+ NSLog(@"Block argument returns nothing and takes in a NSString object.");
+ block(@"Argument given to block to execute."); // Calling block.
+ }
+
+ @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)
+
+[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/perl.html.markdown b/perl.html.markdown
new file mode 100644
index 00000000..da2e0cdf
--- /dev/null
+++ b/perl.html.markdown
@@ -0,0 +1,147 @@
+---
+name: perl
+category: language
+language: perl
+filename: learnperl.pl
+contributors:
+ - ["Korjavin Ivan", "http://github.com/korjavin"]
+---
+
+Perl 5 is a highly capable, feature-rich programming language with over 25 years of development.
+
+Perl 5 runs on over 100 platforms from portables to mainframes and is suitable for both rapid prototyping and large scale development projects.
+
+```perl
+# Single line comments start with a number symbol.
+
+
+#### Perl variable types
+
+# Variables begin with the $ symbol.
+# A valid variable name starts with a letter or underscore,
+# followed by any number of letters, numbers, or underscores.
+
+### Perl has three main variable types: scalars, arrays, and hashes.
+
+## Scalars
+# A scalar represents a single value:
+my $animal = "camel";
+my $answer = 42;
+
+# Scalar values can be strings, integers or floating point numbers, and Perl will automatically convert between them as required.
+
+## Arrays
+# An array represents a list of values:
+my @animals = ("camel", "llama", "owl");
+my @numbers = (23, 42, 69);
+my @mixed = ("camel", 42, 1.23);
+
+
+
+## Hashes
+# A hash represents a set of key/value pairs:
+
+my %fruit_color = ("apple", "red", "banana", "yellow");
+
+# You can use whitespace and the "=>" operator to lay them out more nicely:
+
+my %fruit_color = (
+ apple => "red",
+ banana => "yellow",
+ );
+# Scalars, arrays and hashes are documented more fully in perldata. (perldoc perldata).
+
+# More complex data types can be constructed using references, which allow you to build lists and hashes within lists and hashes.
+
+#### Conditional and looping constructs
+
+# Perl has most of the usual conditional and looping constructs.
+
+if ( $var ) {
+ ...
+} elsif ( $var eq 'bar' ) {
+ ...
+} else {
+ ...
+}
+
+unless ( condition ) {
+ ...
+ }
+# This is provided as a more readable version of "if (!condition)"
+
+# the Perlish post-condition way
+print "Yow!" if $zippy;
+print "We have no bananas" unless $bananas;
+
+# while
+ while ( condition ) {
+ ...
+ }
+
+
+# for and foreach
+for ($i = 0; $i <= $max; $i++) {
+ ...
+ }
+
+foreach (@array) {
+ print "This element is $_\n";
+ }
+
+
+#### Regular expressions
+
+# Perl's regular expression support is both broad and deep, and is the subject of lengthy documentation in perlrequick, perlretut, and elsewhere. However, in short:
+
+# Simple matching
+if (/foo/) { ... } # true if $_ contains "foo"
+if ($a =~ /foo/) { ... } # true if $a contains "foo"
+
+# Simple substitution
+
+$a =~ s/foo/bar/; # replaces foo with bar in $a
+$a =~ s/foo/bar/g; # replaces ALL INSTANCES of foo with bar in $a
+
+
+#### Files and I/O
+
+# You can open a file for input or output using the "open()" function.
+
+open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
+open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
+open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
+
+# You can read from an open filehandle using the "<>" operator. In scalar context it reads a single line from
+# the filehandle, and in list context it reads the whole file in, assigning each line to an element of the list:
+
+my $line = <$in>;
+my @lines = <$in>;
+
+#### Writing subroutines
+
+# Writing subroutines is easy:
+
+sub logger {
+ my $logmessage = shift;
+ open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
+ print $logfile $logmessage;
+}
+
+# Now we can use the subroutine just as any other built-in function:
+
+logger("We have a logger subroutine!");
+```
+
+#### Using Perl modules
+
+Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN (http://www.cpan.org/). A number of popular modules are included with the Perl distribution itself.
+
+perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
+
+#### Further Reading
+
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [Learn at www.perl.com](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - and perl built-in : `perldoc perlintro`
diff --git a/php.html.markdown b/php.html.markdown
index ce228870..e1bb86a0 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -11,7 +11,7 @@ This document describes PHP 5+.
```php
<?php // PHP code must be enclosed with <?php tags
-// If your php file only contains PHP code, it is best practise
+// If your php file only contains PHP code, it is best practice
// to omit the php closing tag.
// Two forward slashes start a one-line comment.
@@ -59,6 +59,9 @@ $float = 1.234;
$float = 1.2e3;
$float = 7E-10;
+// Delete variable
+unset($int1)
+
// Arithmetic
$sum = 1 + 1; // 2
$difference = 2 - 1; // 1
@@ -69,7 +72,7 @@ $quotient = 2 / 1; // 2
$number = 0;
$number += 1; // Increment $number by 1
echo $number++; // Prints 1 (increments after evaluation)
-echo ++$number; // Prints 3 (increments before evalutation)
+echo ++$number; // Prints 3 (increments before evaluation)
$number /= $float; // Divide and assign the quotient to $number
// Strings should be enclosed in single quotes;
@@ -104,7 +107,7 @@ echo 'This string ' . 'is concatenated';
/********************************
* Constants
*/
-
+
// A constant is defined by using define()
// and can never be changed during runtime!
@@ -136,6 +139,11 @@ echo $associative['One']; // prints 1
$array = ['One', 'Two', 'Three'];
echo $array[0]; // => "One"
+// Add an element to the end of an array
+$array[] = 'Four';
+
+// Remove element from array
+unset($array[3]);
/********************************
* Output
@@ -176,6 +184,11 @@ $y = 0;
echo $x; // => 2
echo $z; // => 0
+// Dumps type and value of variable to stdout
+var_dump($z); // prints int(0)
+
+// Prints variable to stdout in human-readable format
+print_r($array); // prints: Array ( [0] => One [1] => Two [2] => Three )
/********************************
* Logic
@@ -199,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.
@@ -440,6 +453,13 @@ class MyClass
static $staticVar = 'static';
+ // Static variables and their visibility
+ public static $publicStaticVar = 'publicStatic';
+ // Accessible within the class only
+ private static $privateStaticVar = 'privateStatic';
+ // Accessible from the class and subclasses
+ protected static $protectedStaticVar = 'protectedStatic';
+
// Properties must declare their visibility
public $property = 'public';
public $instanceProp;
@@ -458,10 +478,17 @@ class MyClass
print 'MyClass';
}
+ //final keyword would make a function unoverridable
final function youCannotOverrideMe()
{
}
+/*
+ * Declaring class properties or methods as static makes them accessible without
+ * needing an instantiation of the class. A property declared as static can not
+ * be accessed with an instantiated class object (though a static method can).
+*/
+
public static function myStaticMethod()
{
print 'I am static';
@@ -650,10 +677,14 @@ $cls = new SomeOtherNamespace\MyClass();
## More Information
-Visit the [official PHP documentation](http://www.php.net/manual/) for reference and community input.
+Visit the [official PHP documentation](http://www.php.net/manual/) for reference
+and community input.
-If you're interested in up-to-date best practices, visit [PHP The Right Way](http://www.phptherightway.com/).
+If you're interested in up-to-date best practices, visit
+[PHP The Right Way](http://www.phptherightway.com/).
-If you're coming from a language with good package management, check out [Composer](http://getcomposer.org/).
+If you're coming from a language with good package management, check out
+[Composer](http://getcomposer.org/).
-For common standards, visit the PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards).
+For common standards, visit the PHP Framework Interoperability Group's
+[PSR standards](https://github.com/php-fig/fig-standards).
diff --git a/pogo.html.markdown b/pogo.html.markdown
new file mode 100644
index 00000000..60a83edd
--- /dev/null
+++ b/pogo.html.markdown
@@ -0,0 +1,202 @@
+---
+language: pogoscript
+contributors:
+ - ["Tim Macfarlane", "http://github.com/refractalize"]
+filename: learnPogo.pogo
+---
+
+Pogoscript is a little language that emphasises readability, DSLs and provides excellent asynchronous primitives for writing connected JavaScript applications for the browser or server.
+
+``` javascript
+// defining a variable
+water temperature = 24
+
+// re-assigning a variable after its definition
+water temperature := 26
+
+// functions allow their parameters to be placed anywhere
+temperature at (a) altitude = 32 - a / 100
+
+// longer functions are just indented
+temperature at (a) altitude :=
+ if (a < 0)
+ water temperature
+ else
+ 32 - a / 100
+
+// calling a function
+current temperature = temperature at 3200 altitude
+
+// this function constructs a new object with methods
+position (x, y) = {
+ x = x
+ y = y
+
+ distance from position (p) =
+ dx = self.x - p.x
+ dy = self.y - p.y
+ Math.sqrt (dx * dx + dy * dy)
+}
+
+// `self` is similar to `this` in JavaScript with the
+// exception that `self` isn't redefined in each new
+// function definition
+// `self` just does what you expect
+
+// calling methods
+position (7, 2).distance from position (position (5, 1))
+
+// as in JavaScript, objects are hashes too
+position.'x' == position.x == position.('x')
+
+// arrays
+positions = [
+ position (1, 1)
+ position (1, 2)
+ position (1, 3)
+]
+
+// indexing an array
+positions.0.y
+
+n = 2
+positions.(n).y
+
+// strings
+poem = 'Tail turned to red sunset on a juniper crown a lone magpie cawks.
+ Mad at Oryoki in the shrine-room -- Thistles blossomed late afternoon.
+ Put on my shirt and took it off in the sun walking the path to lunch.
+ A dandelion seed floats above the marsh grass with the mosquitos.
+ At 4 A.M. the two middleaged men sleeping together holding hands.
+ In the half-light of dawn a few birds warble under the Pleiades.
+ Sky reddens behind fir trees, larks twitter, sparrows cheep cheep cheep
+ cheep cheep.'
+
+// that's Allen Ginsburg
+
+// interpolation
+outlook = 'amazing!'
+console.log "the weather tomorrow is going to be #(outlook)"
+
+// regular expressions
+r/(\d+)m/i
+r/(\d+) degrees/mg
+
+// operators
+true @and true
+false @or true
+@not false
+2 < 4
+2 >= 2
+2 > 1
+
+// plus all the javascript ones
+
+// to define your own
+(p1) plus (p2) =
+ position (p1.x + p2.x, p1.y + p2.y)
+
+// `plus` can be called as an operator
+position (1, 1) @plus position (0, 2)
+// or as a function
+(position (1, 1)) plus (position (0, 2))
+
+// explicit return
+(x) times (y) = return (x * y)
+
+// new
+now = @new Date ()
+
+// functions can take named optional arguments
+spark (position, color: 'black', velocity: {x = 0, y = 0}) = {
+ color = color
+ position = position
+ velocity = velocity
+}
+
+red = spark (position 1 1, color: 'red')
+fast black = spark (position 1 1, velocity: {x = 10, y = 0})
+
+// functions can unsplat arguments too
+log (messages, ...) =
+ console.log (messages, ...)
+
+// blocks are functions passed to other functions.
+// This block takes two parameters, `spark` and `c`,
+// the body of the block is the indented code after the
+// function call
+
+render each @(spark) into canvas context @(c)
+ ctx.begin path ()
+ ctx.stroke style = spark.color
+ ctx.arc (
+ spark.position.x + canvas.width / 2
+ spark.position.y
+ 3
+ 0
+ Math.PI * 2
+ )
+ ctx.stroke ()
+
+// asynchronous calls
+
+// JavaScript both in the browser and on the server (with Node.js)
+// makes heavy use of asynchronous IO with callbacks. Async IO is
+// amazing for performance and making concurrency simple but it
+// quickly gets complicated.
+// Pogoscript has a few things to make async IO much much easier
+
+// Node.js includes the `fs` module for accessing the file system.
+// Let's list the contents of a directory
+
+fs = require 'fs'
+directory listing = fs.readdir! '.'
+
+// `fs.readdir()` is an asynchronous function, so we can call it
+// using the `!` operator. The `!` operator allows you to call
+// async functions with the same syntax and largely the same
+// semantics as normal synchronous functions. Pogoscript rewrites
+// it so that all subsequent code is placed in the callback function
+// to `fs.readdir()`.
+
+// to catch asynchronous errors while calling asynchronous functions
+
+try
+ another directory listing = fs.readdir! 'a-missing-dir'
+catch (ex)
+ console.log (ex)
+
+// in fact, if you don't use `try catch`, it will raise the error up the
+// stack to the outer-most `try catch` or to the event loop, as you'd expect
+// with non-async exceptions
+
+// all the other control structures work with asynchronous calls too
+// here's `if else`
+config =
+ if (fs.stat! 'config.json'.is file ())
+ JSON.parse (fs.read file! 'config.json' 'utf-8')
+ else
+ {
+ color: 'red'
+ }
+
+// to run two asynchronous calls concurrently, use the `?` operator.
+// The `?` operator returns a *future* which can be executed to
+// wait for and obtain the result, again using the `!` operator
+
+// we don't wait for either of these calls to finish
+a = fs.stat? 'a.txt'
+b = fs.stat? 'b.txt'
+
+// now we wait for the calls to finish and print the results
+console.log "size of a.txt is #(a!.size)"
+console.log "size of b.txt is #(b!.size)"
+
+// futures in Pogoscript are analogous to Promises
+```
+
+That's it.
+
+Download [Node.js](http://nodejs.org/) and `npm install pogo`.
+
+There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), inlcuding a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!
diff --git a/pt-br/elisp-pt.html.markdown b/pt-br/elisp-pt.html.markdown
new file mode 100644
index 00000000..fc2d1e40
--- /dev/null
+++ b/pt-br/elisp-pt.html.markdown
@@ -0,0 +1,359 @@
+---
+language: elisp
+contributors:
+ - ["Bastien Guerry", "http://bzg.fr"]
+translators:
+ - ["Lucas Tadeu Teixeira", "http://ltt.me"]
+lang: pt-br
+filename: learn-emacs-lisp-pt.el
+---
+
+```scheme
+;; Introdução ao Emacs Lisp em 15 minutos (v0.2d)
+;;
+;; Autor: Bastien / @bzg2 / http://bzg.fr
+;;
+;; Antes de começar, leia este texto escrito Peter Norvig:
+;; http://norvig.com/21-days.html
+;;
+;; Agora instale GNU Emacs 24.3:
+;;
+;; Debian: apt-get install emacs (ou veja as instruções da sua distribuição)
+;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
+;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
+;;
+;; Informações mais gerais podem ser encontradas em:
+;; http://www.gnu.org/software/emacs/#Obtaining
+
+;; Aviso importante:
+;;
+;; Realizar este tutorial não danificará seu computador, a menos
+;; que você fique tão irritado a ponto de jogá-lo no chão. Neste caso,
+;; me abstenho de qualquer responsabilidade. Divirta-se!
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Abra o Emacs.
+;;
+;; Aperte a tecla `q' para ocultar a mensagem de boas vindas.
+;;
+;; Agora olhe para a linha cinza na parte inferior da janela:
+;;
+;; "*scratch*" é o nome do espaço de edição em que você se encontra.
+;; Este espaço de edição é chamado "buffer".
+;;
+;; O buffer de rascunho (i.e., "scratch") é o buffer padrão quando
+;; o Emacs é aberto. Você nunca está editando arquivos: você está
+;; editando buffers que você pode salvar em um arquivo.
+;;
+;; "Lisp interaction" refere-se a um conjunto de comandos disponíveis aqui.
+;;
+;; O Emacs possui um conjunto de comandos embutidos (disponíveis em
+;; qualquer buffer) e vários subconjuntos de comandos disponíveis
+;; quando você ativa um modo específico. Aqui nós utilizamos
+;; `lisp-interaction-mode', que possui comandos para interpretar e navegar
+;; em código Elisp.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Pontos e vírgulas iniciam comentários em qualquer parte de uma linha.
+;;
+;; Programas codificados em Elisp são compostos por expressões simbólicas
+;; (conhecidas também por "sexps"):
+(+ 2 2)
+
+;; Esta expressão simbólica significa "Some 2 e 2".
+
+;; "Sexps" são envoltas em parêntese, possivelmente aninhados:
+(+ 2 (+ 1 1))
+
+;; Uma expressão simbólica contém átomos ou outras expressões
+;; simbólicas. Nos exemplos acima, 1 e 2 são átomos;
+;; (+ 2 (+ 1 1)) e (+ 1 1) são expressões simbólicas.
+
+;; No modo `lisp-interaction-mode' você pode interpretar "sexps".
+;; Posicione o cursor logo após o parêntese de fechamento e,
+;; então, segure apertado Ctrl e aperte a tecla j ("C-j", em resumo).
+
+(+ 3 (+ 1 2))
+;; ^ posicione o cursor aqui
+;; `C-j' => 6
+
+;; `C-j' insere o resultado da interpretação da expressão no buffer.
+
+;; `C-xC-e' exibe o mesmo resultado na linha inferior do Emacs,
+;; chamada de "mini-buffer". Nós geralmente utilizaremos `C-xC-e',
+;; já que não queremos poluir o buffer com texto desnecessário.
+
+;; `setq' armazena um valor em uma variável:
+(setq my-name "Bastien")
+;; `C-xC-e' => "Bastien" (texto exibido no mini-buffer)
+
+;; `insert' insere "Hello!" na posição em que se encontra seu cursor:
+(insert "Hello!")
+;; `C-xC-e' => "Hello!"
+
+;; Nós executamos `insert' com apenas um argumento ("Hello!"), mas
+;; mais argumentos podem ser passados -- aqui utilizamos dois:
+
+(insert "Hello" " world!")
+;; `C-xC-e' => "Hello world!"
+
+;; Você pode utilizar variávies no lugar de strings:
+(insert "Hello, I am " my-name)
+;; `C-xC-e' => "Hello, I am Bastien"
+
+;; Você pode combinar "sexps" em funções:
+(defun hello () (insert "Hello, I am " my-name))
+;; `C-xC-e' => hello
+
+;; Você pode interpretar chamadas de funções:
+(hello)
+;; `C-xC-e' => Hello, I am Bastien
+
+;; Os parêntesis vazios na definição da função significam que ela
+;; não aceita argumentos. Mas sempre utilizar `my-name' é um tédio!
+;; Vamos dizer à função para aceitar um argumento (o argumento é
+;; chamado "name"):
+
+(defun hello (name) (insert "Hello " name))
+;; `C-xC-e' => hello
+
+;; Agora vamos executar a função com a string "you" como o valor
+;; para seu único parâmetro:
+(hello "you")
+;; `C-xC-e' => "Hello you"
+
+;; Aí sim!
+
+;; Respire um pouco.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Agora mude para um novo buffer chamado "*test*":
+
+(switch-to-buffer-other-window "*test*")
+;; `C-xC-e'
+;; => [a tela exibirá duas janelas e o cursor estará no buffer *test*]
+
+;; Posicione o mouse sobre a janela superior e clique com o botão
+;; esquerdo para voltar. Ou você pode utilizar `C-xo' (i.e. segure
+;; ctrl-x e aperte o) para voltar para a outra janela, de forma interativa.
+
+;; Você pode combinar várias "sexps" com `progn':
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (hello "you"))
+;; `C-xC-e'
+;; => [A tela exibirá duas janelas e o cursor estará no buffer *test*]
+
+;; Agora, se você não se importar, pararei de pedir que você aperte
+;; `C-xC-e': faça isso para cada "sexp" que escrevermos.
+
+;; Sempre volte para o buffer *scratch* com o mouse ou `C-xo'.
+
+;; Frequentemente, é útil apagar o conteúdo do buffer:
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "there"))
+
+;; Ou voltar para a outra janela:
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "you")
+ (other-window 1))
+
+;; Você pode armazenar um valor em uma variável local utilizando `let':
+(let ((local-name "you"))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello local-name)
+ (other-window 1))
+
+;; Neste caso, não é necessário utilizar `progn' já que `let' combina
+;; várias "sexps".
+
+;; Vamos formatar uma string:
+(format "Hello %s!\n" "visitor")
+
+;; %s é um espaço reservado para uma string, substituído por "visitor".
+;; \n é um caractere de nova linha.
+
+;; Vamos refinar nossa função utilizando `format':
+(defun hello (name)
+ (insert (format "Hello %s!\n" name)))
+
+(hello "you")
+
+;; Vamos criar outra função que utilize `let':
+(defun greeting (name)
+ (let ((your-name "Bastien"))
+ (insert (format "Hello %s!\n\nI am %s."
+ name ; the argument of the function
+ your-name ; the let-bound variable "Bastien"
+ ))))
+
+;; E executá-la:
+(greeting "you")
+
+;; Algumas funções são interativas:
+(read-from-minibuffer "Enter your name: ")
+
+;; Ao ser interpretada, esta função retorna o que você digitou no prompt.
+
+;; Vamos fazer nossa função `greeting' pedir pelo seu nome:
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (insert (format "Hello!\n\nI am %s and you are %s."
+ from-name ; the argument of the function
+ your-name ; the let-bound var, entered at prompt
+ ))))
+
+(greeting "Bastien")
+
+;; Vamos finalizá-la fazendo-a exibir os resultados em outra janela:
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (insert (format "Hello %s!\n\nI am %s." your-name from-name))
+ (other-window 1)))
+
+;; Agora teste-a:
+(greeting "Bastien")
+
+;; Respire um pouco.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Vamos armazenar uma lista de nomes:
+(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
+
+;; Pegue o primeiro elemento desta lista utilizando `car':
+(car list-of-names)
+
+;; Pegue uma lista de todos os elementos, exceto o primeiro, utilizando
+;; `cdr':
+(cdr list-of-names)
+
+;; Adicione um elemento ao início da lista com `push':
+(push "Stephanie" list-of-names)
+
+;; NOTA: `car' e `cdr' não modificam a lista, `push' sim.
+;; Esta é uma diferença importante: algumas funções não têm qualquer
+;; efeito colateral (como `car'), enquanto outras sim (como `push').
+
+;; Vamos executar `hello' para cada elemento em `list-of-names':
+(mapcar 'hello list-of-names)
+
+;; Refine `greeting' para saudar todos os nomes em `list-of-names':
+(defun greeting ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (mapcar 'hello list-of-names)
+ (other-window 1))
+
+(greeting)
+
+;; Você se lembra da função `hello' que nós definimos lá em cima? Ela
+;; recebe um argumento, um nome. `mapcar' executa `hello', sucessivamente,
+;; utilizando cada elemento de `list-of-names' como argumento para `hello'.
+
+;; Agora vamos arrumar, um pouco, o que nós temos escrito no buffer:
+
+(defun replace-hello-by-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (search-forward "Hello")
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+;; (goto-char (point-min)) vai para o início do buffer.
+;; (search-forward "Hello") busca pela string "Hello".
+;; (while x y) interpreta a(s) sexp(s) y enquanto x retornar algo.
+;; Se x retornar `nil' (nada), nós saímos do laço.
+
+(replace-hello-by-bonjour)
+
+;; Você deveria ver todas as ocorrências de "Hello" no buffer *test*
+;; substituídas por "Bonjour".
+
+;; Você deveria, também, receber um erro: "Search failed: Hello".
+;;
+;; Para evitar este erro, você precisa dizer ao `search-forward' se ele
+;; deveria parar de buscar em algum ponto no buffer, e se ele deveria
+;; falhar de forma silenciosa quando nada fosse encontrado:
+
+;; (search-forward "Hello" nil t) dá conta do recado:
+
+;; O argumento `nil' diz: a busca não está limitada a uma posição.
+;; O argumento `t' diz: falhe silenciosamente quando nada for encontrado.
+
+;; Nós utilizamos esta "sexp" na função abaixo, que não gera um erro:
+
+(defun hello-to-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ ;; Say hello to names in `list-of-names'
+ (mapcar 'hello list-of-names)
+ (goto-char (point-min))
+ ;; Replace "Hello" by "Bonjour"
+ (while (search-forward "Hello" nil t)
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+(hello-to-bonjour)
+
+;; Vamos colorir os nomes:
+
+(defun boldify-names ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
+ (add-text-properties (match-beginning 1)
+ (match-end 1)
+ (list 'face 'bold)))
+ (other-window 1))
+
+;; Esta função introduz `re-search-forward': ao invés de buscar
+;; pela string "Bonjour", você busca por um padrão utilizando uma
+;; "expressão regular" (abreviada pelo prefixo "re-").
+
+;; A expressão regular é "Bonjour \\(.+\\)!" e lê-se:
+;; a string "Bonjour ", e
+;; um grupo de | que é o \\( ... \\)
+;; quaisquer caracteres | que é o .
+;; possivelmente repetidos | que é o +
+;; e a string "!".
+
+;; Preparado? Teste!
+
+(boldify-names)
+
+;; `add-text-properties' adiciona... propriedades de texto, como uma fonte.
+
+;; OK, terminamos por aqui. Feliz Hacking!
+
+;; Se você quiser saber mais sobre uma variável ou função:
+;;
+;; C-h v uma-variável RET
+;; C-h f uma-função RET
+;;
+;; Para ler o manual de Emacs Lisp que vem com o Emacs:
+;;
+;; C-h i m elisp RET
+;;
+;; Para ler uma introdução online ao Emacs Lisp:
+;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
+
+;; Agradecimentos a estas pessoas por seu feedback e sugestões:
+;; - Wes Hardaker
+;; - notbob
+;; - Kevin Montuori
+;; - Arne Babenhauserheide
+;; - Alan Schmitt
+;; - LinXitoW
+;; - Aaron Meurer
+```
diff --git a/pt-br/erlang-pt.html.markdown b/pt-br/erlang-pt.html.markdown
new file mode 100644
index 00000000..a81e5a1f
--- /dev/null
+++ b/pt-br/erlang-pt.html.markdown
@@ -0,0 +1,254 @@
+---
+language: erlang
+filename: learnerlang-pt.erl
+contributors:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
+translators:
+ - ["Guilherme Heuser Prestes", "http://twitter.com/gprestes"]
+lang: pt-br
+---
+
+```erlang
+% Símbolo de porcento começa comentários de uma linha.
+
+%% Dois caracteres de porcento devem ser usados para comentar funções.
+
+%%% Três caracteres de porcento devem ser usados para comentar módulos.
+
+% Nós usamos três tipos de pontuação em Erlang.
+% Vírgulas (`,`) separam argumentos em chamadas de função, construtores de
+% dados, e padrões.
+% Pontos finais (`.`) separam totalmente funções e expressões no prompt.
+% Ponto e vírgulas (`;`) separam cláusulas. Nós encontramos cláusulas em
+% vários contextos: definições de função e em expressões com `case`, `if`,
+% `try..catch` e `receive`.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 1. Variáveis e casamento de padrões.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Num = 42. % Todos nomes de variáveis devem começar com uma letra maiúscula.
+
+% Erlang tem atribuição única de variáveis, se você tentar atribuir um valor
+% diferente à variável `Num`, você receberá um erro.
+Num = 43. % ** exception error: no match of right hand side value 43
+
+% Na maioria das linguagens, `=` denota um comando de atribuição. Em Erlang, no
+% entanto, `=` denota uma operação de casamento de padrão. `Lhs = Rhs` realmente
+% significa isso: avalia o lado direito (Rhs), e então casa o resultado com o
+% padrão no lado esquerdo (Lhs).
+Num = 7 * 6.
+
+% Número de ponto flutuante.
+Pi = 3.14159.
+
+% Átomos são usados para representar diferentes valores constantes não
+% numéricos. Átomos começam com letras minúsculas seguidas por uma sequência de
+% caracteres alfanuméricos ou sinais de subtraço (`_`) ou arroba (`@`).
+Hello = hello.
+OtherNode = example@node.
+
+% Átomos com valores alfanuméricos podem ser escritos colocando aspas por fora
+% dos átomos.
+AtomWithSpace = 'some atom with space'.
+
+% Tuplas são similares a structs em C.
+Point = {point, 10, 45}.
+
+% Se nós queremos extrair alguns valores de uma tupla, nós usamos o operador `=`.
+{point, X, Y} = Point. % X = 10, Y = 45
+
+% Nós podemos usar `_` para ocupar o lugar de uma variável que não estamos interessados.
+% O símbolo `_` é chamado de variável anônima. Ao contrário de variáveis regulares,
+% diversas ocorrências de _ no mesmo padrão não precisam se amarrar ao mesmo valor.
+Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
+{_, {_, {_, Who}, _}, _} = Person. % Who = joe
+
+% Nós criamos uma lista colocando valores separados por vírgula entre colchetes.
+% Cada elemento de uma lista pode ser de qualquer tipo.
+% O primeiro elemento de uma lista é a cabeça da lista. Se removermos a cabeça
+% da lista, o que sobra é chamado de cauda da lista.
+ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
+
+% Se `T` é uma lista, então `[H|T]` também é uma lista, com cabeça `H` e cauda `T`.
+% A barra vertical (`|`) separa a cabeça de uma lista de sua cauda.
+% `[]` é uma lista vazia.
+% Podemos extrair elementos de uma lista com uma operação de casamento de
+% padrão. Se temos uma lista não-vazia `L`, então a expressão `[X|Y] = L`, onde
+% `X` e `Y` são variáveis desamarradas, irá extrair a cabeça de uma lista para
+% `X` e a cauda da lista para `Y`.
+[FirstThing|OtherThingsToBuy] = ThingsToBuy.
+% FirstThing = {apples, 10}
+% OtherThingsToBuy = {pears, 6}, {milk, 3}
+
+% Não existe o tipo string em Erlang. Strings são somente listas de inteiros.
+% Strings são representadas dentro de aspas duplas (`"`).
+Name = "Hello".
+[72, 101, 108, 108, 111] = "Hello".
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 2. Programação sequencial.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Módulos são a unidade básica de código em Erlang. Todas funções que
+% escrevemos são armazenadas em módulos. Módulos são armazenados em arquivos
+% com extensão `.erl`.
+% Módulos devem ser compilados antes que o código possa ser rodado. Um módulo
+% compilado tem a extensão `.beam`.
+-module(geometry).
+-export([area/1]). % lista de funções exportadas de um módulo.
+
+% A função `area` consiste de duas cláusulas. As cláusulas são separadas por um
+% ponto e vírgula, e a cláusula final é terminada por um ponto final.
+% Cada cláusula tem uma cabeça em um corpo; a cabeça consiste de um nome de
+% função seguido por um padrão (entre parêntesis), e o corpo consiste de uma
+% sequência de expressões, que são avaliadas se o padrão na cabeça é um par bem
+% sucedido dos argumentos da chamada. Os padrões são casados na ordem que
+% aparecem na definição da função.
+area({rectangle, Width, Ht}) -> Width * Ht;
+area({circle, R}) -> 3.14159 * R * R.
+
+% Compila o código no arquivo geometry.erl.
+c(geometry). % {ok,geometry}
+
+% Nós precisamos incluir o nome do módulo junto com o nome da função de maneira
+% a identificar exatamente qual função queremos chamar.
+geometry:area({rectangle, 10, 5}). % 50
+geometry:area({circle, 1.4}). % 6.15752
+
+% Em Erlang, duas funções com o mesmo nome e diferentes aridades (números de
+% argumentos) no mesmo módulo representam funções totalmente diferentes.
+-module(lib_misc).
+-export([sum/1]). % exporta a função `sum` de aridade 1 aceitando um argumento: lista de inteiros.
+sum(L) -> sum(L, 0).
+sum([], N) -> N;
+sum([H|T], N) -> sum(T, H+N).
+
+% Funs são funções "anônimas". Elas são chamadas desta maneira por que elas não
+% têm nome. No entanto podem ser atribuídas a variáveis.
+Double = fun(X) -> 2*X end. % `Double` aponta para uma função anônima com referência: #Fun<erl_eval.6.17052888>
+Double(2). % 4
+
+% Funções aceitam funs como seus argumentos e podem retornar funs.
+Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
+Triple = Mult(3).
+Triple(5). % 15
+
+% Compreensão de lista são expressões que criam listas sem precisar usar funs,
+% maps, ou filtros.
+% A notação `[F(X) || X <- L]` significa "a lista de `F(X)` onde `X` é tomada
+% da lista `L`."
+L = [1,2,3,4,5].
+[2*X || X <- L]. % [2,4,6,8,10]
+% Uma compreensão de lista pode ter geradores e filtros que selecionam
+% subconjuntos dos valores gerados.
+EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
+
+% Sentinelas são contruções que podemos usar para incrementar o poder de
+% casamento de padrão. Usando sentinelas, podemos executar testes simples e
+% comparações nas variáveis em um padrão.
+% Você pode usar sentinelas nas cabeças das definições de função onde eles são
+% introduzidos pela palavra-chave `when`, ou você pode usá-los em qualquer
+% lugar na linguagem onde uma expressão é permitida.
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+% Um sentinela é uma série de expressões sentinelas, separadas por
+% vírgulas (`,`).
+% O sentinela `GuardExpr1, GuardExpr2, ..., GuardExprN` é verdadeiro se todas
+% expressões sentinelas `GuardExpr1, GuardExpr2, ...` forem verdadeiras.
+is_cat(A) when is_atom(A), A =:= cat -> true;
+is_cat(A) -> false.
+is_dog(A) when is_atom(A), A =:= dog -> true;
+is_dog(A) -> false.
+
+% Uma `sequência sentinela` é um sentinela ou uma série de sentinelas separados
+% por ponto e vírgula (`;`). A sequência sentinela `G1; G2; ...; Gn` é
+% verdadeira se pelo menos um dos sentinelas `G1, G2, ...` for verdadeiro.
+is_pet(A) when is_dog(A); is_cat(A) -> true;
+is_pet(A) -> false.
+
+% Registros provêem um método para associar um nome com um elemento particular
+% em uma tupla.
+% Definições de registro podem ser incluídas em arquivos fonte Erlang ou em
+% arquivos com extensão `.hrl`, que então são incluídos em arquivos fonte Erlang.
+-record(todo, {
+ status = reminder, % Default value
+ who = joe,
+ text
+}).
+
+% Nós temos que ler definições de registro no prompt antes que possamos definir
+% um registro. Nós usamos a função de prompt `rr` (abreviação de read records)
+% para fazer isso.
+rr("records.hrl"). % [todo]
+
+% Criando e atualizando registros:
+X = #todo{}.
+% #todo{status = reminder, who = joe, text = undefined}
+X1 = #todo{status = urgent, text = "Fix errata in book"}.
+% #todo{status = urgent, who = joe, text = "Fix errata in book"}
+X2 = X1#todo{status = done}.
+% #todo{status = done,who = joe,text = "Fix errata in book"}
+
+% Expressões `case`.
+% A função `filter` retorna uma lista de todos elementos `X` em uma lista `L`
+% para qual `P(X)` é verdadeiro.
+filter(P, [H|T]) ->
+ case P(H) of
+ true -> [H|filter(P, T)];
+ false -> filter(P, T)
+ end;
+filter(P, []) -> [].
+filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
+
+% Expressões `if`.
+max(X, Y) ->
+ if
+ X > Y -> X;
+ X < Y -> Y;
+ true -> nil;
+ end.
+
+% Aviso: pelo menos um dos sentinelas na expressão `if` deve retornar
+% verdadeiro; Caso contrário, uma exceção será levantada.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 3. Exceções.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Exceções são levantadas pelo sistema quando erros internos são encontrados ou
+% explicitamente em código pela chamada `throw(Exception)`, `exit(Exception)`
+% ou `erlang:error(Exception)`.
+generate_exception(1) -> a;
+generate_exception(2) -> throw(a);
+generate_exception(3) -> exit(a);
+generate_exception(4) -> {'EXIT', a};
+generate_exception(5) -> erlang:error(a).
+
+% Erlang tem dois métodos para capturar uma exceção. Uma é encapsular a chamada
+% para a função que levanta uma exceção dentro de uma expressão `try...catch`.
+catcher(N) ->
+ try generate_exception(N) of
+ Val -> {N, normal, Val}
+ catch
+ throw:X -> {N, caught, thrown, X};
+ exit:X -> {N, caught, exited, X};
+ error:X -> {N, caught, error, X}
+ end.
+
+% O outro é encapsular a chamada em uma expressão `catch`. Quando você captura
+% uma exceção, é convertida em uma tupla que descreve o erro.
+catcher(N) -> catch generate_exception(N).
+
+```
+
+## Referências
+
+* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
+* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang2/programming-erlang)
+* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
+* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)
+
diff --git a/pt-br/go-pt.html.markdown b/pt-br/go-pt.html.markdown
new file mode 100644
index 00000000..cca58b16
--- /dev/null
+++ b/pt-br/go-pt.html.markdown
@@ -0,0 +1,308 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo-pt.go
+lang: pt-br
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+translators:
+ - ["Nuno Antunes", "https://github.com/ntns"]
+---
+
+A linguagem Go foi criada a partir da necessidade de ver trabalho feito. Não
+é a última moda em ciências da computação, mas é a mais recente e mais rápida
+forma de resolver os problemas do mundo real.
+
+Tem conceitos familiares de linguagens imperativas com tipagem estática. É
+rápida a compilar e rápida a executar, acrescentando mecanismos de concorrência
+fáceis de entender para tirar partido dos CPUs multi-core de hoje em dia, e tem
+recursos para ajudar com a programação em larga escala.
+
+Go vem com uma biblioteca padrão exaustiva e uma comunidade entusiasta.
+
+```go
+// Comentário de uma linha
+/* Comentário de
+ várias linhas */
+
+// A cláusula package aparece no início de cada arquivo.
+// Main é um nome especial declarando um executável ao invés de uma biblioteca.
+package main
+
+// A cláusula Import declara os pacotes referenciados neste arquivo.
+import (
+ "fmt" // Um pacote da biblioteca padrão da linguagem Go
+ "net/http" // Sim, um servidor web!
+ "strconv" // Conversão de Strings
+)
+
+// Definição de uma função. Main é especial. É o ponto de entrada para o
+// programa executável. Goste-se ou não, a linguagem Go usa chavetas.
+func main() {
+ // A função Println envia uma linha para stdout.
+ // É necessário qualifica-la com o nome do pacote, fmt.
+ fmt.Println("Olá Mundo!")
+
+ // Chama outra função dentro deste pacote.
+ beyondHello()
+}
+
+// As funções declaram os seus parâmetros dentro de parênteses. Se a função
+// não receber quaisquer parâmetros, é obrigatório usar parênteses vazios.
+func beyondHello() {
+ var x int // Declaração de variável. Tem de ser declarada antes de usar.
+ x = 3 // Atribuição de variável.
+ // Declarações "curtas" usam := para inferir o tipo, declarar e atribuir.
+ y := 4
+ sum, prod := learnMultiple(x, y) // a função retorna dois valores
+ fmt.Println("soma:", sum, "produto:", prod)
+ learnTypes() // continuar a aprender!
+}
+
+// As funções podem receber parâmetros e retornar (vários!) valores.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // retorna dois valores
+}
+
+// Alguns tipos e literais básicos.
+func learnTypes() {
+ // Declarações "curtas" geralmente servem para o que pretendemos.
+ s := "Aprender Go!" // tipo string
+
+ s2 := `Uma string em "bruto"
+pode incluir quebras de linha.` // mesmo tipo string
+
+ // literal não-ASCII. A linguagem Go utiliza de raiz a codificação UTF-8.
+ g := 'Σ' // tipo rune, um alias para uint32, que contém um código unicode
+
+ f := 3.14195 // float64, número de vírgula flutuante de 64bit (IEEE-754)
+ c := 3 + 4i // complex128, representado internamente com dois float64s
+
+ // Declaração de variáveis, com inicialização.
+ var u uint = 7 // inteiro sem sinal, tamanho depende da implementação do Go
+ var pi float32 = 22. / 7
+
+ // Sintaxe de conversão de tipo, com declaração "curta".
+ n := byte('\n') // byte é um alias para uint8
+
+ // Os arrays têm tamanho fixo e definido antes da compilação.
+ var a4 [4]int // um array de 4 ints, inicializado com ZEROS
+ a3 := [...]int{3, 1, 5} // um array de 3 ints, inicializado como mostrado
+
+ // As slices têm tamanho dinâmico. Os arrays e as slices têm cada um as
+ // suas vantagens mas o uso de slices é muito mais comum.
+ s3 := []int{4, 5, 9} // compare com a3. sem reticências aqui
+ s4 := make([]int, 4) // aloca uma slice de 4 ints, inicializada com ZEROS
+ var d2 [][]float64 // declaração apenas, nada é alocado
+ bs := []byte("uma slice") // sintaxe de conversão de tipos
+
+ p, q := learnMemory() // learnMemory retorna dois apontadores para int.
+ fmt.Println(*p, *q) // * segue um apontador. isto imprime dois ints.
+
+ // Os maps são um tipo de matriz associativa, semelhante aos tipos hash
+ // ou dictionary que encontramos noutras linguagens.
+ m := map[string]int{"três": 3, "quatro": 4}
+ m["um"] = 1
+
+ // As variáveis não usadas são um erro em Go.
+ // O traço inferior permite "usar" uma variável, mas descarta o seu valor.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Enviar para o stdout conta como utilização de uma variável.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl()
+}
+
+// A linguagem Go é totalmente garbage collected. Tem apontadores mas não
+// permite que os apontadores sejam manipulados com aritmética. Pode-se cometer
+// um erro com um apontador nulo, mas não por incrementar um apontador.
+func learnMemory() (p, q *int) {
+ // A função retorna os valores p e q, que são do tipo apontador para int.
+ p = new(int) // a função new aloca memória, neste caso para um int.
+ // O int alocado é inicializado com o valor 0, p deixa de ser nil.
+ s := make([]int, 20) // alocar 20 ints como um único bloco de memória
+ s[3] = 7 // atribui o valor 7 a um deles
+ r := -2 // declarar outra variável local
+ return &s[3], &r // & obtém o endereço de uma variável.
+}
+
+func expensiveComputation() int {
+ return 1e6
+}
+
+func learnFlowControl() {
+ // As instruções if exigem o uso de chavetas, e não requerem parênteses.
+ if true {
+ fmt.Println("eu avisei-te")
+ }
+ // A formatação do código-fonte é "estandardizada" através do comando
+ // da linha de comandos "go fmt."
+ if false {
+ // reclamar
+ } else {
+ // exultar
+ }
+ // Preferir o uso de switch em vez de ifs em cadeia.
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // os cases não fazem "fall through"
+ case 2:
+ // esta linha só é executada se e só se x=2
+ }
+ // Tal como a instrução if, a instrução for não usa parênteses.
+ for x := 0; x < 3; x++ { // x++ é uma instrução, nunca uma expressão
+ fmt.Println("iteração", x)
+ }
+ // note que, x == 1 aqui.
+
+ // A instrução for é a única para ciclos, mas assume várias formas.
+ for { // ciclo infinito
+ break // brincadeirinha
+ continue // nunca executado
+ }
+ // O uso de := numa instrução if permite criar uma variável local,
+ // que existirá apenas dentro do bloco if.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // As funções podem ser closures.
+ xBig := func() bool {
+ return x > 100 // referencia x, declarado acima da instrução switch.
+ }
+ fmt.Println("xBig:", xBig()) // true (1e6 é o último valor de x)
+ x /= 1e5 // agora temos x == 10
+ fmt.Println("xBig:", xBig()) // false
+
+ // Quando for mesmo necessário, pode usar o velho goto.
+ goto love
+love:
+
+ learnInterfaces() // Mais coisas interessantes chegando!
+}
+
+// Define Stringer como uma interface consistindo de um método, String.
+type Stringer interface {
+ String() string
+}
+
+// Define pair como uma struct com dois campos ints chamados x e y.
+type pair struct {
+ x, y int
+}
+
+// Define um método para o tipo pair. O tipo pair implementa agora a
+// interface Stringer.
+func (p pair) String() string { // p é chamado de "receptor"
+ // Sprintf é outra função pública no pacote fmt.
+ // Uso de pontos para referenciar os campos de p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Uma struct pode ser inicializada com os valores dos seus campos dentro
+ // de chavetas, seguindo a mesma ordem com que os campos foram definidos.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // chama o método String de p, que tem tipo pair.
+ var i Stringer // declara i do tipo interface Stringer.
+ i = p // válido, porque pair implementa Stringer
+ // Chama o método String de i, que tem tipo Stringer. Mesmo que acima.
+ fmt.Println(i.String())
+
+ // As funções no pacote fmt chamam o método String para pedir a um objecto
+ // uma representação textual de si mesmo.
+ fmt.Println(p) // mesmo que acima. Println chama o método String.
+ fmt.Println(i) // mesmo que acima.
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" forma idiomática usada para saber se algo funcionou ou não.
+ m := map[int]string{3: "três", 4: "quatro"}
+ if x, ok := m[1]; !ok { // ok vai ser false porque 1 não está no map m.
+ fmt.Println("ninguem lá")
+ } else {
+ fmt.Print(x) // x seria o valor, se 1 estivesse no map.
+ }
+ // Um valor de erro comunica mais informação sobre o problema.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta o valor
+ // imprime "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // Vamos revisitar as interfaces um pouco mais tarde. Entretanto,
+ learnConcurrency()
+}
+
+// c é um channel, um objecto para comunicação concurrency-safe.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- é operador "enviar" quando um channel aparece à esquerda.
+}
+
+// Vamos usar a função inc para incrementar números de forma concorrente.
+func learnConcurrency() {
+ // A mesma função make usada anteriormente para alocar uma slice.
+ // Make aloca e inicializa slices, maps, e channels.
+ c := make(chan int)
+ // Inicia três goroutines concorrentes. Os números serão incrementados de
+ // forma concorrente, talvez em paralelo se a máquina for capaz e estiver
+ // configurada correctamente. As três goroutines enviam para o mesmo canal.
+ go inc(0, c) // go é a instrução para iniciar uma goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Lê três resultados do channel c e imprime os seus valores.
+ // Não se pode dizer em que ordem os resultados vão chegar!
+ fmt.Println(<-c, <-c, <-c) // channel na direita, <- é operador "receptor".
+
+ cs := make(chan string) // outro channel, este lida com strings.
+ cc := make(chan chan string) // channel que lida com channels de strings.
+ go func() { c <- 84 }() // inicia uma goroutine para enviar um valor
+ go func() { cs <- "palavroso" }() // outra vez, para o channel cs desta vez
+ // A instrução select tem uma sintaxe semelhante à instrução switch mas
+ // cada caso envolve uma operação com channels. Esta instrução seleciona,
+ // de forma aleatória, um caso que esteja pronto para comunicar.
+ select {
+ case i := <-c: // o valor recebido pode ser atribuído a uma variável
+ fmt.Printf("é um %T", i)
+ case <-cs: // ou o valor recebido pode ser descartado
+ fmt.Println("é uma string")
+ case <-cc: // channel vazio, não se encontra pronto para comunicar.
+ fmt.Println("não aconteceu")
+ }
+ // Neste ponto um valor foi recebido de um dos channels c ou cs. Uma das
+ // duas goroutines iniciadas acima completou, a outra continua bloqueada.
+
+ learnWebProgramming() // Go faz. Você quer faze-lo também.
+}
+
+// Basta apenas uma função do pacote http para iniciar um servidor web.
+func learnWebProgramming() {
+ // O primeiro parâmetro de ListenAndServe é o endereço TCP onde escutar.
+ // O segundo parâmetro é uma interface, especificamente http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // não ignorar erros
+}
+
+// Tornar pair um http.Handler ao implementar o seu único método, ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Servir dados com um método de http.ResponseWriter
+ w.Write([]byte("Aprendeu Go em Y minutos!"))
+}
+```
+
+## Leitura Recomendada
+
+A principal fonte de informação é o [web site oficial Go](http://golang.org/).
+Lá é possível seguir o tutorial, experimentar de forma iterativa, e ler muito.
+
+A própria especificação da linguagem é altamente recomendada. É fácil de ler e
+incrivelmente curta (em relação ao que é habitual hoje em dia).
+
+Na lista de leitura para os aprendizes de Go deve constar o [código fonte da
+biblioteca padrão](http://golang.org/src/pkg/). Exaustivamente documentado, é
+a melhor demonstração de código fácil de ler e de perceber, do estilo Go, e da
+sua escrita idiomática. Ou então clique no nome de uma função na [documentação]
+(http://golang.org/pkg/) e veja o código fonte aparecer!
+
diff --git a/pt-br/haskell-pt.html.markdown b/pt-br/haskell-pt.html.markdown
new file mode 100644
index 00000000..55f90bd6
--- /dev/null
+++ b/pt-br/haskell-pt.html.markdown
@@ -0,0 +1,620 @@
+---
+language: haskell
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
+translators:
+ - ["Lucas Tonussi", "http://www.inf.ufsc.br/~tonussi/"]
+lang: pt-br
+filename: learnhaskell-pt.hs
+---
+
+As linguagens funcionais são linguagens de programação com base em avaliação
+de funções matemáticas (expressões), evitando-se o conceito de mudança de
+estado com alteração de dados. Neste aspecto, este paradigma é oposto ao
+paradigma imperativo que se baseia em alterações de estados.
+
+A programação funcional começou no cálculo lambda, que foi base teórica para
+o desenvolvimento deste paradigma de programação.
+
+
+```haskell
+-- Para comentar a linha basta dois traços seguidos.
+
+{- Abre chaves traço e traço fecha chaves cria um campo
+ para comentário em múltiplas linhas.
+-}
+
+----------------------------------------------------
+-- 1. Tipos Primitivos de Dados e Operadores
+----------------------------------------------------
+
+-- Numerais
+
+0 -- 3
+1 -- 1
+2 -- 2 ...
+
+-- Alguns Operadores Fundamentais
+
+7 + 7 -- 7 mais 7
+7 - 7 -- 7 menos 7
+7 * 7 -- 7 vezes 7
+7 / 7 -- 7 dividido por 7
+
+-- Divisões não são inteiras, são fracionádas por padrão da linguagem
+28736 / 82374 -- 0.3488479374559934
+
+
+-- Divisão inteira
+82374 `div` 28736 -- 2
+
+-- Divisão modular
+82374 `mod` 28736 -- 24902
+
+-- Booleanos como tipo primitivo de dado
+True -- Verdadeiro
+False -- Falso
+
+-- Operadores unitário
+not True -- Nega uma verdade
+not False -- Nega uma falácia
+
+
+-- Operadores binários
+7 == 7 -- 7 é igual a 7 ?
+7 /= 7 -- 7 é diferente de 7 ?
+7 < 7 -- 7 é menor que 7 ?
+7 > 7 -- 7 é maior que 7 ?
+
+
+{- Haskell é uma linguagem que tem uma sintáxe bastante familiar na
+ matemática, por exemplo em chamadas de funções você tem:
+
+ NomeFunção ArgumentoA ArgumentoB ArgumentoC ...
+-}
+
+-- Strings e Caractéres
+"Texto entre abre áspas e fecha áspas define uma string"
+'a' -- Caractere
+'A' -- Caractere
+
+'Strings entre aspas simples sobe um erro' -- Erro léxico!
+
+-- Concatenação de Strings
+"StringA" ++ "StringB" -- "StringAStringB"
+
+-- Concatenação de Caracteres
+"haskell" == ['h','a','s','k','e','l','l'] -- True
+"haskell" == 'h':'a':'s':'k':'e':'l':'l':[] -- True
+
+-- Você pode listar uma string pelos seus caractéres
+"AbBbbcAbbcbBbcbcb" !! 0 -- 'A'
+"AbBbbcAbbcbBbcbcb" !! 1 -- 'b'
+"AbBbbcAbbcbBbcbcb" !! 2 -- 'B'
+
+----------------------------------------------------
+-- Listas e Túplas
+----------------------------------------------------
+
+-- A construção de uma lista precisa ser de elementos homogêneos
+[1, 2, 3, 4, 5] -- Homogênea
+[1, a, 2, b, 3] -- Heterogênea (Erro)
+
+-- Haskell permite que você crie sequências
+[1..5]
+
+{- Haskell usa avaliação preguiçosa o que
+ permite você ter listas "infinitas".
+-}
+
+-- Uma lista "infinita" cuja razão é 1
+[1..]
+
+-- O 777º elemento de uma lista de razão 1
+[1..] !! 777 -- 778
+
+-- União de listas [lista_0] ++ [lista_1] ++ [lista_i]
+[1..5] ++ [6..10] ++ [1..4] -- [1,2,3,4,5,6,7,8,9,10,1,2,3,4]
+
+-- Adiciona um cabeçalho a sua lista e desloca a cauda
+0:[1..10] -- [0, 1, 2, 3, 4, 5]
+'a':['a'..'e'] -- "aabcde"
+
+-- Indexação em uma lista
+[0..] !! 5 -- 5
+
+-- Operadores de Listas usuais
+head ['a'..'e'] -- Qual o cabeçalho da lista ?
+tail ['a'..'e'] -- Qual a cauda da lista ?
+init ['a'..'e'] -- Qual a lista menos o último elemento ?
+last ['a'..'e'] -- Qual o último elemento ?
+
+-- Compreensão de Lista (List Comprehension)
+
+{- Uma lista pode ser especificada
+ pela definição de eus elementos.
+ A compreensão de listas é feita
+ com um construtor de listas que
+ utiliza conceitos e notações
+ da teoria dos conjuntos.
+
+ Exemplo:
+
+ A = { x**2 | X pertence aos Naturais && x é par}
+-}
+
+let par x = mod x 2 == 0
+let constroi_lista = [x * x | x <- [9 ..39], par x]
+-- [100,144,196,256,324,400,484,576,676,784,900,1024,1156,1296,1444]
+
+par 4 -- True
+par 3 -- False
+
+
+-- Listas com regras
+{- Para todo x se x é elemento da lista
+ faça 2 vezes x mas componha a lista
+ com apenas aqueles elementos cujo
+ 2*x é maior que 4
+-}
+[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
+
+-- Tuplas
+("Q", "Gamma", "b", "Sigma", "delta", "q0", "F") -- 7-Tuple Turing Machine
+
+-- Retirando da tupla
+
+{- Com as funções fst (primeiro) e snd (segundo)
+ você só pode enviar por parâmetro uma tupla
+ bi-dimensional ou seja, 2 dimensões == (x,y)
+-}
+
+fst ((2,3), [2,3]) -- (2,3)
+snd ((2,3), [4,3]) -- [4,3]
+
+
+----------------------------------------------------
+-- 3. Funções em Haskell
+----------------------------------------------------
+
+-- Uma função simples que toma duas variáveis
+{- Haskell trabalha em cima de recursão
+ Portanto certifique-se que você
+ Entende como recurssão funciona.
+-}
+
+soma a b = a + b -- Função que vai em um programa.hs
+
+{- Dentro do GHCi (Interpretador Haskell)
+ Você terá que fazer da seguinte maneira-- Podemos criar nos
+
+ Prelude> let soma a b = a + b
+ Prelude> soma 7 7 -- 14
+-}
+
+let constroi_lista = [x * x | x <- [9 ..39], par x]
+
+{- Você pode usar crases para chamar
+ Funcões de maneira diferente
+-}
+
+7 `soma` 7 -- 14
+
+{- Haskell permite que você crie os
+ seus próprios operadores baseados
+ nos já existendes
+-}
+
+let (~/\) a b = a `mod` b
+15^13 ~/\ 432 -- 759375
+
+-- Casamento de Padrões em Tuplas
+coordenadas (x, y) = (x + 13, y - 31)
+
+{- Haskell trabalha com casamento de padrões onde dada
+ um conjunto de funções definidas de diferentes maneiras
+ Haskell vai procurar por aquela que trabalha o seu tipo
+ de entrada.
+-}
+
+-- Guardas "|" É um jeito simples de representar funções recursivas
+
+let fatorial n | n == 0 = 1 | otherwise = fatorial (n - 1) * n -- Teste: fatorial 5
+
+-- Ainda podemos fazer:
+
+let fatorial 0 = 1
+let fatorial n = fatorial (n - 1) * n
+
+{- Podemos criar nossos próprios Mapeadores
+ Onde `primeiro` é o primeiro elemento de
+ uma lista é `resto` é o resto da lista.
+-}
+
+mapa mapeador _ [] = []
+mapa mapeador (primeiro : resto) = mapeador primeiro : (mapa mapeador resto)
+
+{- Uma função anônima é uma função sem um nome.
+ É uma abstração do cálculo lambda:
+
+ \x -> x + 1
+ λ.x (x + 1)
+
+ Em Haskell Barra Invertida é um jeito para
+ se escrever Lambda (λ). Uma ótima pedida
+ Para entender Haskell e outras linguagens como Lisp
+ É estudar Cálculo Lambda, é um entendimento matemático
+ mais apurado. E do ponto de vista computacional é
+ bastante interessante. Em EXTRAS você encontrará
+ Links para aprender Cálculo Lambda.
+-}
+
+(\x -> x + 1) 4 -- 5
+
+
+{- Algumas vezes é mais conveniente usar expressões lambda
+ do que definir um nome para uma função. Na matemática
+ Nomes são muito simbólicos. Isso acontece bastante
+ quando você estiver trabalhando `map` ou `foldl` / `foldr`
+-}
+
+-- Sem usar expressões anônimas !
+listaSomaUm lst = map somaUm' lst where somaUm' x = x + 1
+
+-- Usando expressões anônimas !
+listaSomaUm' lst = map (\x -> x + 1) lst
+
+----------------------------------------------------
+-- 4. Mais Funções
+----------------------------------------------------
+
+{- Currying: Se você não passar todos os argumentos
+ para uma função, ela irá ser "currificada". O que
+ significa que irá retornar a função que pega o resto
+ dos elementos.
+-}
+
+soma a b = a + b
+foo = soma 10 -- foo ganha a propriedade "currying"
+foo 5 -- 15
+
+-- Outra maneira
+foo = (+10)
+foo 5 -- 15
+
+{- Composição de Funções
+ O (.) encadeia funções! Por exemplo,
+ aqui foo é uma função que recebe um valor.
+ Ela soma 10 a ela, multiplica o resultado por 5
+ e então retorna o resultado final.
+-}
+foo = (*5) . (+10)
+
+-- (5 + 10) * 5 = 75
+foo 5 -- 75
+
+{- Concertando precedência:
+ Haskell tem outra função chamada `$`. Isso altera a precedência
+ de computação. Ou seja Haskell computa o que está sendo sinalizado com $
+ da esquerda para a direita . Você pode usar `.` e `$` para se livrar
+ de parentízação desnecessária.
+-}
+
+(even (fatorial 3)) -- true
+
+-- Usando `.` e `$`
+even . fatorial $ 3 -- true
+
+----------------------------------------------------
+-- 5. Tipos
+----------------------------------------------------
+
+-- Haskell é fortemente tipado e tudo tem uma assinatura típica.
+
+-- Tipos Básicos:
+460 :: Integer
+"music" :: String
+True :: Bool
+
+{- Funções também tem tipos.
+ `not` recebe um booleano e retorna um booleano:
+ not :: Bool -> Bool
+-}
+
+{- Aqui temos uma função que recebe dois argumentos
+ soma :: Integer -> Integer -> Integer
+-}
+
+{- Quando você define um valor em Haskell
+ uma boa prática de programação é escrever
+ o TIPO acima dessa mesma. Como segue:
+-}
+
+double :: Integer -> Integer
+double x = x * 2
+
+----------------------------------------------------
+-- 6. Controle de Fluxo e IF-THEN-ELSE
+----------------------------------------------------
+
+-- Blocos IF-THEN-ELSE
+let valor_alternado = if 144 `mod` 6 == 4 then "acertou" else "errou" -- errou
+
+-- É legal identar quando você tem múltiplos branchs para acontecer
+
+let valor_alternado = if 144 `mod` 6 == 4
+ then "acertou"
+ else "errou"
+
+-- Blocos CASE
+
+{- caso <argumento> seja :
+ <ajuda> -> mostra_ajuda
+ <inicia> -> inicia_programa
+ <_> -> putStrLn "ExArgumentoInvalido"
+
+ Onde `_` Significa Qualquer Outra Coisa.
+-}
+
+
+case args of
+ "ajuda" -> mostra_ajuda
+ "inicia" -> inicia_programa
+ _ -> putStrLn "ExArgumentoInvalido"
+
+{- Haskell não funciona na base de loops pois ele é
+ fortemente baseado em funcões recursivas e cálculo lambda
+
+ Use `map` uma função build-in do interpretador
+ para, por exemplo, mapear uma lista:
+-}
+map (*2) [1..5] -- [2, 4, 6, 8, 10]
+
+-- Você pode criar um FOR-LOOP usando map
+let for array funcao = map funcao array
+for [0..5] $ \i -> show i
+
+-- Ou ainda (Pesquise sobre show em Haskell):
+for [0..5] show
+
+
+{- foldl computação é feita esquerda para direita
+ foldr computação é feita direita para esquerda
+
+ Você pode usar foldl or foldr a fim de reduzir uma lista
+ fold(l||r) <funcao> <valor inicial> <lista>
+-}
+
+-- Fold Left
+foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
+
+-- Pensando Recursivamente Esquerda-Direita
+(2 * (2 * (2 * 4 + 1) + 2) + 3) -- 43
+
+-- Fold Right
+foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
+
+-- Pensando Recursivamente Direita-Esquerda
+(2 * 3 + (2 * 2 + (2 * 1 + 4)))
+
+----------------------------------------------------
+-- 7. Declaração de Dados
+----------------------------------------------------
+
+{- Vamos começar definindo um tipo de
+ dado que é uma cor rgb então ela
+ tem valores para vermelho azul e verde
+ ela é composta desses 3 comprimentos
+ Vamos usar `data` e `say` que são built-in:
+
+ Haskell pede que você user letra
+ maiuscula para tipos (types) ou classes (Class)
+
+ Por favor, visite: http://www.haskell.org/haskellwiki/Type
+ E de uma olhada na fórmula genérica de declaração de dados.
+-}
+
+data Cor = Vermelho | Azul | Verde
+
+-- say :: Color -> String
+
+let say Vermelho = "Vermelho"
+let say Azul = "Azul"
+let say Verde = "Verde"
+
+{- O seu tipo de dados por receber parâmetros também
+ vamos com um exemplo usando `data` e a Classe `Maybe`.
+-}
+
+data Maybe a = Nothing | Just a
+
+-- Just e Nothing são todos derivadas de Maybe
+Just "hello" -- tipo `Maybe String`
+Just 1 -- tipo `Maybe Int`
+Nothing -- tipo `Maybe a` para algum `a`
+
+
+----------------------------------------------------
+-- 8. Mônadas
+----------------------------------------------------
+
+{- As mônadas permitem que o programador construa computações
+ sando os blocos de comando sequenciais, os quais, por sua vez,
+ podem ter outras sequencias de computações. Para entender melhor
+ a classe Monads você precisa ler um pouco mais sobre Classes em
+ Haskell e o polímofirmo ad hoc do Haskell.
+
+ A Classe Mônada padrão em Haskell é a seguinte:
+-}
+
+class Monad m where
+ (>>=) :: m a -> (a -> m b) -> m b
+ (>>) :: m a -> m b -> m b
+ return :: m -> m a
+ fail :: String -> m a
+
+ -- Definição completa mínima:
+ -- (>>=), return
+
+ m >> k = m >>= \_ -> k
+ fail s = error s
+
+{- Como exemplo, a função le_imprime opera com a função ">=" da
+ classe mônada, a qual repassa o retorno obtido com a função
+ getLine para uma função lambda \e qualquer.
+
+ GHC-BASICS
+ Cria um arquivo chamado le_imprime.hs
+ compile: ghc --make -c -O Programa_Haskell_Principal.hs
+ execute: ./Programa_Haskell_Principal
+-}
+
+le_imprime :: IO ()
+le_imprime = getLine >>= \e -> putStrLn e -- le_imprime = getLine >>= putStrLn
+
+{- Mônadas abrem a possibilidade de criar computações
+ no estilo imperativo dentro de um grande programa funcional
+
+ Leis das Mônadas:
+
+ 1. return a >>= k = k a
+ 2. m >>= return = m
+ 3. m >>= (\x -> k x >>= h) = (m >>= k) >>= h
+-}
+
+-- O operador >> é chamada então (p -> q, p então q)
+let m >> n = m >>= \_ -> n
+
+
+----------------------------------------------------
+-- 9. Haskell Entrada/Saída
+----------------------------------------------------
+
+{- Quando um programa Haskell é executado a função `main` é
+ chamada. E ela precisa retornar um valor do tipo IO().
+-}
+
+module Main where
+ main :: IO ()
+ main = putStrLn $ "Oi Glasgow!"
+
+-- Ou simplesmente:
+
+main = putStrLn $ "Oi Glasgow!"
+
+{- putStrLn é do tipo String -> IO()
+
+ É o jeito mais fácil de conseguir E/S se você implementar
+ o seu programa como uma função de String para String.
+
+ A função:
+ interact :: (String -> String) -> IO ()
+ Joga texto, roda a função nela mesma, e imprime a saída
+-}
+
+module Main where
+ contadorLinhas = show . length . lines
+ main = interact contadorLinhas
+
+-- Use a notação `do` para encadear ações. Por exemplo:
+
+diga_oi :: IO ()
+
+diga_oi = do
+
+ putStrLn "Qual eh o seu nome?"
+ name <- getLine
+ putStrLn $ "Oi, " ++ name
+
+main = diga_oi
+
+{- Exercício! Escreva sua própria versão
+ onde irá ler apenas uma linhas de input.
+
+ Vamos entender melhor como `getLine` funciona?
+ getLine :: IO String
+ Pense que o valor do tipo `IO a` representando um
+ programa de computador que irá gerar um valor do tipo `a`
+ quando for ele executado.
+
+ Nós podemos guardar e reusar isso apenas apontando `<-`.
+ Nós podemos também cria nossas próprias ações do tipo `IO String`
+-}
+
+nova_acao :: IO String
+
+nova_acao = do
+ putStrLn "Uma string curta o bastante."
+ entra1 <- getLine
+ entra2 <- getLine
+ -- return :: String -> IO String
+ return (entra1 ++ "\n" ++ entra2)
+
+{- Nós podemos usar da seguinte maneira
+ como acabamos de usar `getLine`, exemplo:
+-}
+
+main'' = do
+ putStrLn "String A"
+ result <- action
+ putStrLn result
+ putStrLn "String B"
+
+----------------------------------------------------
+-- 9. O Haskell REPL (Read Eval Print Loop)
+----------------------------------------------------
+
+{- Digite dhci no seu terminal
+ para começar o interpretador
+ lembre-se que para definir
+ funções e variáveis em haskell
+ pelo interpretador você precisar
+ iniciar com `let`
+-}
+
+Prelude> let foo = 1.4
+
+-- Você pode ver o tipo de algo usando `:t`:
+
+Prelude> :t foo
+foo :: Double
+```
+
+
+# Extra
+
+Compilador e Interpretador Haskell
+
+* [GHC](http://www.haskell.org/ghc/docs/latest/html/users_guide/index.html)
+* [GHC/GHCi](http://www.haskell.org/haskellwiki/GHC)
+* [Haskell em 5 Passos !!!](http://www.haskell.org/haskellwiki/Haskell_in_5_steps)
+
+Instale Haskell [Aqui!](http://www.haskell.org/platform/).
+
+Aplicações Haskell Muito Interessantes:
+
+* [Música e Som](http://www.haskell.org/haskellwiki/Applications_and_libraries/Music_and_sound)
+* [Haskell SuperCollider Servidor](https://github.com/kaoskorobase/hsc3-server)
+* [Haskell SuperCollider Cliente](http://hackage.haskell.org/package/hsc3)
+* [Física e Matemática](http://www.haskell.org/haskellwiki/Applications_and_libraries/Mathematics)
+* [Jogos](http://www.haskell.org/haskellwiki/Applications_and_libraries/Games)
+* [Bio Informática](http://www.haskell.org/haskellwiki/Applications_and_libraries/Bioinformatics)
+* [Muitos Outras Aplicações](http://www.haskell.org/haskellwiki/Libraries_and_tools)
+
+Comunidade Haskell
+* [Musica das Mônadas](http://www.haskell.org/haskellwiki/Music_of_monads)
+* [Entendendo Mônadas](https://en.wikibooks.org/wiki/Haskell/Understanding_monads)
+
+Tutoriais:
+
+* [Mapeadores](http://www.haskell.org/ghc/docs/6.12.2/html/libraries/containers-0.3.0.0/Data-Map.html)
+* [Aprenda Haskell!](http://haskell.tailorfontela.com.br/chapters)
+* [Fundação Teórica da Linguagem Haskell](http://www.haskell.org/haskellwiki/Lambda_calculus)
+* [Classe Maybe](http://www.haskell.org/haskellwiki/Maybe)
+* [Zvon Referência Haskell](http://www.zvon.org/other/haskell/)
+
+Obtenha Também Haskell Wiki Book [Aqui!](https://en.wikibooks.org/wiki/Haskell)
+
+Leia Sobre As Mônadas [Aqui!](http://www.haskell.org/haskellwiki/Monads)
+
+Livro: Haskell Uma Abordagem Prática - Claudio Cesar de Sá e Márcio Ferreira da Silva
diff --git a/pt-br/java-pt.html.markdown b/pt-br/java-pt.html.markdown
new file mode 100644
index 00000000..a884f273
--- /dev/null
+++ b/pt-br/java-pt.html.markdown
@@ -0,0 +1,435 @@
+---
+
+language: java
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
+translators:
+ - ["Victor Kléber Santos L. Melo", "http://victormelo.com.br/blog"]
+ - ["Renê Douglas N. de Morais", "mailto:rene.douglas.bsi@gmail.com"]
+lang: pt-br
+filename: LearnJava-pt.java
+
+---
+
+Java é uma linguagem de programação de propósito geral, concorrente, baseada em classes e orientada a objetos.
+[Leia mais aqui](http://docs.oracle.com/javase/tutorial/java/index.html)
+
+```java
+// Comentários de uma linha começam com //
+/*
+Comentários de várias linhas são feitos dessa forma.
+*/
+/**
+Comentários JavaDoc são feitos assim. São usados para descrever a Classe ou os atributos da Classe.
+*/
+
+// Importa a classe ArrayList que está dentro do pacote java.util
+import java.util.ArrayList;
+// Importa todas as classes que estão dentro do pacote java.security
+import java.security.*;
+
+// Cada arquivo .java contém uma classe pública, com o mesmo nome do arquivo.
+public class LearnJava {
+
+ // Um programa precisa ter um método main como um ponto de entrada.
+ public static void main (String[] args) {
+
+ // O System.out.println é usado para imprimir no console
+ System.out.println("Olá Mundo!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Para imprimir sem inserir uma nova lina, use o System.out.print
+ System.out.print("Olá ");
+ System.out.print("Mundo");
+
+
+ ///////////////////////////////////////
+ // Tipos & Variáveis
+ ///////////////////////////////////////
+
+ // Declara-se variáveis usando <tipo> <nome> [
+ // Byte - inteiro de 8 bits com sinal complementado a dois
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Short - inteiro de 16 bits com sinal complementado a dois
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - inteiro de 32 bits com sinal complementado a dois
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Long - inteiro de 64 bits com sinal complementado a dois
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L é usado para indicar que o valor da variável é do tipo Long;
+ // sem o L, tudo é tratado como inteiro por padrão.
+
+ // Nota: Java não tem tipos sem sinal
+
+ // Float - Ponto Flutuante 32-bits, de precisão simples no padrão IEEE 754
+ float fooFloat = 234.5f;
+ // f é usado para indicar que o valor da variável é do tipo float;
+ // caso contrário, ela é tratada como double.
+
+ // Double - Ponto Flutuante 64-bits, de precisão dupla no padrão IEEE 754
+ double fooDouble = 123.4;
+
+ // Boolean - true & false
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - Um caractere Unicode de 16 bits
+ char fooChar = 'A';
+
+ // Usa-se o final para fazer com que a variável seja imutável.
+ final int HORAS_QUE_TRABALHEI_POR_SEMANA = 9001;
+
+ // Strings
+ String fooString = "Aqui está minha String!";
+
+ // \n é um caractere de escape que inicia uma nova linha
+ String barString = "Imprimir em uma nova linha?\nSem problemas!";
+ // \t é um caractere de escape que adiciona um caractere de tabulação
+ String bazString = "Você quer adicionar tabulação?\tSem problemas!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Arrays
+ //O tamanho do array precisa ser determinado na sua declaração
+ //O formato para declarar um array é:
+ //<tipo de dado> [] <nome da variável> = new <tipo de dado>[<tamanho do array>];
+ int [] intArray = new int[10];
+ String [] stringArray = new String[1];
+ boolean [] booleanArray = new boolean[100];
+
+ // Outra maneira de declarar e inicializar um array
+ int [] y = {9000, 1000, 1337};
+
+ // Indexando um array - Acessando um elemento
+ System.out.println("intArray no índice 0: " + intArray[0]);
+
+ // O primeiro termo de um array é o 0 e eles são mutáveis.
+ intArray[1] = 1;
+ System.out.println("intArray no índice 1: " + intArray[1]); // => 1
+
+ // Outras estruturas que devem ser vistas
+ // ArrayLists - São parecidos com os arrays, porém oferecem mais funcionalidades
+ // e o tamanho é mutável.
+ // LinkedLists
+ // Maps
+ // HashMaps
+
+ ///////////////////////////////////////
+ // Operadores
+ ///////////////////////////////////////
+ System.out.println("\n->Operadores");
+
+ int i1 = 1, i2 = 2; // Forma abreviada de escrever múltiplas declarações.
+
+ // Aritmética é feita da forma convencional
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 arredondado para baixo)
+
+ // Módulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Operadores de comparação
+ System.out.println("3 == 2? " + (3 == 2)); // => false
+ System.out.println("3 != 2? " + (3 != 2)); // => true
+ System.out.println("3 > 2? " + (3 > 2)); // => true
+ System.out.println("3 < 2? " + (3 < 2)); // => false
+ System.out.println("2 <= 2? " + (2 <= 2)); // => true
+ System.out.println("2 >= 2? " + (2 >= 2)); // => true
+
+ // Operadores bit-a-bit!
+ /*
+ ~ Complemento de um
+ << Deslocamento a esquerda com sinal
+ >> Deslocamento a direita com sinal
+ >>> Deslocamento a direita sem sinal
+ & E bit-a-bit
+ | OU bit-a-bit
+ ^ OU exclusivo bit-a-bit
+ */
+
+ // Incrementações
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementação");
+ System.out.println(i++); //i = 1. Pós-Incrementação
+ System.out.println(++i); //i = 2. Pre-Incrementação
+ System.out.println(i--); //i = 1. Pós-Decrementação
+ System.out.println(--i); //i = 0. Pre-Decrementação
+
+ ///////////////////////////////////////
+ // Estruturas de Controle
+ ///////////////////////////////////////
+ System.out.println("\n->Estruturas de Controle");
+
+ // Os comandos If são parecidos com o da linguagem C
+ int j = 10;
+ if (j == 10){
+ System.out.println("Eu serei impresso");
+ } else if (j > 10) {
+ System.out.println("Eu não");
+ } else {
+ System.out.println("Eu também não");
+ }
+
+ // O Loop While
+ int fooWhile = 0;
+ while(fooWhile < 100)
+ {
+ //System.out.println(fooWhile);
+ //Incrementando o contador
+ //Iteração feita 99 vezes, fooWhile 0->99
+ fooWhile++;
+ }
+ System.out.println("Valor do fooWhile: " + fooWhile);
+
+ // O Loop Do While
+ int fooDoWhile = 0;
+ do
+ {
+ //System.out.println(fooDoWhile);
+ //Incrementando o contador
+ //Iteração feita 99 vezes, fooDoWhile 0->99
+ fooDoWhile++;
+ }while(fooDoWhile < 100);
+ System.out.println("Valor do fooDoWhile: " + fooDoWhile);
+
+ // O Loop For
+ int fooFor;
+ //estrutura do loop for => for(<operação_de_início>; <condição>; <passo>)
+ for(fooFor=0; fooFor<10; fooFor++){
+ //System.out.println(fooFor);
+ //Iteração feita 10 vezes, fooFor 0->9
+ }
+ System.out.println("Valor do fooFor: " + fooFor);
+
+ // O Loop For Each
+ // Itera automaticamente por um array ou lista de objetos.
+ int[] fooList = {1,2,3,4,5,6,7,8,9};
+ //estrutura do loop for each => for(<objeto> : <array_de_objeto>)
+ //lê-se: para cada objeto no array
+ //nota: o tipo do objeto deve ser o mesmo do array.
+
+ for( int bar : fooList ){
+ //System.out.println(bar);
+ //Itera 9 vezes e imprime 1-9 em novas linhas
+ }
+
+ // Switch
+ // Um switch funciona com os tipos de dados: byte, short, char e int
+ // Ele também funciona com tipos enumerados (vistos em tipos Enum)
+ // como também a classe String e algumas outras classes especiais
+ // tipos primitivos: Character, Byte, Short e Integer
+ int mes = 3;
+ String mesString;
+ switch (mes){
+ case 1:
+ mesString = "Janeiro";
+ break;
+ case 2:
+ mesString = "Fevereiro";
+ break;
+ case 3:
+ mesString = "Março";
+ break;
+ default:
+ mesString = "Algum outro mês";
+ break;
+ }
+ System.out.println("Resultado do Switch: " + mesString);
+
+ // Condição de forma abreviada.
+ // Você pode usar o operador '?' para atribuições rápidas ou decisões lógicas.
+ // Lê-se "Se (declaração) é verdadeira, use <primeiro valor>
+ // caso contrário, use <segundo valor>".
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println(bar); //Imprime A, pois a condição é verdadeira.
+
+
+ ///////////////////////////////////////
+ // Convertendo tipos de dados e Casting
+ ///////////////////////////////////////
+
+ //Conversão de Dados
+
+ //Convertendo String para Inteiro.
+ Integer.parseInt("123");//retorna uma versão inteira de "123".
+
+ //Convertendo Inteiro para String
+ Integer.toString(123);//retorna uma versão String de 123.
+
+ // Para outras conversões confira as seguintes classes
+ // Double
+ // Long
+ // String
+
+ // Casting
+ // Você pode também converter objetos java, há vários detalhes e
+ // lida com alguns conceitos intermediários
+ // Dê uma olhada no link:
+ // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+
+ ///////////////////////////////////////
+ // Classes e Métodos
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes e Métodos");
+
+ // (segue a definição da classe Bicicleta)
+
+ // Use o new para instanciar uma classe
+ Bicicleta caloi = new Bicicleta(); // Objeto caloi criado.
+
+ // Chame os métodos do objeto
+ caloi.aumentarVelocidade(3); // Você deve sempre usar métodos para modificar variáveis
+ caloi.setRitmo(100);
+
+ // toString é uma convenção para mostrar o valor deste objeto.
+ System.out.println("informações de caloi: " + caloi.toString());
+
+ } // Fim do método main
+} // Fim da classe LearnJava
+
+
+// Você pode incluir outras classes que não são públicas num arquivo .java
+
+
+// Sintaxe de declaração de Classe.
+// <public/private/protected> class <nome da classe>{
+// // atributos, construtores e todos os métodos.
+// // funções são chamadas de métodos em Java.
+// }
+
+class Bicicleta {
+
+ // Atributos/Variáveis da classe Bicicleta.
+ public int ritmo; // Public: Pode ser acessada em qualquer lugar.
+ private int velocidade; // Private: Apenas acessível a classe.
+ protected int catraca; // Protected: Acessível a classe e suas subclasses.
+ String nome; // default: Apenas acessível ao pacote.
+
+ // Construtores são uma forma de criação de classes
+ // Este é o construtor padrão.
+ public Bicicleta() {
+ catraca = 1;
+ ritmo = 50;
+ velocidade = 5;
+ nome = "Bontrager";
+ }
+
+ // Este é um construtor específico (ele contém argumentos).
+ public Bicicleta (int ritmoInicial, int velocidadeInicial, int catracaInicial, String nome) {
+ this.catraca = catracaInicial;
+ this.ritmo = ritmoInicial;
+ this.velocidade = velocidadeInicial;
+ this.nome = nome;
+ }
+
+ // Sintaxe de um método:
+ // <public/private/protected> <tipo de retorno> <nome do método>(<args>) //
+
+ // Classes em Java costumam implementar métodos getters e setters para seus campos.
+
+ // Sintaxe de declaração de métodos
+ // <escopo> <tipo de retorno> <nome do método>(<args>) //
+ public int getRitmo() {
+ return ritmo;
+ }
+
+ // Métodos do tipo void não requerem declaração de retorno.
+ public void setRitmo(int novoValor) {
+ ritmo = novoValor;
+ }
+
+ public void setEquipamento(int novoValor) {
+ catraca = novoValor;
+ }
+
+ public void aumentarVelocidade(int incremento) {
+ velocidade += incremento;
+ }
+
+ public void diminuirVelocidade(int decremento) {
+ velocidade -= decremento;
+ }
+
+ public void setNome(String novoNome) {
+ nome = novoNome;
+ }
+
+ public String getNome() {
+ return nome; // retorna um dado do tipo String.
+ }
+
+ //Método para mostrar os valores dos atributos deste objeto.
+ @Override
+ public String toString() {
+ return "catraca: " + catraca +
+ " ritmo: " + ritmo +
+ " velocidade: " + velocidade +
+ " nome: " + nome;
+ }
+} // fim classe Bicicleta
+
+// Velocipede é uma subclasse de bicicleta.
+class Velocipede extends Bicicleta {
+ // (Velocípedes são bicicletas com rodas dianteiras grandes
+ // Elas não possuem catraca.)
+
+ public Velocipede(int ritmoInicial, int velocidadeInicial){
+ // Chame o construtor do pai (construtor de Bicicleta) com o comando super.
+ super(ritmoInicial, velocidadeInicial, 0, "PennyFarthing");
+ }
+
+ // Você pode marcar um método que você está substituindo com uma @annotation
+ // Para aprender mais sobre o que são as annotations e sua finalidade
+ // dê uma olhada em: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setEquipamento(int catraca) {
+ catraca = 0;
+ }
+
+}
+
+```
+
+## Leitura Recomendada
+
+Os links fornecidos aqui abaixo são apenas para ter uma compreensão do tema, use o Google e encontre exemplos específicos.
+
+Outros tópicos para pesquisar:
+
+* [Tutorial Java para Sun Trail / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
+
+* [Modificadores de acesso do Java](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Coceitos de Programação Orientada à Objetos](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Herança](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polimorfismo](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstração](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Exceções](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Tipos Genéricos](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Conversões de código Java](http://www.oracle.com/technetwork/java/codeconv-138413.html)
+
+Livros:
+
+* [Use a cabeça, Java] (http://www.headfirstlabs.com/books/hfjava/)
diff --git a/pt-br/php-pt.html.markdown b/pt-br/php-pt.html.markdown
new file mode 100644
index 00000000..344df43a
--- /dev/null
+++ b/pt-br/php-pt.html.markdown
@@ -0,0 +1,700 @@
+---
+language: php
+contributors:
+ - ["Malcolm Fell", "http://emarref.net/"]
+ - ["Trismegiste", "https://github.com/Trismegiste"]
+translators:
+ - ["Abdala Cerqueira", "http://abda.la"]
+ - ["Raquel Diniz", "http://twitter.com/raquelrdiniz"]
+lang: pt-br
+filename: learnphp-pt.php
+---
+
+Este documento descreve PHP 5+.
+
+```php
+<?php // O código PHP deve estar incluso na tag <?php
+
+// Se o arquivo PHP só contém código PHP, a melhor prática
+// é omitir a tag de fechamento PHP.
+
+// Duas barras iniciam o comentário de uma linha.
+
+# O hash (aka pound symbol) também inicia, mas // é mais comum
+
+/*
+ O texto envolto por barra-asterisco e asterisco-barra
+ faz um comentário de múltiplas linhas
+*/
+
+// Utilize "echo" ou "print" para imprimir a saída
+print('Olá '); // Imprime "Olá " sem quebra de linha
+
+// () são opcionais para print e echo
+echo "Mundo\n"; // Imprime "Mundo" com quebra de linha
+// (Todas as declarações devem terminar com um ponto e vírgula)
+
+// Qualquer coisa fora da tag <?php é impresso automaticamente
+?>
+Olá mundo novamente!
+<?php
+
+
+/************************************
+ * Tipos e variáveis
+ */
+
+// Variáveis começam com o símbolo $.
+// Um nome de variável válido se inicia com uma letra ou sublinhado,
+// seguido por qualquer quantidade de letras, números ou sublinhados.
+
+// Valores booleanos não diferenciam maiúsculo de minúsculo (case-insensitive)
+$boolean = true; // ou TRUE ou True
+$boolean = false; // ou FALSE ou False
+
+// Inteiros
+$int1 = 12; // => 12
+$int2 = -12; // => -12
+$int3 = 012; // => 10 (um 0 denota um número octal)
+$int4 = 0x0F; // => 15 (um 0x denota um literal hex)
+
+// Flutuantes - Floats (aka doubles)
+$float = 1.234;
+$float = 1.2e3;
+$float = 7E-10;
+
+// Excluir variável
+unset($int1)
+
+// Aritmética
+$soma = 1 + 1; // 2
+$diferenca = 2 - 1; // 1
+$produto = 2 * 2; // 4
+$quociente = 2 / 1; // 2
+
+// Taquigrafia aritmética
+$numero = 0;
+$numero += 1; // Incrementa $number em 1
+echo $numero++; // Imprime 1 (incrementa após a avaliação)
+echo ++$numero; // Imprime 3 (incrementa antes da avaliação)
+$numero /= $float; // Divide e atribui o quociente de $numero
+
+// Strings podem ser colocadas entre aspas simples
+$sgl_quotes = '$String'; // => '$String'
+
+// Evite o uso de aspas duplas, exceto para incorporar outras variáveis
+$dbl_quotes = "Esta é uma $sgl_quotes."; // => 'Esta é uma $String.'
+
+// Os caracteres especiais só são escapados entre aspas duplas
+$escapado = "Este contém um \t caractere tab.";
+$naoescapado = 'Este contém somente a barra e o t: \t';
+
+// Coloque uma variável entre chaves se necessário
+$dinheiro = "Eu tenho $${numero} no banco.";
+
+// Desde o PHP 5.3, nowdocs podem ser usados para múltiplas linhas sem análise
+$nowdoc = <<<'FIM'
+múltiplas linhas
+string
+FIM;
+
+// Heredocs farão a análise
+$heredoc = <<<FIM
+múltiplas linhas
+$sgl_quotes
+FIM;
+
+// Concatenação de string é feita com .
+echo 'Esta string ' . 'é concatenada';
+
+
+/********************************
+ * Constantes
+ */
+
+// Uma constante é definida usando define()
+// e nunca pode ser mudada durante a execução!
+
+// Um nome de constante válida começa com uma letra ou sublinhado,
+// seguido por qualquer quantidade de letras, números ou sublinhados.
+define("FOO", "alguma coisa");
+
+// Acesso a uma constante é possível usando diretamente o nome escolhido
+echo 'Isto sairá '.FOO;
+
+
+/********************************
+ * Arrays
+ */
+
+// Todos os arrays em PHP são arrays associativos (hashmaps),
+
+// Funciona com todas as versões do PHP
+$associativo = array('Um' => 1, 'Dois' => 2, 'Tres' => 3);
+
+// PHP 5.4 introduziu uma nova sintaxe
+$associativo = ['Um' => 1, 'Dois' => 2, 'Tres' => 3];
+
+echo $associativo['Um']; // imprime 1
+
+// Uma lista de literais atribui chaves inteiras implicitamente
+$array = ['Um', 'Dois', 'Tres'];
+echo $array[0]; // => "Um"
+
+// Adiciona um elemento no final do array
+$array[] = 'Quatro';
+
+// Remove um elemento do array
+unset($array[3]);
+
+/********************************
+ * Saída
+ */
+
+echo('Olá Mundo!');
+// Imprime Olá Mundo! para stdout.
+// Stdout é uma página web se executado em um navegador.
+
+print('Olá Mundo!'); // O mesmo que o echo
+
+// echo é atualmente um construtor de linguagem, então você pode
+// remover os parênteses.
+echo 'Olá Mundo!';
+print 'Olá Mundo!'; // O print também é
+
+$paragrafo = 'parágrafo';
+
+echo 100; // Imprime valores escalares diretamente
+echo $paragrafo; // ou variáveis
+
+// Se a abertura de tags curtas está configurada, ou sua versão do PHP é
+// 5.4.0 ou maior, você pode usar a sintaxe de echo curto
+?>
+<p><?= $paragrafo ?></p>
+<?php
+
+$x = 1;
+$y = 2;
+$x = $y; // $x agora contém o mesmo valor de $y
+$z = &$y;
+// $z agora contém uma referência para $y. Mudando o valor de
+// $z irá mudar o valor de $y também, e vice-versa.
+// $x irá permanecer inalterado com o valor original de $y
+
+echo $x; // => 2
+echo $z; // => 2
+$y = 0;
+echo $x; // => 2
+echo $z; // => 0
+
+// Despeja tipos e valores de variável para o stdout
+var_dump($z); // imprime int(0)
+
+// Imprime variáveis para stdout em formato legível para humanos
+print_r($array); // imprime: Array ( [0] => Um [1] => Dois [2] => Tres )
+
+/********************************
+ * Lógica
+ */
+$a = 0;
+$b = '0';
+$c = '1';
+$d = '1';
+
+// assert lança um aviso se o seu argumento não é verdadeiro
+
+// Estas comparações serão sempre verdadeiras, mesmo que os tipos
+// não sejam os mesmos.
+assert($a == $b); // igualdade
+assert($c != $a); // desigualdade
+assert($c <> $a); // alternativa para desigualdade
+assert($a < $c);
+assert($c > $b);
+assert($a <= $b);
+assert($c >= $d);
+
+// A seguir, só serão verdadeiras se os valores correspondem e são do mesmo tipo.
+assert($c === $d);
+assert($a !== $d);
+assert(1 == '1');
+assert(1 !== '1');
+
+// As variáveis podem ser convertidas entre tipos, dependendo da sua utilização.
+
+$inteiro = 1;
+echo $inteiro + $inteiro; // => 2
+
+$string = '1';
+echo $string + $string; // => 2 (strings são coagidas para inteiros)
+
+$string = 'one';
+echo $string + $string; // => 0
+// Imprime 0 porque o operador + não pode fundir a string 'um' para um número
+
+// Tipo de fundição pode ser utilizado para tratar uma variável
+// como um outro tipo
+
+$booleano = (boolean) 1; // => true
+
+$zero = 0;
+$booleano = (boolean) $zero; // => false
+
+// Há também funções dedicadas para fundir a maioria dos tipos
+$inteiro = 5;
+$string = strval($inteiro);
+
+$var = null; // valor Null
+
+
+/********************************
+ * Estruturas de controle
+ */
+
+if (true) {
+ print 'Eu fico impresso';
+}
+
+if (false) {
+ print 'Eu não\'t';
+} else {
+ print 'Eu fico impresso';
+}
+
+if (false) {
+ print 'Não fica impresso';
+} elseif(true) {
+ print 'Fica';
+}
+
+// operadores ternários
+print (false ? 'Não fica impresso' : 'Fica');
+
+$x = 0;
+if ($x === '0') {
+ print 'Não imprime';
+} elseif($x == '1') {
+ print 'Não imprime';
+} else {
+ print 'Imprime';
+}
+
+
+
+// Esta sintaxe alternativa é útil para modelos (templates)
+?>
+
+<?php if ($x): ?>
+Isto é exibido se o teste for verdadeiro.
+<?php else: ?>
+Isto é apresentado caso contrário.
+<?php endif; ?>
+
+<?php
+
+// Use switch para salvar alguma lógica.
+switch ($x) {
+ case '0':
+ print 'Switch faz coerção de tipo';
+ break; // Você deve incluir uma pausa, ou você vai cair
+ // no caso 'dois' e 'tres'
+ case 'dois':
+ case 'tres':
+ // Faz alguma coisa, se a variável é 'dois' ou 'tres'
+ break;
+ default:
+ // Faz algo por padrão
+}
+
+// While, do...while e for são repetições provavelmente familiares
+$i = 0;
+while ($i < 5) {
+ echo $i++;
+}; // Imprime "01234"
+
+echo "\n";
+
+$i = 0;
+do {
+ echo $i++;
+} while ($i < 5); // Imprime "01234"
+
+echo "\n";
+
+for ($x = 0; $x < 10; $x++) {
+ echo $x;
+} // Imprime "0123456789"
+
+echo "\n";
+
+$rodas = ['bicicleta' => 2, 'carro' => 4];
+
+// Repetições foreach podem iterar sobre arrays
+foreach ($rodas as $contador_rodas) {
+ echo $contador_rodas;
+} // Imprime "24"
+
+echo "\n";
+
+// Você pode iterar sobre as chaves, bem como os valores
+foreach ($rodas as $veiculo => $contador_rodas) {
+ echo "O $veiculo tem $contador_rodas rodas";
+}
+
+echo "\n";
+
+$i = 0;
+while ($i < 5) {
+ if ($i === 3) {
+ break; // Sai da repetição
+ }
+ echo $i++;
+} // Imprime "012"
+
+for ($i = 0; $i < 5; $i++) {
+ if ($i === 3) {
+ continue; // Ignora esta iteração da repetição
+ }
+ echo $i;
+} // Imprime "0124"
+
+
+/********************************
+ * Functions
+ */
+
+// Define a função com "function":
+function minha_funcao () {
+ return 'Olá';
+}
+
+echo minha_funcao(); // => "Olá"
+
+// Um nome de função válido começa com uma letra ou sublinhado,
+// seguido por qualquer quantidade de letras, números ou sublinhados.
+
+function adicionar($x, $y = 1) { // $y é opcional e o valor padrão é 1
+ $resultado = $x + $y;
+ return $resultado;
+}
+
+echo adicionar(4); // => 5
+echo adicionar(4, 2); // => 6
+
+// $resultado não é acessível fora da função
+// print $resultado; // Dá uma aviso.
+
+// Desde o PHP 5.3 você pode declarar funções anônimas
+$inc = function ($x) {
+ return $x + 1;
+};
+
+echo $inc(2); // => 3
+
+function foo ($x, $y, $z) {
+ echo "$x - $y - $z";
+}
+
+// Funções podem retornar funções
+function bar ($x, $y) {
+ // Utilize 'use' para trazer variáveis de fora
+ return function ($z) use ($x, $y) {
+ foo($x, $y, $z);
+ };
+}
+
+$bar = bar('A', 'B');
+$bar('C'); // Imprime "A - B - C"
+
+// Você pode chamar funções nomeadas usando strings
+$nome_funcao = 'add';
+echo $nome_funcao(1, 2); // => 3
+// Útil para dinamicamente determinar qual função será executada.
+// Ou utilize call_user_func(callable $callback [, $parameter [, ... ]]);
+
+/********************************
+ * Includes (Incluir)
+ */
+
+<?php
+// PHP dentro de arquivos incluídos também deve começar com uma tag
+// de abertura do PHP.
+
+include 'meu-arquivo.php';
+// O código meu-arquivo.php já está disponível no escopo atual.
+// Se o arquivo não pode ser incluído (por exemplo, arquivo não encontrado),
+//um aviso é emitido.
+
+include_once 'meu-arquivo.php';
+// Se o código no meu-arquivo.php foi incluído em outro lugar, ele não vai
+// ser incluído novamente. Isso evita vários erros de declaração de classe
+
+require 'meu-arquivo.php';
+require_once 'meu-arquivo.php';
+// Faz o mesmo que o include(), exceto que o require() irá causar um erro fatal
+// se o arquivo não puder ser incluído
+
+// Conteúdo de meu-include.php:
+<?php
+
+return 'Qualquer coisa que você quiser.';
+// Fim do arquivo
+
+// Includes e requires também podem retornar um valor.
+$valor = include 'meu-include.php';
+
+// Arquivos são incluídos com base no caminho determinado ou,
+// se este não for passado, com base na diretiva de configuração include_path.
+// Se o arquivo não é encontrado no include_path, o include vai finalmente
+// verificar no próprio diretório do script chamado e no diretório
+// de trabalho atual antes de falhar.
+/* */
+
+/********************************
+ * Classes
+ */
+
+// As classes são definidas com a palavra-chave class
+
+class MinhaClasse
+{
+ const MINHA_CONST = 'valor'; // Uma constante
+
+ static $valorEstatico = 'estatico';
+
+ // Variáveis estáticas e sua visibilidade
+ public static $valorEstaticoPublico = 'estaticoPublico';
+ // Acessível somente dentro da classe
+ private static $valorEstaticoPrivado = 'estaticoPrivado';
+ // Acessível a partir da classe e subclasses
+ protected static $valorEstaticoProtegido = 'estaticoProtegido';
+
+ // Propriedades devem declarar a sua visibilidade
+ public $propriedade = 'publica';
+ public $propInstancia;
+ protected $prot = 'protegida'; // Acessível a partir da classe e subclasses
+ private $priv = 'privada'; // Acessível somente dentro da classe
+
+ // Criar um construtor com o __construct
+ public function __construct($propInstancia) {
+ // Acesse variável de instância utilizando $this
+ $this->propInstancia = $propInstancia;
+ }
+
+ // Métodos são declarados como funções dentro de uma classe
+ public function meuMetodo()
+ {
+ print 'MinhaClasse';
+ }
+
+ //palavra-chave final faz uma função não poder ser sobrescrita
+ final function voceNaoPodeMeSobrescrever()
+ {
+ }
+
+/*
+ * Declarando propriedades ou métodos de classe como estáticos faz deles
+ * acessíveis sem precisar instanciar a classe. A propriedade declarada
+ * como estática não pode ser acessada com um objeto
+ * instanciado da classe (embora métodos estáticos possam).
+*/
+
+ public static function meuMetodoEstatico()
+ {
+ print 'Eu sou estatico';
+ }
+}
+
+echo MinhaClasse::MINHA_CONST; // Imprime 'valor';
+echo MinhaClasse::$valorEstatico; // Imprime 'estatico';
+MinhaClasse::meuMetodoEstatico(); // Imprime 'Eu sou estatico';
+
+// Instantiate classes using new
+$minha_classe = new MinhaClasse('Uma propriedade de instância');
+// Os parênteses são opcionais, se não passar algum argumento.
+
+// Acesse membros da classe utilizando ->
+echo $minha_classe->propriedade; // => "publica"
+echo $minha_classe->instanceProp; // => "Uma propriedade de instância"
+$minha_classe->meuMetodo(); // => "MinhaClasse"
+
+
+// Estender classes usando "extends"
+class MinhaOutraClasse extends MinhaClasse
+{
+ function imprimePropriedadeProtegida()
+ {
+ echo $this->prot;
+ }
+
+ // Sobrescrever um método
+ function meuMetodo()
+ {
+ parent::meuMetodo();
+ print ' > MinhaOutraClasse';
+ }
+}
+
+$minha_outra_classe = new MinhaOutraClasse('Propriedade de instância');
+$minha_outra_classe->imprimePropriedadeProtegida(); // => Prints "protegida"
+$minha_outra_classe->myMethod(); // Prints "MinhaClasse > MinhaOutraClasse"
+
+final class VoceNaoPodeMeEstender
+{
+}
+
+// Você pode usar "métodos mágicos" para criar getters e setters
+class MinhaClasseMapa
+{
+ private $propriedade;
+
+ public function __get($chave)
+ {
+ return $this->$chave;
+ }
+
+ public function __set($chave, $valor)
+ {
+ $this->$chave = $valor;
+ }
+}
+
+$x = new MinhaClasseMapa();
+echo $x->propriedade; // Irá usar o método __get()
+$x->propriedade = 'Algo'; // Irá usar o método __set()
+
+// Classes podem ser abstratas (usando a palavra-chave abstract) ou
+// implementar interfaces (usando a palavra-chave implements).
+// Uma interface é declarada com a palavra-chave interface.
+
+interface InterfaceUm
+{
+ public function fazAlgo();
+}
+
+interface InterfaceDois
+{
+ public function fazOutraCoisa();
+}
+
+// interfaces podem ser estendidas
+interface InterfaceTres extends InterfaceDois
+{
+ public function fazOutroContrato();
+}
+
+abstract class MinhaClasseAbstrata implements InterfaceUm
+{
+ public $x = 'fazAlgo';
+}
+
+class MinhaClasseConcreta extends MinhaClasseAbstrata implements InterfaceDois
+{
+ public function fazAlgo()
+ {
+ echo $x;
+ }
+
+ public function fazOutraCoisa()
+ {
+ echo 'fazOutraCoisa';
+ }
+}
+
+
+// Classes podem implementar mais de uma interface
+class UmaOutraClasse implements InterfaceUm, InterfaceDois
+{
+ public function fazAlgo()
+ {
+ echo 'fazAlgo';
+ }
+
+ public function fazOutraCoisa()
+ {
+ echo 'fazOutraCoisa';
+ }
+}
+
+
+/********************************
+ * Traits (Traços)
+ */
+
+// Traits estão disponíveis a partir de PHP 5.4.0 e
+// são declarados usando "trait"
+
+trait MeuTraco
+{
+ public function meuMetodoDeTraco()
+ {
+ print 'Eu tenho MeuTraco';
+ }
+}
+
+class MinhaClasseTracada
+{
+ use MeuTraco;
+}
+
+$cls = new MinhaClasseTracada();
+$cls->meuMetodoDeTraco(); // Imprime "Eu tenho MeuTraco"
+
+
+/********************************
+ * Namespaces (Espaço nominal)
+ */
+
+// Esta seção é separada porque a declaração de espaços nominais
+// deve ser a primeira instrução em um arquivo. Vamos fingir, aqui não é o caso
+
+<?php
+
+// Por padrão, as classes existem no espaço nominal global e podem
+// ser explicitamente chamadas com uma barra invertida.
+
+$cls = new \MinhaClasse();
+
+
+
+// Definir o espaço nominal para o arquivo
+namespace Meu\Espaconominal;
+
+class MinhaClasse
+{
+}
+
+// (de outro arquivo)
+$cls = new Meu\Espaconominal\MinhaClasse;
+
+//Ou de dentro de outro espaço nominal.
+namespace Meu\Outro\Espaconominal;
+
+use My\Espaconominal\MinhaClasse;
+
+$cls = new MinhaClasse();
+
+//Ou você pode usar como apelido de espaço nominal;
+
+namespace Meu\Outro\Espaconominal;
+
+use Meu\Espaconominal as OutroEspaconominal;
+
+$cls = new OutroEspaconominal\MinhaClasse();
+
+*/
+
+```
+
+## Mais informações
+
+Visite a [documentação oficial do PHP](http://www.php.net/manual/)
+para referência e participação da comunidade.
+
+Se você estiver interessado em melhores práticas atualizadas, visite
+[PHP The Right Way](http://www.phptherightway.com/).
+
+Se você está vindo de uma linguagem com bom gerenciamento de pacotes, confira
+[Composer](http://getcomposer.org/).
+
+Para os padrões comuns, visite o Grupo de Interoperabilidade de Framework PHP
+[PSR standards](https://github.com/php-fig/fig-standards).
diff --git a/pt-br/python-pt.html.markdown b/pt-br/python-pt.html.markdown
index e08bb5a8..5afd46d0 100644
--- a/pt-br/python-pt.html.markdown
+++ b/pt-br/python-pt.html.markdown
@@ -4,7 +4,7 @@ contributors:
- ["Louie Dinh", "http://ldinh.ca"]
translators:
- ["Vilson Vieira", "http://automata.cc"]
-lang: pt-bf
+lang: pt-br
filename: learnpython-pt.py
---
diff --git a/pt-br/ruby-pt.html.markdown b/pt-br/ruby-pt.html.markdown
new file mode 100644
index 00000000..4a8a1b5c
--- /dev/null
+++ b/pt-br/ruby-pt.html.markdown
@@ -0,0 +1,387 @@
+---
+language: ruby
+lang: pt-br
+filename: learnruby-pt.rb
+contributors:
+ - ["Bruno Henrique - Garu", "http://garulab.com"]
+translators:
+ - ["Katyanna Moura", "https://twitter.com/amelie_kn"]
+---
+
+```ruby
+# Isso é um comentário
+
+=begin
+Isso é um comentário multilinha
+Ninguém os usa
+Você não deve usar também
+=end
+
+# Primeiro e principal: Tudo é um objeto.
+
+# Números são objetos
+
+3.class #=> Fixnum
+
+3.to_s #=> "3"
+
+
+# Um pouco de aritmética básica
+
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Aritimética é apenas açúcar sintático
+# para chamar um método de um objeto
+1.+(3) #=> 4
+10.* 5 #=> 50
+
+# Valores especiais são objetos
+nil # Nada para ver aqui
+true # verdadeiro
+false # falso
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Igualdade
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Desigualdade
+1 != 1 #=> false
+2 != 1 #=> true
+!true #=> false
+!false #=> true
+
+# além de 'false', 'nil' é o único outro valor falso
+
+!nil #=> true
+!false #=> true
+!0 #=> false
+
+# Mais comparações
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Strings são objects
+
+'Eu sou uma string'.class #=> String
+"Eu também sou uma string".class #=> String
+
+placeholder = "usar interpolação de string"
+"Eu posso #{placeholder} quando estiver usando aspas duplas"
+#=> "Eu posso usar insterpolação de string quando estiver usando aspas duplas"
+
+# imprime para output (saída)
+puts "Estou imprimindo"
+
+# Variáveis
+x = 25 #=> 25
+x #=> 25
+
+# Note que uma atribuição retorna o valor atribuido
+# Isso significa que você pode fazer múltiplas atribuições:
+
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# Por convenção, use snake_case para nomes de variáveis
+snake_case = true
+
+# Use nomes de variáveis descritivos
+caminho_para_a_raiz_do_projeto = '/bom/nome/'
+caminho = '/nome/ruim/'
+
+# Símbolos (são objetos)
+# Símbolos são imutáveis, são constantes reutilizáveis representadadas
+# internamente por um valor inteiro. Eles são frequentemente usados no
+# lugar de strings para transmitir com eficiência os valores específicos
+# e significativos
+
+:pendente.class #=> Symbol
+
+status = :pendente
+
+status == :pendente #=> true
+
+status == 'pendente' #=> false
+
+status == :aprovado #=> false
+
+# Arrays
+
+# Isso é um array
+[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# Arrays podem conter diferentes tipos de itens
+
+array = [1, "Oi", false] #=> => [1, "Oi", false]
+
+# Arrays podem ser indexados
+# a partir do começo
+array[0] #=> 1
+array[12] #=> nil
+
+# Como aritimética, o acesso via [var]
+# é apenas açúcar sintático
+# para chamar o método [] de um objeto
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# a partir do final
+array[-1] #=> 5
+
+# Com um índice de começo e fim
+array[2, 4] #=> [3, 4, 5]
+
+# Ou com um intervalo de valores
+array[1..3] #=> [2, 3, 4]
+
+# Adicionar a um array como este
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Hashes são o principal dicionário de Ruby com pares de chaves(keys)/valor(value).
+# Hashes são simbolizados com chaves "{}"
+hash = {'cor' => 'verde', 'numero' => 5}
+
+hash.keys #=> ['cor', 'numero']
+
+# Hashes podem ser rapidamente pesquisados pela chave (key)
+hash['cor'] #=> 'verde'
+hash['numero'] #=> 5
+
+# Procurar em um hash por uma chave que não existe retorna nil:
+hash['nada aqui'] #=> nil
+
+# Interar sobre hashes com o método #each:
+hash.each do |k, v|
+ puts "#{k} is #{v}"
+end
+
+hash.each do |k, v|
+ puts "#{k} é #{v}"
+end
+
+# Desde o Ruby 1.9, temos uma sintaxe especial quando usamos símbolos como chaves (keys)
+
+novo_hash = { defcon: 3, acao: true}
+
+novo_hash.keys #=> [:defcon, :acao]
+
+# Dica: Tanto Arrays quanto Hashes são Enumerable.
+# Eles compartilham um monte de métodos úteis como each, map, count e mais
+
+# Estruturas de controle
+
+if true
+ "Se verdadeiro"
+elsif false
+ "else if, opicional"
+else
+ "else, também é opicional"
+end
+
+for contador in 1..5
+ puts "interação #{contador}"
+end
+#=> contador 1
+#=> contador 2
+#=> contador 3
+#=> contador 4
+#=> contador 5
+
+# PORÉM
+# Ninguém usa para loops
+# Use "each" em vez, dessa forma:
+
+(1..5).each do |contador|
+ puts "interação #{contador}"
+end
+#=> contador 1
+#=> contador 2
+#=> contador 3
+#=> contador 4
+#=> contador 5
+
+contador = 1
+while contador <= 5 do
+ puts "interação #{contador}"
+ contador += 1
+end
+#=> contador 1
+#=> contador 2
+#=> contador 3
+#=> contador 4
+#=> contador 5
+
+grau = 'B'
+
+case grau
+when 'A'
+ puts "Um longo caminho a percorrer, pequeno gafanhoto"
+when 'B'
+ puts "Melhor sorte da próxima vez"
+when 'C'
+ puts "Você pode fazer melhor"
+when 'D'
+ puts "Scraping through"
+when 'F'
+ puts "Você falhou"
+else
+ puts "Alternative grading system, eh?"
+end
+
+# Funções
+
+def dobrar(x)
+ x * 2
+end
+
+# Funções (e todos os blocos) retornam implicitamente o valor da última linha
+dobrar(2) #=> 4
+
+# Parênteses são opicionais onde o resultado é claro
+dobrar 3 #=> 6
+
+dobrar dobrar 3 #=> 12
+
+def somar(x,y)
+ x + y
+end
+
+# Argumentos de métodos são separados por uma vírgula
+somar 3, 4 #=> 7
+
+somar somar(3,4), 5 #=> 12
+
+# yield
+# Todos os métodos possuem implicitamente um paramêntro opcional que é um bloco
+# ele pode ser chamado com a palavra chave 'yield'
+
+def ao_redor
+ puts "{"
+ yield
+ puts "}"
+end
+
+ao_redor { puts 'Olá mundo' }
+
+# {
+# Olá mundo
+# }
+
+
+# Define uma classe com a palavra chave 'class'
+
+class Humano
+
+ # Uma variável de classe. Ela é compartilhada por todas as instâncias dessa classe
+ @@especies = "H. sapiens"
+
+ # Inicialização básica (contructor)
+ def initialize(nome, idade=0)
+ # Atribui o argumento para a variável de instancia "nome" do objeto
+ @nome = nome
+ # Se a idade não for passada, nós definimos um valor padrão na lista de argumentos
+ @idade = idade
+ end
+
+ # Método básico para atribuir valor
+ def nome=(nome)
+ @nome = nome
+ end
+
+ # Método básico de resgatar valor
+ def nome
+ @nome
+ end
+
+ # Um método de classe usa a palavra chave self para se defenciar dos métodos de instância.
+ # Ele só pode ser chamado na classe, não na instancia
+ def self.diz(msg)
+ puts "#{msg}"
+ end
+
+ def especies
+ @@especies
+ end
+
+end
+
+
+# Instanciando uma classe
+jim = Humano.new("Jim Halpert")
+
+dwight = Humano.new("Dwight K. Schrute")
+
+# Vamos chamar um par de métodos
+jim.especies #=> "H. sapiens"
+
+jim.nome #=> "Jim Halpert"
+
+jim.nome = "Jim Halpert II" #=> "Jim Halpert II"
+
+jim.nome #=> "Jim Halpert II"
+
+dwight.especies #=> "H. sapiens"
+
+dwight.nome #=> "Dwight K. Schrute"
+
+# Chamar o método de classe
+Humano.diz("Oi") #=> "Oi"
+
+# Uma classe também é objeto em Ruby. Então uma classe pode possuir variável de instância
+# Variáveis de classe são compartilhadas entre a classe e todos os seus descendentes.
+
+
+# Classe base
+class Humano
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# classe filha
+class Trabalhador < Humano
+end
+
+Humano.foo # 0
+Trabalhador.foo # 0
+
+Humano.foo = 2 # 2
+Trabalhador.foo # 2
+
+# Uma variável de instância não é compartilhada por suas classes decendentes.
+
+class Humano
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(value)
+ @bar = value
+ end
+end
+
+class Doutor < Humano
+end
+
+Humano.bar # 0
+Doutor.bar # nil
+
+```
diff --git a/pt-br/visualbasic-pt.html.markdown b/pt-br/visualbasic-pt.html.markdown
new file mode 100644
index 00000000..76cca567
--- /dev/null
+++ b/pt-br/visualbasic-pt.html.markdown
@@ -0,0 +1,285 @@
+---
+language: Visual Basic
+contributors:
+ - ["Brian Martin", "http://brianmartin.biz"]
+translators:
+ - ["AdrianoJP", "https://github.com/AdrianoJP"]
+lang: pt-br
+filename: learnvisualbasic-pt.vb
+---
+
+```vb
+Module Module1
+
+module Module1
+
+ Sub Main ()
+ ' Uma visão geral de console de aplicativos do Visual Basic antes de
+ ' mergulharmos mais profundamente na linguagem
+ ' Aspas simples começam comentários.
+ ' Para Navegar este tutorial dentro do compilador do Visual Basic,
+ ' eu criei um sistema de navegação.
+ ' Este sistema de navegação vai ser explicado conforme avançarmos no
+ ' tutorial, e você vai entender o que isso significa.
+ Console.Title = (" Saiba X em Y Minutes" )
+ Console.WriteLine ( "NAVEGAÇÃO" ) 'Mostrar
+ Console.ForegroundColor = ConsoleColor.Green
+ Console.WriteLine ("1. Saída Olá Mundo" )
+ Console.WriteLine ("2. Entrada Olá Mundo" )
+ Console.WriteLine ("3. Cálculando números inteiros " )
+ Console.WriteLine ("4. Calculando números decimais " )
+ Console.WriteLine ("5 . Calculadora de Trabalho " )
+ Console.WriteLine ("6. Usando Do While Loops " )
+ Console.WriteLine ("7. Usando Para While Loops " )
+ Console.WriteLine ("8 . Declarações condicionais " )
+ Console.WriteLine ("9. Selecione uma bebida" )
+ Console.WriteLine ("50 . About" )
+ Console.WriteLine ("Por favor, escolha um número da lista acima " )
+ Seleção Dim As String = Console.ReadLine
+ Select A seleção dos casos
+ Caso "1" 'Output HelloWorld
+ Console.clear () ' Limpa a aplicação e abre o sub privado
+ HelloWorldOutput () ' Nome Private Sub, Abre Private Sub
+ Caso "2" 'Olá entrada
+ Console.clear ( )
+ HelloWorldInput ( )
+ Caso de "3" 'Calculando Números Inteiros
+ Console.clear ( )
+ CalculatingWholeNumbers ( )
+ Caso "4" ' Números decimais Calculting
+ Console.clear ( )
+ CalculatingDecimalNumbers ( )
+ Caso "5" ' Calcculator Trabalho
+ Console.clear ( )
+ WorkingCalculator ( )
+ Caso "6" 'Usando Do While Loops
+ Console.clear ( )
+ UsingDoWhileLoops ( )
+ Caso de "7" 'Usando pois enquanto Loops
+ Console.clear ( )
+ UsingForLoops ( )
+ Caso "8" ' Instruções condicionais
+ Console.clear ( )
+ ConditionalStatement ( )
+ Caso "9" "Declaração If / Else
+ Console.clear ( )
+ IfElseStatement () ' Selecione uma bebida
+ Caso "50" 'Quem caixa de msg
+ Console.clear ( )
+ Console.Title = (" Saiba X em Y Minutos :: Quem " )
+ MsgBox (" Este tutorial é de Brian Martin ( @ BrianMartinn " )
+ Console.clear ( )
+ Main ()
+ Console.ReadLine ()
+
+ End Select
+ End Sub
+
+ ' Um - Eu estou usando números para ajudar com a navegação acima quando eu voltar
+ ' depois de construí-lo .
+
+ " Nós usamos subs privadas para separar diferentes seções do programa.
+ Private Sub HelloWorldOutput ()
+ ' Título de aplicativo do console
+ Console.Title = " Olá Mundo Ouput | Saiba X em Y Minutes"
+ 'Use Console.Write ("") ou Console.WriteLine ("") para imprimir saídas.
+ " Seguido por Console.Read () alternativamente Console.ReadLine ()
+ ' Console.ReadLine () imprime a saída para o console.
+ Console.WriteLine ( "Olá Mundo" )
+ Console.ReadLine ()
+ End Sub
+
+ ' Dois
+ Private Sub HelloWorldInput ()
+ Console.Title = " Olá Mundo YourName | Saiba X em Y Minutes"
+ ' Variáveis
+ 'Os dados inseridos por um usuário precisa ser armazenada .
+ ' As variáveis ​​também começar com um Dim e terminar com um Como VariableType .
+
+ ' Neste tutorial, nós queremos saber o que o seu nome, e faça o programa
+ ' Responder ao que é dito.
+ Nome de usuário Dim As String
+ " Nós usamos string como string é uma variável de texto baseado .
+ Console.WriteLine (" Olá, Qual é o seu nome? ") ' Peça ao usuário seu nome.
+ username = Console.ReadLine () ' armazena o nome usuários.
+ Console.WriteLine (" Olá " + nome do usuário) " A saída é Olá ' Seu nome '
+ Console.ReadLine () ' Outsputs acima.
+ ' O código acima irá lhe fazer uma pergunta seguiu imprimindo sua resposta.
+ " Outras variáveis ​​incluem Integer e usamos inteiro para números inteiros.
+ End Sub
+
+ "Três
+ Sub CalculatingWholeNumbers particulares ()
+ Console.Title = " Cálculo de Números Inteiros | Saiba X em Y Minutes"
+ Console.Write ("Primeiro número:") 'Digite um número inteiro, 1, 2, 50, 104 ect
+ Dim a As Integer = Console.ReadLine ()
+ Console.Write ("Segundo número:") 'Enter segundo número inteiro.
+ Dim b As Integer = Console.ReadLine ()
+ Dim c As Integer = a + b
+ Console.WriteLine ( c)
+ Console.ReadLine ()
+ " O texto acima é uma calculadora simples
+ End Sub
+
+ 'Quatro
+ Sub CalculatingDecimalNumbers particulares ()
+ Console.Title = " Calculando com duplo | Saiba X em Y Minutes"
+ ' Claro que gostaria de ser capaz de somar decimais .
+ " Por isso, poderia mudar o acima de Integer para Double.
+
+ " Digite um número inteiro , 1,2 , 2,4 , 50,1 , 104,9 ect
+ Console.Write ("Primeiro número:")
+ Dim a As Double = Console.ReadLine
+ Console.Write ("Segundo número:") 'Enter segundo número inteiro.
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Console.WriteLine ( c)
+ Console.ReadLine ()
+ " Portanto, o programa acima pode adicionar até 1,1-2,2
+ End Sub
+
+ ' Cinco
+ Private Sub WorkingCalculator ()
+ Console.Title = " A Calculadora de Trabalho | Saiba X em Y Minutes"
+ " No entanto, se você gostaria que a calculadora para subtrair, dividir , múltiplos e
+ ' somar.
+ ' Copie e cole o código acima novamente .
+ Console.Write ("Primeiro número:")
+ Dim a As Double = Console.ReadLine
+ Console.Write ("Segundo número:") 'Enter segundo número inteiro.
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ " Ao adicionar as linhas abaixo , somos capazes de calcular a subtração ,
+ ' multply bem como dividir os valores de a e b
+ Console.Gravar ( a.ToString ( ) + " + " + b.ToString ( ) )
+ 'Queremos pad as respostas para a esquerda por três espaços.
+ Console.WriteLine (" =" + c.ToString.PadLeft (3) )
+ Console.Gravar ( a.ToString ( ) + " * " + b.ToString ( ) )
+ Console.WriteLine (" =" + d.ToString.PadLeft (3) )
+ Console.Gravar ( a.ToString ( ) + " - " + b.ToString ( ) )
+ Console.WriteLine (" =" + e.ToString.PadLeft (3) )
+ Console.Write ( a.ToString () + "/" + b.ToString ())
+ Console.WriteLine (" =" + e.ToString.PadLeft (3) )
+ Console.ReadLine ()
+
+ End Sub
+
+ ' Seis
+ Sub UsingDoWhileLoops particulares ()
+ ' Assim como o sub privado anterior
+ ' Desta vez, perguntar se o usuário deseja continuar ( Sim ou Não ? )
+ ' Estamos usando Do While Loop , como não temos certeza se o usuário quer usar o
+ 'programa mais de uma vez .
+ Console.Title = " UsingDoWhileLoops | Saiba X em Y Minutes"
+ Dim resposta As String ' Nós usamos a variável " String" como a resposta é um texto
+ Do ' Começamos o programa com
+ Console.Write ("Primeiro número:")
+ Dim a As Double = Console.ReadLine
+ Console.Write ("Segundo número:")
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ Console.Gravar ( a.ToString ( ) + " + " + b.ToString ( ) )
+ Console.WriteLine (" =" + c.ToString.PadLeft (3) )
+ Console.Gravar ( a.ToString ( ) + " * " + b.ToString ( ) )
+ Console.WriteLine (" =" + d.ToString.PadLeft (3) )
+ Console.Gravar ( a.ToString ( ) + " - " + b.ToString ( ) )
+ Console.WriteLine (" =" + e.ToString.PadLeft (3) )
+ Console.Write ( a.ToString () + "/" + b.ToString ())
+ Console.WriteLine (" =" + e.ToString.PadLeft (3) )
+ Console.ReadLine ()
+ ' Faça a pergunta , se o usuário deseja continuar? Infelizmente,
+ "é sensível a maiúsculas.
+ Console.Write ( "Deseja continuar? (Sim / não )")
+ " O programa pega a variável e imprime e começa de novo.
+ answer = Console.ReadLine
+ " O comando para a variável para trabalhar seria , neste caso, " sim "
+ Loop While resposta = "yes"
+
+ End Sub
+
+ ' Sete
+ Sub UsingForLoops particulares ()
+ ' Às vezes, o programa só precisa ser executado uma vez.
+ " Neste programa vamos estar em contagem regressiva a partir de 10.
+
+ Console.Title = " Usando Para Loops | Saiba X em Y Minutes"
+ 'Declare variável e qual o número que deve contar para baixo na etapa 1,
+ ' Passo -2, -3 Passo ect.
+ Para i As Integer = 10 para 0 passo -1
+ Console.WriteLine ( i.ToString ) ' Imprime o valor do contador
+ Next i ' Calcular novo valor
+ Console.WriteLine ( "Start ") ' Vamos começar o bebê programa !
+ Console.ReadLine () ' POW ! - Talvez eu fiquei um pouco animado, então :)
+ End Sub
+
+ ' Oito
+ Private Sub ConditionalStatement ()
+ Console.Title = " Instruções condicionais | Saiba X em Y Minutes"
+ UserName Dim As String = Console.ReadLine
+ Console.WriteLine (" Olá, Qual é o seu nome? ") ' Peça ao usuário seu nome.
+ username = Console.ReadLine () ' armazena o nome usuários.
+ Se userName = " Adam " Então
+ Console.WriteLine (" Olá Adam " )
+ Console.WriteLine (" Obrigado por criar este site útil " )
+ Console.ReadLine ()
+ outro
+ Console.WriteLine (" Olá " + nome do usuário)
+ Console.WriteLine (" Você check-out www.learnxinyminutes.com " )
+ Console.ReadLine () ' Fins e imprime a declaração acima .
+ End If
+ End Sub
+
+ 'Nove
+ Private Sub IfElseStatement ()
+ Console.Title = "Se Declaração / Else | Saiba X em Y Minutes"
+ 'Às vezes é importante ter em conta mais de duas alternativas.
+ 'Às vezes, há um bom número de outros.
+ 'Quando este for o caso , mais do que uma if seria necessária .
+ 'Uma instrução if é ótimo para máquinas de venda automática . Quando o usuário digita um código.
+ ' A1 , A2, A3 , ect para selecionar um item.
+ 'Todas as opções podem ser combinadas em uma única if.
+
+ Seleção Dim Valor String = Console.ReadLine ' para a seleção
+ Console.WriteLine (" A1. Para Soda " )
+ Console.WriteLine (" A2. Para Fanta " )
+ Console.WriteLine (" A3 . Para Guaraná" )
+ Console.WriteLine (" A4. Para Coca Diet" )
+ Console.ReadLine ()
+ Se a seleção = "A1" Então
+ Console.WriteLine (" soda " )
+ Console.ReadLine ()
+ Seleção ElseIf = " A2 " Então
+ Console.WriteLine (" fanta " )
+ Console.ReadLine ()
+ Seleção ElseIf = " A3 " Então
+ Console.WriteLine ( "guaraná" )
+ Console.ReadLine ()
+ Seleção ElseIf = " A4 " Então
+ Console.WriteLine ( "coca diet" )
+ Console.ReadLine ()
+ outro
+ Console.WriteLine (" Por favor seleccione um produto" )
+ Console.ReadLine ()
+ End If
+
+ End Sub
+
+End Module
+
+```
+
+##Referências
+
+Aprendi Visual Basic no aplicativo de console. Isso me permitiu entender os princípios da programação de computador para continuar a aprender outras linguagens de programação facilmente.
+
+Eu criei um tutorial mais aprofundado do <a href="http://www.vbbootcamp.co.uk/" Title="Visual Basic Tutorial">Visual Basic</a> para aqueles que gostariam de saber mais.
+
+Toda a sintaxe deste tutorial é válida. Copie e cole o código no compilador do Visual Basic e execute (com o F5) o programa.
diff --git a/pt-pt/brainfuck-pt.html.markdown b/pt-pt/brainfuck-pt.html.markdown
new file mode 100644
index 00000000..da4c787f
--- /dev/null
+++ b/pt-pt/brainfuck-pt.html.markdown
@@ -0,0 +1,84 @@
+---
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+lang: pt-pt
+---
+
+Brainfuck (não capitalizado excepto no início de uma frase) é uma linguagem de
+programação Turing-completa extremamente simples com apenas 8 comandos.
+
+```
+Qualquer caractere excepto "><+-.,[]" (não contar com as aspas) é ignorado.
+
+Brainfuck é representado por um vector com 30 000 células inicializadas a zero
+e um ponteiro de dados que aponta para a célula actual.
+
+Existem 8 comandos:
++ : Incrementa o valor da célula actual em 1.
+- : Decrementa o valor da célula actual em 1.
+> : Move o ponteiro de dados para a célula seguinte (célula à direita).
+< : Move o ponteiro de dados para a célula anterior (célula à esquerda).
+. : Imprime o valor ASCII da célula actual. (ex. 65 = 'A').
+, : Lê um único caractere para a célula actual.
+[ : Se o valor da célula actual for zero, salta para o ] correspondente.
+ Caso contrário, passa para a instrução seguinte.
+] : Se o valor da célula actual for zero, passa para a instrução seguinte.
+ Caso contrário, volta para a instrução relativa ao [ correspondente.
+
+[ e ] formam um ciclo while. Obviamente, devem ser equilibrados.
+
+Vejamos alguns programas básicos de brainfuck.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6.
+A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se
+o ponteiro de dados para a célula #2. Incrementa-se o valor da célula #2 10
+vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se
+a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para
+a célula #1 chegar a 0, momento em que se salta para o ] correspondente,
+continuando com a instrução seguinte).
+
+Nesta altura encontramo-nos na célula #1, cujo valor é 0, enquanto a célula #2
+tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5
+vezes para um valor final de 65, é então impresso o valor da célula #2. Ao valor
+65 corresponde o caractere 'A' em ASCII, 'A' é então impresso para o terminal.
+
+, [ > + < - ] > .
+
+Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é
+iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na
+célula #2, movemos o ponteiro de dados de volta para a célula #1, finalmente
+decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser
+igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de
+dados está a apontar para a célula #1 no fim do ciclo, movemos o ponteiro para a
+célula #2 e imprimimos o valor em ASCII.
+
+Os espaços servem apenas para tornar o programa mais legível. Podemos escrever
+o mesmo programa da seguinte maneira:
+
+,[>+<-]>.
+
+Tenta descobrir o que este programa faz:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Este programa lê dois números e multiplica-os.
+
+Basicamente o programa pede dois caracteres ao utilizador. Depois é iniciado um
+ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados
+para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula
+#2, incrementando o valor da célula #3. Contudo, existe um problema, no final do
+ciclo interior a célula #2 tem o valor 0. Para resolver este problema o valor da
+célula #4 é também incrementado e copiado para a célula #2.
+```
+
+Fica então explicado brainfuck. Simples, não? Por divertimento podes escrever os
+teus próprios programas em brainfuck, ou então escrever um interpretador de
+brainfuck noutra linguagem. O interpretador é relativamente fácil de se
+implementar, mas se fores masoquista, tenta escrever um interpretador de
+brainfuck… em brainfuck.
diff --git a/pt-pt/git-pt.html.markdown b/pt-pt/git-pt.html.markdown
new file mode 100644
index 00000000..66cda07f
--- /dev/null
+++ b/pt-pt/git-pt.html.markdown
@@ -0,0 +1,416 @@
+---
+category: tool
+tool: git
+lang: pt-pt
+filename: LearnGit.txt
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+translators:
+ - ["Rafael Jegundo", "http://rafaeljegundo.github.io/"]
+---
+
+Git é um sistema distribuido de gestão para código fonte e controlo de versões.
+
+Funciona através de uma série de registos de estado do projecto e usa esse
+registo para permitir funcionalidades de versionamento e gestão de código
+fonte.
+
+## Conceitos de versionamento
+
+### O que é controlo de versões
+
+Controlo de versões (*source control*) é um processo de registo de alterações
+a um ficheiro ou conjunto de ficheiros ao longo do tempo.
+
+### Controlo de versões: Centralizado VS Distribuido
+
+* Controlo de versões centralizado foca-se na sincronização, registo e *backup*
+de ficheiros.
+* Controlo de versões distribuido foca-se em partilhar alterações. Cada
+alteração é associada a um *id* único.
+* Sistemas distribuidos não têm estrutura definida. É possivel ter um sistema
+centralizado ao estilo SVN usando git.
+
+[Informação adicional (EN)](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Porquê usar git?
+
+* Permite trabalhar offline.
+* Colaborar com outros é fácil!
+* Criar *branches* é fácil!
+* Fazer *merge* é fácil!
+* Git é rápido.
+* Git é flexivel.
+
+## Git - Arquitectura
+
+
+### Repositório
+
+Um conjunto de ficheiros, directórios, registos históricos, *commits* e
+referências. Pode ser imaginado como uma estrutura de dados de código fonte
+com a particularidade de cada elemento do código fonte permitir acesso ao
+histórico das suas alterações, entre outras coisas.
+
+Um repositório git é constituido pelo directório .git e a *working tree*
+
+### Directório .git (componente do repositório)
+
+O repositório .git contém todas as configurações, *logs*, *branches*,
+referências e outros.
+
+[Lista detalhada (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### *Working Tree* (componente do repositório)
+
+Isto é basicamente os directórios e ficheiros do repositório. É frequentemente
+referido como o directório do projecto.
+
+### *Index* (componente do directório .git)
+
+O *Index* é a camada de interface no git. Consistente num elemento que separa
+o directório do projecto do repositório git. Isto permite aos programadores um
+maior controlo sobre o que é registado no repositório git.
+
+### *Commit*
+
+Um *commit** de git é um registo de um cojunto de alterações ou manipulações
+no nos ficheiros do projecto.
+Por exemplo, ao adicionar cinco ficheiros e remover outros 2, estas alterações
+serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
+para outros repositórios ou não!
+
+### *Branch*
+
+Um *branch* é essencialmente uma referência que aponta para o último *commit*
+efetuado. à medida que são feitos novos commits, esta referência é atualizada
+automaticamente e passa a apontar para o commit mais recente.
+
+### *HEAD* e *head* (componentes do directório .git)
+
+*HEAD* é a referência que aponta para o *branch* em uso. Um repositório só tem
+uma *HEAD* activa.
+*head* é uma referência que aponta para qualquer *commit*. Um repositório pode
+ter um número indefinido de *heads*
+
+### Recursos conceptuais (EN)
+
+* [Git para Cientistas de Computação](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git para Designers](http://hoth.entp.com/output/git_for_designers.html)
+
+## Comandos
+
+### *init*
+
+Cria um repositório Git vazio. As definições, informação guardada e outros do
+repositório git são guardados num directório (pasta) denominado ".git".
+
+```bash
+$ git init
+```
+
+### *config*
+
+Permite configurar as definições, sejam as definições do repositório, sistema
+ou configurações globais.
+
+```bash
+# Imprime & Define Algumas Variáveis de Configuração Básicas (Global)
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[Aprenda Mais Sobre git config. (EN)](http://git-scm.com/docs/git-config)
+
+### help
+
+Para aceder rapidamente a um guia extremamente detalhada sobre cada comando.
+Ou para dar apenas uma lembraça rápida de alguma semântica.
+
+```bash
+# Ver rapidamente os comandos disponiveis
+$ git help
+
+# Ver todos os comandos disponiveis
+$ git help -a
+
+# Requerer *help* sobre um comando especifico - manual de utilizador
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Apresenta as diferenças entre o ficheiro *index* (no fundo a versão corrente
+do repositório) e o *commit* da *HEAD* atual.
+
+
+```bash
+# Apresenta o *branch*, ficheiros não monitorizados, alterações e outras
+# difereças
+$ git status
+
+# Para aprender mais detalhes sobre git *status*
+$ git help status
+```
+
+### add
+
+Adiciona ficheiros ao repositório corrente. Se os ficheiros novos não forem
+adicionados através de `git add` ao repositório, então eles não serão
+incluidos nos commits!
+
+```bash
+# adiciona um ficheiro no directório do project atual
+$ git add HelloWorld.java
+
+# adiciona um ficheiro num sub-directório
+$ git add /path/to/file/HelloWorld.c
+
+# permite usar expressões regulares!
+$ git add ./*.java
+```
+
+### branch
+
+Gere os *branches*. É possível ver, editar, criar e apagar branches com este
+comando.
+
+```bash
+# listar *branches* existentes e remotos
+$ git branch -a
+
+# criar um novo *branch*
+$ git branch myNewBranch
+
+# apagar um *branch*
+$ git branch -d myBranch
+
+# alterar o nome de um *branch*
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# editar a descrição de um *branch*
+$ git branch myBranchName --edit-description
+```
+
+### checkout
+
+Atualiza todos os ficheiros no directório do projecto de forma a ficarem iguais
+à versão do index ou do *branch* especificado.
+
+```bash
+# Checkout de um repositório - por predefinição para o branch master
+$ git checkout
+# Checkout de um branch especifico
+$ git checkout branchName
+# Cria um novo branch e faz checkout para ele.
+# Equivalente a: "git branch <name>; git checkout <name>"
+$ git checkout -b newBranch
+```
+
+### clone
+
+Clona ou copia um repositório existente para um novo directório. Também
+adiciona *branches* de monitorização remota para cada *branch* no repositório
+clonado o que permite enviar alterações para um *branch* remoto.
+
+```bash
+# Clona learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+```
+
+### commit
+
+Guarda o conteudo atual do index num novo *commit*. Este *commit* contém
+as alterações feitas e a mensagem criada pelo utilizador.
+
+```bash
+# commit com uma mensagem
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+```
+
+### diff
+
+Apresenta as diferenças entre um ficheiro no repositório do projecto, *index*
+e *commits*
+
+```bash
+# Apresenta a diferença entre o directório atual e o index
+$ git diff
+
+# Apresenta a diferença entre o index e os commits mais recentes
+$ git diff --cached
+
+# Apresenta a diferença entre o directório atual e o commit mais recente
+$ git diff HEAD
+```
+
+### grep
+
+Permite procurar facilmente num repositório
+
+Configurações opcionais:
+
+```bash
+# Obrigado a Travis Jeffery por estas
+# Define a apresentação de números de linha nos resultados do grep
+$ git config --global grep.lineNumber true
+
+# Torna os resultados da pesquisa mais fáceis de ler, agrupando-os
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Pesquisa por "variableName" em todos os ficheiros de java
+$ git grep 'variableName' -- '*.java'
+
+# Pesquisa por uma linha que contém "arrayListName" e "add" ou "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Google é teu amigo; para mais exemplos:
+[Git Grep Ninja (EN)](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Apresenta commits do repositório.
+
+```bash
+# Apresenta todos os commits
+$ git log
+
+# Apresenta X commits
+$ git log -n 10
+
+# Apresenta apenas commits de merge
+$ git log --merges
+```
+
+### merge
+
+"Merge" (junta) as alterações de commits externos com o *branch* atual.
+
+```bash
+# Junta o branch especificado com o atual
+$ git merge branchName
+
+# Para gerar sempre um commit ao juntar os branches
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Alterar o nome ou mover um ficheiro.
+
+```bash
+# Alterar o nome de um ficheiro
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Mover um ficheiro
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Forçar a alteração de nome ou mudança local
+# "existingFile" já existe no directório, será sobre-escrito.
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Puxa alterações de um repositório e junta-as com outro branch
+
+```bash
+# Atualiza o repositório local, juntando as novas alterações
+# do repositório remoto 'origin' e branch 'master'
+# git pull <remote> <branch>
+# git pull => aplica a predefinição => git pull origin master
+$ git pull origin master
+
+# Juntar alterações do branch remote e fazer rebase commits do branch
+# no repositório local, como: "git pull <remote> <branch>, git rebase <branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Enviar e juntar alterações de um branch para o seu branch correspondente
+num repositório remoto.
+
+```bash
+# Envia e junta as alterações de um repositório local
+# para um remoto denominado "origin" no branch "master".
+# git push <remote> <branch>
+# git push => aplica a predefinição => git push origin master
+$ git push origin master
+```
+
+### rebase (cautela!)
+
+Pega em todas as alterações que foram registadas num branch e volta a
+aplicá-las em outro branch.
+*Não deve ser feito rebase de commits que foram enviados para um repositório
+público*
+
+```bash
+# Faz Rebase de experimentBranch para master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Additional Reading (EN).](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (cautela!)
+
+Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
+*pulls*, *commits*, *adds* e outros. É um comando muito poderoso mas também
+perigoso se não há certeza quanto ao que se está a fazer.
+
+```bash
+# Restabelece a camada intermediária dr registo para o último
+# commit (o directório fica sem alterações)
+$ git reset
+
+# Restabelece a camada intermediária de registo para o último commit, e
+# sobre-escreve o projecto atual
+$ git reset --hard
+
+# Move a head do branch atual para o commit especificado, sem alterar o projecto.
+# todas as alterações ainda existem no projecto
+$ git reset 31f2bb1
+
+# Inverte a head do branch atual para o commit especificado
+# fazendo com que este esteja em sintonia com o directório do projecto
+# Remove alterações não registadas e todos os commits após o commit especificado
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+O oposto de git add, git rm remove ficheiros do branch atual.
+
+```bash
+# remove HelloWorld.c
+$ git rm HelloWorld.c
+
+# Remove um ficheiro de um sub-directório
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Informação complementar (EN)
+
+* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video Tutorials](http://git-scm.com/videos)
+
+* [git-scm - Documentation](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
+
+* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/python.html.markdown b/python.html.markdown
index f0b74d08..210c9619 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -2,6 +2,7 @@
language: python
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "http://aminbandali.com"]
filename: learnpython.py
---
@@ -15,7 +16,9 @@ Note: This article applies to Python 2.7 specifically, but should be applicable
to Python 2.x. Look for another tour of Python 3 soon!
```python
-# Single line comments start with a hash.
+
+# Single line comments start with a number symbol.
+
""" Multiline strings can be written
using three "'s, and are often used
as comments
@@ -26,60 +29,60 @@ to Python 2.x. Look for another tour of Python 3 soon!
####################################################
# You have numbers
-3 #=> 3
+3 # => 3
# Math is what you would expect
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
# Division is a bit tricky. It is integer division and floors the results
# automatically.
-5 / 2 #=> 2
+5 / 2 # => 2
# To fix division we need to learn about floats.
2.0 # This is a float
-11.0 / 4.0 #=> 2.75 ahhh...much better
+11.0 / 4.0 # => 2.75 ahhh...much better
# Enforce precedence with parentheses
-(1 + 3) * 2 #=> 8
+(1 + 3) * 2 # => 8
# Boolean values are primitives
True
False
# negate with not
-not True #=> False
-not False #=> True
+not True # => False
+not False # => True
# Equality is ==
-1 == 1 #=> True
-2 == 1 #=> False
+1 == 1 # => True
+2 == 1 # => False
# Inequality is !=
-1 != 1 #=> False
-2 != 1 #=> True
+1 != 1 # => False
+2 != 1 # => True
# More comparisons
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
# Comparisons can be chained!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
# Strings are created with " or '
"This is a string."
'This is also a string.'
# Strings can be added too!
-"Hello " + "world!" #=> "Hello world!"
+"Hello " + "world!" # => "Hello world!"
# A string can be treated like a list of characters
-"This is a string"[0] #=> 'T'
+"This is a string"[0] # => 'T'
# % can be used to format strings, like this:
"%s can be %s" % ("strings", "interpolated")
@@ -91,12 +94,12 @@ not False #=> True
"{name} wants to eat {food}".format(name="Bob", food="lasagna")
# None is an object
-None #=> None
+None # => None
-# Don't use the equality `==` symbol to compare objects to None
-# Use `is` instead
-"etc" is None #=> False
-None is None #=> True
+# Don't use the equality "==" symbol to compare objects to None
+# Use "is" instead
+"etc" is None # => False
+None is None # => True
# The 'is' operator tests for object identity. This isn't
# very useful when dealing with primitive values, but is
@@ -104,28 +107,30 @@ None is None #=> True
# None, 0, and empty strings/lists all evaluate to False.
# All other values are True
-0 == False #=> True
-"" == False #=> True
+bool(0) # => False
+bool("") # => False
####################################################
## 2. Variables and Collections
####################################################
-# Printing is pretty easy
-print "I'm Python. Nice to meet you!"
+# Python has a print function, available in versions 2.7 and 3...
+print("I'm Python. Nice to meet you!")
+# and an older print statement, in all 2.x versions but removed from 3.
+print "I'm also Python!"
# No need to declare variables before assigning to them.
some_var = 5 # Convention is to use lower_case_with_underscores
-some_var #=> 5
+some_var # => 5
# Accessing a previously unassigned variable is an exception.
# See Control Flow to learn more about exception handling.
some_other_var # Raises a name error
# if can be used as an expression
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
# Lists store sequences
li = []
@@ -133,57 +138,63 @@ li = []
other_li = [4, 5, 6]
# Add stuff to the end of a list with append
-li.append(1) #li is now [1]
-li.append(2) #li is now [1, 2]
-li.append(4) #li is now [1, 2, 4]
-li.append(3) #li is now [1, 2, 4, 3]
+li.append(1) # li is now [1]
+li.append(2) # li is now [1, 2]
+li.append(4) # li is now [1, 2, 4]
+li.append(3) # li is now [1, 2, 4, 3]
# Remove from the end with pop
-li.pop() #=> 3 and li is now [1, 2, 4]
+li.pop() # => 3 and li is now [1, 2, 4]
# Let's put it back
li.append(3) # li is now [1, 2, 4, 3] again.
# Access a list like you would any array
-li[0] #=> 1
+li[0] # => 1
# Look at the last element
-li[-1] #=> 3
+li[-1] # => 3
# Looking out of bounds is an IndexError
-li[4] # Raises an IndexError
+li[4] # Raises an IndexError
# You can look at ranges with slice syntax.
# (It's a closed/open range for you mathy types.)
-li[1:3] #=> [2, 4]
+li[1:3] # => [2, 4]
# Omit the beginning
-li[2:] #=> [4, 3]
+li[2:] # => [4, 3]
# Omit the end
-li[:3] #=> [1, 2, 4]
+li[:3] # => [1, 2, 4]
+# Select every second entry
+li[::2] # =>[1, 4]
+# Revert the list
+li[::-1] # => [3, 4, 2, 1]
+# Use any combination of these to make advanced slices
+# li[start:end:step]
-# Remove arbitrary elements from a list with del
-del li[2] # li is now [1, 2, 3]
+# Remove arbitrary elements from a list with "del"
+del li[2] # li is now [1, 2, 3]
# You can add lists
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li and other_li is left alone
+li + other_li # => [1, 2, 3, 4, 5, 6] - Note: values for li and for other_li are not modified.
-# Concatenate lists with extend
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+# Concatenate lists with "extend()"
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
-# Check for existence in a list with in
-1 in li #=> True
+# Check for existence in a list with "in"
+1 in li # => True
-# Examine the length with len
-len(li) #=> 6
+# Examine the length with "len()"
+len(li) # => 6
# Tuples are like lists but are immutable.
tup = (1, 2, 3)
-tup[0] #=> 1
+tup[0] # => 1
tup[0] = 3 # Raises a TypeError
# You can do all those list thingies on tuples too
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
# You can unpack tuples (or lists) into variables
a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
@@ -199,60 +210,60 @@ empty_dict = {}
filled_dict = {"one": 1, "two": 2, "three": 3}
# Look up values with []
-filled_dict["one"] #=> 1
+filled_dict["one"] # => 1
-# Get all keys as a list
-filled_dict.keys() #=> ["three", "two", "one"]
+# Get all keys as a list with "keys()"
+filled_dict.keys() # => ["three", "two", "one"]
# Note - Dictionary key ordering is not guaranteed.
# Your results might not match this exactly.
-# Get all values as a list
-filled_dict.values() #=> [3, 2, 1]
+# Get all values as a list with "values()"
+filled_dict.values() # => [3, 2, 1]
# Note - Same as above regarding key ordering.
-# Check for existence of keys in a dictionary with in
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
+# Check for existence of keys in a dictionary with "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
# Looking up a non-existing key is a KeyError
-filled_dict["four"] # KeyError
+filled_dict["four"] # KeyError
-# Use get method to avoid the KeyError
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
+# Use "get()" method to avoid the KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
# The get method supports a default argument when the value is missing
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
-# Setdefault method is a safe way to add new key-value pair into dictionary
-filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5
+# "setdefault()" inserts into a dictionary only if the given key isn't present
+filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
# Sets store ... well sets
empty_set = set()
-# Initialize a set with a bunch of values
-some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
+# Initialize a "set()" with a bunch of values
+some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4])
# Since Python 2.7, {} can be used to declare a set
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Add more items to a set
-filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
# Do set intersection with &
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
# Do set union with |
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
# Do set difference with -
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Check for existence in a set with in
-2 in filled_set #=> True
-10 in filled_set #=> False
+2 in filled_set # => True
+10 in filled_set # => False
####################################################
@@ -265,11 +276,11 @@ some_var = 5
# Here is an if statement. Indentation is significant in python!
# prints "some_var is smaller than 10"
if some_var > 10:
- print "some_var is totally bigger than 10."
+ print("some_var is totally bigger than 10.")
elif some_var < 10: # This elif clause is optional.
- print "some_var is smaller than 10."
+ print("some_var is smaller than 10.")
else: # This is optional too.
- print "some_var is indeed 10."
+ print("some_var is indeed 10.")
"""
@@ -281,10 +292,10 @@ prints:
"""
for animal in ["dog", "cat", "mouse"]:
# You can use % to interpolate formatted strings
- print "%s is a mammal" % animal
-
+ print("%s is a mammal" % animal)
+
"""
-`range(number)` returns a list of numbers
+"range(number)" returns a list of numbers
from zero to the given number
prints:
0
@@ -293,7 +304,7 @@ prints:
3
"""
for i in range(4):
- print i
+ print(i)
"""
While loops go until a condition is no longer met.
@@ -305,14 +316,14 @@ prints:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Shorthand for x = x + 1
# Handle exceptions with a try/except block
# Works on Python 2.6 and up:
try:
- # Use raise to raise an error
+ # Use "raise" to raise an error
raise IndexError("This is an index error")
except IndexError as e:
pass # Pass is just a no-op. Usually you would do recovery here.
@@ -322,23 +333,24 @@ except IndexError as e:
## 4. Functions
####################################################
-# Use def to create new functions
+# Use "def" to create new functions
def add(x, y):
- print "x is %s and y is %s" % (x, y)
+ print("x is %s and y is %s" % (x, y))
return x + y # Return values with a return statement
# Calling functions with parameters
-add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11
+add(5, 6) # => prints out "x is 5 and y is 6" and returns 11
# Another way to call functions is with keyword arguments
add(y=6, x=5) # Keyword arguments can arrive in any order.
+
# You can define functions that take a variable number of
# positional arguments
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1, 2, 3)
# You can define functions that take a variable number of
@@ -347,25 +359,27 @@ def keyword_args(**kwargs):
return kwargs
# Let's call it to see what happens
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
# You can do both at once, if you like
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
{"a": 3, "b": 4}
"""
-# When calling functions, you can do the opposite of varargs/kwargs!
+# When calling functions, you can do the opposite of args/kwargs!
# Use * to expand tuples and use ** to expand kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # equivalent to foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # equivalent to foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
+
# Python has first class functions
def create_adder(x):
@@ -374,23 +388,24 @@ def create_adder(x):
return adder
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
# There are also anonymous functions
-(lambda x: x > 2)(3) #=> True
+(lambda x: x > 2)(3) # => True
# There are built-in higher order functions
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# We can use list comprehensions for nice maps and filters
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Classes
####################################################
+
# We subclass from object to get a class.
class Human(object):
@@ -402,9 +417,9 @@ class Human(object):
# Assign the argument to the instance's name attribute
self.name = name
- # An instance method. All methods take self as the first argument
+ # An instance method. All methods take "self" as the first argument
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "%s: %s" % (self.name, msg)
# A class method is shared among all instances
# They are called with the calling class as the first argument
@@ -420,21 +435,21 @@ class Human(object):
# Instantiate a class
i = Human(name="Ian")
-print i.say("hi") # prints out "Ian: hi"
+print(i.say("hi")) # prints out "Ian: hi"
j = Human("Joel")
-print j.say("hello") #prints out "Joel: hello"
+print(j.say("hello")) # prints out "Joel: hello"
# Call our class method
-i.get_species() #=> "H. sapiens"
+i.get_species() # => "H. sapiens"
# Change the shared attribute
Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
# Call the static method
-Human.grunt() #=> "*grunt*"
+Human.grunt() # => "*grunt*"
####################################################
@@ -443,12 +458,12 @@ Human.grunt() #=> "*grunt*"
# You can import modules
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) # => 4
# You can get specific functions from a module
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
# You can import all functions from a module.
# Warning: this is not recommended
@@ -456,10 +471,10 @@ from math import *
# You can shorten module names
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
# Python modules are just ordinary python files. You
-# can write your own, and import them. The name of the
+# can write your own, and import them. The name of the
# module is the same as the name of the file.
# You can find out which functions and attributes
@@ -468,6 +483,55 @@ import math
dir(math)
+####################################################
+## 7. Advanced
+####################################################
+
+# Generators help you make lazy code
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# A generator creates values on the fly.
+# Instead of generating and returning all values at once it creates one in each
+# iteration. This means values bigger than 15 wont be processed in
+# double_numbers.
+# Note range is a generator too. Creating a list 1-900000000 would take lot of
+# time to be made
+_range = range(1, 900000000)
+# will double all numbers until a result >=30 found
+for i in double_numbers(_range):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Decorators
+# in this example beg wraps say
+# Beg will call say. If say_please is True then it will change the returned
+# message
+from functools import wraps
+
+
+def beg(_say):
+ @wraps(_say)
+ def wrapper(*args, **kwargs):
+ msg, say_please = _say(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Please! I am poor :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Can you buy me a beer?"
+ return msg, say_please
+
+
+print(say()) # Can you buy me a beer?
+print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
```
## Ready For More?
@@ -479,6 +543,7 @@ dir(math)
* [The Official Docs](http://docs.python.org/2.6/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Dead Tree
diff --git a/python3.html.markdown b/python3.html.markdown
new file mode 100644
index 00000000..54f425ed
--- /dev/null
+++ b/python3.html.markdown
@@ -0,0 +1,578 @@
+---
+language: python3
+contributors:
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+filename: learnpython3.py
+---
+
+Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular
+languages in existence. I fell in love with Python for its syntactic clarity. It's basically
+executable pseudocode.
+
+Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
+
+Note: This article applies to Python 3 specifically. Check out the other tutorial if you want to learn the old Python 2.7
+
+```python
+
+# Single line comments start with a number symbol.
+
+""" Multiline strings can be written
+ using three "'s, and are often used
+ as comments
+"""
+
+####################################################
+## 1. Primitive Datatypes and Operators
+####################################################
+
+# You have numbers
+3 # => 3
+
+# Math is what you would expect
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+
+# Except division which returns floats by default
+35 / 5 # => 7.0
+
+# When you use a float, results are floats
+3 * 2.0 # => 6.0
+
+# Enforce precedence with parentheses
+(1 + 3) * 2 # => 8
+
+
+# Boolean values are primitives
+True
+False
+
+# negate with not
+not True # => False
+not False # => True
+
+
+# Equality is ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Inequality is !=
+1 != 1 # => False
+2 != 1 # => True
+
+# More comparisons
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Comparisons can be chained!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+
+# Strings are created with " or '
+"This is a string."
+'This is also a string.'
+
+# Strings can be added too! But try not to do this.
+"Hello " + "world!" # => "Hello world!"
+
+# A string can be treated like a list of characters
+"This is a string"[0] # => 'T'
+
+# .format can be used to format strings, like this:
+"{} can be {}".format("strings", "interpolated")
+
+# You can repeat the formatting arguments to save some typing.
+"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") #=> "Jack be nimble, Jack be quick, Jack jump over the candle stick"
+# You can use keywords if you don't want to count.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
+
+
+# None is an object
+None # => None
+
+# Don't use the equality "==" symbol to compare objects to None
+# Use "is" instead. This checks for equality of object identity.
+"etc" is None # => False
+None is None # => True
+
+# None, 0, and empty strings/lists/dicts all evaluate to False.
+# All other values are True
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
+
+
+####################################################
+## 2. Variables and Collections
+####################################################
+
+# Python has a print function
+print("I'm Python. Nice to meet you!")
+
+# No need to declare variables before assigning to them. Convention is to use lower_case_with_underscores
+some_var = 5
+some_var # => 5
+
+# Accessing a previously unassigned variable is an exception.
+# See Control Flow to learn more about exception handling.
+some_unknown_var # Raises a NameError
+
+# Lists store sequences
+li = []
+# You can start with a prefilled list
+other_li = [4, 5, 6]
+
+# Add stuff to the end of a list with append
+li.append(1) # li is now [1]
+li.append(2) # li is now [1, 2]
+li.append(4) # li is now [1, 2, 4]
+li.append(3) # li is now [1, 2, 4, 3]
+# Remove from the end with pop
+li.pop() # => 3 and li is now [1, 2, 4]
+# Let's put it back
+li.append(3) # li is now [1, 2, 4, 3] again.
+
+# Access a list like you would any array
+li[0] # => 1
+# Look at the last element
+li[-1] # => 3
+
+# Looking out of bounds is an IndexError
+li[4] # Raises an IndexError
+
+# You can look at ranges with slice syntax.
+# (It's a closed/open range for you mathy types.)
+li[1:3] # => [2, 4]
+# Omit the beginning
+li[2:] # => [4, 3]
+# Omit the end
+li[:3] # => [1, 2, 4]
+# Select every second entry
+li[::2] # =>[1, 4]
+# Revert the list
+li[::-1] # => [3, 4, 2, 1]
+# Use any combination of these to make advanced slices
+# li[start:end:step]
+
+# Remove arbitrary elements from a list with "del"
+del li[2] # li is now [1, 2, 3]
+
+# You can add lists
+li + other_li # => [1, 2, 3, 4, 5, 6] - Note: values for li and for other_li are not modified.
+
+# Concatenate lists with "extend()"
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+
+# Check for existence in a list with "in"
+1 in li # => True
+
+# Examine the length with "len()"
+len(li) # => 6
+
+
+# Tuples are like lists but are immutable.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Raises a TypeError
+
+# You can do all those list thingies on tuples too
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# You can unpack tuples (or lists) into variables
+a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
+# Tuples are created by default if you leave out the parentheses
+d, e, f = 4, 5, 6
+# Now look how easy it is to swap two values
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionaries store mappings
+empty_dict = {}
+# Here is a prefilled dictionary
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Look up values with []
+filled_dict["one"] # => 1
+
+# Get all keys as a list with "keys()". We need to wrap the call in list() because we are getting back an iterable. We'll talk about those later.
+list(filled_dict.keys()) # => ["three", "two", "one"]
+# Note - Dictionary key ordering is not guaranteed.
+# Your results might not match this exactly.
+
+# Get all values as a list with "values()". Once again we need to wrap it in list() to get it out of the iterable.
+list(filled_dict.values()) # => [3, 2, 1]
+# Note - Same as above regarding key ordering.
+
+# Check for existence of keys in a dictionary with "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# Looking up a non-existing key is a KeyError
+filled_dict["four"] # KeyError
+
+# Use "get()" method to avoid the KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# The get method supports a default argument when the value is missing
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+
+# "setdefault()" inserts into a dictionary only if the given key isn't present
+filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+
+# Remove keys from a dictionary with del
+del filled_dict["one"] # Removes the key "one" from filled dict
+
+
+# Sets store ... well sets
+empty_set = set()
+# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
+
+# Add more items to a set
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# Do set intersection with &
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# Do set union with |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Do set difference with -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Check for existence in a set with in
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+####################################################
+## 3. Control Flow and Iterables
+####################################################
+
+# Let's just make a variable
+some_var = 5
+
+# Here is an if statement. Indentation is significant in python!
+# prints "some_var is smaller than 10"
+if some_var > 10:
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # This elif clause is optional.
+ print("some_var is smaller than 10.")
+else: # This is optional too.
+ print("some_var is indeed 10.")
+
+
+"""
+For loops iterate over lists
+prints:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # You can use % to interpolate formatted strings
+ print("{} is a mammal".format(animal))
+
+"""
+"range(number)" returns a list of numbers
+from zero to the given number
+prints:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+While loops go until a condition is no longer met.
+prints:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Shorthand for x = x + 1
+
+# Handle exceptions with a try/except block
+try:
+ # Use "raise" to raise an error
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass is just a no-op. Usually you would do recovery here.
+
+
+# Python's offers a fundamental abstraction called the Iterable.
+# An iterable is an object that can be treated as a sequence.
+# The object returned the range function, is an iterable.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) #=> range(1,10). This is an object that implements our Iterable interface
+
+i We can loop over it.
+for i in our_iterable:
+ print(i) # Prints one, two, three
+
+# However we cannot address elements by index.
+our_iterable[1] # Raises a TypeError
+
+# An iterable is an object that knows how to create an iterator.
+our_iterator = iter(our_iterable)
+
+# Our iterator is an object that can remember the state as we traverse through it.
+# We get the next object by calling the __next__ function.
+our_iterator.__next__() #=> "one"
+
+# It maintains state as we call __next__.
+our_iterator.__next__() #=> "two"
+our_iterator.__next__() #=> "three"
+
+# After the iterator has returned all of its data, it gives you a StopIterator Exception
+our_iterator.__next__() # Raises StopIteration
+
+# You can grab all the elements of an iterator by calling list() on it.
+list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
+
+
+
+####################################################
+## 4. Functions
+####################################################
+
+# Use "def" to create new functions
+def add(x, y):
+ print("x is %s and y is %s" % (x, y))
+ return x + y # Return values with a return statement
+
+# Calling functions with parameters
+add(5, 6) # => prints out "x is 5 and y is 6" and returns 11
+
+# Another way to call functions is with keyword arguments
+add(y=6, x=5) # Keyword arguments can arrive in any order.
+
+
+# You can define functions that take a variable number of
+# positional arguments
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+
+# You can define functions that take a variable number of
+# keyword arguments, as well
+def keyword_args(**kwargs):
+ return kwargs
+
+# Let's call it to see what happens
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# You can do both at once, if you like
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) prints:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# When calling functions, you can do the opposite of args/kwargs!
+# Use * to expand tuples and use ** to expand kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # equivalent to foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
+
+
+# Python has first class functions
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# There are also anonymous functions
+(lambda x: x > 2)(3) # => True
+
+# TODO - Fix for iterables
+# There are built-in higher order functions
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# We can use list comprehensions for nice maps and filters
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+
+####################################################
+## 5. Classes
+####################################################
+
+
+# We subclass from object to get a class.
+class Human(object):
+
+ # A class attribute. It is shared by all instances of this class
+ species = "H. sapiens"
+
+ # Basic initializer
+ def __init__(self, name):
+ # Assign the argument to the instance's name attribute
+ self.name = name
+
+ # An instance method. All methods take "self" as the first argument
+ def say(self, msg):
+ return "{name}: {message}" % (name=self.name, message=msg)
+
+ # A class method is shared among all instances
+ # They are called with the calling class as the first argument
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # A static method is called without a class or instance reference
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instantiate a class
+i = Human(name="Ian")
+print(i.say("hi")) # prints out "Ian: hi"
+
+j = Human("Joel")
+print(j.say("hello")) # prints out "Joel: hello"
+
+# Call our class method
+i.get_species() # => "H. sapiens"
+
+# Change the shared attribute
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# Call the static method
+Human.grunt() # => "*grunt*"
+
+
+####################################################
+## 6. Modules
+####################################################
+
+# You can import modules
+import math
+print(math.sqrt(16)) # => 4
+
+# You can get specific functions from a module
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# You can import all functions from a module.
+# Warning: this is not recommended
+from math import *
+
+# You can shorten module names
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Python modules are just ordinary python files. You
+# can write your own, and import them. The name of the
+# module is the same as the name of the file.
+
+# You can find out which functions and attributes
+# defines a module.
+import math
+dir(math)
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# Generators help you make lazy code
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# A generator creates values on the fly.
+# Instead of generating and returning all values at once it creates one in each
+# iteration. This means values bigger than 15 wont be processed in
+# double_numbers.
+# Note range is a generator too. Creating a list 1-900000000 would take lot of
+# time to be made
+_range = range(1, 900000000)
+# will double all numbers until a result >=30 found
+for i in double_numbers(_range):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Decorators
+# in this example beg wraps say
+# Beg will call say. If say_please is True then it will change the returned
+# message
+from functools import wraps
+
+
+def beg(_say):
+ @wraps(_say)
+ def wrapper(*args, **kwargs):
+ msg, say_please = _say(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Please! I am poor :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Can you buy me a beer?"
+ return msg, say_please
+
+
+print(say()) # Can you buy me a beer?
+print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
+```
+
+## Ready For More?
+
+### Free Online
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [Ideas for Python Projects](http://pythonpracticeprojects.com)
+
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+
+### Dead Tree
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/r.html.markdown b/r.html.markdown
index 03aa1dd2..ea94ae42 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -10,7 +10,7 @@ R is a statistical computing language. It has lots of libraries for uploading an
```python
-# Comments start with hashtags.
+# Comments start with number symbols.
# You can't make a multi-line comment per se,
# but you can stack multiple comments like so.
@@ -298,7 +298,7 @@ if (4 > 3) {
# Defined like so:
jiggle <- function(x) {
- x+ rnorm(x, sd=.1) #add in a bit of (controlled) noise
+ x = x + rnorm(1, sd=.1) #add in a bit of (controlled) noise
return(x)
}
diff --git a/racket.html.markdown b/racket.html.markdown
index adacd91d..6abc8759 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.
@@ -195,7 +196,7 @@ my-pet ; => #<dog>
(hash-ref m 'd 0) ; => 0
;; Use `hash-set' to extend an immutable hash table
-;; (Returns the extended hash instdead of mutating it)
+;; (Returns the extended hash instead of mutating it)
(define m2 (hash-set m 'd 4))
m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
@@ -223,7 +224,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(define hello-world (lambda () "Hello World"))
(hello-world) ; => "Hello World"
-;; You can shorten this using the function definition syntatcic sugae:
+;; You can shorten this using the function definition syntactic sugar:
(define (hello-world2) "Hello World")
;; The () in the above is the list of arguments for the function
@@ -495,7 +496,7 @@ vec ; => #(1 2 3 4)
;; 8. Classes and Objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Create a class fish% (-% is idomatic for class bindings)
+;; Create a class fish% (-% is idiomatic for class bindings)
(define fish%
(class object%
(init size) ; initialization argument
@@ -551,7 +552,7 @@ vec ; => #(1 2 3 4)
(set! i (add1 i))))
;; Macros are hygienic, you cannot clobber existing variables!
-(define-syntax-rule (swap! x y) ; -! is idomatic for mutation
+(define-syntax-rule (swap! x y) ; -! is idiomatic for mutation
(let ([tmp x])
(set! x y)
(set! y tmp)))
@@ -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/red.html.markdown b/red.html.markdown
new file mode 100644
index 00000000..73a13606
--- /dev/null
+++ b/red.html.markdown
@@ -0,0 +1,219 @@
+---
+name: Red
+category: language
+language: Red
+filename: learnred.red
+contributors:
+ - ["Arnold van Hofwegen", "https://github.com/iArnold"]
+---
+
+
+Red was created out of the need to get work done, and the tool the author wanted to use, the language of REBOL, had a couple of drawbacks.
+It was not Open Sourced at that time and it is an interpreted language, what means that it is on average slow compared to a compiled language.
+
+Red, together with its C-level dialect Red/System, provides a language that covers the entire programming space you ever need to program something in.
+Red is a language heavily based on the language of REBOL. Where Red itself reproduces the flexibility of the REBOL language, the underlying language Red will be built upon,
+Red/System, covers the more basic needs of programming like C can, being closer to the metal.
+
+Red will be the world's first Full Stack Programming Language. This means that it will be an effective tool to do (almost) any programming task on every level
+from the metal to the meta without the aid of other stack tools.
+Furthermore Red will be able to cross-compile Red source code without using any GCC like toolchain
+from any platform to any other platform. And it will do this all from a binary executable that is supposed to stay under 1 MB.
+
+Ready to learn your first Red?
+
+```
+All text before the header will be treated as comment, as long as you avoid using the
+word "red" starting with a capital "R" in this pre-header text. This is a temporary
+shortcoming of the used lexer but most of the time you start your script or program
+with the header itself.
+The header of a red script is the capitalized word "red" followed by a
+whitespace character followed by a block of square brackets [].
+The block of brackets can be filled with useful information about this script or
+program: the author's name, the filename, the version, the license, a summary of
+what the program does or any other files it needs.
+The red/System header is just like the red header, only saying "red/System" and
+not "red".
+
+Red []
+
+;this is a commented line
+
+print "Hello Red World" ; this is another comment
+
+comment {
+ This is a multiline comment.
+ You just saw the Red version of the "Hello World" program.
+}
+
+; Your program's entry point is the first executable code that is found
+; no need to restrict this to a 'main' function.
+
+; Valid variable names start with a letter and can contain numbers,
+; variables containing only capital A thru F and numbers and ending with 'h' are
+; forbidden, because that is how hexadecimal numbers are expressed in Red and
+; Red/System.
+
+; assign a value to a variable using a colon ":"
+my-name: "Red"
+reason-for-using-the-colon: {Assigning values using the colon makes
+ the equality sign "=" exclusively usable for comparisons purposes,
+ exactly what "=" was intended for in the first place!
+ Remember this y = x + 1 and x = 1 => y = 2 stuff from school?
+}
+is-this-name-valid?: true
+
+; print output using print, or prin for printing without a newline or linefeed at the
+; end of the printed text.
+
+prin " My name is " print my-name
+My name is Red
+
+print ["My name is " my-name lf]
+My name is Red
+
+; In case you haven't already noticed: statements do NOT end with a semicolon ;-)
+
+;
+; Datatypes
+;
+; If you know Rebol, you probably have noticed it has lots of datatypes. Red
+; does not have yet all those types, but as Red want to be close to Rebol it
+; will have a lot of datatypes.
+; You can recognize types by the exclamation sign at the end. But beware
+; names ending with an exclamation sign are allowed.
+; Some of the available types are integer! string! block!
+
+; Declaring variables before using them?
+; Red knows by itself what variable is best to use for the data you want to use it
+; for.
+; A variable declaration is not always necessary.
+; It is considered good coding practise to declare your variables,
+; but it is not forced upon you by Red.
+; You can declare a variable and specify its type. a variable's type determines its
+; size in bytes.
+
+; Variables of integer! type are usually 4 bytes or 32 bits
+my-integer: 0
+; Red's integers are signed. No support for unsigned atm but that will come.
+
+; To find out the type of variable use type?
+type? my-integer
+integer!
+
+; A variable can be initialized using another variable that gets initialized
+; at the same time.
+i2: 1 + i1: 1
+
+; Arithmetic is straightforward
+i1 + i2 ; result 3
+i2 - i1 ; result 1
+i2 * i1 ; result 2
+i1 / i2 ; result 0 (0.5, but truncated towards 0)
+
+; Comparison operators are probably familiar, and unlike in other languages you
+; only need a single '=' sign for comparison.
+; There is a boolean like type in Red. It has values true and false, but also the
+; values on/off or yes/no can be used
+
+3 = 2 ; result false
+3 != 2 ; result true
+3 > 2 ; result true
+3 < 2 ; result false
+2 <= 2 ; result true
+2 >= 2 ; result true
+
+;
+; Control Structures
+;
+; if
+; Evaluate a block of code if a given condition is true. IF does not return any value,
+; so cannot be used in an expression.
+if a < 0 [print "a is negative"]
+
+; either
+; Evaluate a block of code if a given condition is true, else evaluate an alternative
+; block of code. If the last expressions in both blocks have the same type, EITHER can
+; be used inside an expression.
+either a < 0 [
+ either a = 0 [
+ msg: "zero"
+ ][
+ msg: "negative"
+ ]
+][
+ msg: "positive"
+]
+
+print ["a is " msg lf]
+
+; There is an alternative way to write this
+; (Which is allowed because all code paths return a value of the same type):
+
+msg: either a < 0 [
+ either a = 0 [
+ "zero"
+ ][
+ "negative"
+ ]
+ ][
+ "positive"
+]
+print ["a is " msg lf]
+
+; until
+; Loop over a block of code until the condition at end of block, is met.
+; UNTIL does not return any value, so it cannot be used in an expression.
+c: 5
+until [
+ prin "o"
+ c: c - 1
+ c = 0 ; the condition to end the until loop
+]
+; will output:
+ooooo
+; Note that the loop will always be evaluated at least once, even if the condition is
+; not met from the beginning.
+
+; while
+; While a given condition is met, evaluate a block of code.
+; WHILE does not return any value, so it cannot be used in an expression.
+c: 5
+while [c > 0][
+ prin "o"
+ c: c - 1
+]
+; will output:
+ooooo
+
+;
+; Functions
+;
+; function example
+twice: function [a [integer!] /one return: [integer!]][
+ c: 2
+ a: a * c
+ either one [a + 1][a]
+]
+b: 3
+print twice b ; will output 6.
+
+; Import external files with #include and filenames start with a % sign
+#include %includefile.red
+; Now the functions in the included file can be used too.
+
+```
+
+## Further Reading
+
+The main source for information about Red is the [Red language homepage](http://www.red-lang.org).
+
+The source can be found on [github](https://github.com/red/red).
+
+The Red/System language specification can be found [here](http://static.red-lang.org/red-system-specs-light.html).
+
+To learn more about Rebol and Red join the [chat on StackOverflow](http://chat.stackoverflow.com/rooms/291/rebol-and-red). You will need 20 points to chat but if you ask or answer questions about Red or Rebol we will help you get those points. And if that is not working for you drop a mail to us on the [Red mailing list](mailto: red-langNO_SPAM@googlegroups.com) (remove NO_SPAM).
+
+Maybe you want to try Red right away? That is possible on the [try Rebol and Red site](http://tryrebol.esperconsultancy.nl).
+
+You can also learn Red by learning some [Rebol](http://www.rebol.com/docs.html).
diff --git a/ro-ro/bash-ro.html.markdown b/ro-ro/bash-ro.html.markdown
new file mode 100644
index 00000000..debeb67a
--- /dev/null
+++ b/ro-ro/bash-ro.html.markdown
@@ -0,0 +1,177 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Darren Lin", "https://github.com/CogBear"]
+ - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
+ - ["Denis Arh", "https://github.com/darh"]
+translators:
+ - ["Adrian Bordinc", "https://github.com/ellimist"]
+lang: ro-ro
+filename: LearnBash-ro.sh
+---
+
+Bash este numele shell-ului unix, care a fost de asemenea distribuit drept shell pentru sistemul de operare GNU si ca shell implicit pentru Linux si Mac OS X.
+Aproape toate exemplele de mai jos pot fi parte dintr-un script sau pot fi executate direct in linia de comanda.
+
+[Citeste mai multe:](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# Prima linie din script se numeste "shebang"
+# care spune systemului cum sa execute scriptul
+# http://en.wikipedia.org/wiki/Shebang_(Unix)
+# Dupa cum te-ai prins deja, comentariile incep cu #.
+# Shebang este de asemenea un comentariu.
+
+# Exemplu simplu de hello world:
+echo Hello world!
+
+# Fiecare comanda incepe pe o linie noua, sau dupa punct si virgula ;
+echo 'Prima linie'; echo 'A doua linie'
+
+# Declararea unei variabile se face astfel:
+VARIABLE="Niste text"
+
+# DAR nu asa:
+VARIABLE = "Niste text"
+# Bash va crede ca VARIABLE este o comanda care trebuie executata si va
+# returna o eroare pentru ca nu va putea fi gasita.
+
+# Folosind variabila:
+echo $VARIABLE
+echo "$VARIABLE"
+echo '$VARIABLE'
+# Atunci cand folosesti variabila, o atribui, o exporti sau altfel,
+# numele ei se scrie fara $.
+# Daca vrei sa folosesti valoarea variabilei, atunci trebuie sa folosesti $.
+# Atentie la faptul ca ' (apostrof) nu va inlocui variabla cu valoarea ei.
+
+# Inlocuirea de caractere in variabile
+echo ${VARIABLE/Some/A}
+# Asta va inlocui prima aparitie a "Some" cu "A" in variabila de mai sus.
+
+# Substring dintr-o variabila
+echo ${VARIABLE:0:7}
+# Asta va returna numai primele 7 caractere din variabila.
+
+# Valoarea implicita a unei variabile:
+echo ${FOO:-"ValoareaImplicitaDacaFOOLipsesteSauEGoala"}
+# Asta functioneaza pentru null (FOO=),
+# sir de caractere gol (FOO=""), zero (FOO=0) returneaza 0
+
+# Variabile pre-existente
+echo "Ulima valoare returnata de ultimul program rulat: $?"
+echo "ID-ul procesului (PID) care ruleaza scriptul: $$"
+echo "Numarul de argumente: $#"
+echo "Argumentele scriptului: $@"
+echo "Argumentele scriptului separate in variabile: $1 $2..."
+
+# Citind o valoare din consola
+echo "Care e numele tau?"
+read NAME # Observa faptul ca nu a trebuit sa declaram o variabila noua
+echo Salut, $NAME!
+
+# Avem obisnuita instructiune "if"
+# Foloseste "man test" pentru mai multe informatii
+# despre instructinea conditionala
+if [ $NAME -ne $USER ]
+then
+ echo "Numele tau este username-ul tau"
+else
+ echo "Numele tau nu este username-ul tau"
+fi
+
+# Este de asemenea si executarea conditionala de comenzi
+echo "Intotdeauna executat" || echo "Executat daca prima instructiune esueaza"
+echo "Intotdeauna executat" && echo "Executat daca prima instructiune NU esueaza"
+
+# Expresiile apar in urmatorul format
+echo $(( 10 + 5 ))
+
+# Spre deosebire de alte limbaje de programare bash este un shell - asa ca
+# functioneaza in contextul directorului curent. Poti vedea fisiere si directoare
+# din directorul curent folosind comanda "ls":
+ls
+
+# Aceste comenzi au optiuni care la controleaza executia
+ls -l # Listeaza fiecare fisier si director pe o linie separata
+
+# Rezultatele comenzii anterioare pot fi
+# trimise urmatoarei comenzi drept argument
+# Comanda grep filtreaza argumentele trimise cu sabloane.
+# Astfel putem vedea fiserele .txt din directorul curent.
+ls -l | grep "\.txt"
+
+# De asemenea poti redirectiona o comanda, input si error output
+python2 hello.py < "input.in"
+python2 hello.py > "output.out"
+python2 hello.py 2> "error.err"
+# Output-ul va suprascrie fisierul daca acesta exista.
+# Daca vrei sa fie concatenate poti folosi ">>"
+
+# Comenzile pot fi inlocuite in interiorul altor comenzi folosind $( ):
+# Urmatoarea comanda afiseaza numarul de fisiere
+# si directoare din directorul curent
+echo "Sunt $(ls | wc -l) fisiere aici."
+
+# Acelasi lucru se poate obtine folosind apostrf-ul inversat ``,
+# dar nu pot fi folosite unele in interiorul celorlalte asa ca modalitatea
+# preferata este de a folosi $( )
+echo "Sunt `ls | wc -l` fisiere aici."
+
+# Bash foloseste o instructiune 'case' care functioneaza
+# in mod similar cu instructiunea switch din Java si C++
+case "$VARIABLE" in
+ 0) echo "Este un zero.";;
+ 1) echo "Este un unu.";;
+ *) echo "Nu este null";;
+esac
+
+# Instructiunea for parcurge toate elementele trimise:
+# Continutul variabilei $VARIABLE este printat de 3 ori
+for VARIABLE in {1..3}
+do
+ echo "$VARIABLE"
+done
+
+# while loop:
+while [true]
+do
+ echo "in interiorul iteratiei aici..."
+ break
+done
+
+# De asemenea poti defini functii
+# Definitie:
+function foo ()
+{
+ echo "Argumentele functioneaza ca si argumentele scriptului: $@"
+ echo "Si: $1 $2..."
+ echo "Asta este o functie"
+ return 0
+}
+
+# sau mai simplu
+bar ()
+{
+ echo "Alta metoda de a declara o functie"
+ return 0
+}
+
+# Invocarea unei functii
+foo "Numele meu este: " $NAME
+
+# Sunt o multime de comenzi utile pe care ar trebui sa le inveti:
+tail -n 10 file.txt
+# printeaza ultimele 10 linii din fisierul file.txt
+head -n 10 file.txt
+# printeaza primele 10 linii din fisierul file.txt
+sort file.txt
+# sorteaza liniile din file.txt
+uniq -d file.txt
+# raporteaza sau omite liniile care se repeta, cu -d le raporteaza
+cut -d ',' -f 1 file.txt
+# printeaza doar prima coloana inainte de caracterul ","
+```
diff --git a/ro-ro/python-ro.html.markdown b/ro-ro/python-ro.html.markdown
new file mode 100644
index 00000000..125ba2f4
--- /dev/null
+++ b/ro-ro/python-ro.html.markdown
@@ -0,0 +1,490 @@
+---
+language: python
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Ovidiu Ciule", "https://github.com/ociule"]
+filename: learnpython-ro.py
+lang: ro-ro
+---
+
+Python a fost creat de Guido Van Rossum la începutul anilor '90. Python a devenit astăzi unul din
+cele mai populare limbaje de programare. M-am indrăgostit de Python pentru claritatea sa sintactică.
+Python este aproape pseudocod executabil.
+
+Opinia dumneavoastră este binevenită! Puteţi sa imi scrieţi la [@ociule](http://twitter.com/ociule) sau ociule [at] [google's email service]
+
+Notă: Acest articol descrie Python 2.7, dar este util şi pentru Python 2.x. O versiune Python 3 va apărea
+în curând, în limba engleză mai întâi.
+
+```python
+# Comentariile pe o singură linie încep cu un caracter diez.
+""" Şirurile de caractere pe mai multe linii pot fi încadrate folosind trei caractere ", şi sunt des
+ folosite ca şi comentarii pe mai multe linii.
+"""
+
+####################################################
+## 1. Operatori şi tipuri de date primare
+####################################################
+
+# Avem numere
+3 #=> 3
+
+# Matematica se comportă cum ne-am aştepta
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Împărţirea este un pic surprinzătoare. Este de fapt împărţire pe numere întregi şi rotunjeşte
+# automat spre valoarea mai mică
+5 / 2 #=> 2
+
+# Pentru a folosi împărţirea fără rest avem nevoie de numere reale
+2.0 # Acesta e un număr real
+11.0 / 4.0 #=> 2.75 ahhh ... cum ne aşteptam
+
+# Ordinea operaţiilor se poate forţa cu paranteze
+(1 + 3) * 2 #=> 8
+
+# Valoriile boolene sunt şi ele valori primare
+True
+False
+
+# Pot fi negate cu operatorul not
+not True #=> False
+not False #=> True
+
+# Egalitatea este ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Inegalitate este !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Comparaţii
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Comparaţiile pot fi inlănţuite!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Şirurile de caractere pot fi încadrate cu " sau '
+"Acesta e un şir de caractere."
+'Şi acesta este un şir de caractere.'
+
+# Şirurile de caractere pot fi adăugate!
+"Hello " + "world!" #=> "Hello world!"
+
+# Un şir de caractere poate fi folosit ca o listă
+"Acesta e un şir de caractere"[0] #=> 'A'
+
+# Caracterul % (procent) poate fi folosit pentru a formata şiruri de caractere :
+"%s pot fi %s" % ("şirurile", "interpolate")
+
+# O metodă mai nouă de a formata şiruri este metoda "format"
+# Este metoda recomandată
+"{0} pot fi {1}".format("şirurile", "formatate")
+# Puteţi folosi cuvinte cheie dacă nu doriţi sa număraţi
+"{nume} vrea să mănânce {fel}".format(nume="Bob", fel="lasagna")
+
+# "None", care reprezintă valoarea nedefinită, e un obiect
+None #=> None
+
+# Nu folosiţi operatorul == pentru a compara un obiect cu None
+# Folosiţi operatorul "is"
+"etc" is None #=> False
+None is None #=> True
+
+# Operatorul "is" testeaza dacă obiectele sunt identice.
+# Acastă operaţie nu e foarte folositoare cu tipuri primare,
+# dar e foarte folositoare cu obiecte.
+
+# None, 0, şi şiruri de caractere goale sunt evaluate ca si fals, False.
+# Toate celelalte valori sunt adevărate, True.
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variabile şi colecţii
+####################################################
+
+# Printarea este uşoară
+print "Eu sunt Python. Încântat de cunoştinţă!"
+
+
+# Nu este nevoie sa declari variabilele înainte de a le folosi
+o_variabila = 5 # Convenţia este de a folosi caractere_minuscule_cu_underscore
+o_variabila #=> 5
+
+# Dacă accesăm o variabilă nefolosită declanşăm o excepţie.
+# Vezi secţiunea Control de Execuţie pentru mai multe detalii despre excepţii.
+alta_variabila # Declanşează o eroare de nume
+
+# "If" poate fi folosit într-o expresie.
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listele sunt folosite pentru colecţii
+li = []
+# O listă poate avea valori de la început
+alta_li = [4, 5, 6]
+
+# Se adaugă valori la sfârşitul lister cu append
+li.append(1) #li e acum [1]
+li.append(2) #li e acum [1, 2]
+li.append(4) #li e acum [1, 2, 4]
+li.append(3) #li este acum [1, 2, 4, 3]
+# Se şterg de la sfarşit cu pop
+li.pop() #=> 3 şi li e acum [1, 2, 4]
+# Să o adaugăm înapoi valoarea
+li.append(3) # li e din nou [1, 2, 4, 3]
+
+# Putem accesa valorile individuale dintr-o listă cu operatorul index
+li[0] #=> 1
+# Valoarea speciala -1 pentru index accesează ultima valoare
+li[-1] #=> 3
+
+# Dacă depaşim limitele listei declanşăm o eroare IndexError
+li[4] # Declanşează IndexError
+
+# Putem să ne uităm la intervale folosind sintaxa de "felii"
+# În Python, intervalele sunt închise la început si deschise la sfârşit.
+li[1:3] #=> [2, 4]
+# Fără început
+li[2:] #=> [4, 3]
+# Fără sfarşit
+li[:3] #=> [1, 2, 4]
+
+# Putem şterge elemente arbitrare din lista cu operatorul "del" care primeşte indexul lor
+del li[2] # li e acum [1, 2, 3]
+
+# Listele pot fi adăugate
+li + alta_li #=> [1, 2, 3, 4, 5, 6] - Notă: li si alta_li nu sunt modificate!
+
+# Concatenăm liste cu "extend()"
+li.extend(alta_li) # Acum li este [1, 2, 3, 4, 5, 6]
+
+# Se verifică existenţa valorilor in lista cu "in"
+1 in li #=> True
+
+# Şi lungimea cu "len()"
+len(li) #=> 6
+
+
+# Tuplele sunt ca şi listele dar imutabile
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Declanşează TypeError
+
+# Pot fi folosite ca şi liste
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Tuplele pot fi despachetate
+a, b, c = (1, 2, 3) # a este acum 1, b este acum 2 şi c este acum 3
+# Tuplele pot fi folosite şi fără paranteze
+d, e, f = 4, 5, 6
+# Putem inversa valori foarte uşor!
+e, d = d, e # d este acum 5 şi e este acum 4
+
+
+# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
+dict_gol = {}
+# Şi un dicţionar cu valori
+dict_cu_valori = {"unu": 1, "doi": 2, "trei": 3}
+
+# Căutaţi valori cu []
+dict_cu_valori["unu"] #=> 1
+
+# Obţinem lista cheilor cu "keys()"
+dict_cu_valori.keys() #=> ["trei", "doi", "unu"]
+# Notă - ordinea cheilor obţinute cu keys() nu este garantată.
+# Puteţi obţine rezultate diferite de exemplul de aici.
+
+# Obţinem valorile cu values()
+dict_cu_valori.values() #=> [3, 2, 1]
+# Notă - aceeaşi ca mai sus, aplicată asupra valorilor.
+
+# Verificăm existenţa unei valori cu "in"
+"unu" in dict_cu_valori #=> True
+1 in dict_cu_valori #=> False
+
+# Accesarea unei chei care nu exista declanşează o KeyError
+dict_cu_valori["four"] # KeyError
+
+# Putem folosi metoda "get()" pentru a evita KeyError
+dict_cu_valori.get("one") #=> 1
+dict_cu_valori.get("four") #=> None
+# Metoda get poate primi ca al doilea argument o valoare care va fi returnată
+# când cheia nu este prezentă.
+dict_cu_valori.get("one", 4) #=> 1
+dict_cu_valori.get("four", 4) #=> 4
+
+# "setdefault()" este o metodă pentru a adăuga chei-valori fără a le modifica, dacă cheia există deja
+dict_cu_valori.setdefault("five", 5) #dict_cu_valori["five"] este acum 5
+dict_cu_valori.setdefault("five", 6) #dict_cu_valori["five"] exista deja, nu este modificată, tot 5
+
+
+# Set este colecţia mulţime
+set_gol = set()
+# Putem crea un set cu valori
+un_set = set([1,2,2,3,4]) # un_set este acum set([1, 2, 3, 4]), amintiţi-vă ca mulţimile garantează unicatul!
+
+# În Python 2.7, {} poate fi folosit pentru un set
+set_cu_valori = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Putem adăuga valori cu add
+set_cu_valori.add(5) # set_cu_valori este acum {1, 2, 3, 4, 5}
+
+# Putem intersecta seturi
+alt_set = {3, 4, 5, 6}
+set_cu_valori & alt_set #=> {3, 4, 5}
+
+# Putem calcula uniunea cu |
+set_cu_valori | alt_set #=> {1, 2, 3, 4, 5, 6}
+
+# Diferenţa între seturi se face cu -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Verificăm existenţa cu "in"
+2 in set_cu_valori #=> True
+10 in set_cu_valori #=> False
+
+
+####################################################
+## 3. Controlul Execuţiei
+####################################################
+
+# O variabilă
+o_variabila = 5
+
+# Acesta este un "if". Indentarea este importanta în python!
+# Printează "o_variabila este mai mică ca 10"
+if o_variabila > 10:
+ print "o_variabila e mai mare ca 10."
+elif o_variabila < 10: # Clauza elif e opţională.
+ print "o_variabila este mai mică ca 10."
+else: # Şi else e opţional.
+ print "o_variabila este exact 10."
+
+
+"""
+Buclele "for" pot fi folosite pentru a parcurge liste
+Vom afişa:
+ câinele este un mamifer
+ pisica este un mamifer
+ şoarecele este un mamifer
+"""
+for animal in ["câinele", "pisica", "şoarecele"]:
+ # Folosim % pentru a compune mesajul
+ print "%s este un mamifer" % animal
+
+"""
+"range(număr)" crează o lista de numere
+de la zero la numărul dat
+afişează:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While repetă pana când condiţia dată nu mai este adevărată.
+afişează:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Prescurtare pentru x = x + 1
+
+# Recepţionăm excepţii cu blocuri try/except
+
+# Acest cod e valid in Python > 2.6:
+try:
+ # Folosim "raise" pentru a declanşa o eroare
+ raise IndexError("Asta este o IndexError")
+except IndexError as e:
+ pass # Pass nu face nimic. În mod normal aici ne-am ocupa de eroare.
+
+
+####################################################
+## 4. Funcţii
+####################################################
+
+# Folosim "def" pentru a defini funcţii
+def add(x, y):
+ print "x este %s şi y este %s" % (x, y)
+ return x + y # Funcţia poate returna valori cu "return"
+
+# Apelăm funcţia "add" cu parametrii
+add(5, 6) #=> Va afişa "x este 5 şi y este 6" şi va returna 11
+
+# Altă cale de a apela funcţii: cu parametrii numiţi
+add(y=6, x=5) # Ordinea parametrilor numiţi nu contează
+
+# Putem defini funcţii care primesc un număr variabil de parametrii nenumiţi
+# Aceşti parametrii nenumiţi se cheamă si poziţinali
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# Şi putem defini funcţii care primesc un număr variabil de parametrii numiţi
+def keyword_args(**kwargs):
+ return kwargs
+
+# Hai să vedem cum merge
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Se pot combina
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) va afişa:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Când apelăm funcţii, putem face inversul args/kwargs!
+# Folosim * pentru a expanda tuple şi ** pentru a expanda kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # echivalent cu foo(1, 2, 3, 4)
+all_the_args(**kwargs) # echivalent cu foo(a=3, b=4)
+all_the_args(*args, **kwargs) # echivalent cu foo(1, 2, 3, 4, a=3, b=4)
+
+# În Python, funcţiile sunt obiecte primare
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Funcţiile pot fi anonime
+(lambda x: x > 2)(3) #=> True
+
+# Există funcţii de ordin superior (care operează pe alte funcţii) predefinite
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Putem folosi scurtături de liste pentru a simplifica munca cu map si filter
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. Clase
+####################################################
+
+# Moştenim object pentru a crea o nouă clasă
+class Om(object):
+
+ # Acesta este un atribut al clasei. Va fi moştenit de toate instanţele.
+ species = "H. sapiens"
+
+ # Constructor (mai degrabă, configurator de bază)
+ def __init__(self, nume):
+ # Valoarea parametrului este stocată in atributul instanţei
+ self.nume = nume
+
+ # Aceasta este o metoda a instanţei.
+ # Toate metodele primesc "self" ca si primul argument.
+ def spune(self, mesaj):
+ return "%s: %s" % (self.nume, mesaj)
+
+ # O metodă a clasei. Este partajată de toate instanţele.
+ # Va primi ca si primul argument clasa căreia îi aparţine.
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # O metoda statica nu primeste un argument automat.
+ @staticmethod
+ def exclama():
+ return "*Aaaaaah*"
+
+
+# Instanţiem o clasă
+i = Om(nume="Ion")
+print i.spune("salut") # afişează: "Ion: salut"
+
+j = Om("George")
+print j.spune("ciau") # afişează George: ciau"
+
+# Apelăm metoda clasei
+i.get_species() #=> "H. sapiens"
+
+# Modificăm atributul partajat
+Om.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Apelăm metoda statică
+Om.exclama() #=> "*Aaaaaah*"
+
+
+####################################################
+## 6. Module
+####################################################
+
+# Pentru a folosi un modul, trebuie importat
+import math
+print math.sqrt(16) #=> 4
+
+# Putem importa doar anumite funcţii dintr-un modul
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Putem importa toate funcţiile dintr-un modul, dar nu este o idee bună
+# Nu faceţi asta!
+from math import *
+
+# Numele modulelor pot fi modificate la import, de exemplu pentru a le scurta
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Modulele python sunt pur şi simplu fişiere cu cod python.
+# Puteţi sa creaţi modulele voastre, şi sa le importaţi.
+# Numele modulului este acelasi cu numele fişierului.
+
+# Cu "dir" inspectăm ce funcţii conţine un modul
+import math
+dir(math)
+
+
+```
+
+## Doriţi mai mult?
+
+### Gratis online, în limba engleză
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Cărţi, în limba engleză
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/ro-ro/ruby-ro.html.markdown b/ro-ro/ruby-ro.html.markdown
new file mode 100644
index 00000000..12672b68
--- /dev/null
+++ b/ro-ro/ruby-ro.html.markdown
@@ -0,0 +1,491 @@
+---
+language: ruby
+contributors:
+ - ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
+ - ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+translators:
+ - ["Adrian Bordinc", "https://github.com/ellimist"]
+filename: learnruby-ro.rb
+lang: ro-ro
+---
+
+```ruby
+# Acesta este un comentariu
+
+=begin
+Acesta este un comentariu pe mai multe linii
+Nimeni nu le foloseste
+Si nici tu nu ar trebui sa o faci
+=end
+
+# In primul rand: totul este un obiect
+
+# Numerele sunt obiecte
+
+3.class #=> Fixnum
+
+3.to_s #=> "3"
+
+
+# Aritmetica de baza
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Aritmetica este doar "zahar sintactic"
+# pentru a putea chema metode pe un obiect
+1.+(3) #=> 4
+10.* 5 #=> 50
+
+# Valorile speciale sunt obiecte
+nil # Nimic
+true # true
+false # false
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Egalitate
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Inegalitate
+1 != 1 #=> false
+2 != 1 #=> true
+!true #=> false
+!false #=> true
+
+# Excluzand "false", "nil" este singura valoare "falsa"
+
+!nil #=> true
+!false #=> true
+!0 #=> false
+
+# Mai multe comparatii
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Sirurule de caractere sunt obiecte
+
+'Sunt un sir de caractere'.class #=> String
+"Si eu sunt un sir de caractere".class #=> String
+
+fi_inlocuit = "fi inlocuit"
+"Pot #{fi_inlocuit} atunci cand folosesc dublu apostrof"
+#=> "Pot fi inlocuit atunci cand folosesc dublu apostrof"
+
+
+# Printeaza
+puts "Afisez rezultate!"
+
+# Variabile
+x = 25 #=> 25
+x #=> 25
+
+# Retineti faptul ca atribuire unei valori, o si returneaza pe aceasta
+# Asta inseamna ca poti sa faci atribuire multipla:
+
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# Prin conventie se foloseste "snake_case" in denumirea variabilelor
+snake_case = true
+
+# Folositi nume descriptive pentru variablie
+adresa_radacina_proiect = '/nume/bun/'
+adresa = '/nume/nu atat de bun/'
+
+# Simbolurile (sunt obiecte)
+# Simbolurile sunt constante imutabile, reutilizabile, reprezentate intern
+# de o valoare numerica. Sunt deseori folosite in locul sirurilor de caractere
+# pentru a da un nume reprezentativ unei valori
+
+:exemplu_simbol.class #=> Symbol
+
+status = :exemplu_simbol
+
+status == :exemplu_simbol #=> adevarat
+
+status == 'exemplu_simbol' #=> fals
+
+status == :aprobat #=> fals
+
+# Vectori
+
+# Acesta este un vector
+vector = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# Vectorii pot contine diferite tipuri de date
+
+[1, "salut", false] #=> [1, "salut", false]
+
+# Vectorii pot fi indexati
+# de la inceput
+vector[0] #=> 1
+vector[12] #=> nil
+
+# Ca si aritmetica, accessul [valoare]
+# este doar "zahar sintactic"
+# pentru a chema metoda [] a unui obiect
+vector.[] 0 #=> 1
+vector.[] 12 #=> nil
+
+# De la sfarsit
+vector[-1] #=> 5
+
+# Cu un index de inceput si o lungime
+vector[2, 3] #=> [3, 4, 5]
+
+# Sau cu un interval
+vector[1..3] #=> [2, 3, 4]
+
+# Adauga elemente intr-un vector in felul urmator:
+vector << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Hash-urile sunt dictionarele din Ruby cu perechi cheie/valoare.
+# Hash-urile sunt notate cu acolade
+hash = {'culoare' => 'verde', 'numar' => 5}
+
+hash.keys #=> ['culoare', 'numar']
+
+# Poti lua valoare unui element dintr-un hash foarte rapid folosind cheia
+hash['culoare'] #=> 'verde'
+hash['numar'] #=> 5
+
+# Incercand sa accesezi un element dintr-un hash
+# printr-o cheie care nu exista va returna "nil".
+hash['nimic_aici'] #=> nil
+
+# Incepand cu Ruby 1.9, este o sintaxa speciala
+# pentru atunci cand se folosesc simboluri drept chei:
+
+hash_nou = { defcon: 3, actiune: true}
+
+hash_now.keys #=> [:defcon, :actiune]
+
+# Pont: Atat vectorii (Array) si hash-urile (Hash) sunt enumerabile (Enumerable)
+# Ele impart o multime de metode utile precum each, map, count si altele
+
+
+# Structuri de control
+
+if true
+ "instructiune if"
+elsif false
+ "else if, optional"
+else
+ "else, de asemenea optional"
+end
+
+for numar in 1..5
+ puts "iteratia #{numar}"
+end
+#=> iteratia 1
+#=> iteratia 2
+#=> iteratia 3
+#=> iteratia 4
+#=> iteratia 5
+
+# TOTUSI, Nici una nu foloseste instructiunea for
+# In locul acesteia ar trebui sa folosesti metoda "each" si sa ii trimiti un block
+# Un bloc este o bucata de cod pe care o poti trimite unei metode precum "each".
+# Este analog pentru "lambda", functii anonime,
+# sau closures in alte limbaje de programare.
+#
+# Metoda "each" a unui interval, ruleaza block-ul o data
+# pentru fiecare element din interval.
+# Block-ul primeste ca si parametru un index
+# Invocand metoda "each" cu un block, arata in urmatorul fel:
+
+(1..5).each do |index|
+ puts "iteratia #{index}"
+end
+#=> iteratia 1
+#=> iteratia 2
+#=> iteratia 3
+#=> iteratia 4
+#=> iteratia 5
+
+# Poti de asemenea sa pui block-ul intre acolade
+(1..5).each {|index| puts "iteratia #{index}"}
+
+# Continutul unei structuri de date poate fi parcurs folosind "each".
+array.each do |element|
+ puts "#{element} parte din vector"
+end
+hash.each do |cheie, valoare|
+ puts "#{cheie} este #{valoare}"
+end
+
+index = 1
+while index <= 5 do
+ puts "iteratia #{index}"
+ index += 1
+end
+#=> iteratia 1
+#=> iteratia 2
+#=> iteratia 3
+#=> iteratia 4
+#=> iteratia 5
+
+nota = 'B'
+
+case nota
+when 'A'
+ puts "Bravo pustiule!"
+when 'B'
+ puts "Mai mult noroc data viitoare"
+when 'C'
+ puts "Poti mai mult"
+when 'D'
+ puts "Incet, incet..."
+when 'F'
+ puts "Ai esuat!"
+else
+ puts "Sistem de notare alternativ?!"
+end
+
+# Functii
+
+def dublu(x)
+ x * 2
+end
+
+# Functille (si toate block-urile)
+# returneaza implicit valoarea ultimei instructiuni
+dublu(2) #=> 4
+
+# Parantezele sunt optionale cand rezultatul nu este ambiguu
+dublu 3 #=> 6
+
+dublu dublu 3 #=> 12
+
+def suma(x,y)
+ x + y
+end
+
+# Argumentele metodei sunt separate printr-o virgula
+suma 3, 4 #=> 7
+
+suma suma(3,4), 5 #=> 12
+
+# yield
+# Toate metodele au un parametru block, implicit si optional
+# care poate fi invocat folosit cuvantul cheie 'yield'
+
+def incercuieste
+ puts "{"
+ yield
+ puts "}"
+end
+
+incercuieste { puts 'Salut Mihai!' }
+
+# {
+# Salut Mihai!
+# }
+
+
+# Poti trimite un block unei functii.
+# "&" marcheaza o referinta trimisa unui block
+def vizitatori(&block)
+ block.call "un_parametru"
+end
+
+# Poti trimite o lista de argumente, care va fi convertita intr-un vector (array).
+# Pentru asta se foloseste ("*")
+def vizitatori(*vector)
+ vector.each { |vizitator| puts "#{vizitator}" }
+end
+
+# Defineste o clasa folosind cuvantul cheie "class"
+class Om
+
+ # O variabila apartinand clasei. Este folosita in toate instantele clasei
+ @@specie = "H. sapiens"
+
+ # Constructor
+ def initialize(nume, varsta=0)
+ # Atribuie argumentul, variabilei "nume", care apartine doar unei instante
+ @nume = nume
+ # Daca varsta nu este data, o sa ii atribuim valoarea implicita
+ # din lista de argumente (0, in cazul nostru)
+ @varsta = varsta
+ end
+
+ # Metoda pentru a seta valoarea unei variabile
+ def nume=(nume)
+ @nume = nume
+ end
+
+ # Metoda pentru a lua valoarea unei variabile
+ def nume
+ @nume
+ end
+
+ # Functionalitatea de mai sus poate fi obtinuta
+ # folosing metoda "attr_accessor" dupa cum urmeaza:
+ attr_accessor :nume
+
+ # Metodele pentru a lua si a seta valoarea unei variabile
+ # pot fi de asemenea obtinute individial:
+ attr_reader :nume
+ attr_writer :nume
+
+ # O metoda apartinand unei clase foloseste "self" pentru a se diferentia
+ # de metodele unei instante ale clasei respective
+ # Poate fi invocata doar pe clasa, si nu pe o instanta a acesteia
+ def self.spune(msg)
+ puts "#{msg}"
+ end
+
+ def specie
+ @@specie
+ end
+
+end
+
+
+# Creaza o instanta a unei clase
+ion = Om.new("Ionut Popescu")
+
+eugen = Om.new("Eugen Ionescu")
+
+# Sa invocam niste metode
+ion.specie #=> "H. sapiens"
+ion.nume #=> "Ionut Popescu"
+ion.nume = "Ionut Popescu JR." #=> "Ionut Popescu JR."
+ion.nume #=> "Ionut Popescu JR."
+eugen.specie #=> "H. sapiens"
+eugen.nume #=> "Eugen Ionescu"
+
+# Invoca o metoda a unei clase
+Om.spune("Salut") #=> "Salut"
+
+
+# Scopul unei variabile este definit de modul in care le numim
+# Variabilele care incep cu $ au scop global
+$var = "Sunt o variabila globala"
+defined? $var #=> "global-variable"
+
+# Variabilele care incep cu @ apartin unei instante
+@var = "Sunt o variabila a unei instante"
+defined? @var #=> "instance-variable"
+
+# Variabilele care incep cu @@ apartin unei clase
+@@var = "Sunt variabila unei clase"
+defined? @@var #=> "class variable"
+
+# Variabilele care incep cu litera mare sunt constante
+Var = "Sunt o constanta"
+defined? Var #=> "constant"
+
+# Clasele sunt de asemenea obiecte in ruby. Astfel incat clasele
+# pot avea variabile care apartin unei instante
+# O variabila care apartine unei clase poate fi accesata de toate
+# instantele acesteia si de clasele care o extind
+
+# clasa parinte
+class Om
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(valoare)
+ @@foo = valoare
+ end
+end
+
+# clasa copil
+class Muncitor < Om
+end
+
+Om.foo # 0
+Muncitor.foo # 0
+
+Om.foo = 2 # 2
+Muncitor.foo # 2
+
+# Variabilele care apartin unei instante ale unei clase,
+# nu sunt impartite de (copii acesteia) clasele care o extind
+class Om
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(valoare)
+ @bar = valoare
+ end
+end
+
+class Doctor < Om
+end
+
+Om.bar # 0
+Doctor.bar # nil
+
+module ExempluModul
+ def foo
+ 'foo'
+ end
+end
+
+# Incluzand modulul instantei unui obiect
+# Extinzand modulul unei instante ale unei clase
+
+class Persoana
+ include ExempluModul
+end
+
+class Carte
+ extend ExempluModul
+end
+
+Persoana.foo # => NoMethodError: undefined method `foo' for Persoana:Class
+Persoana.new.foo # => 'foo'
+Carte.foo # => 'foo'
+Carte.new.foo # => NoMethodError: undefined method `foo'
+
+# Callbacks atunci cand includerea si extinderea unui modul sunt executate
+
+module ModulExempluCallBack
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class CevaRelevant
+ include ModulExempluCallBack
+end
+
+CevaRelevant.bar # => 'bar'
+CevaRelevant.qux # => NoMethodError: undefined method `qux'
+CevaRelevant.new.bar # => NoMethodError: undefined method `bar'
+CevaRelevant.new.qux # => 'qux'
+```
diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown
new file mode 100644
index 00000000..5988b159
--- /dev/null
+++ b/ru-ru/c-ru.html.markdown
@@ -0,0 +1,483 @@
+---
+language: c
+filename: learnc-ru.c
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+ - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
+translators:
+ - ["Evlogy Sutormin", "http://evlogii.com"]
+lang: ru-ru
+---
+
+Что ж, Си всё ещё является лидером среди современных высокопроизводительных языков.
+
+Для большинствоа программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали,
+но этот язык даёт больше, чем просто повышение производительности.
+Держите это руководство в памяти и вы сможете использовать Си максимально эффективно.
+
+```c
+// Однострочный комментарий начинается с // - доступен только после С99.
+
+/*
+Многострочный комментарий выглядит так. Работает начиная с С89.
+*/
+
+// Импорт файлов происходит с помощью **#include**
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// Файлы <в угловых скобочках> будут подключаться из стандартной библиотеки.
+// Свои файлы необходимо подключать с помощью "двойных кавычек".
+#include "my_header.h"
+
+// Объявление функций должно происходить в .h файлах или вверху .c файла.
+void function_1();
+void function_2();
+
+// Точка входа в программу – это функция main.
+int main() {
+ // для форматированного вывода в консоль используется printf
+ // %d – означает, что будем выводить целое число, \n переводит указатель вывода
+ // на новую строчку
+ printf("%d\n", 0); // => напечатает "0"
+ // Каждый оператор заканчивается точкой с запятой.
+
+ ///////////////////////////////////////
+ // Типы
+ ///////////////////////////////////////
+
+ // int обычно имеет длину 4 байта
+ int x_int = 0;
+
+ // short обычно имеет длину 2 байта
+ short x_short = 0;
+
+ // char гарантированно имеет длину 1 байта
+ char x_char = 0;
+ char y_char = 'y'; // Символьные литералы заключаются в кавычки ''
+
+ // long как правило занимает от 4 до 8 байт
+ // long long занимает как минимум 64 бита
+ long x_long = 0;
+ long long x_long_long = 0;
+
+ // float это 32-битное число с плавающей точкой
+ float x_float = 0.0;
+
+ // double это 64-битное число с плавающей точкой
+ double x_double = 0.0;
+
+ // Целые типы могут быть беззнаковыми.
+ unsigned short ux_short;
+ unsigned int ux_int;
+ unsigned long long ux_long_long;
+
+ // sizeof(T) возвращает размер переменной типа Т в байтах.
+ // sizeof(obj) возвращает размер объекта obj в байтах.
+ printf("%zu\n", sizeof(int)); // => 4 (на большинстве машин int занимает 4 байта)
+
+ // Если аргуметом sizeof будет выражение, то этот аргумент вычисляется
+ // ещё во время компиляции кода (кроме динамических массивов).
+ int a = 1;
+ // size_t это беззнаковый целый тип который использует как минимум 2 байта
+ // для записи размера объекта
+ size_t size = sizeof(a++); // a++ не выполнится
+ printf("sizeof(a++) = %zu, где a = %d\n", size, a);
+ // выведет строку "sizeof(a++) = 4, где a = 1" (на 32-битной архитектуре)
+
+ // Можно задать размер массива при объявлении.
+ char my_char_array[20]; // Этот массив занимает 1 * 20 = 20 байт
+ int my_int_array[20]; // Этот массив занимает 4 * 20 = 80 байт (сумма 4-битных слов)
+
+ // Можно обнулить массив при объявлении.
+ char my_array[20] = {0};
+
+ // Индексация массива происходит также как и в других Си-подобных языках.
+ my_array[0]; // => 0
+
+ // Массивы изменяемы. Это просто память как и другие переменные.
+ my_array[1] = 2;
+ printf("%d\n", my_array[1]); // => 2
+
+ // В C99 (а также опционально в C11), массив может быть объявлен динамически.
+ // Размер массива не обязательно должен быть рассчитан на этапе компиляции.
+ printf("Enter the array size: "); // спрашиваем юзера размер массива
+ char buf[0x100];
+ fgets(buf, sizeof buf, stdin);
+ size_t size = strtoul(buf, NULL, 10); // strtoul парсит строку в беззнаковое целое
+ int var_length_array[size]; // объявление динамического массива
+ printf("sizeof array = %zu\n", sizeof var_length_array);
+ // Вывод программы (в зависимости от архитектуры) будет таким:
+ // > Enter the array size: 10
+ // > sizeof array = 40
+
+ // Строка – это просто массив символов, оканчивающийся нулевым (NUL (0x00)) байтом
+ // представляемым в строке специальным символом '\0'.
+ // Нам не нужно вставлять нулевой байт в строковой литерал,
+ // компилятор всё сделает за нас.
+ char a_string[20] = "This is a string";
+ printf("%s\n", a_string); // %s обозначает вывод строки
+
+ printf("%d\n", a_string[16]); // => 0
+ // байт #17 тоже равен 0 (а также 18, 19, и 20)
+
+ // Если между одинарными кавычками есть символ – это символьный литерал,
+ // но это тип int, а не char (по историческим причинам).
+
+ int cha = 'a'; // хорошо
+ char chb = 'a'; // тоже хорошо (подразумевается преобразование int в char)
+
+ ///////////////////////////////////////
+ // Операторы
+ ///////////////////////////////////////
+
+ // Можно использовать множественное объявление.
+ int i1 = 1, i2 = 2;
+ float f1 = 1.0, f2 = 2.0;
+
+ // Арифметика обычная
+ i1 + i2; // => 3
+ i2 - i1; // => 1
+ i2 * i1; // => 2
+ i1 / i2; // => 0 (0.5, но обрезается до 0)
+
+ f1 / f2; // => 0.5, плюс-минус погрешность потому что,
+ // цифры с плавающей точкой вычисляются неточно!
+
+ // Модуль
+ 11 % 3; // => 2
+
+ // Операции сравнения вам уже знакомы, но в Си нет булевого типа.
+ // Вместо него используется int. 0 это false, всё остальное это true.
+ // Операции сравнения всегда возвращают 1 или 0.
+ 3 == 2; // => 0 (false)
+ 3 != 2; // => 1 (true)
+ 3 > 2; // => 1
+ 3 < 2; // => 0
+ 2 <= 2; // => 1
+ 2 >= 2; // => 1
+
+ // Си это не Питон – операции сравнения могут быть только парными.
+ int a = 1;
+ // ОШИБКА:
+ int between_0_and_2 = 0 < a < 2;
+ // Правильно:
+ int between_0_and_2 = 0 < a && a < 2;
+
+ // Логика
+ !3; // => 0 (логическое НЕ)
+ !0; // => 1
+ 1 && 1; // => 1 (логическое И)
+ 0 && 1; // => 0
+ 0 || 1; // => 1 (лигическое ИЛИ)
+ 0 || 0; // => 0
+
+ // Битовые операторы
+ ~0x0F; // => 0xF0 (побитовое отрицание)
+ 0x0F & 0xF0; // => 0x00 (побитовое И)
+ 0x0F | 0xF0; // => 0xFF (побитовое ИЛИ)
+ 0x04 ^ 0x0F; // => 0x0B (исключающее ИЛИ (XOR))
+ 0x01 << 1; // => 0x02 (побитовый сдвиг влево (на 1))
+ 0x02 >> 1; // => 0x01 (побитовый сдвиг вправо (на 1))
+
+ // Будьте осторожны при сдвиге беззнакового int, эти операции не определены:
+ // - сдвиг в знаковый бит у целого числа (int a = 1 << 32)
+ // - сдвиг влево отрицательных чисел (int a = -1 << 2)
+
+ ///////////////////////////////////////
+ // Структуры ветвления
+ ///////////////////////////////////////
+
+ // Условный оператор
+ if (0) {
+ printf("I am never run\n");
+ } else if (0) {
+ printf("I am also never run\n");
+ } else {
+ printf("I print\n");
+ }
+
+ // Цикл с предусловием
+ int ii = 0;
+ while (ii < 10) {
+ printf("%d, ", ii++); // инкрементация происходит после того как
+ // знаечние ii передано ("postincrement")
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ //Цикл с постусловием
+ int kk = 0;
+ do {
+ printf("%d, ", kk);
+ } while (++kk < 10); // инкрементация происходит перед тем как
+ // передаётся знаечние kk ("preincrement")
+ // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ // Цикл со счётчиком
+ int jj;
+ for (jj=0; jj < 10; jj++) {
+ printf("%d, ", jj);
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ // Ветвление с множественным выбором
+ switch (some_integral_expression) {
+ case 0: // значения должны быть целыми константами (и могут быть выражениями)
+ do_stuff();
+ break; // если не написать break; то управление будет передено следующему блоку
+ case 1:
+ do_something_else();
+ break;
+ default:
+ // если не было совпадения, то выполняется блок default:
+ fputs("ошибка!\n", stderr);
+ exit(-1);
+ break;
+ }
+
+ ///////////////////////////////////////
+ // Форматирование вывода
+ ///////////////////////////////////////
+
+ // Каждое выражение в Си имеет тип, но вы можете привести один тип к другому,
+ // если хотите (с некоторыми искажениями).
+
+ int x_hex = 0x01; // Вы можете назначать переменные с помощью шеснадцатеричного кода.
+
+ // Приведение типов будет пытаться сохранять цифровые значения.
+ printf("%d\n", x_hex); // => Prints 1
+ printf("%d\n", (short) x_hex); // => Prints 1
+ printf("%d\n", (char) x_hex); // => Prints 1
+
+ // Типы могут переполняться без вызова предупреждения.
+ printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
+
+ // Для определения максимального значения типов `char`, `signed char` и `unisigned char`,
+ // соответственно используйте CHAR_MAX, SCHAR_MAX и UCHAR_MAX макросы из <limits.h>
+
+ // Целые типы могут быть приведены к вещественным и наоборот.
+ printf("%f\n", (float)100); // %f formats a float
+ printf("%lf\n", (double)100); // %lf formats a double
+ printf("%d\n", (char)100.0);
+
+ ///////////////////////////////////////
+ // Указатели
+ ///////////////////////////////////////
+
+ // Указатель – это переменная которая хранит адрес в памяти.
+ // При объявлении указателя указывается тип данных переменной на которую он будет ссылаться.
+ // Вы можете получить адрес любой переменной, а потом работать с ним.
+
+ // Используйте & для получения адреса переменной.
+ int x = 0;
+ printf("%p\n", (void *)&x); // => Напечатает адрес в памяти, где лежит переменная x
+ // (%p выводит указатель на void *)
+
+ // Для объявления указателя нужно поставить * перед именем.
+ int *px, not_a_pointer; // px это указатель на int
+ px = &x; // сохранит адрес x в px
+ printf("%p\n", (void *)px); // => Напечатает адрес в памяти, где лежит переменная px
+ printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
+ // => Напечатает "8, 4" в 64 битной системе
+
+ // Для того, чтобы получить знаечние по адресу, напечатайте * перед именем.
+ // Да, использование * при объявлении указателя и получении значения по адресу
+ // немного запутано, но вы привыкнете.
+ printf("%d\n", *px); // => Напечаатет 0, значение перемененной x
+
+ // Вы также можете изменять значение, на которое указывает указатель.
+ (*px)++; // Инкрементирует значение на которое указывает px на единицу
+ printf("%d\n", *px); // => Напечатает 1
+ printf("%d\n", x); // => Напечатает 1
+
+ // Массивы удобно использовать для болшого количества однотипных данных.
+ int x_array[20];
+ int xx;
+ for (xx = 0; xx < 20; xx++) {
+ x_array[xx] = 20 - xx;
+ } // Объявление x_array с значениями 20, 19, 18,... 2, 1
+
+ // Объявление указателя на int с адресом массива.
+ int* x_ptr = x_array;
+ // x_ptr сейчас указывает на первый элемент массива (со значением 20).
+ // Это рабоатет, потому что имя массива возвращает указатель на первый элемент.
+ // Например, когда массив передаётся в функцию или назначается указателю, он
+ // невявно преобразуется в указатель.
+ // Исключения: когда массив является аргументом для оператор '&':
+ int arr[10];
+ int (*ptr_to_arr)[10] = &arr; // &arr не является 'int *'!
+ // он является "указателем на массив" (из десяти 'int'ов).
+ // или когда массив это строчный литерал, используемый при объявлении массива символов:
+ char arr[] = "foobarbazquirk";
+ // или когда массив является аргументом `sizeof` или `alignof` операторов:
+ int arr[10];
+ int *ptr = arr; // то же самое что и "int *ptr = &arr[0];"
+ printf("%zu %zu\n", sizeof arr, sizeof ptr); // напечатает "40, 4" или "40, 8"
+
+ // Декрементация и инкрементация указателей зависит от их типа
+ // (это называется арифметика указателей)
+ printf("%d\n", *(x_ptr + 1)); // => Напечатает 19
+ printf("%d\n", x_array[1]); // => Напечатает 19
+
+ // Вы также можете динамически выделять несколько блоков памяти с помощью
+ // функции malloc из стандартной библиотеки, которая принимает один
+ // аргумент типа size_t – количество байт необходимых для выделения.
+ int *my_ptr = malloc(sizeof(*my_ptr) * 20);
+ for (xx = 0; xx < 20; xx++) {
+ *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
+ } // Выделяет память для 20, 19, 18, 17... 2, 1 (как int'ы)
+
+ // Работа с памятью с помощью указателей может давать неожиданные и
+ // непредсказуемые результаты.
+ printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь-знает-что?
+ // Скорей всего программа вылетит.
+
+ // Когда вы закончили работать с памятью, которую ранее выделили, вам необходимо
+ // освободить её, иначе это может вызвать утечку памяти или ошибки.
+ free(my_ptr);
+
+ // Строки это массивы символов, но обычно они представляются как
+ // указатели на символ (как указатели на первый элемент массива).
+ // Хорошей практикой считается использование `const char *' при объявлении
+ // строчного литерала. При таком подходе литерал не может быть изменён.
+ // (например "foo"[0] = 'a' вызовет ошибку!)
+
+ const char *my_str = "This is my very own string literal";
+ printf("%c\n", *my_str); // => 'T'
+
+ // Это не работает, если строка является массивом
+ // (потенциально задаваемой с помощью строкового литерала)
+ // который находиться в перезаписываемой части памяти:
+
+ char foo[] = "foo";
+ foo[0] = 'a'; // это выполнится и строка теперь "aoo"
+
+ void function_1()
+} // конец функции main()
+
+///////////////////////////////////////
+// Функции
+///////////////////////////////////////
+
+// Синтаксис объявления функции:
+// <возвращаемый тип> <имя функции>(аргументы)
+
+int add_two_ints(int x1, int x2) {
+ return x1 + x2; // Используйте return для возврата значения
+}
+
+/*
+Данные в функцию передаются "по значению", но никто не мешает
+вам передавать в функцию указатели и менять данные по указателям.
+
+Например: инвертировать строку прямо в функции
+*/
+
+// void означает, что функция ничего не возвращает
+void str_reverse(char *str_in) {
+ char tmp;
+ int ii = 0;
+ size_t len = strlen(str_in); // `strlen()` является частью стандартной библиотеки
+ for (ii = 0; ii < len / 2; ii++) {
+ tmp = str_in[ii];
+ str_in[ii] = str_in[len - ii - 1]; // ii-тый символ с конца
+ str_in[len - ii - 1] = tmp;
+ }
+}
+
+char c[] = "This is a test.";
+str_reverse(c);
+printf("%s\n", c); // => Выведет ".tset a si sihT"
+
+///////////////////////////////////////
+// Типы и структуры определяемые пользователем
+///////////////////////////////////////
+
+// typedef используется для задания стандартным типам своих названий
+typedef int my_type;
+my_type my_type_var = 0;
+
+// Структуры это просто коллекция данных, память выделяется последовательно,
+// в том порядке в котором записаны данные.
+struct rectangle {
+ int width;
+ int height;
+};
+
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int) – не всегда верно
+// из-за особенностей компиляции (необычное поведение при отступах)[1].
+
+void function_1() {
+ struct rectangle my_rec;
+
+ // Доступ к структурам через точку
+ my_rec.width = 10;
+ my_rec.height = 20;
+
+ // Вы можете объявить указатель на структуру
+ struct rectangle *my_rec_ptr = &my_rec;
+
+ // Можно доступаться к структуре и через указатель
+ (*my_rec_ptr).width = 30;
+
+ // ... или ещё лучше: используйте оператор -> для лучшей читабельночти
+ my_rec_ptr->height = 10; // то же что и "(*my_rec_ptr).height = 10;"
+}
+
+// Вы можете применить typedef к структуре, для удобства.
+typedef struct rectangle rect;
+
+int area(rect r) {
+ return r.width * r.height;
+}
+
+// Если вы имеете большую структуру, можно доступаться к ней "по указателю",
+// чтобы избежать копирования всей структуры.
+int area(const rect *r) {
+ return r->width * r->height;
+}
+
+///////////////////////////////////////
+// Указатели на функции
+///////////////////////////////////////
+
+/*
+Во время исполнения функции находятся по известным адресам в памяти.
+Указатель на функцию может быть использован для непосредственного вызова функции.
+Однако синтаксис может сбивать с толку.
+
+Пример: использование str_reverse по указателю
+*/
+
+void str_reverse_through_pointer(char *str_in) {
+ // Определение функции через указатель.
+ void (*f)(char *); // Сигнатура должна полность совпадать с целевой функцией.
+ f = &str_reverse; // Присвоить фактический адрес (во время исполнения)
+ // "f = str_reverse;" тоже будет работать.
+ //Имя функции (как и массива) возвращает указатель на начало.
+ (*f)(str_in); // Просто вызываем функцию через указатель.
+ // "f(str_in);" или вот так
+}
+```
+
+## На почитать
+
+Лучше всего найдите копию [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
+Это **книга** написанная создателями Си. Но будьте осторожны, она содержит идеи которые больше не считаются хорошими.
+
+Другой хороший ресурс: [Learn C the hard way](http://c.learncodethehardway.org/book/).
+
+Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com).
+
+Очень важно использовать правильные отступы и ставить пробелы в нужных местах.
+Читаемый код лучше чем красивый или быстрый код.
+Чтобы научиться писать хороший код, почитайте [Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
+
+Также не забывайте, что [Google](http://google.com) и [Яндекс](http://yandex.ru) – ваши хорошие друзья.
+
+[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown
new file mode 100644
index 00000000..2f508a00
--- /dev/null
+++ b/ru-ru/clojure-ru.html.markdown
@@ -0,0 +1,427 @@
+---
+language: clojure
+filename: learnclojure-ru.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Alexey Pirogov", "http://twitter.com/alex_pir"]
+lang: ru-ru
+---
+
+Clojure, это представитель семейства Lisp-подобных языков, разработанный
+для Java Virtual Machine. Язык идейно гораздо ближе к чистому
+[функциональному программированию](https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) чем его прародитель Common Lisp, но в то же время обладает набором инструментов для работы с состоянием,
+таких как [STM](https://ru.wikipedia.org/wiki/Software_transactional_memory).
+
+Благодаря такому сочетанию технологий в одном языке, разработка программ,
+предполагающих конкурентное выполнение, значительно упрощается
+и даже может быть автоматизирована.
+
+(Последующие примеры кода предполагают выполнение в Clojure версии 1.2 и выше)
+
+
+```clojure
+; Комментарии начинаются символом ";".
+
+; Код на языке Clojure записывается в виде "форм",
+; которые представляют собой обычные списки элементов, разделенных пробелами,
+; заключённые в круглые скобки
+;
+; Clojure Reader (инструмент языка, отвечающий за чтение исходного кода),
+; анализируя форму, предполагает, что первым элементом формы (т.е. списка)
+; является функция или макрос, который следует вызвать, передав ему
+; в качестве аргументов остальные элементы списка-формы.
+
+; Первым вызовом в файле должен быть вызов функции ns,
+; которая отвечает за выбор текущего пространства имен (namespace)
+(ns learnclojure-ru)
+
+; Несколько простых примеров:
+
+; str объединяет в единую строку все свои аргументы
+(str "Hello" " " "World") ; => "Hello World"
+
+; Арифметика тоже выглядит несложно
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; Проверка на равенство (Equality)
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; Для булевой логики вам может понадобиться not
+(not true) ; => false
+
+; Вложенные формы, конечно же, допустимы и работают вполне предсказуемо
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Типы
+;;;;;;;;;;;;;
+
+; Clojure использует типы Java для представления булевых значений,
+; строк и чисел
+; Узнать тип мы можем, использую функцию `class
+(class 1) ; Целочисленные литералы типа по-умолчанию являются java.lang.Long
+(class 1.) ; Числа с плавающей точкой, это java.lang.Double
+(class "") ; Строки всегда заключаются в двойные кавычки
+ ; и представляют собой java.lang.String
+(class false) ; Булевы значения, это экземпляры java.lang.Boolean
+(class nil) ; "Пустое" значение называется "nil"
+
+; Если Вы захотите создать список из чисел, вы можете просто
+; предварить форму списка символом "'", который подскажет Reader`у,
+; что эта форма не требует вычисления
+'(+ 1 2) ; => (+ 1 2)
+; ("'", это краткая запись формы (quote (+ 1 2))
+
+; "Квотированный" список можно вычислить, передав его функции eval
+(eval '(+ 1 2)) ; => 3
+
+; Коллекции и Последовательности
+;;;;;;;;;;;;;;;;;;;
+
+; Списки (Lists) в clojure структурно представляют собой "связанные списки",
+; тогда как Векторы (Vectors), устроены как массивы.
+; Векторы и Списки тоже являются классами Java!
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; Список может быть записан, как (1 2 3), но в этом случае
+; он будет воспринят reader`ом, как вызов функции.
+; Есть два способа этого избежать:
+; '(1 2 3) - квотирование,
+; (list 1 2 3) - явное конструирование списка с помощью функции list.
+
+; "Коллекции", это некие наборы данных
+; И списки, и векторы являются коллекциями:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; "Последовательности" (seqs), это абстракция над наборами данных,
+; элементы которых "упакованы" последовательно.
+; Списки - последовательности, а вектора - нет.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Любая seq предоставляет доступ только к началу последовательности данных,
+; не предоставляя информацию о её длине.
+; При этом последовательности могут быть и бесконечными,
+; т.к. являются ленивыми и предоставляют данные только по требованию!
+(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)
+
+; reduce поможет "свернуть" коллекцию
+(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-формы в форму вызова)
+((fn [] "Hello World")) ; => "Hello World"
+
+; Назначить значению имя можно специальной формой def
+(def x 1)
+x ; => 1
+
+; Назначить имя можно любому значению, в т.ч. и функции:
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; Поскольку именование функций - очень частая операция,
+; clojure позволяет, сделать это проще:
+(defn hello-world [] "Hello World")
+
+; Вектор [] в форме описания функции, следующий сразу за именем,
+; описывает параметры функции:
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; Одна функция может иметь сразу несколько наборов аргументов:
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; Также функция может иметь набор аргументов переменной длины
+(defn count-args [& args] ; args будет содержать seq аргументов
+ (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"
+
+; Для создания анонимных функций есть специальный синтаксис:
+; функциональные литералы
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; такие функциональные литералы удобно использовать с map, filter и reduce
+(map #(* 10 %1) [1 2 3 5]) ; => (10 20 30 50)
+(filter #(> %1 3) [1 2 3 4 5 6 7]) ; => (4 5 6 7)
+(reduce #(str %1 "," %2) [1 2 3 4]) ; => "1,2,3,4"
+
+; Отображения (Maps)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Hash maps и array maps имеют одинаковый интерфейс.
+; Hash maps производят поиск по ключу быстрее, но не сохраняют порядок ключей
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Array maps автоматически преобразуются в hash maps,
+; как только разрастутся до определенного размера
+
+; Отображения могут использовать в качестве ключей любые хэшируемые значения,
+; однако предпочтительными являются ключи,
+; являющиеся "ключевыми словами" (keywords)
+(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}
+
+; Предыдущий пример содержит запятые в коде, однако reader не использует их,
+; при обработке литералов - запятые просто воспринимаются,
+; как "пробельные символы" (whitespaces)
+
+; Отображение может выступать в роли функции, возвращающей значение по ключу
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; При попытке получить отсутствующее значение, будет возвращён nil
+(stringmap "d") ; => nil
+
+; Иногда бывает удобно указать конкретное значение по-умолчанию:
+({:a 1 :b 2} :c "Oops!") ; => "Oops!"
+
+; Keywords тоже могут использоваться в роли функций!
+(:b keymap) ; => 2
+
+; Однако этот фокус не пройдёт со строками.
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Добавить пару ключ-значение в отображение можно функцией assoc
+(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}
+
+; Множества (Sets)
+;;;;;;;;;;;;;;;;;;
+
+(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
+; содержится множество функций для работы с множествами
+
+; Полезные формы
+;;;;;;;;;;;;;;;;;
+
+; Конструкции ветвления в clojure, это обычные макросы
+; и подобны их собратьям в других языках:
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; Специальная форма let позволяет присвоить имена значениям локально.
+; При этом все изменения будут видны только вложенным формам:
+(def a 10)
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; Несколько форм можно объединить в одну форму посредством do
+; Значением 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)
+
+; Теперь нам доступны операции над множествами:
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; use позволяет указать, какие конкретно имена
+; должны быть импортированы из модуля:
+(use '[clojure.set :only [intersection]])
+
+; Также модуль может быть импортирован формой require
+(require 'clojure.string)
+
+; После этого модуль становится доступе в текущем пространстве имен,
+; а вызов его функций может быть осуществлен указанием полного имени функции:
+(clojure.string/blank? "") ; => true
+
+; Импортируемому модулю можно назначить короткое имя:
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (Литерал вида #"" обозначает регулярное выражение)
+
+; Вместо отдельной формы require (и use, хотя это и не приветствуется) можно
+; указать необходимые модули прямо в форме ns:
+(ns test
+ (:require
+ [clojure.string :as str] ; Внимание: при указании внутри формы ns
+ [clojure.set :as set])) ; имена пакетов не квотируются!
+
+; Java
+;;;;;;;
+
+; Стандартная библиотека Java очень богата,
+; и всё это богатство доступно и для Clojure!
+
+; import позволяет импортировать модули Java
+(import java.util.Date)
+
+; В том числе и из ns
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Имя класса, сопровождаемое символом "." позволяет
+; инстанцировать объекты Java-классов:
+(Date.) ; <a date object>
+
+; форма . позволяет вызывать методы:
+(. (Date.) getTime) ; <a timestamp>
+(.getTime (Date.)) ; а можно и так
+
+; Статические методы вызываются как функции модуля:
+(System/currentTimeMillis) ; <a timestamp> (Модуль system всегда доступен!)
+
+; 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
+
+; Работа с изменяемым сотоянием
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Clojure предоставляет набор инструментов
+; для работы с изменяемым состоянием: Software Transactional Memory.
+; Структуры STM представлены тремя типами:
+; - атомы (atoms)
+; - агенты (agents)
+; - ссылки (references)
+
+; Самые простые хранители состояния - атомы:
+(def my-atom (atom {})) ; {} - начальное состояние атома
+
+; Обновляется атом посредством swap!.
+; swap! применяет функцию аргумент к текущему значению
+; атома и помещает в атом результат
+(swap! my-atom assoc :a 1) ; Обновляет my-atom, помещая в него (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Обновляет my-atom, помещая в него (assoc {:a 1} :b 2)
+
+; Получить значение атома можно посредством '@'
+; (провести так называемую операцию dereference)
+my-atom ;=> Atom<#...> (Возвращает объект типа Atom)
+@my-atom ; => {:a 1 :b 2}
+
+; Пример реализации счётчика на атоме
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; С другими STM-конструкциями - refs и agents - можно ознакомиться тут:
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+```
+
+### Для будущего чтения
+
+Это руководство не претендует на полноту, но мы смеем надеяться, способно вызвать интерес к дальнейшему изучению языка.
+
+Clojure.org - сайт содержит большое количество статей по языку:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org - сайт документации языка с примерами использования функций:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure - отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org (да, именно) неплохой перечень статей для начинающих:
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/ru-ru/erlang-ru.html.markdown b/ru-ru/erlang-ru.html.markdown
new file mode 100644
index 00000000..99ea79ee
--- /dev/null
+++ b/ru-ru/erlang-ru.html.markdown
@@ -0,0 +1,256 @@
+---
+language: erlang
+contributors:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
+translators:
+ - ["Nikita Kalashnikov", "https://root.yuuzukiyo.net/"]
+filename: learnerlang-ru.erl
+lang: ru-ru
+---
+
+```erlang
+% Символ процента предваряет однострочный комментарий.
+
+%% Два символа процента обычно используются для комментариев к функциям.
+
+%%% Три символа процента используются для комментариев к модулям.
+
+% Пунктуационные знаки, используемые в Erlang:
+% Запятая (`,`) разделяет аргументы в вызовах функций, структурах данных и
+% образцах.
+% Точка (`.`) (с пробелом после них) разделяет функции и выражения в
+% оболочке.
+% Точка с запятой (`;`) разделяет выражения в следующих контекстах:
+% формулы функций, выражения `case`, `if`, `try..catch` и `receive`.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 1. Переменные и сопоставление с образцом.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Num = 42. % Все названия переменных начинаются с большой буквы.
+
+% Erlang использует единичное присваивание переменным. Если вы попытаетесь
+% присвоить другое значение переменной `Num`, вы получите ошибку.
+Num = 43. % ** exception error: no match of right hand side value 43
+
+% В большинстве языков `=` обозначает операцию присвоения. В отличие от них, в
+% Erlang `=` — операция сопоставления с образцом. `Lhs = Rhs` на самом
+% деле подразумевает «вычисли правую часть выражения (Rhs) и затем сопоставь
+% результат с образцом слева (Lhs)».
+Num = 7 * 6.
+
+% Числа с плавающей точкой.
+Pi = 3.14159.
+
+% Атомы используются для представления различных нечисловых констант. Названия
+% атомов начинаются с буквы в нижнем регистре, за которой могут следовать другие
+% буквы английского алфавита, цифры, символ подчёркивания (`_`) или «собака»
+% (`@`).
+Hello = hello.
+OtherNode = example@node.
+
+% Если в имени атома нужно использовать другие символы, кроме допустимых,
+% имя атома необходимо взять в одинарные кавычки (`'`).
+AtomWithSpace = 'some atom with space'.
+
+% Кортежы подобны структурам в языке C.
+Point = {point, 10, 45}.
+
+% Если нужно извлечь определённые данные из кортежа, используется оператор
+% сопоставления с образцом — `=`.
+{point, X, Y} = Point. % X = 10, Y = 45
+
+% Символ `_` может использоваться как «заполнитель» для переменных, значения
+% которых в текущем выражении нас не интересуют. Он называется анонимной
+% переменной. В отличие от остальных переменных, множественные использования
+% `_` в одном образце не требуют, чтобы все значения, присваевыемые этой
+% переменной, были идентичными.
+Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
+{_, {_, {_, Who}, _}, _} = Person. % Who = joe
+
+% Список создаётся путём заключения его элементов в квадратные скобки и
+% разделения их запятыми. Отдельные элементы списка могут быть любого типа.
+% Первый элемент списка называется головой списка. Список, получающийся в
+% результате отделения головы, называется хвостом списка.
+ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
+
+% Если `T` — список, то `[H|T]` — тоже список, где `H` является головой, а `T` —
+% хвостом. Вертикальная черта (`|`) разделяет голову и хвост списка.
+% `[]` — пустой список.
+% Мы можем извлекать элементы из списка с помощью сопоставления с образцом.
+% Если у нас есть непустой список `L`, тогда выражение `[X|Y] = L`, где `X` и
+% `Y` — свободные (не связанные с другими значениям) переменные, извлечёт голову
+% списка в `X` и его хвост в `Y`.
+[FirstThing|OtherThingsToBuy] = ThingsToBuy.
+% FirstThing = {apples, 10}
+% OtherThingsToBuy = {pears, 6}, {milk, 3}
+
+% В Erlang нет строк как отдельного типа. Все используемые в программах строки
+% являются обычным списком целых чисел. Строковые значения всегда должны быть в
+% двойных кавычках (`"`).
+Name = "Hello".
+[72, 101, 108, 108, 111] = "Hello".
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 2. Последовательное программирование.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Модуль — основная единица кода в Erlang. В них пишутся и сохраняются все
+% функции. Модули хранятся в файлах с расширением `.erl`.
+% Модули должны быть скомпилированы перед тем, как использовать код из них.
+% Скомпилированный файл модуля имеет разрешение `.beam`.
+-module(geometry).
+-export([area/1]). % список функций, экспортируемых из модуля.
+
+% Функция `area` состоит из двух формул (clauses). Формулы отделяются друг от
+% друга точкой с запятой, после последнего определения должна стоять точка с
+% пробелом после неё.
+% Каждое определение имеет заголовок и тело. Заголовок состоит из названия
+% функции и образца (в скобках); тело состоит из последовательных выражений,
+% вычисляемых, когда аргументы функции совпадают с образцом в заголовке.
+% Сопоставление с образцами в заголовках происходит в том порядке, в котором
+% они перечислены в определении функции.
+area({rectangle, Width, Ht}) -> Width * Ht;
+area({circle, R}) -> 3.14159 * R * R.
+
+% Компиляция файла с исходным кодом geometry.erl.
+c(geometry). % {ok,geometry}
+
+% Необходимо указывать имя модуля вместе с именем функции для определения, какую
+% именно фукнцию мы хотим вызвать.
+geometry:area({rectangle, 10, 5}). % 50
+geometry:area({circle, 1.4}). % 6.15752
+
+% В Erlang две функции с разной арностью (числом аргументов) в пределах одного
+% модуля представляются как две разные функции.
+-module(lib_misc).
+-export([sum/1]). % экспорт функции `sum` с арностью 1, принимающую один аргумент.
+sum(L) -> sum(L, 0).
+sum([], N) -> N;
+sum([H|T], N) -> sum(T, H+N).
+
+% Fun'ы — анонимные функции, называемые так по причине отсутствия имени. Зато
+% их можно присваивать переменным.
+Double = fun(X) -> 2*X end. % `Double` указывает на анонимную функцию с идентификатором: #Fun<erl_eval.6.17052888>
+Double(2). % 4
+
+% Функции могут принимать fun'ы как параметры и возвращать их в качестве
+% результата вычислений.
+Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
+Triple = Mult(3).
+Triple(5). % 15
+
+% Выделения списоков (list comprehensions) — выражения, создающие списки без
+% применения анонимных функций, фильтров или map'ов.
+% Запись `[F(X) || X <- L]` значит «список `F(X)`, где `X` последовательно
+% выбирается из списка `L`».
+L = [1,2,3,4,5].
+[2*X || X <- L]. % [2,4,6,8,10]
+% В выделениях списков могут быть генераторы и фильтры для отделения подмножеств
+% генерируемых значений.
+EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
+
+% Охранные выражения используются для простых проверок переменных в образцах,
+% что значительно расширяет возможности сопоставления. Они могут использоваться
+% в заголовках определений функций, предварённые ключевым словом `when`, а также
+% в условных конструкциях.
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+% Охранные выражения можно группировать, разделяя запятой.
+% Последовательность `GuardExpr1, GuardExpr2, ..., GuardExprN` является истинной
+% только в том случае, когда все выражения, которые она содержат, являются
+% истинными.
+is_cat(A) when is_atom(A), A =:= cat -> true;
+is_cat(A) -> false.
+is_dog(A) when is_atom(A), A =:= dog -> true;
+is_dog(A) -> false.
+
+% Последовательность охранных выражений, разделённых точками с запятой, является
+% истинной в том случае, если хотя бы одно выражение из списка `G1; G2; ...; Gn`
+% является истинным.
+is_pet(A) when is_dog(A); is_cat(A) -> true;
+is_pet(A) -> false.
+
+% Записи предоставляют возможность именования определённых элементов в кортежах.
+% Определения записей могут быть включены в исходный код модулей Erlang или же
+% в заголовочные файлы с расширением `.hrl`.
+-record(todo, {
+ status = reminder, % Значение по умолчанию.
+ who = joe,
+ text
+}).
+
+% Для чтения определений записей из файлов в оболочке можно использовать команду
+% `rr`.
+rr("records.hrl"). % [todo]
+
+% Создание и изменение записей.
+X = #todo{}.
+% #todo{status = reminder, who = joe, text = undefined}
+X1 = #todo{status = urgent, text = "Fix errata in book"}.
+% #todo{status = urgent, who = joe, text = "Fix errata in book"}
+X2 = X1#todo{status = done}.
+% #todo{status = done,who = joe,text = "Fix errata in book"}
+
+% Условное выражение `case`.
+% Функция `filter` возвращет список всех элементов `X` из списка `L`, для
+% которых выражение `P(X)` является истинным.
+filter(P, [H|T]) ->
+ case P(H) of
+ true -> [H|filter(P, T)];
+ false -> filter(P, T)
+ end;
+filter(P, []) -> [].
+filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
+
+% Условное выражение `if`.
+max(X, Y) ->
+ if
+ X > Y -> X;
+ X < Y -> Y;
+ true -> nil;
+ end.
+
+% Внимание: в выражении `if` должно быть как минимум одно охранное выраженние,
+% вычисляющееся в true, иначе возникнет исключение.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 3. Обработка исключений.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Исключения возникают в случае внутренних ошибок системы или вызываются
+% непосредственно из кода программы с помощью вызовов `throw(Exception)`,
+% `exit(Exception)` или `erlang:error(Exception)`.
+generate_exception(1) -> a;
+generate_exception(2) -> throw(a);
+generate_exception(3) -> exit(a);
+generate_exception(4) -> {'EXIT', a};
+generate_exception(5) -> erlang:error(a).
+
+% В Erlang есть два способа обработки исключений. Первый заключается в
+% использовании выражения `try..catch` в функции, в которой возможен выброс
+% исключения.
+catcher(N) ->
+ try generate_exception(N) of
+ Val -> {N, normal, Val}
+ catch
+ throw:X -> {N, caught, thrown, X};
+ exit:X -> {N, caught, exited, X};
+ error:X -> {N, caught, error, X}
+ end.
+
+% Второй способ заключается в использовании `catch`. Во время поимки исключения
+% оно преобразуется в кортеж с информацией об ошибке.
+catcher(N) -> catch generate_exception(N).
+
+```
+
+## Ссылки:
+
+* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
+* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang)
+* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
+* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)
diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown
new file mode 100644
index 00000000..ffda01b7
--- /dev/null
+++ b/ru-ru/go-ru.html.markdown
@@ -0,0 +1,336 @@
+---
+language: Go
+filename: learngo-ru.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+translators:
+ - ["Artem Medeusheyev", "https://github.com/armed"]
+ - ["Valery Cherepanov", "https://github.com/qumeric"]
+lang: ru-ru
+---
+
+Go - это язык общего назначения, целью которого является удобство, простота,
+конкуррентность. Это не тренд в компьютерных науках, а новейший и быстрый
+способ решать насущные проблемы.
+
+Концепции Go схожи с другими императивными статически типизированными языками.
+Быстро компилируется и быстро исполняется, имеет легкие в понимании конструкции
+для создания масштабируемых и многопоточных программ.
+
+Может похвастаться отличной стандартной библиотекой и большим комьюнити, полным
+энтузиастов.
+
+```go
+// Однострочный комментарий
+/* Многострочный
+ комментарий */
+
+// Ключевое слово package присутствует в начале каждого файла.
+// Main это специальное имя, обозначающее исполняемый файл, нежели библиотеку.
+package main
+
+// Import предназначен для указания зависимостей этого файла.
+import (
+ "fmt" // Пакет в стандартной библиотеке Go
+ "net/http" // Да, это веб-сервер!
+ "strconv" // Конвертирование типов в строки и обратно
+ m "math" // Импортировать math под локальным именем m.
+)
+
+// Объявление функции. Main это специальная функция, служащая точкой входа для
+// исполняемой программы. Нравится вам или нет, но Go использует фигурные
+// скобки.
+func main() {
+ // Println выводит строку в stdout.
+ // Данная функция находится в пакете fmt.
+ fmt.Println("Hello world!")
+
+ // Вызов другой функции из текущего пакета.
+ beyondHello()
+}
+
+// Функции содержат входные параметры в круглых скобках.
+// Пустые скобки все равно обязательны, даже если параметров нет.
+func beyondHello() {
+ var x int // Переменные должны быть объявлены до их использования.
+ x = 3 // Присвоение значения переменной.
+ // Краткое определение := позволяет объявить перменную с автоматической
+ // подстановкой типа из значения.
+ y := 4
+ sum, prod := learnMultiple(x, y) // Функция возвращает два значения.
+ fmt.Println("sum:", sum, "prod:", prod) // Простой вывод.
+ learnTypes() // < y minutes, learn more!
+}
+
+// Функция имеющая входные параметры и возврат нескольких значений.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Возврат двух значений.
+}
+
+// Некотрые встроенные типы и литералы.
+func learnTypes() {
+ // Краткое определение переменной говорит само за себя.
+ s := "Learn Go!" // Тип string.
+
+ s2 := `"Чистый" строковой литерал
+может содержать переносы строк` // Тоже тип данных string
+
+ // Символ не из ASCII. Исходный код Go в кодировке UTF-8.
+ g := 'Σ' // тип rune, это алиас для типа uint32, содержит символ юникода.
+
+ f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754).
+ c := 3 + 4i // complex128, внутри себя содержит два float64.
+
+ // Синтаксис var с инициализациями.
+ var u uint = 7 // Беззнаковое, но размер зависит от реализации, как и у int.
+ var pi float32 = 22. / 7
+
+ // Синтаксис приведения типа с кратким определением
+ n := byte('\n') // byte – это алиас для uint8.
+
+ // Массивы имеют фиксированный размер на момент компиляции.
+ var a4 [4]int // массив из 4-х int, инициализирован нулями.
+ a3 := [...]int{3, 1, 5} // массив из 3-х int, ручная инициализация.
+
+ // Слайсы (slices) имеют динамическую длину. И массивы, и слайсы имеют свои
+ // преимущества, но слайсы используются гораздо чаще.
+ s3 := []int{4, 5, 9} // Сравните с a3. Тут нет троеточия.
+ s4 := make([]int, 4) // Выделение памяти для слайса из 4-х int (нули).
+ var d2 [][]float64 // Только объявление, память не выделяется.
+ bs := []byte("a slice") // Синтаксис приведения типов.
+
+ p, q := learnMemory() // Объявление p и q как указателей на int.
+ fmt.Println(*p, *q) // * извлекает указатель. Печатает два int-а.
+
+ // Map, также как и словарь или хеш из некоторых других языков, является
+ // ассоциативным массивом с динамически изменяемым размером.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ delete(m, "three") // Встроенная функция, удаляет элемент из map-а.
+
+ // Неиспользуемые переменные в Go являются ошибкой.
+ // Нижнее подчеркивание позволяет игнорировать такие переменные.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Вывод считается использованием переменной.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // Идем дальше.
+}
+
+// У Go есть полноценный сборщик мусора. В нем есть указатели но нет арифметики
+// указателей. Вы можете допустить ошибку с указателем на nil, но не с
+// инкрементацией указателя.
+func learnMemory() (p, q *int) {
+ // Именованные возвращаемые значения p и q являются указателями на int.
+ p = new(int) // Встроенная функция new выделяет память.
+ // Выделенный int проинициализирован нулем, p больше не содержит nil.
+ s := make([]int, 20) // Выделение единого блока памяти под 20 int-ов.
+ s[3] = 7 // Присвоить значение одному из них.
+ r := -2 // Определить еще одну локальную переменную.
+ return &s[3], &r // Амперсанд(&) обозначает получение адреса переменной.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // If-ы всегда требуют наличине фигурных скобок, но не круглых.
+ if true {
+ fmt.Println("told ya")
+ }
+ // Форматирование кода стандартизировано утилитой "go fmt".
+ if false {
+ // Будущего нет.
+ } else {
+ // Жизнь прекрасна.
+ }
+ // Используйте switch вместо нескольких if-else.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Case-ы в Go не "проваливаются" (неявный break).
+ case 43:
+ // Не выполнится.
+ }
+ // For, как и if не требует круглых скобок
+ // Переменные, объявленные в for и if являются локальными.
+ for x := 0; x < 3; x++ { // ++ – это операция.
+ fmt.Println("итерация", x)
+ }
+ // Здесь x == 42.
+
+ // For – это единственный цикл в Go, но у него есть альтернативные формы.
+ for { // Бесконечный цикл.
+ break // Не такой уж и бесконечный.
+ continue // Не выполнится.
+ }
+ // Как и в for, := в if-е означает объявление и присвоение значения y,
+ // проверка y > x происходит после.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Функции являются замыканиями.
+ xBig := func() bool {
+ return x > 10000 // Ссылается на x, объявленый выше switch.
+ }
+ fmt.Println("xBig:", xBig()) // true (т.к. мы присвоили x = e^10).
+ x = 1.3e3 // Тут х == 1300
+ fmt.Println("xBig:", xBig()) // Теперь false.
+
+ // Метки, куда же без них, их все любят.
+ goto love
+love:
+
+ learnDefer() // Быстрый обзор важного ключевого слова.
+ learnInterfaces() // О! Интерфейсы, идем далее.
+}
+
+func learnDefer() (ok bool) {
+ // Отложенные(deferred) выражения выполняются сразу перед тем, как функция
+ // возвратит значение.
+ defer fmt.Println("deferred statements execute in reverse (LIFO) order.")
+ defer fmt.Println("\nThis line is being printed first because")
+ // defer широко используется для закрытия файлов, чтобы закрывающая файл
+ // функция находилась близко к открывающей.
+ return true
+}
+
+// Объявление Stringer как интерфейса с одним методом, String.
+type Stringer interface {
+ String() string
+}
+
+// Объявление pair как структуры с двумя полями x и y типа int.
+type pair struct {
+ x, y int
+}
+
+// Объявление метода для типа pair. Теперь pair реализует интерфейс Stringer.
+func (p pair) String() string { // p в данном случае называют receiver-ом.
+ // Sprintf – еще одна функция из пакета fmt.
+ // Обращение к полям p через точку.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Синтаксис с фигурными скобками это "литерал структуры". Он возвращает
+ // проинициализированную структуру, а оператор := присваивает её p.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Вызов метода String у переменной p типа pair.
+ var i Stringer // Объявление i как типа с интерфейсом Stringer.
+ i = p // Валидно, т.к. pair реализует Stringer.
+ // Вызов метода String у i типа Stringer. Вывод такой же, что и выше.
+ fmt.Println(i.String())
+
+ // Функции в пакете fmt сами всегда вызывают метод String у объектов для
+ // получения строкового представления о них.
+ fmt.Println(p) // Вывод такой же, что и выше. Println вызывает метод String.
+ fmt.Println(i) // Вывод такой же, что и выше.
+
+ learnVariadicParams("Учиться", "учиться", "и еще раз учиться!")
+}
+
+// Функции могут иметь варьируемое количество параметров.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Вывести все параметры с помощью итерации.
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // Передать все варьируемые параметры.
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // Идиома ", ok" служит для обозначения корректного срабатывания чего-либо.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok будет false, потому что 1 нет в map-е.
+ fmt.Println("тут никого нет")
+ } else {
+ fmt.Print(x) // x содержал бы значение, если бы 1 был в map-е.
+ }
+ // Идиома ", err" служит для обозначения была ли ошибка или нет.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ игнорирует значение
+ // выведет "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // Мы еще обратимся к интерфейсам чуть позже, а пока...
+ learnConcurrency()
+}
+
+// c – это тип данных channel (канал), объект для конкуррентного взаимодействия.
+func inc(i int, c chan int) {
+ c <- i + 1 // когда channel слева, <- являтся оператором "отправки".
+}
+
+// Будем использовать функцию inc для конкуррентной инкрементации чисел.
+func learnConcurrency() {
+ // Тот же make, что и в случае со slice. Он предназначен для выделения
+ // памяти и инициализации типов slice, map и channel.
+ c := make(chan int)
+ // Старт трех конкуррентных goroutine. Числа будут инкрементированы
+ // конкуррентно и, может быть параллельно, если машина правильно
+ // сконфигурирована и позволяет это делать. Все они будут отправлены в один
+ // и тот же канал.
+ go inc(0, c) // go начинает новую горутину.
+ go inc(10, c)
+ go inc(-805, c)
+ // Считывание всех трех результатов из канала и вывод на экран.
+ // Нет никакой гарантии в каком порядке они будут выведены.
+ fmt.Println(<-c, <-c, <-c) // канал справа, <- обозначает "получение".
+
+ cs := make(chan string) // другой канал, содержит строки.
+ cc := make(chan chan string) // канал каналов со строками.
+ go func() { c <- 84 }() // пуск новой горутины для отправки значения
+ go func() { cs <- "wordy" }() // еще раз, теперь для cs
+ // Select тоже что и switch, но работает с каналами. Он случайно выбирает
+ // готовый для взаимодействия канал.
+ select {
+ case i := <-c: // полученное значение можно присвоить переменной
+ fmt.Printf("это %T", i)
+ case <-cs: // либо значение можно игнорировать
+ fmt.Println("это строка")
+ case <-cc: // пустой канал, не готов для коммуникации.
+ fmt.Println("это не выполнится.")
+ }
+ // В этой точке значение будет получено из c или cs. Одна горутина будет
+ // завершена, другая останется заблокированной.
+
+ learnWebProgramming() // Да, Go это может.
+}
+
+// Всего одна функция из пакета http запускает web-сервер.
+func learnWebProgramming() {
+ // У ListenAndServe первый параметр это TCP адрес, который нужно слушать.
+ // Второй параметр это интерфейс типа http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // не игнорируйте сообщения об ошибках
+}
+
+// Реализация интерфейса http.Handler для pair, только один метод ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Обработка запроса и отправка данных методом из http.ResponseWriter
+ w.Write([]byte("You learned Go in Y minutes!"))
+}
+```
+
+## Что дальше
+
+Основа всех основ в Go это [официальный веб сайт](http://golang.org/).
+Там можно пройти туториал, поиграться с интерактивной средой Go и почитать
+объемную документацию.
+
+Для живого ознакомления рекомендуется почитать исходные коды [стандартной
+библиотеки Go](http://golang.org/src/pkg/). Отлично задокументированная, она
+является лучшим источником для чтения и понимания Go, его стиля и идиом. Либо
+можно, кликнув на имени функции в [документации](http://golang.org/pkg/),
+перейти к ее исходным кодам.
diff --git a/ru-ru/haskell-ru.html.markdown b/ru-ru/haskell-ru.html.markdown
new file mode 100644
index 00000000..03e66d05
--- /dev/null
+++ b/ru-ru/haskell-ru.html.markdown
@@ -0,0 +1,546 @@
+---
+language: haskell
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
+translators:
+ - ["Aleksey Pirogov", "http://astynax.github.io"]
+lang: ru-ru
+---
+
+Haskell разрабатывался, как чистый функциональный язык программирования, применимый на практике. Язык известен благодаря своей системе типов, и "знаменит" благодаря монадам. [Меня][autor] же Haskell заставляет возвращаться к себе снова и снова именно своей элегантностью и [я][autor] получаю истинное удовольствие, программируя на Haskell.
+
+```haskell
+-- Однострочные комментарии начинаются с двух дефисов
+{- Многострочный комментарий
+заключается в пару фигурных скобок с дефисами с внутренней стороны.
+-}
+
+-------------------------------------------------------
+-- 1. Примитивные типы и простейшие операции над ними
+-------------------------------------------------------
+
+-- Числа объявляются просто
+3 -- 3
+
+-- Арифметика тоже выглядит вполне ожидаемо
+1 + 1 -- 2
+8 - 1 -- 7
+10 * 2 -- 20
+35 / 5 -- 7.0
+
+-- Операция деления всегда возвращает действительное число
+35 / 4 -- 8.75
+
+-- Делим нацело так
+35 `div` 4 -- 8
+
+-- Булевы значения - тоже примитивные значения
+True
+False
+
+-- Булева алгебра
+not True -- False
+not False -- True
+1 == 1 -- True
+1 /= 1 -- False
+1 < 10 -- True
+
+-- В примере выше `not`, это функция, принимающая один аргумент.
+-- При вызове функции в Haskell список аргументов
+-- не нужно заключать в скобки - аргументы просто
+-- перечисляются через пробелы сразу после имени функции.
+-- Т.о. типичный вызов выглядит так:
+-- func arg1 arg2 arg3...
+-- Ниже же будет показано, как определять свои функции.
+
+-- Строки и символы
+"Это строка."
+'ы' -- а это символ
+'Нельзя заключать длинные строки в одинарные кавычки.' -- ошибка!
+
+-- Строки можно конкатенировать
+"Привет" ++ ", Мир!" -- "Привет, Мир!"
+
+-- При этом строки - это просто списки символов!
+"Я - строка!" !! 0 -- 'Я'
+
+
+----------------------------------------------------
+-- Списки и Кортежи
+----------------------------------------------------
+
+-- Все элементы списка в Haskell
+-- должны иметь один и тот же тип.
+
+-- Эти два списка - эквивалентны:
+[1, 2, 3, 4, 5]
+[1..5]
+
+-- Haskell позволяет определять даже бесконечные списки!
+[1..] -- список всех натуральных чисел!
+
+-- Бесконечные списки возможно в Haskell потому, что он "ленив".
+-- В Haskell все вычисления производятся тогда и только тогда,
+-- когда их результат потребуется.
+-- Эта стратегия так и называется - "lazy evaluation".
+-- Скажем, если вам нужен тысячный элемент из
+-- списка натуральных чисел (бесконечного) и вы напишете так:
+
+[1..] !! 999 -- 1000
+
+-- То Haskell вычислит элементы этого списка от 1 до 1000...
+-- ... и остановится, ведь последующие элементы пока не нужны.
+-- Это значит, что остальные элементы нашего
+-- "бесконечного" списка не будут вычисляться! По крайней мере,
+-- пока не понадобятся и они.
+
+-- Списки можно объединять
+[1..5] ++ [6..10]
+
+-- И добавлять значения в начало
+0:[1..5] -- [0, 1, 2, 3, 4, 5]
+
+-- А можно обратиться по индексу
+[0..] !! 5 -- 5
+
+-- Вот ещё несколько функций, часто используемых со списками
+head [1..5] -- 1
+tail [1..5] -- [2, 3, 4, 5]
+init [1..5] -- [1, 2, 3, 4]
+last [1..5] -- 5
+
+-- list comprehensions - "формулы" для описания списков
+[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
+
+-- можно указать условие попадания элементов в список
+[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
+
+-- Списки могут даже состоять из других списков
+[[1,2,3],[4,5,6]] !! 1 !! 2 -- 6 (вторая строка, третий столбец)
+
+-- Кортежи позволяют своим элементам иметь различные типы,
+-- но при этом кортежи имеют фиксированную длину.
+-- Кортеж:
+("haskell", 1)
+
+-- Часто кортежи из двух элементов называются "парами".
+-- Элементы пары можно получать так:
+fst ("haskell", 1) -- "haskell"
+snd ("haskell", 1) -- 1
+
+----------------------------------------------------
+-- 3. Функции
+----------------------------------------------------
+-- Простая функция, принимающая два аргумента
+add a b = a + b
+
+-- Внимание!
+-- Если вы используете ghci (интерактивный интерпретатор Haskell),
+-- вам нужно использовать ключевое слово `let`, примерно так:
+-- let add a b = a + b
+
+-- Вызовем нашу функцию
+add 1 2 -- 3
+
+-- Функцию можно поместить между первым и вторым аргументами,
+-- если заключить её имя в обратные кавычки
+1 `add` 2 -- 3
+
+{- Вы можете также определять функции, имя которых
+вообще не содержит букв! Таки функции и называются "операторами",
+и, да, вы можете определять свои операторы!
+Скажем, оператор целочисленного деления можно определить так -}
+(//) a b = a `div` b
+35 // 4 -- 8
+{- Здесь оператор заключен в скобки - как говорят,
+поставлен в префиксную позицию.
+В префиксной позиции оператор можно не только определять,
+но и вызывать -}
+(+) 1 2 -- 3
+
+-- Охранные выражения (guards) порой удобны,
+-- если наша функция ветвится
+fib x
+ | x < 2 = x
+ | otherwise = fib (x - 1) + fib (x - 2)
+
+{- Сопоставление с образцом (pattern matching)
+чем-то напоминает охранные выражения.
+Здесь мы видим три определения функции fib.
+При вызове функции по имени Haskell использует
+первое определение, к образцу которого
+"подойдет" набор аргументов -}
+fib 1 = 1
+fib 2 = 2
+fib x = fib (x - 1) + fib (x - 2)
+
+-- Pattern matching для кортежей выглядит так
+foo (x, y) = (x + 1, y + 2)
+
+{- Pattern matching для списков устроен чуть сложнее.
+Пусть `x` - первый элемент списка, а `xs` - остальные элементы.
+Тогда операции `head` и `tail` могут быть определены так -}
+myHead (x:xs) = x
+myTail (x:xs) = xs
+
+-- Функцию отображения мы можем написать так
+myMap func [] = []
+myMap func (x:xs) = func x:(myMap func xs)
+
+-- При сопоставлении происходит привязка
+-- элементов значения с именами в образце
+fstPlusThird (a : _ : b : _) = a + b
+fstPlusThird [1,2,3,4,5] -- 4
+-- Значения, для которых вместо имени указано `_`,
+-- игнорируются. Это удобно, когда важен сам факт
+-- совпадения образца
+oneElem [_] = True
+oneElem _ = False
+
+startsWith x (y:_) = x == y
+startsWith _ _ = False
+
+startsWith 'H' "Hello!" -- True
+startsWith 'H' "hello!" -- False
+
+{- Обратите внимание на тот факт,
+что первый аргумент нашей функции `myMap` - тоже функция!
+Функции, подобно `myMap`, принимающие другие функции
+в качестве параметров, или, скажем, возвращающие функции
+в качестве результата, называются
+Функциями Высших Порядков (ФВП, High Order Functions, HOF)
+-}
+
+-- Вместе с ФВП часто используются анонимные функции
+myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
+-- Такие функции описываются в виде
+-- \arg1 arg1 .. -> expression
+
+-- Популярные в других языках ФВП присутствуют и в Haskell
+map (\x -> x * 10) [1..5] -- [10, 20, 30, 40, 50]
+filter (\x -> x > 2) [1..5] -- [3, 4, 5]
+
+{- Функция свертки
+(она же `reduce` или `inject` в других языках)
+в Haskell представлены функциями `foldr` и `foldl`.
+Суть свертки можно представить так:
+
+foldl f x0 [x1,x2,x3] -> (f (f (f x0 x1) x2) x3)
+foldr f x0 [x1,x2,x3] -> (f x1 (f x2 (f x3 x0)))
+
+Здесь x0 - начальное значения так называемого "аккумулятора"
+-}
+-- Эти два вызова дают одинаковый результат
+foldr (\x acc -> acc + x) 0 [1..5] -- 15
+foldl (\acc x -> acc + x) 0 [1..5] -- 15
+-- Тут можно даже заменить анонимную функцию на оператор
+foldr (+) 0 [1..5] -- 15
+foldl (+) 0 [1..5] -- 15
+
+-- Зато здесь разница видна
+foldr (\x acc -> (x + 10) : acc) [] [1..3] -- [11, 12, 13]
+foldl (\acc x -> (x + 10) : acc) [] [1..3] -- [13, 12, 11]
+
+{- Часто в качестве начального значения
+удобно брать крайнее значение списка (крайнее слева или справа).
+Для этого есть пара функций - `foldr1` и `foldl1` -}
+foldr1 (+) [1..5] -- 15
+foldl1 (+) [1..5] -- 15
+
+----------------------------------------------------
+-- 4. Больше о функциях
+----------------------------------------------------
+
+{- Каррирование (currying)
+Если в Haskell при вызове функции передать не все аргументы,
+Функция становится "каррированой" - результатом вызова станет
+новая функция, которая при вызове и примет оставшиеся аргументы -}
+
+add a b = a + b
+foo = add 10 -- теперь foo будет принимать число
+ -- и добавлять к нему 10
+foo 5 -- 15
+
+-- Для операторов можно "опустить" любой из двух аргументов
+-- Используя этот факт можно определить
+-- функцию `foo` из кода выше несколько иначе
+foo = (+10)
+foo 5 -- 15
+
+-- Поупражняемся
+map (10-) [1..3] -- [9, 8, 7]
+filter (<5) [1..10] -- [1, 2, 3, 4]
+
+{- Композиция функций
+Функция (.) соединяет пару функций в цепочку.
+К примеру, можно соединить функцию, добавляющую 10,
+с функцией, умножающей на 5 -}
+foo = (*5) . (+10)
+
+-- (5 + 10) * 5 = 75
+foo 5 -- 75
+
+{- Управление приоритетом вычисления
+В Haskell есть функция `$`, которая применяет
+свой первый аргумент ко второму с наименьшим приоритетом
+(обычное применение функций имеет наивысший приоритет)
+Эта функция часто позволяет избежать использования
+"лишних" скобок -}
+head (tail (tail "abcd")) -- 'c'
+head $ tail $ tail "abcd" -- 'c'
+-- того же эффекта иногда можно достичь использованием композиции
+(head . tail . tail) "abcd" -- 'c'
+head . tail . tail $ "abcd" -- 'c'
+{- Тут стоит сразу запомнить, что композиция функций
+возвращает именно новую функцию, как в последнем примере.
+Т.е. можно делать так -}
+third = head . tail . tail
+-- но не так
+third = head $ tail $ tail -- (head (tail (tail))) - ошибка!
+
+----------------------------------------------------
+-- 5. Сигнатуры типов
+----------------------------------------------------
+
+{- Haskell обладает очень сильной системой типов.
+И типизация в Haskell - строгая. Каждое выражение имеет тип,
+который может быть описан сигнатурой.
+Сигнатура записывается в форме
+expression :: type signature
+-}
+
+-- Типы примитивов
+5 :: Integer
+"hello" :: String
+True :: Bool
+
+{- Функции тоже имеют тип
+`not` принимает булево значение и возвращает булев результат
+not :: Bool -> Bool
+
+Вот функция двух аргументов
+add :: Integer -> Integer -> Integer
+
+Тут то мы и видим предпосылки к каррированию: тип
+на самом деле выглядит так (скобки просто обычно опускаются)
+add :: (Integer -> Integer) -> Integer
+т.е. функция принимает аргумент,
+и возвращает функцию от второго аргумента! -}
+
+-- Считается хорошим тоном указывать сигнатуру определений,
+-- которые доступны другим разработчикам (публичны). Пример:
+double :: Integer -> Integer
+double x = x * 2
+
+----------------------------------------------------
+-- 6. Управление потоком исполнения
+----------------------------------------------------
+
+-- Выражение `if`
+haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
+
+-- Выражение `if` можно записать и в несколько строк.
+-- Соблюдайте отступы!
+haskell = if 1 == 1
+ then "awesome"
+ else "awful"
+
+-- Так как `if` - выражение, ветка `else` обязательна!
+-- И более того, результаты выражений в ветках `then` и `else`
+-- должны иметь одинаковый тип!
+
+-- `case`-выражение выглядит так
+case args of -- парсим аргументы командной строки
+ "help" -> printHelp
+ "start" -> startProgram
+ _ -> putStrLn "bad args"
+
+-- При вычислении результата `case`-выражения производится
+-- сопоставление с образцом:
+fib x = case x of
+ 1 -> 1
+ 2 -> 1
+ _ -> fib (x - 1) + fib (x - 2)
+
+-- В Haskell нет циклов - вместо них используются рекурсия,
+-- отображение, фильтрация и свертка (map/filter/fold)
+map (*2) [1..5] -- [2, 4, 6, 8, 10]
+
+for array func = map func array
+for [0..3] $ \i -> show i -- ["0", "1", "2", "3"]
+for [0..3] show -- ["0", "1", "2", "3"]
+
+----------------------------------------------------
+-- 7. Пользовательские типы данных
+----------------------------------------------------
+
+-- Создадим свой Haskell-тип данных
+
+data Color = Red | Blue | Green
+
+-- Попробуем использовать
+
+say :: Color -> String
+say Red = "You are Red!"
+say Blue = "You are Blue!"
+say Green = "You are Green!"
+
+-- Типы могут иметь параметры (параметры типов)
+
+data Maybe a = Nothing | Just a
+
+-- Все эти выражения имеют тип `Maybe`
+Just "hello" -- :: `Maybe String`
+Just 1 -- :: `Maybe Int`
+Nothing -- :: `Maybe a` для любого `a`
+
+-- Типы могут быть достаточно сложными
+data Figure = Rectangle (Int, Int) Int Int
+ | Square (Int, Int) Int
+ | Point (Int, Int)
+
+area :: Figure -> Int
+area (Point _) = 0
+area (Square _ s) = s * s
+area (Rectangle _ w h) = w * h
+
+----------------------------------------------------
+-- 8. Ввод-вывод в Haskell
+----------------------------------------------------
+
+-- Полноценно объяснить тему ввода-вывода невозможно
+-- без объяснения монад, но для использования в простых случаях
+-- вводного описания будет достаточно.
+
+-- Когда программа на Haskell выполняется,
+-- вызывается функция с именем `main`.
+-- Эта функция должна вернуть значение типа `IO ()`
+-- Например
+
+main :: IO ()
+main = putStrLn $ "Hello, sky! " ++ (say Blue)
+-- `putStrLn` имеет тип `String -> IO ()`
+
+-- Проще всего реализовать программу с вводом-выводом (IO),
+-- если вы реализуете функцию с типом `String -> String`.
+-- Далее ФВП
+-- interact :: (String -> String) -> IO ()
+-- сделает всё за нас!
+
+countLines :: String -> String
+countLines = show . length . lines
+-- здесь `lines` разделяет строку на список строк
+-- по символу перевода строки
+
+main' :: IO ()
+main' = interact countLines
+
+{- Вы можете думать о типе `IO ()`,
+как о некотором представлении последовательности
+действий, которые должен совершить компьютер.
+Такое представление напоминает программу
+на императивном языке программирования. Для описания
+такой последовательности используется `do`-нотация -}
+
+sayHello :: IO ()
+sayHello = do
+ putStrLn "What is your name?"
+ name <- getLine -- запрашиваем строку и связываем с "name"
+ putStrLn $ "Hello, " ++ name
+
+-- Упражнение:
+-- напишите свою реализацию функции `interact`,
+-- которая запрашивает и обрабатывает только одну строку
+
+{- Код функции `sayHello` не будет исполняться
+при её определении. Единственное место, где IO-действия
+могут быть произведены - функция `main`!
+Чтобы эта программа выполнила действия в функции `sayHello`,
+закомментируйте предыдущее определение функции `main`
+и добавьте новое определение:
+
+main = sayHello -}
+
+{- Давайте подробнее рассмотрим, как работает функция `getLine`
+Её тип:
+ getLine :: IO String
+Вы можете думать, что значение типа `IO a` представляет
+собой компьютерную программу, в результате выполнения которой
+генерируется значение типа `a`, в дополнение
+к остальным эффектам, производимым при выполнении - таким как
+печать текста на экран. Это значение типа `a` мы можем
+сохранить с помощью оператора `<-`. Мы даже можем реализовать
+свое действие, возвращающее значение: -}
+
+action :: IO String
+action = do
+ putStrLn "This is a line. Duh"
+ input1 <- getLine
+ input2 <- getLine
+ -- Тип блока `do` будет соответствовать типу последнего
+ -- выполненного в блоке выражения.
+ -- Заметим, что `return` - не ключевое слово, а функция
+ -- типа `a -> IO a`
+ return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
+
+-- Теперь это действие можно использовать вместо `getLine`:
+
+main'' = do
+ putStrLn "I will echo two lines!"
+ result <- action
+ putStrLn result
+ putStrLn "This was all, folks!"
+
+{- Тип `IO` - пример "монады". Языку Haskell нужны монады,
+чтобы оставаться преимущественно чистым функциональным языком.
+Любые функции, взаимодействующие с внешним миром
+(производящие ввод-вывод) имеют `IO` в своих сигнатурах.
+Это позволяет судить о функции как о "чистой" - такая не будет
+производить ввод-вывод. В ином случая функция - не "чистая".
+
+Такой подход позволяет очень просто разрабатывать многопоточные
+программы - чистые функции, запущенные параллельно
+не будут конфликтовать между собой в борьбе за ресурсы. -}
+
+----------------------------------------------------
+-- 9. Haskell REPL
+----------------------------------------------------
+
+{- Интерактивная консоль Haskell запускается командой `ghci`.
+Теперь можно вводить строки кода на Haskell.
+Связывание значений с именами производится
+с помощью выражения `let`: -}
+
+let foo = 5
+
+-- Тип значения или выражения можно узнать
+-- с помощью команды `:t`:
+
+>:t foo
+foo :: Integer
+
+-- Также можно выполнять действия с типом `IO ()`
+
+> sayHello
+What is your name?
+Friend!
+Hello, Friend!
+
+```
+
+Многое о Haskell, например классы типов и монады невозможно уместить в столь короткую статью. Огромное количество очень интересных идей лежит в основе языка, и именно благодаря этому фундаменту на языке так приятно писать код. Позволю себе привести ещё один маленький пример кода на Haskell - реализацию быстрой сортировки:
+
+```haskell
+qsort [] = []
+qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
+ where lesser = filter (< p) xs
+ greater = filter (>= p) xs
+```
+
+Haskell прост в установке, забирайте [здесь](http://www.haskell.org/platform/) и пробуйте! Это же так интересно!.
+
+Более глубокое погрузиться в язык позволят прекрасные книги
+[Learn you a Haskell](http://learnyouahaskell.com/) и
+[Real World Haskell](http://book.realworldhaskell.org/).
+
+[autor]: http://adit.io имеется в виду автор оригинального текста Adit Bhargava *(примечание переводчика)*
diff --git a/ru-ru/julia-ru.html.markdown b/ru-ru/julia-ru.html.markdown
new file mode 100644
index 00000000..cd55e116
--- /dev/null
+++ b/ru-ru/julia-ru.html.markdown
@@ -0,0 +1,750 @@
+---
+language: julia
+contributors:
+ - ["Leah Hanson", "http://leahhanson.us"]
+translators:
+ - ["Sergey Skovorodkin", "https://github.com/skovorodkin"]
+filename: learnjulia-ru.jl
+lang: ru-ru
+---
+
+Julia — гомоиконный функциональный язык программирования для технических расчётов.
+Несмотря на полную поддержку гомоиконных макросов, функций первого класса и конструкций управления низкого уровня, этот язык так же прост в изучении и применении, как и Python.
+
+Документ описывает текущую dev-версию Julia от 18-о октября 2013 года.
+
+```ruby
+
+# Однострочные комментарии начинаются со знака решётки.
+
+####################################################
+## 1. Примитивные типы данных и операторы
+####################################################
+
+# Всё в Julia — выражение.
+
+# Простые численные типы
+3 # => 3 (Int64)
+3.2 # => 3.2 (Float64)
+2 + 1im # => 2 + 1im (Complex{Int64})
+2//3 # => 2//3 (Rational{Int64})
+
+# Доступны все привычные инфиксные операторы
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+5 / 2 # => 2.5 # деление Int на Int всегда возвращает Float
+div(5, 2) # => 2 # для округления к нулю используется div
+5 \ 35 # => 7.0
+2 ^ 2 # => 4 # возведение в степень
+12 % 10 # => 2
+
+# С помощью скобок можно изменить приоритет операций
+(1 + 3) * 2 # => 8
+
+# Побитовые операторы
+~2 # => -3 # НЕ (NOT)
+3 & 5 # => 1 # И (AND)
+2 | 4 # => 6 # ИЛИ (OR)
+2 $ 4 # => 6 # сложение по модулю 2 (XOR)
+2 >>> 1 # => 1 # логический сдвиг вправо
+2 >> 1 # => 1 # арифметический сдвиг вправо
+2 << 1 # => 4 # логический/арифметический сдвиг влево
+
+# Функция bits возвращает бинарное представление числа
+bits(12345)
+# => "0000000000000000000000000000000000000000000000000011000000111001"
+bits(12345.0)
+# => "0100000011001000000111001000000000000000000000000000000000000000"
+
+# Логические значения являются примитивами
+true
+false
+
+# Булевы операторы
+!true # => false
+!false # => true
+1 == 1 # => true
+2 == 1 # => false
+1 != 1 # => false
+2 != 1 # => true
+1 < 10 # => true
+1 > 10 # => false
+2 <= 2 # => true
+2 >= 2 # => true
+# Сравнения можно объединять цепочкой
+1 < 2 < 3 # => true
+2 < 3 < 2 # => false
+
+# Строки объявляются с помощью двойных кавычек — "
+"This is a string."
+
+# Символьные литералы создаются с помощью одинарных кавычек — '
+'a'
+
+# Строки индексируются как массивы символов
+"This is a string"[1] # => 'T' # Индексы начинаются с единицы
+# Индексирование не всегда правильно работает для UTF8-строк,
+# поэтому рекомендуется использовать итерирование (map, for-циклы и т.п.).
+
+# Для строковой интерполяции используется знак доллара ($):
+"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
+# В скобках можно использовать любое выражение языка.
+
+# Другой способ форматирования строк — макрос printf
+@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
+
+####################################################
+## 2. Переменные и коллекции
+####################################################
+
+# Вывод
+println("I'm Julia. Nice to meet you!")
+
+# Переменные инициализируются без предварительного объявления
+some_var = 5 # => 5
+some_var # => 5
+
+# Попытка доступа к переменной до инициализации вызывает ошибку
+try
+ some_other_var # => ERROR: some_other_var not defined
+catch e
+ println(e)
+end
+
+# Имена переменных начинаются с букв.
+# После первого символа можно использовать буквы, цифры,
+# символы подчёркивания и восклицательные знаки.
+SomeOtherVar123! = 6 # => 6
+
+# Допустимо использование unicode-символов
+☃ = 8 # => 8
+# Это особенно удобно для математических обозначений
+2 * π # => 6.283185307179586
+
+# Рекомендации по именованию:
+# * имена переменных в нижнем регистре, слова разделяются символом
+# подчёркивания ('\_');
+#
+# * для имён типов используется CamelCase;
+#
+# * имена функций и макросов в нижнем регистре
+# без разделения слов символом подчёркивания;
+#
+# * имя функции, изменяющей переданные ей аргументы (in-place function),
+# оканчивается восклицательным знаком.
+
+# Массив хранит последовательность значений, индексируемых с единицы до n:
+a = Int64[] # => пустой массив Int64-элементов
+
+# Одномерный массив объявляется разделёнными запятой значениями.
+b = [4, 5, 6] # => массив из трёх Int64-элементов: [4, 5, 6]
+b[1] # => 4
+b[end] # => 6
+
+# Строки двумерного массива разделяются точкой с запятой.
+# Элементы строк разделяются пробелами.
+matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
+
+# push! и append! добавляют в список новые элементы
+push!(a,1) # => [1]
+push!(a,2) # => [1,2]
+push!(a,4) # => [1,2,4]
+push!(a,3) # => [1,2,4,3]
+append!(a,b) # => [1,2,4,3,4,5,6]
+
+# pop! удаляет из списка последний элемент
+pop!(b) # => возвращает 6; массив b снова равен [4,5]
+
+# Вернём 6 обратно
+push!(b,6) # b снова [4,5,6].
+
+a[1] # => 1 # индексы начинаются с единицы!
+
+# Последний элемент можно получить с помощью end
+a[end] # => 6
+
+# Операции сдвига
+shift!(a) # => 1 and a is now [2,4,3,4,5,6]
+unshift!(a,7) # => [7,2,4,3,4,5,6]
+
+# Восклицательный знак на конце названия функции означает,
+# что функция изменяет переданные ей аргументы.
+arr = [5,4,6] # => массив из 3 Int64-элементов: [5,4,6]
+sort(arr) # => [4,5,6]; но arr равен [5,4,6]
+sort!(arr) # => [4,5,6]; а теперь arr — [4,5,6]
+
+# Попытка доступа за пределами массива выбрасывает BoundsError
+try
+ a[0] # => ERROR: BoundsError() in getindex at array.jl:270
+ a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
+catch e
+ println(e)
+end
+
+# Вывод ошибок содержит строку и файл, где произошла ошибка,
+# даже если это случилось в стандартной библиотеке.
+# Если вы собрали Julia из исходных кодов,
+# то найти эти файлы можно в директории base.
+
+# Создавать массивы можно из последовательности
+a = [1:5] # => массив из 5 Int64-элементов: [1,2,3,4,5]
+
+# Срезы
+a[1:3] # => [1, 2, 3]
+a[2:] # => [2, 3, 4, 5]
+a[2:end] # => [2, 3, 4, 5]
+
+# splice! удаляет элемент из массива
+# Remove elements from an array by index with splice!
+arr = [3,4,5]
+splice!(arr,2) # => 4 ; arr теперь равен [3,5]
+
+# append! объединяет списки
+b = [1,2,3]
+append!(a,b) # теперь a равен [1, 2, 3, 4, 5, 1, 2, 3]
+
+# Проверка на вхождение
+in(1, a) # => true
+
+# Длина списка
+length(a) # => 8
+
+# Кортеж — неизменяемая структура.
+tup = (1, 2, 3) # => (1,2,3) # кортеж (Int64,Int64,Int64).
+tup[1] # => 1
+try:
+ tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
+catch e
+ println(e)
+end
+
+# Многие функции над списками работают и для кортежей
+length(tup) # => 3
+tup[1:2] # => (1,2)
+in(2, tup) # => true
+
+# Кортежи можно распаковывать в переменные
+a, b, c = (1, 2, 3) # => (1,2,3) # a = 1, b = 2 и c = 3
+
+# Скобки из предыдущего примера можно опустить
+d, e, f = 4, 5, 6 # => (4,5,6)
+
+# Кортеж из одного элемента не равен значению этого элемента
+(1,) == 1 # => false
+(1) == 1 # => true
+
+# Обмен значений
+e, d = d, e # => (5,4) # d = 5, e = 4
+
+
+# Словари содержат ассоциативные массивы
+empty_dict = Dict() # => Dict{Any,Any}()
+
+# Для создания словаря можно использовать литерал
+filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
+# => Dict{ASCIIString,Int64}
+
+# Значения ищутся по ключу с помощью оператора []
+filled_dict["one"] # => 1
+
+# Получить все ключи
+keys(filled_dict)
+# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# Заметьте, словарь не запоминает порядок, в котором добавляются ключи.
+
+# Получить все значения.
+values(filled_dict)
+# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# То же касается и порядка значений.
+
+# Проверка вхождения ключа в словарь
+in(("one", 1), filled_dict) # => true
+in(("two", 3), filled_dict) # => false
+haskey(filled_dict, "one") # => true
+haskey(filled_dict, 1) # => false
+
+# Попытка обратиться к несуществующему ключу выбросит ошибку
+try
+ filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
+catch e
+ println(e)
+end
+
+# Используйте метод get со значением по умолчанию, чтобы избежать этой ошибки
+# get(dictionary,key,default_value)
+get(filled_dict,"one",4) # => 1
+get(filled_dict,"four",4) # => 4
+
+# Для коллекций неотсортированных уникальных элементов используйте Set
+empty_set = Set() # => Set{Any}()
+# Инициализация множества
+filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
+
+# Добавление элементов
+push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
+
+# Проверка вхождения элементов во множество
+in(2, filled_set) # => true
+in(10, filled_set) # => false
+
+# Функции для получения пересечения, объединения и разницы.
+other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
+intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
+union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
+setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
+
+
+####################################################
+## 3. Поток управления
+####################################################
+
+# Создадим переменную
+some_var = 5
+
+# Выражение if. Отступы не имеют значения.
+if some_var > 10
+ println("some_var is totally bigger than 10.")
+elseif some_var < 10 # Необязательная ветка elseif.
+ println("some_var is smaller than 10.")
+else # else-ветка также опциональна.
+ println("some_var is indeed 10.")
+end
+# => prints "some var is smaller than 10"
+
+
+# Цикл for проходит по итерируемым объектам
+# Примеры итерируемых типов: Range, Array, Set, Dict и String.
+for animal=["dog", "cat", "mouse"]
+ println("$animal is a mammal")
+ # Для вставки значения переменной или выражения в строку используется $
+end
+# Выведет:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
+
+# Другой вариант записи.
+for animal in ["dog", "cat", "mouse"]
+ println("$animal is a mammal")
+end
+# Выведет:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
+
+for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
+ println("$(a[1]) is a $(a[2])")
+end
+# Выведет:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
+
+for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
+ println("$k is a $v")
+end
+# Выведет:
+# dog is a mammal
+# cat is a mammal
+# mouse is a mammal
+
+# Цикл while выполняется до тех пор, пока верно условие
+x = 0
+while x < 4
+ println(x)
+ x += 1 # Короткая запись x = x + 1
+end
+# Выведет:
+# 0
+# 1
+# 2
+# 3
+
+# Обработка исключений
+try
+ error("help")
+catch e
+ println("caught it $e")
+end
+# => caught it ErrorException("help")
+
+
+####################################################
+## 4. Функции
+####################################################
+
+# Для определения новой функции используется ключевое слово 'function'
+#function имя(аргументы)
+# тело...
+#end
+function add(x, y)
+ println("x is $x and y is $y")
+
+ # Функция возвращает значение последнего выражения
+ x + y
+end
+
+add(5, 6) # => Вернёт 11, напечатав "x is 5 and y is 6"
+
+# Функция может принимать переменное количество позиционных аргументов.
+function varargs(args...)
+ return args
+ # для возвращения из функции в любом месте используется 'return'
+end
+# => varargs (generic function with 1 method)
+
+varargs(1,2,3) # => (1,2,3)
+
+# Многоточие (...) — это splat.
+# Мы только что воспользовались им в определении функции.
+# Также его можно использовать при вызове функции,
+# где он преобразует содержимое массива или кортежа в список аргументов.
+Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # формирует множество массивов
+Set([1,2,3]...) # => Set{Int64}(1,2,3) # эквивалентно Set(1,2,3)
+
+x = (1,2,3) # => (1,2,3)
+Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # множество кортежей
+Set(x...) # => Set{Int64}(2,3,1)
+
+
+# Опциональные позиционные аргументы
+function defaults(a,b,x=5,y=6)
+ return "$a $b and $x $y"
+end
+
+defaults('h','g') # => "h g and 5 6"
+defaults('h','g','j') # => "h g and j 6"
+defaults('h','g','j','k') # => "h g and j k"
+try
+ defaults('h') # => ERROR: no method defaults(Char,)
+ defaults() # => ERROR: no methods defaults()
+catch e
+ println(e)
+end
+
+# Именованные аргументы
+function keyword_args(;k1=4,name2="hello") # обратите внимание на ;
+ return ["k1"=>k1,"name2"=>name2]
+end
+
+keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
+keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
+keyword_args() # => ["name2"=>"hello","k2"=>4]
+
+# В одной функции можно совмещать все виды аргументов
+function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
+ println("normal arg: $normal_arg")
+ println("optional arg: $optional_positional_arg")
+ println("keyword arg: $keyword_arg")
+end
+
+all_the_args(1, 3, keyword_arg=4)
+# Выведет:
+# normal arg: 1
+# optional arg: 3
+# keyword arg: 4
+
+# Функции в Julia первого класса
+function create_adder(x)
+ adder = function (y)
+ return x + y
+ end
+ return adder
+end
+
+# Анонимная функция
+(x -> x > 2)(3) # => true
+
+# Эта функция идентичная предыдущей версии create_adder
+function create_adder(x)
+ y -> x + y
+end
+
+# Если есть желание, можно воспользоваться полным вариантом
+function create_adder(x)
+ function adder(y)
+ x + y
+ end
+ adder
+end
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+
+# Встроенные функции высшего порядка
+map(add_10, [1,2,3]) # => [11, 12, 13]
+filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# Списковые сборки
+[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+
+####################################################
+## 5. Типы
+####################################################
+
+# Julia has a type system.
+# Каждое значение имеет тип, но переменные не определяют тип значения.
+# Функция `typeof` возвращает тип значения.
+typeof(5) # => Int64
+
+# Types are first-class values
+# Типы являются значениями первого класса
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
+# Тип DataType представляет типы, включая себя самого.
+
+# Типы используются в качестве документации, для оптимизации и организации.
+# Статически типы не проверяются.
+
+# Пользователь может определять свои типы
+# Типы похожи на структуры в других языках
+# Новые типы определяются с помощью ключевого слова `type`
+
+# type Name
+# field::OptionalType
+# ...
+# end
+type Tiger
+ taillength::Float64
+ coatcolor # отсутствие типа равносильно `::Any`
+end
+
+# Аргументы конструктора по умолчанию — свойства типа
+# в порядке их определения.
+tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
+
+# Тип объекта по сути является конструктором значений такого типа
+sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
+
+# Эти типы, похожие на структуры, называются конкретными.
+# Можно создавать объекты таких типов, но не их подтипы.
+# Другой вид типов — абстрактные типы.
+
+# abstract Name
+abstract Cat # просто имя и точка в иерархии типов
+
+# Объекты абстрактных типов создавать нельзя,
+# но зато от них можно наследовать подтипы.
+# Например, Number — это абстрактный тип.
+subtypes(Number) # => 6 элементов в массиве Array{Any,1}:
+ # Complex{Float16}
+ # Complex{Float32}
+ # Complex{Float64}
+ # Complex{T<:Real}
+ # ImaginaryUnit
+ # Real
+subtypes(Cat) # => пустой массив Array{Any,1}
+
+# У всех типов есть супертип. Для его определения есть функция `super`.
+typeof(5) # => Int64
+super(Int64) # => Signed
+super(Signed) # => Real
+super(Real) # => Number
+super(Number) # => Any
+super(super(Signed)) # => Number
+super(Any) # => Any
+# Все эти типы, за исключением Int64, абстрактные.
+
+# Для создания подтипа используется оператор <:
+type Lion <: Cat # Lion — это подтип Cat
+ mane_color
+ roar::String
+end
+
+# У типа может быть несколько конструкторов.
+# Для создания нового определите функцию с именем, как у типа,
+# и вызовите имеющийся конструктор.
+Lion(roar::String) = Lion("green",roar)
+# Мы создали внешний (т.к. он находится вне определения типа) конструктор.
+
+type Panther <: Cat # Panther — это тоже подтип Cat
+ eye_color
+
+ # Определим свой конструктор вместо конструктора по умолчанию
+ Panther() = new("green")
+end
+# Использование внутренних конструкторов позволяет
+# определять, как будут создаваться объекты типов.
+# Но по возможности стоит пользоваться внешними конструкторами.
+
+####################################################
+## 6. Мультиметоды
+####################################################
+
+# Все именованные функции являются generic-функциями,
+# т.е. все они состоят из разных методов.
+# Каждый конструктор типа Lion — это метод generic-функции Lion.
+
+# Приведём пример без использования конструкторов, создадим функцию meow
+
+# Определения Lion, Panther и Tiger
+function meow(animal::Lion)
+ animal.roar # доступ к свойству типа через точку
+end
+
+function meow(animal::Panther)
+ "grrr"
+end
+
+function meow(animal::Tiger)
+ "rawwwr"
+end
+
+# Проверка
+meow(tigger) # => "rawwr"
+meow(Lion("brown","ROAAR")) # => "ROAAR"
+meow(Panther()) # => "grrr"
+
+# Вспомним иерархию типов
+issubtype(Tiger,Cat) # => false
+issubtype(Lion,Cat) # => true
+issubtype(Panther,Cat) # => true
+
+# Определим функцию, принимающую на вход объекты типа Cat
+function pet_cat(cat::Cat)
+ println("The cat says $(meow(cat))")
+end
+
+pet_cat(Lion("42")) # => выведет "The cat says 42"
+try
+ pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
+catch e
+ println(e)
+end
+
+# В объектно-ориентированных языках распространена одиночная диспетчеризация —
+# подходящий метод выбирается на основе типа первого аргумента.
+# В Julia все аргументы участвуют в выборе нужного метода.
+
+# Чтобы понять разницу, определим функцию с несколькими аргументами.
+function fight(t::Tiger,c::Cat)
+ println("The $(t.coatcolor) tiger wins!")
+end
+# => fight (generic function with 1 method)
+
+fight(tigger,Panther()) # => выведет The orange tiger wins!
+fight(tigger,Lion("ROAR")) # => выведет The orange tiger wins!
+
+# Переопределим поведение функции, если Cat-объект является Lion-объектом
+fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
+# => fight (generic function with 2 methods)
+
+fight(tigger,Panther()) # => выведет The orange tiger wins!
+fight(tigger,Lion("ROAR")) # => выведет The green-maned lion wins!
+
+# Драться можно не только с тиграми!
+fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
+# => fight (generic function with 3 methods)
+
+fight(Lion("balooga!"),Panther()) # => выведет The victorious cat says grrr
+try
+ fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
+catch
+end
+
+# Вообще, пускай кошачьи могут первыми проявлять агрессию
+fight(c::Cat,l::Lion) = println("The cat beats the Lion")
+# => Warning: New definition
+# fight(Cat,Lion) at none:1
+# is ambiguous with
+# fight(Lion,Cat) at none:2.
+# Make sure
+# fight(Lion,Lion)
+# is defined first.
+#fight (generic function with 4 methods)
+
+# Предупреждение говорит, что неясно, какой из методов вызывать:
+fight(Lion("RAR"),Lion("brown","rarrr")) # => выведет The victorious cat says rarrr
+# Результат может оказаться разным в разных версиях Julia
+
+fight(l::Lion,l2::Lion) = println("The lions come to a tie")
+fight(Lion("RAR"),Lion("brown","rarrr")) # => выведет The lions come to a tie
+
+
+# Под капотом
+# Язык позволяет посмотреть на сгенерированные ассемблерный и LLVM-код.
+
+square_area(l) = l * l # square_area (generic function with 1 method)
+
+square_area(5) #25
+
+# Что происходит, когда мы передаём функции square_area целое число?
+code_native(square_area, (Int32,))
+ # .section __TEXT,__text,regular,pure_instructions
+ # Filename: none
+ # Source line: 1 # Вводная часть
+ # push RBP
+ # mov RBP, RSP
+ # Source line: 1
+ # movsxd RAX, EDI #
+ # imul RAX, RAX #
+ # pop RBP #
+ # ret #
+
+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 # Произведение чисел одинарной точности (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 # Произведение чисел двойной точности (AVX)
+ # pop RBP
+ # ret
+ #
+# Если хотя бы один из аргументов является числом с плавающей запятой,
+# то Julia будет использовать соответствующие инструкции.
+# Вычислим площать круга
+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 # Загрузить целое число (r)
+ # movabs RAX, 4593140240 # Загрузить 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
+ #
+```
+
+## Что дальше?
+
+Для более подробной информации читайте [документацию по языку](http://docs.julialang.org/en/latest/manual/)
+
+Если вам нужна помощь, задавайте вопросы в [списке рассылки](https://groups.google.com/forum/#!forum/julia-users).
diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown
new file mode 100644
index 00000000..72e3b9e0
--- /dev/null
+++ b/ru-ru/objective-c-ru.html.markdown
@@ -0,0 +1,317 @@
+---
+language: Objective-C
+filename: LearnObjectiveC.m
+contributors:
+ - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+translators:
+ - ["Evlogy Sutormin", "http://evlogii.com"]
+lang: ru-ru
+---
+
+Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple,
+построенный на основе языка Си и парадигм Smalltalk.
+В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения.
+
+```cpp
+// Однострочный комментарий
+
+/*
+Многострочный
+комментарий
+*/
+
+// Импорт файлов фреймворка Foundation с помощью #import
+#import <Foundation/Foundation.h>
+#import "MyClass.h"
+
+// Точка входа в программу это функция main,
+// которая возвращает целый тип integer
+int main (int argc, const char * argv[])
+{
+ // Создание autorelease pool для управления памятью
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // Используйте NSLog для печати в консоль
+ NSLog(@"Hello World!"); // Напечатает строку "Hello World!"
+
+ ///////////////////////////////////////
+ // Типы и переменные
+ ///////////////////////////////////////
+
+ // Простое объявление
+ int myPrimitive1 = 1;
+ long myPrimitive2 = 234554664565;
+
+ // Помещайте * в начало названия объекта для строго типизированного объявления
+ MyClass *myObject1 = nil; // Строгая типизация
+ id myObject2 = nil; // Слабая типизация
+
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
+ // %@ – это объект
+ // 'description' это общий для всех объектов метод вывода данных
+
+ // Строка
+ NSString *worldString = @"World";
+ NSLog(@"Hello %@!", worldString); // напечатает "Hello World!"
+
+ // Символьные литералы
+ NSNumber *theLetterZNumber = @'Z';
+ char theLetterZ = [theLetterZNumber charValue];
+ NSLog(@"%c", theLetterZ);
+
+ // Целочисленный литералы
+ NSNumber *fortyTwoNumber = @42;
+ int fortyTwo = [fortyTwoNumber intValue];
+ NSLog(@"%i", fortyTwo);
+
+ // Беззнаковый целочисленный литерал
+ NSNumber *fortyTwoUnsignedNumber = @42U;
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *fortyTwoLongNumber = @42L;
+ long fortyTwoLong = [fortyTwoLongNumber longValue];
+ NSLog(@"%li", fortyTwoLong);
+
+ // Вещественный литерал
+ NSNumber *piFloatNumber = @3.141592654F;
+ float piFloat = [piFloatNumber floatValue];
+ NSLog(@"%f", piFloat);
+
+ NSNumber *piDoubleNumber = @3.1415926535;
+ double piDouble = [piDoubleNumber doubleValue];
+ NSLog(@"%f", piDouble);
+
+ // BOOL (булевый) литерал
+ NSNumber *yesNumber = @YES;
+ NSNumber *noNumber = @NO;
+
+ // Массив
+ NSArray *anArray = @[@1, @2, @3, @4];
+ NSNumber *thirdNumber = anArray[2];
+ NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
+
+ // Словарь
+ NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
+ NSObject *valueObject = aDictionary[@"A Key"];
+ NSLog(@"Object = %@", valueObject); // Напечатает "Object = (null)"
+
+ ///////////////////////////////////////
+ // Операторы
+ ///////////////////////////////////////
+
+ // Операторы работают также как в Си.
+ // Например:
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (НЕТ)
+ 3 != 2; // => 1 (ДА)
+ 1 && 1; // => 1 (логическое И)
+ 0 || 1; // => 1 (логическое ИЛИ)
+ ~0x0F; // => 0xF0 (побитовое отрицание)
+ 0x0F & 0xF0; // => 0x00 (побитовое И)
+ 0x01 << 1; // => 0x02 (побитовый сдвиг влево (на 1))
+
+ ///////////////////////////////////////
+ // Структуры ветвления
+ ///////////////////////////////////////
+
+ // Условный оператор
+ if (NO)
+ {
+ NSLog(@"I am never run");
+ } else if (0)
+ {
+ NSLog(@"I am also never run");
+ } else
+ {
+ NSLog(@"I print");
+ }
+
+ // Ветвление с множественным выбором
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"I am never run");
+ } break;
+ case 1:
+ {
+ NSLog(@"I am also never run");
+ } break;
+ default:
+ {
+ NSLog(@"I print");
+ } break;
+ }
+
+ // Цикл с предусловием
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++ инкрементирует ii после передачи значения
+ } // => напечатает "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Цикл со счётчиком
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj);
+ } // => напечатает "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // // Цикл просмотра
+ NSArray *values = @[@0, @1, @2, @3];
+ for (NSNumber *value in values)
+ {
+ NSLog(@"%@,", value);
+ } // => напечатает "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Обработка исключений
+ @try
+ {
+ // Ваше исключение здесь
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"File Not Found on System" userInfo:nil];
+ } @catch (NSException * e)
+ {
+ NSLog(@"Exception: %@", e);
+ } @finally
+ {
+ NSLog(@"Finally");
+ } // => напечатает "Exception: File Not Found on System"
+ // "Finally"
+
+ ///////////////////////////////////////
+ // Объекты
+ ///////////////////////////////////////
+
+ // Создание объектов через выделение памяти и инициализацию.
+ // Объект не является полнофункциональным пока обе части не выполнятся.
+ MyClass *myObject = [[MyClass alloc] init];
+
+ // В Objective-C можель ООП базируется на передаче сообщений.
+ // В Objective-C Вы не просто вызваете метод; вы посылаете сообщение.
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Очищайте память, перед завершением работы программы.
+ [pool drain];
+
+ // Конец программы.
+ return 0;
+}
+
+///////////////////////////////////////
+// Классы и функции
+///////////////////////////////////////
+
+// Объявляйте свой класс в файле МойКласс.h
+// Синтаксис объявления:
+// @interface ИмяКласса : ИмяКлассаРодителя <ИмплементируемыеПротоколы>
+// {
+// Объявление переменных;
+// }
+// -/+ (тип) Объявление метода(ов).
+// @end
+
+
+@interface MyClass : NSObject <MyProtocol>
+{
+ int count;
+ id data;
+ NSString *name;
+}
+// При объявлении свойств сразу генерируются геттер и сеттер
+@property int count;
+@property (copy) NSString *name; // Скопировать объект в ходе присвоения.
+@property (readonly) id data; // Генерация только геттера
+
+// Методы
++/- (return type)methodSignature:(Parameter Type *)parameterName;
+
+// + для методов класса
++ (NSString *)classMethod;
+
+// - для метода объекта
+- (NSString *)instanceMethodWithParameter:(NSString *)string;
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
+
+@end
+
+// Имплементируйте методы в файле МойКласс.m:
+
+@implementation MyClass
+
+// Вызывается при высвобождении памяти под объектом
+- (void)dealloc
+{
+}
+
+// Конструкторы – это способ осздания объектов класса.
+// Это обычный конструктор вызываемый при создании объекта клсааа.
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ self.count = 1;
+ }
+ return self;
+}
+
++ (NSString *)classMethod
+{
+ return [[self alloc] init];
+}
+
+- (NSString *)instanceMethodWithParameter:(NSString *)string
+{
+ return @"New string";
+}
+
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
+{
+ return @42;
+}
+
+// Методы объявленные в МyProtocol (см. далее)
+- (void)myProtocolMethod
+{
+ // имплементация
+}
+
+@end
+
+/*
+ * Протокол объявляет методы которые должны быть имплементированы
+ * Протокол не является классом. Он просто определяет интерфейс,
+ * который должен быть имплементирован.
+ */
+
+@protocol MyProtocol
+ - (void)myProtocolMethod;
+@end
+```
+## На почитать
+
+[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/)
+
+[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
+
+[iOS разработчик: Обзор книг для новичка](http://habrahabr.ru/post/166213/)
+
+[Хочешь быть iOS разработчиком? Будь им!](http://www.pvsm.ru/ios/12662/print/)
diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown
new file mode 100644
index 00000000..edcac4dd
--- /dev/null
+++ b/ru-ru/php-ru.html.markdown
@@ -0,0 +1,663 @@
+---
+language: php
+contributors:
+ - ["Malcolm Fell", "http://emarref.net/"]
+ - ["Trismegiste", "https://github.com/Trismegiste"]
+translators:
+ - ["SlaF", "https://github.com/SlaF"]
+lang: ru-ru
+filename: learnphp-ru.php
+---
+
+Этот документ описывает версию PHP 5 и выше.
+
+```php
+<?php // PHP код должен быть заключен в теги <?php
+
+// Если ваш файл содержит только PHP код, то можно
+// пропустить закрывающийся ?>
+
+// А так начинаются комментарии
+
+# Это тоже комментарий но // предпочтительнее
+
+/*
+ Окруженный /* и */ текст превращается
+ в многострочный комментарий
+*/
+
+// Используйте "echo" или "print" для вывода.
+print('Hello '); // Напечатать "Hello " без перевода строки
+
+// () необязательно применять для print и echo
+echo "World\n"; // Печатать "World" и перейти на новую строку.
+// (все утверждения должны заканчиваться ;)
+
+// Любые символы за пределами закрывающегося тега выводятся автоматически:
+?>
+Hello World Again!
+<?php
+
+
+/************************************
+ * Типы и Переменные
+ */
+
+// Переменные начинаются с символа $.
+// Правильное имя переменной начинается с буквы или знака подчеркивания,
+// и может содержать любые цифры, буквы, или знаки подчеркивания.
+// Не рекомендуется использовать кирилические символы в именах (прим. пер.)
+
+// Логические значения нечувствительны к регистру
+$boolean = true; // или TRUE или True
+$boolean = false; // или FALSE или False
+
+// Целые числа
+$int1 = 12; // => 12
+$int2 = -12; // => -12-
+$int3 = 012; // => 10 (ведущий 0 обозначает восьмеричное число)
+$int4 = 0x0F; // => 15 (ведущие символы 0x означает шестнадцатеричное число)
+
+// Дробные числа
+$float = 1.234;
+$float = 1.2e3;
+$float = 7E-10;
+
+// Арифметика
+$sum = 1 + 1; // 2
+$difference = 2 - 1; // 1
+$product = 2 * 2; // 4
+$quotient = 2 / 1; // 2
+
+// Арифметические сокращения
+$number = 0;
+$number += 1; // Увеличивает $number на 1
+echo $number++; // Печатает 1 (инкрементируется после вывода)
+echo ++$number; // Печатает 3 (инкрементируется до вывода)
+$number /= $float; // Делится и результат присваивается $number
+
+// Строки должны быть заключены в одинарные кавычки;
+$sgl_quotes = '$String'; // => '$String'
+
+// Избегайте двойных кавычек за исключением случаев интерполирования переменной
+$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
+
+// Специальные (escape) символы работают только в двойных кавычках
+$escaped = "This contains a \t tab character.";
+$unescaped = 'This just contains a slash and a t: \t';
+
+// Заключайте переменные в фигурные скобки если это необходимо
+$money = "I have $${number} in the bank.";
+
+// Начиная с PHP 5.3, синтаксис nowdocs может использоваться для
+// неинтерполированного многострочного текста
+$nowdoc = <<<'END'
+Multi line
+string
+END;
+
+// Heredocs поддерживает интерполяцию переменных
+$heredoc = <<<END
+Multi line
+$sgl_quotes
+END;
+
+// Строки соединяются при помощи .
+echo 'This string ' . 'is concatenated';
+
+
+/********************************
+ * Константы
+ */
+
+// Константа определяется при помощи define()
+// и никогда не может быть изменена во время выполнения программы!
+
+// Правильное имя константы начинается с буквы или символа подчеркивания,
+// и содержит любое колличество букв, цифр и знаков подчеркивания.
+define("FOO", "something");
+
+// Доступ к константе возможен через прямое указание её имени
+echo 'This outputs '.FOO;
+
+/********************************
+ * Массивы
+ */
+
+// Все массивы в PHP - это ассоциативные массивы или хеши,
+
+// Ассоциативные массивы, известные в других языках как хеш-карты.
+
+// Работает во всех версиях РHP
+$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
+
+// В PHP 5.4 появился новый синтаксис
+$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
+
+echo $associative['One']; // печатает 1
+
+// Список тоже содержит целочисленные ключи
+$array = ['One', 'Two', 'Three'];
+echo $array[0]; // => "One"
+
+
+/********************************
+ * Вывод
+ */
+
+echo('Hello World!');
+// Печатает Hello World! на stdout.
+// Stdout это веб-страница запущенная в браузере.
+
+print('Hello World!'); // Аналогично echo
+
+// echo - это конструкция языка, вы можете опустить скобки.
+echo 'Hello World!';
+print 'Hello World!'; // Выводит Hello World!
+
+$paragraph = 'paragraph';
+
+echo 100; // Печать скалярной переменной напрямую
+echo $paragraph; // или печать переменной
+
+// Если короткие теги разрешены, или ваша версия PHP >= 5.4
+// вы можете использовать сокращенный синтаксис echo
+?>
+<p><?= $paragraph ?></p>
+<?php
+
+$x = 1;
+$y = 2;
+$x = $y; // $x теперь содержит значение переменной $y
+$z = &$y;
+// $z содержит ссылку на $y. Изменение значения $z затронет значение $y и наоборот.
+// Значение $x остается неизменным.
+
+echo $x; // => 2
+echo $z; // => 2
+$y = 0;
+echo $x; // => 2
+echo $z; // => 0
+
+
+/********************************
+ * Логические выражения
+ */
+$a = 0;
+$b = '0';
+$c = '1';
+$d = '1';
+
+// Утверждение (assert) выдает предупреждение если аргумент не true
+
+// Эти сравнения всегда будут истинными, даже если типы будут различаться
+assert($a == $b); // "равно"
+assert($c != $a); // "не равно"
+assert($c <> $a); // другое обозначение "не равно"
+assert($a < $c); // меньше
+assert($c > $b); // больше
+assert($a <= $b); // меньше или равно
+assert($c >= $d); // больше или равно
+
+// Следующие утверждения истинны если переменные имеют одинаковый тип.
+assert($c === $d);
+assert($a !== $d);
+assert(1 == '1');
+assert(1 !== '1');
+
+// Переменные могут изменять тип, в зависимости от их использования.
+$integer = 1;
+echo $integer + $integer; // => 2
+
+$string = '1';
+echo $string + $string; // => 2 (строка превращается в число)
+
+// Выводится 0 по той причине, что оператор + не может привести строку 'one' к
+// числовому типу
+$string = 'one';
+echo $string + $string; // => 0
+
+// Приведение типов (type casting) может быть использовано для преобразование
+// переменной в другой тип
+$boolean = (boolean) 1; // => true
+
+$zero = 0;
+$boolean = (boolean) $zero; // => false
+
+// Также существуют функции выполняющие приведение типов
+$integer = 5;
+$string = strval($integer);
+$float = floatval($integer);
+
+$var = null; // Null
+
+// И похожая по действию функция
+$integer = 10;
+$boolen = settype($integer, "string") // теперь $integer имеет строковый тип
+
+// settype возвращает true - если преобразование удалось и false в противном случае
+
+/********************************
+ * Управляющие структуры
+ */
+
+if (true) {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'I don\'t';
+} else {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'Does not get printed';
+} elseif(true) {
+ print 'Does';
+}
+
+// Тернарный оператор
+print (false ? 'Does not get printed' : 'Does');
+
+$x = 0;
+if ($x === '0') {
+ print 'Does not print';
+} elseif($x == '1') {
+ print 'Does not print';
+} else {
+ print 'Does print';
+}
+
+// Альтернативный синтаксис полезный для шаблонов
+?>
+
+<?php if ($x): ?>
+This is displayed if the test is truthy.
+<?php else: ?>
+This is displayed otherwise.
+<?php endif; ?>
+
+<?php
+
+// Использование switch.
+switch ($x) {
+ case '0':
+ print 'Switch does type coercion';
+ break; // You must include a break, or you will fall through
+ // to cases 'two' and 'three'
+ case 'two':
+ case 'three':
+ // Do something if $variable is either 'two' or 'three'
+ break;
+ default:
+ // Do something by default
+}
+
+// Циклы: while, do...while и for
+$i = 0;
+while ($i < 5) {
+ echo $i++;
+}; // Prints "01234"
+
+echo "\n";
+
+$i = 0;
+do {
+ echo $i++;
+} while ($i < 5); // Prints "01234"
+
+echo "\n";
+
+for ($x = 0; $x < 10; $x++) {
+ echo $x;
+} // Prints "0123456789"
+
+echo "\n";
+
+$wheels = ['bicycle' => 2, 'car' => 4];
+
+// Циклы foreach могут обходить массивы
+foreach ($wheels as $wheel_count) {
+ echo $wheel_count;
+} // Prints "24"
+
+echo "\n";
+
+// Вы можете обходить как ключи, так и их значения
+foreach ($wheels as $vehicle => $wheel_count) {
+ echo "A $vehicle has $wheel_count wheels";
+}
+
+echo "\n";
+
+$i = 0;
+while ($i < 5) {
+ if ($i === 3) {
+ break; // Exit out of the while loop
+ }
+ echo $i++;
+} // Prints "012"
+
+for ($i = 0; $i < 5; $i++) {
+ if ($i === 3) {
+ continue; // Skip this iteration of the loop
+ }
+ echo $i;
+} // Prints "0124"
+
+
+/********************************
+ * Функции
+ */
+
+// Определение функции:
+function my_function () {
+ return 'Hello';
+}
+
+echo my_function(); // => "Hello"
+
+// Правильное имя функции начинается с буквы или символа подчеркивания
+// и состоит из букв, цифр или знаков подчеркивания.
+
+function add ($x, $y = 1) { // $y по умолчанию равно 1
+ $result = $x + $y;
+ return $result;
+}
+
+echo add(4); // => 5
+echo add(4, 2); // => 6
+
+// $result недоступна за пределами функции
+// print $result; // Выдает предупреждение
+
+// Начиная с PHP 5.3 вы можете объявлять анонимные функции:
+$inc = function ($x) {
+ return $x + 1;
+};
+
+echo $inc(2); // => 3
+
+function foo ($x, $y, $z) {
+ echo "$x - $y - $z";
+}
+
+// Функции могут возвращать функции
+function bar ($x, $y) {
+ // Используйте 'use' для передачи внешних переменных
+ return function ($z) use ($x, $y) {
+ foo($x, $y, $z);
+ };
+}
+
+$bar = bar('A', 'B');
+$bar('C'); // Prints "A - B - C"
+
+// Вы можете вызывать именованные функции используя строки
+$function_name = 'add';
+echo $function_name(1, 2); // => 3
+// Полезно для программного определения запущенной функции.
+// Или используйте call_user_func(callable $callback [, $parameter [, ... ]]);
+
+
+/********************************
+ * Includes
+ */
+
+<?php
+// PHP код внутри включаемого файла должен начинаться с тега PHP.
+
+include 'my-file.php';
+// Код в файле my-file.php теперь доступен в текущем в текущем пространстве имен.
+// Если файл не удалось включить, будет выдано предупреждение.
+
+include_once 'my-file.php';
+// Если код в файле my-file.php уже был включен, он не будет включен повторно.
+// Это предотвращает ошибку повторного включения файла.
+
+require 'my-file.php';
+require_once 'my-file.php';
+
+// Same as include(), except require() will cause a fatal error if the
+// file cannot be included.
+// Действует также как и include(), но если файл не удалось подключить,
+// функция выдает неисправимую ошибку
+
+// Содержимое файла my-include.php:
+<?php
+
+return 'Anything you like.';
+// Конец файла
+
+// Эти функции могут также возвращать значения.
+$value = include 'my-include.php';
+
+// Имена файлов содержат их путь в файловой системе, или если передано просто
+// имя файла, PHP обращается к директиве include_path. Если файл не найден в
+// include_path, предпринимается попытка поиска в папке, где выполняется скрипт
+// или в текущей рабочей директории. Если не в одном из этих мест файл не
+// найден - выдается ошибка
+/* */
+
+/********************************
+ * Классы
+ */
+
+// Классы определяются при помощи ключевого слова "class"
+
+class MyClass
+{
+ const MY_CONST = 'value'; // A constant
+
+ static $staticVar = 'static';
+
+ // Properties must declare their visibility
+ public $property = 'public';
+ public $instanceProp;
+ protected $prot = 'protected'; // Accessible from the class and subclasses
+ private $priv = 'private'; // Accessible within the class only
+
+ // Create a constructor with __construct
+ public function __construct($instanceProp) {
+ // Access instance variables with $this
+ $this->instanceProp = $instanceProp;
+ }
+
+ // Methods are declared as functions inside a class
+ public function myMethod()
+ {
+ print 'MyClass';
+ }
+
+ final function youCannotOverrideMe()
+ {
+ }
+
+ public static function myStaticMethod()
+ {
+ print 'I am static';
+ }
+}
+
+echo MyClass::MY_CONST; // Выведет 'value';
+echo MyClass::$staticVar; // Выведет 'static';
+MyClass::myStaticMethod(); // Выведет 'I am static';
+
+// Новый экземпляр класса используя new
+$my_class = new MyClass('An instance property');
+
+// Если аргументы отсутствуют, можно не ставить круглые скобки
+
+// Доступ к членам класса используя ->
+echo $my_class->property; // => "public"
+echo $my_class->instanceProp; // => "An instance property"
+$my_class->myMethod(); // => "MyClass"
+
+// Наследование классов используя "extends"
+class MyOtherClass extends MyClass
+{
+ function printProtectedProperty()
+ {
+ echo $this->prot;
+ }
+
+ // Override a method
+ function myMethod()
+ {
+ parent::myMethod();
+ print ' > MyOtherClass';
+ }
+}
+
+$my_other_class = new MyOtherClass('Instance prop');
+$my_other_class->printProtectedProperty(); // => Выведет "protected"
+$my_other_class->myMethod(); // Выведет "MyClass > MyOtherClass"
+
+final class YouCannotExtendMe
+{
+}
+
+// Вы можете использовать "магические методы" для создания геттеров и сеттеров
+class MyMapClass
+{
+ private $property;
+
+ public function __get($key)
+ {
+ return $this->$key;
+ }
+
+ public function __set($key, $value)
+ {
+ $this->$key = $value;
+ }
+}
+
+$x = new MyMapClass();
+echo $x->property; // Будет использован метод __get()
+$x->property = 'Something'; // Будет использован метод __set()
+
+// Классы могут быть абстрактными (используя ключевое слово abstract)
+// или реализовывать интерфейсы (используя ключевое слово implements).
+// Интерфейсы определяются при помощи ключевого слова interface
+
+interface InterfaceOne
+{
+ public function doSomething();
+}
+
+interface InterfaceTwo
+{
+ public function doSomethingElse();
+}
+
+// Интерфейсы могут быть расширены
+interface InterfaceThree extends InterfaceTwo
+{
+ public function doAnotherContract();
+}
+
+abstract class MyAbstractClass implements InterfaceOne
+{
+ public $x = 'doSomething';
+}
+
+class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo $x;
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+// Классы могут реализовывать более одного интерфейса
+class SomeOtherClass implements InterfaceOne, InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo 'doSomething';
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+
+/********************************
+ * Трейты
+ */
+
+// Трейты появились в PHP 5.4.0 и объявляются при помощи ключевого слова trait
+
+trait MyTrait
+{
+ public function myTraitMethod()
+ {
+ print 'I have MyTrait';
+ }
+}
+
+class MyTraitfulClass
+{
+ use MyTrait;
+}
+
+$cls = new MyTraitfulClass();
+$cls->myTraitMethod(); // Prints "I have MyTrait"
+
+
+/********************************
+ * Пространства имен
+ */
+
+// Это секция особая, ведь объявление пространства имен
+// должно быть самым первым в файле. Позвольте сделать вид, что это не так
+
+<?php
+
+// По умолчанию, классы существуют в глобальном пространстве имен и могут быть
+// вызваны с обратным слешем.
+
+$cls = new \MyClass();
+
+// Задание пространства имен файла
+namespace My\Namespace;
+
+class MyClass
+{
+}
+
+// (из другого файла)
+$cls = new My\Namespace\MyClass;
+
+// Или внутри другого пространства имен.
+namespace My\Other\Namespace;
+
+use My\Namespace\MyClass;
+
+$cls = new MyClass();
+
+// Или вы можете создать псевдоним для пространства имен:
+namespace My\Other\Namespace;
+
+use My\Namespace as SomeOtherNamespace;
+
+$cls = new SomeOtherNamespace\MyClass();
+
+*/
+
+```
+
+## Смотрите также:
+Посетите страницу [официальной документации PHP](http://www.php.net/manual/) для справки.
+Если вас интересуют полезные приемы использования PHP посетите [PHP The Right Way](http://www.phptherightway.com/).
+Если вы раньше пользовались языком с хорошей организацией пакетов, посмотрите [Composer](http://getcomposer.org/).
+Для изучения стандартов использования языка посетите PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards).
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
new file mode 100644
index 00000000..204eb357
--- /dev/null
+++ b/ru-ru/python-ru.html.markdown
@@ -0,0 +1,493 @@
+---
+language: python
+lang: ru-ru
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Yury Timofeev", "http://twitter.com/gagar1n"]
+filename: learnpython-ru.py
+---
+
+Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных
+языков. Я люблю его за его понятный и доходчивый синтаксис - это почти что исполняемый псевдокод.
+
+С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [google's email service]
+
+Замечание: Эта статья относится к Python 2.7, но должно работать и в Python 2.x. Скоро будет версия и для Python 3!
+
+```python
+# Однострочные комментарии начинаются с hash-символа.
+""" Многострочный текст может быть
+ записан, используя 3 знака " и обычно используется
+ в качестве комментария
+"""
+
+####################################################
+## 1. Примитивные типы данных и операторов
+####################################################
+
+# У вас есть числа
+3 #=> 3
+
+# Математика работает вполне ожидаемо
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# А вот деление немного сложнее. В этом случае происходит деление
+# целых чисел и результат автоматически округляется в меньшую сторону.
+5 / 2 #=> 2
+
+# Чтобы научиться делить, сначала нужно немного узнать о дробных числах.
+2.0 # Это дробное число
+11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
+
+# Приоритет операций указывается скобками
+(1 + 3) * 2 #=> 8
+
+# Логические значения являются примитивами
+True
+False
+
+# Для отрицания используется ключевое слово not
+not True #=> False
+not False #=> True
+
+# Равенство это ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Неравенство это !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Еще немного сравнений
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Сравнения могут быть соединены в цепь!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Строки определяются символом " или '
+"Это строка."
+'Это тоже строка.'
+
+# И строки тоже могут складываться!
+"Привет " + "мир!" #=> "Привет мир!"
+
+# Со строкой можно работать, как со списком символов
+"Это строка"[0] #=> 'Э'
+
+# Символ % используется для форматирования строк, например:
+"%s могут быть %s" % ("строки", "интерполированы")
+
+# Новый метод форматирования строк - использование метода format.
+# Это предпочитаемый способ.
+"{0} могут быть {1}".format("строки", "форматированы")
+# Если вы не хотите считать, можете использовать ключевые слова.
+"{name} хочет есть {food}".format(name="Боб", food="лазанью")
+
+# None является объектом
+None #=> None
+
+# Не используйте оператор равенства '=='' для сравнения
+# объектов с None. Используйте для этого 'is'
+"etc" is None #=> False
+None is None #=> True
+
+# Оператор 'is' проверяет идентичность объектов. Он не
+# очень полезен при работе с примитивными типами, но
+# зато просто незаменим при работе с объектами.
+
+# None, 0, и пустые строки/списки равны False.
+# Все остальные значения равны True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Переменные и коллекции
+####################################################
+
+# Печатать довольно просто
+print "Я Python. Приятно познакомиться!"
+
+
+# Необязательно объявлять переменные перед их инициализацией.
+some_var = 5 # По соглашению используется нижний_регистр_с_подчеркиваниями
+some_var #=> 5
+
+# При попытке доступа к неинициализированной переменной,
+# выбрасывается исключение.
+# См. раздел "Поток управления" для информации об исключениях.
+some_other_var # Выбрасывает ошибку именования
+
+# if может быть использован как выражение
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Списки хранят последовательности
+li = []
+# Можно сразу начать с заполненным списком
+other_li = [4, 5, 6]
+
+# Объекты добавляются в конец списка методом append
+li.append(1) # [1]
+li.append(2) # [1, 2]
+li.append(4) # [1, 2, 4]
+li.append(3) # [1, 2, 4, 3]
+# И удаляются с конца методом pop
+li.pop() #=> возвращает 3 и li становится равен [1, 2, 4]
+# Положим элемент обратно
+li.append(3) # [1, 2, 4, 3].
+
+# Обращайтесь со списком, как с обычным массивом
+li[0] #=> 1
+# Обратимся к последнему элементу
+li[-1] #=> 3
+
+# Попытка выйти за границы массива приведет к IndexError
+li[4] # Выдает IndexError
+
+# Можно обращаться к диапазону, используя "кусочный синтаксис" (slice syntax)
+# (Для тех, кто любит математику, это называется замкнуто/открытый интервал.)
+li[1:3] #=> [2, 4]
+# Опускаем начало
+li[2:] #=> [4, 3]
+# Опускаем конец
+li[:3] #=> [1, 2, 4]
+
+# Удаляем произвольные элементы из списка оператором del
+del li[2] # [1, 2, 3]
+
+# Вы можете складывать списки
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Замечание: li и other_li остаются нетронутыми
+
+# Конкатенировать списки можно методом extend
+li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
+
+# Проверить элемент на вхождение в список можно оператором in
+1 in li #=> True
+
+# Длина списка вычисляется функцией len
+len(li) #=> 6
+
+
+# Кортежи - это такие списки, только неизменяемые
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Выдает TypeError
+
+# Все то же самое можно делать и с кортежами
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Вы можете распаковывать кортежи (или списки) в переменные
+a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+# Кортежи создаются по умолчанию, если опущены скобки
+d, e, f = 4, 5, 6
+# Обратите внимание, как легко поменять местами значения двух переменных
+e, d = d, e # теперь d == 5, а e == 4
+
+
+# Словари содержат ассоциативные массивы
+empty_dict = {}
+# Вот так описывается предзаполненный словарь
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Значения ищутся по ключу с помощью оператора []
+filled_dict["one"] #=> 1
+
+# Можно получить все ключи в виде списка
+filled_dict.keys() #=> ["three", "two", "one"]
+# Замечание - сохранение порядка ключей в словаре не гарантируется
+# Ваши результаты могут не совпадать с этими.
+
+# Можно получить и все значения в виде списка
+filled_dict.values() #=> [3, 2, 1]
+# То же самое замечание насчет порядка ключей справедливо и здесь
+
+# При помощи оператора in можно проверять ключи на вхождение в словарь
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Попытка получить значение по несуществующему ключу выбросит KeyError
+filled_dict["four"] # KeyError
+
+# Чтобы избежать этого, используйте метод get
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# Метод get также принимает аргумент default, значение которого будет
+# возвращено при отсутствии указанного ключа
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# Метод setdefault - это безопасный способ добавить новую пару ключ-значение в словарь
+filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] по прежнему возвращает 5
+
+
+# Множества содержат... ну, в общем, множества
+empty_set = set()
+# Инициализация множества набором значений
+some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
+
+# Начиная с Python 2.7, вы можете использовать {} чтобы обьявить множество
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Добавление новых элементов в множество
+filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
+
+# Пересечение множеств: &
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Объединение множеств: |
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Разность множеств: -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Проверка на вхождение во множество: in
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Поток управления
+####################################################
+
+# Для начала заведем переменную
+some_var = 5
+
+# Так выглядит выражение if. Отступы в python очень важны!
+# результат: "some_var меньше, чем 10"
+if some_var > 10:
+ print "some_var намного больше, чем 10."
+elif some_var < 10: # Выражение elif необязательно.
+ print "some_var меньше, чем 10."
+else: # Это тоже необязательно.
+ print "some_var равно 10."
+
+
+"""
+Циклы For проходят по спискам
+
+Результат:
+ собака это млекопитающее
+ кошка это млекопитающее
+ мышь это млекопитающее
+"""
+for animal in ["собака", "кошка", "мышь"]:
+ # Можете использовать оператор % для интерполяции форматированных строк
+ print "%s это млекопитающее" % animal
+
+"""
+`range(number)` возвращает список чисел
+от нуля до заданного числа
+Результат:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
+Результат:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # То же самое, что x = x + 1
+
+# Обрабывайте исключения блоками try/except
+
+# Работает в Python 2.6 и выше:
+try:
+ # Для выбора ошибки используется raise
+ raise IndexError("Это IndexError")
+except IndexError as e:
+ # pass это просто отсутствие оператора. Обычно здесь происходит
+ # восстановление от ошибки.
+ pass
+
+
+####################################################
+## 4. Функции
+####################################################
+
+# Используйте def для создания новых функций
+def add(x, y):
+ print "x равен %s, а y равен %s" % (x, y)
+ return x + y # Возвращайте результат выражением return
+
+# Вызов функции с аргументами
+add(5, 6) #=> prints out "x равен 5, а y равен 6" и возвращает 11
+
+# Другой способ вызова функции с аргументами
+add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
+
+# Вы можете определить функцию, принимающую неизвестное количество аргументов
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# А также можете определить функцию, принимающую изменяющееся количество
+# именованных аргументов
+def keyword_args(**kwargs):
+ return kwargs
+
+# Вызовем эту функцию и посмотрим, что из этого получится
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Если хотите, можете использовать оба способа одновременно
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) выводит:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Вызывая функции, можете сделать наоборот!
+# Используйте символ * для передачи кортежей и ** для передачи словарей
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # эквивалент foo(1, 2, 3, 4)
+all_the_args(**kwargs) # эквивалент foo(a=3, b=4)
+all_the_args(*args, **kwargs) # эквивалент foo(1, 2, 3, 4, a=3, b=4)
+
+# Python имеет функции первого класса
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Также есть и анонимные функции
+(lambda x: x > 2)(3) #=> True
+
+# Есть встроенные функции высшего порядка
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Мы можем использовать списки для удобного отображения и фильтрации
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. Классы
+####################################################
+
+# Чтобы получить класс, мы наследуемся от object.
+class Human(object):
+
+ # Атрибут класса. Он разделяется всеми экземплярами этого класса
+ species = "H. sapiens"
+
+ # Обычный конструктор
+ def __init__(self, name):
+ # Присваивание значения аргумента атрибуту класса name
+ self.name = name
+
+ # Метод экземпляра. Все методы принимают self в качестве первого аргумента
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Метод класса разделяется между всеми экземплярами
+ # Они вызываются с указыванием вызывающего класса в качестве первого аргумента
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Статический метод вызывается без ссылки на класс или экземпляр
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Инстанцирование класса
+i = Human(name="Иван")
+print i.say("привет") # "Иван: привет"
+
+j = Human("Петр")
+print j.say("Привет") # "Петр: привет"
+
+# Вызов метода класса
+i.get_species() #=> "H. sapiens"
+
+# Присвоение разделяемому атрибуту
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Вызов статического метода
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Модули
+####################################################
+
+# Вы можете импортировать модули
+import math
+print math.sqrt(16) #=> 4
+
+# Вы можете импортировать отдельные функции модуля
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Можете импортировать все функции модуля.
+# (Хотя это и не рекомендуется)
+from math import *
+
+# Можете сокращать имена модулей
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Модули в Python это обычные файлы с кодом python. Вы
+# можете писать свои модули и импортировать их. Название
+# модуля совпадает с названием файла.
+
+# Вы можете узнать, какие функции и атрибуты определены
+# в модуле
+import math
+dir(math)
+
+
+```
+
+## Хотите еще?
+
+### Бесплатные онлайн-материалы
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Платные
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown
new file mode 100644
index 00000000..318e0e09
--- /dev/null
+++ b/ru-ru/ruby-ru.html.markdown
@@ -0,0 +1,468 @@
+---
+language: ruby
+lang: ru-ru
+filename: learnruby-ru.rb
+contributors:
+ - ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
+ - ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+translators:
+ - ["Alexey Makarov", "https://github.com/Anakros"]
+---
+
+```ruby
+# Это комментарий
+
+=begin
+Это многострочный комментарий
+Никто их не использует
+И они не рекомендуются к использованию
+=end
+
+# Первое и самое главное: Всё является объектом.
+
+# Числа это объекты
+
+3.class #=> Fixnum
+
+3.to_s #=> "3"
+
+
+# Немного простой арифметики
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Арифметика -- это синтаксический сахар
+# над вызовом метода для объекта
+1.+(3) #=> 4
+10.* 5 #=> 50
+
+# Логические величины -- это объекты
+nil # Здесь ничего нет
+true # истина
+false # ложь
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Операция равенства
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Операция неравенства
+1 != 1 #=> false
+2 != 1 #=> true
+!true #=> false
+!false #=> true
+
+# nil -- имеет такое же логическое значение, как и false
+
+!nil #=> true
+!false #=> true
+!0 #=> false
+
+# Больше операций сравнения
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Строки -- это объекты
+
+'Я строка'.class #=> String
+"Я тоже строка".class #=> String
+
+placeholder = "использовать интерполяцию строк"
+"Я могу #{placeholder}, когда создаю строку с двойными кавычками"
+#=> "Я могу использовать интерполяцию строк,
+# когда создаю строку с двойными кавычками"
+
+
+# печатать в стандартный вывод
+puts "Я печатаюсь!"
+
+# Переменные
+x = 25 #=> 25
+x #=> 25
+
+# Присваивание значения возвращает то самое присвоенное значение.
+# Это позволяет делать множественные присваивания:
+
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# По соглашению, используйте snake_case для имён переменных
+snake_case = true
+
+# Используйте подробные имена для переменных
+# Но не переборщите!
+path_to_project_root = '/good/name/'
+path = '/bad/name/'
+
+# Идентификаторы (тоже объекты)
+
+# Идентификаторы -- это неизменяемые, многоразовые константы.
+# Для каждого идентификатора (кроме текста) сохраняется цифровой хэш.
+# При последующем использовании идентификатора, заместо создания нового объекта,
+# будет найден уже существующий по цифровому хэшу.
+# Они часто используются вместо строк для ускорения работы приложений
+
+:pending.class #=> Symbol
+
+status = :pending
+
+status == :pending #=> true
+
+status == 'pending' #=> false
+
+status == :approved #=> false
+
+# Массивы
+
+# Это массив
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# Массив может содержать различные типы значений
+
+[1, "hello", false] #=> [1, "hello", false]
+
+# Значение в массиве можно получить по индексу с левой границы
+array[0] #=> 1
+array[12] #=> nil
+
+# Как и арифметика, доступ к значению в массиве
+# это синтаксический сахар над вызовом метода для объекта
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# Также, можно получить по индексу с правой границы
+array[-1] #=> 5
+
+# С заданными левой и правой границами индексов
+array[2, 4] #=> [3, 4, 5]
+
+# Или с использованием диапазона значений
+array[1..3] #=> [2, 3, 4]
+
+# Вот так можно добавить значение в массив
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Хэши -- это массив пар "ключ => значение".
+# Хэши объявляются с использованием фигурных скобок:
+hash = {'color' => 'green', 'number' => 5}
+
+hash.keys #=> ['color', 'number']
+
+# Значение в хэше легко может быть найдено по ключу:
+hash['color'] #=> 'green'
+hash['number'] #=> 5
+
+# Поиск по ключу, которого в хэше нет вернёт nil:
+hash['nothing here'] #=> nil
+
+# начиная с Ruby 1.9, существует специальный синтаксис
+# при использовании идентификаторов как ключей хэша:
+
+new_hash = { defcon: 3, action: true}
+
+new_hash.keys #=> [:defcon, :action]
+
+# Массивы и Хэши -- перечисляемые типы данных
+# У них есть много полезных методов, например: each, map, count и другие
+
+# Управление ходом выполнения (Управляющие структуры)
+
+if true
+ "Если истина"
+elsif false
+ "Иначе, если ложь (опционально)"
+else
+ "Во всех других случаях"
+end
+
+for counter in 1..5
+ puts "итерация #{counter}"
+end
+#=> итерация 1
+#=> итерация 2
+#=> итерация 3
+#=> итерация 4
+#=> итерация 5
+
+# Однако, никто не использует "for" для циклов.
+# Вместо него Вы должны использовать метод "each" вместе с блоком кода.
+#
+# Блок кода -- это один из вариантов создания замыканий (лямбды,
+# анонимные функции).
+# Блок может только передаваться методу, сам по себе он существовать не может.
+# "for" не имеет своей области видимости и все переменные, объявленные в нём
+# будут доступны отовсюду. "each" вместе с блоком создаёт свою область видимости
+
+# Метод "each" для диапазона значений запускает блок кода один раз
+# для каждого из значений диапазона
+# Блок передаёт счётчик (counter) в качестве параметра.
+# Вызов метода "each" с блоком выглядит следующим образом:
+
+(1..5).each do |counter|
+ puts "итерация #{counter}"
+end
+#=> итерация 1
+#=> итерация 2
+#=> итерация 3
+#=> итерация 4
+#=> итерация 5
+
+# Вы также можете ограничивать блоки фигурными скобками:
+(1..5).each {|counter| puts "итерация #{counter}"}
+
+# Содержимое структурных данных также можно перебирать используя "each":
+array.each do |element|
+ puts "#{element} -- часть массива"
+end
+hash.each do |key, value|
+ puts "#{key} -- это #{value}"
+end
+
+counter = 1
+while counter <= 5 do
+ puts "итерация #{counter}"
+ counter += 1
+end
+#=> итерация 1
+#=> итерация 2
+#=> итерация 3
+#=> итерация 4
+#=> итерация 5
+
+grade = 'B'
+
+case grade
+when 'A'
+ puts "Так держать, детка!"
+when 'B'
+ puts "Тебе повезёт в следующий раз"
+when 'C'
+ puts "Ты можешь сделать лучше"
+when 'D'
+ puts "Выскоблил последнее"
+when 'F'
+ puts "Ты провалился!"
+else
+ puts "Альтернативная система оценок, да?"
+end
+
+# Функции
+
+def double(x)
+ x * 2
+end
+
+# Функции (и все блоки) неявно возвращают значение последней операции
+double(2) #=> 4
+
+# Скобки необязательны, если возвращаемый результат однозначен
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x,y)
+ x + y
+end
+
+# Аргументы метода разделены запятой
+sum 3, 4 #=> 7
+
+sum sum(3,4), 5 #=> 12
+
+# yield
+# Все методы имеют неявный, опциональный параметр,
+# который может быть вызван с помощью инструкции "yield"
+
+def surround
+ puts "{"
+ yield
+ puts "}"
+end
+
+surround { puts 'hello world' }
+
+# {
+# hello world
+# }
+
+
+# Определение класса с помощью ключевого слова "class"
+class Human
+
+ # Переменная класса, она является общей для всех экземпляров класса
+ @@species = "H. sapiens"
+
+ # Базовый метод-конструктор
+ def initialize(name, age=0)
+ # Присвоить аргумент "name" переменной "name" экземпляра класса
+ @name = name
+ # Если аргумент "age" не задан,
+ # мы используем значение по умолчанию из списка аргументов
+ @age = age
+ end
+
+ # Базовый метод установки значения для переменной (setter)
+ def name=(name)
+ @name = name
+ end
+
+ # Базовый метод получения значения переменной (getter)
+ def name
+ @name
+ end
+
+ # Метод класса определяется с ключевым словом "self",
+ # чтобы можно было отличить его от метода экземпляра класса.
+ # Он может быть вызван только на уровне класса, но не экземпляра.
+ def self.say(msg)
+ puts "#{msg}"
+ end
+
+ def species
+ @@species
+ end
+
+end
+
+
+# Создание экземпляра класса
+jim = Human.new("Jim Halpert")
+
+dwight = Human.new("Dwight K. Schrute")
+
+# Давайте вызовем несколько методов
+jim.species #=> "H. sapiens"
+jim.name #=> "Jim Halpert"
+jim.name = "Jim Halpert II" #=> "Jim Halpert II"
+jim.name #=> "Jim Halpert II"
+dwight.species #=> "H. sapiens"
+dwight.name #=> "Dwight K. Schrute"
+
+# Вызов метода класса
+Human.say("Hi") #=> "Hi"
+
+# Область видимости переменной определяется тем, как мы даём имя переменной.
+# Переменные, имя которых начинается с "$" имеют глобальную область видимости
+$var = "I'm a global var"
+defined? $var #=> "global-variable"
+
+# Переменная экземпляра класса, она видна только в экземпляре
+@var = "I'm an instance var"
+defined? @var #=> "instance-variable"
+
+# Переменная класса, видна для всех экземпляров этого класса и в самом классе
+@@var = "I'm a class var"
+defined? @@var #=> "class variable"
+
+# Имена переменных с большой буквы используются для создания констант
+Var = "I'm a constant"
+defined? Var #=> "constant"
+
+# Класс тоже объект в Ruby. Класс может иметь переменные экземпляра.
+# Переменная класса доступна в классе, его экземплярах и его потомках.
+
+# Пример класса
+class Human
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# Производный класс (класс-потомок)
+class Worker < Human
+end
+
+Human.foo # 0
+Worker.foo # 0
+
+Human.foo = 2 # 2
+Worker.foo # 2
+
+# Переменная экземпляра класса недоступна в потомках этого класса.
+
+class Human
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(value)
+ @bar = value
+ end
+end
+
+class Doctor < Human
+end
+
+Human.bar # 0
+Doctor.bar # nil
+
+module ModuleExample
+ def foo
+ 'foo'
+ end
+end
+
+# Включение модулей в класс добавляет их методы в экземпляр класса
+# Или в сам класс, зависит только от метода подключения
+class Person
+ include ModuleExample
+end
+
+class Book
+ extend ModuleExample
+end
+
+Person.foo # => NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo # => 'foo'
+Book.foo # => 'foo'
+Book.new.foo # => NoMethodError: undefined method `foo'
+
+# Коллбэки при подключении модуля
+
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar # => 'bar'
+Something.qux # => NoMethodError: undefined method `qux'
+Something.new.bar # => NoMethodError: undefined method `bar'
+Something.new.qux # => 'qux'
+```
diff --git a/ruby-ecosystem.html.markdown b/ruby-ecosystem.html.markdown
index a31f552d..d186f712 100644
--- a/ruby-ecosystem.html.markdown
+++ b/ruby-ecosystem.html.markdown
@@ -63,7 +63,7 @@ Very mature/compatible:
* MRI - Written in C, this is the reference implementation of ruby. By
definition it is 100% compatible (with itself). All other rubies
-maintain capatability with MRI (see RubySpec below).
+maintain compatibility with MRI (see [RubySpec](#rubyspec) below).
* JRuby - Written in Java and ruby, this robust implementation is quite fast.
Most importantly, JRuby's strength is JVM/Java interop, leveraging existing
JVM tools, projects, and languages.
@@ -81,7 +81,7 @@ development.
Less mature/compatible:
* Topaz - Written in RPython (using the PyPy toolchain), Topaz is fairly young
- and not yet compatable. It shows promise to be a high-performance ruby
+ and not yet compatible. It shows promise to be a high-performance ruby
implementation.
* IronRuby - Written in C# targeting the .NET platform, work on IronRuby seems
to have stopped since Microsoft pulled their support.
@@ -93,13 +93,13 @@ which MRI version to target.
## RubySpec
-Most ruby implementations rely heavily on (RubySpec)[http://rubyspec.org/]. Ruby
+Most ruby implementations rely heavily on [RubySpec](http://rubyspec.org/). Ruby
has no official specification, so the community has written executable specs in
ruby to test their implementations' compatability with MRI.
## RubyGems
-(RubyGems)[http://rubygems.org/] is a community-run package manager for ruby.
+[RubyGems](http://rubygems.org/) is a community-run package manager for ruby.
RubyGems ships with ruby, so there is no need to download it separately.
Ruby packages are called "gems," and they can be hosted by the community at
@@ -108,7 +108,7 @@ things like version, dependencies, author(s), and license(s).
## Bundler
-(Bundler)[http://bundler.io/] is a gem dependency resolver. It uses a project's
+[Bundler](http://bundler.io/) is a gem dependency resolver. It uses a project's
Gemfile to find dependencies, and then fetches those dependencies' dependencies
recursively. It does this until all dependencies are resolved and downloaded, or
it will stop if a conflict has been found.
@@ -121,9 +121,9 @@ dependency graph to resolve.
# Testing
-Testing is a large of ruby culture. Ruby comes with its own Unit-style testing
-framework called minitest (Or TestUnit for ruby version 1.8.x). There are many
-testing libraries with different goals.
+Testing is a large part of ruby culture. Ruby comes with its own Unit-style
+testing framework called minitest (Or TestUnit for ruby version 1.8.x). There
+are many testing libraries with different goals.
* TestUnit - Ruby 1.8's built-in "Unit-style" testing framework
* minitest - Ruby 1.9/2.0's built-in testing framework
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 861a94ad..962853a2 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -5,6 +5,11 @@ contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+
---
```ruby
@@ -30,11 +35,12 @@ You shouldn't either
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
+2 ** 5 #=> 32
# Arithmetic is just syntactic sugar
# for calling a method on an object
1.+(3) #=> 4
-10.* 5 #=> 50
+10.* 5 #=> 50
# Special values are objects
nil # Nothing to see here
@@ -76,6 +82,10 @@ placeholder = "use string interpolation"
"I can #{placeholder} when using double quoted strings"
#=> "I can use string interpolation when using double quoted strings"
+# Combine strings, but not with numbers
+"hello " + "world" #=> "hello world"
+"hello " + 3 #=> TypeError: can't convert Fixnum into String
+"hello " + 3.to_s #=> "hello 3"
# print to the output
puts "I'm printing!"
@@ -116,11 +126,11 @@ status == :approved #=> false
# Arrays
# This is an array
-[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# Arrays can contain different types of items
-array = [1, "hello", false] #=> => [1, "hello", false]
+[1, "hello", false] #=> [1, "hello", false]
# Arrays can be indexed
# From the front
@@ -136,8 +146,8 @@ array.[] 12 #=> nil
# From the end
array[-1] #=> 5
-# With a start and end index
-array[2, 4] #=> [3, 4, 5]
+# With a start index and length
+array[2, 3] #=> [3, 4, 5]
# Or with a range
array[1..3] #=> [2, 3, 4]
@@ -158,11 +168,6 @@ hash['number'] #=> 5
# Asking a hash for a key that doesn't exist returns nil:
hash['nothing here'] #=> nil
-# Iterate over hashes with the #each method:
-hash.each do |k, v|
- puts "#{k} is #{v}"
-end
-
# Since Ruby 1.9, there's a special syntax when using symbols as keys:
new_hash = { defcon: 3, action: true}
@@ -177,9 +182,9 @@ new_hash.keys #=> [:defcon, :action]
if true
"if statement"
elsif false
- "else if, optional"
+ "else if, optional"
else
- "else, also optional"
+ "else, also optional"
end
for counter in 1..5
@@ -191,9 +196,15 @@ end
#=> iteration 4
#=> iteration 5
-# HOWEVER
-# No-one uses for loops
-# Use `each` instead, like this:
+# HOWEVER, No-one uses for loops.
+# Instead you should use the "each" method and pass it a block.
+# A block is a bunch of code that you can pass to a method like "each".
+# It is analogous to lambdas, anonymous functions or closures in other
+# programming languages.
+#
+# The "each" method of a range runs the block once for each element of the range.
+# The block is passed a counter as a parameter.
+# Calling the "each" method with a block looks like this:
(1..5).each do |counter|
puts "iteration #{counter}"
@@ -204,6 +215,17 @@ end
#=> iteration 4
#=> iteration 5
+# You can also surround blocks in curly brackets:
+(1..5).each {|counter| puts "iteration #{counter}"}
+
+# The contents of data structures can also be iterated using each.
+array.each do |element|
+ puts "#{element} is part of the array"
+end
+hash.each do |key, value|
+ puts "#{key} is #{value}"
+end
+
counter = 1
while counter <= 5 do
puts "iteration #{counter}"
@@ -228,17 +250,33 @@ when 'D'
puts "Scraping through"
when 'F'
puts "You failed!"
-else
+else
puts "Alternative grading system, eh?"
end
+#=> "Better luck next time"
+
+# cases can also use ranges
+grade = 82
+case grade
+ when 90..100
+ puts "Hooray!"
+ when 80...90
+ puts "OK job"
+ else
+ puts "You failed!"
+end
+
+#=> "OK job"
+
+
# Functions
def double(x)
x * 2
end
-# Functions (and all blocks) implcitly return the value of the last statement
+# Functions (and all blocks) implicitly return the value of the last statement
double(2) #=> 4
# Parentheses are optional where the result is unambiguous
@@ -272,6 +310,18 @@ surround { puts 'hello world' }
# }
+# You can pass a block to a function
+# "&" marks a reference to a passed block
+def guests(&block)
+ block.call "some_argument"
+end
+
+# You can pass a list of arguments, which will be converted into an array
+# That's what splat operator ("*") is for
+def guests(*array)
+ array.each { |guest| puts "#{guest}" }
+end
+
# Define a class with the class keyword
class Human
@@ -296,6 +346,13 @@ class Human
@name
end
+ # The above functionality can be encapsulated using the attr_accessor method as follows
+ attr_accessor :name
+
+ # Getter/setter methods can also be created individually like this
+ attr_reader :name
+ attr_writer :name
+
# A class method uses self to distinguish from instance methods.
# It can only be called on the class, not an instance.
def self.say(msg)
@@ -325,6 +382,23 @@ dwight.name #=> "Dwight K. Schrute"
# Call the class method
Human.say("Hi") #=> "Hi"
+# Variable's scopes are defined by the way we name them.
+# Variables that start with $ have global scope
+$var = "I'm a global var"
+defined? $var #=> "global-variable"
+
+# Variables that start with @ have instance scope
+@var = "I'm an instance var"
+defined? @var #=> "instance-variable"
+
+# Variables that start with @@ have class scope
+@@var = "I'm a class var"
+defined? @@var #=> "class variable"
+
+# Variables that start with a capital letter are constants
+Var = "I'm a constant"
+defined? Var #=> "constant"
+
# Class also is object in ruby. So class can have instance variables.
# Class variable is shared among the class and all of its descendants.
@@ -371,4 +445,64 @@ end
Human.bar # 0
Doctor.bar # nil
+module ModuleExample
+ def foo
+ 'foo'
+ end
+end
+
+# Including modules binds the methods to the object instance
+# Extending modules binds the methods to the class instance
+
+class Person
+ include ModuleExample
+end
+
+class Book
+ extend ModuleExample
+end
+
+Person.foo # => NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo # => 'foo'
+Book.foo # => 'foo'
+Book.new.foo # => NoMethodError: undefined method `foo'
+
+# Callbacks when including and extending a module are executed
+
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar # => 'bar'
+Something.qux # => NoMethodError: undefined method `qux'
+Something.new.bar # => NoMethodError: undefined method `bar'
+Something.new.qux # => 'qux'
```
+
+## Additional resources
+
+- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges.
+- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/)
+- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
+- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free addition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online.
+
+
diff --git a/scala.html.markdown b/scala.html.markdown
index b1b3ecbf..2666746e 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -104,10 +104,13 @@ val sq = (x:Int) => x * x
sq(10) // Gives you this: res33: Int = 100.
+// The colon explicitly defines the type of a value, in this case a function
+// taking an Int and returning an Int.
+val add10: Int => Int = _ + 10
+
// Scala allows methods and functions to return, or take as parameters, other
// functions or methods.
-val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
// Anonymous functions can be used instead of named functions:
@@ -374,7 +377,7 @@ import scala.collection.immutable._
import scala.collection.immutable.{List, Map}
// Rename an import using '=>'
-import scala.collection.immutable{ List => ImmutableList }
+import scala.collection.immutable.{ List => ImmutableList }
// Import all classes, except some. The following excludes Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _}
@@ -396,7 +399,7 @@ object Application {
// To read a file line by line
import scala.io.Source
-for(line <- Source.fromPath("myfile.txt").getLines())
+for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
// To write a file use Java's PrintWriter
diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown
new file mode 100644
index 00000000..b545f3e1
--- /dev/null
+++ b/standard-ml.html.markdown
@@ -0,0 +1,396 @@
+---
+language: "Standard ML"
+contributors:
+ - ["Simon Shine", "http://shine.eu.org/"]
+ - ["David Pedersen", "http://lonelyproton.com/"]
+---
+
+Standard ML is a functional programming language with type inference and some
+side-effects. Some of the hard parts of learning Standard ML are: Recursion,
+pattern matching, type inference (guessing the right types but never allowing
+implicit type conversion). If you have an imperative background, not being able
+to update variables can feel severely inhibiting.
+
+```ocaml
+(* Comments in Standard ML begin with (* and end with *). Comments can be
+ nested which means that all (* tags must end with a *) tag. This comment,
+ for example, contains two nested comments. *)
+
+(* A Standard ML program consists of declarations, e.g. value declarations: *)
+val rent = 1200
+val phone_no = 5551337
+val pi = 3.14159
+val negative_number = ~15 (* Yeah, unary minus uses the 'tilde' symbol *)
+
+(* And just as importantly, functions: *)
+fun is_large(x : int) = if x > 37 then true else false
+
+(* Floating-point numbers are called "reals". *)
+val tau = 2.0 * pi (* You can multiply two reals *)
+val twice_rent = 2 * rent (* You can multiply two ints *)
+(* val meh = 1.25 * 10 *) (* But you can't multiply an int and a real *)
+
+(* +, - and * are overloaded so they work for both int and real. *)
+(* The same cannot be said for division which has separate operators: *)
+val real_division = 14.0 / 4.0 (* gives 3.5 *)
+val int_division = 14 div 4 (* gives 3, rounding down *)
+val int_remainder = 14 mod 4 (* gives 2, since 3*4 = 12 *)
+
+(* ~ is actually sometimes a function (e.g. when put in front of variables) *)
+val negative_rent = ~(rent) (* Would also have worked if rent were a "real" *)
+
+(* There are also booleans and boolean operators *)
+val got_milk = true
+val got_bread = false
+val has_breakfast = got_milk andalso got_bread (* 'andalso' is the operator *)
+val has_something = got_milk orelse got_bread (* 'orelse' is the operator *)
+val is_sad = not(has_something) (* not is a function *)
+
+(* Many values can be compared using equality operators: = and <> *)
+val pays_same_rent = (rent = 1300) (* false *)
+val is_wrong_phone_no = (phone_no <> 5551337) (* false *)
+
+(* The operator <> is what most other languages call !=. *)
+(* 'andalso' and 'orelse' are called && and || in many other languages. *)
+
+(* Actually, most of the parentheses above are unnecessary. Here are some
+ different ways to say some of the things mentioned above: *)
+fun is_large x = x > 37 (* The parens above were necessary because of ': int' *)
+val is_sad = not has_something
+val pays_same_rent = rent = 1300 (* Looks confusing, but works *)
+val is_wrong_phone_no = phone_no <> 5551337
+val negative_rent = ~rent (* ~ rent (notice the space) would also work *)
+
+(* Parentheses are mostly necessary when grouping things: *)
+val some_answer = is_large (5 + 5) (* Without parens, this would break! *)
+(* val some_answer = is_large 5 + 5 *) (* Read as: (is_large 5) + 5. Bad! *)
+
+
+(* Besides booleans, ints and reals, Standard ML also has chars and strings: *)
+val foo = "Hello, World!\n" (* The \n is the escape sequence for linebreaks *)
+val one_letter = #"a" (* That funky syntax is just one character, a *)
+
+val combined = "Hello " ^ "there, " ^ "fellow!\n" (* Concatenate strings *)
+
+val _ = print foo (* You can print things. We are not interested in the *)
+val _ = print combined (* result of this computation, so we throw it away. *)
+(* val _ = print one_letter *) (* Only strings can be printed this way *)
+
+
+val bar = [ #"H", #"e", #"l", #"l", #"o" ] (* SML also has lists! *)
+(* val _ = print bar *) (* Lists are unfortunately not the same as strings *)
+
+(* Fortunately they can be converted. String is a library and implode and size
+ are functions available in that library that take strings as argument. *)
+val bob = String.implode bar (* gives "Hello" *)
+val bob_char_count = String.size bob (* gives 5 *)
+val _ = print (bob ^ "\n") (* For good measure, add a linebreak *)
+
+(* You can have lists of any kind *)
+val numbers = [1, 3, 3, 7, 229, 230, 248] (* : int list *)
+val names = [ "Fred", "Jane", "Alice" ] (* : string list *)
+
+(* Even lists of lists of things *)
+val groups = [ [ "Alice", "Bob" ],
+ [ "Huey", "Dewey", "Louie" ],
+ [ "Bonnie", "Clyde" ] ] (* : string list list *)
+
+val number_count = List.length numbers (* gives 7 *)
+
+(* You can put single values in front of lists of the same kind using
+ the :: operator, called "the cons operator" (known from Lisp). *)
+val more_numbers = 13 :: numbers (* gives [13, 1, 3, 3, 7, ...] *)
+val more_groups = ["Batman","Superman"] :: groups
+
+(* Lists of the same kind can be appended using the @ ("append") operator *)
+val guest_list = [ "Mom", "Dad" ] @ [ "Aunt", "Uncle" ]
+
+(* This could have been done with the "cons" operator. It is tricky because the
+ left-hand-side must be an element whereas the right-hand-side must be a list
+ of those elements. *)
+val guest_list = "Mom" :: "Dad" :: [ "Aunt", "Uncle" ]
+val guest_list = "Mom" :: ("Dad" :: ("Aunt" :: ("Uncle" :: [])))
+
+(* If you have many lists of the same kind, you can concatenate them all *)
+val everyone = List.concat groups (* [ "Alice", "Bob", "Huey", ... ] *)
+
+(* A list can contain any (finite) number of values *)
+val lots = [ 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 7, 3 ] (* still just an int list *)
+
+(* Lists can only contain one kind of thing... *)
+(* val bad_list = [ 1, "Hello", 3.14159 ] : ??? list *)
+
+
+(* Tuples, on the other hand, can contain a fixed number of different things *)
+val person1 = ("Simon", 28, 3.14159) (* : string * int * real *)
+
+(* You can even have tuples inside lists and lists inside tuples *)
+val likes = [ ("Alice", "ice cream"),
+ ("Bob", "hot dogs"),
+ ("Bob", "Alice") ] (* : (string * string) list *)
+
+val mixup = [ ("Alice", 39),
+ ("Bob", 37),
+ ("Eve", 41) ] (* : (string * int) list *)
+
+val good_bad_stuff =
+ (["ice cream", "hot dogs", "chocolate"],
+ ["liver", "paying the rent" ]) (* string list * string list *)
+
+
+(* Functions! *)
+fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
+val test_it = add_them (3, 4) (* gives 7 *)
+
+(* Larger functions are usually broken into several lines for readability *)
+fun thermometer temp =
+ if temp < 37
+ then "Cold"
+ else if temp > 37
+ then "Warm"
+ else "Normal"
+
+val test_thermo = thermometer 40 (* gives "Warm" *)
+
+(* if-sentences are actually expressions and not statements/declarations.
+ A function body can only contain one expression. There are some tricks
+ for making a function do more than just one thing, though. *)
+
+(* A function can call itself as part of its result (recursion!) *)
+fun fibonacci n =
+ if n = 0 then 0 else (* Base case *)
+ if n = 1 then 1 else (* Base case *)
+ fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
+
+(* Sometimes recursion is best understood by evaluating a function by hand:
+
+ fibonacci 4
+ ~> fibonacci (4 - 1) + fibonacci (4 - 2)
+ ~> fibonacci 3 + fibonacci 2
+ ~> (fibonacci (3 - 1) + fibonacci (3 - 2)) + fibonacci 2
+ ~> (fibonacci 2 + fibonacci 1) + fibonacci 2
+ ~> ((fibonacci (2 - 1) + fibonacci (2 - 2)) + fibonacci 1) + fibonacci 2
+ ~> ((fibonacci 1 + fibonacci 0) + fibonacci 1) + fibonacci 2
+ ~> ((1 + fibonacci 0) + fibonacci 1) + fibonacci 2
+ ~> ((1 + 0) + fibonacci 1) + fibonacci 2
+ ~> (1 + fibonacci 1) + fibonacci 2
+ ~> (1 + 1) + fibonacci 2
+ ~> 2 + fibonacci 2
+ ~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
+ ~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
+ ~> 2 + (fibonacci 1 + fibonacci 0)
+ ~> 2 + (1 + fibonacci 0)
+ ~> 2 + (1 + 0)
+ ~> 2 + 1
+ ~> 3 which is the 4th Fibonacci number, according to this definition
+
+ *)
+
+(* A function cannot change the variables it can refer to. It can only
+ temporarily shadow them with new variables that have the same names. In this
+ sense, variables are really constants and only behave like variables when
+ dealing with recursion. For this reason, variables are also called value
+ bindings. An example of this: *)
+
+val x = 42
+fun answer(question) =
+ if question = "What is the meaning of life, the universe and everything?"
+ then x
+ else raise Fail "I'm an exception. Also, I don't know what the answer is."
+val x = 43
+val hmm = answer "What is the meaning of life, the universe and everything?"
+(* Now, hmm has the value 42. This is because the function answer refers to
+ the copy of x that was visible before its own function definition. *)
+
+
+(* Functions can take several arguments by taking one tuples as argument: *)
+fun solve2 (a : real, b : real, c : real) =
+ ( (~b + Math.sqrt(b * b - 4.0*a*c)) / (2.0 * a),
+ (~b - Math.sqrt(b * b - 4.0*a*c)) / (2.0 * a) )
+
+(* Sometimes, the same computation is carried out several times. It makes sense
+ to save and re-use the result the first time. We can use "let-bindings": *)
+fun solve2 (a : real, b : real, c : real) =
+ let val discr = b * b - 4.0*a*c
+ val sqr = Math.sqrt discr
+ val denom = 2.0 * a
+ in ((~b + sqr) / denom,
+ (~b - sqr) / denom) end
+
+
+(* Pattern matching is a funky part of functional programming. It is an
+ alternative to if-sentences. The fibonacci function can be rewritten: *)
+fun fibonacci 0 = 0 (* Base case *)
+ | fibonacci 1 = 1 (* Base case *)
+ | fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
+
+(* Pattern matching is also possible on composite types like tuples and lists.
+ Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one
+ three-tuple solve2 takes as argument. Similarly, but less intuitively, you
+ can match on a list consisting of elements in it (from the beginning of the
+ list only). *)
+fun first_elem (x::xs) = x
+fun second_elem (x::y::xs) = y
+fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
+ | evenly_positioned_elems [odd] = [] (* Base case: throw away *)
+ | evenly_positioned_elems [] = [] (* Base case *)
+
+
+(* Higher order functions: Functions can take other functions as arguments.
+ Functions are just other kinds of values, and functions don't need names
+ to exist. Functions without names are called "anonymous functions" or
+ lambda expressions or closures (since they also have a lexical scope). *)
+val is_large = (fn x => x > 37)
+val add_them = fn (a,b) => a + b
+val thermometer =
+ fn temp => if temp < 37
+ then "Cold"
+ else if temp > 37
+ then "Warm"
+ else "Normal"
+
+(* The following uses an anonymous function directly and gives "ColdWarm" *)
+val some_result = (fn x => thermometer (x - 5) ^ thermometer (x + 5)) 37
+
+(* Here is a higher-order function that works on lists (a list combinator) *)
+val readings = [ 34, 39, 37, 38, 35, 36, 37, 37, 37 ] (* first an int list *)
+val opinions = List.map thermometer readings (* gives [ "Cold", "Warm", ... ] *)
+
+(* And here is another one for filtering lists *)
+val warm_readings = List.filter is_large readings (* gives [39, 38] *)
+
+(* You can create your own higher-order functions, too. Functions can also take
+ several arguments by "currying" them. Syntax-wise this means adding spaces
+ between function arguments instead of commas and surrounding parentheses. *)
+fun map f [] = []
+ | map f (x::xs) = f(x) :: map f xs
+
+(* map has type ('a -> 'b) -> 'a list -> 'b list and is called polymorphic. *)
+(* 'a is called a type variable. *)
+
+
+(* We can declare functions as infix *)
+val plus = add_them (* plus is now equal to the same function as add_them *)
+infix plus (* plus is now an infix operator *)
+val seven = 2 plus 5 (* seven is now bound to 7 *)
+
+(* Functions can also be made infix before they are declared *)
+infix minus
+fun x minus y = x - y (* It becomes a little hard to see what's the argument *)
+val four = 8 minus 4 (* four is now bound to 4 *)
+
+(* An infix function/operator can be made prefix with 'op' *)
+val n = op + (5, 5) (* n is now 10 *)
+
+(* 'op' is useful when combined with high order functions because they expect
+ functions and not operators as arguments. Most operators are really just
+ infix functions. *)
+val sum_of_numbers = foldl op+ 0 [1,2,3,4,5]
+
+
+(* Datatypes are useful for creating both simple and complex structures *)
+datatype color = Red | Green | Blue
+
+(* Here is a function that takes one of these as argument *)
+fun say(col) =
+ if col = Red then "You are red!" else
+ if col = Green then "You are green!" else
+ if col = Blue then "You are blue!" else
+ raise Fail "Unknown color"
+
+val _ = print (say(Red) ^ "\n")
+
+(* Datatypes are very often used in combination with pattern matching *)
+fun say Red = "You are red!"
+ | say Green = "You are green!"
+ | say Blue = "You are blue!"
+ | say _ = raise Fail "Unknown color"
+
+
+(* Here is a binary tree datatype *)
+datatype 'a btree = Leaf of 'a
+ | Node of 'a btree * 'a * 'a btree (* three-arg constructor *)
+
+(* Here is a binary tree *)
+val myTree = Node (Leaf 9, 8, Node (Leaf 3, 5, Leaf 7))
+
+(* Drawing it, it might look something like...
+
+ 8
+ / \
+ leaf -> 9 5
+ / \
+ leaf -> 3 7 <- leaf
+ *)
+
+(* This function counts the sum of all the elements in a tree *)
+fun count (Leaf n) = n
+ | count (Node (leftTree, n, rightTree)) = count leftTree + n + count rightTree
+
+val myTreeCount = count myTree (* myTreeCount is now bound to 32 *)
+
+
+(* Exceptions! *)
+(* Exceptions can be raised/thrown using the reserved word 'raise' *)
+fun calculate_interest(n) = if n < 0.0
+ then raise Domain
+ else n * 1.04
+
+(* Exceptions can be caught using "handle" *)
+val balance = calculate_interest ~180.0
+ handle Domain => ~180.0 (* x now has the value ~180.0 *)
+
+(* Some exceptions carry extra information with them *)
+(* Here are some examples of built-in exceptions *)
+fun failing_function [] = raise Empty (* used for empty lists *)
+ | failing_function [x] = raise Fail "This list is too short!"
+ | failing_function [x,y] = raise Overflow (* used for arithmetic *)
+ | failing_function xs = raise Fail "This list is too long!"
+
+(* We can pattern match in 'handle' to make sure
+ a specfic exception was raised, or grab the message *)
+val err_msg = failing_function [1,2] handle Fail _ => "Fail was raised"
+ | Domain => "Domain was raised"
+ | Empty => "Empty was raised"
+ | _ => "Unknown exception"
+
+(* err_msg now has the value "Unknown exception" because Overflow isn't
+ listed as one of the patterns -- thus, the catch-all pattern _ is used. *)
+
+(* We can define our own exceptions like this *)
+exception MyException
+exception MyExceptionWithMessage of string
+exception SyntaxError of string * (int * int)
+
+(* File I/O! *)
+(* Write a nice poem to a file *)
+fun writePoem(filename) =
+ let val file = TextIO.openOut(filename)
+ val _ = TextIO.output(file, "Roses are red,\nViolets are blue.\n")
+ val _ = TextIO.output(file, "I have a gun.\nGet in the van.\n")
+ in TextIO.closeOut(file) end
+
+(* Read a nice poem from a file into a list of strings *)
+fun readPoem(filename) =
+ let val file = TextIO.openIn filename
+ val poem = TextIO.inputAll file
+ val _ = TextIO.closeIn file
+ in String.tokens (fn c => c = #"\n") poem
+ end
+
+val _ = writePoem "roses.txt"
+val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,",
+ "Violets are blue.",
+ "I have a gun.",
+ "Get in the van." ] *)
+```
+
+## Further learning
+
+* Install an interactive compiler (REPL), for example
+ [Poly/ML](http://www.polyml.org/),
+ [Moscow ML](http://mosml.org),
+ [SML/NJ](http://smlnj.org/).
+* Follow the Coursera course [Programming Languages](https://www.coursera.org/course/proglang).
+* Get the book *ML for the Working Programmer* by Larry C. Paulson.
+* Use [StackOverflow's sml tag](http://stackoverflow.com/questions/tagged/sml).
diff --git a/tr-tr/brainfuck-tr.html.markdown b/tr-tr/brainfuck-tr.html.markdown
new file mode 100644
index 00000000..baca4217
--- /dev/null
+++ b/tr-tr/brainfuck-tr.html.markdown
@@ -0,0 +1,87 @@
+---
+language: brainfuck
+filename: brainfuck-tr
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io"]
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+---
+
+Brainfuck (normalde brainfuck olarak bütün harfleri küçük olarak yazılır.)
+son derece minimal bir programlama dilidir. (Sadece 8 komut) ve tamamen
+Turing'dir.
+
+```
+"><+-.,[]" (tırnak işaretleri hariç) karakterleri dışındaki her karakter
+gözardı edilir.
+
+Brainfuck 30,000 hücresi olan ve ilk değerleri sıfır olarak atanmış bir
+dizidir. İşaretçi ilk hücreyi işaret eder.
+
+Sekik komut vardır:
++ : Geçerli hücrenin değerini bir artırır.
+- : Geçerli hücrenin değerini bir azaltır.
+> : Veri işaretçisini bir sonraki hücreye hareket ettirir(sağdaki hücreye).
+< : Veri işaretçisini bir önceki hücreye hareket ettirir(soldaki hücreye).
+. : Geçerli hücrenin ASCII değerini yazdırır (örn: 65 = 'A').
+, : Bir girdilik karakteri aktif hücre için okur.
+[ : Eğer geçerli hücredeki değer sıfır ise, ]ifadesine atlar.
+ Diğer durumlarda bir sonraki yönergeye geçer.
+] : Eğer geçerli hücredeki değer sıfır ise, bir sonraki yönergeye geçer.
+ Diğer durumlarda, [ ifadesine karşılık gelen yönergelere döner.
+
+[ ve ] bir while döngüsü oluşturur. Açıkça, dengeli olmalıdırlar.
+
+Basit bir brainfuck programına göz atalım.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Bu program 'A' karaterini ekrana basar. İlk olarak, #1'inci hücre 6'ya artırılır.
+#1'inci hücre döngü için kullanılacaktır. Sonra, ([) döngüsüne girilir ve
+#2'inci hücreye hareket edilir. #2'inci hücre 10 kez artırılır, #1'inci hücreye
+geri dönülür. #1 hücresini bir azaltır. Bu döngü 6 kez gerçekleşir. (Bu 6 kez
+azaltmak demektir, #1 hücresi 0 değerini alır ve bu noktada ] ifadesini atlar).
+
+Bu noktada, biz #1 hücresindeyiz, değeri şu anda 0 ve #2 hücresinin değeri
+60'tır. Biz #2 hücresine hareket diyoruz ve bu hücreyi 5 defa artırıyoruz.
+#2'nin şu anki değeri 65 olur. Sonra #2 hücresinin ASCII karşılığını
+yazdırıyoruz. 65 değerinin ASCII karşılığı 'A'dır. Ekrana 'A' yazılacaktır.
+
+
+, [ > + < - ] > .
+
+Bu program kullanıcıdan bir girdi okur, ve karakteri bir diğer hücreye yazdırır,
+ve daha sonra aynı karakteri ekrana yazdırır.
+
+, ifadesi kullanıcıdan karakteri #1 hücresine okur. Sonra bir döngü
+başlar. #2 hücresine hareket edilir, #2 hücresinin değeri bir artırılır, #1
+hücresine geri dönülür, ve #1 hücresinin değer bir azaltılır. Bu #1 hücresinin
+değeri 0 olana kadar devam eder ve #2 hücresi #1'in eski değerini tutar. Çünkü
+biz #1 hücresindeki verileri döngü süresince #2 hücresine taşıyoruz, ve sonunda
+#2 hücresinin ASCII değerini yazdırıyoruz.
+
+Boşluk karakteri sadece okunabilirliği artırmak içindir. Aşağıdaki gibi de
+yazabilirsiniz.
+
+,[>+<-]>.
+
+
+Bu uygulamanın ne yaptığına bakalım:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Bu program 2 sayı alır, ve birbiri ile çarpar.
+
+Özetle, ilk olarak iki girdi alır. Sonra, #1 hücresinde şarta bağlı harici bir
+döngü başlar. Sonra #2 ye hareket edilir, ve içerde #2 hücresine bağlı bir döngü
+daha başlar ve #3 hücresinin değerini artırır. Ama, Bir problem vardır: iç
+döngünün sonunda #2'inci hücrenin değeri 0 olacaktır. Bunu çözmek için #4
+hücresinin de değerini yükseltiyoruz, ve sonra #4 hücresinin değerini #2'ye
+kopyalıyoruz.
+```
+
+İşte brainfuck. Zor değil değil mi? Eğlenmek için kendi programınızı
+yazabilirsiniz, veya farklı bir dilde brainfuck yorumlayıcısı yazabilirsiniz.
+Yorumlayıcı oldukça basittir, ama mazoşist iseniz, brainfuck içerisinde bir
+brainfuck yorumlayıcısı yazmayı deneyebilirsiniz.
diff --git a/tr-tr/c-tr.html.markdown b/tr-tr/c-tr.html.markdown
new file mode 100644
index 00000000..128901de
--- /dev/null
+++ b/tr-tr/c-tr.html.markdown
@@ -0,0 +1,488 @@
+---
+name: c
+category: language
+language: c
+filename: learnc-tr.c
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+
+---
+/*
+C halen modern yüksek performans bilgisayarların dili.
+
+C bir çok programcının kullandığı en düşük seviye dillerdendir, ama
+salt hız ile daha fazlasını karşılar. C'nin bellek yönetiminden iyi
+anlarsanız sizi isteğiniz yere götürecektir.
+
+```c
+// Tek satır yorum // karakterleri ile başlar
+
+/*
+Çoklu satırlı yorumlar bu şekilde görünür.
+*/
+
+// C Standart kütüphanelerini uygulamanıza #include<ornek.h> ile
+// dahil edebilirsiniz.
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// Kendi başlık(header) dosyalarınız dahil etmek için "çift tırnak"
+// kullanmalısınız.
+#include "my_header.h"
+
+// Fonksiyonlarınızı bir .h dosyasında ya da c dosyanızın üst tarafta
+// tanımlayın.
+
+void function_1();
+void function_2();
+
+// Programınızın giriş noktası main isimli bir fonksiyondur ve
+// integer değer döner
+int main() {
+
+ // çıktıları yazdırmak için printf kullanılır, "print formatted"
+ // %d bir sayı tipidir, \n yeni satır karakteridir
+ printf("%d\n", 0); // => 0 karakteri yazdırılır.
+ // Tüm ifadeler noktalı virgül ile bitmelidir.
+
+ ///////////////////////////////////////
+ // Tipler
+ ///////////////////////////////////////
+
+ // Değişkenleri kullanmadan önce tanımlamalısınız. Bir değişken tanımlarken
+ // tipini belirtmelisiniz; bu tip onun byte olarak boyutunu belirler.
+
+ // int değişken tipi 4 byte boyutundadır.
+ int x_int = 0;
+
+ // short değişken tipi genellikle 2 byte boyutundadır.
+ short x_short = 0;
+
+ // char tipi 1 byte boyutunu garanti eder.
+ char x_char = 0;
+ char y_char = 'y'; // Karakterler '' işaretleri arasına yazılır.
+
+ // long tipi 4-8 byte olur; long long tipi en azından 64 bit garantiler.
+ long x_long = 0;
+ long long x_long_long = 0;
+
+ // float tipi 32-bit kayan noktalı sayı boyutundadır.
+ float x_float = 0.0;
+
+ // double değişken tipi 64-bit kayan noktalı yazı tipindedir.
+ double x_double = 0.0;
+
+ // Integral türleri işaretsiz olabilir. Bunun anlamı, onlar eksi değer
+ // olamaz demektir, ama aynı boyuttaki işaretsiz bir sayının maksimum
+ // değeri işaretli bir sayının maksimum değeriden büyük olur.
+ unsigned char ux_char;
+ unsigned short ux_short;
+ unsigned int ux_int;
+ unsigned long long ux_long_long;
+
+ // Diğer taraftan char, ki her zaman bir byte boyutundadır, bu tipler
+ // makinenize göre boyut değiştirir. sizeof(T) size bir değişkenin byte
+ // cinsinden boyutunu verir öyle ki bu tipin boyutunu taşınabilir bir
+ // şekilde ifade edilebilir
+ // Örneğin,
+ printf("%lu\n", sizeof(int)); // => 4 (bir çok makinede 4-byte words)
+
+ // If the argument of the `sizeof` operator 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;
+
+ // size_t bir objeyi temsil etmek için kullanılan 2 byte uzunluğundaki bir
+ // işaretsiz tam sayı tipidir
+
+ size_t size = sizeof(a++); // a++ is not evaluated
+ printf("sizeof(a++) = %zu where a = %d\n", size, a);
+ // prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
+
+ // Diziler somut bir boyut ile oluşturulmalıdır.
+ char my_char_array[20]; // Bu dizi 1 * 20 = 20 byte alan kaplar
+ int my_int_array[20]; // Bu dizi 4 * 20 = 80 byte alan kaplar
+ // (4-byte bir word varsayılır)
+
+ // Şu şekilde bir diziyi 0 ile oluşturabilirsiniz:
+ char my_array[20] = {0};
+
+ // Dizinin elemanlarını indexlemek diğer diller gibidir, veya
+ // diğer diller C gibi.
+ my_array[0]; // => 0
+
+ // Diziler değişebilirdir (mutable); O sadece memory!
+ my_array[1] = 2;
+ printf("%d\n", my_array[1]); // => 2
+
+ // In C99 (and as an optional feature in C11), variable-length arrays (VLAs)
+ // can be declared as well. The size of such an array need not be a compile
+ // time constant:
+ printf("Enter the array size: "); // ask the user for an array size
+ char buf[0x100];
+ fgets(buf, sizeof buf, stdin);
+
+ // strtoul parses a string to an unsigned integer
+ size_t size = strtoul(buf, NULL, 10);
+ int var_length_array[size]; // declare the VLA
+ printf("sizeof array = %zu\n", sizeof var_length_array);
+
+ // A possible outcome of this program may be:
+ // > Enter the array size: 10
+ // > sizeof array = 40
+
+ // String'ler bir NUL (0x00) byte ile sonlandırılmış karakter dizileridir,
+ // bu string içerisinde özel bir karakter olan '\0' ile gösterilir.
+ // (Biz Nul byte'i string karakterleri arasında bulundurmamıza gerek
+ // yoktur; derleyici onu bizim için dizinin sonuna ekler.)
+ char a_string[20] = "This is a string";
+ printf("%s\n", a_string); // %s bir string formatıdır.
+
+ /*
+ a_string 16 karakter uzunluğundadır.
+ 17. karakter NUL karakteridir.
+ 18., 19. ve 20. karakterler tanımsızdır.(undefined)
+ */
+
+ printf("%d\n", a_string[16]); // => 0
+ // i.e., byte #17 is 0 (as are 18, 19, and 20)
+
+ // If we have characters between single quotes, that's a character literal.
+ // It's of type `int`, and *not* `char` (for historical reasons).
+ int cha = 'a'; // fine
+ char chb = 'a'; // fine too (implicit conversion from int to char)
+
+ ///////////////////////////////////////
+ // Operatörler
+ ///////////////////////////////////////
+
+ int i1 = 1, i2 = 2; // Çoklu tanımlama için kısayol.
+ float f1 = 1.0, f2 = 2.0;
+
+ // Aritmatik basittir.
+ i1 + i2; // => 3
+ i2 - i1; // => 1
+ i2 * i1; // => 2
+ i1 / i2; // => 0 (0.5'dir ama 0 a yuvarlanmıştır.)
+
+ f1 / f2; // => 0.5, artı veya eksi epsilon
+
+ // Modüler aritmetikte vardır.
+ 11 % 3; // => 2
+
+ // Karşılaştırma operatörleri muhtemelen tanıdıktır, ama
+ // C'de boolean tipi yoktur. Bunun yerine sayı(int) kullanırız.
+ // 0 false yerine ve diğer herşey true yerine geçmektedir.
+ // (Karşılaştırma operatörleri her zaman 0 veya 1 dönmektedir.)
+ 3 == 2; // => 0 (false)
+ 3 != 2; // => 1 (true)
+ 3 > 2; // => 1
+ 3 < 2; // => 0
+ 2 <= 2; // => 1
+ 2 >= 2; // => 1
+
+ // Sayılar üzerinde mantık işlemleri
+ !3; // => 0 (Logical not)
+ !0; // => 1
+ 1 && 1; // => 1 (Logical and)
+ 0 && 1; // => 0
+ 0 || 1; // => 1 (Logical or)
+ 0 || 0; // => 0
+
+ // Bit boyutunda işlem yapmak için operatörler
+ ~0x0F; // => 0xF0 (bitwise negation)
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x0F | 0xF0; // => 0xFF (bitwise OR)
+ 0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
+ 0x01 << 1; // => 0x02 (bitwise left shift (by 1))
+ 0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
+
+ // Be careful when shifting signed integers - the following are undefined:
+ // - shifting into the sign bit of a signed integer (int a = 1 << 32)
+ // - left-shifting a negative number (int a = -1 << 2)
+ // - shifting by an offset which is >= the width of the type of the LHS:
+ // int a = 1 << 32; // UB if int is 32 bits wide
+
+ ///////////////////////////////////////
+ // Kontrol Yapıları
+ ///////////////////////////////////////
+
+ if (0) {
+ printf("I am never run\n");
+ } else if (0) {
+ printf("I am also never run\n");
+ } else {
+ printf("I print\n");
+ }
+
+ // While Döngüsü
+ int ii = 0;
+ while (ii < 10) {
+ printf("%d, ", ii++); // ii++, ii değişkenini değerini kullandıktan sonra artırır.
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ int kk = 0;
+ do {
+ printf("%d, ", kk);
+ } while (++kk < 10); // ++kk, kk değişkeninin değerini kullanmadan önce artırır.
+ // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ // For Döngüsü
+ int jj;
+ for (jj=0; jj < 10; jj++) {
+ printf("%d, ", jj);
+ } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ ///////////////////////////////////////
+ // Tip Dönüşümleri
+ ///////////////////////////////////////
+
+ // C'de her değer bir tipe sahiptir, ama siz bir değeri bir başka tipe
+ // dönüştürebilirsiniz.
+
+ int x_hex = 0x01; // Hex literatüründe değer atayabilirsiniz.
+
+ // Türler arasındaki dönüşümde kendi değerini korumak için çalışacaktır.
+ printf("%d\n", x_hex); // => Prints 1
+ printf("%d\n", (short) x_hex); // => Prints 1
+ printf("%d\n", (char) x_hex); // => Prints 1
+
+ // Tip hiçbir hata vermeden taşacaktır(overflow).
+ printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 eğer karakter 8 bit uzunluğunda ise)
+
+ // `char`, `signed char` ve `unsigned char` karakter tiplerinin maksimum uzunluğunu
+ // belirlemek için <limits.h> kütüphanesindeki CHAR_MAX, SCHAR_MAX ve UCHAR_MAX
+ // macrolarını kullanınız.
+
+ // Integral tipi kayan noktalı yazı tipine dönüştürülecektir ve tam tersi.
+ printf("%f\n", (float)100); // %f formats a float
+ printf("%lf\n", (double)100); // %lf formats a double
+ printf("%d\n", (char)100.0);
+
+ ///////////////////////////////////////
+ // İşaretçiler (Pointers)
+ ///////////////////////////////////////
+
+ // Bir işaretci bellek adresini barındıran bir değişkendir. Tanımlaması ile işaret
+ // edeceği verinin tipi de belirtilecektir. Değişkenlerininzi bellek adreslerini
+ // getirerek bellek ile ilgili karışıklığı ortadan kaldırabilirsiniz.
+
+ int x = 0;
+ printf("%p\n", &x); // & işareti bir değişkenin bellek adresini getirmek için kullanılır.
+ // (%p işaretçilerin formatıdır)
+ // => Bazı bellek adresleri yazdırılacaktır.
+
+
+ // İşaretçiler tanımlanırken * ile başlar
+ int *px, not_a_pointer; // px sayı tipinde bir işaretçidir.
+ px = &x; // X değişkeninin bellek adresi px değişkeninde tutulmaktadır.
+ printf("%p\n", px); // => x değişkeninin bellek adresi yazdırılacaktır.
+ printf("%d, %d\n", (int)sizeof(px), (int)sizeof(not_a_pointer));
+ // => 64-bit sistemde "8, 4" yazdırılacaktır.
+
+ // İşaretçinin adres olarak gösterdiği yerdeki değeri almak için
+ // değişkenin önüne * işareti ekleyiniz.
+ printf("%d\n", *px); // => 0 bastıracaktır, x in değeridir,
+ // çünkü px değişkeni x in adresini göstermektedir.
+
+ // Ayrıca siz işaretçinin gösterdiği yerin değerini
+ // değiştirebilirsiniz. Burada referansı parantez içerisinde göstereceğiz
+ // çünkü ++ işleminin önceliği * işleminden yüksektir.
+ (*px)++; // px'in işaret ettiği değeri 1 artır.
+ printf("%d\n", *px); // => 1 yazdırılır.
+ printf("%d\n", x); // => 1 yazdırılır.
+
+ int x_array[20]; // Diziler(arrays) bellekten yan yana bellek bloklarını
+ // tahsis etmek için iyi bir yöntemdir.
+ int xx;
+ for (xx=0; xx<20; xx++) {
+ x_array[xx] = 20 - xx;
+ } // x_array dizisi 20, 19, 18,... 2, 1 değerleri ile oluşturuluyor.
+
+ // Bir sayı tipinde işaretçi tanımlanıyor ve x_array'i işaret ediyor.
+ int* x_ptr = x_array;
+ // x_ptr artık dizinin ilk elemanını işaret etmektedir (the integer 20).
+ // Bu çalışacaktır çünkü diziler(arrays) aslında sadece onların ilk
+ // elemanlarını gösteren birer işaretçidir.
+ // For example, when an array is passed to a function or is assigned to a pointer,
+ // it decays into (implicitly converted to) a pointer.
+ // Exceptions: when the array is the argument of the `&` (address-od) operator:
+ int arr[10];
+ int (*ptr_to_arr)[10] = &arr; // &arr is NOT of type `int *`!
+ // It's of type "pointer to array" (of ten `int`s).
+ // or when the array is a string literal used for initializing a char array:
+ char arr[] = "foobarbazquirk";
+ // 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"
+
+ // Diziler ilk elemanlarını gösteren birer işaretçidirler.
+ printf("%d\n", *(x_ptr)); // => 20 yazılacaktır.
+ printf("%d\n", x_array[0]); // => 20 yazılacaktır.
+
+ // İşaretçiler kendi tiplerinde artırılır ve azaltılır.
+ printf("%d\n", *(x_ptr + 1)); // => 19 yazılacaktır.
+ printf("%d\n", x_array[1]); // => 19 yazılacaktır.
+
+ // Ayrıca dinamik olarak bir bellek bloğunu standart kütüphanede bulunan
+ // malloc fonksiyonu ile uygulamanız için ayırabilirsiniz. Bu fonksiyon
+ // byte türünden ayırmak istediğiniz bloğun boyutunu parametre olarak alır.
+ int* my_ptr = (int*) malloc(sizeof(int) * 20);
+ for (xx=0; xx<20; xx++) {
+ *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx 'de aynı zamanda çalışabilir
+ } // Bellekte 20, 19, 18, 17... 2, 1 (as ints) şeklinde oluşturulmuş olacaktır.
+
+ // Eğer ayrımadığınız bir bellek adresini çağırırsanız
+ // öngörülmeyen bir değer dönecektir.
+ printf("%d\n", *(my_ptr + 21)); // => kim-bilir-ne-yazacak?
+
+ // Malloc fonksiyonu ile ayrıdığınız bellek kısmı ile işiniz bittiğinde
+ // onu free fonksiyonu ile boşaltmalısınız, aksi durumda uygulamanız
+ // kapatılana kadar belleğin o kısmını kimse kullanamaz.
+ free(my_ptr);
+
+ // Metin Dizileri(String) birer karakter dizisidir(char array), ama
+ // genelde karakter işaretçisi olarak kullanılır.
+ char* my_str = "This is my very own string";
+
+ printf("%c\n", *my_str); // => 'T'
+
+ function_1();
+} // main fonksiyon sonu
+
+///////////////////////////////////////
+// Fonksiyonlar
+///////////////////////////////////////
+
+// Fonksiyon tanımlama sözdizimi:
+// <return type> <fonksiyon adi>(<args>)
+
+int add_two_ints(int x1, int x2){
+ return x1 + x2; // bir değer geri döndürmek için return kullanılır.
+}
+
+/*
+Fonksiyonlar pass-by-value'dür, ama isterseniz işaretçi referanslarını
+kullanarak fonksiyona gönderilen parametrenin değerini değiştirebilirsiniz.
+
+Example: Bir metni tersine çevirme
+*/
+
+// Bir void konksiyonu hiç bir değer dönmez
+void str_reverse(char* str_in){
+ char tmp;
+ int ii=0, len = strlen(str_in); // Strlen C'nin standart kütüphanesinin bir fonksiyonu
+ for(ii=0; ii<len/2; ii++){
+ tmp = str_in[ii];
+ str_in[ii] = str_in[len - ii - 1]; // sondan ii'inci elemanı
+ str_in[len - ii - 1] = tmp;
+ }
+}
+
+/*
+char c[] = "This is a test.";
+str_reverse(c);
+printf("%s\n", c); // => ".tset a si sihT"
+*/
+
+///////////////////////////////////////
+// Kullanıcı Tanımlı Tipler ve Yapılar
+///////////////////////////////////////
+
+// Typedef'ler bir tip takma adı oluşturur.
+typedef int my_type;
+my_type my_type_var = 0;
+
+// Struct'lar bir veri koleksiyonudur.
+struct rectangle {
+ int width;
+ int height;
+};
+
+// It's not generally true that
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int)
+// due to potential padding between the structure members (this is for alignment
+// reasons). [1]
+
+void function_1(){
+
+ struct rectangle my_rec;
+
+ // "." ile yapı üyelerine ulaşılabilir.
+ my_rec.width = 10;
+ my_rec.height = 20;
+
+ // Bir yapının adresini işaretçiye atayabilirsiniz.
+ struct rectangle* my_rec_ptr = &my_rec;
+
+ // İşaretçi üzerinden bir yapıya ulaşabilirsiniz.
+ (*my_rec_ptr).width = 30;
+
+ // ya da -> işareti ile yapının elemanlarına ulaşabilirsiniz.
+ my_rec_ptr->height = 10; // (*my_rec_ptr).height = 10; ile aynıdır.
+}
+
+// Kolaylık sağlamak için bir yapıya typedef tanımlayabilirsiniz.
+typedef struct rectangle rect;
+
+int area(rect r){
+ return r.width * r.height;
+}
+
+///////////////////////////////////////
+// Fonksiyon İşaretçiler
+///////////////////////////////////////
+
+/*
+Çalışma zamanında, fonksiyonların bilinen bir bellek adresleri vardır. Fonksiyon
+işaretçileri fonksiyonları direk olarak çağırmayı sağlayan veya geri bildirim(callback)
+için parametre gönderirken kullanılan başka birer işaretçidirler. Ama, syntax tanımı
+başlangıçta biraz karışık gelebilir.
+
+Örnek: bir işaretçiden str_reverse kullanımı
+*/
+void str_reverse_through_pointer(char * str_in) {
+ // f adında bir fonksiyon işaretçisi tanımlanır.
+ void (*f)(char *); // Signature should exactly match the target function.
+ f = &str_reverse; // Assign the address for the actual function (determined at runtime)
+ (*f)(str_in); // Just calling the function through the pointer
+ // f(str_in); // That's an alternative but equally valid syntax for calling it.
+}
+
+/*
+As long as function signatures match, you can assign any function to the same pointer.
+Function pointers are usually typedef'd for simplicity and readability, as follows:
+*/
+
+typedef void (*my_fnp_type)(char *);
+
+// Gerçek bir işaretçi tanımlandığı zaman ki kullanımı:
+// ...
+// my_fnp_type f;
+
+```
+
+## Daha Fazla Okuma Listesi
+
+[K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)'in bir kopyasını bulundurmak mükemmel olabilir
+
+Diğer bir iyi kaynak ise [Learn C the hard way](http://c.learncodethehardway.org/book/)
+
+It's very important to use proper spacing, indentation and to be consistent with your coding style in general.
+Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the
+[Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
+
+Diğer taraftan google sizin için bir arkadaş olabilir.
+
+[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member \ No newline at end of file
diff --git a/tr-tr/objective-c-tr.html.markdown b/tr-tr/objective-c-tr.html.markdown
new file mode 100644
index 00000000..854d70f6
--- /dev/null
+++ b/tr-tr/objective-c-tr.html.markdown
@@ -0,0 +1,320 @@
+---
+language: Objective-C
+contributors:
+ - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+filename: LearnObjectiveC-tr.m
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+---
+
+Objective-C Apple tarafından, OSX ve iOS işletim sistemleri ve onların
+kendi çatıları olan Cocoa ve Cocoa Touch için kullanılan bir programlama dilidir.
+Genel açamlı, object-oriented bir yapıya sahip programlama dilidir. C
+programlama diline Smalltalk stilinde mesajlaşma ekler.
+
+```cpp
+// Tek satır yorum // işaretleri ile başlar
+
+/*
+Çoklu satır yorum bu şekilde görünür.
+*/
+
+// #import ile Foundation başlıklarını projeye import edebiliriz.
+#import <Foundation/Foundation.h>
+#import "MyClass.h"
+
+// Progarmınızı girişi bir main fonksiyonudur ve bir integer değer döner.
+int main (int argc, const char * argv[])
+{
+ // Programdaki bellek kullanımını kontrol etmek için autorelease bir
+ // oluşturuyoruz. Autorelease bellekte kullanılmayan değerlerin kendi
+ // kendini silmesi demektir.
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // NSLog konsola bir satırlık bilgi yazdırmak için kullanılır.
+ NSLog(@"Hello World!"); // "Hello World!" değeri yazdırılır.
+
+ ///////////////////////////////////////
+ // Tipler & Değişkenler
+ ///////////////////////////////////////
+
+ // Basit Tanımlamalar
+ int myPrimitive1 = 1;
+ long myPrimitive2 = 234554664565;
+
+ // Nesne Tanımlamaları
+ // strongly-typed nesne tanımlaması için karakter değişken isminin önüne
+ // * karakteri konulur.
+ MyClass *myObject1 = nil; // Strong typing
+ id myObject2 = nil; // Weak typing
+ // %@ bir nesnedir.
+ // 'description' objelerin değerlerinin gösterilmesi için bir düzendir.
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]);
+ // "(null) and (null)" yazdırılacaktır.
+
+ // Karakter Dizisi (String)
+ NSString *worldString = @"World";
+ NSLog(@"Hello %@!", worldString); // "Hello World!" yazdırılacaktır.
+
+ // Karakterler
+ NSNumber *theLetterZNumber = @'Z';
+ char theLetterZ = [theLetterZNumber charValue];
+ NSLog(@"%c", theLetterZ);
+
+ // Tamsayılar
+ NSNumber *fortyTwoNumber = @42;
+ int fortyTwo = [fortyTwoNumber intValue];
+ NSLog(@"%i", fortyTwo);
+
+ NSNumber *fortyTwoUnsignedNumber = @42U;
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *fortyTwoLongNumber = @42L;
+ long fortyTwoLong = [fortyTwoLongNumber longValue];
+ NSLog(@"%li", fortyTwoLong);
+
+ // Kayan Noktalı Sayılar (Floats)
+ NSNumber *piFloatNumber = @3.141592654F;
+ float piFloat = [piFloatNumber floatValue];
+ NSLog(@"%f", piFloat);
+
+ NSNumber *piDoubleNumber = @3.1415926535;
+ piDouble = [piDoubleNumber doubleValue];
+ NSLog(@"%f", piDouble);
+
+ // BOOL Değerler
+ NSNumber *yesNumber = @YES;
+ NSNumber *noNumber = @NO;
+
+ // Dizi objeleri
+ NSArray *anArray = @[@1, @2, @3, @4];
+ NSNumber *thirdNumber = anArray[2];
+ NSLog(@"Third number = %@", thirdNumber); // "Third number = 3" yazdırılır
+
+ // Dictionary objeleri
+ NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
+ NSObject *valueObject = aDictionary[@"A Key"];
+ NSLog(@"Object = %@", valueObject); // "Object = (null)" yazıdılır
+
+ ///////////////////////////////////////
+ // Operatörler
+ ///////////////////////////////////////
+
+ // Operatörler C dilindeki gibi çalışır.
+ // Örneğin:
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (NO)
+ 3 != 2; // => 1 (YES)
+ 1 && 1; // => 1 (Logical and)
+ 0 || 1; // => 1 (Logical or)
+ ~0x0F; // => 0xF0 (bitwise negation)
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x01 << 1; // => 0x02 (bitwise left shift (by 1))
+
+ ///////////////////////////////////////
+ // Kontrol Yapıları
+ ///////////////////////////////////////
+
+ // If-Else ifadesi
+ if (NO)
+ {
+ NSLog(@"I am never run");
+ } else if (0)
+ {
+ NSLog(@"I am also never run");
+ } else
+ {
+ NSLog(@"I print");
+ }
+
+ // Switch ifadesi
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"I am never run");
+ } break;
+ case 1:
+ {
+ NSLog(@"I am also never run");
+ } break;
+ default:
+ {
+ NSLog(@"I print");
+ } break;
+ }
+
+ // While döngü ifadesi
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++, ii değişkenini kullanıldıktan
+ //sonra yerinde artırır.
+ } // => "0,"
+ // "1,"
+ // "2,"
+ // "3," yazdırılır
+
+ // For döngü ifadesi
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj++);
+ } // => "0,"
+ // "1,"
+ // "2,"
+ // "3," yazdırılır
+
+ // Foreach ifadesi
+ NSArray *values = @[@0, @1, @2, @3];
+ for (NSNumber *value in values)
+ {
+ NSLog(@"%@,", value);
+ } // => "0,"
+ // "1,"
+ // "2,"
+ // "3," yazdırılır
+
+ // Try-Catch-Finally ifadesi
+ @try
+ {
+ // İfadelerinizi buraya yazın
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"Sistemde Dosya Bulunamadı" userInfo:nil];
+ } @catch (NSException * e)
+ {
+ NSLog(@"Exception: %@", e);
+ } @finally
+ {
+ NSLog(@"Finally");
+ } // => "Exception: Sistemde Dosya Bulunamadı"
+ // "Finally"
+ // yazdırılacaktır
+
+ ///////////////////////////////////////
+ // Objeler
+ ///////////////////////////////////////
+
+ // Bellekten bir alan ayırmak ve objeyi burada oluşturmak bir obje örneği
+ // oluşturalım. Bir obje allocate ve init aşamalarını bitirmeden tam olarak
+ // işlevsel değildir.
+ MyClass *myObject = [[MyClass alloc] init];
+
+ // Objective-C nesne yönelimli programlama modelinin temelinde objelere
+ // mesaj gönderme vardır.
+ // Objective-C'de bir method çağırılmaz, ona bir mesaj gönderilir.
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Programda kullanılan bellek temizlenir
+ [pool drain];
+
+ // Program Sonu
+ return 0;
+}
+
+///////////////////////////////////////
+// Sınıflar ve Fonksiyonlar
+///////////////////////////////////////
+
+// Sınıfınızı (MyClass.h) header dosyasında tanımlayın:
+
+// Sınıf tanımlama yapısı:
+// @interface ClassName : ParentClassName <ImplementedProtocols>
+// {
+// Üye değişken (member variable) tanımlaması;
+// }
+// -/+ (type) Method tanımlaması;
+// @end
+@interface MyClass : NSObject <MyCustomProtocol>
+{
+ int count;
+ id data;
+ NSString *name;
+}
+// getter ve setter için otomatik oluşturulmuş gösterim.
+@property int count;
+@property (copy) NSString *name; // Copy the object during assignment.
+@property (readonly) id data; // Declare only a getter method.
+
+// Metodlar
++/- (return type)methodSignature:(Parameter Type *)parameterName;
+
+// "+" class metodları içindir
++ (NSString *)classMethod;
+
+// "-" instance metodu içindir
+- (NSString *)instanceMethodWithParmeter:(NSString *)string;
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
+
+@end
+
+// Metodların implementasyonlarını (MyClass.m) dosyasında yapıyoruz:
+
+@implementation UserObject
+
+// Obje bellekten silineceği (release) zaman çağırılır
+- (void)dealloc
+{
+}
+
+// Constructor'lar sınıf oluşturmanın bir yoludur
+// Bu varsayılan bir constructor'dur ve bir obje oluşturulurken çağrılır.
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ self.count = 1;
+ }
+ return self;
+}
+
++ (NSString *)classMethod
+{
+ return [[self alloc] init];
+}
+
+- (NSString *)instanceMethodWithParmeter:(NSString *)string
+{
+ return @"New string";
+}
+
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
+{
+ return @42;
+}
+
+// MyProtocol içerisinde metod tanımlamaları
+- (void)myProtocolMethod
+{
+ // ifadeler
+}
+
+@end
+
+/*
+ * Bir `protocol` herhangi bir sınıf tarafından implement edilen metodları tanımlar
+ * `Protocol`ler sınıfların kendileri değildir. Onlar basitçe diğer objelerin
+ * implementasyon için sorumlu oldukları bir arayüz (interface) tanımlarlar.
+ */
+@protocol MyProtocol
+ - (void)myProtocolMethod;
+@end
+
+
+
+```
+## Daha Fazla Okuma
+
+[Vikipedi Objective-C](http://tr.wikipedia.org/wiki/Objective-C)
+
+[Objective-C Öğrenme](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
+
+[Lise Öğrencileri için iOS: Başlangıç](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
diff --git a/tr-tr/php-tr.html.markdown b/tr-tr/php-tr.html.markdown
new file mode 100644
index 00000000..3db437cf
--- /dev/null
+++ b/tr-tr/php-tr.html.markdown
@@ -0,0 +1,705 @@
+---
+language: php
+filename: learnphp-tr.php
+contributors:
+ - ["Malcolm Fell", "http://emarref.net/"]
+ - ["Trismegiste", "https://github.com/Trismegiste"]
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+---
+
+PHP 5+ versiyonu için geçerlidir.
+
+```php
+<?php // PHP kodları <?php etiketleri içerisinde bulunmalıdır.
+
+// Eğer php dosyanız sadece PHP kodu içeriyorsa, php'nin kapatma
+// etiketini kapatmayabilirsiniz.
+
+// // işareti ile tek satırlık yorum satırı başlar.
+
+# # işareti de aynı görevi görür ancak // daha genel kullanımdadır.
+
+
+
+/*
+ Çoklu satır kodu bu şekilde yazıyoruz. slash yıldız ile başlar
+ ve yıldız slash ile biter.
+*/
+
+// "echo" ya da "print" metodları çıktı almak için kullanılır.
+print('Hello '); // Ekrana Yeni satır karakteri olmadan "Hello "
+ // yazdırılır.
+
+// () parantezler "echo" ve "print" metodları için isteğe bağlıdır.
+echo "World\n"; // Ekrana yeni satır karakteri olmadan "World"
+ // yazdırılır.
+// (Bütün ifadeler noktalı virgül ile bitmelidir.)
+
+// <?php tagı dışarısındaki herşey otomatik olarak yazdırılacaktır.
+?>
+Hello World Again!
+<?php
+
+
+/************************************
+* Tipler ve Değişkenler
+*************************************/
+
+// Değişkenler $ sembolü ile başlar.
+// Geçerli bir değişken bir harf veya alt çizgi ile başlar,
+// devamında da bir sayı, harf veya alt çizgi ile devam eder.
+
+// Mantıksal değerler
+// Boolean values are harf büyüklüğüne duyarsızdır.
+$boolean = true; // veya TRUE veya True
+$boolean = false; // veya FALSE veya False
+
+// Tam Sayılar
+$int1 = 12; // => 12
+$int2 = -12; // => -12
+$int3 = 012; // => 10 (öneki 0 olan sekizlik(octal) bir sayıyı gösterir)
+$int4 = 0x0F; // => 15 (öneki 0x olanlar hex sayıları gösterir.)
+
+// Kayan Noktalı Sayılar
+$float = 1.234;
+$float = 1.2e3;
+$float = 7E-10;
+
+// Değişken Silmek
+unset($int1)
+
+// Aritmetik
+$sum = 1 + 1; // 2
+$difference = 2 - 1; // 1
+$product = 2 * 2; // 4
+$quotient = 2 / 1; // 2
+
+// Aritmetik Kısayolları
+$number = 0;
+$number += 1; // $number değişkeninin değerini 1 artırır.
+echo $number++; // 1 yazdırılır. (Yazdırıldıktan sonra artırılır.)
+echo ++$number; // 3 yazdırılır. (yazdırılmadan önce artırılır.)
+$number /= $float; // Bölünür ve bölüm $number değerine eşitlenir.
+
+// Karakter dizileri(strings) tek tırnak ile kullanılmalıdır.
+$sgl_quotes = '$String'; // => '$String'
+
+// Bir değişken içermediği sürece çift tırnak kullanmaktan kaçının
+$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
+
+// Özel karakterler sadece çift tırnak ile kullanılabilir.
+$escaped = "This contains a \t tab character.";
+$unescaped = 'This just contains a slash and a t: \t';
+
+// Gerekirse bir değişkeni küme ayracı içine alın.
+$money = "I have $${number} in the bank.";
+
+// Since PHP 5.3, nowdocs can be used for uninterpolated multi-liners
+$nowdoc = <<<'END'
+Multi line
+string
+END;
+
+// Heredocs will do string interpolation
+$heredoc = <<<END
+Multi line
+$sgl_quotes
+END;
+
+// . işareti ile karakter dizileri birbirine birleştirilebilir.
+echo 'This string ' . 'is concatenated';
+
+
+/********************************
+ * Sabitler
+ */
+
+// Bir sabit define() metodu kullanılarak tanımlanır.
+// ve çalışma zamanından hiçbir zaman değişmez!
+
+// geçerli bir sabit bir harf veya altçizgi ile başlar,
+// ve bir sayı, harf ya da altçizgi ile devam eder.
+define("FOO", "something");
+
+// sabite ulaşmak için direk olarak seçilen ismi kullanabilirsiniz.
+echo 'This outputs '.FOO;
+
+
+/********************************
+ * Diziler
+ */
+
+// PHP'de bütün diziler ilişikilendirilebilirdir. (hashmaps),
+// İlişkilendirilebilir(associative) diziler, hashmap olarak bilinir.
+
+// PHP'nin bütün versiyonları için çalışır
+$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
+
+// PHP 5.4 ile yeni bir söz dizimi kullanılmaya başlandı
+$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
+
+echo $associative['One']; // 1 yazdıracaktır.
+
+// Liste kullanımında index'ler tam sayıdır.
+$array = ['One', 'Two', 'Three'];
+echo $array[0]; // => "One"
+
+// Dizinin sonuna bir eleman ekleme
+$array[] = 'Four';
+
+// Diziden eleman silme
+unset($array[3]);
+
+/********************************
+ * Çıktı
+ */
+
+echo('Hello World!');
+// Hello World! çıktısı stdout'a yazdırılır.
+// Eğer bir web browser ile çalışıyorsanır Stdout bir web sayfasıdır.
+
+print('Hello World!'); // echo ile aynıdır.
+
+// Aslında echo bir dil sabitidir, parantezleri kullanmayabilirsiniz.
+echo 'Hello World!';
+print 'Hello World!'; // Bu yazdırılacaktır.
+
+$paragraph = 'paragraph';
+
+echo 100; // Echo ile doğrudan sayısal değer kullanımı
+echo $paragraph; // veya değişken
+
+// PHP 5.4.0 veya daha üstü sürümlerde kısa açılış etiketi
+// konfigürasyonları yapıldı ise, kısa açılış etiketini kullanabilirsiniz.
+?>
+<p><?= $paragraph ?></p>
+<?php
+
+$x = 1;
+$y = 2;
+$x = $y; // Şu anda $x değişkeni $y ile aynı değere sahiptir.
+$z = &$y;
+// $z, $y'nin referansını içermektedir.
+// $z'nin değerinin değişmesi $y'nin değerinide değiştireceltir veya
+// tam tersi. Ancak $x özgün değeri olarak kalacaktır.
+
+echo $x; // => 2
+echo $z; // => 2
+$y = 0;
+echo $x; // => 2
+echo $z; // => 0
+
+// Dump'lar değişkenin tipi ve değerini yazdırır
+var_dump($z); // int(0) yazdırılacaktır
+
+// Print'ler ise değişkeni okunabilir bir formatta yazdıracaktır.
+print_r($array); // Çıktı: Array ( [0] => One [1] => Two [2] => Three )
+
+
+/********************************
+ * Mantık
+ */
+$a = 0;
+$b = '0';
+$c = '1';
+$d = '1';
+
+// Argüman doğru değilse bir hata fırlatılacaktır.
+
+// Bu karşılaştırmalar tipler aynı olmasa bile her zaman true olacaktır.
+assert($a == $b); // equality
+assert($c != $a); // inequality
+assert($c <> $a); // alternative inequality
+assert($a < $c);
+assert($c > $b);
+assert($a <= $b);
+assert($c >= $d);
+
+// Aşağıdakiler yanlızca değer ve tip aynı olduğunda true olacaktır.
+assert($c === $d);
+assert($a !== $d);
+assert(1 == '1');
+assert(1 !== '1');
+
+// Değişkenler kullanıma bağlı olarak farklı tiplere çevrilebilir.
+
+$integer = 1;
+echo $integer + $integer; // => 2
+
+$string = '1';
+echo $string + $string; // => 2 (Karakter dizisi tam sayıya çevrilmeye zorlanır)
+
+$string = 'one';
+echo $string + $string; // => 0
+// Çıktı 0 olacaktır, çünkü + operatörü karakter dizisi olan 'one' değerini
+// bir sayıya çeviremez.
+
+// Veri tipi çevirileri bir değişkeni farklı bir türde
+// düzenlemek için kullanılabilir.
+
+$boolean = (boolean) 1; // => true
+
+$zero = 0;
+$boolean = (boolean) $zero; // => false
+
+// Veri tiplerini çevirmek için bazı fonksiyonlar vardır.
+$integer = 5;
+$string = strval($integer);
+
+$var = null; // Null değeri.
+
+
+/********************************
+ * Kontrol Yapıları
+ */
+
+if (true) {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'I don\'t';
+} else {
+ print 'I get printed';
+}
+
+if (false) {
+ print 'Does not get printed';
+} elseif(true) {
+ print 'Does';
+}
+
+// Üçlü operatör
+print (false ? 'Does not get printed' : 'Does');
+
+$x = 0;
+if ($x === '0') {
+ print 'Does not print';
+} elseif($x == '1') {
+ print 'Does not print';
+} else {
+ print 'Does print';
+}
+
+
+
+// Bu alternatif sözdizimi template'ler için kullanışlıdır.
+?>
+
+<?php if ($x): ?>
+This is displayed if the test is truthy.
+<?php else: ?>
+This is displayed otherwise.
+<?php endif; ?>
+
+<?php
+
+// Use switch to save some logic.
+switch ($x) {
+ case '0':
+ print 'Switch does type coercion';
+ break; // Bir breake yazmalısınız ya da 'two' ve 'three'
+ // durumunuda kapsarsınız.
+ case 'two':
+ case 'three':
+ // $variable değişkeni 'two' ya da 'three' ise
+ break;
+ default:
+ // Varsayılan olarak bir şey yap
+}
+
+// While, do...while ve for döngüleri tanıdıktır.
+$i = 0;
+while ($i < 5) {
+ echo $i++;
+}; // "01234" yazdırılacaktır
+
+echo "\n";
+
+$i = 0;
+do {
+ echo $i++;
+} while ($i < 5); // "01234" yazdırılacaktır.
+
+echo "\n";
+
+for ($x = 0; $x < 10; $x++) {
+ echo $x;
+} // "0123456789" yazdırılacaktır.
+
+echo "\n";
+
+$wheels = ['bicycle' => 2, 'car' => 4];
+
+// Foreach döngüsü diziler üzerinde çalışır
+foreach ($wheels as $wheel_count) {
+ echo $wheel_count;
+} // "24" yazdırılacaktır.
+
+echo "\n";
+
+// Key-Value değerlere ulaşabilirsiniz.
+foreach ($wheels as $vehicle => $wheel_count) {
+ echo "A $vehicle has $wheel_count wheels";
+}
+
+echo "\n";
+
+$i = 0;
+while ($i < 5) {
+ if ($i === 3) {
+ break; // while döngüsünden çıkar
+ }
+ echo $i++;
+} // Prints "012"
+
+for ($i = 0; $i < 5; $i++) {
+ if ($i === 3) {
+ continue; // Aktif döngüyü atlar
+ }
+ echo $i;
+} // "0124" yazdırılacaktır.
+
+
+
+/********************************
+ * Fonksiyonlar
+ */
+
+// Bir fonksiyon tanımlamak için "function" kullanılır:
+function my_function () {
+ return 'Hello';
+}
+
+echo my_function(); // => "Hello"
+
+// Geçerli bir fonksiyon ismi bir harf veya altçizgi ile başlar ve
+// bir sayı, harf ya da alt çizgi ile devam eder.
+
+function add ($x, $y = 1) { // $y değeri isteğe bağlıdır ve
+ // varsayılan değeri 1'dir
+ $result = $x + $y;
+ return $result;
+}
+
+echo add(4); // => 5
+echo add(4, 2); // => 6
+
+// $result fonksiyon dışında ulaşılabilir değildir.
+// print $result; // Bir uyarı verecektir.
+
+// PHP 5.3'den beri bir anonymous fonksiyon tanımlayabilirsiniz;
+$inc = function ($x) {
+ return $x + 1;
+};
+
+echo $inc(2); // => 3
+
+function foo ($x, $y, $z) {
+ echo "$x - $y - $z";
+}
+
+// Fonksiyonlar bir fonksiyon dönebilir.
+function bar ($x, $y) {
+ // Fonksiyona dışardan değişken gönderebilmek için 'use' komutunu kullanın.
+ return function ($z) use ($x, $y) {
+ foo($x, $y, $z);
+ };
+}
+
+$bar = bar('A', 'B');
+$bar('C'); // "A - B - C" yazdırılacaktır.
+
+// Fonksiyonun ismini karakter dizinden çağırabilirsiniz.
+$function_name = 'add';
+echo $function_name(1, 2); // => 3
+// Programatik olarak fonksiyonları çalıştırmak için yararlı olabilir
+// veya, call_user_func(callable $callback [, $parameter [, ... ]]); kulanın.
+
+
+/********************************
+ * Includes
+ */
+
+<?php
+// PHP'de include edilecek dosyalar PHP açma etiketi ile başlamalı. (!)
+
+include 'my-file.php';
+// my-file.php dosyasındaki kodlar artık mevcut scope'da kullanılabilir.
+// Eğer dosya include edilemezse bir uyarı (örneğin: file not found)
+// fırlatılacaktır.
+
+include_once 'my-file.php';
+// Eğer bir dosya include edildi ise tekrar include edilmeyecektir.
+// Bu çoklu class tanımlama hatalarını önler.
+
+require 'my-file.php';
+require_once 'my-file.php';
+// Dosya include edilemediğinde fatal error veren require() bu konu
+// dışında include() ile aynıdır.
+
+// my-include.php dosyasının içeriği:
+<?php
+
+return 'Anything you like.';
+// Dosya sonu
+
+// Include'lar ver require'lar aynı zamanda bir return dönebilir.
+$value = include 'my-include.php';
+
+// Dosyalar verilen dosya yoluna göre include edilir veya, hiçbirşey
+// verilmezse include_path konfigürasyonuna göre include edecektir.
+// Eğer dosya include_path'da da bulunamazsa include hata vermeden
+// önce içinde bulunulan dizini kontrol ecektir.
+/* */
+
+
+/********************************
+ * Sınıflar
+ */
+
+// Sınıflar class kelimesi ile tanımlanır
+
+class MyClass
+{
+ const MY_CONST = 'value'; // Bir sabit
+
+ static $staticVar = 'static';
+
+ // Static değişkenler ve onların görünürlüğü
+ public static $publicStaticVar = 'publicStatic';
+ private static $privateStaticVar = 'privateStatic';
+ // Sadece bu sınıf içerisinde erişilebilir
+ protected static $protectedStaticVar = 'protectedStatic';
+ // Bu sınıf ve alt sınıflarından erişilebilir
+
+ // Özellikler görünürlüğü ile birlikte tanımlanmalıdır.
+ public $property = 'public';
+ public $instanceProp;
+ protected $prot = 'protected'; // Sınıf ve alt sınıflardan erişilebilir
+ private $priv = 'private'; // Sadece bu sınıftan erişilebilir
+
+ // __construct ile bir constructor oluşturulabilir.
+ public function __construct($instanceProp) {
+ // $this ile instance değişkenine erişilir.
+ $this->instanceProp = $instanceProp;
+ }
+
+ // Sınıfın içerisinde metodlar fonksiyonlar gibi tanımlanır.
+ public function myMethod()
+ {
+ print 'MyClass';
+ }
+
+ //final anahtar kelimesi bu metodu override edilemez yapacaktır.
+ final function youCannotOverrideMe()
+ {
+ }
+
+/*
+Bir sınıfın özelliğini ya da metodunu statik yaptığınız takdirde sınıfın bir
+objesini oluşturmadan bu elemana erişebilirsiniz. Bir özellik statik tanımlanmış
+ise obje üzerinden bu elemana erişilemez. (Statik metodlar öyle değildir.)
+*/
+
+
+ public static function myStaticMethod()
+ {
+ print 'I am static';
+ }
+}
+
+echo MyClass::MY_CONST; // 'value' şeklinde çıktı verir;
+echo MyClass::$staticVar; // 'static' şeklinde çıktı verir;
+MyClass::myStaticMethod(); // 'I am static' şeklinde çıktı verir;
+
+// Sınıfların new ile kullanımı
+$my_class = new MyClass('An instance property');
+// Eğer argüman göndermeyeceksek parantezler isteğe bağlıdır.
+
+// Sınıfın üyelerine erişim ->
+echo $my_class->property; // => "public"
+echo $my_class->instanceProp; // => "An instance property"
+$my_class->myMethod(); // => "MyClass"
+
+
+// "extends" ile sınıfı extend etmek
+class MyOtherClass extends MyClass
+{
+ function printProtectedProperty()
+ {
+ echo $this->prot;
+ }
+
+ // Bir methodu ezmek
+ function myMethod()
+ {
+ parent::myMethod();
+ print ' > MyOtherClass';
+ }
+}
+
+$my_other_class = new MyOtherClass('Instance prop');
+$my_other_class->printProtectedProperty(); // "protected" şeklinde çıktı verir.
+$my_other_class->myMethod(); // "MyClass > MyOtherClass" şeklinde çıktı verir
+
+final class YouCannotExtendMe
+{
+}
+
+// getter ve setter'ları oluşturmak için "magic method"ları kullanabilirsiniz.
+class MyMapClass
+{
+ private $property;
+
+ public function __get($key)
+ {
+ return $this->$key;
+ }
+
+ public function __set($key, $value)
+ {
+ $this->$key = $value;
+ }
+}
+
+$x = new MyMapClass();
+echo $x->property; // __get() metodunu kullanacaktır.
+$x->property = 'Something'; // __set() metodunu kullanacaktır.
+
+// Sınıflar abstract olabilir(abstract kelimesini kullanarak) veya
+// interface'ler uygulanabilir (implements kelimesi kullanılarak).
+// Bir interface "interface" kelimesi kullanılarak oluşturulur.
+
+interface InterfaceOne
+{
+ public function doSomething();
+}
+
+interface InterfaceTwo
+{
+ public function doSomethingElse();
+}
+
+// interfaces can be extended
+interface InterfaceThree extends InterfaceTwo
+{
+ public function doAnotherContract();
+}
+
+abstract class MyAbstractClass implements InterfaceOne
+{
+ public $x = 'doSomething';
+}
+
+class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo $x;
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+
+// Sınıflar birden fazla interface kullanabilir.
+class SomeOtherClass implements InterfaceOne, InterfaceTwo
+{
+ public function doSomething()
+ {
+ echo 'doSomething';
+ }
+
+ public function doSomethingElse()
+ {
+ echo 'doSomethingElse';
+ }
+}
+
+
+
+/********************************
+ * Traits
+ */
+// Trait'ler PHP 5.4.0'dan beri kullanılabilir ve "trait" kullanılarak
+// tanımlanır.
+
+trait MyTrait
+{
+ public function myTraitMethod()
+ {
+ print 'I have MyTrait';
+ }
+}
+
+class MyTraitfulClass
+{
+ use MyTrait;
+}
+
+$cls = new MyTraitfulClass();
+$cls->myTraitMethod(); // "I have MyTrait" çıktısını verir.
+
+
+
+/********************************
+ * İsim Uzayları
+ */
+
+// Bu alan ayrılmıştır, çünkü isim uzayı tanımı bir dosyada en başta
+// yapılmalıdır. Bu örnekte böyle olmadığını varsayalım.
+
+<?php
+
+// Varsayılan olarak, sınıflar global isim uzayındadır, ve açıkça bir
+// ters slash ile çağrılabilir.
+
+$cls = new \MyClass();
+
+
+
+// Bir dosya için isim uzayı atama
+namespace My\Namespace;
+
+class MyClass
+{
+}
+
+// (diğer bir dosya)
+$cls = new My\Namespace\MyClass;
+
+//veya diğer bir isim uzayında.
+namespace My\Other\Namespace;
+
+use My\Namespace\MyClass;
+
+$cls = new MyClass();
+
+// veya isim uzayına bir takma isim koyabilirsiniz.
+
+namespace My\Other\Namespace;
+
+use My\Namespace as SomeOtherNamespace;
+
+$cls = new SomeOtherNamespace\MyClass();
+
+*/
+
+```
+
+## Daha fazla bilgi
+
+Referans ve topluluk yazıları için [official PHP documentation](http://www.php.net/manual/) adresini ziyaret edin.
+
+Güncel en yi örnekler için [PHP Usulüne Uygun](http://kulekci.net/php-the-right-way/) adresini ziyaret edin.
+
+Eğer bir paket yöneticisi olan dil kullandıysanız, [Composer](http://getcomposer.org/)'a bir göz atın.
+
+Genel standartlar için PHP Framework Interoperability Group'unun [PSR standards](https://github.com/php-fig/fig-standards) ziyaret edebilirsiniz.
+
diff --git a/tr-tr/python-tr.html.markdown b/tr-tr/python-tr.html.markdown
new file mode 100644
index 00000000..01285080
--- /dev/null
+++ b/tr-tr/python-tr.html.markdown
@@ -0,0 +1,502 @@
+---
+language: python
+filename: learnpython-tr.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+---
+Python Guido Van Rossum tarafından 90'ların başında yaratılmıştır. Şu anda
+varolanlar arasında en iyi dillerden birisidir. Ben (Louie Dinh) Python
+dilinin syntax'ının belirginliğine aşığım. O basit olarak çalıştırılabilir
+pseudocode'dur.
+
+Geri bildirimlerden son derece mutluluk duyarım! Bana [@louiedinh](http://twitter.com/louiedinh)
+adresinden ya da louiedinh [at] [google's email service] adresinden ulaşabilirsiniz.
+
+Çeviri için geri bildirimleri de [@kulekci](http://twitter.com/kulekci)
+adresine yapabilirsiniz.
+
+Not: Bu yazıdaki özellikler Python 2.7 için geçerlidir, ama Python 2.x için de
+uygulanabilir. Python 3 için başka bir zaman tekrar bakınız.
+
+
+```python
+# Tek satır yorum hash işareti ile başlar.
+""" Çoklu satır diziler üç tane çift tırnak
+ arasında yazılır. Ve yorum olarak da
+ kullanılabilir
+"""
+
+
+####################################################
+## 1. İlkel Veri Tipleri ve Operatörler
+####################################################
+
+# Sayılar
+3 #=> 3
+
+# Matematik beklediğiniz gibi
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Bölünme biraz ilginç. EĞer tam sayılar üzerinde bölünme işlemi yapıyorsanız
+# sonuç otomatik olarak kırpılır.
+5 / 2 #=> 2
+
+# Bölünme işlemini düzenlemek için kayan noktalı sayıları bilmeniz gerekir.
+2.0 # Bu bir kayan noktalı sayı
+11.0 / 4.0 #=> 2.75 ahhh...daha iyi
+
+# İşlem önceliğini parantezler ile sağlayabilirsiniz.
+(1 + 3) * 2 #=> 8
+
+# Boolean değerleri bilindiği gibi
+True
+False
+
+# not ile nagatif(mantıksal) değerini alma
+not True #=> False
+not False #=> True
+
+# Eşitlik ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Eşitsizlik !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Daha fazla karşılaştırma
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Karşılaştırma zincirleme yapılabilir!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Karakter dizisi " veya ' ile oluşturulabilir
+"This is a string."
+'This is also a string.'
+
+# Karakter dizileri birbirleri ile eklenebilir
+"Hello " + "world!" #=> "Hello world!"
+
+# A string can be treated like a list of characters
+# Bir string'e karakter listesi gibi davranabilirsiniz.
+"This is a string"[0] #=> 'T'
+
+# % karakter dizisini(string) formatlamak için kullanılır, bunun gibi:
+"%s can be %s" % ("strings", "interpolated")
+
+# String'leri formatlamanın yeni bir yöntem ise format metodudur.
+# Bu metod tercih edilen yöntemdir.
+"{0} can be {1}".format("strings", "formatted")
+# Eğer saymak istemiyorsanız anahtar kelime kullanabilirsiniz.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+
+# None bir objedir
+None #=> None
+
+# "==" eşitliğini non objesi ile karşılaştırmak için kullanmayın.
+# Onun yerine "is" kullanın.
+"etc" is None #=> False
+None is None #=> True
+
+# 'is' operatörü obje kimliği için test etmektedir. Bu ilkel değerler
+# için kullanışlı değildir, ama objeleri karşılaştırmak için kullanışlıdır.
+
+# None, 0 ve boş string/list'ler False olarak değerlendirilir.
+# Tüm eşitlikler True döner
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Değişkenler ve Kolleksiyonlar
+####################################################
+
+# Ekrana yazdırma oldukça kolaydır.
+print "I'm Python. Nice to meet you!"
+
+
+# Değişkenlere bir değer atamadan önce tanımlamaya gerek yoktur.
+some_var = 5 # Değişken isimlerinde gelenek küçük karakter ve alt çizgi
+ # kullanmaktır.
+some_var #=> 5
+
+# Daha önceden tanımlanmamış ya da assign edilmemeiş bir değişkene erişmeye
+# çalıştığınızda bir hata fırlatılacaktır. Hata ayıklama hakkında daha fazla
+# bilgi için kontrol akışı kısmına göz atınız.
+some_other_var # isim hatası fırlatılır
+
+# isterseniz "if"i bir ifade gibi kullanabilirsiniz.
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listeler
+li = []
+# Önceden değerleri tanımlanmış listeler
+other_li = [4, 5, 6]
+
+# Bir listenin sonuna birşeyler eklemek
+li.append(1) #li şu anda [1]
+li.append(2) #li şu anda [1, 2]
+li.append(4) #li şu anda [1, 2, 4]
+li.append(3) #li şu anda [1, 2, 4, 3]
+# pop ile sondan birşeyler silmek
+li.pop() #=> 3 and li is now [1, 2, 4]
+# Tekrar sonuna eklemek
+li.append(3) # li is now [1, 2, 4, 3] again.
+
+# Dizi gibi listenin elemanlarına erişmek
+li[0] #=> 1
+# Son elemanın değerine ulaşmak
+li[-1] #=> 3
+
+# Listede bulunmayan bir index'teki elemana erişirken "IndexError" hatası
+# fırlatılır
+li[4] # IndexError fırlatılır
+
+# slice syntax'ı ile belli aralıktakı değerlere bakabilirsiniz.
+# (Açık ve kapalı aralıklıdır.)
+li[1:3] #=> [2, 4]
+# Başlangıcı ihmal etme
+li[2:] #=> [4, 3]
+# Sonu ihmal etme
+li[:3] #=> [1, 2, 4]
+
+# "del" ile istenilen bir elemanı listeden silmek
+del li[2] # li is now [1, 2, 3]
+
+# Listeleri birbiri ile birleştirebilirsiniz.
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Not: li ve other_li yanlız bırakılır
+
+# extend ile listeleri birleştirmek
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+
+# bir değerin liste içerisinde varlığını "in" ile kontrol etmek
+1 in li #=> True
+
+# "len" ile listenin uzunluğunu bulmak
+len(li) #=> 6
+
+# Tüpler listeler gibidir sadece değişmezler(immutable)
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # TypeError fırlatılır.
+
+# Litelerde yapılanların hepsini tüplerde de yapılabilir
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Tüplerin(veya listelerin) içerisindeki değerleri değişkenelere
+# atanabilir
+a, b, c = (1, 2, 3) # a şu anda 1, b şu anda 2 ve c şu anda 3
+# Eğer parantez kullanmaz iseniz tüpler varsayılan olarak oluşturulur
+d, e, f = 4, 5, 6
+# şimdi iki değeri değiş tokuş etmek çok kolaydır.
+e, d = d, e # d şimdi 5 ve e şimdi 4
+
+
+# Sözlükler (Dictionaries) key-value saklanır.
+empty_dict = {}
+# Sözlüklere önceden değer atama örneği
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Değere ulaşmak için [] kullanılır
+filled_dict["one"] #=> 1
+
+# Tüm anahtarlara(key) "keys()" metodu ile ulaşılır
+filled_dict.keys() #=> ["three", "two", "one"]
+# Not - Sözlüklerin anahtarlarının sıralı geleceği garanti değildir
+# Sonuçlarınız değer listesini aldığınızda tamamen eşleşmeyebilir
+
+# Tüm değerleri almak için "values()" kullanabilirsiniz.
+filled_dict.values() #=> [3, 2, 1]
+# Not - Sıralama ile ilgili anahtarlar ile aynı durum geçerlidir.
+
+# Bir anahtarın sözlükte oluş olmadığını "in" ile kontrol edilebilir
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Olmayan bir anahtar çağrıldığında KeyError fırlatılır.
+filled_dict["four"] # KeyError
+
+# "get()" metodu KeyError fırlatılmasını önler
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# get() metodu eğer anahtar mevcut değilse varsayılan bir değer atama
+# imknaı sağlar.
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# "setdefault()" metodu sözlüğe yeni bir key-value eşleşmesi eklemenin
+# güvenli bir yoludur.
+filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5
+
+
+# Sets store ... well sets
+empty_set = set()
+# Bir demek değer ile bir "set" oluşturmak
+some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
+
+# Python 2.7'den beri {}'ler bir "set" tanımlaman için kullanılabilir
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Bir set'e daha fazla eleman eklemek
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# "&" işareti ile iki set'in kesişimlerini alınabilir
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# | işareti ile
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# "-" işareti ile iki set'in farkları alınabilir
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# "in" ile değerin set içerisinde olup olmadığını kontrol edebilirsiniz
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Akış Denetimi
+####################################################
+
+# Bir değişken oluşturmak
+some_var = 5
+
+# Buradaki bir if ifadesi. Girintiler(Intentation) Python'da önemlidir!
+# "some_var is smaller than 10" yazdırılır.
+if some_var > 10:
+ print "some_var is totally bigger than 10."
+elif some_var < 10: # elif ifadesi isteğe bağlıdır
+ print "some_var is smaller than 10."
+else: # Bu da isteğe bağlıdır.
+ print "some_var is indeed 10."
+
+
+"""
+For döngüleri listeler üzerinde iterasyon yapar
+Ekrana yazdırılan:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # Biçimlendirmeleri string'e katmak için % kullanabilirsiniz
+ print "%s is a mammal" % animal
+
+"""
+"range(number)" ifadesi sıfırdan verilen sayıya kadar bir sayı listesi döner
+Ekrana yazdırılan:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While döngüsü koşul sağlanmayana kadar devam eder
+Ekrana yazdırılan:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Shorthand for x = x + 1
+
+# try/except bloğu ile hatalar ayıklanabilir
+
+# Python 2.6 ve üstü için çalışacaktır:
+try:
+ # "raise" bir hata fırlatmak için kullanılabilir
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass is just a no-op. Usually you would do recovery here.
+
+
+####################################################
+## 4. Fonksiyonlar
+####################################################
+
+
+# Yeni bir fonksiyon oluşturmak için "def" kullanılır
+def add(x, y):
+ print "x is %s and y is %s" % (x, y)
+ return x + y # Return values with a return statement
+
+# Fonksiyonu parametre ile çağırmak
+add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11
+
+# Diğer bir yol fonksiyonları anahtar argümanları ile çağırmak
+add(y=6, x=5) # Anahtar argümanlarının sırası farklı da olabilir
+
+# Değişken sayıda parametresi olan bir fonksiyon tanımlayabilirsiniz
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+# Değişken sayıda anahtar argümanlı parametre alan fonksiyonlar da
+# tanımlayabilirsiniz.
+def keyword_args(**kwargs):
+ return kwargs
+
+# Şu şekilde kullanılacaktır
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Eğer isterseniz ikisini aynı anda da yapabilirsiniz
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) prints:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Fonksiyonu çağırırken, args/kwargs'ın tam tersini de yapabilirsiniz!
+# Tüpü yaymak için * ve kwargs'ı yaymak için ** kullanın.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # foo(1, 2, 3, 4) ile eşit
+all_the_args(**kwargs) # foo(a=3, b=4) ile eşit
+all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4) ile eşit
+
+# Python first-class fonksiyonlara sahiptir
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Anonymous fonksiyonlar da vardır
+(lambda x: x > 2)(3) #=> True
+
+# Dahili yüksek seviye fonksiyonlar vardır
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Map etme(maps) ve filtreleme(filtres) için liste kullanabiliriz.
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+
+####################################################
+## 5. Sınıflar
+####################################################
+
+# We subclass from object to get a class.
+class Human(object):
+
+ # Bir sınıf özelliği. Bu sınıfın tüm "instance"larına paylaşılmıştır.
+ species = "H. sapiens"
+
+ # Basic initializer
+ def __init__(self, name):
+ # Metoda gelen argümanın değerini sınıfın elemanı olan "name"
+ # değişkenine atama
+ self.name = name
+
+ # Bir instance metodu. Tüm metodlar ilk argüman olarak "self"
+ # parametresini alır
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Bir sınıf metodu tüm "instance"lar arasında paylaşılır
+ # İlk argüman olarak sınıfı çağırarak çağrılırlar
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Bir statik metod bir sınıf ya da instance referansı olmadan çağrılır
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Bir sınıf örneği oluşturmak
+i = Human(name="Ian")
+print i.say("hi") # "Ian: hi" çıktısı verir
+
+j = Human("Joel")
+print j.say("hello") # "Joel: hello" çıktısı verir
+
+# Sınıf metodunu çağıralım
+i.get_species() #=> "H. sapiens"
+
+# Paylaşılan sınıf özellik değiştirelim.
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Statik metodu çağırma
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modüller
+####################################################
+
+# Modülleri sayfaya dahil edebilirsiniz
+import math
+print math.sqrt(16) #=> 4
+
+# Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Modüldeki tüm fonksiyonları dahil edebilirsiniz
+# Uyarı: bu önerilmez
+from math import *
+
+# Modülün adını kısaltabilirsiniz
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Python modülleri sıradan python dosyalarıdır. Kendinize bir modül
+# yazabilirsiniz, ve dahil edebilirsiniz. Modülün adı ile dosya adı
+# aynı olmalıdır.
+
+# Modüllerde tanımlanmış fonksiyon ve metodları öğrenebilirsiniz.
+import math
+dir(math)
+
+
+
+```
+
+## Daha fazlası için hazır mısınız?
+
+### Ücretsiz Dökümanlar
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Dead Tree
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/vi-vn/git-vi.html.markdown b/vi-vn/git-vi.html.markdown
new file mode 100644
index 00000000..bdb88204
--- /dev/null
+++ b/vi-vn/git-vi.html.markdown
@@ -0,0 +1,393 @@
+---
+category: tool
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+filename: LearnGit-vi.txt
+lang: vi-vn
+---
+
+Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system).
+
+Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, and nó hoạt động
+với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và
+quản lý mã nguồn của bạn.
+
+## Khái Niệm Versioning
+
+### Version Control là gì?
+
+Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian.
+
+### Centralized Versioning VS Distributed Versioning
+
+* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin.
+* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất.
+* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git.
+
+[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Tại Sao Dùng Git?
+
+* Có thể hoạt động offline.
+* Cộng tác với nhau rất dễ dàng!
+* Phân nhánh dễ dàng!
+* Trộn (Merging)
+* Git nhanh.
+* Git linh hoạt.
+
+## Kiến Trúc Git
+
+
+### Repository
+
+Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn,
+với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác.
+
+Một git repository bao gồm thư mục .git & tree đang làm việc.
+
+### Thư mục .git (thành phần của một repository)
+
+Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa.
+[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Tree Đang Làm (thành phần của một repository)
+
+Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu
+thư mục đang làm việc của bạn
+
+### Chỉ mục (thành phần của một thư mục .git)
+
+Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn
+từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git
+repository.
+
+### Commit
+
+Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn.
+Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong
+một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không!
+
+### Nhánh
+
+Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit,
+con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất.
+
+### HEAD và head (thành phần của thư mục .git)
+
+HEAD là một con trỏ đến nhánh hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
+head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head.
+
+### Các Tài Nguyên Mang Tính Khái Niệm
+
+* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
+
+
+## Các Lệnh
+
+
+### init
+
+Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git
+được lưu ở một thư mục tên là ".git".
+
+```bash
+$ git init
+```
+
+### config
+
+Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh
+toàn cục (global)
+
+
+
+```bash
+# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global)
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config)
+
+### help
+
+Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để
+nhắc bạn một số cú pháp.
+
+```bash
+# Xem nhanh các lệnh có sẵn
+$ git help
+
+# Xem tất các các lệnh
+$ git help -a
+
+# Lệnh help riêng biệt - tài liệu người dùng
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit
+hiện tại.
+
+
+```bash
+# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác
+$ git status
+
+# Để xem các "tid bits" về git status
+$ git help status
+```
+
+### add
+
+Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến
+tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit!
+
+```bash
+# thêm một file vào thư mục hiện tại
+$ git add HelloWorld.java
+
+# thêm một file vào một thư mục khác
+$ git add /path/to/file/HelloWorld.c
+
+# Hỗ trợ Regular Expression!
+$ git add ./*.java
+```
+
+### branch
+
+Quản lý nhánh. Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
+
+```bash
+# liệt kê các nhanh đang có và ở remote
+$ git branch -a
+
+# tạo nhánh mới
+$ git branch myNewBranch
+
+# xóa một nhánh
+$ git branch -d myBranch
+
+# đặt tên lại một nhánh
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# chỉnh sủa diễn giải của một nhánh
+$ git branch myBranchName --edit-description
+```
+
+### checkout
+
+Cập nhật tất cả các file torng tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
+
+```bash
+# Checkout (chuyển) một repo - mặc định là nhánh master
+$ git checkout
+# Checkout một nhánh cụ thể
+$ git checkout branchName
+# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>"
+$ git checkout -b newBranch
+```
+
+### clone
+
+Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm
+các nhánh có remote-tracking cho mỗi nhánh trong một repo được nhân bản, mà
+cho phép bạn push đến một nhánh remote.
+
+```bash
+# Nhân bản learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+```
+
+### commit
+
+Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một lời nhắn (ghi chú) tạo ra bởi người dùng.
+
+```bash
+# commit với một ghi chú
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+```
+
+### diff
+
+Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits.
+
+```bash
+# Hiển thị sự khác biệt giữa thư mục hiện tại và index
+$ git diff
+
+# Hiển thị khác biệt giữa index và commit mới nhất.
+$ git diff --cached
+
+# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất
+$ git diff HEAD
+```
+
+### grep
+
+Cho phép bạn tìm kiếm nhanh một repo.
+
+Các tinh chỉnh tùy chọn:
+
+```bash
+# Cảm ơn Travis Jeffery vì những lệnh này
+# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep
+$ git config --global grep.lineNumber true
+
+# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Tìm "variableName" trong tất cả các file Java
+$ git grep 'variableName' -- '*.java'
+
+# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Google để xem thêm các ví dụ
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Hiển thị các commit đến repo.
+
+```bash
+# Hiện tất cả các commit
+$ git log
+
+# Hiện X commit
+$ git log -n 10
+
+# Chỉ hiện các commit đã merge merge commits
+$ git log --merges
+```
+
+### merge
+
+"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại.
+
+```bash
+# Merge nhánh cụ thể vào nhánh hiện tại.
+$ git merge branchName
+
+# Luôn khởi tạo một merge commit khi trộn (merge)
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Đặt lại tên hoặc di chuyển một file
+
+```bash
+# Đặt lại tên một file
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Di chuyển một file
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Buộc đặt lại tên hoặc di chuyển
+# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Kéo (tải) về từ một repo và merge nó vào nhánh khác.
+
+```bash
+# Cập nhật repo cục bộ của bạn, bằng cách merge các thay đổi mới
+# từ remote "origin" và nhánh "master".
+# git pull <remote> <branch>
+# git pull => hoàn toàn mặc định như => git pull origin master
+$ git pull origin master
+
+# Merge các thay đổi từ nhánh remote và rebase
+# các commit nhánh lên trên thư mục cục bộ, như: "git pull <remote> <branch>, git rebase <branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Đẩy và trộn (mege) các tay đổi từ một nhánh đế một remote & nhánh.
+
+```bash
+# Push và merge các thay đổi từ repo cục bộ đến một
+# remote tên là "origin" và nhánh "master".
+# git push <remote> <branch>
+# git push => hoàn toàn defaults to => git push origin master
+$ git push origin master
+```
+
+### rebase (thận trọng)
+
+Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác.
+*Không rebase các commit mà bạn đã push đến một repo công khai*.
+
+```bash
+# Rebase experimentBranch lên master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (thận trọng)
+
+Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges,
+pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không
+biết mình đang làm gì.
+
+```bash
+# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi)
+$ git reset
+
+# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại
+$ git reset --hard
+
+# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi)
+# tất cả thay đổi vẫn duy trì trong thư mục.
+$ git reset 31f2bb1
+
+# Di chuyển nhánh hiện tại lùi về một commit cụ thể
+# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit
+# sau một commit cụ thể).
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+Ngược lại với git add, git rm xóa file từ tree đang làm việc.
+
+```bash
+# xóa HelloWorld.c
+$ git rm HelloWorld.c
+
+# Xóa file từ thư mục khác
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Thông tin thêm
+
+* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video Tutorials](http://git-scm.com/videos)
+
+* [git-scm - Documentation](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
+
+* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/vi-vn/objective-c-vi.html.markdown b/vi-vn/objective-c-vi.html.markdown
new file mode 100644
index 00000000..6d19ca02
--- /dev/null
+++ b/vi-vn/objective-c-vi.html.markdown
@@ -0,0 +1,318 @@
+---
+
+language: Objective-C
+contributors:
+ - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+lang: vi-vn
+filename: LearnObjectiveC-vi.m
+
+---
+
+Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành OS X, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch.
+Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
+
+```cpp
+// Chú thích dòng đơn bắt đầu với //
+
+/*
+Chú thích đa dòng trông như thế này.
+*/
+
+// Nhập các headers của framework Foundation với cú pháp #import
+#import <Foundation/Foundation.h>
+#import "MyClass.h"
+
+// Đầu vào chương trình của bạn là một hàm gọi là
+// main với một kiểu trả về kiểu integer.
+int main (int argc, const char * argv[])
+{
+ // Tạo một autorelease pool để quản lý bộ nhớ vào chương trình
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // Sử dụng hàm NSLog() để in ra các dòng lệnh vào console
+ NSLog(@"Hello World!"); // Print the string "Hello World!"
+
+ ///////////////////////////////////////
+ // Kiểu & Biến (Types & Variables)
+ ///////////////////////////////////////
+
+ // Khai báo số nguyên
+ int myPrimitive1 = 1;
+ long myPrimitive2 = 234554664565;
+
+ // Khai báo đối tượng
+ // Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong
+ MyClass *myObject1 = nil; // Strong
+ id myObject2 = nil; // Weak
+ // %@ là một đối tượng
+ // 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng
+ NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)"
+
+ // Chuỗi
+ NSString *worldString = @"World";
+ NSLog(@"Hello %@!", worldString); // In ra "Hello World!"
+
+ // Ký tự literals
+ NSNumber *theLetterZNumber = @'Z';
+ char theLetterZ = [theLetterZNumber charValue];
+ NSLog(@"%c", theLetterZ);
+
+ // Số nguyên literals
+ NSNumber *fortyTwoNumber = @42;
+ int fortyTwo = [fortyTwoNumber intValue];
+ NSLog(@"%i", fortyTwo);
+
+ NSNumber *fortyTwoUnsignedNumber = @42U;
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *fortyTwoLongNumber = @42L;
+ long fortyTwoLong = [fortyTwoLongNumber longValue];
+ NSLog(@"%li", fortyTwoLong);
+
+ // Dấu phẩy động (floating point) literals
+ NSNumber *piFloatNumber = @3.141592654F;
+ float piFloat = [piFloatNumber floatValue];
+ NSLog(@"%f", piFloat);
+
+ NSNumber *piDoubleNumber = @3.1415926535;
+ double piDouble = [piDoubleNumber doubleValue];
+ NSLog(@"%f", piDouble);
+
+ // BOOL literals
+ NSNumber *yesNumber = @YES;
+ NSNumber *noNumber = @NO;
+
+ // Đối tượng Mảng
+ NSArray *anArray = @[@1, @2, @3, @4];
+ NSNumber *thirdNumber = anArray[2];
+ NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3"
+
+ // Đối tượng Từ điển
+ NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
+ NSObject *valueObject = aDictionary[@"A Key"];
+ NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)"
+
+ ///////////////////////////////////////
+ // Toán Tử (Operators)
+ ///////////////////////////////////////
+
+ // Các toán tử cũng hoạt động giống như ngôn ngữ C
+ // Ví dụ:
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (NO)
+ 3 != 2; // => 1 (YES)
+ 1 && 1; // => 1 (Logical and)
+ 0 || 1; // => 1 (Logical or)
+ ~0x0F; // => 0xF0 (bitwise negation)
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1))
+
+ /////////////////////////////////////////////
+ // Cấu Trúc Điều Khiển (Controls Structures)
+ /////////////////////////////////////////////
+
+ // Câu lệnh If-Else
+ if (NO)
+ {
+ NSLog(@"I am never run");
+ } else if (0)
+ {
+ NSLog(@"I am also never run");
+ } else
+ {
+ NSLog(@"I print");
+ }
+
+ // Câu lệnh Switch
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"I am never run");
+ } break;
+ case 1:
+ {
+ NSLog(@"I am also never run");
+ } break;
+ default:
+ {
+ NSLog(@"I print");
+ } break;
+ }
+
+ // Câu lệnh vòng lặp While
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó.
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh vòng lặp For
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj);
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh Foreach
+ NSArray *values = @[@0, @1, @2, @3];
+ for (NSNumber *value in values)
+ {
+ NSLog(@"%@,", value);
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh Try-Catch-Finally
+ @try
+ {
+ // Your statements here
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil];
+ } @catch (NSException * e)
+ {
+ NSLog(@"Exception: %@", e);
+ } @finally
+ {
+ NSLog(@"Finally");
+ } // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống"
+ // "Finally"
+
+ ///////////////////////////////////////
+ // Đối Tượng (Objects)
+ ///////////////////////////////////////
+
+ // Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó.
+ // Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành
+ MyClass *myObject = [[MyClass alloc] init];
+
+ // Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message)
+ // và các thực thể đối tượng với nhau.
+ // Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp.
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình
+ [pool drain];
+
+ // Kết thúc chương trình
+ return 0;
+}
+
+///////////////////////////////////////
+// Lớp và Hàm (Classes & Functions)
+///////////////////////////////////////
+
+// Khai báo lớp của bạn ở một tập tin header (MyClass.h):
+// Cú pháp Khai Báo Lớp:
+// @interface ClassName : ParentClassName <ImplementedProtocols>
+// {
+// Khai báo biến thành viên;
+// }
+// -/+ (type) Khai báo method;
+// @end
+@interface MyClass : NSObject <MyProtocol>
+{
+ int count;
+ id data;
+ NSString *name;
+}
+// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter
+@property int count;
+@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán.
+@property (readonly) id data; // Chỉ khai báo phương thức getter.
+
+// Phương thức
++/- (return type)methodSignature:(Parameter Type *)parameterName;
+
+// dấu '+' cho phương thức lớp
++ (NSString *)classMethod;
+
+// dấu '-' cho phương thức thực thể
+- (NSString *)instanceMethodWithParameter:(NSString *)string;
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
+
+@end
+
+// Thực thi các phương thức trong một tập tin thực thi (MyClass.m):
+
+@implementation MyClass
+
+// Gọi khi đối tượng được release
+- (void)dealloc
+{
+}
+
+// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp
+// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ self.count = 1;
+ }
+ return self;
+}
+
++ (NSString *)classMethod
+{
+ return [[self alloc] init];
+}
+
+- (NSString *)instanceMethodWithParameter:(NSString *)string
+{
+ return @"New string";
+}
+
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
+{
+ return @42;
+}
+
+// Các phương thức được khai báo vào MyProtocol
+- (void)myProtocolMethod
+{
+ // câu lệnh
+}
+
+@end
+
+/*
+ * Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào.
+ * Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface)
+ * mà các đối tượng khác có trách nhiệm sẽ thực thi.
+ */
+@protocol MyProtocol
+ - (void)myProtocolMethod;
+@end
+
+
+
+```
+## Xem Thêm
+
++ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
+
++ Apple Docs':
+ + [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
+
+ + [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
+
+ + [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)
+
+ + [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
+
++ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
diff --git a/whip.html.markdown b/whip.html.markdown
index b8852ecb..3429ec24 100644
--- a/whip.html.markdown
+++ b/whip.html.markdown
@@ -109,18 +109,18 @@ undefined ; user to indicate a value that hasn't been set
; Dictionaries are Whip's equivalent to JavaScript 'objects' or Python 'dicts'
; or Ruby 'hashes': an unordered collection of key-value pairs.
-{"key1":"value1" "key2":2 3:3}
+{"key1" "value1" "key2" 2 3 3}
; Keys are just values, either identifier, number, or string.
-(def my_dict {my_key:"my_value" "my other key":4})
-; But in Whip, dictionaries get parsed like: value, colon, value;
-; with whitespace between each. So that means
-{"key": "value"
+(def my_dict {my_key "my_value" "my other key" 4})
+; But in Whip, dictionaries get parsed like: value, whitespace, value;
+; with more whitespace between each. So that means
+{"key" "value"
"another key"
-: 1234
+1234
}
; is evaluated to the same as
-{"key":"value" "another key":1234}
+{"key" "value" "another key" 1234}
; Dictionary definitions can be accessed used the `at` function
; (like strings and lists.)
@@ -220,8 +220,8 @@ undefined ; user to indicate a value that hasn't been set
(max (1 2 3 4)) ; 4
; If value is in list or object
(elem 1 (1 2 3)) ; true
-(elem "foo" {"foo":"bar"}) ; true
-(elem "bar" {"foo":"bar"}) ; false
+(elem "foo" {"foo" "bar"}) ; true
+(elem "bar" {"foo" "bar"}) ; false
; Reverse list order
(reverse (1 2 3 4)) ; => (4 3 2 1)
; If value is even or odd
diff --git a/xml.html.markdown b/xml.html.markdown
new file mode 100644
index 00000000..c072e0c7
--- /dev/null
+++ b/xml.html.markdown
@@ -0,0 +1,131 @@
+---
+language: xml
+filename: learnxml.xml
+contributors:
+ - ["João Farias", "https://github.com/JoaoGFarias"]
+---
+
+XML is a markup language designed to store and transport data.
+
+Unlike HTML, XML does not specifies how to display or to format data, just carry it.
+
+* XML Syntax
+
+```xml
+<!-- Comments in XML are like this -->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<bookstore>
+ <book category="COOKING">
+ <title lang="en">Everyday Italian</title>
+ <author>Giada De Laurentiis</author>
+ <year>2005</year>
+ <price>30.00</price>
+ </book>
+ <book category="CHILDREN">
+ <title lang="en">Harry Potter</title>
+ <author>J K. Rowling</author>
+ <year>2005</year>
+ <price>29.99</price>
+ </book>
+ <book category="WEB">
+ <title lang="en">Learning XML</title>
+ <author>Erik T. Ray</author>
+ <year>2003</year>
+ <price>39.95</price>
+ </book>
+</bookstore>
+
+<!-- Above is a typical XML file.
+ It starts with a declaration, informing some metadata (optional)
+
+ XML uses a tree structure. Above, the root node is 'bookstore', which has
+ three child nodes, all 'books'. Those nodes has more child nodes, and so on...
+
+ Nodes are created using open/close tags, and childs are just nodes between
+ the open and close tags.-->
+
+
+<!-- XML carries two kind of data:
+ 1 - Attributes -> That's metadata about a node.
+ Usually, the XML parser uses this information to store the data properly.
+ It is characterized by appearing in parenthesis within the opening tag
+ 2 - Elements -> That's pure data.
+ That's what the parser will retrive from the XML file.
+ Elements appear between the open and close tags, without paranthesis. -->
+
+
+<!-- Below, an element with two attributes -->
+<file type="gif" id="4293">computer.gif</file>
+
+
+```
+
+* Well-Formated Document x Validation
+
+A XML document is well-formated if it is syntactically correct.
+However, is possible to inject more constraints in the document,
+using document definitions, such as DTD and XML Schema.
+
+A XML document which follows a document definition is called valid,
+regarding that document.
+
+With this tool, you can check the XML data outside the application logic.
+
+```xml
+
+<!-- Below, you can see an simplified version of bookstore document,
+ with the addition of DTD definition.-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE note SYSTEM "Bookstore.dtd">
+<bookstore>
+ <book category="COOKING">
+ <title >Everyday Italian</title>
+ <price>30.00</price>
+ </book>
+</bookstore>
+
+<!-- This DTD could be something like:-->
+
+<!DOCTYPE note
+[
+<!ELEMENT bookstore (book+)>
+<!ELEMENT book (title,price)>
+<!ATTLIST book category CDATA "Literature">
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT price (#PCDATA)>
+]>
+
+
+<!-- The DTD starts with a declaration.
+ Following, the root node is declared, requiring 1 or more child nodes 'book'.
+ Eeach 'book' should contain exactly one 'title' and 'price' and an attribute
+ called 'category', with "Literature" as its default value.
+ The 'title' and 'price' nodes contain a parsed character data.-->
+
+<!-- The DTD could be declared inside the XML file itself.-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE note
+[
+<!ELEMENT bookstore (book+)>
+<!ELEMENT book (title,price)>
+<!ATTLIST book category CDATA "Literature">
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT price (#PCDATA)>
+]>
+
+<bookstore>
+ <book category="COOKING">
+ <title >Everyday Italian</title>
+ <price>30.00</price>
+ </book>
+</bookstore>
+
+
+```
+
+
+
diff --git a/yaml.html.markdown b/yaml.html.markdown
new file mode 100644
index 00000000..c5d15895
--- /dev/null
+++ b/yaml.html.markdown
@@ -0,0 +1,139 @@
+---
+language: yaml
+filename: learnyaml.yaml
+contributors:
+ - ["Adam Brenecki", "https://github.com/adambrenecki"]
+---
+
+YAML is a data serialisation language designed to be directly writable and
+readable by humans.
+
+It's a strict superset of JSON, with the addition of syntactically
+significant newlines and indentation, like Python. Unlike Python, however,
+YAML doesn't allow literal tab characters at all.
+
+```yaml
+# Comments in YAML look like this.
+
+################
+# SCALAR TYPES #
+################
+
+# Our root object (which continues for the entire document) will be a map,
+# which is equivalent to a dictionary, hash or object in other languages.
+key: value
+another_key: Another value goes here.
+a_number_value: 100
+scientific_notation: 1e+12
+boolean: true
+null_value: null
+key with spaces: value
+# Notice that strings don't need to be quoted. However, they can be.
+however: "A string, enclosed in quotes."
+"Keys can be quoted too.": "Useful if you want to put a ':' in your key."
+
+# Multiple-line strings can be written either as a 'literal block' (using |),
+# or a 'folded block' (using '>')
+literal_block: |
+ This entire block of text will be the value of the 'literal_block' key,
+ with line breaks being preserved.
+
+ The literal continues until de-dented, and the leading indentation is
+ stripped.
+
+ Any lines that are 'more-indented' keep the rest of their indentation -
+ these lines will be indented by 4 spaces.
+folded_style: >
+ This entire block of text will be the value of 'folded_style', but this
+ time, all newlines will be replaced with a single space.
+
+ Blank lines, like above, are converted to a newline character.
+
+ 'More-indented' lines keep their newlines, too -
+ this text will appear over two lines.
+
+####################
+# COLLECTION TYPES #
+####################
+
+# Nesting is achieved by indentation.
+a_nested_map:
+ key: value
+ another_key: Another Value
+ another_nested_map:
+ hello: hello
+
+# Maps don't have to have string keys.
+0.25: a float key
+
+# Keys can also be multi-line objects, using ? to indicate the start of a key
+? |
+ This is a key
+ that has multiple lines
+: and this is its value
+
+# YAML also allows collection types in keys, but many programming languages
+# will complain.
+
+# Sequences (equivalent to lists or arrays) look like this:
+a_sequence:
+ - Item 1
+ - Item 2
+ - 0.5 # sequences can contain disparate types
+ - Item 4
+ - key: value
+ another_key: another_value
+ -
+ - This is a sequence
+ - inside another sequence
+
+# Since YAML is a superset of JSON, you can also write JSON-style maps and
+# sequences:
+json_map: {"key": "value"}
+json_seq: [3, 2, 1, "takeoff"]
+
+#######################
+# EXTRA YAML FEATURES #
+#######################
+
+# YAML also has a handy feature called 'anchors', which let you easily duplicate
+# content across your document. Both of these keys will have the same value:
+anchored_content: &anchor_name This string will appear as the value of two keys.
+other_anchor: *anchor_name
+
+# YAML also has tags, which you can use to explicitly declare types.
+explicit_string: !!str 0.5
+# Some parsers implement language specific tags, like this one for Python's
+# complex number type.
+python_complex_number: !!python/complex 1+2j
+
+####################
+# EXTRA YAML TYPES #
+####################
+
+# Strings and numbers aren't the only scalars that YAML can understand.
+# ISO-formatted date and datetime literals are also parsed.
+datetime: 2001-12-15T02:59:43.1Z
+datetime_with_spaces: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
+
+# The !!binary tag indicates that a string is actually a base64-encoded
+# representation of a binary blob.
+gif_file: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+
+# YAML also has a set type, which looks like this:
+set:
+ ? item1
+ ? item2
+ ? item3
+
+# Like Python, sets are just maps with null values; the above is equivalent to:
+set2:
+ item1: null
+ item2: null
+ item3: null
+```
diff --git a/zh-cn/bash-cn.html.markdown b/zh-cn/bash-cn.html.markdown
new file mode 100644
index 00000000..6afa659a
--- /dev/null
+++ b/zh-cn/bash-cn.html.markdown
@@ -0,0 +1,148 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Darren Lin", "https://github.com/CogBear"]
+ - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
+translators:
+ - ["Chunyang Xu", "https://github.com/XuChunyang"]
+filename: LearnBash-cn.sh
+lang: zh-cn
+---
+
+Bash 是一个为 GNU 计划编写的 Unix shell,是 Linux 和 Mac OS X 下的默认 shell。
+以下大多数例子可以作为脚本的一部分运行,也可直接在 shell 下交互执行。
+
+[更多信息](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# 脚本的第一行叫 shebang,用来告知系统如何执行该脚本:
+# 参见: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# 如你所见,注释以 # 开头,shebang 也是注释。
+
+# 显示 “Hello world!”
+echo Hello, world!
+
+# 每一句指令以换行或分号隔开:
+echo 'This is the first line'; echo 'This is the second line'
+
+# 声明一个变量:
+VARIABLE="Some string"
+
+# 下面是错误的做法:
+VARIABLE = "Some string"
+# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。
+
+
+# 使用变量:
+echo $VARIABLE
+echo "$VARIABLE"
+echo '$VARIABLE'
+# 当你赋值 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。
+# 如果要使用变量的值, 则要加 $。
+# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
+
+
+# 在变量内部进行字符串代换
+echo ${VARIABLE/Some/A}
+# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。
+
+# 内置变量:
+# 下面的内置变量很有用
+echo "Last program return value: $?"
+echo "Script's PID: $$"
+echo "Number of arguments: $#"
+echo "Scripts arguments: $@"
+echo "Scripts arguments separeted in different variables: $1 $2..."
+
+# 读取输入:
+echo "What's your name?"
+read NAME # 这里不需要声明新变量
+echo Hello, $NAME!
+
+# 通常的 if 结构看起来像这样:
+# 'man test' 可查看更多的信息
+if [ $NAME -ne $USER ]
+then
+ echo "Your name is you username"
+else
+ echo "Your name isn't you username"
+fi
+
+# 根据上一个指令执行结果决定是否执行下一个指令
+echo "Always executed" || echo "Only executed if first command fail"
+echo "Always executed" && echo "Only executed if first command does NOT fail"
+
+# 表达式的格式如下:
+echo $(( 10 + 5 ))
+
+# 与其他编程语言不同的是,bash 运行时依赖上下文。比如,使用 ls 时,列出当前目录。
+ls
+
+# 指令可以带有选项:
+ls -l # 列出文件和目录的详细信息
+
+# 前一个指令的输出可以当作后一个指令的输入。grep 用来匹配字符串。
+# 用下面的指令列出当前目录下所有的 txt 文件:
+ls -l | grep "\.txt"
+
+# 重定向可以到输出,输入和错误输出。
+python2 hello.py < "input.in"
+python2 hello.py > "output.out"
+python2 hello.py 2> "error.err"
+# > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。
+
+# 一个指令可用 $( ) 嵌套在另一个指令内部:
+# 以下的指令会打印当前目录下的目录和文件总数
+echo "There are $(ls | wc -l) items here."
+
+# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
+case "$VARIABLE" in
+ # 列出需要匹配的字符串
+ 0) echo "There is a zero.";;
+ 1) echo "There is a one.";;
+ *) echo "It is not null.";;
+esac
+
+# 循环遍历给定的参数序列:
+# 变量$VARIABLE 的值会被打印 3 次。
+# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。
+for VARIABLE in `seq 3`
+do
+ echo "$VARIABLE"
+done
+
+# 你也可以使用函数
+# 定义函数:
+function foo ()
+{
+ echo "Arguments work just like script arguments: $@"
+ echo "And: $1 $2..."
+ echo "This is a function"
+ return 0
+}
+
+# 更简单的方法
+bar ()
+{
+ echo "Another way to declare functions!"
+ return 0
+}
+
+# 调用函数
+foo "My name is" $NAME
+
+# 有很多有用的指令需要学习:
+tail -n 10 file.txt
+# 打印 file.txt 的最后 10 行
+head -n 10 file.txt
+# 打印 file.txt 的前 10 行
+sort file.txt
+# 将 file.txt 按行排序
+uniq -d file.txt
+# 报告或忽略重复的行,用选项 -d 打印重复的行
+cut -d ',' -f 1 file.txt
+# 打印每行中 ',' 之前内容
+```
diff --git a/zh-cn/brainfuck-cn.html.markdown b/zh-cn/brainfuck-cn.html.markdown
new file mode 100644
index 00000000..a6f3fa09
--- /dev/null
+++ b/zh-cn/brainfuck-cn.html.markdown
@@ -0,0 +1,70 @@
+---
+language: brainfuck
+lang: zh-cn
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["lyuehh", "https://github.com/lyuehh"]
+---
+
+Brainfuck 是一个极小的只有8个指令的图灵完全的编程语言。
+
+```
+除"><+-.,[]"之外的的任何字符都会被忽略 (不包含双引号)。
+
+Brainfuck 包含一个有30,000个单元为0的数组,和
+一个数据指针指向当前的单元。
+
+8个指令如下:
++ : 指针指向的单元的值加1
+- : 指针指向的单元的值减1
+> : 将指针移动到下一个单元(右边的元素)
+< : 将指针移动到上一个单元(左边的元素)
+. : 打印当前单元的内容的ASCII值 (比如 65 = 'A').
+, : 读取一个字符到当前的单元
+[ : 如果当前单元的值是0,则向后调转到对应的]处
+] : 如果当前单元的值不是0,则向前跳转到对应的[处
+
+[ 和 ] 组成了一个while循环。很明显,它们必须配对。
+
+让我们看一些基本的brainfuck 程序。
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+这个程序打印字母'A'。首先,它把 #1 增加到6,使用它来作为循环条件,
+然后,进入循环,将指针移动到 #2 ,将 #2 的值增加到10,然后
+移动回 #1,将单元 #1 的值减1,然后继续。循环共进行了6次。
+
+这时,我们在 #1,它的值为0,#2 的值为60,我们移动到
+#2,将 #2 的内容加上5,然后将 #2 的内容打印出来,65在
+ASCII中表示'A', 所以'A'就会被打印出来。
+
+
+, [ > + < - ] > .
+
+这个程序从用户的输入中读取一个字符,然后把它复制到 #1。
+然后我们开始一个循环,移动到 #2,将 #2 的值加1,再移动回 #1,将 #1
+的值减1,直到 #1的值为0,这样 #2 里就保存了 #1 的旧值,循环结束时我们
+在 #1,这时我们移动到 #2,然后把字符以ASCII打印出来。
+
+而且要记住的一点就是,空格在这里只是为了可读性,你可以将他们写成这样:
+
+,[>+<-]>.
+
+试着思考一下这段程序是干什么的:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+这段程序从输入接收2个参数,然后将他们相乘。
+
+先读取2个输入,然后开始外层循环,以 #1 作为终止条件,然后将指针移动到
+#2,然后开始 #2 的内层循环,将 #3 加1。但是这里有一个小问题,在内层
+循环结束的时候,#2 的值是0了,那么下次执行外层循环的时候,就有问题了。
+为了解决这个问题,我们可以增加 #4 的值,然后把 #4 的值复制到 #2,
+最后结果就保存在 #3 中了。
+```
+好了这就是brainfuck了。也没那么难,是吧?为了好玩,你可以写你自己的
+brainfuck程序,或者用其他语言写一个brainfuck的解释器,解释器非常容易
+实现,但是如果你是一个自虐狂的话,你可以尝试用brainfuck写一个brainfuk的
+解释器。
diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown
index b4bff8fc..223f6e35 100755..100644
--- a/zh-cn/c-cn.html.markdown
+++ b/zh-cn/c-cn.html.markdown
@@ -5,37 +5,52 @@ contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Chenbo Li", "http://binarythink.net/"]
+ - ["Jakukyo Friel", "http://weakish.github.io"]
lang: zh-cn
---
C语言在今天仍然是高性能计算的主要选择。
-C大概是大多数程序员用到的最接近底层的语言了,但是C语言本身不仅可以用来提升程序运行的速度
-注意看看C语言的文档,你就会知道C语言在内存管理方面的强大也是其他语言无法比拟的。
+C大概是大多数程序员用到的最接近底层的语言了,C语言原生的速度就很高了,但是别忘了C的手动内存管理,它会让你将性能发挥到极致。
```c
-// 用“//”来实现单行注释
+// 单行注释以//开始。(仅适用于C99或更新的版本。)
/*
-多行注释是这个样子的
+多行注释是这个样子的。(C89也适用。)
*/
+// 常数: #define 关键词
+#define DAYS_IN_YEAR 365
+
+// 以枚举的方式定义常数
+enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
+// MON自动被定义为2,TUE被定义为3,以此类推。
+
// 用#include来导入头文件
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-// 函数的标签(signature)应该放在.h文件中,并且引入到程序顶部
-// 也可以直接放到你的.c文件的最上面
-void function_1();
-void function_2();
+// <尖括号>间的文件名是C标准库的头文件。
+// 标准库以外的头文件,使用双引号代替尖括号。
+#include "my_header.h"
+
+// 函数的签名可以事先在.h文件中定义,
+// 也可以直接在.c文件的头部定义。
+void function_1(char c);
+void function_2(void);
-// c程序的入口是一个返回值为int型的函数,名字叫做main
+// 如果函数出现在main()之后,那么必须在main()之前
+// 先声明一个函数原型
+int add_two_ints(int x1, int x2); // 函数原型
+
+// 你的程序的入口是一个返回值为整型的main函数
int main() {
-// 用printf来实现标准输出,这种输出也可以用格式来控制
-// %d 代表一个整数, \n 代表一个新行
-printf("%d\n", 0); // => 输出 0
+// 用printf打印到标准输出,可以设定格式,
+// %d 代表整数, \n 代表换行
+printf("%d\n", 0); // => 打印 0
// 所有的语句都要以分号结束
///////////////////////////////////////
@@ -69,18 +84,29 @@ double x_double = 0.0;
// 整数类型也可以有无符号的类型表示。这样这些变量就无法表示负数
// 但是无符号整数所能表示的范围就可以比原来的整数大一些
-unsigned char ux_char;
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;
+// 单引号内的字符是机器的字符集中的整数。
+'0' // => 在ASCII字符集中是48
+'A' // => 在ASCII字符集中是65
+
// char类型一定会占用1个字节,但是其他的类型却会因具体机器的不同而各异
// sizeof(T) 可以返回T类型在运行的机器上占用多少个字节
// 这样你的代码就可以在各处正确运行了
-// 比如
-printf("%lu\n", sizeof(int)); // => 4 (字长为4的机器上)
-
-// 数组必须要在开始被初始化为特定的长度
+// sizeof(obj)返回表达式(变量、字面量等)的尺寸
+printf("%zu\n", sizeof(int)); // => 4 (大多数的机器字长为4)
+
+// 如果`sizeof`的参数是一个表达式,那么这个参数不会被演算(VLA例外,见下)
+// 它产生的值是编译期的常数
+int a = 1;
+// size_t是一个无符号整型,表示对象的尺寸,至少2个字节
+size_t size = sizeof(a++); // a++ 不会被演算
+printf("sizeof(a++) = %zu where a = %d\n", size, a);
+// 打印 "sizeof(a++) = 4 where a = 1" (在32位架构上)
+
+// 数组必须要被初始化为具体的长度
char my_char_array[20]; // 这个数组占据 1 * 20 = 20 个字节
int my_int_array[20]; // 这个数组占据 4 * 20 = 80 个字节
// (这里我们假设字长为4)
@@ -89,48 +115,83 @@ int my_int_array[20]; // 这个数组占据 4 * 20 = 80 个字节
// 可以用下面的方法把数组初始化为0:
char my_array[20] = {0};
-// 对数组任意存取就像其他语言的方式 -- 其实是其他的语言像C
+// 索引数组和其他语言类似 -- 好吧,其实是其他的语言像C
my_array[0]; // => 0
// 数组是可变的,其实就是内存的映射!
my_array[1] = 2;
printf("%d\n", my_array[1]); // => 2
+// 在C99 (C11中是可选特性),变长数组(VLA)也可以声明长度。
+// 其长度不用是编译期常量。
+printf("Enter the array size: "); // 询问用户数组长度
+char buf[0x100];
+fgets(buf, sizeof buf, stdin);
+
+// stroul 将字符串解析为无符号整数
+size_t size = strtoul(buf, NULL, 10);
+int var_length_array[size]; // 声明VLA
+printf("sizeof array = %zu\n", sizeof var_length_array);
+
+// 上述程序可能的输出为:
+// > Enter the array size: 10
+// > sizeof array = 40
+
// 字符串就是以 NUL (0x00) 这个字符结尾的字符数组,
-// 这个字符可以用'\0'来表示.
-// (在字符串字面值中我们不必输入这个字符,编译器会自动添加的)
+// NUL可以用'\0'来表示.
+// (在字符串字面量中我们不必输入这个字符,编译器会自动添加的)
char a_string[20] = "This is a string";
printf("%s\n", a_string); // %s 可以对字符串进行格式化
-
/*
也许你会注意到 a_string 实际上只有16个字节长.
第17个字节是一个空字符(NUL)
-而第18, 19 和 20 个字符的值是不确定的。
+而第18, 19 和 20 个字符的值是未定义。
*/
printf("%d\n", a_string[16]); // => 0
+// byte #17值为0(18,19,20同样为0)
+
+// 单引号间的字符是字符字面量
+// 它的类型是`int`,而 *不是* `char`
+// (由于历史原因)
+int cha = 'a'; // 合法
+char chb = 'a'; // 同样合法 (隐式类型转换
+
+// 多维数组
+int multi_array[2][5] = {
+ {1, 2, 3, 4, 5},
+ {6, 7, 8, 9, 0}
+ }
+// 获取元素
+int array_int = multi_array[0][2]; // => 3
///////////////////////////////////////
// 操作符
///////////////////////////////////////
-int i1 = 1, i2 = 2; // 多个变量声明的简写
+// 多个变量声明的简写
+int i1 = 1, i2 = 2;
float f1 = 1.0, f2 = 2.0;
-// 算数运算
+int a, b, c;
+a = b = c = 0;
+
+// 算数运算直截了当
i1 + i2; // => 3
i2 - i1; // => 1
i2 * i1; // => 2
-i1 / i2; // => 0 (0.5 会被化整为 0)
+i1 / i2; // => 0 (0.5,但会被化整为 0)
f1 / f2; // => 0.5, 也许会有很小的误差
+// 浮点数和浮点数运算都是近似值
// 取余运算
11 % 3; // => 2
-// 比较操作符我们也很熟悉, 但是有一点,C中没有布尔类型
+// 你多半会觉得比较操作符很熟悉, 不过C中没有布尔类型
// 而是用整形替代
-// 0 就是 false, 其他的就是 true. (比较操作符的返回值则仅有0和1)
+// (C99中有_Bool或bool。)
+// 0为假, 其他均为真. (比较操作符的返回值总是返回0或1)
3 == 2; // => 0 (false)
3 != 2; // => 1 (true)
3 > 2; // => 1
@@ -138,7 +199,14 @@ f1 / f2; // => 0.5, 也许会有很小的误差
2 <= 2; // => 1
2 >= 2; // => 1
-// 逻辑运算符需要作用于整数
+// C不是Python —— 连续比较不合法
+int a = 1;
+// 错误
+int between_0_and_2 = 0 < a < 2;
+// 正确
+int between_0_and_2 = 0 < a && a < 2;
+
+// 逻辑运算符适用于整数
!3; // => 0 (非)
!0; // => 1
1 && 1; // => 1 (且)
@@ -146,6 +214,20 @@ f1 / f2; // => 0.5, 也许会有很小的误差
0 || 1; // => 1 (或)
0 || 0; // => 0
+// 条件表达式 ( ? : )
+int a = 5;
+int b = 10;
+int z;
+z = (a > b) ? a : b; // 10 “若a > b返回a,否则返回b。”
+
+// 增、减
+char *s = "iLoveC"
+int j = 0;
+s[j++]; // "i" 返回s的第j项,然后增加j的值。
+j = 0;
+s[++j]; // => "L" 增加j的值,然后返回s的第j项。
+// j-- 和 --j 同理
+
// 位运算
~0x0F; // => 0xF0 (取反)
0x0F & 0xF0; // => 0x00 (和)
@@ -154,6 +236,13 @@ f1 / f2; // => 0.5, 也许会有很小的误差
0x01 << 1; // => 0x02 (左移1位)
0x02 >> 1; // => 0x01 (右移1位)
+// 对有符号整数进行移位操作要小心 —— 以下未定义:
+// 有符号整数位移至符号位 int a = 1 << 32
+// 左移位一个负数 int a = -1 << 2
+// 移位超过或等于该类型数值的长度
+// int a = 1 << 32; // 假定int32位
+
+
///////////////////////////////////////
// 控制结构
///////////////////////////////////////
@@ -168,17 +257,17 @@ if (0) {
// While循环
int ii = 0;
-while (ii < 10) {
+while (ii < 10) { // 任何非0的值均为真
printf("%d, ", ii++); // ii++ 在取值过后自增
-} // => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+} // => 打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
printf("\n");
int kk = 0;
do {
printf("%d, ", kk);
-} while (++kk < 10); // ++kk 先自增,在被取值
-// => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+} while (++kk < 10); // ++kk 先自增,再被取值
+// => 打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
printf("\n");
@@ -186,29 +275,55 @@ printf("\n");
int jj;
for (jj=0; jj < 10; jj++) {
printf("%d, ", jj);
-} // => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+} // => 打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
printf("\n");
+// *****注意*****:
+// 循环和函数必须有主体部分,如果不需要主体部分:
+int i;
+ for (i = 0; i <= 5; i++) {
+ ; // 使用分号表达主体(null语句)
+}
+
+// 多重分支:switch()
+switch (some_integral_expression) {
+case 0: // 标签必须是整数常量表达式
+ do_stuff();
+ break; // 如果不使用break,控制结构会继续执行下面的标签
+case 1:
+ do_something_else();
+ break;
+default:
+ // 假设 `some_integral_expression` 不匹配任何标签
+ fputs("error!\n", stderr);
+ exit(-1);
+ break;
+ }
+
///////////////////////////////////////
// 类型转换
///////////////////////////////////////
// 在C中每个变量都有类型,你可以将变量的类型进行转换
+// (有一定限制)
-int x_hex = 0x01; // 可以用16进制赋值
+int x_hex = 0x01; // 可以用16进制字面量赋值
// 在类型转换时,数字本身的值会被保留下来
-printf("%d\n", x_hex); // => 输出 1
-printf("%d\n", (short) x_hex); // => 输出 1
-printf("%d\n", (char) x_hex); // => 输出 1
+printf("%d\n", x_hex); // => 打印 1
+printf("%d\n", (short) x_hex); // => 打印 1
+printf("%d\n", (char) x_hex); // => 打印 1
// 类型转换时可能会造成溢出,而且不会抛出警告
-printf("%d\n", (char) 257); // => 1 (char的最大值为255)
+printf("%d\n", (char) 257); // => 1 (char的最大值为255,假定char为8位长)
+
+// 使用<limits.h>提供的CHAR_MAX、SCHAR_MAX和UCHAR_MAX宏可以确定`char`、`signed_char`和`unisigned char`的最大值。
+
// 整数型和浮点型可以互相转换
-printf("%f\n", (float)100); // %f 表示单精度浮点
-printf("%lf\n", (double)100); // %lf 表示双精度浮点
+printf("%f\n", (float)100); // %f 格式化单精度浮点
+printf("%lf\n", (double)100); // %lf 格式化双精度浮点
printf("%d\n", (char)100.0);
///////////////////////////////////////
@@ -216,67 +331,89 @@ printf("%d\n", (char)100.0);
///////////////////////////////////////
// 指针变量是用来储存内存地址的变量
-// 指针变量的定义也会告诉你指向的地址的变量的类型
-// 你也可以得到某个变量的地址,并对它们进行操作
+// 指针变量的声明也会告诉它所指向的数据的类型
+// 你可以使用得到你的变量的地址,并把它们搞乱,;-)
int x = 0;
printf("%p\n", &x); // 用 & 来获取变量的地址
-// (%p 表示一个指针)
-// => 输出某个内存地址
+// (%p 格式化一个类型为 void *的指针)
+// => 打印某个内存地址
-// 指针类型在定义是需要以*结束
-int* px; // px是一个指向int型的指针
+// 指针类型在声明中以*开头
+int* px, not_a_pointer; // px是一个指向int型的指针
px = &x; // 把x的地址保存到px中
-printf("%p\n", px); // => 输出内存中的某个地址
+printf("%p\n", (void *)px); // => 输出内存中的某个地址
+printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
+// => 在64位系统上打印“8, 4”。
-// 要得到某个指针指向的内容的值,可以在指针前加一个*来取得(去引用)
+// 要得到某个指针指向的内容的值,可以在指针前加一个*来取得(取消引用)
+// 注意: 是的,这可能让人困惑,'*'在用来声明一个指针的同时取消引用它。
printf("%d\n", *px); // => 输出 0, 即x的值
// 你也可以改变指针所指向的值
-// 此时你需要在*运算符后添加一个括号,因为++比*的优先级更高
-(*px)++; // 把px所指向的值增加2
+// 此时你需要取消引用上添加括号,因为++比*的优先级更高
+(*px)++; // 把px所指向的值增加1
printf("%d\n", *px); // => 输出 1
printf("%d\n", x); // => 输出 1
-int x_array[20]; // 数组是分配一系列连续空间的常用方式
+// 数组是分配一系列连续空间的常用方式
+int x_array[20];
int xx;
for (xx=0; xx<20; xx++) {
x_array[xx] = 20 - xx;
} // 初始化 x_array 为 20, 19, 18,... 2, 1
-// 生命一个变量为指向整型的指针类型,并初始化为指向x_array
+// 声明一个整型的指针,并初始化为指向x_array
int* x_ptr = x_array;
// x_ptr现在指向了数组的第一个元素(即整数20).
-
-// 事实上数组本身就是指向它的第一个元素的指针
-printf("%d\n", *(x_ptr)); // => 输出 20
-printf("%d\n", x_array[0]); // => 输出 20
+// 这是因为数组通常衰减为指向它们的第一个元素的指针。
+// 例如,当一个数组被传递给一个函数或者绑定到一个指针时,
+//它衰减为(隐式转化为)一个指针。
+// 例外: 当数组是`&`操作符的参数:
+int arr[10];
+int (*ptr_to_arr)[10] = &arr; // &arr的类型不是`int *`!
+ // 它的类型是指向数组的指针(数组由10个int组成)
+// 或者当数组是字符串字面量(初始化字符数组)
+char arr[] = "foobarbazquirk";
+// 或者当它是`sizeof`或`alignof`操作符的参数时:
+int arr[10];
+int *ptr = arr; // 等价于 int *ptr = &arr[0];
+printf("%zu, %zu\n", sizeof arr, sizeof ptr); // 应该会输出"40, 4"或"40, 8"
// 指针的增减多少是依据它本身的类型而定的
-printf("%d\n", *(x_ptr + 1)); // => 输出 19
-printf("%d\n", x_array[1]); // => 输出 19
+// (这被称为指针算术)
+printf("%d\n", *(x_ptr + 1)); // => 打印 19
+printf("%d\n", x_array[1]); // => 打印 19
// 你也可以通过标准库函数malloc来实现动态分配
-// 这个函数接受一个代表容量的参数
-// 系统会从堆区分配指定容量字节大小的空间
-int* my_ptr = (int*) malloc(sizeof(int) * 20);
+// 这个函数接受一个代表容量的参数,参数类型为`size_t`
+// 系统一般会从堆区分配指定容量字节大小的空间
+// (在一些系统,例如嵌入式系统中这点不一定成立
+// C标准对此未置一词。)
+int *my_ptr = malloc(sizeof(*my_ptr) * 20);
for (xx=0; xx<20; xx++) {
- *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx 也可以
-} // 初始化内存为 20, 19, 18, 17... 2, 1 (as ints)
+ *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
+} // 初始化内存为 20, 19, 18, 17... 2, 1 (类型为int)
-// 如果对一些未分配的内存取值则会得到未知的结果
+// 对未分配的内存进行取消引用会产生未定义的结果
printf("%d\n", *(my_ptr + 21)); // => 谁知道会输出什么
-// 当你通过malloc得到一块区域后,你需要释放它
+// malloc分配的区域需要手动释放
// 否则没人能够再次使用这块内存,直到程序结束为止
free(my_ptr);
// 字符串通常是字符数组,但是经常用字符指针表示
-// 指针:
-char* my_str = "This is my very own string";
-
+// (它是指向数组的第一个元素的指针)
+// 一个优良的实践是使用`const char *`来引用一个字符串字面量,
+// 因为字符串字面量不应当被修改(即"foo"[0] = 'a'犯了大忌)
+const char* my_str = "This is my very own string";
printf("%c\n", *my_str); // => 'T'
+// 如果字符串是数组,(多半是用字符串字面量初始化的)
+// 情况就不一样了,字符串位于可写的内存中
+char foo[] = "foo";
+foo[0] = 'a'; // 这是合法的,foo现在包含"aoo"
+
function_1();
} // main函数结束
@@ -292,16 +429,21 @@ int add_two_ints(int x1, int x2){
}
/*
-函数是按值传递的, 但是你可以通过传递参数来传递引用,这样函数就可以更改值
+函数是按值传递的。当调用一个函数的时候,传递给函数的参数
+是原有值的拷贝(数组除外)。你在函数内对参数所进行的操作
+不会改变该参数原有的值。
+
+但是你可以通过指针来传递引用,这样函数就可以更改值
例子:字符串本身翻转
*/
// 类型为void的函数没有返回值
-void str_reverse(char* str_in){
+void str_reverse(char *str_in){
char tmp;
- int ii=0, len = strlen(str_in); // Strlen 是C标准库函数
- for(ii=0; ii<len/2; ii++){
+ int ii = 0;
+ size_t len = strlen(str_in); // `strlen()`` 是C标准库函数
+ for(ii = 0; ii < len / 2; ii++){
tmp = str_in[ii];
str_in[ii] = str_in[len - ii - 1]; // 从倒数第ii个开始
str_in[len - ii - 1] = tmp;
@@ -314,6 +456,20 @@ str_reverse(c);
printf("%s\n", c); // => ".tset a si sihT"
*/
+// 如果引用函数之外的变量,必须使用extern关键字
+int i = 0;
+void testFunc() {
+ extern int i; // 使用外部变量 i
+}
+
+// 使用static确保external变量为源文件私有
+static int i = 0; // 其他使用 testFunc()的文件无法访问变量i
+void testFunc() {
+ extern int i;
+}
+//**你同样可以声明函数为static**
+
+
///////////////////////////////////////
// 用户自定义类型和结构
///////////////////////////////////////
@@ -322,12 +478,16 @@ printf("%s\n", c); // => ".tset a si sihT"
typedef int my_type;
my_type my_type_var = 0;
-// 结构是一系列数据的集合
+// struct是数据的集合,成员依序分配,按照
+// 编写的顺序
struct rectangle {
int width;
int height;
};
+// 一般而言,以下断言不成立:
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int)
+//这是因为structure成员之间可能存在潜在的间隙(为了对齐)[1]
void function_1(){
@@ -338,12 +498,12 @@ void function_1(){
my_rec.height = 20;
// 你也可以声明指向结构体的指针
- struct rectangle* my_rec_ptr = &my_rec;
+ struct rectangle *my_rec_ptr = &my_rec;
- // 通过取值来改变结构体的成员...
+ // 通过取消引用来改变结构体的成员...
(*my_rec_ptr).width = 30;
- // ... 或者用 -> 操作符作为简写
+ // ... 或者用 -> 操作符作为简写提高可读性
my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10;
}
@@ -354,18 +514,25 @@ int area(rect r){
return r.width * r.height;
}
+// 如果struct较大,你可以通过指针传递,避免
+// 复制整个struct。
+int area(const rect *r)
+{
+ return r->width * r->height;
+}
+
///////////////////////////////////////
// 函数指针
///////////////////////////////////////
/*
在运行时,函数本身也被存放到某块内存区域当中
-函数指针就像其他指针一样, 但却可以被用来直接调用函数,
-并且可以被四处传递(就像回调函数那样)
-但是,定义的语法有可能在一开始会有些误解
+函数指针就像其他指针一样(不过是存储一个内存地址) 但却可以被用来直接调用函数,
+并且可以四处传递回调函数
+但是,定义的语法初看令人有些迷惑
例子:通过指针调用str_reverse
*/
-void str_reverse_through_pointer(char * str_in) {
+void str_reverse_through_pointer(char *str_in) {
// 定义一个函数指针 f.
void (*f)(char *); // 签名一定要与目标函数相同
f = &str_reverse; // 将函数的地址在运行时赋给指针
@@ -374,7 +541,7 @@ void str_reverse_through_pointer(char * str_in) {
}
/*
-只要函数签名是正确的,任何时候都能将正确的函数赋给某个函数指针
+只要函数签名是正确的,任何时候都能将任何函数赋给某个函数指针
为了可读性和简洁性,函数指针经常和typedef搭配使用:
*/
@@ -384,12 +551,73 @@ typedef void (*my_fnp_type)(char *);
// ...
// my_fnp_type f;
+// 特殊字符
+'\a' // bell
+'\n' // 换行
+'\t' // tab
+'\v' // vertical tab
+'\f' // formfeed
+'\r' // 回车
+'\b' // 退格
+'\0' // null,通常置于字符串的最后。
+ // hello\n\0. 按照惯例,\0用于标记字符串的末尾。
+'\\' // 反斜杠
+'\?' // 问号
+'\'' // 单引号
+'\"' // 双引号
+'\xhh' // 十六进制数字. 例子: '\xb' = vertical tab
+'\ooo' // 十进制数字. 例子: '\013' = vertical tab
+
+// 打印格式:
+"%d" // 整数
+"%3d" // 3位以上整数 (右对齐文本)
+"%s" // 字符串
+"%f" // float
+"%ld" // long
+"%3.2f" // 左3位以上、右2位以上十进制浮
+"%7.4s" // (字符串同样适用)
+"%c" // 字母
+"%p" // 指针
+"%x" // 十六进制
+"%o" // 十进制
+"%%" // 打印 %
+
+///////////////////////////////////////
+// 演算优先级
+///////////////////////////////////////
+//---------------------------------------------------//
+// 操作符 | 组合 //
+//---------------------------------------------------//
+// () [] -> . | 从左到右 //
+// ! ~ ++ -- + = *(type)sizeof | 从右到左 //
+// * / % | 从左到右 //
+// + - | 从左到右 //
+// << >> | 从左到右 //
+// < <= > >= | 从左到右 //
+// == != | 从左到右 //
+// & | 从左到右 //
+// ^ | 从左到右 //
+// | | 从左到右 //
+// && | 从左到右 //
+// || | 从左到右 //
+// ?: | 从右到左 //
+// = += -= *= /= %= &= ^= |= <<= >>= | 从右到左 //
+// , | 从左到右 //
+//---------------------------------------------------//
+
```
## 更多阅读
-最好找一本 [K&R, aka "The C Programming Language", “C程序设计语言”](https://en.wikipedia.org/wiki/The_C_Programming_Language)
+最好找一本 [K&R, aka "The C Programming Language", “C程序设计语言”](https://en.wikipedia.org/wiki/The_C_Programming_Language)。它是关于C最重要的一本书,由C的创作者撰写。不过需要留意的是它比较古老了,因此有些不准确的地方。
+
-其他一些比较好的资源 [Learn C the hard way](http://c.learncodethehardway.org/book/)
+另一个比较好的资源是 [Learn C the hard way](http://c.learncodethehardway.org/book/)
+如果你有问题,请阅读[compl.lang.c Frequently Asked Questions](http://c-faq.com/)。
+
+使用合适的空格、缩进,保持一致的代码风格非常重要。可读性强的代码比聪明的代码、高速的代码更重要。可以参考下[Linux内核编码风格](https://www.kernel.org/doc/Documentation/CodingStyle)
+。
除了这些,多多Google吧
+
+[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
diff --git a/zh-cn/clojure-cn.html.markdown b/zh-cn/clojure-cn.html.markdown
new file mode 100644
index 00000000..fa241384
--- /dev/null
+++ b/zh-cn/clojure-cn.html.markdown
@@ -0,0 +1,368 @@
+---
+language: clojure
+filename: learnclojure-cn.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["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/clojure-macro-cn.html.markdown b/zh-cn/clojure-macro-cn.html.markdown
new file mode 100644
index 00000000..9324841e
--- /dev/null
+++ b/zh-cn/clojure-macro-cn.html.markdown
@@ -0,0 +1,152 @@
+---
+language: "clojure macros"
+filename: learnclojuremacros-zh.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Jakukyo Friel", "http://weakish.github.io"]
+lang: zh-cn
+---
+
+和所有Lisp一样,Clojure内在的[同构性](https://en.wikipedia.org/wiki/Homoiconic)使得你可以穷尽语言的特性,编写生成代码的子过程——“宏”。宏是一种按需调制语言的强大方式。
+
+小心!可以用函数完成的事用宏去实现可不是什么好事。你应该仅在需要控制参数是否或者何时eval的时候使用宏。
+
+你应该熟悉Clojure.确保你了解[Y分钟学Clojure](http://learnxinyminutes.com/docs/zh-cn/clojure-cn/)中的所有内容。
+
+```clojure
+;; 使用defmacro定义宏。宏应该输出一个可以作为clojure代码演算的列表。
+;;
+;; 以下宏的效果和直接写(reverse "Hello World")一致。
+
+(defmacro my-first-macro []
+ (list reverse "Hello World"))
+
+;; 使用macroexpand或macroexpand-1查看宏的结果。
+;;
+;; 注意,调用需要引用。
+(macroexpand '(my-first-macro))
+;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World")
+
+;; 你可以直接eval macroexpand的结果
+(eval (macroexpand '(my-first-macro)))
+; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; 不过一般使用以下形式,更简短,更像函数:
+(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; 创建宏的时候可以使用更简短的引用形式来创建列表
+(defmacro my-first-quoted-macro []
+ '(reverse "Hello World"))
+
+(macroexpand '(my-first-quoted-macro))
+;; -> (reverse "Hello World")
+;; 注意reverse不再是一个函数对象,而是一个符号。
+
+;; 宏可以传入参数。
+(defmacro inc2 [arg]
+ (list + 2 arg))
+
+(inc2 2) ; -> 4
+
+;; 不过,如果你尝试配合使用引用列表,会导致错误,
+;; 因为参数也会被引用。
+;; 为了避免这个问题,clojure提供了引用宏的另一种方式:`
+;; 在`之内,你可以使用~获得外圈作用域的变量。
+(defmacro inc2-quoted [arg]
+ `(+ 2 ~arg))
+
+(inc2-quoted 2)
+
+;; 你可以使用通常的析构参数。用~@展开列表中的变量。
+(defmacro unless [arg & body]
+ `(if (not ~arg)
+ (do ~@body))) ; 别忘了 do!
+
+(macroexpand '(unless true (reverse "Hello World")))
+
+;; ->
+;; (if (clojure.core/not true) (do (reverse "Hello World")))
+
+;; 当第一个参数为假时,(unless)会演算、返回主体。
+;; 否则返回nil。
+
+(unless true "Hello") ; -> nil
+(unless false "Hello") ; -> "Hello"
+
+;; 需要小心,宏会搞乱你的变量
+(defmacro define-x []
+ '(do
+ (def x 2)
+ (list x)))
+
+(def x 4)
+(define-x) ; -> (2)
+(list x) ; -> (2)
+
+;; 使用gensym来获得独有的标识符
+(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)
+
+;; 你可以在 ` 中使用 # 为每个符号自动生成gensym
+(defmacro define-x-hygenically []
+ `(do
+ (def x# 2)
+ (list x#)))
+
+(def x 4)
+(define-x-hygenically) ; -> (2)
+(list x) ; -> (4)
+
+;; 通常会配合宏使用帮助函数。
+;; 让我们创建一些帮助函数来支持(无聊的)算术语法:
+
+(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)))
+
+;; 在创建宏前,我们可以先测试
+(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5))
+
+; 然而,如果我们希望它在编译期执行,就需要创建宏
+(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 (事实上,结果是3N, 因为数字被转化为带/的有理分数)
+```
+
+## 扩展阅读
+
+[Clojure for the Brave and True](http://www.braveclojure.com/)系列的编写宏
+http://www.braveclojure.com/writing-macros/
+
+官方文档
+http://clojure.org/macros
+
+何时使用宏?
+http://dunsmor.com/lisp/onlisp/onlisp_12.html
diff --git a/zh-cn/coffeescript-cn.html.markdown b/zh-cn/coffeescript-cn.html.markdown
new file mode 100644
index 00000000..44561541
--- /dev/null
+++ b/zh-cn/coffeescript-cn.html.markdown
@@ -0,0 +1,101 @@
+---
+language: coffeescript
+contributors:
+ - ["Tenor Biel", "http://github.com/L8D"]
+ - ["Xavier Yao", "http://github.com/xavieryao"]
+translators:
+ - ["Xavier Yao", "http://github.com/xavieryao"]
+filename: coffeescript-cn.coffee
+lang: zh-cn
+---
+
+CoffeeScript是逐句编译为JavaScript的一种小型语言,且没有运行时的解释器。
+作为JavaScript的替代品之一,CoffeeScript旨在编译人类可读、美观优雅且速度不输原生的代码,
+且编译后的代码可以在任何JavaScript运行时正确运行。
+
+参阅 [CoffeeScript官方网站](http://coffeescript.org/)以获取CoffeeScript的完整教程。
+
+``` coffeescript
+# CoffeeScript是一种很潮的编程语言,
+# 它紧随众多现代编程语言的趋势。
+# 因此正如Ruby和Python,CoffeeScript使用井号标记注释。
+
+###
+大段落注释以此为例,可以被直接编译为 '/ *' 和 '* /' 包裹的JavaScript代码。
+
+在继续之前你需要了解JavaScript的基本概念。
+
+示例中 => 后为编译后的JavaScript代码
+###
+
+# 赋值:
+number = 42 #=> var number = 42;
+opposite = true #=> var opposite = true;
+
+# 条件:
+number = -42 if opposite #=> if(opposite) { number = -42; }
+
+# 函数:
+square = (x) -> x * x #=> var square = function(x) { return x * x; }
+
+fill = (container, liquid = "coffee") ->
+ "Filling the #{container} with #{liquid}..."
+#=>var fill;
+#
+#fill = function(container, liquid) {
+# if (liquid == null) {
+# liquid = "coffee";
+# }
+# return "Filling the " + container + " with " + liquid + "...";
+#};
+
+# 区间:
+list = [1..5] #=> var list = [1, 2, 3, 4, 5];
+
+# 对象:
+math =
+ root: Math.sqrt
+ square: square
+ cube: (x) -> x * square x
+#=> var math = {
+# "root": Math.sqrt,
+# "square": square,
+# "cube": function(x) { return x * square(x); }
+#}
+
+# Splats:
+race = (winner, runners...) ->
+ print winner, runners
+#=>race = function() {
+# var runners, winner;
+# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+# return print(winner, runners);
+#};
+
+# 存在判断:
+alert "I knew it!" if elvis?
+#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
+
+# 数组推导:
+cubes = (math.cube num for num in list)
+#=>cubes = (function() {
+# var _i, _len, _results;
+# _results = [];
+# for (_i = 0, _len = list.length; _i < _len; _i++) {
+# num = list[_i];
+# _results.push(math.cube(num));
+# }
+# return _results;
+# })();
+
+foods = ['broccoli', 'spinach', 'chocolate']
+eat food for food in foods when food isnt 'chocolate'
+#=>foods = ['broccoli', 'spinach', 'chocolate'];
+#
+#for (_k = 0, _len2 = foods.length; _k < _len2; _k++) {
+# food = foods[_k];
+# if (food !== 'chocolate') {
+# eat(food);
+# }
+#}
+```
diff --git a/zh-cn/common-lisp-cn.html.markdown b/zh-cn/common-lisp-cn.html.markdown
new file mode 100644
index 00000000..c4dc3274
--- /dev/null
+++ b/zh-cn/common-lisp-cn.html.markdown
@@ -0,0 +1,624 @@
+---
+language: "Common Lisp"
+filename: commonlisp-cn.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+translators:
+ - ["Mac David", "http://macdavid313.com"]
+ - ["mut0u", "http://github.com/mut0u"]
+lang: zh-cn
+---
+
+ANSI Common Lisp 是一个广泛通用于各个工业领域的、支持多种范式的编程语言。
+这门语言也经常被引用作“可编程的编程语言”(可以写代码的代码)。
+
+免费的经典的入门书籍[《实用 Common Lisp 编程》](http://www.gigamonkeys.com/book/)
+
+另外还有一本热门的近期出版的
+[Land of Lisp](http://landoflisp.com/).
+
+```scheme
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 0. 语法
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; 一般形式
+
+;; Lisp有两个基本的语法单元:原子(atom),以及S-表达式。
+;; 一般的,一组S-表达式被称为“组合式”。
+
+10 ; 一个原子; 它对自身进行求值
+
+:THING ;同样是一个原子;它被求值为一个符号 :thing
+
+t ;还是一个原子,代表逻辑真值。
+
+(+ 1 2 3 4) ; 一个S-表达式。
+
+'(4 :foo t) ;同样是一个S-表达式。
+
+
+;;; 注释
+
+;; 一个分号开头的注释表示仅用于此行(单行);两个分号开头的则表示一个所谓标准注释;
+;; 三个分号开头的意味着段落注释;
+;; 而四个分号开头的注释用于文件头注释(译者注:即对该文件的说明)。
+
+#| 块注释
+ 可以涵盖多行,而且...
+ #|
+ 他们可以被嵌套!
+ |#
+|#
+
+;;; 运行环境
+
+;; 有很多不同的Common Lisp的实现;并且大部分的实现是一致(可移植)的。
+;; 对于入门学习来说,CLISP是个不错的选择。
+
+;; 可以通过QuickLisp.org的Quicklisp系统管理你的库。
+
+;; 通常,使用文本编辑器和“REPL”来开发Common Lisp;
+;; (译者注:“REPL”指读取-求值-打印循环)。
+;; “REPL”允许对程序进行交互式的运行、调试,就好像在系统“现场”操作。
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 1. 基本数据类型以及运算符
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; 符号
+
+'foo ; => FOO 注意到这个符号被自动转换成大写了。
+
+;; `intern`由一个给定的字符串而创建相应的符号
+
+(intern "AAAA") ; => AAAA
+
+(intern "aaa") ; => |aaa|
+
+;;; 数字
+9999999999999999999999 ; 整型数
+#b111 ; 二进制 => 7
+#o111 ; 八进制 => 73
+#x111 ; 十六进制 => 273
+3.14159s0 ; 单精度
+3.14159d0 ; 双精度
+1/2 ; 分数
+#C(1 2) ; 复数
+
+
+;; 使用函数时,应当写成这样的形式:(f x y z ...);
+;; 其中,f是一个函数(名),x, y, z为参数;
+;; 如果你想创建一个“字面”意义上(即不求值)的列表, 只需使用单引号 ' ,
+;; 从而避免接下来的表达式被求值。即,只“引用”这个数据(而不求值)。
+'(+ 1 2) ; => (+ 1 2)
+;; 你同样也可以手动地调用一个函数(译者注:即使用函数对象来调用函数):
+(funcall #'+ 1 2 3) ; => 6
+;; 一些算术运算符
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+ ;;; 布尔运算
+t ; 逻辑真(任何不是nil的值都被视为真值)
+nil ; 逻辑假,或者空列表
+(not nil) ; => t
+(and 0 t) ; => t
+(or 0 nil) ; => 0
+
+ ;;; 字符
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA(希腊字母Lambda的小写)
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA(Unicode形式的小写希腊字母Lambda)
+
+;;; 字符串被视为一个定长字符数组
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ;反斜杠用作转义字符
+
+;; 可以拼接字符串
+(concatenate 'string "Hello " "world!") ; => "Hello world!"
+
+;; 一个字符串也可被视作一个字符序列
+(elt "Apple" 0) ; => #\A
+
+;; `format`被用于格式化字符串
+(format nil "~a can be ~a" "strings" "formatted")
+
+;; 利用`format`打印到屏幕上是非常简单的
+;;(译者注:注意到第二个参数是t,不同于刚刚的nil);~% 代表换行符
+(format t "Common Lisp is groovy. Dude.~%")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. 变量
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 你可以通过`defparameter`创建一个全局(动态)变量
+;; 变量名可以是除了:()[]{}",'`;#|\ 这些字符之外的其他任何字符
+
+;; 动态变量名应该由*号开头与结尾!
+;; (译者注:这个只是一个习惯)
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;; 你也可以使用Unicode字符:
+(defparameter *AΛB* nil)
+
+
+;; 访问一个在之前从未被绑定的变量是一种不规范的行为(即使依然是可能发生的);
+;; 不要尝试那样做。
+
+
+;; 局部绑定:在(let ...)语句内,'me'被绑定到"dance with you"上。
+;; `let`总是返回在其作用域内最后一个表达式的值
+
+(let ((me "dance with you"))
+ me)
+;; => "dance with you"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. 结构体和集合
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 结构体
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+
+(dog-p *rover*) ; => t ;; ewww)
+(dog-name *rover*) ; => "rover"
+
+;; Dog-p,make-dog,以及 dog-name都是由defstruct创建的!
+
+;;; 点对单元(Pairs)
+;; `cons`可用于生成一个点对单元, 利用`car`以及`cdr`将分别得到第一个和第二个元素
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+;;; 列表
+
+;; 所有列表都是由点对单元构成的“链表”。它以'nil'(或者'())作为列表的最后一个元素。
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+;; `list`是一个生成列表的便利途径
+(list 1 2 3) ; => '(1 2 3)
+;; 并且,一个引用也可被用做字面意义上的列表值
+'(1 2 3) ; => '(1 2 3)
+
+;; 同样的,依然可以用`cons`来添加一项到列表的起始位置
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; 而`append`也可用于连接两个列表
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; 或者使用`concatenate`
+
+(concatenate 'list '(1 2) '(3 4))
+
+;; 列表是一种非常核心的数据类型,所以有非常多的处理列表的函数
+;; 例如:
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => nil
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; 向量
+
+;; 向量的字面意义是一个定长数组
+;;(译者注:此处所谓“字面意义”,即指#(......)的形式,下文还会出现)
+#(1 2 3) ; => #(1 2 3)
+
+;; 使用`concatenate`来将两个向量首尾连接在一起
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; 数组
+
+;; 向量和字符串只不过是数组的特例
+
+;; 二维数组
+
+(make-array (list 2 2))
+
+;; (make-array '(2 2)) 也是可以的
+
+; => #2A((0 0) (0 0))
+
+(make-array (list 2 2 2))
+
+; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;; 注意:数组的默认初始值是可以指定的
+;; 下面是如何指定的示例:
+
+(make-array '(2) :initial-element 'unset)
+
+; => #(UNSET UNSET)
+
+;; 若想获取数组[1][1][1]上的元素:
+(aref (make-array (list 2 2 2)) 1 1 1)
+
+; => 0
+
+;;; 变长向量
+
+;; 若将变长向量打印出来,那么它的字面意义上的值和定长向量的是一样的
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+
+*adjvec* ; => #(1 2 3)
+
+;; 添加新的元素:
+(vector-push-extend 4 *adjvec*) ; => 3
+
+*adjvec* ; => #(1 2 3 4)
+
+
+
+;;; 不怎么严谨地说,集合也可被视为列表
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;; 然而,你可能想使用一个更好的数据结构,而并非一个链表
+
+;;; 在Common Lisp中,“字典”和哈希表的实现是一样的。
+
+;; 创建一个哈希表
+(defparameter *m* (make-hash-table))
+
+;; 给定键,设置对应的值
+(setf (gethash 'a *m*) 1)
+
+;; (通过键)检索对应的值
+(gethash 'a *m*) ; => 1, t
+
+;; 注意此处有一细节:Common Lisp往往返回多个值。`gethash`返回的两个值是t,代表找到了这个元素;返回nil表示没有找到这个元素。
+;;(译者注:返回的第一个值表示给定的键所对应的值或者nil;)
+;;(第二个是一个布尔值,表示在哈希表中是否存在这个给定的键)
+;; 例如,如果可以找到给定的键所对应的值,则返回一个t,否则返回nil
+
+;; 由给定的键检索一个不存在的值,则返回nil
+;;(译者注:这个nil是第一个nil,第二个nil其实是指该键在哈希表中也不存在)
+ (gethash 'd *m*) ;=> nil, nil
+
+;; 给定一个键,你可以指定其对应的默认值:
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;; 在此,让我们看一看怎样处理`gethash`的多个返回值。
+
+(multiple-value-bind
+ (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind
+ (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. 函数
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 使用`lambda`来创建一个匿名函数。
+;; 一个函数总是返回其形式体内最后一个表达式的值。
+;; 将一个函数对象打印出来后的形式是多种多样的...
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;; 使用`funcall`来调用lambda函数
+(funcall (lambda () "Hello World")) ; => "Hello World"
+
+;; 或者使用`apply`
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;; 显式地定义一个函数(译者注:即非匿名的)
+(defun hello-world ()
+ "Hello World")
+(hello-world) ; => "Hello World"
+
+;; 刚刚上面函数名"hello-world"后的()其实是函数的参数列表
+(defun hello (name)
+ (format nil "Hello, ~a " name))
+
+(hello "Steve") ; => "Hello, Steve"
+
+;; 函数可以有可选形参并且其默认值都为nil
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~a, from ~a" name from)
+ (format t "Hello, ~a" name)))
+
+ (hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas
+
+;; 你也可以指定那些可选形参的默认值
+(defun hello (name &optional (from "The world"))
+ (format t "Hello, ~a, from ~a" name from))
+
+(hello "Steve")
+; => Hello, Steve, from The world
+
+(hello "Steve" "the alpacas")
+; => Hello, Steve, from the alpacas
+
+
+;; 当然,你也可以设置所谓关键字形参;
+;; 关键字形参往往比可选形参更具灵活性。
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~a ~a, from ~a" honorific name from))
+
+(generalized-greeter "Jim") ; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. 等式
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Common Lisp具有一个十分复杂的用于判断等价的系统,下面只是其中一部分的例子
+
+;; 若要比较数值是否等价,使用`=`
+(= 3 3.0) ; => t
+(= 2 1) ; => nil
+
+;; 若要比较对象的类型,则使用`eql`
+;;(译者注:抱歉,翻译水平实在有限,下面是我个人的补充说明)
+;;(`eq` 返回真,如果对象的内存地址相等)
+;;(`eql` 返回真,如果两个对象内存地址相等,或者对象的类型相同,并且值相等)
+;;(例如同为整形数或浮点数,并且他们的值相等时,二者`eql`等价)
+;;(想要弄清`eql`,其实有必要先了解`eq`)
+;;([可以参考](http://stackoverflow.com/questions/547436/whats-the-difference-between-eq-eql-equal-and-equalp-in-common-lisp))
+;;(可以去CLHS上分别查看两者的文档)
+;;(另外,《实用Common Lisp编程》的4.8节也提到了两者的区别)
+(eql 3 3) ; => t
+(eql 3 3.0) ; => nil
+(eql (list 3) (list 3)) ; => nil
+
+;; 对于列表、字符串、以及位向量,使用`equal`
+(equal (list 'a 'b) (list 'a 'b)) ; => t
+(equal (list 'a 'b) (list 'b 'a)) ; => nil
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. 控制流
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; 条件判断语句
+
+(if t ; “test”,即判断语句
+ "this is true" ; “then”,即判断条件为真时求值的表达式
+ "this is false") ; “else”,即判断条件为假时求值的表达式
+; => "this is true"
+
+;; 在“test”(判断)语句中,所有非nil或者非()的值都被视为真值
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;; `cond`将一系列测试语句串联起来,并对相应的表达式求值
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;; 对于给定值的数据类型,`typecase`会做出相应地判断
+(typecase 1
+ (string :string)
+ (integer :int))
+
+; => :int
+
+;;; 迭代
+
+;; 当然,递归是肯定被支持的:
+
+(defun walker (n)
+ (if (zerop n)
+ :walked
+ (walker (1- n))))
+
+(walker) ; => :walked
+
+;; 而大部分场合下,我们使用`DOLIST`或者`LOOP`来进行迭代
+
+
+(dolist (i '(1 2 3 4))
+ (format t "~a" i))
+
+; => 1234
+
+(loop for i from 0 below 10
+ collect i)
+
+; => (0 1 2 3 4 5 6 7 8 9)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. 可变性
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 使用`setf`可以对一个已经存在的变量进行赋值;
+;; 事实上,刚刚在哈希表的例子中我们已经示范过了。
+
+(let ((variable 10))
+ (setf variable 2))
+ ; => 2
+
+
+;; 所谓好的Lisp编码风格就是为了减少使用破坏性函数,防止发生副作用。
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. 类与对象
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 我们就不写什么有关动物的类了,下面给出的人力车的类
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;; `defclass`,后面接类名,以及超类列表
+;; 再接着是槽的列表(槽有点像Java里的成员变量),最后是一些可选的特性
+;; 例如文档说明“:documentation”
+
+;; 如果超类列表为空,则默认该类继承于“standard-object”类(standard-object又是T的子类)
+;; 这种默认行为是可以改变的,但你最好有一定的基础并且知道自己到底在干什么;
+;; 参阅《The Art of the Metaobject Protocol》来了解更多信息。
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+
+;; 在REPL中对human-powered-conveyance类调用`DESCRIBE`后结果如下:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;; 注意到这些有用的返回信息——Common Lisp一直是一个交互式的系统。
+
+;; 若要定义一个方法;
+;; 注意,我们计算自行车轮子周长时使用了这样一个公式:C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;; pi在Common Lisp中已经是一个内置的常量。
+
+;; 假设我们已经知道了效率值(“efficiency value”)和船桨数大概呈对数关系;
+;; 那么效率值的定义应当在构造器/初始化过程中就被完成。
+
+;; 下面是一个Common Lisp构造实例时初始化实例的例子:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;; 接着初构造一个实例并检查平均效率...
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. 宏
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 宏可以让你扩展语法
+
+;; 例如,Common Lisp并没有自带WHILE循环——所以让我们自己来为他添加一个;
+;; 如果按照汇编程序的直觉来看,我们会这样写:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)))
+ `(tagbody
+ (unless ,condition
+ (go ,block-name))
+ (progn
+ ,@body)
+ ,block-name)))
+
+;; 让我们来看看它的高级版本:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;; 然而,在一个比较现代化的编译环境下,这样的WHILE是没有必要的;
+;; LOOP形式的循环和这个WHILE同样的好,并且更易于阅读。
+
+;; 注意反引号'`',逗号','以及'@'这三个符号;
+;; 反引号'`'是一种所谓“quasiquote”的引用类型的运算符,有了它,之后的逗号“,”才有意义。
+;; 逗号“,”意味着解除引用(unquote,即开始求值);
+;; “@”符号则表示将当前的参数插入到当前整个列表中。
+;;(译者注:要想真正用好、用对这三个符号,需要下一番功夫)
+;;(甚至光看《实用 Common Lisp 编程》中关于宏的介绍都是不够的)
+;;(建议再去读一读Paul Graham的两本著作《ANSI Common Lisp》和《On Lisp》)
+
+;; 函数`gensym`创建一个唯一的符号——这个符号确保不会出现在其他任何地方。
+;; 这样做是因为,宏是在编译期展开的
+;; 而在宏中声明的变量名极有可能和常规代码中使用的变量名发生冲突。
+
+;; 可以去《实用 Common Lisp 编程》中阅读更多有关宏的内容。
+```
+
+
+## 拓展阅读
+
+[继续阅读《实用 Common Lisp 编程》一书](http://www.gigamonkeys.com/book/)
+
+
+## 致谢
+
+非常感谢Scheme社区的人们,我基于他们的成果得以迅速的写出这篇有关Common Lisp的快速入门
+同时也感谢
+- [Paul Khuong](https://github.com/pkhuong) ,他提出了很多有用的点评。
+
+##译者寄语
+“祝福那些将思想镶嵌在重重括号之内的人们。”
diff --git a/zh-cn/csharp-cn.html.markdown b/zh-cn/csharp-cn.html.markdown
new file mode 100644
index 00000000..a3cda5b3
--- /dev/null
+++ b/zh-cn/csharp-cn.html.markdown
@@ -0,0 +1,798 @@
+---
+language: c#
+contributors:
+ - ["Irfan Charania", "https://github.com/irfancharania"]
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Melvyn Laïly", "http://x2a.yt"]
+ - ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
+translators:
+ - ["Jakukyo Friel", "http://weakish.github.io"]
+filename: LearnCSharp-cn.cs
+lang: zh-cn
+---
+
+
+C#是一个优雅的、类型安全的面向对象语言。使用C#,开发者可以在.NET框架下构建安全、健壮的应用程序。
+
+[更多关于C#的介绍](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
+
+```c#
+// 单行注释以 // 开始
+/*
+多行注释是这样的
+*/
+/// <summary>
+/// XML文档注释
+/// </summary>
+
+// 声明应用用到的命名空间
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Net;
+using System.Threading.Tasks;
+using System.IO;
+
+// 定义作用域,将代码组织成包
+namespace Learning
+{
+ // 每个 .cs 文件至少需要包含一个和文件名相同的类
+ // 你可以不这么干,但是这样不好。
+ public class LearnCSharp
+ {
+ // 基本语法 - 如果你以前用过 Java 或 C++ 的话,可以直接跳到后文「有趣的特性」
+ public static void Syntax()
+ {
+ // 使用 Console.WriteLine 打印信息
+ Console.WriteLine("Hello World");
+ Console.WriteLine(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // 使用 Console.Write 打印,不带换行符号
+ Console.Write("Hello ");
+ Console.Write("World");
+
+ ///////////////////////////////////////////////////
+ // 类型和变量
+ //
+ // 使用 <type> <name> 定义变量
+ ///////////////////////////////////////////////////
+
+ // Sbyte - 有符号 8-bit 整数
+ // (-128 <= sbyte <= 127)
+ sbyte fooSbyte = 100;
+
+ // Byte - 无符号 8-bit 整数
+ // (0 <= byte <= 255)
+ byte fooByte = 100;
+
+ // Short - 16-bit 整数
+ // 有符号 - (-32,768 <= short <= 32,767)
+ // 无符号 - (0 <= ushort <= 65,535)
+ short fooShort = 10000;
+ ushort fooUshort = 10000;
+
+ // Integer - 32-bit 整数
+ int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
+ uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
+
+ // Long - 64-bit 整数
+ long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
+ // 数字默认为 int 或 uint (取决于尺寸)
+ // 使用 L 标明变量值类型为long 或 ulong
+
+ // Double - 双精度 64-bit IEEE 754 浮点数
+ double fooDouble = 123.4; // 精度: 15-16 位
+
+ // Float - 单精度 32-bit IEEE 754 浮点数
+ float fooFloat = 234.5f; // 精度: 7 位
+ // 使用 f 标明变量值类型为float
+
+ // Decimal - 128-bits 数据类型,比其他浮点类型精度更高
+ // 适合财务、金融
+ decimal fooDecimal = 150.3m;
+
+ // 布尔值 - true & false
+ bool fooBoolean = true; // 或 false
+
+ // Char - 单个 16-bit Unicode 字符
+ char fooChar = 'A';
+
+ // 字符串 -- 和前面的基本类型不同,字符串不是值,而是引用。
+ // 这意味着你可以将字符串设为null。
+ string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
+ Console.WriteLine(fooString);
+
+ // 你可以通过索引访问字符串的每个字符:
+ char charFromString = fooString[1]; // => 'e'
+ // 字符串不可修改: fooString[1] = 'X' 是行不通的;
+
+ // 根据当前的locale设定比较字符串,大小写不敏感
+ string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
+
+ // 基于sprintf的字符串格式化
+ string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
+
+ // 日期和格式
+ DateTime fooDate = DateTime.Now;
+ Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+
+ // 使用 @ 符号可以创建跨行的字符串。使用 "" 来表示 "
+ string bazString = @"Here's some stuff
+on a new line! ""Wow!"", the masses cried";
+
+ // 使用const或read-only定义常量
+ // 常量在编译期演算
+ const int HOURS_I_WORK_PER_WEEK = 9001;
+
+ ///////////////////////////////////////////////////
+ // 数据结构
+ ///////////////////////////////////////////////////
+
+ // 数组 - 从0开始计数
+ // 声明数组时需要确定数组长度
+ // 声明数组的格式如下:
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+
+ // 声明并初始化数组的其他方式:
+ int[] y = { 9000, 1000, 1337 };
+
+ // 访问数组的元素
+ Console.WriteLine("intArray @ 0: " + intArray[0]);
+ // 数组可以修改
+ intArray[1] = 1;
+
+ // 列表
+ // 列表比数组更常用,因为列表更灵活。
+ // 声明列表的格式如下:
+ // List<datatype> <var name> = new List<datatype>();
+ List<int> intList = new List<int>();
+ List<string> stringList = new List<string>();
+ List<int> z = new List<int> { 9000, 1000, 1337 }; // i
+ // <>用于泛型 - 参考下文
+
+ // 列表无默认值
+ // 访问列表元素时必须首先添加元素
+ intList.Add(1);
+ Console.WriteLine("intList @ 0: " + intList[0]);
+
+ // 其他数据结构:
+ // 堆栈/队列
+ // 字典 (哈希表的实现)
+ // 哈希集合
+ // 只读集合
+ // 元组 (.Net 4+)
+
+ ///////////////////////////////////////
+ // 操作符
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Operators");
+
+ int i1 = 1, i2 = 2; // 多重声明的简写形式
+
+ // 算术直截了当
+ Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
+
+ // 取余
+ Console.WriteLine("11%3 = " + (11 % 3)); // => 2
+
+ // 比较操作符
+ Console.WriteLine("3 == 2? " + (3 == 2)); // => false
+ Console.WriteLine("3 != 2? " + (3 != 2)); // => true
+ Console.WriteLine("3 > 2? " + (3 > 2)); // => true
+ Console.WriteLine("3 < 2? " + (3 < 2)); // => false
+ Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
+ Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
+
+ // 位操作符
+ /*
+ ~ 取反
+ << 左移(有符号)
+ >> 右移(有符号)
+ & 与
+ ^ 异或
+ | 或
+ */
+
+ // 自增、自减
+ int i = 0;
+ Console.WriteLine("\n->Inc/Dec-rementation");
+ Console.WriteLine(i++); //i = 1. 事后自增
+ Console.WriteLine(++i); //i = 2. 事先自增
+ Console.WriteLine(i--); //i = 1. 事后自减
+ Console.WriteLine(--i); //i = 0. 事先自减
+
+ ///////////////////////////////////////
+ // 控制结构
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Control Structures");
+
+ // 类似C的if语句
+ int j = 10;
+ if (j == 10)
+ {
+ Console.WriteLine("I get printed");
+ }
+ else if (j > 10)
+ {
+ Console.WriteLine("I don't");
+ }
+ else
+ {
+ Console.WriteLine("I also don't");
+ }
+
+ // 三元表达式
+ // 简单的 if/else 语句可以写成:
+ // <条件> ? <真> : <假>
+ string isTrue = (true) ? "True" : "False";
+
+ // While 循环
+ int fooWhile = 0;
+ while (fooWhile < 100)
+ {
+ //迭代 100 次, fooWhile 0->99
+ fooWhile++;
+ }
+
+ // Do While 循环
+ int fooDoWhile = 0;
+ do
+ {
+ //迭代 100 次, fooDoWhile 0->99
+ fooDoWhile++;
+ } while (fooDoWhile < 100);
+
+ //for 循环结构 => for(<初始条件>; <条件>; <步>)
+ for (int fooFor = 0; fooFor < 10; fooFor++)
+ {
+ //迭代10次, fooFor 0->9
+ }
+
+ // foreach循环
+ // foreach 循环结构 => foreach(<迭代器类型> <迭代器> in <可枚举结构>)
+ // foreach 循环适用于任何实现了 IEnumerable 或 IEnumerable<T> 的对象。
+ // .Net 框架下的集合类型(数组, 列表, 字典...)
+ // 都实现了这些接口
+ // (下面的代码中,ToCharArray()可以删除,因为字符串同样实现了IEnumerable)
+ foreach (char character in "Hello World".ToCharArray())
+ {
+ //迭代字符串中的所有字符
+ }
+
+ // Switch 语句
+ // switch 适用于 byte、short、char和int 数据类型。
+ // 同样适用于可枚举的类型
+ // 包括字符串类, 以及一些封装了原始值的类:
+ // Character、Byte、Short和Integer。
+ int month = 3;
+ string monthString;
+ switch (month)
+ {
+ case 1:
+ monthString = "January";
+ break;
+ case 2:
+ monthString = "February";
+ break;
+ case 3:
+ monthString = "March";
+ break;
+ // 你可以一次匹配多个case语句
+ // 但是你在添加case语句后需要使用break
+ // (否则你需要显式地使用goto case x语句)
+ case 6:
+ case 7:
+ case 8:
+ monthString = "Summer time!!";
+ break;
+ default:
+ monthString = "Some other month";
+ break;
+ }
+
+ ///////////////////////////////////////
+ // 转换、指定数据类型
+ ///////////////////////////////////////
+
+ // 转换类型
+
+ // 转换字符串为整数
+ // 转换失败会抛出异常
+ int.Parse("123");//返回整数类型的"123"
+
+ // TryParse会尝试转换类型,失败时会返回缺省类型
+ // 例如 0
+ int tryInt;
+ if (int.TryParse("123", out tryInt)) // Funciton is boolean
+ Console.WriteLine(tryInt); // 123
+
+ // 转换整数为字符串
+ // Convert类提供了一系列便利转换的方法
+ Convert.ToString(123);
+ // or
+ tryInt.ToString();
+ }
+
+ ///////////////////////////////////////
+ // 类
+ ///////////////////////////////////////
+ public static void Classes()
+ {
+ // 参看文件尾部的对象声明
+
+ // 使用new初始化对象
+ Bicycle trek = new Bicycle();
+
+ // 调用对象的方法
+ trek.SpeedUp(3); // 你应该一直使用setter和getter方法
+ trek.Cadence = 100;
+
+ // 查看对象的信息.
+ Console.WriteLine("trek info: " + trek.Info());
+
+ // 实例化一个新的Penny Farthing
+ PennyFarthing funbike = new PennyFarthing(1, 10);
+ Console.WriteLine("funbike info: " + funbike.Info());
+
+ Console.Read();
+ } // 结束main方法
+
+ // 终端程序 终端程序必须有一个main方法作为入口
+ public static void Main(string[] args)
+ {
+ OtherInterestingFeatures();
+ }
+
+ //
+ // 有趣的特性
+ //
+
+ // 默认方法签名
+
+ public // 可见性
+ static // 允许直接调用类,无需先创建实例
+ int, //返回值
+ MethodSignatures(
+ int maxCount, // 第一个变量,类型为整型
+ int count = 0, // 如果没有传入值,则缺省值为0
+ int another = 3,
+ params string[] otherParams // 捕获其他参数
+ )
+ {
+ return -1;
+ }
+
+ // 方法可以重名,只要签名不一样
+ public static void MethodSignature(string maxCount)
+ {
+ }
+
+ //泛型
+ // TKey和TValue类由用用户调用函数时指定。
+ // 以下函数模拟了Python的SetDefault
+ public static TValue SetDefault<TKey, TValue>(
+ IDictionary<TKey, TValue> dictionary,
+ TKey key,
+ TValue defaultItem)
+ {
+ TValue result;
+ if (!dictionary.TryGetValue(key, out result))
+ return dictionary[key] = defaultItem;
+ return result;
+ }
+
+ // 你可以限定传入值的范围
+ public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
+ {
+ // 我们可以进行迭代,因为T是可枚举的
+ foreach (var item in toPrint)
+ // ittm为整数
+ Console.WriteLine(item.ToString());
+ }
+
+ public static void OtherInterestingFeatures()
+ {
+ // 可选参数
+ MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
+ MethodSignatures(3, another: 3); // 显式指定参数,忽略可选参数
+
+ // 扩展方法
+ int i = 3;
+ i.Print(); // 参见下面的定义
+
+ // 可为null的类型 对数据库交互、返回值很有用
+ // 任何值类型 (i.e. 不为类) 添加后缀 ? 后会变为可为null的值
+ // <类型>? <变量名> = <值>
+ int? nullable = null; // Nullable<int> 的简写形式
+ Console.WriteLine("Nullable variable: " + nullable);
+ bool hasValue = nullable.HasValue; // 不为null时返回真
+ // ?? 是用于指定默认值的语法糖
+ // 以防变量为null的情况
+ int notNullable = nullable ?? 0; // 0
+
+ // 变量类型推断 - 你可以让编译器推断变量类型:
+ var magic = "编译器确定magic是一个字符串,所以仍然是类型安全的";
+ // magic = 9; // 不工作,因为magic是字符串,而不是整数。
+
+ // 泛型
+ //
+ var phonebook = new Dictionary<string, string>() {
+ {"Sarah", "212 555 5555"} // 在电话簿中加入新条目
+ };
+
+ // 调用上面定义为泛型的SETDEFAULT
+ Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // 没有电话
+ // 你不用指定TKey、TValue,因为它们会被隐式地推导出来
+ Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
+
+ // lambda表达式 - 允许你用一行代码搞定函数
+ Func<int, int> square = (x) => x * x; // 最后一项为返回值
+ Console.WriteLine(square(3)); // 9
+
+ // 可抛弃的资源管理 - 让你很容易地处理未管理的资源
+ // 大多数访问未管理资源 (文件操作符、设备上下文, etc.)的对象
+ // 都实现了IDisposable接口。
+ // using语句会为你清理IDisposable对象。
+ using (StreamWriter writer = new StreamWriter("log.txt"))
+ {
+ writer.WriteLine("这里没有什么可疑的东西");
+ // 在作用域的结尾,资源会被回收
+ // (即使有异常抛出,也一样会回收)
+ }
+
+ // 并行框架
+ // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
+ var websites = new string[] {
+ "http://www.google.com", "http://www.reddit.com",
+ "http://www.shaunmccarthy.com"
+ };
+ var responses = new Dictionary<string, string>();
+
+ // 为每个请求新开一个线程
+ // 在运行下一步前合并结果
+ Parallel.ForEach(websites,
+ new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
+ website =>
+ {
+ // Do something that takes a long time on the file
+ using (var r = WebRequest.Create(new Uri(website)).GetResponse())
+ {
+ responses[website] = r.ContentType;
+ }
+ });
+
+ // 直到所有的请求完成后才会运行下面的代码
+ foreach (var key in responses.Keys)
+ Console.WriteLine("{0}:{1}", key, responses[key]);
+
+ // 动态对象(配合其他语言使用很方便)
+ dynamic student = new ExpandoObject();
+ student.FirstName = "First Name"; // 不需要先定义类!
+
+ // 你甚至可以添加方法(接受一个字符串,输出一个字符串)
+ student.Introduce = new Func<string, string>(
+ (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
+ Console.WriteLine(student.Introduce("Beth"));
+
+ // IQUERYABLE<T> - 几乎所有的集合都实现了它,
+ // 带给你 Map / Filter / Reduce 风格的方法
+ var bikes = new List<Bicycle>();
+ bikes.Sort(); // Sorts the array
+ bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // 根据车轮数排序
+ var result = bikes
+ .Where(b => b.Wheels > 3) // 筛选 - 可以连锁使用 (返回IQueryable)
+ .Where(b => b.IsBroken && b.HasTassles)
+ .Select(b => b.ToString()); // Map - 这里我们使用了select,所以结果是IQueryable<string>
+
+ var sum = bikes.Sum(b => b.Wheels); // Reduce - 计算集合中的轮子总数
+
+ // 创建一个包含基于自行车的一些参数生成的隐式对象的列表
+ var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
+ // 很难演示,但是编译器在代码编译完成前就能推导出以上对象的类型
+ foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
+ Console.WriteLine(bikeSummary.Name);
+
+ // ASPARALLEL
+ // 邪恶的特性 —— 组合了linq和并行操作
+ var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
+ // 以上代码会并发地运行。会自动新开线程,分别计算结果。
+ // 适用于多核、大数据量的场景。
+
+ // LINQ - 将IQueryable<T>映射到存储,延缓执行
+ // 例如 LinqToSql 映射数据库, LinqToXml 映射XML文档
+ var db = new BikeRespository();
+
+ // 执行被延迟了,这对于查询数据库来说很好
+ var filter = db.Bikes.Where(b => b.HasTassles); // 不运行查询
+ if (42 > 6) // 你可以不断地增加筛选,包括有条件的筛选,例如用于“高级搜索”功能
+ filter = filter.Where(b => b.IsBroken); // 不运行查询
+
+ var query = filter
+ .OrderBy(b => b.Wheels)
+ .ThenBy(b => b.Name)
+ .Select(b => b.Name); // 仍然不运行查询
+
+ // 现在运行查询,运行查询的时候会打开一个读取器,所以你迭代的是一个副本
+ foreach (string bike in query)
+ Console.WriteLine(result);
+
+
+
+ }
+
+ } // 结束LearnCSharp类
+
+ // 你可以在同一个 .cs 文件中包含其他类
+
+ public static class Extensions
+ {
+ // 扩展函数
+ public static void Print(this object obj)
+ {
+ Console.WriteLine(obj.ToString());
+ }
+ }
+ // 声明类的语法:
+ // <public/private/protected/internal> class <类名>{
+ // //数据字段, 构造器, 内部函数.
+ / // 在Java中函数被称为方法。
+ // }
+
+ public class Bicycle
+ {
+ // 自行车的字段、变量
+ public int Cadence // Public: 任何地方都可以访问
+ {
+ get // get - 定义获取属性的方法
+ {
+ return _cadence;
+ }
+ set // set - 定义设置属性的方法
+ {
+ _cadence = value; // value是被传递给setter的值
+ }
+ }
+ private int _cadence;
+
+ protected virtual int Gear // 类和子类可以访问
+ {
+ get; // 创建一个自动属性,无需成员字段
+ set;
+ }
+
+ internal int Wheels // Internal:在同一程序集内可以访问
+ {
+ get;
+ private set; // 可以给get/set方法添加修饰符
+ }
+
+ int _speed; // 默认为private: 只可以在这个类内访问,你也可以使用`private`关键词
+ public string Name { get; set; }
+
+ // enum类型包含一组常量
+ // 它将名称映射到值(除非特别说明,是一个整型)
+ // enmu元素的类型可以是byte、sbyte、short、ushort、int、uint、long、ulong。
+ // enum不能包含相同的值。
+ public enum BikeBrand
+ {
+ AIST,
+ BMC,
+ Electra = 42, //你可以显式地赋值
+ Gitane // 43
+ }
+ // 我们在Bicycle类中定义的这个类型,所以它是一个内嵌类型。
+ // 这个类以外的代码应当使用`Bicycle.Brand`来引用。
+
+ public BikeBrand Brand; // 声明一个enum类型之后,我们可以声明这个类型的字段
+
+ // 静态方法的类型为自身,不属于特定的对象。
+ // 你无需引用对象就可以访问他们。
+ // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
+ static public int BicyclesCreated = 0;
+
+ // 只读值在运行时确定
+ // 它们只能在声明或构造器内被赋值
+ readonly bool _hasCardsInSpokes = false; // read-only private
+
+ // 构造器是创建类的一种方式
+ // 下面是一个默认的构造器
+ public Bicycle()
+ {
+ this.Gear = 1; // 你可以使用关键词this访问对象的成员
+ Cadence = 50; // 不过你并不总是需要它
+ _speed = 5;
+ Name = "Bontrager";
+ Brand = BikeBrand.AIST;
+ BicyclesCreated++;
+ }
+
+ // 另一个构造器的例子(包含参数)
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ string name, bool hasCardsInSpokes, BikeBrand brand)
+ : base() // 首先调用base
+ {
+ Gear = startGear;
+ Cadence = startCadence;
+ _speed = startSpeed;
+ Name = name;
+ _hasCardsInSpokes = hasCardsInSpokes;
+ Brand = brand;
+ }
+
+ // 构造器可以连锁使用
+ public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
+ this(startCadence, startSpeed, 0, "big wheels", true, brand)
+ {
+ }
+
+ // 函数语法
+ // <public/private/protected> <返回值> <函数名称>(<参数>)
+
+ // 类可以为字段实现 getters 和 setters 方法 for their fields
+ // 或者可以实现属性(C#推荐使用这个)
+ // 方法的参数可以有默认值
+ // 在有默认值的情况下,调用方法的时候可以省略相应的参数
+ public void SpeedUp(int increment = 1)
+ {
+ _speed += increment;
+ }
+
+ public void SlowDown(int decrement = 1)
+ {
+ _speed -= decrement;
+ }
+
+ // 属性可以访问和设置值
+ // 当只需要访问数据的时候,考虑使用属性。
+ // 属性可以定义get和set,或者是同时定义两者
+ private bool _hasTassles; // private variable
+ public bool HasTassles // public accessor
+ {
+ get { return _hasTassles; }
+ set { _hasTassles = value; }
+ }
+
+ // 你可以在一行之内定义自动属性
+ // 这个语法会自动创建后备字段
+ // 你可以给getter或setter设置访问修饰符
+ // 以便限制它们的访问
+ public bool IsBroken { get; private set; }
+
+ // 属性的实现可以是自动的
+ public int FrameSize
+ {
+ get;
+ // 你可以给get或set指定访问修饰符
+ // 以下代码意味着只有Bicycle类可以调用Framesize的set
+ private set;
+ }
+
+ //显示对象属性的方法
+ public virtual string Info()
+ {
+ return "Gear: " + Gear +
+ " Cadence: " + Cadence +
+ " Speed: " + _speed +
+ " Name: " + Name +
+ " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
+ "\n------------------------------\n"
+ ;
+ }
+
+ // 方法可以是静态的。通常用于辅助方法。
+ public static bool DidWeCreateEnoughBycles()
+ {
+ // 在静态方法中,你只能引用类的静态成员
+ return BicyclesCreated > 9000;
+ } // 如果你的类只需要静态成员,考虑将整个类作为静态类。
+
+
+ } // Bicycle类结束
+
+ // PennyFarthing是Bicycle的一个子类
+ class PennyFarthing : Bicycle
+ {
+ // (Penny Farthings是一种前轮很大的自行车。没有齿轮。)
+
+ // 调用父构造器
+ public PennyFarthing(int startCadence, int startSpeed) :
+ base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
+ {
+ }
+
+ protected override int Gear
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ throw new ArgumentException("你不可能在PennyFarthing上切换齿轮");
+ }
+ }
+
+ public override string Info()
+ {
+ string result = "PennyFarthing bicycle ";
+ result += base.ToString(); // 调用父方法
+ return result;
+ }
+ }
+
+ // 接口只包含成员的签名,而没有实现。
+ interface IJumpable
+ {
+ void Jump(int meters); // 所有接口成员是隐式地公开的
+ }
+
+ interface IBreakable
+ {
+ bool Broken { get; } // 接口可以包含属性、方法和事件
+ }
+
+ // 类只能继承一个类,但是可以实现任意数量的接口
+ {
+ int damage = 0;
+
+ public void Jump(int meters)
+ {
+ damage += meters;
+ }
+
+ public bool Broken
+ {
+ get
+ {
+ return damage > 100;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 连接数据库,一个 LinqToSql的示例。
+ /// EntityFramework Code First 很棒 (类似 Ruby的 ActiveRecord, 不过是双向的)
+ /// http://msdn.microsoft.com/en-us/data/jj193542.aspx
+ /// </summary>
+ public class BikeRespository : DbSet
+ {
+ public BikeRespository()
+ : base()
+ {
+ }
+
+ public DbSet<Bicycle> Bikes { get; set; }
+ }
+} // 结束 Namespace
+```
+
+## 没有涉及到的主题
+
+ * Flags
+ * Attributes
+ * 静态属性
+ * Exceptions, Abstraction
+ * ASP.NET (Web Forms/MVC/WebMatrix)
+ * Winforms
+ * Windows Presentation Foundation (WPF)
+
+## 扩展阅读
+
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
+ * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
+ * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
+ * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
+ * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+ * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
diff --git a/zh-cn/css-cn.html.markdown b/zh-cn/css-cn.html.markdown
new file mode 100644
index 00000000..dc6dcc4f
--- /dev/null
+++ b/zh-cn/css-cn.html.markdown
@@ -0,0 +1,212 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+translators:
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+lang: zh-cn
+filename: learncss-cn.css
+---
+
+早期的web没有样式,只是单纯的文本。通过CSS,可以实现网页样式和内容的分离。
+
+简单来说,CSS可以指定HTML页面上的元素所使用的样式。
+
+和其他语言一样,CSS有很多版本。最新的版本是CSS 3. CSS 2.0兼容性最好。
+
+你可以使用[dabblet](http://dabblet.com/)来在线测试CSS的效果。
+
+```css
+/* 注释 */
+
+/* ####################
+ ## 选择器
+ ####################*/
+
+/* 一般而言,CSS的声明语句非常简单。 */
+选择器 { 属性: 值; /* 更多属性...*/ }
+
+/* 选择器用于指定页面上的元素。
+
+针对页面上的所有元素。 */
+* { color:red; }
+
+/*
+假定页面上有这样一个元素
+
+<div class='some-class class2' id='someId' attr='value' />
+*/
+
+/* 你可以通过类名来指定它 */
+.some-class { }
+
+/* 给出所有类名 */
+.some-class.class2 { }
+
+/* 标签名 */
+div { }
+
+/* id */
+#someId { }
+
+/* 由于元素包含attr属性,因此也可以通过这个来指定 */
+[attr] { font-size:smaller; }
+
+/* 以及有特定值的属性 */
+[attr='value'] { font-size:smaller; }
+
+/* 通过属性的值的开头指定 */
+[attr^='val'] { font-size:smaller; }
+
+/* 通过属性的值的结尾来指定 */
+[attr$='ue'] { font-size:smaller; }
+
+/* 通过属性的值的部分来指定 */
+[attr~='lu'] { font-size:smaller; }
+
+
+/* 你可以把这些全部结合起来,注意不同部分间不应该有空格,否则会改变语义 */
+div.some-class[attr$='ue'] { }
+
+/* 你也可以通过父元素来指定。*/
+
+/* 某个元素是另一个元素的直接子元素 */
+div.some-parent > .class-name {}
+
+/* 或者通过该元素的祖先元素 */
+div.some-parent .class-name {}
+
+/* 注意,去掉空格后语义就不同了。
+你能说出哪里不同么? */
+div.some-parent.class-name {}
+
+/* 你可以选择某元素前的相邻元素 */
+.i-am-before + .this-element { }
+
+/* 某元素之前的同级元素(相邻或不相邻) */
+.i-am-any-before ~ .this-element {}
+
+/* 伪类允许你基于页面的行为指定元素(而不是基于页面结构) */
+
+/* 例如,当鼠标悬停在某个元素上时 */
+:hover {}
+
+/* 已访问过的链接*/
+:visited {}
+
+/* 未访问过的链接*/
+:link {}
+
+/* 当前焦点的input元素 */
+:focus {}
+
+
+/* ####################
+ ## 属性
+ ####################*/
+
+选择器 {
+
+ /* 单位 */
+ width: 50%; /* 百分比 */
+ font-size: 2em; /* 当前字体大小的两倍 */
+ width: 200px; /* 像素 */
+ font-size: 20pt; /* 点 */
+ width: 5cm; /* 厘米 */
+ width: 50mm; /* 毫米 */
+ width: 5in; /* 英尺 */
+
+ /* 颜色 */
+ background-color: #F6E; /* 短16位 */
+ background-color: #F262E2; /* 长16位 */
+ background-color: tomato; /* 颜色名称 */
+ background-color: rgb(255, 255, 255); /* rgb */
+ background-color: rgb(10%, 20%, 50%); /* rgb 百分比 */
+ background-color: rgba(255, 0, 0, 0.3); /* rgb 加透明度 */
+
+ /* 图片 */
+ background-image: url(/path-to-image/image.jpg);
+
+ /* 字体 */
+ font-family: Arial;
+ font-family: "Courier New"; /* 使用双引号包裹含空格的字体名称 */
+ font-family: "Courier New", Trebuchet, Arial; /* 如果第一个
+ 字体没找到,浏览器会使用第二个字体,一次类推 */
+}
+
+```
+
+## 使用
+
+CSS文件使用 `.css` 后缀。
+
+```xml
+<!-- 你需要在文件的 <head> 引用CSS文件 -->
+<link rel='stylesheet' type='text/css' href='filepath/filename.css' />
+
+<!-- 你也可以在标记中内嵌CSS。不过强烈建议不要这么干。 -->
+<style>
+ 选择器 { 属性:值; }
+</style>
+
+<!-- 也可以直接使用元素的style属性。
+这是你最不该干的事情。 -->
+<div style='property:value;'>
+</div>
+
+```
+
+## 优先级
+
+同一个元素可能被多个不同的选择器指定,因此可能会有冲突。
+
+假定CSS是这样的:
+
+```css
+/*A*/
+p.class1[attr='value']
+
+/*B*/
+p.class1 {}
+
+/*C*/
+p.class2 {}
+
+/*D*/
+p {}
+
+/*E*/
+p { property: value !important; }
+
+```
+
+然后标记语言为:
+
+```xml
+<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
+</p>
+```
+
+那么将会按照下面的顺序应用风格:
+
+
+* `E` 优先级最高,因为它使用了 `!important`,除非很有必要,尽量避免使用这个。
+* `F` 其次,因为它是嵌入的风格。
+* `A` 其次,因为它比其他指令更具体。
+* `C` 其次,虽然它的具体程度和`B`一样,但是它在`B`之后。
+* 接下来是 `B`。
+* 最后是 `D`。
+
+## 兼容性
+
+CSS2 的绝大部分特性兼容各种浏览器和设备。现在 CSS3 的兼容性也越来越好了。
+但是兼容性问题仍然是需要留意的一个问题。
+
+[QuirksMode CSS](http://www.quirksmode.org/css/)是关于这方面最好的资源。
+
+## 扩展阅读
+
+* [理解CSS的风格优先级: 特定性, 继承和层叠](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/zh-cn/elisp-cn.html.markdown b/zh-cn/elisp-cn.html.markdown
index d303c2e8..06f38d77 100755..100644
--- a/zh-cn/elisp-cn.html.markdown
+++ b/zh-cn/elisp-cn.html.markdown
@@ -132,7 +132,7 @@ lang: zh-cn
;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内
;; 用鼠标单击上面的buffer就会使光标移回。
-;; 或者你可以使用 `C-xo' 是的光标跳到另一个窗口中
+;; 或者你可以使用 `C-xo' 使得光标跳到另一个窗口中
;; 你可以用 `progn'命令将s式结合起来:
(progn
@@ -219,7 +219,7 @@ lang: zh-cn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-;; 我们将一些名字存到列表中;
+;; 我们将一些名字存到列表中:
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
;; 用 `car'来取得第一个名字:
diff --git a/zh-cn/elixir-cn.html.markdown b/zh-cn/elixir-cn.html.markdown
new file mode 100644
index 00000000..daee8d3c
--- /dev/null
+++ b/zh-cn/elixir-cn.html.markdown
@@ -0,0 +1,399 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+translators:
+ - ["lidashuang", "http://github.com/lidashuang"]
+filename: learnelixir-cn.ex
+lang: zh-cn
+---
+
+Elixir 是一门构建在Erlang VM 之上的函数式编程语言。Elixir 完全兼容 Erlang,
+另外还提供了更标准的语法,特性。
+
+```elixir
+
+# 这是单行注释, 注释以井号开头
+
+# 没有多行注释
+# 但你可以堆叠多个注释。
+
+# elixir shell 使用命令 `iex` 进入。
+# 编译模块使用 `elixirc` 命令。
+
+# 如果安装正确,这些命令都会在环境变量里
+
+## ---------------------------
+## -- 基本类型
+## ---------------------------
+
+# 数字
+3 # 整型
+0x1F # 整型
+3.0 # 浮点类型
+
+# 原子(Atoms),以 `:`开头
+:hello # atom
+
+# 元组(Tuple) 在内存中的存储是连续的
+{1,2,3} # tuple
+
+# 使用`elem`函数访问元组(tuple)里的元素:
+elem({1, 2, 3}, 0) #=> 1
+
+# 列表(list)
+[1,2,3] # list
+
+# 可以用下面的方法访问列表的头尾元素:
+[head | tail] = [1,2,3]
+head #=> 1
+tail #=> [2,3]
+
+# 在elixir,就像在Erlang, `=` 表示模式匹配 (pattern matching)
+# 不是赋值。
+#
+# 这表示会用左边的模式(pattern)匹配右侧
+#
+# 上面的例子中访问列表的头部和尾部就是这样工作的。
+
+# 当左右两边不匹配时,会返回error, 在这个
+# 例子中,元组大小不一样。
+# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
+
+# 还有二进制类型 (binaries)
+<<1,2,3>> # binary
+
+# 字符串(Strings) 和 字符列表(char lists)
+"hello" # string
+'hello' # char list
+
+# 多行字符串
+"""
+I'm a multi-line
+string.
+"""
+#=> "I'm a multi-line\nstring.\n"
+
+# 所有的字符串(Strings)以UTF-8编码:
+"héllò" #=> "héllò"
+
+# 字符串(Strings)本质就是二进制类型(binaries), 字符列表(char lists)本质是列表(lists)
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# 在 elixir中,`?a`返回 `a` 的 ASCII 整型值
+?a #=> 97
+
+# 合并列表使用 `++`, 对于二进制类型则使用 `<>`
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'hello ' ++ 'world' #=> 'hello world'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"hello " <> "world" #=> "hello world"
+
+## ---------------------------
+## -- 操作符(Operators)
+## ---------------------------
+
+# 一些数学运算
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# 在 elixir 中,操作符 `/` 返回值总是浮点数。
+
+# 做整数除法使用 `div`
+div(10, 2) #=> 5
+
+# 为了得到余数使用 `rem`
+rem(10, 3) #=> 1
+
+# 还有 boolean 操作符: `or`, `and` and `not`.
+# 第一个参数必须是boolean 类型
+true and true #=> true
+false or true #=> true
+# 1 and true #=> ** (ArgumentError) argument error
+
+# Elixir 也提供了 `||`, `&&` 和 `!` 可以接受任意的类型
+# 除了`false` 和 `nil` 其它都会被当作true.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+
+!true #=> false
+
+# 比较有: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` 和 `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# `===` 和 `!==` 在比较整型和浮点类型时更为严格:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# 我们也可以比较两种不同的类型:
+1 < :hello #=> true
+
+# 总的排序顺序定义如下:
+# number < atom < reference < functions < port < pid < tuple < list < bit string
+
+# 引用Joe Armstrong :“实际的顺序并不重要,
+# 但是,一个整体排序是否经明确界定是非常重要的。”
+
+## ---------------------------
+## -- 控制结构(Control Flow)
+## ---------------------------
+
+# `if` 表达式
+if false do
+ "This will never be seen"
+else
+ "This will"
+end
+
+# 还有 `unless`
+unless true do
+ "This will never be seen"
+else
+ "This will"
+end
+
+# 在Elixir中,很多控制结构都依赖于模式匹配
+
+# `case` 允许我们把一个值与多种模式进行比较:
+case {:one, :two} do
+ {:four, :five} ->
+ "This won't match"
+ {:one, x} ->
+ "This will match and assign `x` to `:two`"
+ _ ->
+ "This will match any value"
+end
+
+# 模式匹配时,如果不需要某个值,通用的做法是把值 匹配到 `_`
+# 例如,我们只需要要列表的头元素:
+[head | _] = [1,2,3]
+head #=> 1
+
+# 下面的方式效果一样,但可读性更好
+[head | _tail] = [:a, :b, :c]
+head #=> :a
+
+# `cond` 可以检测多种不同的分支
+# 使用 `cond` 代替多个`if` 表达式嵌套
+cond do
+ 1 + 1 == 3 ->
+ "I will never be seen"
+ 2 * 5 == 12 ->
+ "Me neither"
+ 1 + 2 == 3 ->
+ "But I will"
+end
+
+# 经常可以看到最后一个条件等于'true',这将总是匹配。
+cond do
+ 1 + 1 == 3 ->
+ "I will never be seen"
+ 2 * 5 == 12 ->
+ "Me neither"
+ true ->
+ "But I will (this is essentially an else)"
+end
+
+# `try/catch` 用于捕获被抛出的值, 它也支持 `after` 子句,
+# 无论是否值被捕获,after 子句都会被调用
+# `try/catch`
+try do
+ throw(:hello)
+catch
+ message -> "Got #{message}."
+after
+ IO.puts("I'm the after clause.")
+end
+#=> I'm the after clause
+# "Got :hello"
+
+## ---------------------------
+## -- 模块和函数(Modules and Functions)
+## ---------------------------
+
+# 匿名函数 (注意点)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+
+# 也支持接收多个子句和卫士(guards).
+# Guards 可以进行模式匹配
+# Guards 使用 `when` 关键字指明:
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir 提供了很多内建函数
+# 在默认作用域都是可用的
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# 你可以在一个模块里定义多个函数,定义函数使用 `def`
+defmodule Math do
+ def sum(a, b) do
+ a + b
+ end
+
+ def square(x) do
+ x * x
+ end
+end
+
+Math.sum(1, 2) #=> 3
+Math.square(3) #=> 9
+
+# 保存到 `math.ex`,使用 `elixirc` 编译你的 Math 模块
+# 在终端里: elixirc math.ex
+
+# 在模块中可以使用`def`定义函数,使用 `defp` 定义私有函数
+# 使用`def` 定义的函数可以被其它模块调用
+# 私有函数只能在本模块内调用
+defmodule PrivateMath do
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+
+# 函数定义同样支持 guards 和 多重子句:
+defmodule Geometry do
+ def area({:rectangle, w, h}) do
+ w * h
+ end
+
+ def area({:circle, r}) when is_number(r) do
+ 3.14 * r * r
+ end
+end
+
+Geometry.area({:rectangle, 2, 3}) #=> 6
+Geometry.area({:circle, 3}) #=> 28.25999999999999801048
+# Geometry.area({:circle, "not_a_number"})
+#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
+
+#由于不变性,递归是Elixir的重要组成部分
+defmodule Recursion do
+ def sum_list([head | tail], acc) do
+ sum_list(tail, acc + head)
+ end
+
+ def sum_list([], acc) do
+ acc
+ end
+end
+
+Recursion.sum_list([1,2,3], 0) #=> 6
+
+# Elixir 模块支持属性,模块内建了一些属性,你也可以自定义属性
+defmodule MyMod do
+ @moduledoc """
+ 内置的属性,模块文档
+ """
+
+ @my_data 100 # 自定义属性
+ IO.inspect(@my_data) #=> 100
+end
+
+## ---------------------------
+## -- 记录和异常(Records and Exceptions)
+## ---------------------------
+
+# 记录就是把特定值关联到某个名字的结构体
+defrecord Person, name: nil, age: 0, height: 0
+
+joe_info = Person.new(name: "Joe", age: 30, height: 180)
+#=> Person[name: "Joe", age: 30, height: 180]
+
+# 访问name的值
+joe_info.name #=> "Joe"
+
+# 更新age的值
+joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
+
+# 使用 `try` `rescue` 进行异常处理
+try do
+ raise "some error"
+rescue
+ RuntimeError -> "rescued a runtime error"
+ _error -> "this will rescue any error"
+end
+
+# 所有的异常都有一个message
+try do
+ raise "some error"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+
+## ---------------------------
+## -- 并发(Concurrency)
+## ---------------------------
+
+# Elixir 依赖于 actor并发模型。在Elixir编写并发程序的三要素:
+# 创建进程,发送消息,接收消息
+
+# 启动一个新的进程使用`spawn`函数,接收一个函数作为参数
+
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+
+# `spawn` 函数返回一个pid(进程标识符),你可以使用pid向进程发送消息。
+# 使用 `<-` 操作符发送消息。
+# 我们需要在进程内接收消息,要用到 `receive` 机制。
+
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Area = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Area = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# 编译这个模块,在shell中创建一个进程,并执行 `area_looop` 函数。
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+
+# 发送一个消息给 `pid`, 会在receive语句进行模式匹配
+pid <- {:rectangle, 2, 3}
+#=> Area = 6
+# {:rectangle,2,3}
+
+pid <- {:circle, 2}
+#=> Area = 12.56000000000000049738
+# {:circle,2}
+
+# shell也是一个进程(process), 你可以使用`self`获取当前 pid
+self() #=> #PID<0.27.0>
+```
+
+## 参考文献
+
+* [Getting started guide](http://elixir-lang.org/getting_started/1.html) from [elixir webpage](http://elixir-lang.org)
+* [Elixir Documentation](http://elixir-lang.org/docs/master/)
+* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) by Fred Hebert
+* "Programming Erlang: Software for a Concurrent World" by Joe Armstrong
diff --git a/zh-cn/git-cn.html.markdown b/zh-cn/git-cn.html.markdown
index 86952eba..4ef3ffb8 100755..100644
--- a/zh-cn/git-cn.html.markdown
+++ b/zh-cn/git-cn.html.markdown
@@ -219,7 +219,7 @@ $ git diff
# 显示索引和最近一次提交的不同
$ git diff --cached
-# 显示宫缩目录和最近一次提交的不同
+# 显示工作目录和最近一次提交的不同
$ git diff HEAD
```
@@ -349,7 +349,7 @@ $ git reset --hard 31f2bb1
### rm
-和add相反,从工作空间中去掉某个文件爱你
+和add相反,从工作空间中去掉某个文件
```bash
# 移除 HelloWorld.c
diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown
new file mode 100644
index 00000000..4a87dc21
--- /dev/null
+++ b/zh-cn/go-cn.html.markdown
@@ -0,0 +1,286 @@
+---
+language: Go
+lang: zh-cn
+filename: learngo-cn.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["pantaovay", "https://github.com/pantaovay"]
+ - ["lidashuang", "https://github.com/lidashuang"]
+
+---
+
+发明Go语言是出于更好地完成工作的需要。Go不是计算机科学的最新发展潮流,但它却提供了解决现实问题的最新最快的方法。
+
+Go拥有命令式语言的静态类型,编译很快,执行也很快,同时加入了对于目前多核CPU的并发计算支持,也有相应的特性来实现大规模编程。
+
+Go语言有非常棒的标准库,还有一个充满热情的社区。
+
+```go
+// 单行注释
+/* 多行
+ 注释 */
+
+// 导入包的子句在每个源文件的开头。
+// Main比较特殊,它用来声明可执行文件,而不是一个库。
+package main
+
+// Import语句声明了当前文件引用的包。
+import (
+ "fmt" // Go语言标准库中的包
+ "net/http" // 一个web服务器包
+ "strconv" // 字符串转换
+)
+
+// 函数声明:Main是程序执行的入口。
+// 不管你喜欢还是不喜欢,反正Go就用了花括号来包住函数体。
+func main() {
+ // 往标准输出打印一行。
+ // 用包名fmt限制打印函数。
+ fmt.Println("Hello world!")
+
+ // 调用当前包的另一个函数。
+ beyondHello()
+}
+
+// 函数可以在括号里加参数。
+// 如果没有参数的话,也需要一个空括号。
+func beyondHello() {
+ var x int // 变量声明,变量必须在使用之前声明。
+ x = 3 // 变量赋值。
+ // 可以用:=来偷懒,它自动把变量类型、声明和赋值都搞定了。
+ y := 4
+ sum, prod := learnMultiple(x, y) // 返回多个变量的函数
+ fmt.Println("sum:", sum, "prod:", prod) // 简单输出
+ learnTypes() // 少于y分钟,学的更多!
+}
+
+// 多变量和多返回值的函数
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // 返回两个值
+}
+
+// 内置变量类型和关键词
+func learnTypes() {
+ // 短声明给你所想。
+ s := "Learn Go!" // String类型
+
+ s2 := `A "raw" string literal
+can include line breaks.` // 同样是String类型
+
+ // 非ascii字符。Go使用UTF-8编码。
+ g := 'Σ' // rune类型,uint32的别名,使用UTF-8编码
+
+ f := 3.14195 // float64类型,IEEE-754 64位浮点数
+ c := 3 + 4i // complex128类型,内部使用两个float64表示
+
+ // Var变量可以直接初始化。
+ var u uint = 7 // unsigned 无符号变量,但是实现依赖int型变量的长度
+ var pi float32 = 22. / 7
+
+ // 字符转换
+ n := byte('\n') // byte是uint8的别名
+
+ // 数组类型编译的时候大小固定。
+ var a4 [4] int // 有4个int变量的数组,初始为0
+ a3 := [...]int{3, 1, 5} // 有3个int变量的数组,同时进行了初始化
+
+ // Slice 可以动态的增删。Array和Slice各有千秋,但是使用slice的地方更多些。
+ s3 := []int{4, 5, 9} // 和a3相比,这里没有省略号
+ s4 := make([]int, 4) // 分配一个有4个int型变量的slice,全部被初始化为0
+
+ var d2 [][]float64 // 声明而已,什么都没有分配
+ bs := []byte("a slice") // 类型转换的语法
+
+ p, q := learnMemory() // 声明p,q为int型变量的指针
+ fmt.Println(*p, *q) // * 取值
+
+ // Map是动态可增长关联数组,和其他语言中的hash或者字典相似。
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // 在Go语言中未使用的变量在编译的时候会报错,而不是warning。
+ // 下划线 _ 可以使你“使用”一个变量,但是丢弃它的值。
+ _,_,_,_,_,_,_,_,_ = s2, g, f, u, pi, n, a3, s4, bs
+ // 输出变量
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // 回到流程控制
+}
+
+// Go全面支持垃圾回收。Go有指针,但是不支持指针运算。
+// 你会因为空指针而犯错,但是不会因为增加指针而犯错。
+func learnMemory() (p, q *int) {
+ // 返回int型变量指针p和q
+ p = new(int) // 内置函数new分配内存
+ // 自动将分配的int赋值0,p不再是空的了。
+ 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 fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了,
+ // 也不用容忍被人的代码风格。
+ if false {
+ // pout
+ } else {
+ // gloat
+ }
+ // 如果太多嵌套的if语句,推荐使用switch
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // 隐式调用break语句,匹配上一个即停止
+ case 2:
+ // 不会运行
+ }
+ // 和if一样,for也不用括号
+ for x := 0; x < 3; x++ { // ++ 自增
+ fmt.Println("iteration", x)
+ }
+ // x在这里还是1。为什么?
+
+ // for 是go里唯一的循环关键字,不过它有很多变种
+ for { // 死循环
+ break // 骗你的
+ continue // 不会运行的
+ }
+ // 和for一样,if中的:=先给y赋值,然后再和x作比较。
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // 闭包函数
+ xBig := func() bool {
+ return x > 100 // x是上面声明的变量引用
+ }
+ fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)
+ x /= 1e5 // x变成10
+ fmt.Println("xBig:", xBig()) // 现在是false
+
+ // 当你需要goto的时候,你会爱死它的!
+ goto love
+love:
+
+ learnInterfaces() // 好东西来了!
+}
+
+// 定义Stringer为一个接口类型,有一个方法String
+type Stringer interface {
+ String() string
+}
+
+// 定义pair为一个结构体,有x和y两个int型变量。
+type pair struct {
+ x, y int
+}
+
+// 定义pair类型的方法,实现Stringer接口。
+func (p pair) String() string { // p被叫做“接收器”
+ // Sprintf是fmt包中的另一个公有函数。
+ // 用 . 调用p中的元素。
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // 花括号用来定义结构体变量,:=在这里将一个结构体变量赋值给p。
+ p := pair{3, 4}
+ fmt.Println(p.String()) // 调用pair类型p的String方法
+ var i Stringer // 声明i为Stringer接口类型
+ i = p // 有效!因为p实现了Stringer接口(类似java中的塑型)
+ // 调用i的String方法,输出和上面一样
+ fmt.Println(i.String())
+
+ // fmt包中的Println函数向对象要它们的string输出,实现了String方法就可以这样使用了。
+ // (类似java中的序列化)
+ fmt.Println(p) // 输出和上面一样,自动调用String函数。
+ fmt.Println(i) // 输出和上面一样。
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok"用来判断有没有正常工作
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok 为false,因为m中没有1
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // 如果x在map中的话,x就是那个值喽。
+ }
+ // 错误可不只是ok,它还可以给出关于问题的更多细节。
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
+ // 输出"strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // 待会再说接口吧。同时,
+ learnConcurrency()
+}
+
+// c是channel类型,一个并发安全的通信对象。
+func inc(i int, c chan int) {
+ c <- i + 1 // <-把右边的发送到左边的channel。
+}
+
+// 我们将用inc函数来并发地增加一些数字。
+func learnConcurrency() {
+ // 用make来声明一个slice,make会分配和初始化slice,map和channel。
+ c := make(chan int)
+ // 用go关键字开始三个并发的goroutine,如果机器支持的话,还可能是并行执行。
+ // 三个都被发送到同一个channel。
+ go inc(0, c) // go is a statement that starts a new goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // 从channel中独处结果并打印。
+ // 打印出什么东西是不可预知的。
+ fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是读操作。
+
+ cs := make(chan string) // 操作string的channel
+ cc := make(chan chan string) // 操作channel的channel
+ go func() { c <- 84 }() // 开始一个goroutine来发送一个新的数字
+ go func() { cs <- "wordy" }() // 发送给cs
+ // Select类似于switch,但是每个case包括一个channel操作。
+ // 它随机选择一个准备好通讯的case。
+ select {
+ case i := <-c: // 从channel接收的值可以赋给其他变量
+ fmt.Println("it's a", i)
+ case <-cs: // 或者直接丢弃
+ fmt.Println("it's a string")
+ case <-cc: // 空的,还没作好通讯的准备
+ fmt.Println("didn't happen.")
+ }
+ // 上面c或者cs的值被取到,其中一个goroutine结束,另外一个一直阻塞。
+
+ learnWebProgramming() // Go很适合web编程,我知道你也想学!
+}
+
+// http包中的一个简单的函数就可以开启web服务器。
+func learnWebProgramming() {
+ // ListenAndServe第一个参数指定了监听端口,第二个参数是一个接口,特定是http.Handler。
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // 不要无视错误。
+}
+
+// 使pair实现http.Handler接口的ServeHTTP方法。
+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/)。
+在那里你可以学习入门教程,通过浏览器交互式地学习,而且可以读到很多东西。
+
+强烈推荐阅读语言定义部分,很简单而且很简洁!(as language definitions go these days.)
+
+学习Go还要阅读Go标准库的源代码,全部文档化了,可读性非常好,可以学到go,go style和go idioms。在文档中点击函数名,源代码就出来了!
diff --git a/zh-cn/haskell-cn.html.markdown b/zh-cn/haskell-cn.html.markdown
index 8d51f144..8d51f144 100755..100644
--- a/zh-cn/haskell-cn.html.markdown
+++ b/zh-cn/haskell-cn.html.markdown
diff --git a/zh-cn/java-cn.html.markdown b/zh-cn/java-cn.html.markdown
index 9422ac2f..f7d319e6 100755..100644
--- a/zh-cn/java-cn.html.markdown
+++ b/zh-cn/java-cn.html.markdown
@@ -322,7 +322,7 @@ class Bicycle {
// 方法声明的语法:
// <作用域> <返回值类型> <方法名>(<参数列表>)
public int getCadence() {
- retur450635425n cadence;
+ return cadence;
}
// void返450635425回值函数没有返回值
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index 89fc256e..86ad1d07 100755..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/lua-cn.html.markdown b/zh-cn/lua-cn.html.markdown
new file mode 100644
index 00000000..95a94c76
--- /dev/null
+++ b/zh-cn/lua-cn.html.markdown
@@ -0,0 +1,413 @@
+---
+language: lua
+lang: zh-cn
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
+ - ["Rob Hoelz", "http://hoelz.ro"]
+ - ["Jakukyo Friel", "http://weakish.github.io"]
+ - ["Craig Roddin", "craig.roddin@gmail.com"]
+ - ["Amr Tamimi", "https://amrtamimi.com"]
+translators:
+ - ["Jakukyo Friel", "http://weakish.github.io"]
+---
+
+```lua
+-- 单行注释以两个连字符开头
+
+--[[
+ 多行注释
+--]]
+
+----------------------------------------------------
+-- 1. 变量和流程控制
+----------------------------------------------------
+
+num = 42 -- 所有的数字都是双精度浮点型。
+-- 别害怕,64位的双精度浮点型数字中有52位用于
+-- 保存精确的整型值; 对于52位以内的整型值,
+-- 不用担心精度问题。
+
+s = 'walternate' -- 和Python一样,字符串不可变。
+t = "也可以用双引号"
+u = [[ 多行的字符串
+ 以两个方括号
+ 开始和结尾。]]
+t = nil -- 撤销t的定义; Lua 支持垃圾回收。
+
+-- 块使用do/end之类的关键字标识:
+while num < 50 do
+ num = num + 1 -- 不支持 ++ 或 += 运算符。
+end
+
+-- If语句:
+if num > 40 then
+ print('over 40')
+elseif s ~= 'walternate' then -- ~= 表示不等于。
+ -- 像Python一样,用 == 检查是否相等 ;字符串同样适用。
+ io.write('not over 40\n') -- 默认标准输出。
+else
+ -- 默认全局变量。
+ thisIsGlobal = 5 -- 通常使用驼峰。
+
+ -- 如何定义局部变量:
+ local line = io.read() -- 读取标准输入的下一行。
+
+ -- ..操作符用于连接字符串:
+ print('Winter is coming, ' .. line)
+end
+
+-- 未定义的变量返回nil。
+-- 这不是错误:
+foo = anUnknownVariable -- 现在 foo = nil.
+
+aBoolValue = false
+
+--只有nil和false为假; 0和 ''都均为真!
+if not aBoolValue then print('twas false') end
+
+-- 'or'和 'and'短路
+-- 类似于C/js里的 a?b:c 操作符:
+ans = aBoolValue and 'yes' or 'no' --> 'no'
+
+karlSum = 0
+for i = 1, 100 do -- 范围包含两端
+ karlSum = karlSum + i
+end
+
+-- 使用 "100, 1, -1" 表示递减的范围:
+fredSum = 0
+for j = 100, 1, -1 do fredSum = fredSum + j end
+
+-- 通常,范围表达式为begin, end[, step].
+
+-- 循环的另一种结构:
+repeat
+ print('the way of the future')
+ num = num - 1
+until num == 0
+
+----------------------------------------------------
+-- 2. 函数。
+----------------------------------------------------
+
+function fib(n)
+ if n < 2 then return 1 end
+ return fib(n - 2) + fib(n - 1)
+end
+
+-- 支持闭包及匿名函数:
+function adder(x)
+ -- 调用adder时,会创建返回的函数,
+ -- 并且会记住x的值:
+ return function (y) return x + y end
+end
+a1 = adder(9)
+a2 = adder(36)
+print(a1(16)) --> 25
+print(a2(64)) --> 100
+
+-- 返回值、函数调用和赋值都可以
+-- 使用长度不匹配的list。
+-- 不匹配的接收方会被赋值nil;
+-- 不匹配的发送方会被丢弃。
+
+x, y, z = 1, 2, 3, 4
+-- x = 1、y = 2、z = 3, 而 4 会被丢弃。
+
+function bar(a, b, c)
+ print(a, b, c)
+ return 4, 8, 15, 16, 23, 42
+end
+
+x, y = bar('zaphod') --> 打印 "zaphod nil nil"
+-- 现在 x = 4, y = 8, 而值15..42被丢弃。
+
+-- 函数是一等公民,可以是局部的,也可以是全局的。
+-- 以下表达式等价:
+function f(x) return x * x end
+f = function (x) return x * x end
+
+-- 这些也是等价的:
+local function g(x) return math.sin(x) end
+local g; g = function (x) return math.sin(x) end
+-- 'local g'使得g可以自引用。
+
+-- 顺便提下,三角函数以弧度为单位。
+
+-- 用一个字符串参数调用函数,可以省略括号:
+print 'hello' --可以工作。
+
+-- 调用函数时,如果只有一个table参数,
+-- 同样可以省略括号(table详情见下):
+print {} -- 一样可以工作。
+
+----------------------------------------------------
+-- 3. Table。
+----------------------------------------------------
+
+-- Table = Lua唯一的组合数据结构;
+-- 它们是关联数组。
+-- 类似于PHP的数组或者js的对象,
+-- 它们是哈希表或者字典,也可以当初列表使用。
+
+-- 按字典/map的方式使用Table:
+
+-- Dict字面量默认使用字符串类型的key:
+t = {key1 = 'value1', key2 = false}
+
+-- 字符串key可以使用类似js的点标记:
+print(t.key1) -- 打印 'value1'.
+t.newKey = {} -- 添加新的键值对。
+t.key2 = nil -- 从table删除 key2。
+
+-- 使用任何非nil的值作为key:
+u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
+print(u[6.28]) -- 打印 "tau"
+
+-- 数字和字符串的key按值匹配的
+-- table按id匹配。
+a = u['@!#'] -- 现在 a = 'qbert'.
+b = u[{}] -- 我们或许期待的是 1729, 但是得到的是nil:
+-- b = nil ,因为没有找到。
+-- 之所以没找到,是因为我们用的key与保存数据时用的不是同
+-- 一个对象。
+-- 所以字符串和数字是移植性更好的key。
+
+-- 只需要一个table参数的函数调用不需要括号:
+function h(x) print(x.key1) end
+h{key1 = 'Sonmi~451'} -- 打印'Sonmi~451'.
+
+for key, val in pairs(u) do -- 遍历Table
+ print(key, val)
+end
+
+-- _G 是一个特殊的table,用于保存所有的全局变量
+print(_G['_G'] == _G) -- 打印'true'.
+
+-- 按列表/数组的方式使用:
+
+-- 列表字面量隐式添加整数键:
+v = {'value1', 'value2', 1.21, 'gigawatts'}
+for i = 1, #v do -- #v 是列表的大小
+ print(v[i]) -- 索引从 1 开始!! 太疯狂了!
+end
+-- 'list'并非真正的类型,v 其实是一个table,
+-- 只不过它用连续的整数作为key,可以像list那样去使用。
+
+----------------------------------------------------
+-- 3.1 元表(metatable) 和元方法(metamethod)。
+----------------------------------------------------
+
+-- table的元表提供了一种机制,支持类似操作符重载的行为。
+-- 稍后我们会看到元表如何支持类似js prototype的行为。
+
+f1 = {a = 1, b = 2} -- 表示一个分数 a/b.
+f2 = {a = 2, b = 3}
+
+-- 这会失败:
+-- s = f1 + f2
+
+metafraction = {}
+function metafraction.__add(f1, f2)
+ 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 -- 调用在f1的元表上的__add(f1, f2) 方法
+
+-- f1, f2 没有关于元表的key,这点和js的prototype不一样。
+-- 因此你必须用getmetatable(f1)获取元表。
+-- 元表是一个普通的table,
+-- 元表的key是普通的Lua中的key,例如__add。
+
+-- 但是下面一行代码会失败,因为s没有元表:
+-- t = s + s
+-- 下面提供的与类相似的模式可以解决这个问题:
+
+-- 元表的__index 可以重载用于查找的点操作符:
+defaultFavs = {animal = 'gru', food = 'donuts'}
+myFavs = {food = 'pizza'}
+setmetatable(myFavs, {__index = defaultFavs})
+eatenBy = myFavs.animal -- 可以工作!感谢元表
+
+-- 如果在table中直接查找key失败,会使用
+-- 元表的__index 递归地重试。
+
+-- __index的值也可以是function(tbl, key)
+-- 这样可以支持自定义查找。
+
+-- __index、__add等的值,被称为元方法。
+-- 这里是一个table元方法的清单:
+
+-- __add(a, b) for a + b
+-- __sub(a, b) for a - b
+-- __mul(a, b) for a * b
+-- __div(a, b) for a / b
+-- __mod(a, b) for a % b
+-- __pow(a, b) for a ^ b
+-- __unm(a) for -a
+-- __concat(a, b) for a .. b
+-- __len(a) for #a
+-- __eq(a, b) for a == b
+-- __lt(a, b) for a < b
+-- __le(a, b) for a <= b
+-- __index(a, b) <fn or a table> for a.b
+-- __newindex(a, b, c) for a.b = c
+-- __call(a, ...) for a(...)
+
+----------------------------------------------------
+-- 3.2 与类相似的table和继承。
+----------------------------------------------------
+
+-- Lua没有内建的类;可以通过不同的方法,利用表和元表
+-- 来实现类。
+
+-- 下面是一个例子,解释在后面:
+
+Dog = {} -- 1.
+
+function Dog:new() -- 2.
+ newObj = {sound = 'woof'} -- 3.
+ self.__index = self -- 4.
+ return setmetatable(newObj, self) -- 5.
+end
+
+function Dog:makeSound() -- 6.
+ print('I say ' .. self.sound)
+end
+
+mrDog = Dog:new() -- 7.
+mrDog:makeSound() -- 'I say woof' -- 8.
+
+-- 1. Dog看上去像一个类;其实它是一个table。
+-- 2. 函数tablename:fn(...) 等价于
+-- 函数tablename.fn(self, ...)
+-- 冒号(:)只是添加了self作为第一个参数。
+-- 阅读7 & 8条 了解self变量是如何得到其值的。
+-- 3. newObj是类Dog的一个实例。
+-- 4. self = 被继承的类。通常self = Dog,不过继承可以改变它。
+-- 如果把newObj的元表和__index都设置为self,
+-- newObj就可以得到self的函数。
+-- 5. 备忘:setmetatable返回其第一个参数。
+-- 6. 冒号(:)的作用和第2条一样,不过这里
+-- self是一个实例,而不是类
+-- 7. 等价于Dog.new(Dog),所以在new()中,self = Dog。
+-- 8. 等价于mrDog.makeSound(mrDog); self = mrDog。
+
+----------------------------------------------------
+
+-- 继承的例子:
+
+LoudDog = Dog:new() -- 1.
+
+function LoudDog:makeSound()
+ s = self.sound .. ' ' -- 2.
+ print(s .. s .. s)
+end
+
+seymour = LoudDog:new() -- 3.
+seymour:makeSound() -- 'woof woof woof' -- 4.
+
+-- 1. LoudDog获得Dog的方法和变量列表。
+-- 2. 因为new()的缘故,self拥有了一个'sound' key,参见第3条。
+-- 3. 等价于LoudDog.new(LoudDog),转换一下就是
+-- Dog.new(LoudDog),这是因为LoudDog没有'new' key,
+-- 但是它的元表中有 __index = Dog。
+-- 结果: seymour的元表是LoudDog,并且
+-- LoudDog.__index = Dog。所以有seymour.key
+-- = seymour.key, LoudDog.key, Dog.key
+-- 从其中第一个有指定key的table获取。
+-- 4. 在LoudDog可以找到'makeSound'的key;
+-- 等价于LoudDog.makeSound(seymour)。
+
+-- 如果有必要,子类也可以有new(),与基类相似:
+function LoudDog:new()
+ newObj = {}
+ -- 初始化newObj
+ self.__index = self
+ return setmetatable(newObj, self)
+end
+
+----------------------------------------------------
+-- 4. 模块
+----------------------------------------------------
+
+
+--[[ 我把这部分给注释了,这样脚本剩下的部分可以运行
+
+-- 假设文件mod.lua的内容类似这样:
+local M = {}
+
+local function sayMyName()
+ print('Hrunkner')
+end
+
+function M.sayHello()
+ print('Why hello there')
+ sayMyName()
+end
+
+return M
+
+-- 另一个文件可以使用mod.lua的功能:
+local mod = require('mod') -- 运行文件mod.lua.
+
+-- require是包含模块的标准做法。
+-- require等价于: (针对没有被缓存的情况;参见后面的内容)
+local mod = (function ()
+ <contents of mod.lua>
+end)()
+-- mod.lua被包在一个函数体中,因此mod.lua的局部变量
+-- 对外不可见。
+
+-- 下面的代码可以工作,因为在这里mod = mod.lua 中的 M:
+mod.sayHello() -- Says hello to Hrunkner.
+
+-- 这是错误的;sayMyName只在mod.lua中存在:
+mod.sayMyName() -- 错误
+
+-- require返回的值会被缓存,所以一个文件只会被运行一次,
+-- 即使它被require了多次。
+
+-- 假设mod2.lua包含代码"print('Hi!')"。
+local a = require('mod2') -- 打印Hi!
+local b = require('mod2') -- 不再打印; a=b.
+
+-- dofile与require类似,但是不缓存:
+dofile('mod2') --> Hi!
+dofile('mod2') --> Hi! (再次运行,与require不同)
+
+-- loadfile加载一个lua文件,但是并不运行它。
+f = loadfile('mod2') -- Calling f() runs mod2.lua.
+
+-- loadstring是loadfile的字符串版本。
+g = loadstring('print(343)') --返回一个函数。
+g() -- 打印343; 在此之前什么也不打印。
+
+--]]
+```
+
+## 参考
+
+
+
+为什么?我非常兴奋地学习lua, 这样我就可以使用[Löve 2D游戏引擎](http://love2d.org/)来编游戏。
+
+怎么做?我从[BlackBulletIV的面向程序员的Lua指南](http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/)入门。接着我阅读了官方的[Lua编程](http://www.lua.org/pil/contents.html)一书。
+
+lua-users.org上的[Lua简明参考](http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf)应该值得一看。
+
+本文没有涉及标准库的内容:
+
+* <a href="http://lua-users.org/wiki/StringLibraryTutorial">string library</a>
+* <a href="http://lua-users.org/wiki/TableLibraryTutorial">table library</a>
+* <a href="http://lua-users.org/wiki/MathLibraryTutorial">math library</a>
+* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a>
+* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a>
+
+使用Lua,欢乐常在!
diff --git a/zh-cn/perl-cn.html.markdown b/zh-cn/perl-cn.html.markdown
new file mode 100644
index 00000000..5b0d6179
--- /dev/null
+++ b/zh-cn/perl-cn.html.markdown
@@ -0,0 +1,152 @@
+---
+name: perl
+category: language
+language: perl
+filename: learnperl-cn.pl
+contributors:
+ - ["Korjavin Ivan", "http://github.com/korjavin"]
+translators:
+ - ["Yadong Wen", "https://github.com/yadongwen"]
+lang: zh-cn
+---
+
+Perl 5是一个功能强大、特性齐全的编程语言,有25年的历史。
+
+Perl 5可以在包括便携式设备和大型机的超过100个平台上运行,既适用于快速原型构建,也适用于大型项目开发。
+
+```perl
+# 单行注释以#号开头
+
+
+#### Perl的变量类型
+
+# 变量以$号开头。
+# 合法变量名以英文字母或者下划线起始,
+# 后接任意数目的字母、数字或下划线。
+
+### Perl有三种主要的变量类型:标量、数组和哈希。
+
+## 标量
+# 标量类型代表单个值:
+my $animal = "camel";
+my $answer = 42;
+
+# 标量类型值可以是字符串、整型或浮点类型,Perl会根据需要自动进行类型转换。
+
+## 数组
+# 数组类型代表一列值:
+my @animals = ("camel", "llama", "owl");
+my @numbers = (23, 42, 69);
+my @mixed = ("camel", 42, 1.23);
+
+
+
+## 哈希
+# 哈希类型代表一个键/值对的集合:
+
+my %fruit_color = ("apple", "red", "banana", "yellow");
+
+# 可以使用空格和“=>”操作符更清晰的定义哈希:
+
+my %fruit_color = (
+ apple => "red",
+ banana => "yellow",
+ );
+# perldata中有标量、数组和哈希更详细的介绍。 (perldoc perldata).
+
+# 可以用引用构建更复杂的数据类型,比如嵌套的列表和哈希。
+
+#### 逻辑和循环结构
+
+# Perl有大多数常见的逻辑和循环控制结构
+
+if ( $var ) {
+ ...
+} elsif ( $var eq 'bar' ) {
+ ...
+} else {
+ ...
+}
+
+unless ( condition ) {
+ ...
+ }
+# 上面这个比"if (!condition)"更可读。
+
+# 有Perl特色的后置逻辑结构
+print "Yow!" if $zippy;
+print "We have no bananas" unless $bananas;
+
+# while
+ while ( condition ) {
+ ...
+ }
+
+
+# for和foreach
+for ($i = 0; $i <= $max; $i++) {
+ ...
+ }
+
+foreach (@array) {
+ print "This element is $_\n";
+ }
+
+
+#### 正则表达式
+
+# Perl对正则表达式有深入广泛的支持,perlrequick和perlretut等文档有详细介绍。简单来说:
+
+# 简单匹配
+if (/foo/) { ... } # 如果 $_ 包含"foo"逻辑为真
+if ($a =~ /foo/) { ... } # 如果 $a 包含"foo"逻辑为真
+
+# 简单替换
+
+$a =~ s/foo/bar/; # 将$a中的foo替换为bar
+$a =~ s/foo/bar/g; # 将$a中所有的foo替换为bar
+
+
+#### 文件和输入输出
+
+# 可以使用“open()”函数打开文件用于输入输出。
+
+open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
+open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
+open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
+
+# 可以用"<>"操作符读取一个打开的文件句柄。 在标量语境下会读取一行,
+# 在列表环境下会将整个文件读入并将每一行赋给列表的一个元素:
+
+my $line = <$in>;
+my @lines = <$in>;
+
+#### 子程序
+
+# 写子程序很简单:
+
+sub logger {
+ my $logmessage = shift;
+ open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
+ print $logfile $logmessage;
+}
+
+# 现在可以像内置函数一样调用子程序:
+
+logger("We have a logger subroutine!");
+
+
+```
+
+#### 使用Perl模块
+
+Perl模块提供一系列特性来帮助你避免重新发明轮子,CPAN是下载模块的好地方( http://www.cpan.org/ )。Perl发行版本身也包含很多流行的模块。
+
+perlfaq有很多常见问题和相应回答,也经常有对优秀CPAN模块的推荐介绍。
+
+#### 深入阅读
+
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [www.perl.com的learn站点](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - 以及 perl 内置的: `perldoc perlintro`
diff --git a/zh-cn/php-cn.html.markdown b/zh-cn/php-cn.html.markdown
index c6ebb515..24939681 100755..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/python-cn.html.markdown b/zh-cn/python-cn.html.markdown
index 764eed54..deb94cdc 100755..100644
--- a/zh-cn/python-cn.html.markdown
+++ b/zh-cn/python-cn.html.markdown
@@ -17,6 +17,7 @@ Python 由 Guido Van Rossum 在90年代初创建。 它现在是最流行的语
如果是Python 3,请在网络上寻找其他教程
```python
+
# 单行注释
""" 多行字符串可以用
三个引号包裹,不过这也可以被当做
@@ -28,84 +29,84 @@ Python 由 Guido Van Rossum 在90年代初创建。 它现在是最流行的语
####################################################
# 数字类型
-3 #=> 3
+3 # => 3
# 简单的算数
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
# 整数的除法会自动取整
-5 / 2 #=> 2
+5 / 2 # => 2
# 要做精确的除法,我们需要引入浮点数
2.0 # 浮点数
-11.0 / 4.0 #=> 2.75 好多了
+11.0 / 4.0 # => 2.75 精确多了
# 括号具有最高优先级
-(1 + 3) * 2 #=> 8
+(1 + 3) * 2 # => 8
-# 布尔值也是原始数据类型
+# 布尔值也是基本的数据类型
True
False
-# 用not来取非
-not True #=> False
-not False #=> True
+# 用 not 来取非
+not True # => False
+not False # => True
# 相等
-1 == 1 #=> True
-2 == 1 #=> False
+1 == 1 # => True
+2 == 1 # => False
# 不等
-1 != 1 #=> False
-2 != 1 #=> True
+1 != 1 # => False
+2 != 1 # => True
# 更多的比较操作符
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
# 比较运算可以连起来写!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
-# 字符串通过"或'括起来
+# 字符串通过 " 或 ' 括起来
"This is a string."
'This is also a string.'
# 字符串通过加号拼接
-"Hello " + "world!" #=> "Hello world!"
+"Hello " + "world!" # => "Hello world!"
# 字符串可以被视为字符的列表
-"This is a string"[0] #=> 'T'
+"This is a string"[0] # => 'T'
# % 可以用来格式化字符串
"%s can be %s" % ("strings", "interpolated")
-# 也可以用format方法来格式化字符串
+# 也可以用 format 方法来格式化字符串
# 推荐使用这个方法
"{0} can be {1}".format("strings", "formatted")
# 也可以用变量名代替数字
"{name} wants to eat {food}".format(name="Bob", food="lasagna")
# None 是对象
-None #=> None
+None # => None
# 不要用相等 `==` 符号来和None进行比较
-# 要用 `is`
-"etc" is None #=> False
-None is None #=> True
+# 要用 `is`
+"etc" is None # => False
+None is None # => True
# 'is' 可以用来比较对象的相等性
# 这个操作符在比较原始数据时没多少用,但是比较对象时必不可少
-# None, 0, 和空字符串都被算作False
-# 其他的均为True
-0 == False #=> True
-"" == False #=> True
+# None, 0, 和空字符串都被算作 False
+# 其他的均为 True
+0 == False # => True
+"" == False # => True
####################################################
@@ -116,16 +117,16 @@ None is None #=> True
print "I'm Python. Nice to meet you!"
-# 给变量赋值前不需要事先生命
-some_var = 5 # 规范用小写字母和下划线来做为变量名
-some_var #=> 5
+# 给变量赋值前不需要事先声明
+some_var = 5 # 一般建议使用小写字母和下划线组合来做为变量名
+some_var # => 5
-# 访问之前为赋值的变量会抛出异常
-# 查看控制流程一节来了解异常处理
-some_other_var # 抛出命名异常
+# 访问未赋值的变量会抛出异常
+# 可以查看控制流程一节来了解如何异常处理
+some_other_var # 抛出 NameError
-# if语句可以作为表达式来使用
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# if 语句可以作为表达式来使用
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
# 列表用来保存序列
li = []
@@ -133,64 +134,64 @@ li = []
other_li = [4, 5, 6]
# 在列表末尾添加元素
-li.append(1) #li 现在是 [1]
-li.append(2) #li 现在是 [1, 2]
-li.append(4) #li 现在是 [1, 2, 4]
-li.append(3) #li 现在是 [1, 2, 4, 3]
+li.append(1) # li 现在是 [1]
+li.append(2) # li 现在是 [1, 2]
+li.append(4) # li 现在是 [1, 2, 4]
+li.append(3) # li 现在是 [1, 2, 4, 3]
# 移除列表末尾元素
-li.pop() #=> 3 and li is now [1, 2, 4]
-# 放回来
+li.pop() # => 3 li 现在是 [1, 2, 4]
+# 重新加进去
li.append(3) # li is now [1, 2, 4, 3] again.
# 像其他语言访问数组一样访问列表
-li[0] #=> 1
+li[0] # => 1
# 访问最后一个元素
-li[-1] #=> 3
+li[-1] # => 3
# 越界会抛出异常
-li[4] # 抛出越界异常
+li[4] # 抛出越界异常
# 切片语法需要用到列表的索引访问
# 可以看做数学之中左闭右开区间
-li[1:3] #=> [2, 4]
+li[1:3] # => [2, 4]
# 省略开头的元素
-li[2:] #=> [4, 3]
+li[2:] # => [4, 3]
# 省略末尾的元素
-li[:3] #=> [1, 2, 4]
+li[:3] # => [1, 2, 4]
# 删除特定元素
-del li[2] # li 现在是 [1, 2, 3]
+del li[2] # li 现在是 [1, 2, 3]
# 合并列表
-li + other_li #=> [1, 2, 3, 4, 5, 6] - 不改变这两个列表
+li + other_li # => [1, 2, 3, 4, 5, 6] - 并不会不改变这两个列表
-# 通过拼接合并列表
-li.extend(other_li) # li 是 [1, 2, 3, 4, 5, 6]
+# 通过拼接来合并列表
+li.extend(other_li) # li 是 [1, 2, 3, 4, 5, 6]
-# 用in来返回元素是否在列表中
-1 in li #=> True
+# 用 in 来返回元素是否在列表中
+1 in li # => True
# 返回列表长度
-len(li) #=> 6
+len(li) # => 6
-# 元组类似于列表,但是他是不可改变的
+# 元组类似于列表,但它是不可改变的
tup = (1, 2, 3)
-tup[0] #=> 1
+tup[0] # => 1
tup[0] = 3 # 类型错误
# 对于大多数的列表操作,也适用于元组
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
# 你可以将元组解包赋给多个变量
-a, b, c = (1, 2, 3) # a是1,b是2,c是3
-# 如果不加括号,那么会自动视为元组
+a, b, c = (1, 2, 3) # a 是 1,b 是 2,c 是 3
+# 如果不加括号,将会被自动视为元组
d, e, f = 4, 5, 6
# 现在我们可以看看交换两个数字是多么容易的事
-e, d = d, e # d是5,e是4
+e, d = d, e # d 是 5,e 是 4
# 字典用来储存映射关系
@@ -199,59 +200,59 @@ empty_dict = {}
filled_dict = {"one": 1, "two": 2, "three": 3}
# 字典也用中括号访问元素
-filled_dict["one"] #=> 1
+filled_dict["one"] # => 1
# 把所有的键保存在列表中
-filled_dict.keys() #=> ["three", "two", "one"]
+filled_dict.keys() # => ["three", "two", "one"]
# 键的顺序并不是唯一的,得到的不一定是这个顺序
# 把所有的值保存在列表中
-filled_dict.values() #=> [3, 2, 1]
+filled_dict.values() # => [3, 2, 1]
# 和键的顺序相同
# 判断一个键是否存在
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# 查询一个不存在的键会抛出键异常
-filled_dict["four"] # 键异常
+# 查询一个不存在的键会抛出 KeyError
+filled_dict["four"] # KeyError
-# 用get方法来避免键异常
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# get方法支持在不存在的时候返回一个默认值
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+# 用 get 方法来避免 KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# get 方法支持在不存在的时候返回一个默认值
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
-# Setdefault是一个更安全的添加字典元素的方法
-filled_dict.setdefault("five", 5) #filled_dict["five"] 的值为 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] 的值仍然是 5
+# setdefault 是一个更安全的添加字典元素的方法
+filled_dict.setdefault("five", 5) # filled_dict["five"] 的值为 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] 的值仍然是 5
# 集合储存无顺序的元素
empty_set = set()
-# 出事话一个集合
-some_set = set([1,2,2,3,4]) # filled_set 现在是 set([1, 2, 3, 4])
+# 初始化一个集合
+some_set = set([1, 2, 2, 3, 4]) # some_set 现在是 set([1, 2, 3, 4])
# Python 2.7 之后,大括号可以用来表示集合
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
-# 为集合添加元素
-filled_set.add(5) # filled_set 现在是 {1, 2, 3, 4, 5}
+# 向集合添加元素
+filled_set.add(5) # filled_set 现在是 {1, 2, 3, 4, 5}
-# 用&来实现集合的交
+# 用 & 来计算集合的交
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
-# 用|来实现集合的并
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+# 用 | 来计算集合的并
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-# 用-来实现集合的差
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+# 用 - 来计算集合的差
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-# 用in来判断元素是否存在于集合中
-2 in filled_set #=> True
-10 in filled_set #=> False
+# 用 in 来判断元素是否存在于集合中
+2 in filled_set # => True
+10 in filled_set # => False
####################################################
@@ -261,13 +262,13 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
# 新建一个变量
some_var = 5
-# 这是个if语句,在python中缩进是很重要的。
-# 会输出 "some var is smaller than 10"
+# 这是个 if 语句,在 python 中缩进是很重要的。
+# 下面的代码片段将会输出 "some var is smaller than 10"
if some_var > 10:
print "some_var is totally bigger than 10."
elif some_var < 10: # 这个 elif 语句是不必须的
print "some_var is smaller than 10."
-else: # 也不是必须的
+else: # 这个 else 也不是必须的
print "some_var is indeed 10."
@@ -281,7 +282,7 @@ else: # 也不是必须的
for animal in ["dog", "cat", "mouse"]:
# 你可以用 % 来格式化字符串
print "%s is a mammal" % animal
-
+
"""
`range(number)` 返回从0到给定数字的列表
输出:
@@ -294,7 +295,7 @@ for i in range(4):
print i
"""
-While循环
+while 循环
输出:
0
1
@@ -304,29 +305,29 @@ While循环
x = 0
while x < 4:
print x
- x += 1 # Shorthand for x = x + 1
+ x += 1 # x = x + 1 的简写
-# 用 try/except块来处理异常
+# 用 try/except 块来处理异常
# Python 2.6 及以上适用:
try:
- # 用raise来抛出异常
+ # 用 raise 来抛出异常
raise IndexError("This is an index error")
except IndexError as e:
- pass # Pass就是什么都不做,不过通常这里会做一些恢复工作
+ pass # pass 就是什么都不做,不过通常这里会做一些恢复工作
####################################################
## 4. 函数
####################################################
-# 用def来新建函数
+# 用 def 来新建函数
def add(x, y):
print "x is %s and y is %s" % (x, y)
- return x + y # Return values with a return statement
+ return x + y # 通过 return 来返回值
# 调用带参数的函数
-add(5, 6) #=> 输出 "x is 5 and y is 6" 返回 11
+add(5, 6) # => 输出 "x is 5 and y is 6" 返回 11
# 通过关键字赋值来调用函数
add(y=6, x=5) # 顺序是无所谓的
@@ -335,7 +336,7 @@ add(y=6, x=5) # 顺序是无所谓的
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1,2,3)
# 我们也可以定义接受多个变量的函数,这些变量是按照关键字排列的
@@ -343,7 +344,7 @@ def keyword_args(**kwargs):
return kwargs
# 实际效果:
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# 你也可以同时将一个函数定义成两种形式
def all_the_args(*args, **kwargs):
@@ -355,38 +356,38 @@ all_the_args(1, 2, a=3, b=4) prints:
{"a": 3, "b": 4}
"""
-# 当调用函数的时候,我们也可以和之前所做的相反,把元组和字典展开为参数
+# 当调用函数的时候,我们也可以进行相反的操作,把元组和字典展开为参数
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # equivalent to foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # 等价于 foo(1, 2, 3, 4)
+all_the_args(**kwargs) # 等价于 foo(a=3, b=4)
+all_the_args(*args, **kwargs) # 等价于 foo(1, 2, 3, 4, a=3, b=4)
-# Python 有一等函数:
+# 函数在 python 中是一等公民
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
# 匿名函数
-(lambda x: x > 2)(3) #=> True
+(lambda x: x > 2)(3) # => True
# 内置高阶函数
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# 可以用列表方法来对高阶函数进行更巧妙的引用
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. 类
####################################################
-# 我们新建的类是从object类中继承的
+# 我们新建的类是从 object 类中继承的
class Human(object):
# 类属性,由所有类的对象共享
@@ -397,9 +398,9 @@ class Human(object):
# 将参数赋给对象成员属性
self.name = name
- # 成员方法,参数要有self
+ # 成员方法,参数要有 self
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "%s: %s" % (self.name, msg)
# 类方法由所有类的对象共享
# 这类方法在调用时,会把类本身传给第一个参数
@@ -421,15 +422,15 @@ j = Human("Joel")
print j.say("hello") # 输出 "Joel: hello"
# 访问类的方法
-i.get_species() #=> "H. sapiens"
+i.get_species() # => "H. sapiens"
# 改变共享属性
Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
# 访问静态变量
-Human.grunt() #=> "*grunt*"
+Human.grunt() # => "*grunt*"
####################################################
@@ -438,12 +439,12 @@ Human.grunt() #=> "*grunt*"
# 我们可以导入其他模块
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) # => 4
-# 我们也可以从一个模块中特定的函数
+# 我们也可以从一个模块中导入特定的函数
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print ceil(3.7) # => 4.0
+print floor(3.7) # => 3.0
# 从模块中导入所有的函数
# 警告:不推荐使用
@@ -451,13 +452,13 @@ from math import *
# 简写模块名
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
# Python的模块其实只是普通的python文件
# 你也可以创建自己的模块,并且导入它们
# 模块的名字就和文件的名字相同
-# 以可以通过下面的信息找找要成为模块需要什么属性或方法
+# 也可以通过下面的方法查看模块中有什么属性和方法
import math
dir(math)
diff --git a/zh-cn/r-cn.html.markdown b/zh-cn/r-cn.html.markdown
new file mode 100644
index 00000000..19c5f25d
--- /dev/null
+++ b/zh-cn/r-cn.html.markdown
@@ -0,0 +1,541 @@
+---
+language: R
+contributors:
+ - ["e99n09", "http://github.com/e99n09"]
+ - ["isomorphismes", "http://twitter.com/isomorphisms"]
+translators:
+ - ["小柒", "http://weibo.com/u/2328126220"]
+ - ["alswl", "https://github.com/alswl"]
+filename: learnr-zh.r
+lang: zh-cn
+---
+
+R 是一门统计语言。它有很多数据分析和挖掘程序包。可以用来统计、分析和制图。
+你也可以在 LaTeX 文档中运行 `R` 命令。
+
+```python
+# 评论以 # 开始
+
+# R 语言原生不支持 多行注释
+# 但是你可以像这样来多行注释
+
+# 在窗口里按回车键可以执行一条命令
+
+
+###################################################################
+# 不用懂编程就可以开始动手了
+###################################################################
+
+data() # 浏览内建的数据集
+data(rivers) # 北美主要河流的长度(数据集)
+ls() # 在工作空间中查看「河流」是否出现
+head(rivers) # 撇一眼数据集
+# 735 320 325 392 524 450
+length(rivers) # 我们测量了多少条河流?
+# 141
+summary(rivers)
+# Min. 1st Qu. Median Mean 3rd Qu. Max.
+# 135.0 310.0 425.0 591.2 680.0 3710.0
+stem(rivers) # 茎叶图(一种类似于直方图的展现形式)
+#
+# The decimal point is 2 digit(s) to the right of the |
+#
+# 0 | 4
+# 2 | 011223334555566667778888899900001111223333344455555666688888999
+# 4 | 111222333445566779001233344567
+# 6 | 000112233578012234468
+# 8 | 045790018
+# 10 | 04507
+# 12 | 1471
+# 14 | 56
+# 16 | 7
+# 18 | 9
+# 20 |
+# 22 | 25
+# 24 | 3
+# 26 |
+# 28 |
+# 30 |
+# 32 |
+# 34 |
+# 36 | 1
+
+
+stem(log(rivers)) # 查看数据集的方式既不是标准形式,也不是取log后的结果! 看起来,是钟形曲线形式的基本数据集
+
+# The decimal point is 1 digit(s) to the left of the |
+#
+# 48 | 1
+# 50 |
+# 52 | 15578
+# 54 | 44571222466689
+# 56 | 023334677000124455789
+# 58 | 00122366666999933445777
+# 60 | 122445567800133459
+# 62 | 112666799035
+# 64 | 00011334581257889
+# 66 | 003683579
+# 68 | 0019156
+# 70 | 079357
+# 72 | 89
+# 74 | 84
+# 76 | 56
+# 78 | 4
+# 80 |
+# 82 | 2
+
+
+hist(rivers, col="#333333", border="white", breaks=25) # 试试用这些参数画画 (译者注:给 river 做统计频数直方图,包含了这些参数:数据源,颜色,边框,空格)
+hist(log(rivers), col="#333333", border="white", breaks=25) #你还可以做更多式样的绘图
+
+# 还有其他一些简单的数据集可以被用来加载。R 语言包括了大量这种 data()
+data(discoveries)
+plot(discoveries, col="#333333", lwd=3, xlab="Year", main="Number of important discoveries per year")
+# 译者注:参数为(数据源,颜色,线条宽度,X 轴名称,标题)
+plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", main="Number of important discoveries per year")
+
+
+# 除了按照默认的年份排序,我们还可以排序来发现特征
+sort(discoveries)
+# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
+# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
+# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
+# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
+
+stem(discoveries, scale=2) # 译者注:茎叶图(数据,放大系数)
+#
+# The decimal point is at the |
+#
+# 0 | 000000000
+# 1 | 000000000000
+# 2 | 00000000000000000000000000
+# 3 | 00000000000000000000
+# 4 | 000000000000
+# 5 | 0000000
+# 6 | 000000
+# 7 | 0000
+# 8 | 0
+# 9 | 0
+# 10 | 0
+# 11 |
+# 12 | 0
+
+max(discoveries)
+# 12
+
+summary(discoveries)
+# Min. 1st Qu. Median Mean 3rd Qu. Max.
+# 0.0 2.0 3.0 3.1 4.0 12.0
+
+
+
+
+#基本的统计学操作也不需要任何编程知识
+
+#随机生成数据
+round(runif(7, min=.5, max=6.5))
+# 译者注:runif 产生随机数,round 四舍五入
+# 1 4 6 1 4 6 4
+
+# 你输出的结果会和我们给出的不同,除非我们设置了相同的随机种子 random.seed(31337)
+
+
+#从标准高斯函数中随机生成 9 次
+rnorm(9)
+# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
+# [7] -0.59975593 0.57629164 1.08455362
+
+
+
+
+
+
+
+
+
+#########################
+# 基础编程
+#########################
+
+# 数值
+
+#“数值”指的是双精度的浮点数
+5 # 5
+class(5) # "numeric"
+5e4 # 50000 # 用科学技术法方便的处理极大值、极小值或者可变的量级
+6.02e23 # 阿伏伽德罗常数#
+1.6e-35 # 布朗克长度
+
+# 长整数并用 L 结尾
+5L # 5
+#输出5L
+class(5L) # "integer"
+
+# 可以自己试一试?用 class() 函数获取更多信息
+# 事实上,你可以找一些文件查阅 `xyz` 以及xyz的差别
+# `xyz` 用来查看源码实现,?xyz 用来看帮助
+
+# 算法
+10 + 66 # 76
+53.2 - 4 # 49.2
+2 * 2.0 # 4
+3L / 4 # 0.75
+3 %% 2 # 1
+
+# 特殊数值类型
+class(NaN) # "numeric"
+class(Inf) # "numeric"
+class(-Inf) # "numeric" # 在以下场景中会用到 integrate( dnorm(x), 3, Inf ) -- 消除 Z 轴数据
+
+# 但要注意,NaN 并不是唯一的特殊数值类型……
+class(NA) # 看上面
+class(NULL) # NULL
+
+
+# 简单列表
+c(6, 8, 7, 5, 3, 0, 9) # 6 8 7 5 3 0 9
+c('alef', 'bet', 'gimmel', 'dalet', 'he')
+c('Z', 'o', 'r', 'o') == "Zoro" # FALSE FALSE FALSE FALSE
+
+# 一些优雅的内置功能
+5:15 # 5 6 7 8 9 10 11 12 13 14 15
+
+seq(from=0, to=31337, by=1337)
+# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
+# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
+
+letters
+# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
+# [20] "t" "u" "v" "w" "x" "y" "z"
+
+month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
+
+
+# Access the n'th element of a list with list.name[n] or sometimes list.name[[n]]
+# 使用 list.name[n] 来访问第 n 个列表元素,有时候需要使用 list.name[[n]]
+letters[18] # "r"
+LETTERS[13] # "M"
+month.name[9] # "September"
+c(6, 8, 7, 5, 3, 0, 9)[3] # 7
+
+
+
+# 字符串
+
+# 字符串和字符在 R 语言中没有区别
+"Horatio" # "Horatio"
+class("Horatio") # "character"
+substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
+gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
+
+
+
+# 逻辑值
+
+# 布尔值
+class(TRUE) # "logical"
+class(FALSE) # "logical"
+# 和我们预想的一样
+TRUE == TRUE # TRUE
+TRUE == FALSE # FALSE
+FALSE != FALSE # FALSE
+FALSE != TRUE # TRUE
+# 缺失数据(NA)也是逻辑值
+class(NA) # "logical"
+#定义NA为逻辑型
+
+
+
+# 因子
+# 因子是为数据分类排序设计的(像是排序小朋友们的年级或性别)
+levels(factor(c("female", "male", "male", "female", "NA", "female"))) # "female" "male" "NA"
+
+factor(c("female", "female", "male", "NA", "female"))
+# female female male NA female
+# Levels: female male NA
+
+data(infert) # 自然以及引产导致的不育症
+levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
+
+
+
+# 变量
+
+# 有许多种方式用来赋值
+x = 5 # 这样可以
+y <- "1" # 更推荐这样
+TRUE -> z # 这样可行,但是很怪
+
+#我们还可以使用强制转型
+as.numeric(y) # 1
+as.character(x) # "5"
+
+# 循环
+
+# for 循环语句
+for (i in 1:4) {
+ print(i)
+}
+
+# while 循环
+a <- 10
+while (a > 4) {
+ cat(a, "...", sep = "")
+ a <- a - 1
+}
+
+# 记住,在 R 语言中 for / while 循环都很慢
+# 建议使用 apply()(我们一会介绍)来错做一串数据(比如一列或者一行数据)
+
+# IF/ELSE
+
+# 再来看这些优雅的标准
+if (4 > 3) {
+ print("Huzzah! It worked!")
+} else {
+ print("Noooo! This is blatantly illogical!")
+}
+
+# =>
+# [1] "Huzzah! It worked!"
+
+# 函数
+
+# 定义如下
+jiggle <- function(x) {
+ x + rnorm(x, sd=.1) #add in a bit of (controlled) noise
+ return(x)
+}
+
+# 和其他 R 语言函数一样调用
+jiggle(5) # 5±ε. 使用 set.seed(2716057) 后, jiggle(5)==5.005043
+
+#########################
+# 数据容器:vectors, matrices, data frames, and arrays
+#########################
+
+# 单维度
+# 你可以将目前我们学习到的任何类型矢量化,只要它们拥有相同的类型
+vec <- c(8, 9, 10, 11)
+vec # 8 9 10 11
+# 矢量的类型是这一组数据元素的类型
+class(vec) # "numeric"
+# If you vectorize items of different classes, weird coercions happen
+#如果你强制的将不同类型数值矢量化,会出现特殊值
+c(TRUE, 4) # 1 4
+c("dog", TRUE, 4) # "dog" "TRUE" "4"
+
+#我们这样来取内部数据,(R 的下标索引顺序 1 开始)
+vec[1] # 8
+# 我们可以根据条件查找特定数据
+which(vec %% 2 == 0) # 1 3
+# 抓取矢量中第一个和最后一个字符
+head(vec, 1) # 8
+tail(vec, 1) # 11
+#如果下标溢出或不存会得到 NA
+vec[6] # NA
+# 你可以使用 length() 获取矢量的长度
+length(vec) # 4
+
+# 你可以直接操作矢量或者矢量的子集
+vec * 4 # 16 20 24 28
+vec[2:3] * 5 # 25 30
+# 这里有许多内置的函数,来表现向量
+mean(vec) # 9.5
+var(vec) # 1.666667
+sd(vec) # 1.290994
+max(vec) # 11
+min(vec) # 8
+sum(vec) # 38
+
+# 二维(相同元素类型)
+
+#你可以为同样类型的变量建立矩阵
+mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
+mat
+# =>
+# [,1] [,2]
+# [1,] 1 4
+# [2,] 2 5
+# [3,] 3 6
+# 和 vector 不一样的是,一个矩阵的类型真的是 「matrix」,而不是内部元素的类型
+class(mat) # => "matrix"
+# 访问第一行的字符
+mat[1,] # 1 4
+# 操作第一行数据
+3 * mat[,1] # 3 6 9
+# 访问一个特定数据
+mat[3,2] # 6
+# 转置整个矩阵(译者注:变成 2 行 3 列)
+t(mat)
+# =>
+# [,1] [,2] [,3]
+# [1,] 1 2 3
+# [2,] 4 5 6
+
+# 使用 cbind() 函数把两个矩阵按列合并,形成新的矩阵
+mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog"))
+mat2
+# =>
+# [,1] [,2]
+# [1,] "1" "dog"
+# [2,] "2" "cat"
+# [3,] "3" "bird"
+# [4,] "4" "dog"
+class(mat2) # matrix
+# Again, note what happened!
+# 注意
+# 因为矩阵内部元素必须包含同样的类型
+# 所以现在每一个元素都转化成字符串
+c(class(mat2[,1]), class(mat2[,2]))
+
+# 按行合并两个向量,建立新的矩阵
+mat3 <- rbind(c(1,2,4,5), c(6,7,0,4))
+mat3
+# =>
+# [,1] [,2] [,3] [,4]
+# [1,] 1 2 4 5
+# [2,] 6 7 0 4
+# 哈哈,数据类型都一样的,没有发生强制转换,生活真美好
+
+# 二维(不同的元素类型)
+
+# 利用 data frame 可以将不同类型数据放在一起
+dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog"))
+names(dat) <- c("number", "species") # 给数据列命名
+class(dat) # "data.frame"
+dat
+# =>
+# number species
+# 1 5 dog
+# 2 2 cat
+# 3 1 bird
+# 4 4 dog
+class(dat$number) # "numeric"
+class(dat[,2]) # "factor"
+# data.frame() 会将字符向量转换为 factor 向量
+
+# 有很多精妙的方法来获取 data frame 的子数据集
+dat$number # 5 2 1 4
+dat[,1] # 5 2 1 4
+dat[,"number"] # 5 2 1 4
+
+# 多维(相同元素类型)
+
+# 使用 arry 创造一个 n 维的表格
+# You can make a two-dimensional table (sort of like a matrix)
+# 你可以建立一个 2 维表格(有点像矩阵)
+array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4))
+# =>
+# [,1] [,2] [,3] [,4]
+# [1,] 1 4 8 3
+# [2,] 2 5 9 6
+#你也可以利用数组建立一个三维的矩阵
+array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2))
+# =>
+# , , 1
+#
+# [,1] [,2]
+# [1,] 2 8
+# [2,] 300 9
+# [3,] 4 0
+#
+# , , 2
+#
+# [,1] [,2]
+# [1,] 5 66
+# [2,] 60 7
+# [3,] 0 847
+
+#列表(多维的,不同类型的)
+
+# R语言有列表的形式
+list1 <- list(time = 1:40)
+list1$price = c(rnorm(40,.5*list1$time,4)) # 随机
+list1
+
+# You can get items in the list like so
+# 你可以这样获得列表的元素
+list1$time
+# You can subset list items like vectors
+# 你也可以和矢量一样获取他们的子集
+list1$price[4]
+
+#########################
+# apply()函数家族
+#########################
+
+# 还记得 mat 么?
+mat
+# =>
+# [,1] [,2]
+# [1,] 1 4
+# [2,] 2 5
+# [3,] 3 6
+# Use apply(X, MARGIN, FUN) to apply function FUN to a matrix X
+# 使用(X, MARGIN, FUN)将函数 FUN 应用到矩阵 X 的行 (MAR = 1) 或者 列 (MAR = 2)
+# That is, R does FUN to each row (or column) of X, much faster than a
+# R 在 X 的每一行/列使用 FUN,比循环要快很多
+apply(mat, MAR = 2, myFunc)
+# =>
+# [,1] [,2]
+# [1,] 3 15
+# [2,] 7 19
+# [3,] 11 23
+# 还有其他家族函数 ?lapply, ?sapply
+
+# 不要被吓到,虽然许多人在此都被搞混
+# plyr 程序包的作用是用来改进 apply() 函数家族
+
+install.packages("plyr")
+require(plyr)
+?plyr
+
+#########################
+# 载入数据
+#########################
+
+# "pets.csv" 是网上的一个文本
+pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
+pets
+head(pets, 2) # 前两行
+tail(pets, 1) # 最后一行
+
+# 以 .csv 格式来保存数据集或者矩阵
+write.csv(pets, "pets2.csv") # 保存到新的文件 pets2.csv
+# set working directory with setwd(), look it up with getwd()
+# 使用 setwd() 改变工作目录,使用 getwd() 查看当前工作目录
+
+# 尝试使用 ?read.csv 和 ?write.csv 来查看更多信息
+
+#########################
+# 画图
+#########################
+
+# 散点图
+plot(list1$time, list1$price, main = "fake data") # 译者注:横轴 list1$time,纵轴 wlist1$price,标题 fake data
+# 回归图
+linearModel <- lm(price ~ time, data = list1) # 译者注:线性模型,数据集为list1,以价格对时间做相关分析模型
+linearModel # 拟合结果
+# 将拟合结果展示在图上,颜色设为红色
+abline(linearModel, col = "red")
+# 也可以获取各种各样漂亮的分析图
+plot(linearModel)
+
+# 直方图
+hist(rpois(n = 10000, lambda = 5), col = "thistle") # 译者注:统计频数直方图
+
+# 柱状图
+barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
+
+# 可以尝试着使用 ggplot2 程序包来美化图片
+install.packages("ggplot2")
+require(ggplot2)
+?ggplot2
+
+```
+
+## 获得 R
+
+* 从 [http://www.r-project.org/](http://www.r-project.org/) 获得安装包和图形化界面
+* [RStudio](http://www.rstudio.com/ide/) 是另一个图形化界面
diff --git a/zh-cn/racket-cn.html.markdown b/zh-cn/racket-cn.html.markdown
new file mode 100644
index 00000000..8ef3671f
--- /dev/null
+++ b/zh-cn/racket-cn.html.markdown
@@ -0,0 +1,608 @@
+---
+
+language: racket
+lang: zh-cn
+filename: learnracket-zh.rkt
+contributors:
+ - ["th3rac25", "https://github.com/voila"]
+ - ["Eli Barzilay", "https://github.com/elibarzilay"]
+ - ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
+translators:
+ - ["lyuehh", "https://github.com/lyuehh"]
+---
+
+Racket是Lisp/Scheme家族中的一个通用的,多范式的编程语言。
+非常期待您的反馈!你可以通过[@th3rac25](http://twitter.com/th3rac25)或以用户名为 th3rac25 的Google邮箱服务和我取得联系
+
+```racket
+#lang racket ; 声明我们使用的语言
+
+;;; 注释
+
+;; 单行注释以分号开始
+
+#| 块注释
+ 可以横跨很多行而且...
+ #|
+ 可以嵌套
+ |#
+|#
+
+;; S表达式注释忽略剩下的表达式
+;; 在调试的时候会非常有用
+#; (被忽略的表达式)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. 原始数据类型和操作符
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; 数字
+9999999999999999999999 ; 整数
+#b111 ; 二进制数字 => 7
+#o111 ; 八进制数字 => 73
+#x111 ; 十六进制数字 => 273
+3.14 ; 实数
+6.02e+23
+1/2 ; 有理数
+1+2i ; 复数
+
+;; 函数调用写作(f x y z ...)
+;; 在这里 f 是一个函数, x, y, z, ... 是参数
+;; 如果你想创建一个列表数据的字面量, 使用 ' 来阻止它们
+;; 被求值
+'(+ 1 2) ; => (+ 1 2)
+;; 接下来,是一些数学运算
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(quotient 5 2) ; => 2
+(remainder 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(exact->inexact 1/3) ; => 0.3333333333333333
+(+ 1+2i 2-3i) ; => 3-1i
+
+;;; 布尔类型
+#t ; 为真
+#f ; 为假,#f 之外的任何值都是真
+(not #t) ; => #f
+(and 0 #f (error "doesn't get here")) ; => #f
+(or #f 0 (error "doesn't get here")) ; => 0
+
+;;; 字符
+#\A ; => #\A
+#\λ ; => #\λ
+#\u03BB ; => #\λ
+
+;;; 字符串是字符组成的定长数组
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; \是转义字符
+"Foo\tbar\41\x21\u0021\a\r\n" ; 包含C语言的转义字符,和Unicode
+"λx:(μα.α→α).xx" ; 字符串可以包含Unicode字符
+
+;; 字符串可以相加
+(string-append "Hello " "world!") ; => "Hello world!"
+
+;; 一个字符串可以看做是一个包含字符的列表
+(string-ref "Apple" 0) ; => #\A
+
+;; format 可以用来格式化字符串
+(format "~a can be ~a" "strings" "formatted")
+
+;; 打印字符串非常简单
+(printf "I'm Racket. Nice to meet you!\n")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. 变量
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 你可以使用 define 定义一个变量
+;; 变量的名字可以使用任何字符除了: ()[]{}",'`;#|\
+(define some-var 5)
+some-var ; => 5
+
+;; 你也可以使用Unicode字符
+(define ⊆ subset?)
+(⊆ (set 3 2) (set 1 2 3)) ; => #t
+
+;; 访问未赋值的变量会引发一个异常
+; x ; => x: undefined ...
+
+;; 本地绑定: `me' 被绑定到 "Bob",并且只在 let 中生效
+(let ([me "Bob"])
+ "Alice"
+ me) ; => "Bob"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. 结构和集合
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 结构体
+(struct dog (name breed age))
+(define my-pet
+ (dog "lassie" "collie" 5))
+my-pet ; => #<dog>
+(dog? my-pet) ; => #t
+(dog-name my-pet) ; => "lassie"
+
+;;; 对 (不可变的)
+;; `cons' 返回对, `car' 和 `cdr' 从对中提取第1个
+;; 和第2个元素
+(cons 1 2) ; => '(1 . 2)
+(car (cons 1 2)) ; => 1
+(cdr (cons 1 2)) ; => 2
+
+;;; 列表
+
+;; 列表由链表构成, 由 `cons' 的结果
+;; 和一个 `null' (或者 '()) 构成,后者标记了这个列表的结束
+(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
+;; `list' 给列表提供了一个非常方便的可变参数的生成器
+(list 1 2 3) ; => '(1 2 3)
+;; 一个单引号也可以用来表示一个列表字面量
+'(1 2 3) ; => '(1 2 3)
+
+;; 仍然可以使用 `cons' 在列表的开始处添加一项
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; `append' 函数可以将两个列表合并
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; 列表是非常基础的类型,所以有*很多*操作列表的方法
+;; 下面是一些例子:
+(map add1 '(1 2 3)) ; => '(2 3 4)
+(map + '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(filter even? '(1 2 3 4)) ; => '(2 4)
+(count even? '(1 2 3 4)) ; => 2
+(take '(1 2 3 4) 2) ; => '(1 2)
+(drop '(1 2 3 4) 2) ; => '(3 4)
+
+;;; 向量
+
+;; 向量是定长的数组
+#(1 2 3) ; => '#(1 2 3)
+
+;; 使用 `vector-append' 方法将2个向量合并
+(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; Set(翻译成集合也不太合适,所以不翻译了..)
+
+;; 从一个列表创建一个Set
+(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
+
+;; 使用 `set-add' 增加一个成员
+;; (函数式特性: 这里会返回一个扩展后的Set,而不是修改输入的值)
+(set-add (set 1 2 3) 4) ; => (set 1 2 3 4)
+
+;; 使用 `set-remove' 移除一个成员
+(set-remove (set 1 2 3) 1) ; => (set 2 3)
+
+;; 使用 `set-member?' 测试成员是否存在
+(set-member? (set 1 2 3) 1) ; => #t
+(set-member? (set 1 2 3) 4) ; => #f
+
+;;; 散列表
+
+;; 创建一个不变的散列表 (可变散列表的例子在下面)
+(define m (hash 'a 1 'b 2 'c 3))
+
+;; 根据键取得值
+(hash-ref m 'a) ; => 1
+
+;; 获取一个不存在的键是一个异常
+; (hash-ref m 'd) => 没有找到元素
+
+;; 你可以给不存在的键提供一个默认值
+(hash-ref m 'd 0) ; => 0
+
+;; 使用 `hash-set' 来扩展一个不可变的散列表
+;; (返回的是扩展后的散列表而不是修改它)
+(define m2 (hash-set m 'd 4))
+m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
+
+;; 记住,使用 `hash` 创建的散列表是不可变的
+m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
+
+;; 使用 `hash-remove' 移除一个键值对 (函数式特性,m并不变)
+(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. 函数
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 使用 `lambda' 创建函数
+;; 函数总是返回它最后一个表达式的值
+(lambda () "Hello World") ; => #<procedure>
+;; 也可以使用 Unicode 字符 `λ'
+(λ () "Hello World") ; => 同样的函数
+
+;; 使用括号调用一个函数,也可以直接调用一个 lambda 表达式
+((lambda () "Hello World")) ; => "Hello World"
+((λ () "Hello World")) ; => "Hello World"
+
+;; 将函数赋值为一个变量
+(define hello-world (lambda () "Hello World"))
+(hello-world) ; => "Hello World"
+
+;; 你可以使用函数定义的语法糖来简化代码
+(define (hello-world2) "Hello World")
+
+;; `()`是函数的参数列表
+(define hello
+ (lambda (name)
+ (string-append "Hello " name)))
+(hello "Steve") ; => "Hello Steve"
+;; 同样的,可以使用语法糖来定义:
+(define (hello2 name)
+ (string-append "Hello " name))
+
+;; 你也可以使用可变参数, `case-lambda'
+(define hello3
+ (case-lambda
+ [() "Hello World"]
+ [(name) (string-append "Hello " name)]))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+;; ... 或者给参数指定一个可选的默认值
+(define (hello4 [name "World"])
+ (string-append "Hello " name))
+
+;; 函数可以将多余的参数放到一个列表里
+(define (count-args . args)
+ (format "You passed ~a args: ~a" (length args) args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+;; ... 也可以使用不带语法糖的 `lambda' 形式:
+(define count-args2
+ (lambda args
+ (format "You passed ~a args: ~a" (length args) args)))
+
+;; 你可以混用两种用法
+(define (hello-count name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args)))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+;; ... 不带语法糖的形式:
+(define hello-count2
+ (lambda (name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args))))
+
+;; 使用关键字
+(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
+ (format "~a ~a, ~a extra args" g name (length args)))
+(hello-k) ; => "Hello World, 0 extra args"
+(hello-k 1 2 3) ; => "Hello World, 3 extra args"
+(hello-k #:greeting "Hi") ; => "Hi World, 0 extra args"
+(hello-k #:name "Finn" #:greeting "Hey") ; => "Hey Finn, 0 extra args"
+(hello-k 1 2 3 #:greeting "Hi" #:name "Finn" 4 5 6)
+ ; => "Hi Finn, 6 extra args"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. 判断是否相等
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 判断数字使用 `='
+(= 3 3.0) ; => #t
+(= 2 1) ; => #f
+
+;; 判断对象使用 `eq?'
+(eq? 3 3) ; => #t
+(eq? 3 3.0) ; => #f
+(eq? (list 3) (list 3)) ; => #f
+
+;; 判断集合使用 `equal?'
+(equal? (list 'a 'b) (list 'a 'b)) ; => #t
+(equal? (list 'a 'b) (list 'b 'a)) ; => #f
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. 控制结构
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; 条件判断
+
+(if #t ; 测试表达式
+ "this is true" ; 为真的表达式
+ "this is false") ; 为假的表达式
+; => "this is true"
+
+;; 注意, 除 `#f` 之外的所有值都认为是真
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(Groucho Zeppo)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'yep
+
+;; `cond' 会进行一系列的判断来选择一个结果
+(cond [(> 2 2) (error "wrong!")]
+ [(< 2 2) (error "wrong again!")]
+ [else 'ok]) ; => 'ok
+
+;;; 模式匹配
+
+(define (fizzbuzz? n)
+ (match (list (remainder n 3) (remainder n 5))
+ [(list 0 0) 'fizzbuzz]
+ [(list 0 _) 'fizz]
+ [(list _ 0) 'buzz]
+ [_ #f]))
+
+(fizzbuzz? 15) ; => 'fizzbuzz
+(fizzbuzz? 37) ; => #f
+
+;;; 循环
+
+;; 循环可以使用递归(尾递归)
+(define (loop i)
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i))))
+(loop 5) ; => i=5, i=6, ...
+
+;; 类似的,可以使用 `let` 定义
+(let loop ((i 0))
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i)))) ; => i=0, i=1, ...
+
+;; 看上面的例子怎么增加一个新的 `loop' 形式, 但是 Racket 已经有了一个非常
+;; 灵活的 `for' 了:
+(for ([i 10])
+ (printf "i=~a\n" i)) ; => i=0, i=1, ...
+(for ([i (in-range 5 10)])
+ (printf "i=~a\n" i)) ; => i=5, i=6, ...
+
+;;; 其他形式的迭代
+;; `for' 允许在很多数据结构中迭代:
+;; 列表, 向量, 字符串, Set, 散列表, 等...
+
+(for ([i (in-list '(l i s t))])
+ (displayln i))
+
+(for ([i (in-vector #(v e c t o r))])
+ (displayln i))
+
+(for ([i (in-string "string")])
+ (displayln i))
+
+(for ([i (in-set (set 'x 'y 'z))])
+ (displayln i))
+
+(for ([(k v) (in-hash (hash 'a 1 'b 2 'c 3 ))])
+ (printf "key:~a value:~a\n" k v))
+
+;;; 更多复杂的迭代
+
+;; 并行扫描多个序列 (遇到长度小的就停止)
+(for ([i 10] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x 1:y 2:z
+
+;; 嵌套循环
+(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z
+
+;; 带有条件判断的 `for`
+(for ([i 1000]
+ #:when (> i 5)
+ #:unless (odd? i)
+ #:break (> i 10))
+ (printf "i=~a\n" i))
+; => i=6, i=8, i=10
+
+;;; 更多的例子帮助你加深理解..
+;; 和 `for' 循环非常像 -- 收集结果
+
+(for/list ([i '(1 2 3)])
+ (add1 i)) ; => '(2 3 4)
+
+(for/list ([i '(1 2 3)] #:when (even? i))
+ i) ; => '(2)
+
+(for/list ([i 10] [j '(x y z)])
+ (list i j)) ; => '((0 x) (1 y) (2 z))
+
+(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10))
+ i) ; => '(6 8 10)
+
+(for/hash ([i '(1 2 3)])
+ (values i (number->string i)))
+; => '#hash((1 . "1") (2 . "2") (3 . "3"))
+
+;; 也有很多其他的内置方法来收集循环中的值:
+(for/sum ([i 10]) (* i i)) ; => 285
+(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000
+(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
+(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
+;; 如果需要合并计算结果, 使用 `for/fold'
+(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
+;; (这个函数可以在大部分情况下替代普通的命令式循环)
+
+;;; 异常
+
+;; 要捕获一个异常,使用 `with-handlers' 形式
+(with-handlers ([exn:fail? (lambda (exn) 999)])
+ (+ 1 "2")) ; => 999
+(with-handlers ([exn:break? (lambda (exn) "no time")])
+ (sleep 3)
+ "phew") ; => "phew", 如果你打断了它,那么结果 => "no time"
+
+;; 使用 `raise' 抛出一个异常后者其他任何值
+(with-handlers ([number? ; 捕获抛出的数字类型的值
+ identity]) ; 将它们作为普通值
+ (+ 1 (raise 2))) ; => 2
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. 可变的值
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 使用 `set!' 给一个已经存在的变量赋一个新值
+(define n 5)
+(set! n (add1 n))
+n ; => 6
+
+;; 给那些明确地需要变化的值使用 `boxes` (在其他语言里类似指针
+;; 或者引用)
+(define n* (box 5))
+(set-box! n* (add1 (unbox n*)))
+(unbox n*) ; => 6
+
+;; 很多 Racket 诗句类型是不可变的 (对,列表,等),有一些既是可变的
+;; 又是不可变的 (字符串,向量,散列表
+;; 等...)
+
+;; 使用 `vector' 或者 `make-vector' 创建一个可变的向量
+(define vec (vector 2 2 3 4))
+(define wall (make-vector 100 'bottle-of-beer))
+;; 使用 `vector-set!` 更新一项
+(vector-set! vec 0 1)
+(vector-set! wall 99 'down)
+vec ; => #(1 2 3 4)
+
+;; 创建一个空的可变散列表,然后操作它
+(define m3 (make-hash))
+(hash-set! m3 'a 1)
+(hash-set! m3 'b 2)
+(hash-set! m3 'c 3)
+(hash-ref m3 'a) ; => 1
+(hash-ref m3 'd 0) ; => 0
+(hash-remove! m3 'a)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. 模块
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 模块让你将你的代码组织为多个文件,成为可重用的模块,
+;; 在这里,我们使用嵌套在本文的整个大模块
+;; 里的子模块(从 "#lang" 这一行开始)
+
+(module cake racket/base ; 基于 racket/base 定义一个 `cake` 模块
+
+ (provide print-cake) ; 这个模块导出的函数
+
+ (define (print-cake n)
+ (show " ~a " n #\.)
+ (show " .-~a-. " n #\|)
+ (show " | ~a | " n #\space)
+ (show "---~a---" n #\-))
+
+ (define (show fmt n ch) ; 内部函数
+ (printf fmt (make-string n ch))
+ (newline)))
+
+;; 使用 `require` 从模块中得到所有 `provide` 的函数
+(require 'cake) ; 这里的 `'`表示是本地的子模块
+(print-cake 3)
+; (show "~a" 1 #\A) ; => 报错, `show' 没有被导出,不存在
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. 类和对象
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 创建一个 fish% 类(%是给类绑定用的)
+(define fish%
+ (class object%
+ (init size) ; 初始化的参数
+ (super-new) ; 父类的初始化
+ ;; 域
+ (define current-size size)
+ ;; 公共方法
+ (define/public (get-size)
+ current-size)
+ (define/public (grow amt)
+ (set! current-size (+ amt current-size)))
+ (define/public (eat other-fish)
+ (grow (send other-fish get-size)))))
+
+;; 创建一个 fish% 类的示例
+(define charlie
+ (new fish% [size 10]))
+
+;; 使用 `send' 调用一个对象的方法
+(send charlie get-size) ; => 10
+(send charlie grow 6)
+(send charlie get-size) ; => 16
+
+;; `fish%' 是一个普通的值,我们可以用它来混入
+(define (add-color c%)
+ (class c%
+ (init color)
+ (super-new)
+ (define my-color color)
+ (define/public (get-color) my-color)))
+(define colored-fish% (add-color fish%))
+(define charlie2 (new colored-fish% [size 10] [color 'red]))
+(send charlie2 get-color)
+;; 或者,不带名字
+(send (new (add-color fish%) [size 10] [color 'red]) get-color)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 9. 宏
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 宏让你扩展这门语言的语法
+
+;; 让我们定义一个while循环
+(define-syntax-rule (while condition body ...)
+ (let loop ()
+ (when condition
+ body ...
+ (loop))))
+
+(let ([i 0])
+ (while (< i 10)
+ (displayln i)
+ (set! i (add1 i))))
+
+;; 宏是安全的,你不能修改现有的变量
+(define-syntax-rule (swap! x y) ; !表示会修改
+ (let ([tmp x])
+ (set! x y)
+ (set! y tmp)))
+
+(define tmp 2)
+(define other 3)
+(swap! tmp other)
+(printf "tmp = ~a; other = ~a\n" tmp other)
+;; 变量 `tmp` 被重命名为 `tmp_1`
+;; 避免名字冲突
+;; (let ([tmp_1 tmp])
+;; (set! tmp other)
+;; (set! other tmp_1))
+
+;; 但它们仍然会导致错误代码,比如:
+(define-syntax-rule (bad-while condition body ...)
+ (when condition
+ body ...
+ (bad-while condition body ...)))
+;; 这个宏会挂掉,它产生了一个无限循环,如果你试图去使用它
+;; 编译器会进入死循环
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 10. 契约
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; 契约限制变量从模块中导入
+
+(module bank-account racket
+ (provide (contract-out
+ [deposit (-> positive? any)] ; 数量一直是正值
+ [balance (-> positive?)]))
+
+ (define amount 0)
+ (define (deposit a) (set! amount (+ amount a)))
+ (define (balance) amount)
+ )
+
+(require 'bank-account)
+(deposit 5)
+
+(balance) ; => 5
+
+;; 客户端尝试存储一个负值时会出错
+;; (deposit -5) ; => deposit: contract violation
+;; expected: positive?
+;; given: -5
+;; more details....
+```
+
+## 进一步阅读
+
+想知道更多吗? 尝试 [Getting Started with Racket](http://docs.racket-lang.org/getting-started/)
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 6530b520..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"]
---
@@ -94,7 +95,7 @@ x = y = 10 #=> 10
x #=> 10
y #=> 10
-# 按照惯例,用snake_case 作为变量名
+# 按照惯例,用 snake_case 作为变量名
snake_case = true
# 使用具有描述性的运算符
@@ -102,7 +103,8 @@ path_to_project_root = '/good/name/'
path = '/bad/name/'
# 符号(Symbols,也是对象)
-# 符号是不可变的,内部用整数类型表示的可重用的值。通常用它代替字符串来有效地表达有意义的值
+# 符号是不可变的,内部用整数类型表示的可重用的值。
+# 通常用它代替字符串来有效地表示有意义的值。
:pending.class #=> Symbol
@@ -172,7 +174,7 @@ new_hash = { defcon: 3, action: true}
new_hash.keys #=> [:defcon, :action]
# 小贴士:数组和哈希表都是可枚举的
-# 它们可以共享一些有用的方法,比如each, map, count, 和more
+# 它们可以共享一些有用的方法,比如each, map, count 等等
# 控制流
diff --git a/zh-cn/scala-cn.html.markdown b/zh-cn/scala-cn.html.markdown
index 1ce41ac6..24f73bb5 100644
--- a/zh-cn/scala-cn.html.markdown
+++ b/zh-cn/scala-cn.html.markdown
@@ -6,7 +6,6 @@ contributors:
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
translators:
- ["Peiyong Lin", ""]
-filename: learn.scala
lang: zh-cn
---
diff --git a/zh-cn/visualbasic-cn.html.markdown b/zh-cn/visualbasic-cn.html.markdown
new file mode 100644
index 00000000..95f01ed6
--- /dev/null
+++ b/zh-cn/visualbasic-cn.html.markdown
@@ -0,0 +1,274 @@
+---
+language: Visual Basic
+contributors:
+ - ["Brian Martin", "http://brianmartin.biz"]
+translators:
+ - ["Abner Chou", "http://github.com/NoahDragon"]
+lang: zh-cn
+filename: learnvisualbasic.vb-cn
+---
+
+```vb
+Module Module1
+
+ Sub Main()
+ ' 让我们先从简单的终端程序学起。
+ ' 单引号用来生成注释(注意是半角单引号,非全角单引号’)
+ ' 为了方便运行此示例代码,我写了个目录索引。
+ ' 可能你还不了解以下代码的意义,但随着教程的深入,
+ ' 你会渐渐理解其用法。
+ Console.Title = ("Learn X in Y Minutes")
+ Console.WriteLine("NAVIGATION") ' 显示目录
+ Console.WriteLine("")
+ Console.ForegroundColor = ConsoleColor.Green
+ Console.WriteLine("1. Hello World Output") ' Hello world 输出示例
+ Console.WriteLine("2. Hello World Input") ' Hello world 输入示例
+ Console.WriteLine("3. Calculating Whole Numbers") ' 求整数之和
+ Console.WriteLine("4. Calculating Decimal Numbers") ' 求小数之和
+ Console.WriteLine("5. Working Calculator") ' 计算器
+ Console.WriteLine("6. Using Do While Loops") ' 使用 Do While 循环
+ Console.WriteLine("7. Using For While Loops") ' 使用 For While 循环
+ Console.WriteLine("8. Conditional Statements") ' 条件语句
+ Console.WriteLine("9. Select A Drink") ' 选饮料
+ Console.WriteLine("50. About") ' 关于
+ Console.WriteLine("Please Choose A Number From The Above List")
+ Dim selection As String = Console.ReadLine
+ Select Case selection
+ Case "1" ' Hello world 输出示例
+ Console.Clear() ' 清空屏幕
+ HelloWorldOutput() ' 调用程序块
+ Case "2" ' Hello world 输入示例
+ Console.Clear()
+ HelloWorldInput()
+ Case "3" ' 求整数之和
+ Console.Clear()
+ CalculatingWholeNumbers()
+ Case "4" ' 求小数之和
+ Console.Clear()
+ CalculatingDecimalNumbers()
+ Case "5" ' 计算器
+ Console.Clear()
+ WorkingCalculator()
+ Case "6" ' 使用 do while 循环
+ Console.Clear()
+ UsingDoWhileLoops()
+ Case "7" ' 使用 for while 循环
+ Console.Clear()
+ UsingForLoops()
+ Case "8" ' 条件语句
+ Console.Clear()
+ ConditionalStatement()
+ Case "9" ' If/Else 条件语句
+ Console.Clear()
+ IfElseStatement() ' 选饮料
+ Case "50" ' 关于本程序和作者
+ Console.Clear()
+ Console.Title = ("Learn X in Y Minutes :: About")
+ MsgBox("This tutorial is by Brian Martin (@BrianMartinn")
+ Console.Clear()
+ Main()
+ Console.ReadLine()
+
+ End Select
+ End Sub
+
+ ' 一、对应程序目录1,下同
+
+ ' 使用 private subs 声明函数。
+ Private Sub HelloWorldOutput()
+ ' 程序名
+ Console.Title = "Hello World Ouput | Learn X in Y Minutes"
+ ' 使用 Console.Write("") 或者 Console.WriteLine("") 来输出文本到屏幕上
+ ' 对应的 Console.Read() 或 Console.Readline() 用来读取键盘输入
+ Console.WriteLine("Hello World")
+ Console.ReadLine()
+ ' Console.WriteLine()后加Console.ReadLine()是为了防止屏幕输出信息一闪而过
+ ' 类似平时常见的“单击任意键继续”的意思。
+ End Sub
+
+ ' 二
+ Private Sub HelloWorldInput()
+ Console.Title = "Hello World YourName | Learn X in Y Minutes"
+ ' 变量
+ ' 用来存储用户输入的数据
+ ' 变量声明以 Dim 开始,结尾为 As VariableType (变量类型).
+
+ ' 此教程中,我们希望知道你的姓名,并让程序记录并输出。
+ Dim username As String
+ ' 我们定义username使用字符串类型(String)来记录用户姓名。
+ Console.WriteLine("Hello, What is your name? ") ' 询问用户输入姓名
+ username = Console.ReadLine() ' 存储用户名到变量 username
+ Console.WriteLine("Hello " + username) ' 输出将是 Hello + username
+ Console.ReadLine() ' 暂停屏幕并显示以上输出
+ ' 以上程序将询问你的姓名,并和你打招呼。
+ ' 其它变量如整型(Integer)我们用整型来处理整数。
+ End Sub
+
+ ' 三
+ Private Sub CalculatingWholeNumbers()
+ Console.Title = "Calculating Whole Numbers | Learn X in Y Minutes"
+ Console.Write("First number: ") ' 输入一个整数:1,2,50,104,等等
+ Dim a As Integer = Console.ReadLine()
+ Console.Write("Second number: ") ' 输入第二个整数
+ Dim b As Integer = Console.ReadLine()
+ Dim c As Integer = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ ' 以上程序将两个整数相加
+ End Sub
+
+ ' 四
+ Private Sub CalculatingDecimalNumbers()
+ Console.Title = "Calculating with Double | Learn X in Y Minutes"
+ ' 当然,我们还需要能够处理小数。
+ ' 只需要要将整型(Integer)改为小数(Double)类型即可。
+
+ ' 输入一个小数: 1.2, 2.4, 50.1, 104.9,等等
+ Console.Write("First number: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Second number: ") ' 输入第二个数
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ ' 以上代码能实现两个小数相加
+ End Sub
+
+ ' 五
+ Private Sub WorkingCalculator()
+ Console.Title = "The Working Calculator| Learn X in Y Minutes"
+ ' 但是如果你希望有个能够处理加减乘除的计算器呢?
+ ' 只需将上面代码复制粘帖即可。
+ Console.Write("First number: ") ' 输入第一个数
+ Dim a As Double = Console.ReadLine
+ Console.Write("Second number: ") ' 输入第二个数
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ ' 通过以下代码我们可以将以上所算的加减乘除结果输出到屏幕上。
+ Console.Write(a.ToString() + " + " + b.ToString())
+ ' 我们希望答案开头能有3个空格,可以使用String.PadLeft(3)方法。
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.ReadLine()
+
+ End Sub
+
+ ' 六
+ Private Sub UsingDoWhileLoops()
+ ' 如同以上的代码一样
+ ' 这次我们将询问用户是否继续 (Yes or No?)
+ ' 我们将使用Do While循环,因为我们不知到用户是否需要使用一次以上。
+ Console.Title = "UsingDoWhileLoops | Learn X in Y Minutes"
+ Dim answer As String ' 我们使用字符串变量来存储answer(答案)
+ Do ' 循环开始
+ Console.Write("First number: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Second number: ")
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ Console.Write(a.ToString() + " + " + b.ToString())
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.ReadLine()
+ ' 询问用户是否继续,注意大小写。
+ Console.Write("Would you like to continue? (yes / no)")
+ ' 程序读入用户输入
+ answer = Console.ReadLine() ' added a bracket here
+ ' 当用户输入"yes"时,程序将跳转到Do,并再次执行
+ Loop While answer = "yes"
+
+ End Sub
+
+ ' 七
+ Private Sub UsingForLoops()
+ ' 有一些程序只需要运行一次。
+ ' 这个程序我们将实现从10倒数计数.
+
+ Console.Title = "Using For Loops | Learn X in Y Minutes"
+ ' 声明变量和Step (步长,即递减的速度,如-1,-2,-3等)。
+ For i As Integer = 10 To 0 Step -1
+ Console.WriteLine(i.ToString) ' 将计数结果输出的屏幕
+ Next i ' 计算新的i值
+ Console.WriteLine("Start")
+ Console.ReadLine()
+ End Sub
+
+ ' 八
+ Private Sub ConditionalStatement()
+ Console.Title = "Conditional Statements | Learn X in Y Minutes"
+ Dim userName As String = Console.ReadLine
+ Console.WriteLine("Hello, What is your name? ") ' 询问用户姓名
+ userName = Console.ReadLine() ' 存储用户姓名
+ If userName = "Adam" Then
+ Console.WriteLine("Hello Adam")
+ Console.WriteLine("Thanks for creating this useful site")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Hello " + userName)
+ Console.WriteLine("Have you checked out www.learnxinyminutes.com")
+ Console.ReadLine() ' 程序停止,并输出以上文本
+ End If
+ End Sub
+
+ ' 九
+ Private Sub IfElseStatement()
+ Console.Title = "If / Else Statement | Learn X in Y Minutes"
+ ' 有时候我们需要考虑多于两种情况。
+ ' 这时我们就需要使用If/ElesIf条件语句。
+ ' If语句就好似个自动售货机,当用户输入A1,A2,A3,等去选择物品时,
+ ' 所有的选择可以合并到一个If语句中
+
+ Dim selection As String = Console.ReadLine() ' 读入用户选择
+ Console.WriteLine("A1. for 7Up") ' A1 七喜
+ Console.WriteLine("A2. for Fanta") ' A2 芬达
+ Console.WriteLine("A3. for Dr. Pepper") ' A3 胡椒医生
+ Console.WriteLine("A4. for Diet Coke") ' A4 无糖可乐
+ Console.ReadLine()
+ If selection = "A1" Then
+ Console.WriteLine("7up")
+ Console.ReadLine()
+ ElseIf selection = "A2" Then
+ Console.WriteLine("fanta")
+ Console.ReadLine()
+ ElseIf selection = "A3" Then
+ Console.WriteLine("dr. pepper")
+ Console.ReadLine()
+ ElseIf selection = "A4" Then
+ Console.WriteLine("diet coke")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Please select a product") ' 请选择你需要的产品
+ Console.ReadLine()
+ End If
+
+ End Sub
+
+End Module
+
+```
+
+## 参考
+
+我(译注:原作者)在命令行下学习的VB。命令行编程使我能够更好的了解程序编译运行机制,并使学习其它语言变得容易。
+
+如果希望进一步学习VB,这里还有更深层次的 <a href="http://www.vbbootcamp.co.uk/" Title="VB教学">VB教学(英文)</a>。
+
+所有代码均通过测试。只需复制粘帖到Visual Basic中,并按F5运行即可。