summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bash.html.markdown78
-rw-r--r--c++.html.markdown151
-rw-r--r--c.html.markdown4
-rw-r--r--chapel.html.markdown1103
-rw-r--r--clojure-macros.html.markdown2
-rw-r--r--clojure.html.markdown2
-rw-r--r--common-lisp.html.markdown8
-rw-r--r--compojure.html.markdown8
-rw-r--r--de-de/yaml-de.html.markdown5
-rw-r--r--el-gr/racket-gr.html.markdown745
-rw-r--r--el-gr/scala-gr.html.markdown689
-rw-r--r--elisp.html.markdown12
-rw-r--r--elixir.html.markdown2
-rw-r--r--erlang.html.markdown105
-rw-r--r--es-es/git-es.html.markdown2
-rw-r--r--es-es/julia-es.html.markdown1268
-rw-r--r--fr-fr/erlang-fr.html.markdown327
-rw-r--r--fr-fr/go-fr.html.markdown1
-rw-r--r--fr-fr/json-fr.html.markdown62
-rw-r--r--fr-fr/lua-fr.html.markdown8
-rw-r--r--fr-fr/r-fr.html.markdown747
-rw-r--r--fr-fr/typescript-fr.html.markdown174
-rw-r--r--git.html.markdown17
-rw-r--r--go.html.markdown14
-rw-r--r--groovy.html.markdown10
-rw-r--r--haskell.html.markdown22
-rw-r--r--haxe.html.markdown23
-rw-r--r--it-it/bash-it.html.markdown275
-rw-r--r--it-it/c++-it.html.markdown720
-rw-r--r--it-it/json-it.html.markdown62
-rw-r--r--java.html.markdown202
-rw-r--r--json.html.markdown2
-rw-r--r--julia.html.markdown8
-rw-r--r--matlab.html.markdown2
-rw-r--r--nim.html.markdown20
-rw-r--r--objective-c.html.markdown2
-rw-r--r--perl.html.markdown66
-rw-r--r--perl6.html.markdown78
-rw-r--r--php.html.markdown2
-rw-r--r--pl-pl/python-pl.html.markdown637
-rw-r--r--pt-br/brainfuck-pt.html.markdown2
-rw-r--r--pt-br/git-pt.html.markdown2
-rw-r--r--pt-br/groovy-pt.html.markdown10
-rw-r--r--pt-br/xml-pt.html.markdown6
-rw-r--r--python.html.markdown71
-rw-r--r--python3.html.markdown70
-rw-r--r--red.html.markdown4
-rw-r--r--ru-ru/bash-ru.html.markdown284
-rw-r--r--ru-ru/javascript-ru.html.markdown4
-rw-r--r--ru-ru/objective-c-ru.html.markdown654
-rw-r--r--ru-ru/python3-ru.html.markdown2
-rw-r--r--ruby.html.markdown12
-rw-r--r--rust.html.markdown29
-rw-r--r--scala.html.markdown118
-rw-r--r--standard-ml.html.markdown66
-rw-r--r--swift.html.markdown57
-rw-r--r--[-rwxr-xr-x]tcl.html.markdown5
-rw-r--r--tmux.html.markdown32
-rw-r--r--tr-tr/csharp-tr.html.markdown2
-rw-r--r--tr-tr/markdown-tr.html.markdown251
-rw-r--r--tr-tr/python3-tr.html.markdown635
-rw-r--r--typescript.html.markdown2
-rw-r--r--visualbasic.html.markdown4
-rw-r--r--zh-cn/bash-cn.html.markdown189
-rw-r--r--zh-cn/c++-cn.html.markdown572
-rw-r--r--zh-cn/go-cn.html.markdown2
-rw-r--r--zh-cn/groovy-cn.html.markdown420
-rw-r--r--zh-cn/haskell-cn.html.markdown263
-rw-r--r--zh-cn/java-cn.html.markdown2
-rw-r--r--zh-cn/javascript-cn.html.markdown2
-rw-r--r--zh-cn/markdown-cn.html.markdown2
-rw-r--r--zh-cn/ruby-cn.html.markdown9
-rw-r--r--zh-cn/rust-cn.html.markdown296
-rw-r--r--zh-cn/scala-cn.html.markdown558
74 files changed, 10790 insertions, 1512 deletions
diff --git a/bash.html.markdown b/bash.html.markdown
index 3b163638..08182c2c 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -10,6 +10,7 @@ contributors:
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
+ - ["Etan Reisner", "https://github.com/deryni"]
filename: LearnBash.sh
---
@@ -31,32 +32,41 @@ echo Hello world!
echo 'This is the first line'; echo 'This is the second line'
# Declaring a variable looks like this:
-VARIABLE="Some string"
+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.
+Variable = "Some string"
+# Bash will decide that Variable is a command it must execute and give an error
+# because it can't be found.
+
+# Or like this:
+Variable= 'Some string'
+# Bash will decide that 'Some string' is a command it must execute and give an
+# error because it can't be found. (In this case the 'Variable=' part is seen
+# as a variable assignment valid only for the scope of the 'Some string'
+# command.)
# Using the variable:
-echo $VARIABLE
-echo "$VARIABLE"
-echo '$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"
+echo ${Variable/Some/A}
+# This will substitute the first occurrence of "Some" with "A"
# Substring from a variable
-echo ${VARIABLE:0:7}
+Length=7
+echo ${Variable:0:Length}
# 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
+echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
+# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0.
+# Note that it only returns default value and doesn't change variable value.
# Builtin variables:
# There are some useful builtin variables, like
@@ -64,16 +74,16 @@ 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..."
+echo "Scripts arguments separated 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!
+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 ]
+if [ $Name -ne $USER ]
then
echo "Your name isn't your username"
else
@@ -85,14 +95,14 @@ echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail"
# To use && and || with if statements, you need multiple pairs of square brackets:
-if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
+if [ $Name == "Steve" ] && [ $Age -eq 15 ]
then
- echo "This will run if $NAME is Steve AND $AGE is 15."
+ echo "This will run if $Name is Steve AND $Age is 15."
fi
-if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
+if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
then
- echo "This will run if $NAME is Daniya OR Zach."
+ echo "This will run if $Name is Daniya OR Zach."
fi
# Expressions are denoted with the following format:
@@ -134,7 +144,7 @@ python hello.py > /dev/null 2>&1
# if you want to append instead, use ">>":
python hello.py >> "output.out" 2>> "error.err"
-# Overwrite output.txt, append to error.err, and count lines:
+# Overwrite output.out, append to error.err, and count lines:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
@@ -142,7 +152,7 @@ wc -l output.out error.err
# see: man fd
echo <(echo "#helloworld")
-# Overwrite output.txt with "#helloworld":
+# Overwrite output.out with "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
@@ -161,7 +171,7 @@ echo "There are $(ls | wc -l) items here."
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
+case "$Variable" in
#List patterns for the conditions you want to meet
0) echo "There is a zero.";;
1) echo "There is a one.";;
@@ -169,10 +179,10 @@ case "$VARIABLE" in
esac
# for loops iterate for as many arguments given:
-# The contents of $VARIABLE is printed three times.
-for VARIABLE in {1..3}
+# The contents of $Variable is printed three times.
+for Variable in {1..3}
do
- echo "$VARIABLE"
+ echo "$Variable"
done
# Or write it the "traditional for loop" way:
@@ -183,16 +193,16 @@ done
# They can also be used to act on files..
# This will run the command 'cat' on file1 and file2
-for VARIABLE in file1 file2
+for Variable in file1 file2
do
- cat "$VARIABLE"
+ cat "$Variable"
done
# ..or the output from a command
# This will cat the output from ls.
-for OUTPUT in $(ls)
+for Output in $(ls)
do
- cat "$OUTPUT"
+ cat "$Output"
done
# while loop:
@@ -220,7 +230,7 @@ bar ()
}
# Calling your function
-foo "My name is" $NAME
+foo "My name is" $Name
# There are a lot of useful commands you should learn:
# prints last 10 lines of file.txt
@@ -235,11 +245,13 @@ uniq -d file.txt
cut -d ',' -f 1 file.txt
# replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible)
sed -i 's/okay/great/g' file.txt
-# print to stdout all lines of file.txt which match some regex, the example prints lines which begin with "foo" and end in "bar"
+# print to stdout all lines of file.txt which match some regex
+# The example prints lines which begin with "foo" and end in "bar"
grep "^foo.*bar$" file.txt
# pass the option "-c" to instead print the number of lines matching the regex
grep -c "^foo.*bar$" file.txt
-# if you literally want to search for the string, and not the regex, use fgrep (or grep -F)
+# if you literally want to search for the string,
+# and not the regex, use fgrep (or grep -F)
fgrep "^foo.*bar$" file.txt
diff --git a/c++.html.markdown b/c++.html.markdown
index 1978d183..ff2a98fd 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -32,8 +32,7 @@ one of the most widely-used programming languages.
// variable declarations, primitive types, and functions.
// Just like in C, your program's entry point is a function called
-// main with an integer return type,
-// though void main() is also accepted by most compilers (gcc, clang, etc.)
+// main with an integer return type.
// This value serves as the program's exit status.
// See http://en.wikipedia.org/wiki/Exit_status for more information.
int main(int argc, char** argv)
@@ -289,7 +288,7 @@ public:
// Functions can also be defined inside the class body.
// Functions defined as such are automatically inlined.
- void bark() const { std::cout << name << " barks!\n" }
+ void bark() const { std::cout << name << " barks!\n"; }
// Along with constructors, C++ provides destructors.
// These are called when an object is deleted or falls out of scope.
@@ -301,7 +300,7 @@ public:
}; // A semicolon must follow the class definition.
// Class member functions are usually implemented in .cpp files.
-void Dog::Dog()
+Dog::Dog()
{
std::cout << "A dog has been constructed\n";
}
@@ -324,7 +323,7 @@ void Dog::print() const
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}
-void Dog::~Dog()
+Dog::~Dog()
{
cout << "Goodbye " << name << "\n";
}
@@ -333,7 +332,7 @@ int main() {
Dog myDog; // prints "A dog has been constructed"
myDog.setName("Barkley");
myDog.setWeight(10);
- myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg"
+ myDog.print(); // prints "Dog is Barkley and weighs 10 kg"
return 0;
} // prints "Goodbye Barkley"
@@ -342,7 +341,7 @@ int main() {
// This class inherits everything public and protected from the Dog class
class OwnedDog : public Dog {
- void setOwner(const std::string& dogsOwner)
+ void setOwner(const std::string& dogsOwner);
// Override the behavior of the print function for all OwnedDogs. See
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
@@ -426,7 +425,7 @@ int main () {
Point up (0,1);
Point right (1,0);
// This calls the Point + operator
- // Point up calls the + (function) with right as its paramater
+ // Point up calls the + (function) with right as its parameter
Point result = up + right;
// Prints "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
@@ -434,6 +433,85 @@ int main () {
}
/////////////////////
+// Templates
+/////////////////////
+
+// Templates in C++ are mostly used for generic programming, though they are
+// much more powerful than generics constructs in other languages. It also
+// supports explicit and partial specialization, functional-style type classes,
+// and also it's Turing-complete.
+
+// We start with the kind of generic programming you might be familiar with. To
+// define a class or function that takes a type parameter:
+template<class T>
+class Box {
+public:
+ // In this class, T can be used as any other type.
+ void insert(const T&) { ... }
+};
+
+// During compilation, the compiler actually generates copies of each template
+// with parameters substituted, and so the full definition of the class must be
+// present at each invocation. This is why you will see template classes defined
+// entirely in header files.
+
+// To instantiate a template class on the stack:
+Box<int> intBox;
+
+// and you can use it as you would expect:
+intBox.insert(123);
+
+// You can, of course, nest templates:
+Box<Box<int> > boxOfBox;
+boxOfBox.insert(intBox);
+
+// Up until C++11, you must place a space between the two '>'s, otherwise '>>'
+// will be parsed as the right shift operator.
+
+// You will sometimes see
+// template<typename T>
+// instead. The 'class' keyword and 'typename' keyword are _mostly_
+// interchangeable in this case. For full explanation, see
+// http://en.wikipedia.org/wiki/Typename
+// (yes, that keyword has its own Wikipedia page).
+
+// Similarly, a template function:
+template<class T>
+void barkThreeTimes(const T& input)
+{
+ input.bark();
+ input.bark();
+ input.bark();
+}
+
+// Notice that nothing is specified about the type parameters here. The compiler
+// will generate and then type-check every invocation of the template, so the
+// above function works with any type 'T' that has a const 'bark' method!
+
+Dog fluffy;
+fluffy.setName("Fluffy")
+barkThreeTimes(fluffy); // Prints "Fluffy barks" three times.
+
+// Template parameters don't have to be classes:
+template<int Y>
+void printMessage() {
+ cout << "Learn C++ in " << Y << " minutes!" << endl;
+}
+
+// And you can explicitly specialize templates for more efficient code. Of
+// course, most real-world uses of specialization are not as trivial as this.
+// Note that you still need to declare the function (or class) as a template
+// even if you explicitly specified all parameters.
+template<>
+void printMessage<10>() {
+ cout << "Learn C++ faster in only 10 minutes!" << endl;
+}
+
+printMessage<20>(); // Prints "Learn C++ in 20 minutes!"
+printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!"
+
+
+/////////////////////
// Exception Handling
/////////////////////
@@ -441,12 +519,13 @@ int main () {
// (see http://en.cppreference.com/w/cpp/error/exception)
// but any type can be thrown an as exception
#include <exception>
+#include <stdexcept>
// All exceptions thrown inside the _try_ block can be caught by subsequent
// _catch_ handlers.
try {
// Do not allocate exceptions on the heap using _new_.
- throw std::exception("A problem occurred");
+ throw std::runtime_error("A problem occurred");
}
// Catch exceptions by const reference if they are objects
catch (const std::exception& ex)
@@ -537,7 +616,7 @@ void doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Open the file in read mode
if (fh == nullptr)
- throw std::exception("Could not open the file.");
+ throw std::runtime_error("Could not open the file.");
try {
doSomethingWithTheFile(fh);
@@ -555,7 +634,7 @@ void doSomethingWithAFile(const char* filename)
// Compare this to the use of C++'s file stream class (fstream)
// fstream uses its destructor to close the file.
// Recall from above that destructors are automatically called
-// whenver an object falls out of scope.
+// whenever an object falls out of scope.
void doSomethingWithAFile(const std::string& filename)
{
// ifstream is short for input file stream
@@ -586,8 +665,56 @@ void doSomethingWithAFile(const std::string& filename)
// vector (i.e. self-resizing array), hash maps, and so on
// all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock
+
+
+/////////////////////
+// Fun stuff
+/////////////////////
+
+// Aspects of C++ that may be surprising to newcomers (and even some veterans).
+// This section is, unfortunately, wildly incomplete; C++ is one of the easiest
+// languages with which to shoot yourself in the foot.
+
+// You can override private methods!
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // overrides Foo::bar!
+};
+
+
+// 0 == false == NULL (most of the time)!
+bool* pt = new bool;
+*pt = 0; // Sets the value points by 'pt' to false.
+pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings.
+
+// nullptr is supposed to fix some of that issue:
+int* pt2 = new int;
+*pt2 = nullptr; // Doesn't compile
+pt2 = nullptr; // Sets pt2 to null.
+
+// But somehow 'bool' type is an exception (this is to make `if (ptr)` compile).
+*pt = nullptr; // This still compiles, even though '*pt' is a bool!
+
+
+// '=' != '=' != '='!
+// Calls Foo::Foo(const Foo&) or some variant copy constructor.
+Foo f2;
+Foo f1 = f2;
+
+// Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of
+// 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes
+// horrifying behavior is called "object slicing."
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Calls Foo::operator=(Foo&) or variant.
+Foo f1;
+f1 = f2;
+
```
-Futher Reading:
+Further Reading:
An up-to-date language reference can be found at
<http://cppreference.com/w/cpp>
diff --git a/c.html.markdown b/c.html.markdown
index 1696d28f..d3f20eda 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -234,7 +234,7 @@ int main() {
// same with j-- and --j
// Bitwise operators!
- ~0x0F; // => 0xF0 (bitwise negation, "1's complement")
+ ~0x0F; // => 0xFFFFFFF0 (bitwise negation, "1's complement", example result for 32-bit int)
0x0F & 0xF0; // => 0x00 (bitwise AND)
0x0F | 0xF0; // => 0xFF (bitwise OR)
0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
@@ -242,7 +242,7 @@ int main() {
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)
+ // - shifting into the sign bit of a signed integer (int a = 1 << 31)
// - 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
diff --git a/chapel.html.markdown b/chapel.html.markdown
new file mode 100644
index 00000000..c8489371
--- /dev/null
+++ b/chapel.html.markdown
@@ -0,0 +1,1103 @@
+---
+language: chapel
+filename: learnchapel.chpl
+contributors:
+ - ["Ian J. Bertolacci", "http://www.cs.colostate.edu/~ibertola/"]
+---
+
+You can read all about Chapel at [Cray's official Chapel website](http://chapel.cray.com).
+In short, Chapel is an open-source, high-productivity, parallel-programming language in development at Cray Inc., and is designed to run on multi-core PCs as well as multi-kilocore supercomputers.
+
+More information and support can be found at the bottom of this document.
+
+```c
+// Comments are C-family style
+// one line comment
+/*
+ multi-line comment
+*/
+
+// Basic printing
+write( "Hello, " );
+writeln( "World!" );
+// write and writeln can take a list of things to print.
+// each thing is printed right next to each other, so include your spacing!
+writeln( "There are ", 3, " commas (\",\") in this line of code" );
+// Different output channels
+stdout.writeln( "This goes to standard output, just like plain writeln() does");
+stderr.writeln( "This goes to standard error" );
+
+// Variables don't have to be explicitly typed as long as
+// the compiler can figure out the type that it will hold.
+var myVar = 10; // 10 is an int, so myVar is implicitly an int
+myVar = -10;
+var mySecondVar = myVar;
+// var anError; // this would be a compile-time error.
+
+// We can (and should) explicitly type things
+var myThirdVar: real;
+var myFourthVar: real = -1.234;
+myThirdVar = myFourthVar;
+
+// There are a number of basic types.
+var myInt: int = -1000; // Signed ints
+var myUint: uint = 1234; // Unsigned ints
+var myReal: real = 9.876; // Floating point numbers
+var myImag: imag = 5.0i; // Imaginary numbers
+var myCplx: complex = 10 + 9i; // Complex numbers
+myCplx = myInt + myImag ; // Another way to form complex numbers
+var myBool: bool = false; // Booleans
+var myStr: string = "Some string..."; // Strings
+
+// Some types can have sizes
+var my8Int: int(8) = 10; // 8 bit (one byte) sized int;
+var my64Real: real(64) = 1.516; // 64 bit (8 bytes) sized real
+
+// Typecasting
+var intFromReal = myReal : int;
+var intFromReal2: int = myReal : int;
+
+// consts are constants, they cannot be changed after set in runtime.
+const almostPi: real = 22.0/7.0;
+
+// params are constants whose value must be known statically at compile-time
+// Their value cannot be changed.
+param compileTimeConst: int = 16;
+
+// The config modifier allows values to be set at the command line
+// and is much easier than the usual getOpts debacle
+// config vars and consts can be changed through the command line at run time
+config var varCmdLineArg: int = -123;
+config const constCmdLineArg: int = 777;
+// Set with --VarName=Value or --VarName Value at run time
+
+// config params can be set/changed at compile-time
+config param paramCmdLineArg: bool = false;
+// Set config with --set paramCmdLineArg=value at compile-time
+writeln( varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg );
+
+// refs operate much like a reference in C++
+var actual = 10;
+ref refToActual = actual; // refToActual refers to actual
+writeln( actual, " == ", refToActual ); // prints the same value
+actual = -123; // modify actual (which refToActual refers to)
+writeln( actual, " == ", refToActual ); // prints the same value
+refToActual = 99999999; // modify what refToActual refers to (which is actual)
+writeln( actual, " == ", refToActual ); // prints the same value
+
+// Math operators
+var a: int, thisInt = 1234, thatInt = 5678;
+a = thisInt + thatInt; // Addition
+a = thisInt * thatInt; // Multiplication
+a = thisInt - thatInt; // Subtraction
+a = thisInt / thatInt; // Division
+a = thisInt ** thatInt; // Exponentiation
+a = thisInt % thatInt; // Remainder (modulo)
+
+// Logical Operators
+var b: bool, thisBool = false, thatBool = true;
+b = thisBool && thatBool; // Logical and
+b = thisBool || thatBool; // Logical or
+b = !thisBool; // Logical negation
+
+// Relational Operators
+b = thisInt > thatInt; // Greater-than
+b = thisInt >= thatInt; // Greater-than-or-equal-to
+b = thisInt < a && a <= thatInt; // Less-than, and, less-than-or-equal-to
+b = thisInt != thatInt; // Not-equal-to
+b = thisInt == thatInt; // Equal-to
+
+// Bitwise operations
+a = thisInt << 10; // Left-bit-shift by 10 bits;
+a = thatInt >> 5; // Right-bit-shift by 5 bits;
+a = ~thisInt; // Bitwise-negation
+a = thisInt ^ thatInt; // Bitwise exclusive-or
+
+// Compound assignment operations
+a += thisInt; // Addition-equals ( a = a + thisInt;)
+a *= thatInt; // Times-equals ( a = a * thatInt; )
+b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
+a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
+// and many, many more.
+// Unlike other C family languages there are no
+// pre/post-increment/decrement operators like
+// ++j, --j, j++, j--
+
+// Swap operator
+var old_this = thisInt;
+var old_that = thatInt;
+thisInt <=> thatInt; // Swap the values of thisInt and thatInt
+writeln( (old_this == thatInt) && (old_that == thisInt) );
+
+// Operator overloads can also be defined, as we'll see with procedures
+
+// Tuples can be of the same type
+var sameTup: 2*int = (10,-1);
+var sameTup2 = (11, -6);
+// or different types
+var diffTup: (int,real,complex) = (5, 1.928, myCplx);
+var diffTupe2 = ( 7, 5.64, 6.0+1.5i );
+
+// Accessed using array bracket notation
+// However, tuples are all 1-indexed
+writeln( "(", sameTup[1], ",", sameTup[2], ")" );
+writeln( diffTup );
+
+// Tuples can also be written into.
+diffTup[1] = -1;
+
+// Can expand tuple values into their own variables
+var (tupInt, tupReal, tupCplx) = diffTup;
+writeln( diffTup == (tupInt, tupReal, tupCplx) );
+
+// Useful for writing a list of variables ( as is common in debugging)
+writeln( (a,b,thisInt,thatInt,thisBool,thatBool) );
+
+// Type aliasing
+type chroma = int; // Type of a single hue
+type RGBColor = 3*chroma; // Type representing a full color
+var black: RGBColor = ( 0,0,0 );
+var white: RGBColor = ( 255, 255, 255 );
+
+// If-then-else works just like any other C-family language
+if 10 < 100 then
+ writeln( "All is well" );
+
+if -1 < 1 then
+ writeln( "Continuing to believe reality" );
+else
+ writeln( "Send mathematician, something's wrong" );
+
+if ( 10 > 100 ) {
+ writeln( "Universe broken. Please reboot universe." );
+}
+
+if ( a % 2 == 0 ) {
+ writeln( a, " is even." );
+} else {
+ writeln( a, " is odd." );
+}
+
+if ( a % 3 == 0 ) {
+ writeln( a, " is even divisible by 3." );
+} else if ( a % 3 == 1 ){
+ writeln( a, " is divided by 3 with a remainder of 1." );
+} else {
+ writeln( b, " is divided by 3 with a remainder of 2." );
+}
+
+// Ternary: if-then-else in a statement
+var maximum = if ( thisInt < thatInt ) then thatInt else thisInt;
+
+// Select statements are much like switch statements in other languages
+// However, Select statements don't cascade like in C or Java
+var inputOption = "anOption";
+select( inputOption ){
+ when "anOption" do writeln( "Chose 'anOption'" );
+ when "otherOption" {
+ writeln( "Chose 'otherOption'" );
+ writeln( "Which has a body" );
+ }
+ otherwise {
+ writeln( "Any other Input" );
+ writeln( "the otherwise case doesn't need a do if the body is one line" );
+ }
+}
+
+// While and Do-While loops are basically the same in every language.
+var j: int = 1;
+var jSum: int = 0;
+while( j <= 1000 ){
+ jSum += j;
+ j += 1;
+}
+writeln( jSum );
+
+// Do-While loop
+do{
+ jSum += j;
+ j += 1;
+}while( j <= 10000 );
+writeln( jSum );
+
+// For loops are much like those in python in that they iterate over a range.
+// Ranges themselves are types, and can be stuffed into variables
+// (more about that later)
+for i in 1..10 do write( i , ", ") ;
+writeln( );
+
+var iSum: int = 0;
+for i in 1..1000 {
+ iSum += i;
+}
+writeln( iSum );
+
+for x in 1..10 {
+ for y in 1..10 {
+ write( (x,y), "\t" );
+ }
+ writeln( );
+}
+
+// Ranges and Domains
+// For-loops and arrays both use ranges and domains to
+// define an index set that can be iterated over.
+// Ranges are single dimensional
+// Domains can be multi-dimensional and can
+// represent indices of different types as well.
+// They are first-class citizen types, and can be assigned into variables
+var range1to10: range = 1..10; // 1, 2, 3, ..., 10
+var range2to11 = 2..11; // 2, 3, 4, ..., 11
+var rangeThistoThat: range = thisInt..thatInt; // using variables
+var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
+
+// Ranges can be unbounded
+var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
+// 1, 2, 3, 4, 5, ...
+// Note: the range(boundedType= ... ) is only
+// necessary if we explicitly type the variable
+
+var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
+
+// Ranges can be strided using the 'by' operator.
+var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
+// Note: the range(stridable=true) is only
+// necessary if we explicitly type the variable
+
+// Use by to create a reverse range
+var reverse2to10by2 = 10..2 by -2; // 10, 8, 6, 4, 2
+
+// The end point of a range can be determined using the count (#) operator
+var rangeCount: range = -5..#12; // range from -5 to 6
+
+// Can mix operators
+var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5
+writeln( rangeCountBy );
+
+// Can query properties of the range
+// Print the first index, last index, number of indices,
+// stride, and ask if 2 is include in the range
+writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
+ rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
+
+for i in rangeCountBy{
+ write( i, if i == rangeCountBy.last then "\n" else ", " );
+}
+
+// Rectangular domains are defined using the same range syntax
+// However they are required to be bounded (unlike ranges)
+var domain1to10: domain(1) = {1..10}; // 1D domain from 1..10;
+var twoDimensions: domain(2) = {-2..2,0..2}; // 2D domain over product of ranges
+var thirdDim: range = 1..16;
+var threeDims: domain(3) = {thirdDim, 1..10, 5..10}; // using a range variable
+
+// Can iterate over the indices as tuples
+for idx in twoDimensions do
+ write( idx , ", ");
+writeln( );
+
+// or can deconstruct the tuple
+for (x,y) in twoDimensions {
+ write( "(", x, ", ", y, ")", ", " );
+}
+writeln( );
+
+// Associative domains act like sets
+var stringSet: domain(string); // empty set of strings
+stringSet += "a";
+stringSet += "b";
+stringSet += "c";
+stringSet += "a"; // Redundant add "a"
+stringSet -= "c"; // Remove "c"
+writeln( stringSet );
+
+// Both ranges and domains can be sliced to produce a range or domain with the
+// intersection of indices
+var rangeA = 1.. ; // range from 1 to infinity
+var rangeB = ..5; // range from negative infinity to 5
+var rangeC = rangeA[rangeB]; // resulting range is 1..5
+writeln( (rangeA, rangeB, rangeC ) );
+
+var domainA = {1..10, 5..20};
+var domainB = {-5..5, 1..10};
+var domainC = domainA[domainB];
+writeln( (domainA, domainB, domainC) );
+
+// Array are similar to those of other languages.
+// Their sizes are defined using domains that represent their indices
+var intArray: [1..10] int;
+var intArray2: [{1..10}] int; //equivalent
+
+// Accessed using bracket notation
+for i in 1..10 do
+ intArray[i] = -i;
+writeln( intArray );
+// We cannot access intArray[0] because it exists outside
+// of the index set, {1..10}, we defined it to have.
+// intArray[11] is illegal for the same reason.
+
+var realDomain: domain(2) = {1..5,1..7};
+var realArray: [realDomain] real;
+var realArray2: [1..5,1..7] real; // Equivalent
+var realArray3: [{1..5,1..7}] real; // Equivalent
+
+for i in 1..5 {
+ for j in realDomain.dim(2) { // Only use the 2nd dimension of the domain
+ realArray[i,j] = -1.61803 * i + 0.5 * j; // Access using index list
+ var idx: 2*int = (i,j); // Note: 'index' is a keyword
+ realArray[idx] = - realArray[(i,j)]; // Index using tuples
+ }
+}
+
+// Arrays have domains as members that we can iterate over
+for idx in realArray.domain { // Again, idx is a 2*int tuple
+ realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
+}
+
+writeln( realArray );
+
+// Can also iterate over the values of an array
+var rSum: real = 0;
+for value in realArray {
+ rSum += value; // Read a value
+ value = rSum; // Write a value
+}
+writeln( rSum, "\n", realArray );
+
+// Using associative domains we can create associative arrays (dictionaries)
+var dictDomain: domain(string) = { "one", "two" };
+var dict: [dictDomain] int = [ "one" => 1, "two" => 2 ];
+dict["three"] = 3;
+for key in dictDomain do writeln( dict[key] );
+
+// Arrays can be assigned to each other in different ways
+var thisArray : [{0..5}] int = [0,1,2,3,4,5];
+var thatArray : [{0..5}] int;
+
+// Simply assign one to the other.
+// This copies thisArray into thatArray, instead of just creating a reference.
+// Modifying thisArray does not also modify thatArray.
+thatArray = thisArray;
+thatArray[1] = -1;
+writeln( (thisArray, thatArray) );
+
+// Assign a slice one array to a slice (of the same size) of the other.
+thatArray[{4..5}] = thisArray[{1..2}];
+writeln( (thisArray, thatArray) );
+
+// Operation can also be promoted to work on arrays.
+var thisPlusThat = thisArray + thatArray;
+writeln( thisPlusThat );
+
+// Arrays and loops can also be expressions, where loop
+// body's expression is the result of each iteration.
+var arrayFromLoop = for i in 1..10 do i;
+writeln( arrayFromLoop );
+
+// An expression can result in nothing,
+// such as when filtering with an if-expression
+var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
+
+writeln( arrayFromLoop );
+
+// Or could be written with a bracket notation
+// Note: this syntax uses the 'forall' parallel concept discussed later.
+var evensOrFivesAgain = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
+
+// Or over the values of the array
+arrayFromLoop = [ value in arrayFromLoop ] value + 1;
+
+// Note: this notation can get somewhat tricky. For example:
+// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
+// would break.
+// The reasons for this are explained in depth when discussing zipped iterators.
+
+// Chapel procedures have similar syntax to other languages functions.
+proc fibonacci( n : int ) : int {
+ if ( n <= 1 ) then return n;
+ return fibonacci( n-1 ) + fibonacci( n-2 );
+}
+
+// Input parameters can be untyped (a generic procedure)
+proc doublePrint( thing ): void {
+ write( thing, " ", thing, "\n");
+}
+
+// Return type can be inferred (as long as the compiler can figure it out)
+proc addThree( n ) {
+ return n + 3;
+}
+
+doublePrint( addThree( fibonacci( 20 ) ) );
+
+// Can also take 'unlimited' number of parameters
+proc maxOf( x ...?k ) {
+ // x refers to a tuple of one type, with k elements
+ var maximum = x[1];
+ for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
+ return maximum;
+}
+writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
+
+// The ? operator is called the query operator, and is used to take
+// undetermined values (like tuple or array sizes, and generic types).
+
+// Taking arrays as parameters.
+// The query operator is used to determine the domain of A.
+// This is important to define the return type (if you wanted to)
+proc invertArray( A: [?D] int ): [D] int{
+ for a in A do a = -a;
+ return A;
+}
+
+writeln( invertArray( intArray ) );
+
+// Procedures can have default parameter values, and
+// the parameters can be named in the call, even out of order
+proc defaultsProc( x: int, y: real = 1.2634 ): (int,real){
+ return (x,y);
+}
+
+writeln( defaultsProc( 10 ) );
+writeln( defaultsProc( x=11 ) );
+writeln( defaultsProc( x=12, y=5.432 ) );
+writeln( defaultsProc( y=9.876, x=13 ) );
+
+// Intent modifiers on the arguments convey how
+// those arguments are passed to the procedure
+// in: copy arg in, but not out
+// out: copy arg out, but not in
+// inout: copy arg in, copy arg out
+// ref: pass arg by reference
+proc intentsProc( in inarg, out outarg, inout inoutarg, ref refarg ){
+ writeln( "Inside Before: ", (inarg, outarg, inoutarg, refarg) );
+ inarg = inarg + 100;
+ outarg = outarg + 100;
+ inoutarg = inoutarg + 100;
+ refarg = refarg + 100;
+ writeln( "Inside After: ", (inarg, outarg, inoutarg, refarg) );
+}
+
+var inVar: int = 1;
+var outVar: int = 2;
+var inoutVar: int = 3;
+var refVar: int = 4;
+writeln( "Outside Before: ", (inVar, outVar, inoutVar, refVar) );
+intentsProc( inVar, outVar, inoutVar, refVar );
+writeln( "Outside After: ", (inVar, outVar, inoutVar, refVar) );
+
+// Similarly we can define intents on the return type
+// refElement returns a reference to an element of array
+proc refElement( array : [?D] ?T, idx ) ref : T {
+ return array[ idx ]; // returns a reference to
+}
+
+var myChangingArray : [1..5] int = [1,2,3,4,5];
+writeln( myChangingArray );
+// Store reference to element in ref variable
+ref refToElem = refElement( myChangingArray, 5 );
+writeln( refToElem );
+refToElem = -2; // modify reference which modifies actual value in array
+writeln( refToElem );
+writeln( myChangingArray );
+// This makes more practical sense for class methods where references to
+// elements in a data-structure are returned via a method or iterator
+
+// We can query the type of arguments to generic procedures
+// Here we define a procedure that takes two arguments of
+// the same type, yet we don't define what that type is.
+proc genericProc( arg1 : ?valueType, arg2 : valueType ): void {
+ select( valueType ){
+ when int do writeln( arg1, " and ", arg2, " are ints" );
+ when real do writeln( arg1, " and ", arg2, " are reals" );
+ otherwise writeln( arg1, " and ", arg2, " are somethings!" );
+ }
+}
+
+genericProc( 1, 2 );
+genericProc( 1.2, 2.3 );
+genericProc( 1.0+2.0i, 3.0+4.0i );
+
+// We can also enforce a form of polymorphism with the 'where' clause
+// This allows the compiler to decide which function to use.
+// Note: that means that all information needs to be known at compile-time.
+// The param modifier on the arg is used to enforce this constraint.
+proc whereProc( param N : int ): void
+ where ( N > 0 ) {
+ writeln( "N is greater than 0" );
+}
+
+proc whereProc( param N : int ): void
+ where ( N < 0 ) {
+ writeln( "N is less than 0" );
+}
+
+whereProc( 10 );
+whereProc( -1 );
+// whereProc( 0 ) would result in a compiler error because there
+// are no functions that satisfy the where clause's condition.
+// We could have defined a whereProc without a where clause that would then have
+// served as a catch all for all the other cases (of which there is only one).
+
+// Operator definitions are through procedures as well.
+// We can define the unary operators:
+// + - ! ~
+// and the binary operators:
+// + - * / % ** == <= >= < > << >> & | ˆ by
+// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
+
+// Boolean exclusive or operator
+proc ^( left : bool, right : bool ): bool {
+ return (left || right) && !( left && right );
+}
+
+writeln( true ^ true );
+writeln( false ^ true );
+writeln( true ^ false );
+writeln( false ^ false );
+
+// Define a * operator on any two types that returns a tuple of those types
+proc *( left : ?ltype, right : ?rtype): ( ltype, rtype ){
+ return (left, right );
+}
+
+writeln( 1 * "a" ); // Uses our * operator
+writeln( 1 * 2 ); // Uses the default * operator
+
+/*
+Note: You could break everything if you get careless with your overloads.
+This here will break everything. Don't do it.
+proc +( left: int, right: int ): int{
+ return left - right;
+}
+*/
+
+// Iterators are a sisters to the procedure, and almost
+// everything about procedures also applies to iterators
+// However, instead of returning a single value,
+// iterators yield many values to a loop.
+// This is useful when a complicated set or order of iterations is needed but
+// allows the code defining the iterations to be separate from the loop body.
+iter oddsThenEvens( N: int ): int {
+ for i in 1..N by 2 do
+ yield i; // yield values instead of returning.
+ for i in 2..N by 2 do
+ yield i;
+}
+
+for i in oddsThenEvens( 10 ) do write( i, ", " );
+writeln( );
+
+// Iterators can also yield conditionally, the result of which can be nothing
+iter absolutelyNothing( N ): int {
+ for i in 1..N {
+ if ( N < i ) { // Always false
+ yield i; // Yield statement never happens
+ }
+ }
+}
+
+for i in absolutelyNothing( 10 ){
+ writeln( "Woa there! absolutelyNothing yielded ", i );
+}
+
+// We can zipper together two or more iterators (who have the same number
+// of iterations) using zip() to create a single zipped iterator, where each
+// iteration of the zipped iterator yields a tuple of one value yielded
+// from each iterator.
+ // Ranges have implicit iterators
+for (positive, negative) in zip( 1..5, -5..-1) do
+ writeln( (positive, negative) );
+
+// Zipper iteration is quite important in the assignment of arrays,
+// slices of arrays, and array/loop expressions.
+var fromThatArray : [1..#5] int = [1,2,3,4,5];
+var toThisArray : [100..#5] int;
+
+// The operation
+toThisArray = fromThatArray;
+// is produced through
+for (i,j) in zip( toThisArray.domain, fromThatArray.domain) {
+ toThisArray[ i ] = fromThatArray[ j ];
+}
+
+toThisArray = [ j in -100..#5 ] j;
+writeln( toThisArray );
+// is produced through
+for (i, j) in zip( toThisArray.domain, -100..#5 ){
+ toThisArray[i] = j;
+}
+writeln( toThisArray );
+
+// This is all very important in undestanding why the statement
+// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
+// exhibits a runtime error.
+// Even though the domain of the array and the loop-expression are
+// the same size, the body of the expression can be though of as an iterator.
+// Because iterators can yield nothing, that iterator yields a different number
+// of things than the domain of the array or loop, which is not allowed.
+
+// Classes are similar to those in C++ and Java.
+// They currently lack privatization
+class MyClass {
+ // Member variables
+ var memberInt : int;
+ var memberBool : bool = true;
+
+ // Classes have default constructors that don't need to be coded (see below)
+ // Our explicitly defined constructor
+ proc MyClass( val : real ){
+ this.memberInt = ceil( val ): int;
+ }
+
+ // Our explicitly defined destructor
+ proc ~MyClass( ){
+ writeln( "MyClass Destructor called ", (this.memberInt, this.memberBool) );
+ }
+
+ // Class methods
+ proc setMemberInt( val: int ){
+ this.memberInt = val;
+ }
+
+ proc setMemberBool( val: bool ){
+ this.memberBool = val;
+ }
+
+ proc getMemberInt( ): int{
+ return this.memberInt;
+ }
+
+ proc getMemberBool( ): bool {
+ return this.memberBool;
+ }
+
+}
+
+// Construct using default constructor, using default values
+var myObject = new MyClass( 10 );
+ myObject = new MyClass( memberInt = 10 ); // Equivalent
+writeln( myObject.getMemberInt( ) );
+// ... using our values
+var myDiffObject = new MyClass( -1, true );
+ myDiffObject = new MyClass( memberInt = -1,
+ memberBool = true ); // Equivalent
+writeln( myDiffObject );
+
+// Construct using written constructor
+var myOtherObject = new MyClass( 1.95 );
+ myOtherObject = new MyClass( val = 1.95 ); // Equivalent
+writeln( myOtherObject.getMemberInt( ) );
+
+// We can define an operator on our class as well but
+// the definition has to be outside the class definition
+proc +( A : MyClass, B : MyClass) : MyClass {
+ return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
+ memberBool = A.getMemberBool( ) || B.getMemberBool( ) );
+}
+
+var plusObject = myObject + myDiffObject;
+writeln( plusObject );
+
+// Destruction
+delete myObject;
+delete myDiffObject;
+delete myOtherObject;
+delete plusObject;
+
+// Classes can inherit from one or more parent classes
+class MyChildClass : MyClass {
+ var memberComplex: complex;
+}
+
+// Generic Classes
+class GenericClass {
+ type classType;
+ var classDomain: domain(1);
+ var classArray: [classDomain] classType;
+
+ // Explicit constructor
+ proc GenericClass( type classType, elements : int ){
+ this.classDomain = {1..#elements};
+ }
+
+ // Copy constructor
+ // Note: We still have to put the type as an argument, but we can
+ // default to the type of the other object using the query (?) operator
+ // Further, we can take advantage of this to allow our copy constructor
+ // to copy classes of different types and cast on the fly
+ proc GenericClass( other : GenericClass(?otherType),
+ type classType = otherType ) {
+ this.classDomain = other.classDomain;
+ // Copy and cast
+ for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
+ }
+
+ // Define bracket notation on a GenericClass
+ // object so it can behave like a normal array
+ // i.e. objVar[ i ] or objVar( i )
+ proc this( i : int ) ref : classType {
+ return this.classArray[ i ];
+ }
+
+ // Define an implicit iterator for the class
+ // to yield values from the array to a loop
+ // i.e. for i in objVar do ....
+ iter these( ) ref : classType {
+ for i in this.classDomain do
+ yield this[i];
+ }
+
+}
+
+var realList = new GenericClass( real, 10 );
+// We can assign to the member array of the object using the bracket
+// notation that we defined ( proc this( i: int ){ ... } )
+for i in realList.classDomain do realList[i] = i + 1.0;
+// We can iterate over the values in our list with the iterator
+// we defined ( iter these( ){ ... } )
+for value in realList do write( value, ", " );
+writeln( );
+
+// Make a copy of realList using the copy constructor
+var copyList = new GenericClass( realList );
+for value in copyList do write( value, ", " );
+writeln( );
+
+// Make a copy of realList and change the type, also using the copy constructor
+var copyNewTypeList = new GenericClass( realList, int );
+for value in copyNewTypeList do write( value, ", " );
+writeln( );
+
+// Modules are Chapel's way of managing name spaces.
+// The files containing these modules do not need to be named after the modules
+// (as in Java), but files implicitly name modules.
+// In this case, this file implicitly names the 'learnchapel' module
+
+module OurModule {
+ // We can use modules inside of other modules.
+ use Time; // Time is one of the standard modules.
+
+ // We'll use this procedure in the parallelism section.
+ proc countdown( seconds: int ){
+ for i in 1..seconds by -1 {
+ writeln( i );
+ sleep( 1 );
+ }
+ }
+
+ // Submodules of OurModule
+ // It is possible to create arbitrarily deep module nests.
+ module ChildModule {
+ proc foo(){
+ writeln( "ChildModule.foo()");
+ }
+ }
+
+ module SiblingModule {
+ proc foo(){
+ writeln( "SiblingModule.foo()" );
+ }
+ }
+} // end OurModule
+
+// Using OurModule also uses all the modules it uses.
+// Since OurModule uses Time, we also use time.
+use OurModule;
+
+// At this point we have not used ChildModule or SiblingModule so their symbols
+// (i.e. foo ) are not available to us.
+// However, the module names are, and we can explicitly call foo() through them.
+SiblingModule.foo(); // Calls SiblingModule.foo()
+
+// Super explicit naming.
+OurModule.ChildModule.foo(); // Calls ChildModule.foo()
+
+use ChildModule;
+foo(); // Less explicit call on ChildModule.foo()
+
+// We can declare a main procedure
+// Note: all the code above main still gets executed.
+proc main(){
+
+ // Parallelism
+ // In other languages, parallelism is typically done with
+ // complicated libraries and strange class structure hierarchies.
+ // Chapel has it baked right into the language.
+
+ // A begin statement will spin the body of that statement off
+ // into one new task.
+ // A sync statement will ensure that the progress of the main
+ // task will not progress until the children have synced back up.
+ sync {
+ begin { // Start of new task's body
+ var a = 0;
+ for i in 1..1000 do a += 1;
+ writeln( "Done: ", a);
+ } // End of new tasks body
+ writeln( "spun off a task!");
+ }
+ writeln( "Back together" );
+
+ proc printFibb( n: int ){
+ writeln( "fibonacci(",n,") = ", fibonacci( n ) );
+ }
+
+ // A cobegin statement will spin each statement of the body into one new task
+ cobegin {
+ printFibb( 20 ); // new task
+ printFibb( 10 ); // new task
+ printFibb( 5 ); // new task
+ {
+ // This is a nested statement body and thus is a single statement
+ // to the parent statement and is executed by a single task
+ writeln( "this gets" );
+ writeln( "executed as" );
+ writeln( "a whole" );
+ }
+ }
+ // Notice here that the prints from each statement may happen in any order.
+
+ // Coforall loop will create a new task for EACH iteration
+ var num_tasks = 10; // Number of tasks we want
+ coforall taskID in 1..#num_tasks {
+ writeln( "Hello from task# ", taskID );
+ }
+ // Again we see that prints happen in any order.
+ // NOTE! coforall should be used only for creating tasks!
+ // Using it to iterating over a structure is very a bad idea!
+
+ // forall loops are another parallel loop, but only create a smaller number
+ // of tasks, specifically --dataParTasksPerLocale=number of task
+ forall i in 1..100 {
+ write( i, ", ");
+ }
+ writeln( );
+ // Here we see that there are sections that are in order, followed by
+ // a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
+ // This is because each task is taking on a chunk of the range 1..10
+ // (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
+ // in parallel.
+ // Your results may depend on your machine and configuration
+
+ // For both the forall and coforall loops, the execution of the
+ // parent task will not continue until all the children sync up.
+
+ // forall loops are particularly useful for parallel iteration over arrays.
+ // Lets run an experiment to see how much faster a parallel loop is
+ use Time; // Import the Time module to use Timer objects
+ var timer: Timer;
+ var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
+
+ // Serial Experiment
+ timer.start( ); // Start timer
+ for (x,y) in myBigArray.domain { // Serial iteration
+ myBigArray[x,y] = (x:real) / (y:real);
+ }
+ timer.stop( ); // Stop timer
+ writeln( "Serial: ", timer.elapsed( ) ); // Print elapsed time
+ timer.clear( ); // Clear timer for parallel loop
+
+ // Parallel Experiment
+ timer.start( ); // start timer
+ forall (x,y) in myBigArray.domain { // Parallel iteration
+ myBigArray[x,y] = (x:real) / (y:real);
+ }
+ timer.stop( ); // Stop timer
+ writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
+ timer.clear( );
+ // You may have noticed that (depending on how many cores you have)
+ // that the parallel loop went faster than the serial loop
+
+ // The bracket style loop-expression described
+ // much earlier implicitly uses a forall loop.
+ [ val in myBigArray ] val = 1 / val; // Parallel operation
+
+ // Atomic variables, common to many languages, are ones whose operations
+ // occur uninterupted. Multiple threads can both modify atomic variables
+ // and can know that their values are safe.
+ // Chapel atomic variables can be of type bool, int, uint, and real.
+ var uranium: atomic int;
+ uranium.write( 238 ); // atomically write a variable
+ writeln( uranium.read() ); // atomically read a variable
+
+ // operations are described as functions, you could define your own operators.
+ uranium.sub( 3 ); // atomically subtract a variable
+ writeln( uranium.read() );
+
+ var replaceWith = 239;
+ var was = uranium.exchange( replaceWith );
+ writeln( "uranium was ", was, " but is now ", replaceWith );
+
+ var isEqualTo = 235;
+ if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
+ writeln( "uranium was equal to ", isEqualTo,
+ " so replaced value with ", replaceWith );
+ } else {
+ writeln( "uranium was not equal to ", isEqualTo,
+ " so value stays the same... whatever it was" );
+ }
+
+ sync {
+ begin { // Reader task
+ writeln( "Reader: waiting for uranium to be ", isEqualTo );
+ uranium.waitFor( isEqualTo );
+ writeln( "Reader: uranium was set (by someone) to ", isEqualTo );
+ }
+
+ begin { // Writer task
+ writeln( "Writer: will set uranium to the value ", isEqualTo, " in..." );
+ countdown( 3 );
+ uranium.write( isEqualTo );
+ }
+ }
+
+ // sync vars have two states: empty and full.
+ // If you read an empty variable or write a full variable, you are waited
+ // until the variable is full or empty again
+ var someSyncVar$: sync int; // varName$ is a convention not a law.
+ sync {
+ begin { // Reader task
+ writeln( "Reader: waiting to read." );
+ var read_sync = someSyncVar$;
+ writeln( "value is ", read_sync );
+ }
+
+ begin { // Writer task
+ writeln( "Writer: will write in..." );
+ countdown( 3 );
+ someSyncVar$ = 123;
+ }
+ }
+
+ // single vars can only be written once. A read on an unwritten single results
+ // in a wait, but when the variable has a value it can be read indefinitely
+ var someSingleVar$: single int; // varName$ is a convention not a law.
+ sync {
+ begin { // Reader task
+ writeln( "Reader: waiting to read." );
+ for i in 1..5 {
+ var read_single = someSingleVar$;
+ writeln( "Reader: iteration ", i,", and the value is ", read_single );
+ }
+ }
+
+ begin { // Writer task
+ writeln( "Writer: will write in..." );
+ countdown( 3 );
+ someSingleVar$ = 5; // first and only write ever.
+ }
+ }
+
+ // Heres an example of using atomics and a synch variable to create a
+ // count-down mutex (also known as a multiplexer)
+ var count: atomic int; // our counter
+ var lock$: sync bool; // the mutex lock
+
+ count.write( 2 ); // Only let two tasks in at a time.
+ lock$.writeXF( true ); // Set lock$ to full (unlocked)
+ // Note: The value doesnt actually matter, just the state
+ // (full:unlocked / empty:locked)
+ // Also, writeXF() fills (F) the sync var regardless of its state (X)
+
+ coforall task in 1..#5 { // Generate tasks
+ // Create a barrier
+ do{
+ lock$; // Read lock$ (wait)
+ }while ( count.read() < 1 ); // Keep waiting until a spot opens up
+
+ count.sub(1); // decrement the counter
+ lock$.writeXF( true ); // Set lock$ to full (signal)
+
+ // Actual 'work'
+ writeln( "Task #", task, " doing work." );
+ sleep( 2 );
+
+ count.add( 1 ); // Increment the counter
+ lock$.writeXF( true ); // Set lock$ to full (signal)
+ }
+
+ // we can define the operations + * & | ^ && || min max minloc maxloc
+ // over an entire array using scans and reductions
+ // Reductions apply the operation over the entire array and
+ // result in a single value
+ var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2];
+ var sumOfValues = + reduce listOfValues;
+ var maxValue = max reduce listOfValues; // 'max' give just max value
+
+ // 'maxloc' gives max value and index of the max value
+ // Note: We have to zip the array and domain together with the zip iterator
+ var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
+ listOfValues.domain);
+
+ writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
+
+ // Scans apply the operation incrementally and return an array of the
+ // value of the operation at that index as it progressed through the
+ // array from array.domain.low to array.domain.high
+ var runningSumOfValues = + scan listOfValues;
+ var maxScan = max scan listOfValues;
+ writeln( runningSumOfValues );
+ writeln( maxScan );
+} // end main()
+```
+
+Who is this tutorial for?
+-------------------------
+
+This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
+It won't teach you how to develop amazingly performant code, and it's not exhaustive.
+Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
+
+Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
+
+### What this tutorial is lacking:
+
+ * Exposition of the standard modules
+ * Multiple Locales (distributed memory system)
+ * Records
+ * Parallel iterators
+
+Your input, questions, and discoveries are important to the developers!
+-----------------------------------------------------------------------
+
+The Chapel language is still in-development (version 1.11.0), so there are occasional hiccups with performance and language features.
+The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
+Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
+
+If you're really interested in the development of the compiler or contributing to the project,
+[check out the master Github repository](https://github.com/chapel-lang/chapel).
+It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
+
+Installing the Compiler
+-----------------------
+
+Chapel can be built and installed on your average 'nix machine (and cygwin).
+[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
+and its as easy as
+
+ 1. `tar -xvf chapel-1.11.0.tar.gz`
+ 2. `cd chapel-1.11.0`
+ 3. `make`
+ 4. `source util/setchplenv.bash # or .sh or .csh or .fish`
+
+You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so its suggested that you drop that command in a script that will get executed on startup (like .bashrc).
+
+Chapel is easily installed with Brew for OS X
+
+ 1. `brew update`
+ 2. `brew install chapel`
+
+Compiling Code
+--------------
+
+Builds like other compilers:
+
+`chpl myFile.chpl -o myExe`
+
+Notable arguments:
+
+ * `--fast`: enables a number of optimizations and disables array bounds checks. Should only enable when application is stable.
+ * `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>` at compile-time.
+ * `--main-module <Module Name>`: use the main() procedure found in the module `<Module Name>` as the executable's main.
+ * `--module-dir <Directory>`: includes `<Directory>` in the module search path. \ No newline at end of file
diff --git a/clojure-macros.html.markdown b/clojure-macros.html.markdown
index 8e671936..9e907a7f 100644
--- a/clojure-macros.html.markdown
+++ b/clojure-macros.html.markdown
@@ -109,7 +109,7 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
(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
+;; help us support a (dumb) inline arithmetic syntax
(declare inline-2-helper)
(defn clean-arg [arg]
(if (seq? arg)
diff --git a/clojure.html.markdown b/clojure.html.markdown
index 7917ab08..a125d18f 100644
--- a/clojure.html.markdown
+++ b/clojure.html.markdown
@@ -22,7 +22,7 @@ and often automatically.
; Clojure is written in "forms", which are just
; lists of things inside parentheses, separated by whitespace.
;
-; The clojure reader assumes that the first thing is a
+; The clojure reader assumes that the first thing is a
; function or macro to call, and the rest are arguments.
; The first call in a file should be ns, to set the namespace
diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown
index c4ecb5e8..f9f64d68 100644
--- a/common-lisp.html.markdown
+++ b/common-lisp.html.markdown
@@ -573,13 +573,15 @@ nil ; for false - and the empty list
"While `condition` is true, `body` is executed.
`condition` is tested prior to each execution of `body`"
- (let ((block-name (gensym)))
+ (let ((block-name (gensym)) (done (gensym)))
`(tagbody
+ ,block-name
(unless ,condition
- (go ,block-name))
+ (go ,done))
(progn
,@body)
- ,block-name)))
+ (go ,block-name)
+ ,done)))
;; Let's look at the high-level version of this:
diff --git a/compojure.html.markdown b/compojure.html.markdown
index 36a8d123..32181e26 100644
--- a/compojure.html.markdown
+++ b/compojure.html.markdown
@@ -155,8 +155,8 @@ Now, your handlers may utilize query parameters:
```clojure
(defroutes myapp
(GET "/posts" req
- (let [title (get (:params req) "title")
- author (get (:params req) "author")]
+ (let [title (get (:params req) :title)
+ author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
```
@@ -165,8 +165,8 @@ Or, for POST and PUT requests, form parameters as well
```clojure
(defroutes myapp
(POST "/posts" req
- (let [title (get (:params req) "title")
- author (get (:params req) "author")]
+ (let [title (get (:params req) :title)
+ author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
```
diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown
index 88318014..19ea9e87 100644
--- a/de-de/yaml-de.html.markdown
+++ b/de-de/yaml-de.html.markdown
@@ -1,10 +1,11 @@
---
language: yaml
-filename: learnyaml.yaml
contributors:
- ["Adam Brenecki", "https://github.com/adambrenecki"]
translators:
- - ["Ruben M.", https://github.com/switchhax]
+ - ["Ruben M.", "https://github.com/switchhax"]
+filename: learnyaml-de.yaml
+lang: de-de
---
YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann.
diff --git a/el-gr/racket-gr.html.markdown b/el-gr/racket-gr.html.markdown
new file mode 100644
index 00000000..4c4576bb
--- /dev/null
+++ b/el-gr/racket-gr.html.markdown
@@ -0,0 +1,745 @@
+---
+language: racket
+filename: learnracket-gr.rkt
+contributors:
+ - ["th3rac25", "https://github.com/voila"]
+ - ["Eli Barzilay", "https://github.com/elibarzilay"]
+ - ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
+ - ["Duong H. Nguyen", "https://github.com/cmpitg"]
+ - ["Keyan Zhang", "https://github.com/keyanzhang"]
+translators:
+ - ["Vasilis Panagiotopoulos" , "https://github.com/billpcs/"]
+lang: el-gr
+---
+
+H Racket είναι μια γενικού σκοπού, πολυ-υποδειγματική γλώσσα προγραμματισμού που ανήκει
+στην οικογένεια της Lisp/Scheme
+
+```racket
+#lang racket ; ορίζει την γλώσσα που χρησιμοποιόυμε
+
+;;; Σχόλια
+
+;; Τα σχόλια μιας γραμμής ξεκινούν με ερωτηματικό
+
+#| Τα σχόλια ολόκληρου μπλόκ
+ μπορούν να εκτείνονται σε πολλές γραμμές και...
+ #|
+ μπορούν να είναι εμφωλευμένα!
+ |#
+|#
+
+;; Τα σχόλια S-expression (εκφράσεις S) comments απορρίπτουν την
+;; έκφραση που ακολουθεί, δυνατότητα που είναι χρήσιμη για να
+;; κάνουμε σχόλια κάποιες εκφράσεις κατα τη διάρκεια του debugging
+
+#; (αυτή η έκφραση δεν θα εκτελεστεί)
+
+;; (Αν δεν καταλαβαίνεται τι είναι οι εκφράσεις , περιμένετε... Θα το μάθουμε
+;; πολύ συντομα!)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. Πρωτογενείς τύποι μεταβλητών και τελεστές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Αριθμοί
+9999999999999999999999 ; ακέραιοι
+#b111 ; δυαδικοί => 7
+#o111 ; οκταδικοί => 73
+#x111 ; δεκαεξαδικοί => 273
+3.14 ; πραγματικοί
+6.02e+23
+1/2 ; ρητοί
+1+2i ; μιγαδικοί
+
+;; Οι μορφή των συναρτήσεων είναι (f x y z)
+;; όπου το f είναι η συνάρτηση και τα x y z
+;; είναι οι όροι που η συνάρτηση δέχεται
+;; ως ορίσματα. Αν θέλουμε να δημιουργήσουμε
+;; μια λίστα στην κυριολεξία απο δίαφορα δεδομένα,
+;; χρησιμοποιούμε το ' για να το εμποδίσουμε απο το να
+;; αξιολογηθεί σαν έκφραση. Για παράδειγμα:
+'(+ 1 2) ; => Παραμένει (+ 1 2) και δεν γίνεται η πράξη
+;; Τώρα , ας κάνουμε μερικές πράξεις
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(quotient 5 2) ; => 2
+(remainder 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(exact->inexact 1/3) ; => 0.3333333333333333
+(+ 1+2i 2-3i) ; => 3-1i
+
+;;; Λογικές μεταβλητές
+#t ; για το true (αληθής)
+#f ; για το false (ψευδής)
+(not #t) ; => #f
+(and 0 #f (error "doesn't get here")) ; => #f
+(or #f 0 (error "doesn't get here")) ; => 0
+
+;;; Χαρακτήρες
+#\A ; => #\A
+#\λ ; => #\λ
+#\u03BB ; => #\λ
+
+;;; Τα αλφαριθμητικά είναι πίνακες χαρακτήρων συγκεκριμένου μήκους
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; Το backslash είναι χαρακτήρας διαφυγής
+"Foo\tbar\41\x21\u0021\a\r\n" ; Συμπεριλαμβάνονται οι χαρακτήες διαφυγής της C,
+ ; σε Unicode
+"λx:(μα.α→α).xx" ; Μπορούν να υπάρχουν και Unicode χαρακτήρες
+
+;; Μπορούμε να εννώσουμε αλφαριθμητικά!
+(string-append "Hello " "world!") ; => "Hello world!"
+
+;; Ένα αλφαριθμητικό μπορούμε να το χρησιμοπιησουμε
+;; όπως και μια λίστα απο χαρακτήρες
+(string-ref "Apple" 0) ; => #\A ;; Παίρνουμε το πρώτο στοιχείο
+
+;; Η συνάρτηση format μπορεί να χρησιμοποιηθεί για
+;; να μορφοποιήσουμε αλφαριθμητικά
+(format "~a can be ~a" "strings" "formatted") ;; => "strings can be formatted"
+
+;; Η εκτύπωση είναι εύκολη.
+(printf "I'm Racket. Nice to meet you!\n")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Μεταβλητές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Μπορούμε να δημιουργήσουμε μεταβλητές
+;; χρησιμοποιώντας το define.
+;; Ένα όνομα μεταβλητής μπορεί να χρησιμοποιεί οποιονδήποτε
+;; χαρακτήρα, εκτός από τους: ()[]{}",'`;#|\
+(define some-var 5)
+some-var ; => 5
+
+;; Μπορούμε επίσης να χρησιμοποιήσουμε unicode χαρακτήρες.
+(define ⊆ subset?) ;; Εδώ ουστιαστικά δίνουμε στη ήδη ύπαρχουσα συνάρτηση subset?
+ ;; ένα νέο όνομα ⊆ , και παρακάτω την καλούμε με το νέο της όνομα.
+(⊆ (set 3 2) (set 1 2 3)) ; => #t
+
+;; Αν ζητήσουμε μια μεταβλητή που δεν έχει οριστεί πρίν π.χ
+(printf name)
+;; θα πάρουμε το παρακάτω μήνυμα
+;name: undefined;
+; cannot reference undefined identifier
+; context...:
+
+;; Η τοπική δέσμευση : `me' δευσμεύεται με το "Bob" μόνο μέσα στο (let ...)
+(let ([me "Bob"])
+ "Alice"
+ me) ; => "Bob"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Δομές και συλλογές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Δομές
+(struct dog (name breed age))
+(define my-pet
+ (dog "lassie" "collie" 5))
+my-pet ; => #<dog>
+(dog? my-pet) ; => #t
+(dog-name my-pet) ; => "lassie"
+
+;;; Ζεύγη (αμετάβλητα)
+;; Η δεσμευμένη λέξη `cons' δημιουργεί ζεύγη,
+;; και το `car' και το `cdr' εξάγουν το πρώτο και
+;; το δεύτερο στοιχείο αντίστοιχα.
+(cons 1 2) ; => '(1 . 2)
+(car (cons 1 2)) ; => 1
+(cdr (cons 1 2)) ; => 2
+
+;;; Λίστες
+
+;; Οι λίστες είναι linked-list δομές δεδομένων,
+;; που έχουν δημιουργηθεί απο ζευγάρια 'cons'
+;; και τελειώνουν με 'null' (ή αλλιώς '()) για να
+;; δηλώσουν ότι αυτό είναι το τέλος της λίστας
+(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
+;; Η δεσμευμένη λέξη 'list' είναι ένας εναλλακτικός
+;; (και σαφώς πιο βολικός) τρόπος για να δημιουργούμε
+;; λίστες
+(list 1 2 3) ; => '(1 2 3)
+;; αλλά και χρησιμοποιώντας ένα μονό εισαγωγικό το
+;; το αποτέλεσμα είναι και πάλι το ίδιο
+'(1 2 3) ; => '(1 2 3)
+
+;; Μπορούμε και πάλι όμως να χρησιμοποιούμε το 'cons' για να
+;; προσθέσουμε ένα στοιχείο στην αρχή της λίστας
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;; Μπορούμε να χρησιμοποιούμε το 'append' για να προσθέτουμε
+;; στοιχεία στο τέλος μιας λίστας. Το στοιχείο αυτό μπορεί
+;; και να είναι ολόκληρη λίστα!
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;; Οι λίστες στην Racket είναι πολύ βασικές , οπότε υπάρχουν πολλές
+;; δυνατές λειτουργίες για αυτές. Παρακάτω είναι μερικά παραδείγματα:
+(map add1 '(1 2 3)) ; => '(2 3 4)
+(map + '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(filter even? '(1 2 3 4)) ; => '(2 4)
+(count even? '(1 2 3 4)) ; => 2
+(take '(1 2 3 4) 2) ; => '(1 2)
+(drop '(1 2 3 4) 2) ; => '(3 4)
+
+;;; Διανύσματα
+
+;; Τα διανύσματα είναι πίνακες σταθερού μήκους
+#(1 2 3) ; => '#(1 2 3)
+
+;; Χρησιμοποιύμε το `vector-append' για να προσθέσουμε διανύσματα
+(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+;;; Σύνολα
+
+;; Δημιουργούμε ένα σύνολο απο μία λίστα
+(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
+
+;; Προσθέτουμε έναν αριθμό στο σύνολο χρησιμοποιώντας το `set-add'
+(set-add (set 1 2 3) 4) ; => (set 1 2 3 4)
+
+;; Αφαιρούμε με το `set-remove'
+(set-remove (set 1 2 3) 1) ; => (set 2 3)
+
+;; Βλέπουμε αν υπάρχει ένας αριθμός στο σύνολο με το `set-member?'
+(set-member? (set 1 2 3) 1) ; => #t
+(set-member? (set 1 2 3) 4) ; => #f
+
+;;; Πίνακες κατακερματισμού (Hashes)
+
+;; Δημιουργήστε ένα αμετάβλητο πίνακα κατακερματισμού
+(define m (hash 'a 1 'b 2 'c 3))
+
+;; Παίρνουμε μια τιμή απο τον πίνακα
+(hash-ref m 'a) ; => 1
+
+;; Άν ζητήσουμε μια τιμή που δέν υπάρχει παίρνουμε μία εξαίρεση
+; (hash-ref m 'd) => no value found for key
+
+;; Μπορούμε να δώσουμε μια default τιμή για τα κλειδιά που λείπουν
+(hash-ref m 'd 0) ; => 0
+
+
+;; Χρησιμοποιούμε το 'hash-set' για να επεκτείνουμε
+;; ένα πίνακα κατακερματισμού
+(define m2 (hash-set m 'd 4))
+m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
+
+;; Θυμηθείτε ! Αυτοί οι πίνακες κατακερματισμού
+;; είναι αμετάβλητοι!
+m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
+
+;; Χρησιμοποιούμε το `hash-remove' για να αφαιρέσουμε
+;; κλειδία
+(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Συναρτήσεις
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Χρησιμοποιούμε το `lambda' για να δημιουργήσουμε συναρτήσεις.
+;; Μια συνάρτηση πάντα επιστρέφει την τιμή της τελευταίας της έκφρασης
+(lambda () "Hello World") ; => #<procedure>
+;; Μπορούμε επίσης να χρησιμοποιήσουμε το `λ'
+(λ () "Hello World") ; => Ίδια συνάρτηση
+
+;; Χρησιμοποιύμε τις παρενθέσεις για να καλέσουμε όλες τις συναρτήσεις
+;; συμπεριλαμβανομένων και των εκφράσεων 'λάμδα'
+((lambda () "Hello World")) ; => "Hello World"
+((λ () "Hello World")) ; => "Hello World"
+
+;; Εκχωρούμε σε μια μετάβλητη την συνάρτηση
+(define hello-world (lambda () "Hello World"))
+(hello-world) ; => "Hello World"
+
+;; Μπορούμε αυτό να το κάνουμε συντομότερο χρησιμοποιώντας
+;; το λεγόμενο syntactic sugar :
+(define (hello-world2) "Hello World")
+
+;; Το () στο παραπάνω είναι η λίστα από τα ορίσματα για την συνάρτηση
+
+(define hello
+ (lambda (name)
+ (string-append "Hello " name)))
+(hello "Steve") ; => "Hello Steve"
+;; ... ή ισοδύναμα, χρησιμοποιώντας sugared ορισμό:
+(define (hello2 name)
+ (string-append "Hello " name))
+
+;; Μπορούμε να έχουμε συναρτήσεις με πολλές μεταβλητές χρησιμοποιώντας
+;; το `case-lambda'
+(define hello3
+ (case-lambda
+ [() "Hello World"]
+ [(name) (string-append "Hello " name)]))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+;; ... ή να ορίσουμε προαιρετικά ορίσματα με μια έκφραση προκαθορισμένης τιμής
+(define (hello4 [name "World"])
+ (string-append "Hello " name))
+
+;; Οι συναρτήσεις μπορούν να πακετάρουν επιπλέον
+;; ορίσματα μέσα σε μια λίστα
+(define (count-args . args)
+ (format "You passed ~a args: ~a" (length args) args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+;; ... ή με unsugared μορφή `lambda':
+(define count-args2
+ (lambda args
+ (format "You passed ~a args: ~a" (length args) args)))
+
+;; Μπορούμε να εμπλέξουμε κανονικά και πακεταρισμένα ορίσματα
+(define (hello-count name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args)))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+;; ... και unsugared:
+(define hello-count2
+ (lambda (name . args)
+ (format "Hello ~a, you passed ~a extra args" name (length args))))
+
+;; Και με λέξεις κλειδία
+(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
+ (format "~a ~a, ~a extra args" g name (length args)))
+(hello-k) ; => "Hello World, 0 extra args"
+(hello-k 1 2 3) ; => "Hello World, 3 extra args"
+(hello-k #:greeting "Hi") ; => "Hi World, 0 extra args"
+(hello-k #:name "Finn" #:greeting "Hey") ; => "Hey Finn, 0 extra args"
+(hello-k 1 2 3 #:greeting "Hi" #:name "Finn" 4 5 6)
+ ; => "Hi Finn, 6 extra args"
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Ισότητα
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; για αριθμούς χρησιμοποιούμε το `='
+(= 3 3.0) ; => #t
+(= 2 1) ; => #f
+
+;; Το `eq?' επιστρέφει #t αν δύο 2 ορίσματα αναφέρονται στο
+;; ίδιο αντικείμενο (στη μνήμη),αλλιώς επιστρέφει #f.
+;; Με άλλα λόγια, είναι απλή σύγκριση δεικτών.
+(eq? '() '()) ; => #t, αφού υπάρχει μόνο μια άδεια λίστα στη μνήμη
+(let ([x '()] [y '()])
+ (eq? x y)) ; => #t, το ίδιο με πάνω
+
+(eq? (list 3) (list 3)) ; => #f
+(let ([x (list 3)] [y (list 3)])
+ (eq? x y)) ; => #f — δεν είναι η ίδια λίστα στην μνήμη!
+
+(let* ([x (list 3)] [y x])
+ (eq? x y)) ; => #t, Αφού το x και το y τώρα δείχνουν στην ίδια θέση
+
+(eq? 'yes 'yes) ; => #t
+(eq? 'yes 'no) ; => #f
+
+(eq? 3 3) ; => #t — να είστε προσεκτικοί εδώ
+ ; Είναι προτιμότερο να χρησιμοποιείτε `=' για την
+ ; σύγκριση αριθμών.
+(eq? 3 3.0) ; => #f
+
+(eq? (expt 2 100) (expt 2 100)) ; => #f
+(eq? (integer->char 955) (integer->char 955)) ; => #f
+
+(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; Το `eqv?' υποστηρίζει την σύκριση αριθμών αλλα και χαρακτήρων
+;; Για άλλα ήδη μεταβλητών το `eqv?' και το `eq?' επιστρέφουν το ίδιο.
+(eqv? 3 3.0) ; => #f
+(eqv? (expt 2 100) (expt 2 100)) ; => #t
+(eqv? (integer->char 955) (integer->char 955)) ; => #t
+
+(eqv? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; Το `equal?' υποστηρίζει την σύγκριση των παρακάτω τύπων μεταβλητών:
+;; αλφαριθμητικά, αλφαριθμητικά από bytes, μεταβλητά ζεύγη , διανύσματα,
+;; πίνακες κατακερματισμού και δομές.
+;; Για άλλα ήδη τύπων μεταβλητών το `equal?' και το `eqv?' επιστρέφουν το
+;; ίδιο αποτέλεσμα.
+(equal? 3 3.0) ; => #f
+(equal? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #t
+(equal? (list 3) (list 3)) ; => #t
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Έλεχγος Ροής
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Συνθήκες (conditionals)
+
+(if #t ; έκφραση ελέχγου
+ "this is true" ; έκφραση then
+ "this is false") ; έκφραση else
+; => "this is true"
+
+
+;; Στα conditionals, όλες οι μη #f τιμές θεωρούνται ως #t
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(Groucho Zeppo)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'yep
+
+;; Οι αλυσίδες `cond' είναι σειρές από ελέγχους για να
+;; επιλεγεί ένα αποτέλεσμα
+(cond [(> 2 2) (error "wrong!")]
+ [(< 2 2) (error "wrong again!")]
+ [else 'ok]) ; => 'ok
+
+;;; Αντιστοίχιση μοτίβων
+
+(define (fizzbuzz? n)
+ (match (list (remainder n 3) (remainder n 5))
+ [(list 0 0) 'fizzbuzz]
+ [(list 0 _) 'fizz]
+ [(list _ 0) 'buzz]
+ [_ #f]))
+
+(fizzbuzz? 15) ; => 'fizzbuzz
+(fizzbuzz? 37) ; => #f
+
+;;; Βρόχοι
+
+;; Οι επαναλήψεις μπορούν να γίνουν μέσω αναδρομής
+(define (loop i)
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i))))
+(loop 5) ; => i=5, i=6, ...
+
+;; Παρομοίως με τη χρήση 'let'
+(let loop ((i 0))
+ (when (< i 10)
+ (printf "i=~a\n" i)
+ (loop (add1 i)))) ; => i=0, i=1, ...
+
+
+;; Θα δείτε παρακάτω πως να προσθέσουμε μια νέα μορφή επανάληψης
+;; αλλά η Racket έχει ήδη πολύ ευέλικτη μορφή για τους βρόχους
+(for ([i 10])
+ (printf "i=~a\n" i)) ; => i=0, i=1, ...
+(for ([i (in-range 5 10)])
+ (printf "i=~a\n" i)) ; => i=5, i=6, ...
+
+;;;
+;;; Επανάληψη μέσα σε ακολουθίες:
+;; Το `for' επιτρέπει την επανάληψη μέσα σε πολλά
+;; άλλα ήδη από ακολουθίες: Λίστες, διανύσματα,
+;; αλφαριθμητικά, σύνολα κτλ..
+
+(for ([i (in-list '(l i s t))])
+ (displayln i))
+
+(for ([i (in-vector #(v e c t o r))])
+ (displayln i))
+
+(for ([i (in-string "string")])
+ (displayln i))
+
+(for ([i (in-set (set 'x 'y 'z))])
+ (displayln i))
+
+(for ([(k v) (in-hash (hash 'a 1 'b 2 'c 3 ))])
+ (printf "key:~a value:~a\n" k v))
+
+;;; Πιο περίπλοκες επαναλήψεις
+
+;; Παράλληλη σάρωση σε πολλαπλές ακολουθίες
+;; (σταματά στην πιο σύντομη)
+(for ([i 10] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x 1:y 2:z
+
+;; Εμφολευμένοι βρόχοι
+(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j))
+; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z
+
+;; Συνθήκες
+(for ([i 1000]
+ #:when (> i 5)
+ #:unless (odd? i)
+ #:break (> i 10))
+ (printf "i=~a\n" i))
+; => i=6, i=8, i=10
+
+;;; Σάρωση σε λίστες
+;; Παρόμοιο με τους βρόχους 'for', απλά συλλέγουμε τα αποτελέσματα
+
+(for/list ([i '(1 2 3)])
+ (add1 i)) ; => '(2 3 4)
+
+(for/list ([i '(1 2 3)] #:when (even? i))
+ i) ; => '(2)
+
+(for/list ([i 10] [j '(x y z)])
+ (list i j)) ; => '((0 x) (1 y) (2 z))
+
+(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10))
+ i) ; => '(6 8 10)
+
+(for/hash ([i '(1 2 3)])
+ (values i (number->string i)))
+; => '#hash((1 . "1") (2 . "2") (3 . "3"))
+
+;; Υπάρχουν πολλά είδη απο προϋπάρχοντες τρόπους για να συλλέγουμε
+;; τιμές από τους βρόχους
+
+(for/sum ([i 10]) (* i i)) ; => 285
+(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000
+(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
+(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
+
+;; Και για να χρησιμοποιήσουμε ένα αφθαίρετο συνδιασμό χρησιμοποιούμε
+;; το 'for/fold'
+(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
+
+;; Αυτό συχνά μπορεί να αντικαταστήσει τους κοινούς
+;; προστακτικούς βρόχους (imperative loops)
+
+;;; Εξαιρέσεις
+
+;; Για να πιάσουμε τις εξαιρέσεις χρησιμοποιούμε το
+;; `with-handlers'
+(with-handlers ([exn:fail? (lambda (exn) 999)])
+ (+ 1 "2")) ; => 999
+(with-handlers ([exn:break? (lambda (exn) "no time")])
+ (sleep 3)
+ "phew") ; => "phew", αλλά αν γίνει το break => "no time"
+
+;; Χρησιμοποιούμε το 'raise' για να άρουμε μια εξαίρεση
+;; ή οποιαδήποτε άλλη τιμή
+(with-handlers ([number? ; πιάνουμε αριθμητικές τιμές
+ identity]) ; και τις επιστρέφουμε σαν απλές τιμές
+ (+ 1 (raise 2))) ; => 2
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Αλλαγή τιμών
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Χρησιμοποιούμε το 'set!' για να θέσουμε μια νέα τιμή
+;; σε μια ήδη υπάρχουσα μεταβλητή
+(define n 5)
+(set! n (add1 n))
+n ; => 6
+
+;; Χρησιμοποιούμε τα boxes για να δηλώσουμε ρητά ότι μια μεταβητή
+;; θα είναι mutable (θα μπορεί να αλλάξη η τιμή της)
+;; Αυτό είναι παρόμοιο με τους pointers σε άλλες γλώσσες
+(define n* (box 5))
+(set-box! n* (add1 (unbox n*)))
+(unbox n*) ; => 6
+
+
+;; Πολλοί τύποι μεταβλητών στη Racket είναι αμετάβλητοι πχ τα ζεύγη, οι
+;; λίστες κτλ. Άλλοι υπάρχουν και σε μεταβλητή και σε αμετάβλητη μορφή
+;; πχ αλφαριθμητικά, διανύσματα κτλ
+(define vec (vector 2 2 3 4))
+(define wall (make-vector 100 'bottle-of-beer))
+;; Χρησιμοποιούμε το 'vector-set!' για να ανεώσουμε κάποια
+;; συγκεκριμένη θέση
+(vector-set! vec 0 1)
+(vector-set! wall 99 'down)
+vec ; => #(1 2 3 4)
+
+
+;; Έτσι δημιουργούμε ένα άδειο μεταβλητό πίνακα κατακερματισμού
+;; και τον χειριζόμαστε κατάλληλα
+(define m3 (make-hash))
+(hash-set! m3 'a 1)
+(hash-set! m3 'b 2)
+(hash-set! m3 'c 3)
+(hash-ref m3 'a) ; => 1
+(hash-ref m3 'd 0) ; => 0
+(hash-remove! m3 'a)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Ενότητες (modules)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; Οι ενότητες μας επιτρέπουν να οργανώνουμε τον κώδικα σε πολλαπλά
+;; αρχεία και επαναχρησιμοποιούμενες βιβλιοθήκες
+;; Εδώ χρησιμοποιούμε υπο-ενότητες, εμφωλευμένες μέσα σε μια
+;; άλλη ενότητα που δημιουργεί αυτό το κείμενο (ξεκινώντας από
+;; την γραμμή '#lang' )
+(module cake racket/base ; ορίζουμε μια ενότητα 'cake' βασισμένο στο
+ ; racket/base
+
+ (provide print-cake) ; συνάρτηση που εξάγεται από την ενότητα
+
+ (define (print-cake n)
+ (show " ~a " n #\.)
+ (show " .-~a-. " n #\|)
+ (show " | ~a | " n #\space)
+ (show "---~a---" n #\-))
+
+ (define (show fmt n ch) ; εσωτερική συνάρτηση
+ (printf fmt (make-string n ch))
+ (newline)))
+
+;; Χρησιμοποιομε το 'require' για να πάρουμε όλα τα
+;; παρεχόμενα ονόματα από μία ενότητα
+(require 'cake) ; το ' είναι για τοπική υποενότητα
+(print-cake 3)
+; (show "~a" 1 #\A) ; => error, το `show' δεν έχει εξαχθεί
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 8. Κλάσεις και αντικείμενα
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Δημιουργούμε μια κλάση fish% (- συνήθως χρησιμοποιούμε
+;; το % στο όνομα μιας κλάσης )
+(define fish%
+ (class object%
+ (init size) ; initialization argument
+ (super-new) ; superclass initialization
+ ;; Field
+ (define current-size size)
+ ;; Public methods
+ (define/public (get-size)
+ current-size)
+ (define/public (grow amt)
+ (set! current-size (+ amt current-size)))
+ (define/public (eat other-fish)
+ (grow (send other-fish get-size)))))
+
+;; Δημιουργούμε ένα instance του fish%
+(define charlie
+ (new fish% [size 10]))
+
+;; Χρησιμοποιούμε το 'send' για να καλέσουμε
+;; τις μεθόδους ενός αντικειμένου
+(send charlie get-size) ; => 10
+(send charlie grow 6)
+(send charlie get-size) ; => 16
+
+;; Το `fish%' είναι μία τιμή "πρώτης κλάσης"
+;; με το οποίο μπορούμε να κάνουμε προσμείξεις
+(define (add-color c%)
+ (class c%
+ (init color)
+ (super-new)
+ (define my-color color)
+ (define/public (get-color) my-color)))
+(define colored-fish% (add-color fish%))
+(define charlie2 (new colored-fish% [size 10] [color 'red]))
+(send charlie2 get-color)
+;; ή χωρίς καθόλου ονόματα :
+(send (new (add-color fish%) [size 10] [color 'red]) get-color)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 9. Μακροεντολές
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Οι μακροεντολές μας επιτρέπουν να επεκτείνουμε
+;; το συντακτικό μιάς γλώσσας.
+
+;; Ας προσθέσουμε έναν βρόχο while
+(define-syntax-rule (while condition body ...)
+ (let loop ()
+ (when condition
+ body ...
+ (loop))))
+
+(let ([i 0])
+ (while (< i 10)
+ (displayln i)
+ (set! i (add1 i))))
+
+;; Macros are hygienic, you cannot clobber existing variables!
+(define-syntax-rule (swap! x y) ; -! is idiomatic for mutation
+ (let ([tmp x])
+ (set! x y)
+ (set! y tmp)))
+
+(define tmp 2)
+(define other 3)
+(swap! tmp other)
+(printf "tmp = ~a; other = ~a\n" tmp other)
+;; Η μεταβλητή 'tmp' μετονομάζεται σε 'tmp_1'
+;; για να αποφευχθεί η σύγκρουση με τα ονόματα
+;; (let ([tmp_1 tmp])
+;; (set! tmp other)
+;; (set! other tmp_1))
+
+;; Αλλά ακόμα υπάρχουν ακόμη μετασχηματισμοί του κώδικα, π.χ:
+(define-syntax-rule (bad-while condition body ...)
+ (when condition
+ body ...
+ (bad-while condition body ...)))
+;; αυτή η μακροεντολή είναι χαλασμένη: δημιουγεί ατέρμονα βρόχο
+;; και αν προσπαθήσουμε να το χρησιμοποιήσουμε, ο μεταγλωττιστής
+;; θα μπεί στον ατέρμονα βρόχο.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 10. Συμβόλαια (Contracts)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Τα συμβόλαια βάζουν περιορισμόυς σε τιμές που προέρχονται
+;; από ενότητες (modules)
+(module bank-account racket
+ (provide (contract-out
+ [deposit (-> positive? any)] ; οι ποσότητες είναι πάντα θετικές
+ [balance (-> positive?)]))
+
+ (define amount 0)
+ (define (deposit a) (set! amount (+ amount a)))
+ (define (balance) amount)
+ )
+
+(require 'bank-account)
+(deposit 5)
+
+(balance) ; => 5
+
+;; Πελάτες που προσπαθούν να καταθέσουν ένα μη θετικό ποσό παίρνουν
+;; το μήνυμα (deposit -5) ; => deposit: contract violation
+;; expected: positive?
+;; given: -5
+;; more details....
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 11. Είσοδος και έξοδος
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Η Racket έχει την έννοια του "port", που είναι παρόμοιο με τα
+;; file descriptors σε άλλες γλώσσες.
+
+;; Ανοίγουμε το "/tmp/tmp.txt" και γράφουμε μέσα "Hello World"
+;; Αυτό θα προκαλούσε σφάλμα αν το αρχείο υπήρχε ήδη
+(define out-port (open-output-file "/tmp/tmp.txt"))
+(displayln "Hello World" out-port)
+(close-output-port out-port)
+
+;; Προσθέτουμε στο τέλος του "/tmp/tmp.txt"
+(define out-port (open-output-file "/tmp/tmp.txt"
+ #:exists 'append))
+(displayln "Hola mundo" out-port)
+(close-output-port out-port)
+
+;; Διαβάζουμε απο αρχείο ξανά
+(define in-port (open-input-file "/tmp/tmp.txt"))
+(displayln (read-line in-port))
+; => "Hello World"
+(displayln (read-line in-port))
+; => "Hola mundo"
+(close-input-port in-port)
+
+;; Εναλλακτικά, με το call-with-output-file δεν χρειάζεται να κλείσουμε
+;; ρητά το αρχείο
+(call-with-output-file "/tmp/tmp.txt"
+ #:exists 'update ; Rewrite the content
+ (λ (out-port)
+ (displayln "World Hello!" out-port)))
+
+;; Και το call-with-input-file κάνει το ίδιο πράγμα για την είσοδο
+(call-with-input-file "/tmp/tmp.txt"
+ (λ (in-port)
+ (displayln (read-line in-port))))
+```
+
+## Επιπλέον πηγές
+
+Ψάχνεις για περισσότερα ; [Getting Started with Racket](http://docs.racket-lang.org/getting-started/)
diff --git a/el-gr/scala-gr.html.markdown b/el-gr/scala-gr.html.markdown
new file mode 100644
index 00000000..e29c7e70
--- /dev/null
+++ b/el-gr/scala-gr.html.markdown
@@ -0,0 +1,689 @@
+---
+language: Scala
+contributors:
+ - ["George Petrov", "http://github.com/petrovg"]
+ - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+translators:
+ - ["Vasilis Panagiotopoulos" , "https://github.com/billpcs/"]
+filename: learnscala-gr.scala
+lang: el-gr
+---
+
+Scala - Η επεκτάσιμη γλώσσα
+
+```scala
+
+/*
+ Προετοιμαστείτε:
+
+ 1) Κατεβάστε την Scala - http://www.scala-lang.org/downloads
+ 2) Κάνετε εξαγωγή στην επιθυμητή σας τοποθεσία και βάλτε τον υποφάκελο bin
+ στο path του συστήματος
+ 3) Ξεκινήστε ένα scala REPL γράφοντας scala. Θα πρέπει να βλέπετε το prompt:
+
+ scala>
+
+ Αυτό είναι το αποκαλούμενο REPL (Read-Eval-Print Loop) *.
+ Μπορείτε να πληκτρολογήσετε οποιαδήποτε έγκυρη έκφραση σε Scala μέσα του ,
+ και το αποτέλεσμα θα τυπωθεί. Θα εξηγήσουμε πως μοιάζουν τα αρχεία της Scala
+ αργότερα μέσα στο tutorial , αλλά για τώρα ας αρχίσουμε με κάποια βασικά.
+ *[Βρόχος του Διάβασε - Αξιολόγησε - Τύπωσε]
+*/
+
+
+/////////////////////////////////////////////////
+// 1. Βασικές έννοιες
+/////////////////////////////////////////////////
+
+// Τα σχόλια μίας γραμμής ξεκινούν με δύο "/" (:forward slashes) .
+
+/*
+ Τα σχόλια που επεκτείνονται σε πολλές γραμμές , όπως μπορείτε
+ να δείτε , φαίνοται κάπως έτσι.
+*/
+
+// Εκτύπωση με νέα γραμμή στην επόμενη εκτύπωση
+println("Hello world!")
+println(10)
+
+// Εκτύπωση χωρίς νέα γραμμή στην επόμενη εκτύπωση
+print("Hello world")
+
+// Η δήλωση μεταβλητών γίνεται χρησιμοποιώντας var ή val.
+// Οι δηλώσεις val είναι αμετάβλητες, ενώ οι var είναι μεταβλητές.
+// Η αμεταβλητότητα είναι συμφέρουσα και προσπαθούμε να την χρησιμοποιούμε.
+val x = 10 // το x είναι τώρα 10
+x = 20 // σφάλμα: αλλαγή σε val
+var y = 10
+y = 20 // το y είναι τώρα 20
+
+/*
+ Η Scala είναι στατικού τύπου γλώσσα, εν τούτις προσέξτε ότι στις παραπάνω
+ δηλώσεις , δεν προσδιορίσαμε κάποιον τύπο. Αυτό συμβαίνει λόγω ενός
+ χαρακτηριστικού της Scala που λέγεται συμπερασματολογία τύπων. Στις
+ περισσότερες των περιπτώσεων, ο μεταγλωττιστής της Scala μπορεί να
+ μαντέψει ποιός είναι ο τύπος μιας μεταβλητής. Μπορούμε να δηλώσουμε
+ αναλυτικά τον τύπο μιάς μεταβλητής ως εξής:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+/*
+ Προσέξτε ότι υπάρχει αυτόματη μετατροπή από ακέραιο (Int) σε διπλής
+ ακρίβειας (Double), και συνεπώς το αποτέλεσμα είναι 10.0 και όχι 10.
+*/
+val b: Double = 10
+
+// Λογικές τιμές
+true
+false
+
+// Λογικές Πράξεις
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// Η αριθμιτική είναι όπως τα συνηθισμένα
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
+
+
+/*
+ Αξιολογώντας μια έκφραση στο REPL, σας δίνεται ο τύπος και
+ η τιμή του αποτελέσματος
+*/
+
+1 + 7
+
+/* Η παραπάνω γραμμή έχει το εξής αποτέλεσμα:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Αυτό σημαίνει ότι το αποτέλεσμα της αξιολόγησης του 1 + 7 είναι ένα αντικείμενο
+ τύπου Int με τιμή 8
+
+ Σημειώστε ότι το "res29" είναι ένα σειριακά δημιουργούμενο όνομα μεταβλητής
+ για να αποθηκεύονται τα αποτελέσματα των εκφράσεων που έχετε πληκτρολογήσει
+ και συνεπώς η έξοδός σας μπορεί να διαφέρει.
+*/
+
+"Τα αλφαριθμητικά στην Scala περικλείονται από διπλά εισαγωγικά"
+'a' // Ένας χαρακτήρας στην Scala
+// res30: Char = a
+// 'Αλφαριθημτικά με μονά εισαγωγικά δεν υφίστανται <= Αυτό θα προκαλέσει σφάλμα.
+
+// Τα αλφαριθμητικά έχουν τις συνηθισμένες μεθόδους της Java ορισμένες πάνω τους.
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
+
+// Έχουν επίσης μερικές επιπλένον μεθόδους Scala.
+// Δείτε επίσης : scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
+
+// Παρεμβολή αλφαριθμητικών : παρατηρήστε το πρόθεμα "s"
+val n = 45
+s"We have $n apples" // => "We have 45 apples"
+
+// Παρατηρήστε την χρήση των '{', '}'
+val a = Array(11, 9, 6)
+s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
+s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
+s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
+
+// Μορφοποίηση με παρεμβεβλημένα αλφαριθμητικά με το πρόθεμα "f"
+f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
+f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
+
+// Raw αλφαριθμητικά, που αγνοούν τους ειδικούς χαρακτήρες.
+raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
+
+// Μερικούς χαρακτήρες πρέπει να τους κάνουμε "escape",
+// λ.χ ένα διπλό εισαγωγικό μέσα σε ένα αλφαριθμητικό :
+"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
+
+/*
+ Τα τριπλά διπλά-εισαγωγικά επιτρέπουν στα αλφαριθμητικά να εκτείνονται σε
+ πολλαπλές γραμμές και να περιέχουν διπλά εισαγωγικά
+*/
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Συναρτήσεις
+/////////////////////////////////////////////////
+
+// Οι συναρτήσεις ορίζονται ως εξής:
+//
+// def functionName(args...): ReturnType = { body... }
+//
+// Αν προέρχεστε απο πιο παραδοσιακές γλώσσες (C/C++ , Java) παρατηρήστε
+// την παράλειψη του return. Στην Scala , η τελευταία έκφραση στο μπλόκ
+// της συνάρτησης είναι η τιμή που επιστρέφει η συνάρτηση.
+def sumOfSquares(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// Τα { } μπορούν να παραλειφθούν αν η συνάρτηση αποτελείται απο μια απλή έκφραση:
+def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
+
+// Η σύνταξη για την κλήση συναρτήσεων είναι γνώριμη:
+sumOfSquares(3, 4) // => 25
+
+// Στις περισσότερες των περιπτώσεων (με τις αναδρομικές συναρτήσεις να αποτελούν
+// την πιο αξιοπρόσεκτη εξαίρεση) , ο τύπος επιστροφής της συνάρτησης μπορεί να
+// παραλειφθεί, και η ίδια συμπερασματολογία τύπων που είδαμε με τις μεταβλητές
+// θα δουλεύει και με τους τύπους επιστροφής της συνάρτησης:
+def sq(x: Int) = x * x // Ο μεταγλωττιστής μπορεί να μαντέψει ότι
+ // ο τύπος επιστροφής της συνάρτησης είναι Int
+
+// Οι συναρτήσεις μπορούν να έχουν προκαθορισμένες τιμές:
+def addWithDefault(x: Int, y: Int = 5) = x + y
+addWithDefault(1, 2) // => 3
+addWithDefault(1) // => 6
+
+
+// Οι ανώνυμες συναρτήσεις είναι ως εξής:
+(x:Int) => x * x
+
+// Σε αντίθεση με τα defs , ακόμα και ο τύπος εισόδου απο τις ανώνυμες
+// συναρτήσεις μπορεί να παραληφθεί αν τα συμφραζόμενα το κάνουν ξεκάθαρο.
+// Προσέξτε τον τύπο "Int => Int" που σημαίνει ότι μια συνάρτηση παίρνει
+// ένα Int και επιστρέφει ένα Int.
+val sq: Int => Int = x => x * x
+
+// Οι ανώνυμες συναρτήσεις μπορούν να κληθούν όπως συνήθως:
+sq(10) // => 100
+
+// Αν κάθε όρισμα στην ανώνυμη συνάρτηση χρησιμοποιείται μόνο μία φορά,
+// η Scala επιτρέπει έναν ακόμα πιο σύντομο τρόπο να οριστεί. Αυτές
+// οι ανώνυμες συναρτήσεις αποδεικνύεται ότι είναι πολύ κοινές ,
+// όπως θα γίνει προφανές στο μέρος των δομών δεδομένων.
+val addOne: Int => Int = _ + 1
+val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+addOne(5) // => 6
+weirdSum(2, 4) // => 16
+
+// Η δεσμευμένη λέξη return υπάρχει στην Scala , αλλά επιστρέφει μόνο
+// από το πιο εσωτερικό def που την περικλείει.
+// ΠΡΟΣΟΧΗ: Η χρήση του return στην Scala είναι επιρρεπής σε λάθη
+// και θα πρέπει να αποφεύγεται.
+// Δεν έχει καμία επίδραση στις ανώνυμες συναρτήσεις. Για παράδειγμα:
+def foo(x: Int): Int = {
+ val anonFunc: Int => Int = { z =>
+ if (z > 5)
+ return z // Αυτή η σειρά κάνει το z την τιμή που επιστρέφει η foo!
+ else
+ z + 2 // Αυτή η γραμμή είναι η τιμή που επιστρέφει η anonFunc
+ }
+ anonFunc(x) // Αυτή η γραμμή είναι η τιμή που επιστρέφει η foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Έλεγχος ροής
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach( println )
+
+r foreach println
+// ΠΡΟΣΟΧΗ: Η Scala είναι σχετικά επιεικής ως αναφορά τις τελείες και
+// τις παρενθέσεις. Διαβάστε τους κανόνες ξεχωριστά.
+// Αυτό βοηθάει στο να γράφεις DSLs και APIs που διαβάζονται σαν τα Αγγλικά.
+
+(5 to 1 by -1) foreach ( println )
+
+// Ένας βρόχος while :
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+while (i < 10) { println("i " + i); i+=1 } // Ναι ξανά! Τι συνέβει; Γιατί;
+
+i // Εμφάνισε την τιμή του i. Σημειώστε ότι ένας βρόχος while είναι βρόχος
+ // με την κλασική έννοια - εκτελείται σειριακά καθώς αλλάζει η μεταβλητή
+ // του βρόχου. Το while είναι πολύ γρήγορο , γρηγορότερο απο τους βρόχους
+ // της Java , αλλά η χρήση combinators και comprehensions όπως πιο πάνω ,
+ // είναι πιο εύκολη στην κατανόηση και στην παραλληλοποίηση.
+
+// Ένας βρόχος do while :
+do {
+ println("x is still less than 10");
+ x += 1
+} while (x < 10)
+
+// Η αναδρομή ουράς είναι ένας ιδιωματικός τρόπος να κάνεις επαναλαμβανόμενα
+// πράγματα στην Scala. Οι αναδρομικές συναρτήσεις απαιτούν να γράφτεί
+// ρητά ο τύπος που θα επιστρέψουν , αλλιώς ο μεταγλωττιστής δεν μπορεί
+// αλλιώς να τον συνάγει. Παρακάτω είναι μια συνάρτηση που επιστρέφει Unit.
+def showNumbersInRange(a:Int, b:Int):Unit = {
+ print(a)
+ if (a < b)
+ showNumbersInRange(a + 1, b)
+}
+showNumbersInRange(1,14)
+
+
+// Έλεγχος Ροής
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Δομές Δεδομένων
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0)
+a(3)
+a(21) // "Πετάει" exception
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork")
+m("spoon")
+m("bottle") // "Πετάει" exception
+
+val safeM = m.withDefaultValue("no lo se")
+safeM("bottle")
+
+val s = Set(1, 3, 7)
+s(0)
+s(1)
+
+/* Δείτε το documentation του map εδώ -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ */
+
+
+// Πλειάδες
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Γιατί να το έχουμε αυτό;
+val divideInts = (x:Int, y:Int) => (x / y, x % y)
+
+divideInts(10,3) // Η συνάρτηση divideInts επιστρέφει το αποτέλεσμα
+ // της ακαίρεας διαίρεσης και το υπόλοιπο.
+
+// Για να έχουμε πρόσβαση στα στοιχεία μιας πλειάδας, χρησιμοποιούμε το _._n
+// όπου το n είναι ο δείκτης με βάση το 1 του στοιχείου.
+val d = divideInts(10,3)
+
+d._1
+
+d._2
+
+
+/////////////////////////////////////////////////
+// 5. Αντικειμενοστραφής Προγραμματισμός
+/////////////////////////////////////////////////
+
+/*
+ Ότι έχουμε κάνει ως τώρα σε αυτό το tutorial ήταν απλές εκφράσεις
+ (τιμές , συναρτήσεις , κτλ). Αυτές οι εκφράσεις βολεύουν όταν τις
+ γράφουμε στο REPL για γρήγορες δοκιμές, αλλά δεν μπορούν να υπάρχουν
+ από μόνες τους σε ένα αρχείο Scala. Για παράδειγμα , δεν μπορούμε να
+ έχουμε μόνο ένα "val x = 5" στο αρχείο Scala. Αντί αυτού , τα μόνα
+ στοιχεία του πάνω επιπέδου που επιτρέπονται στην Scala είναι:
+
+ - αντικείμενα (objects)
+ - κλάσεις (classes)
+ - κλάσεις περίπτωσης (case classes στην Scala)
+ - Χαρακτηριστικά (traits , όπως ονομάζονται στην Scala)
+
+ Και τώρα θα εξηγήσουμε τι είναι αυτά.
+*/
+// Οι κλάσεις είναι παρόμοιες με τις κλάσεις σε άλλες γλώσσες. Τα ορίσματα του
+// "κατασκευαστή" (constructor) δηλώνονται μετά από το όνομα της κλάσης ,
+// και η αρχικοποιήση γίνεται μέσα στο σώμα της κλάσης.
+class Dog(br: String) {
+ // Κώδικας για τον "κατασκευαστή"
+ var breed: String = br
+
+ // Ορίζεται μια μέθοδος bark , που επιστρέφει ένα αλφαριθμητικό
+ def bark = "Woof, woof!"
+
+ // Οι τιμές και οι μέθοδοι είναι public εκτός αν χρησιμοποιήσουμε κάποια
+ // απο τις λέξεις κλειδιά "protected" και "private" .
+ private def sleep(hours: Int) =
+ println(s"I'm sleeping for $hours hours")
+
+ // Οι abstract μέθοδοι είναι απλά μέθοδοι χωρίς σώμα. Αν βγάζαμε
+ // το σχόλιο απο την επόμενη γραμμή η κλάση Dog θα έπρεπε να
+ // δηλωθεί ως abstract class Dog(...) { ... } :
+ // def chaseAfter(what: String): String
+}
+
+val mydog = new Dog("greyhound")
+println(mydog.breed) // => "greyhound"
+println(mydog.bark) // => "Woof, woof!"
+
+
+// Η λέξη "object" δημιουργεί ένα type ΚΑΙ ένα singleton instance αυτού.
+// Είναι κοινό για τις κλάσεις στην Scala να έχουν ένα "συντροφικό object",
+// όπου η συμπεριφορά για κάθε instance αιχμαλωτίζεται μέσα στις κλάσεις
+// αυτές καθ' αυτές, αλλά η συμπρεριφορά που σχετίζεται με όλα τα instances
+// της κλάσης πάνε μέσα στο object. Η διαφορά είναι παρόμοια με τις
+// μεθόδους κλάσεων σε σχέση με στατικές μεθόδους σε άλλες γλώσσες.
+// Προσέξτε οτι τα objects και οι κλάσεις μπορούν να έχουν το ίδιο όνομα.
+object Dog {
+ def allKnownBreeds = List("pitbull", "shepherd", "retriever")
+ def createDog(breed: String) = new Dog(breed)
+}
+
+// Οι κλάσεις περίπτωσης (case classes) είναι που έχουν την επιπλέον
+// λειτουργικότητα ενσωματωμένη. Μιά συνήθης ερώτηση για αρχάριους στην
+// Scala είναι πότε να χρησιμοπούνται κλάσεις και πότε case κλάσεις.
+// Γενικά οι κλάσεις τείνουν να εστιάζουν στην ενθυλάκωση, τον
+// πολυμορφισμό και τη συμπεριφορά. Οι τιμές μέσα σε αυτές τις κλάσεις
+// τείνουν να είναι private , και μόνο οι μέθοδοι είναι εκτεθειμένες.
+// Ο κύριος σκοπός των case classes είναι να κρατούν δεδομένα που είναι
+// σταθερές(immutable). Συνήθως έχουν λίγες μεθόδους και οι μέθοδοι σπάνια
+// έχουν παρενέργειες.
+case class Person(name: String, phoneNumber: String)
+
+// Δημιουργία ενός instance. Πραρατηρήστε ότι τα case classes
+// δεν χρειάζονται την λέξη "new" .
+val george = Person("George", "1234")
+val kate = Person("Kate", "4567")
+
+// Με τα case classes, παίρνεις μερικά προνόμια δωρεάν , όπως:
+george.phoneNumber // => "1234"
+
+// Ελέχγεται η ισότητα για κάθε πεδίο (δεν χρειάζεται να
+// κάνουμε override στο .equals)
+Person("George", "1234") == Person("Kate", "1236") // => false
+
+// Έυκολος τρόπος να κάνουμε αντιγραφή. Δημιουργούμε έναν νέο geroge:
+// otherGeorge == Person("george", "9876")
+val otherGeorge = george.copy(phoneNumber = "9876")
+
+// Και πολλά άλλα. Τα case classes έχουν και αντιστοίχιση προτύπων
+// (pattern matching) δωρεάν, δείτε παρακάτω.
+
+// Τα χαρακτηριστικά (traits) έρχονται σε λίγο καιρό !
+
+/////////////////////////////////////////////////
+// 6. Αντιστοίχιση Προτύπων
+/////////////////////////////////////////////////
+
+// Η αντιστοίχιση προτύπων (pattern matching) είναι ένα πολύ δυνατό και
+// ευρέως χρησιμοποιούμενο χαρακτηριστικό στην Scala. Παρακάτω βλέπουμε
+// πως γίνεται το pattern matching σε ένα case class. Σημείωση: Σε
+// αντίθεση με άλλες γλώσσες η Scala δεν χρειάζεται breaks, γιατί γίνεται
+// αυτόματα όταν γίνει κάποιο match.
+
+def matchPerson(person: Person): String = person match {
+ // Μετά προσδιορίζουμε το πρότυπο (pattern):
+ case Person("George", number) => "We found George! His number is " + number
+ case Person("Kate", number) => "We found Kate! Her number is " + number
+ case Person(name, number) => "We matched someone : " + name + ", phone : " + number
+}
+
+val email = "(.*)@(.*)".r // Ορίζουμε ένα regex για το επόμενο παράδειγμα.
+ // (regex <- REGular EXpression)
+
+// Το pattern matching μπορεί να μοιάζει γνώριμο απο τα switch statements σε
+// γλώσσες που ανήκουν στην οικογένεια της C αλλά είναι πολύ πιο ισχυρό.
+// Στην Scala , μπορούμε να κάνουμε match πολύ περισσότερα:
+def matchEverything(obj: Any): String = obj match {
+ // Μπορούμε να ταιριάξουμε τιμές:
+ case "Hello world" => "Got the string Hello world"
+
+ // Μπορούμε να ταιριάξουμε τύπους:
+ case x: Double => "Got a Double: " + x
+
+ // Μπορούμε να βάλουμε συνθήκες:
+ case x: Int if x > 10000 => "Got a pretty big number!"
+
+ // Μπορούμε να ταιριάξουμε case classes όπως πρίν:
+ case Person(name, number) => s"Got contact info for $name!"
+
+ // Μπορούμε να ταιριάξουμε regex:
+ case email(name, domain) => s"Got email address $name@$domain"
+
+ // Μπορούμε να ταιριάξουμε πλειάδες:
+ case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
+
+ // Μπορούμε να ταιριάξουμε δομές δεδομένων:
+ case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
+
+ // Μπορούμε να ταιριάξουμε πρότυπα που το ένα είναι μέσα στο άλλο:
+ case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
+}
+
+// Στην πραγματικότητα , μπορούμε να κάνουμε pattern matching σε όποιο αντικείμενο
+// έχει την μέθοδο "unapply". Αυτό το χαρακτηριστικό είναι τόσο ισχυρό ώστε
+// η Scala επιτρέπει να ορίστούν ολόκληρες συναρτήσεις σαν patterns.
+val patternFunc: Person => String = {
+ case Person("George", number) => s"George's number: $number"
+ case Person(name, number) => s"Random person's number: $number"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Συναρτησιακός Προγραμματισμός
+/////////////////////////////////////////////////
+
+// Η Scala επιτρέπει στις μεθόδους και τις συναρτήσεις να επιστρέφουν ή να
+// δέχονται ως παραμέτρους άλλες μεθόδους ή συναρτήσεις.
+
+val add10: Int => Int = _ + 10 // Μια συνάρτηση που δέχεται Int και επιστρέφει Int
+List(1, 2, 3) map add10 // List(11, 12, 13) - το add10 εφαρμόζεται σε κάθε στοιχείο
+ // μέσω του map
+
+// Οι ανώνυμες συναρτήσεις μπορούν να χρησιμοποιηθούν αντί
+// ονοματισμένων (όπως απο πάνω) :
+List(1, 2, 3) map (x => x + 10)
+
+// Και το σύμβολο της κάτω παύλας , μπορεί να χρησιμοποιηθεί αν υπάρχει μόνο
+// ένα όρισμα στην ανώνυμη συνάρτηση. Έτσι δεσμεύεται ως η μεταβλητή.
+List(1, 2, 3) map (_ + 10)
+
+// Αν το μπλόκ της ανώνυμης συνάρτησης ΚΑΙ η συνάρτηση που εφαρμόζεται
+// (στην περίπτωσή μας το foreach και το println) παίρνουν ένα όρισμα
+// μπορείτε να παραλείψετε την κάτω παύλα.
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Συνδυαστές
+
+s.map(sq)
+
+val sSquared = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// Η συνάρτηση filter παίρνει ένα κατηγορούμενο (predicate)
+// που είναι μια συνάρτηση απο το A -> Boolean και διαλέγει
+// όλα τα στοιχεία που ικανοποιούν αυτό το κατηγορούμενο.
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Person(name:String, age:Int)
+List(
+ Person(name = "Dom", age = 23),
+ Person(name = "Bob", age = 30)
+).filter(_.age > 25) // List(Person("Bob", 30))
+
+
+// Το foreach είναι μια μέθοδος της Scala , που ορίζεται για ορισμένες
+// συλλογές (collections). Παίρνει έναν τύπο και επιστρέφει Unit
+// (μια μέθοδο void)
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+
+// For comprehensions
+
+for { n <- s } yield sq(n)
+
+val nSquared2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/*
+ Προσοχή : Αυτά δεν ήταν βρόχοι for. Η σημασιολογία ενός βρόχου for είναι
+ η επανάληψη, ενώ ένα for-comprehension ορίζει μια σχέση μεταξύ δύο
+ συνόλων δεδομένων.
+*/
+
+/////////////////////////////////////////////////
+// 8. Implicits
+/////////////////////////////////////////////////
+/*
+ ΠΡΟΣΟΧΗ! Τα implicits είναι ένα σύνολο απο ισχυρά χαρακτηριστικά της Scala
+ και επομένως είναι εύκολο να γίνει κατάχρηση. Οι αρχάριοι στην Scala θα
+ πρέπει να αντισταθούν στον πειρασμό να τα χρησιμοποιήσουν έως ότου, όχι
+ μόνο καταλάβουν πως λειτουργούν, αλλά ακόμα εξασκηθούν πάνω τους.
+ Ο μόνος λόγος που συμπεριλάβαμε αυτό το κομμάτι στο tutorial είναι
+ γιατί είναι τόσο κοινό στις βιβλιοθήκες της Scala , που αδύνατο να κάνεις
+ οτιδήποτε σημαντικό χωρίς να χρησιμοποιήσεις μια που να έχει implicits.
+
+*/
+
+// Κάθε τιμή (vals , συναρτήσεις , αντικείμενα , κτλ) μπορεί να δηλωθεί ως
+// implicit χρησιμοποιώντας , ναι το μαντέψατε , την λέξη "implicit".
+// Σημειώστε ότι χρησιμοποιούμε την κλάση Dog που δημιουργήσαμε στο
+// 5ο μέρος των παραδειγμάτων.
+implicit val myImplicitInt = 100
+implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
+
+
+// Απο μόνη της, η λέξη implicit, δεν αλλάζει την συμπεριφορά μιάς τιμής
+// οπότε οι παραπάνω μπορούν να χρησιμοποιοηθούν όπως συνήθως.
+myImplicitInt + 2 // => 102
+myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
+
+// Η διαφορά είναι ότι τώρα αυτές οι τιμές έχουν την δυνατότητα να
+// χρησιμοποιηθούν όταν ένα άλλο κομμάτι κώδικα "χρειάζεται" μια
+// implicit τιμή. Μια τέτοια περίπτωση είναι τα ορίσματα μιας implicit
+// συνάρτησης:
+def sendGreetings(toWhom: String)(implicit howMany: Int) =
+ s"Hello $toWhom, $howMany blessings to you and yours!"
+
+// Άν τροφοδοτήσουμε μια τιμή για το "homMany", η συνάρτηση συμπεριφέρεται
+// ως συνήθως
+sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
+
+// Αλλά αν παραλείψουμε την παράμετρο implicit , μια implicit τιμή του ιδίου τύπου
+// χρησιμοποιείται, στην περίπτωσή μας, το "myImplicitInt"
+sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+
+// Οι παράμετροι implicit συναρτήσεων μας επιτρέπουν να προσομοιάζουμε
+// κλάσεις τύπων (type classes) σε άλλες συναρτησιακές γλώσσες.
+// Χρησιμοποιείται τόσο συχνά που έχει την δικιά του συντομογραφία.
+// Οι επόμενες δύο γραμμές κώδικα σημαίνουν το ίδιο πράγμα.
+def foo[T](implicit c: C[T]) = ...
+def foo[T : C] = ...
+
+
+
+// Μια άλλη περίπτωση στην οποία ο μεταγλωττιστής αναζητά μια implicit τιμή
+// είναι αν έχετε obj.method (...)
+// αλλά το "obj" δεν έχει την "method" ως μέθοδο. Σε αυτή την περίπτωση,
+// αν υπάρχει μια implicit μετατροπή του τύπου Α => Β, όπου Α είναι ο τύπος
+// του obj, ενώ το Β έχει μία μέθοδο που ονομάζεται «method», εφαρμόζεται η
+// εν λόγω μετατροπή. Έτσι, έχοντας την MyImplicitFunction μέσα στο πεδίο
+// εφαρμογής(scope), μπορούμε να πούμε:
+"Retriever".breed // => "Golden Retriever"
+"Sheperd".bark // => "Woof, woof!"
+
+// Εδώ το String αρχικά μετατρέπεται σε Dog χρησιμοποιώντας την συνάρτησή μας
+// παραπάνω, και μετά καλείται η κατάλληλη μέθοδος. Αυτό είναι ένα εξερετικά
+// ισχυρό χαρακτηριστικό, αλλά δεν πρέπει να χρησιμοποιείται με ελαφριά την
+// καρδιά. Μάλιστα, όταν ορίσατε την συνάρτηση implicit παραπάνω, ο μεταγλωττιστής
+// θα πρέπει να σας έδωσε μια προειδοποιήση, ότι δεν πρέπει να το κάνετε αυτό
+// εκτός αν πραγματικά γνωρίζετε τι κάνετε.
+
+
+/////////////////////////////////////////////////
+// 9. Διάφορα
+/////////////////////////////////////////////////
+
+// Εισαγωγή βιβλιοθηκών κτλ
+import scala.collection.immutable.List
+
+// Εισαγωγή των πάντων απο το scala.collection.immutable
+import scala.collection.immutable._
+
+// Εισαγωγή πολλών κλάσεων σε μία έκφραση
+import scala.collection.immutable.{List, Map}
+
+// Δώστε ένα νέο όνομα στην εισαγωγή σας χρησιμοποιώντας το '=>'
+import scala.collection.immutable.{ List => ImmutableList }
+
+// Εισαγωγή όλων των κλάσεων εκτός απο μερικές.
+// Το επόμενο δεν εισάγει το Map και το Set:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// Το σημείο εισαγωγής του προγράμματος σας ορίζεται σε ένα αρχείο scala ,
+// χρησιμοποιώντας ένα αντικείμενο (object), με μία μέθοδο , την main.
+object Application {
+ def main(args: Array[String]): Unit = {
+ // Εδω γράφουμε ...
+ }
+}
+
+// Files can contain multiple classes and objects. Compile with scalac
+// Τα files μπορούν να περιέχουν περισσότερες απο μία κλάσεις και
+// αντικείμενα. Το compile γίνεται με την εντολή scalac
+
+// Εισαγωγή και εξαγωγή.
+
+// Για να διβάσετε ένα αρχείο γραμμή προς γραμμή
+import scala.io.Source
+for(line <- Source.fromFile("myfile.txt").getLines())
+ println(line)
+
+// Για να γράψετε σε ένα αρχείο
+val writer = new PrintWriter("myfile.txt")
+writer.write("Writing line for line" + util.Properties.lineSeparator)
+writer.write("Another line here" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Further resources
+
+[Scala for the impatient](http://horstmann.com/scala/)
+
+[Twitter Scala school](http://twitter.github.io/scala_school/)
+
+[The scala documentation](http://docs.scala-lang.org/)
+
+[Try Scala in your browser](http://scalatutorials.com/tour/)
+
+Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
+
diff --git a/elisp.html.markdown b/elisp.html.markdown
index 3208ffb8..3bed5d1c 100644
--- a/elisp.html.markdown
+++ b/elisp.html.markdown
@@ -29,7 +29,7 @@ filename: learn-emacs-lisp.el
;; I hereby decline any responsability. Have fun!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
+;;
;; Fire up Emacs.
;;
;; Hit the `q' key to dismiss the welcome message.
@@ -42,9 +42,9 @@ filename: learn-emacs-lisp.el
;; The scratch buffer is the default buffer when opening Emacs.
;; You are never editing files: you are editing buffers that you
;; can save to a file.
-;;
+;;
;; "Lisp interaction" refers to a set of commands available here.
-;;
+;;
;; Emacs has a built-in set of commands available in every buffer,
;; and several subsets of commands available when you activate a
;; specific mode. Here we use the `lisp-interaction-mode', which
@@ -109,7 +109,7 @@ filename: learn-emacs-lisp.el
;; The empty parentheses in the function's definition means that
;; it does not accept arguments. But always using `my-name' is
;; boring, let's tell the function to accept one argument (here
-;; the argument is called "name"):
+;; the argument is called "name"):
(defun hello (name) (insert "Hello " name))
;; `C-xC-e' => hello
@@ -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)))
@@ -318,7 +318,7 @@ 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 not ! | this is the [^!]
+;; any character | this is the .
;; possibly repeated | this is the +
;; and the "!" string.
diff --git a/elixir.html.markdown b/elixir.html.markdown
index fb5f183a..c8599838 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -195,7 +195,7 @@ cond do
"But I will"
end
-# It is common to see the last condition equal to `true`, which will always match.
+# It is common to set the last condition equal to `true`, which will always match.
cond do
1 + 1 == 3 ->
"I will never be seen"
diff --git a/erlang.html.markdown b/erlang.html.markdown
index 04086aeb..8b67a76a 100644
--- a/erlang.html.markdown
+++ b/erlang.html.markdown
@@ -18,7 +18,7 @@ filename: learnerlang.erl
% Periods (`.`) (followed by whitespace) separate entire functions and
% expressions in the shell.
% Semicolons (`;`) separate clauses. We find clauses in several contexts:
-% function definitions and in `case`, `if`, `try..catch` and `receive`
+% function definitions and in `case`, `if`, `try..catch`, and `receive`
% expressions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -27,20 +27,20 @@ filename: learnerlang.erl
Num = 42. % All variable names must start with an uppercase letter.
-% Erlang has single assignment variables, if you try to assign a different value
-% to the variable `Num`, you’ll get an error.
+% Erlang has single-assignment variables; if you try to assign a different
+% value to the variable `Num`, you’ll get an error.
Num = 43. % ** exception error: no match of right hand side value 43
% In most languages, `=` denotes an assignment statement. In Erlang, however,
-% `=` denotes a pattern matching operation. `Lhs = Rhs` really means this:
-% evaluate the right side (Rhs), and then match the result against the pattern
-% on the left side (Lhs).
+% `=` denotes a pattern-matching operation. `Lhs = Rhs` really means this:
+% evaluate the right side (`Rhs`), and then match the result against the
+% pattern on the left side (`Lhs`).
Num = 7 * 6.
-% Floating point number.
+% Floating-point number.
Pi = 3.14159.
-% Atoms, are used to represent different non-numerical constant values. Atoms
+% Atoms are used to represent different non-numerical constant values. Atoms
% start with lowercase letters, followed by a sequence of alphanumeric
% characters or the underscore (`_`) or at (`@`) sign.
Hello = hello.
@@ -53,34 +53,34 @@ AtomWithSpace = 'some atom with space'.
% Tuples are similar to structs in C.
Point = {point, 10, 45}.
-% If we want to extract some values from a tuple, we use the pattern matching
+% If we want to extract some values from a tuple, we use the pattern-matching
% operator `=`.
{point, X, Y} = Point. % X = 10, Y = 45
% We can use `_` as a placeholder for variables that we’re not interested in.
% The symbol `_` is called an anonymous variable. Unlike regular variables,
-% several occurrences of _ in the same pattern don’t have to bind to the same
-% value.
+% several occurrences of `_` in the same pattern don’t have to bind to the
+% same value.
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
% We create a list by enclosing the list elements in square brackets and
% separating them with commas.
% The individual elements of a list can be of any type.
-% The first element of a list is the head of the list. If you imagine removing the
-% head from the list, what’s left is called the tail of the list.
+% The first element of a list is the head of the list. If you imagine removing
+% the head from the list, what’s left is called the tail of the list.
ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
% If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`.
% The vertical bar (`|`) separates the head of a list from its tail.
% `[]` is the empty list.
-% We can extract elements from a list with a pattern matching operation. If we
+% We can extract elements from a list with a pattern-matching operation. If we
% have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`
% are unbound variables, will extract the head of the list into `X` and the tail
% of the list into `Y`.
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
% FirstThing = {apples, 10}
-% OtherThingsToBuy = {pears, 6}, {milk, 3}
+% OtherThingsToBuy = [{pears, 6}, {milk, 3}]
% There are no strings in Erlang. Strings are really just lists of integers.
% Strings are enclosed in double quotation marks (`"`).
@@ -117,17 +117,19 @@ c(geometry). % {ok,geometry}
geometry:area({rectangle, 10, 5}). % 50
geometry:area({circle, 1.4}). % 6.15752
-% In Erlang, two functions with the same name and different arity (number of arguments)
-% in the same module represent entirely different functions.
+% In Erlang, two functions with the same name and different arity (number of
+% arguments) in the same module represent entirely different functions.
-module(lib_misc).
--export([sum/1]). % export function `sum` of arity 1 accepting one argument: list of integers.
+-export([sum/1]). % export function `sum` of arity 1
+ % accepting one argument: list of integers.
sum(L) -> sum(L, 0).
sum([], N) -> N;
sum([H|T], N) -> sum(T, H+N).
-% Funs are "anonymous" functions. They are called this way because they have no
-% name. However they can be assigned to variables.
-Double = fun(X) -> 2*X end. % `Double` points to an anonymous function with handle: #Fun<erl_eval.6.17052888>
+% Funs are "anonymous" functions. They are called this way because they have
+% no name. However, they can be assigned to variables.
+Double = fun(X) -> 2 * X end. % `Double` points to an anonymous function
+ % with handle: #Fun<erl_eval.6.17052888>
Double(2). % 4
% Functions accept funs as their arguments and can return funs.
@@ -140,8 +142,9 @@ Triple(5). % 15
% The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken
% from the list `L`."
L = [1,2,3,4,5].
-[2*X || X <- L]. % [2,4,6,8,10]
-% A list comprehension can have generators and filters which select subset of the generated values.
+[2 * X || X <- L]. % [2,4,6,8,10]
+% A list comprehension can have generators and filters, which select subset of
+% the generated values.
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
% Guards are constructs that we can use to increase the power of pattern
@@ -155,17 +158,31 @@ max(X, Y) -> Y.
% A guard is a series of guard expressions, separated by commas (`,`).
% The guard `GuardExpr1, GuardExpr2, ..., GuardExprN` is true if all the guard
-% expressions `GuardExpr1, GuardExpr2, ...` evaluate to true.
+% expressions `GuardExpr1`, `GuardExpr2`, ..., `GuardExprN` evaluate to `true`.
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.
-% A `guard sequence` is either a single guard or a series of guards, separated
-%by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at least
-% one of the guards `G1, G2, ...` evaluates to true.
-is_pet(A) when is_dog(A); is_cat(A) -> true;
-is_pet(A) -> false.
+% We won't dwell on the `=:=` operator here; just be aware that it is used to
+% check whether two Erlang expressions have the same value *and* the same type.
+% Contrast this behaviour to that of the `==` operator:
+1 + 2 =:= 3. % true
+1 + 2 =:= 3.0. % false
+1 + 2 == 3.0. % true
+
+% A guard sequence is either a single guard or a series of guards, separated
+% by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at
+% least one of the guards `G1`, `G2`, ..., `Gn` evaluates to `true`.
+is_pet(A) when is_atom(A), (A =:= dog) or (A =:= cat) -> true;
+is_pet(A) -> false.
+
+% Warning: not all valid Erlang expressions can be used as guard expressions;
+% in particular, our `is_cat` and `is_dog` functions cannot be used within the
+% guard sequence in `is_pet`'s definition. For a description of the
+% expressions allowed in guard sequences, refer to this
+% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
+% of the Erlang reference manual.
% Records provide a method for associating a name with a particular element in a
% tuple.
@@ -188,7 +205,7 @@ X = #todo{}.
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"}
+% #todo{status = done, who = joe, text = "Fix errata in book"}
% `case` expressions.
% `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is
@@ -206,11 +223,11 @@ max(X, Y) ->
if
X > Y -> X;
X < Y -> Y;
- true -> nil;
+ true -> nil
end.
-% Warning: at least one of the guards in the `if` expression must evaluate to true;
-% otherwise, an exception will be raised.
+% Warning: at least one of the guards in the `if` expression must evaluate to
+% `true`; otherwise, an exception will be raised.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -218,7 +235,7 @@ max(X, Y) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exceptions are raised by the system when internal errors are encountered or
-% explicitly in code by calling `throw(Exception)`, `exit(Exception)` or
+% explicitly in code by calling `throw(Exception)`, `exit(Exception)`, or
% `erlang:error(Exception)`.
generate_exception(1) -> a;
generate_exception(2) -> throw(a);
@@ -227,7 +244,7 @@ generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a).
% Erlang has two methods of catching an exception. One is to enclose the call to
-% the function, which raised the exception within a `try...catch` expression.
+% the function that raises the exception within a `try...catch` expression.
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
@@ -241,23 +258,24 @@ catcher(N) ->
% exception, it is converted into a tuple that describes the error.
catcher(N) -> catch generate_exception(N).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 4. Concurrency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Erlang relies on the actor model for concurrency. All we need to write
-% concurrent programs in erlang are three primitives: spawning processes,
+% concurrent programs in Erlang are three primitives: spawning processes,
% sending messages and receiving messages.
-% To start a new process we use the `spawn` function, which takes a function
+% To start a new process, we use the `spawn` function, which takes a function
% as argument.
F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
spawn(F). % <0.44.0>
-% `spawn` returns a pid (process identifier), you can use this pid to send
-% messages to the process. To do message passing we use the `!` operator.
-% For all of this to be useful we need to be able to receive messages. This is
+% `spawn` returns a pid (process identifier); you can use this pid to send
+% messages to the process. To do message passing, we use the `!` operator.
+% For all of this to be useful, we need to be able to receive messages. This is
% achieved with the `receive` mechanism:
-module(calculateGeometry).
@@ -272,12 +290,13 @@ calculateArea() ->
io:format("We can only calculate area of rectangles or circles.")
end.
-% Compile the module and create a process that evaluates `calculateArea` in the shell
+% Compile the module and create a process that evaluates `calculateArea` in the
+% shell.
c(calculateGeometry).
CalculateArea = spawn(calculateGeometry, calculateArea, []).
CalculateArea ! {circle, 2}. % 12.56000000000000049738
-% The shell is also a process, you can use `self` to get the current pid
+% The shell is also a process; you can use `self` to get the current pid.
self(). % <0.41.0>
```
diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown
index 5c9d3378..73853a9d 100644
--- a/es-es/git-es.html.markdown
+++ b/es-es/git-es.html.markdown
@@ -38,7 +38,7 @@ uno o varios archivos, a lo largo del tiempo.
* Se puede trabajar sin conexion.
* Colaborar con otros es sencillo!.
* Derivar, Crear ramas del proyecto (aka: Branching) es facil!.
-* Combinar (aka: Marging)
+* Combinar (aka: Merging)
* Git es rapido.
* Git es flexible.
diff --git a/es-es/julia-es.html.markdown b/es-es/julia-es.html.markdown
index 203ee3bb..1e01c2e3 100644
--- a/es-es/julia-es.html.markdown
+++ b/es-es/julia-es.html.markdown
@@ -4,757 +4,937 @@ contributors:
- ["Leah Hanson", "http://leahhanson.us"]
translators:
- ["Guillermo Garza", "http://github.com/ggarza"]
+ - ["Ismael Venegas Castelló", "https://github.com/Ismael-VC"]
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.
+![JuliaLang](https://camo.githubusercontent.com/e1ae5c7f6fe275a50134d5889a68f0acdd09ada8/687474703a2f2f6a756c69616c616e672e6f72672f696d616765732f6c6f676f5f68697265732e706e67)
-Esto se basa en la versión de desarrollo actual de Julia, del 18 de octubre de
-2013.
+[Julia](http://julialanges.github.io) es un [lenguaje de programación](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n) [multiplataforma](http://es.wikipedia.org/wiki/Multiplataforma) y [multiparadigma](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_multiparadigma) de [tipado dinámico](http://es.wikipedia.org/wiki/Tipado_din%C3%A1mico), [alto nivel](http://es.wikipedia.org/wiki/Lenguaje_de_alto_nivel) y [alto desempeño](http://es.wikipedia.org/wiki/Computaci%C3%B3n_de_alto_rendimiento) para la computación [genérica](http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_de_prop%C3%B3sito_general), [técnica y científica](http://es.wikipedia.org/wiki/Computaci%C3%B3n_cient%C3%ADfica), con una sintaxis que es familiar para los usuarios de otros entornos de computación técnica y científica. Provee de un [sofisticado compilador JIT](http://es.wikipedia.org/wiki/Compilaci%C3%B3n_en_tiempo_de_ejecuci%C3%B3n), [ejecución distribuida y paralela](http://docs.julialang.org/en/release-0.3/manual/parallel-computing), [precisión numérica](http://julia.readthedocs.org/en/latest/manual/integers-and-floating-point-numbers) y de una [extensa librería con funciones matemáticas](http://docs.julialang.org/en/release-0.3/stdlib). La librería estándar, escrita casi completamente en Julia, también integra las mejores y más maduras librerías de C y Fortran para el [álgebra lineal](http://docs.julialang.org/en/release-0.3/stdlib/linalg), [generación de números aleatorios](http://docs.julialang.org/en/release-0.3/stdlib/numbers/?highlight=random#random-numbers), [procesamiento de señales](http://docs.julialang.org/en/release-0.3/stdlib/math/?highlight=signal#signal-processing), y [procesamiento de cadenas](http://docs.julialang.org/en/release-0.3/stdlib/strings). Adicionalmente, la comunidad de [desarrolladores de Julia](https://github.com/JuliaLang/julia/graphs/contributors) contribuye un número de [paquetes externos](http://pkg.julialang.org) a través del gestor de paquetes integrado de Julia a un paso acelerado. [IJulia](https://github.com/JuliaLang/IJulia.jl), una colaboración entre las comunidades de [IPython](http://ipython.org) y Julia, provee de una poderosa interfaz gráfica basada en el [navegador para Julia](https://juliabox.org).
-```ruby
+En Julia los programas están organizados entorno al [despacho múltiple](http://docs.julialang.org/en/release-0.3/manual/methods/#man-methods); definiendo funciones y sobrecargándolas para diferentes combinaciones de tipos de argumentos, los cuales también pueden ser definidos por el usuario.
-# Comentarios de una línea comienzan con una almohadilla (o signo gato)
+### ¡Prueba Julia ahora mismo!
-#= Commentarios multilinea pueden escribirse
- usando '#=' antes de el texto y '=#'
- después del texto. También se pueden anidar.
+* [TryJupyter](https://try.jupyter.org)
+* [JuliaBox](https://juliabox.org)
+* [SageMathCloud](https://cloud.sagemath.com)
+
+### Resumen de Características:
+
+* [Despacho múltiple](http://en.wikipedia.org/wiki/Multiple_dispatch): permite definir el comportamiento de las funciones a través de múltiples combinaciones de tipos de argumentos (**métodos**).
+* Sistema de **tipado dinámico**: tipos para la documentación, la optimización y el despacho.
+* [Buen desempeño](http://julialang.org/benchmarks), comparado al de lenguajes **estáticamente compilados** como C.
+* [Gestor de paquetes](http://docs.julialang.org/en/release-0.3/stdlib/pkg) integrado.
+* [Macros tipo Lisp](http://docs.julialang.org/en/release-0.3/manual/metaprogramming/#macros) y otras comodidades para la [meta programación](http://docs.julialang.org/en/release-0.3/manual/metaprogramming).
+* Llamar funciones de otros lenguajes, mediante paquetes como: **Python** ([PyCall](https://github.com/stevengj/PyCall.jl)), [Mathematica](http://github.com/one-more-minute/Mathematica.jl), **Java** ([JavaCall](http://github.com/aviks/JavaCall.jl)), **R** ([Rif](http://github.com/lgautier/Rif.jl) y [RCall](http://github.com/JuliaStats/RCall.jl)) y **Matlab** ([MATLAB](http://github.com/JuliaLang/MATLAB.jl)).
+* [Llamar funciones de C y Fortran](http://docs.julialang.org/en/release-0.3/manual/calling-c-and-fortran-code) **directamente**: sin necesidad de usar envoltorios u APIs especiales.
+* Poderosas características de **línea de comandos** para [gestionar otros procesos](http://docs.julialang.org/en/release-0.3/manual/running-external-programs).
+* Diseñado para la [computación paralela y distribuida](http://docs.julialang.org/en/release-0.3/manual/parallel-computing) **desde el principio**.
+* [Corrutinas](http://en.wikipedia.org/wiki/Coroutine): hilos ligeros "**verdes**".
+* Los [tipos definidos por el usuario](http://docs.julialang.org/en/release-0.3/manual/types) son tan **rápidos y compactos** como los tipos estándar integrados.
+* [Generación automática de código](http://docs.julialang.org/en/release-0.3/stdlib/base/?highlight=%40code#internals) **eficiente y especializado** para diferentes tipos de argumentos.
+* [Conversiones y promociones](http://docs.julialang.org/en/release-0.3/manual/conversion-and-promotion) para tipos numéricos y de otros tipos, **elegantes y extensibles**.
+* Soporte eficiente para [Unicode](http://es.wikipedia.org/wiki/Unicode), incluyendo [UTF-8](http://es.wikipedia.org/wiki/UTF-8) pero sin limitarse solo a este.
+* [Licencia MIT](https://github.com/JuliaLang/julia/blob/master/LICENSE.md): libre y de código abierto.
+
+Esto se basa en la versión `0.3.11`.
+
+```julia
+# Los comentarios de una línea comienzan con una almohadilla (o signo de gato).
+
+#=
+ Los commentarios multilínea 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.
+##############################################
+# 1. Tipos de datos primitivos y operadores. #
+##############################################
+
+# Todo en Julia es una expresión (Expr).
# 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})
+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.
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0 # dividir un Int por un Int siempre resulta
+ # en un Float
+5 / 2 # => 2.5
+div(5, 2) # => 2 # para un resultado truncado, usa la función 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 # desplazamiento lógico hacia la derecha
+2 >> 1 # => 1 # desplazamiento aritmético hacia la derecha
+2 << 1 # => 4 # desplazamiento lógico/aritmético hacia la izquierda
+
+# 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
+# Los valores booleanos (Bool) son primitivos.
+true # => true
+false # => false
+
+# Operadores 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
+1 < 2 < 3 # => true
+2 < 3 < 2 # => false
-# Strings se crean con "
-"Esto es un string."
+# Los literales de cadenas (String) se crean con la comilla doble: "
+"Esto es una cadena."
-# Literales de caracteres se escriben con '
+# Los literales de caracteres (Char) se crean con la comilla simple: '
'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,
+# Una cadena puede ser indexada como una arreglo de caracteres.
+"Esto es un string."[1] # => 'E' # Los índices en Julia comienzan en: 1
+
+# Sin embargo, esto no va a funcionar bien para las cadenas UTF8 (UTF8String),
# 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.
+# $ puede ser utilizado para la interpolación de cadenas, se puede poner
+# cualquier expresión de Julia dentro los paréntesis.
+"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
+
+# Otra forma para formatear cadenas es usando el macro printf.
+@printf "%d es menor de %f\n" 4.5 5.3 # 5 es menor de 5.300000
-# 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("¡Hola Julia!") # ¡Hola Julia!
-# Imprimir es muy fácil
-println("Soy Julia. ¡Encantado de conocerte!")
-####################################################
-## 2. Variables y Colecciones
-####################################################
+##############################
+# 2. Variables y Colecciones #
+##############################
# No hay necesidad de declarar las variables antes de asignarlas.
-una_variable = 5 # => 5
-una_variable # => 5
+una_variable = 5 # => 5
+una_variable # => 5
-# Acceder a variables no asignadas previamente es una excepción.
+# Acceder a una variable no asignada previamente es una excepción.
try
- otra_variable # => ERROR: some_other_var not defined
+ otra_variable # ERROR: otra_variable not defined
catch e
- println(e)
+ println(e) # UndefVarError(:otra_variable)
end
-# Los nombres de variables comienzan con una letra.
-# Después de eso, puedes utilizar letras, dígitos, guiones y signos de
+# Los nombres de variables comienzan con una letra o guion bajo: _.
+# Después de eso, puedes utilizar letras, dígitos, guiones bajos y signos de
# exclamación.
-OtraVariable123! = 6 # => 6
+otraVariable_123! = 6 # => 6
+
+# También puedes utilizar caracteres Unicode.
+☃ = 8 # => 8
-# 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
+# (multiplicación implicita).
+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 un guion bajo:
+
+ otra_variable
+
+ * Los nombres de los tipos comienzan con una letra mayúscula y separación de
+ palabras se muestra con CamelCase en vez de guion bajo:
+
+ OtroTipo
+
+ * Los nombres de las funciones y los macros están en minúsculas, sin
+ underscore:
+
+ otromacro
+
+ * Funciones que modifican sus entradas tienen nombres que terminan en: !.
+ Estas funciones a veces se les llaman funciones transformadoras o
+ funciones in situ:
+
+ otra_funcion!
+=#
+
+# Los arreglos (Array) almacenan una secuencia de valores indexados de entre 1 hasta n.
+a = Int64[] # => 0-element Array{Int64,1}
+
+# Los literales de arregos unidimensionales se pueden escribir con valores
+# separados por comas.
+b = [4, 5, 6]
+#=
+ => 3-element Array{Int64,1}:
+ 4
+ 5
+ 6
+=#
+b[1] # => 4
+b[end] # => 6
+
+# Los arreglos bidimensionales usan valores separados por espacios y filas
+# separadas por punto y coma.
+matrix = [1 2; 3 4]
+#=
+ => 2x2 Array{Int64,2}:
+ 1 2
+ 3 4
+=#
+
+# Añadir cosas a la final de un arreglo 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 del 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 # recuerda, 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
+
+# También 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]
+
+# Los nombres de funciónes que terminan en exclamaciones indican que modifican
+# su o sus argumentos de entrada.
+arr = [5, 4, 6] # => 3-element Array{Int64,1}: [5,4,6]
+sort(arr) # => [4,5,6] y arr es todavía: [5,4,6]
+sort!(arr) # => [4,5,6] y 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
+ 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)
+ println(e) # BoundsError()
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.
+# Las excepciones y los errores dan la línea y el archivo de su procedencia,
+# aunque provenga de la librería estándar. Si compilas Julia del código fuente,
+# puedes buscar en el código para encontrar estos archivos.
+
+# Se puede inicializar un arreglo con un rango (Range).
+a = [1:5] # => 5-element Array{Int64,1}: [1,2,3,4,5]
-# Se puede inicializar arrays de un range
-a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
+# Puedes mirar en los rangos con la sintaxis de rebanada.
+a[1:3] # => [1,2,3]
+a[2:end] # => [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 un arreglo por índice con splice!
+arr = [3, 4, 5]
+splice!(arr, 2) # => 4 y arr es ahora: [3,5]
-# Eliminar elementos de una array por índice con splice!
-arr = [3,4,5]
-splice!(arr,2) # => 4 ; arr es ahora [3,5]
+# Concatenar arreglos con append!
+b = [1, 2, 3]
+append!(a, b) # a ahora es: [1,2,3,4,5,1,2,3]
-# 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 de un elemento en un arreglo con in.
+in(1, a) # => true
-# Comprueba la existencia en una lista con in
-in(1, a) # => true
+# Examina la longitud con length.
+length(a) # => 8
-# Examina la longitud con length
-length(a) # => 8
+# Las tuplas (Tuple) son inmutables.
+tup = (1, 2, 3) # => (1,2,3) # una tupla tipo (Int64,Int64,Int64)
+tup[1] # => 1
-# 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)
+ tup[1] = 3 # ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
catch e
- println(e)
+ println(e) # MethodError(setindex!,(:tup,3,1))
end
-# Muchas funciones de lista también trabajan en las tuples
-length(tup) # => 3
-tup[1:2] # => (1,2)
-in(2, tup) # => true
+# Muchas funciones de arreglos también trabajan en con las tuplas.
+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
+# Se pueden desempacar las tuplas en variables individuales.
+a, b, c = (1, 2, 3) # => (1,2,3) # ahora a es 1, b es 2 y c es 3
-# Los tuples se crean, incluso si se omite el paréntesis
-d, e, f = 4, 5, 6 # => (4,5,6)
+# Los tuplas se crean, incluso si se omiten los 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
+# Una tupla de un elemento es distinta 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
+# Mira que fácil es cambiar dos valores!
+e, d = d, e # => (5,4) # ahora d es 5 y e es 4
+# Los diccionarios (Dict) son arreglos asociativos.
+dicc_vacio = Dict() # => Dict{Any,Any} with 0 entries
-# Dictionaries almanecan mapeos
-dict_vacio = Dict() # => Dict{Any,Any}()
+# Se puede crear un diccionario usando una literal.
+dicc_lleno = ["uno" => 1, "dos" => 2, "tres" => 3]
+#=
+ => Dict{ASCIIString,Int64} with 3 entries:
+ "tres" => 3
+ "dos" => 2
+ "uno" => 1
+=#
+
+# Busca valores con: [].
+dicc_lleno["uno"] # => 1
+
+# Obtén todas las claves con.
+keys(dicc_lleno)
+#=
+ => KeyIterator for a Dict{ASCIIString,Int64} with 3 entries. Keys:
+ "tres"
+ "dos"
+ "uno"
+=#
-# Se puede crear un dictionary usando un literal
-dict_lleno = ["one"=> 1, "two"=> 2, "three"=> 3]
-# => Dict{ASCIIString,Int64}
+# Nota: los elementos del diccionario no están ordenados y no se guarda el orden
+# en que se insertan.
-# Busca valores con []
-dict_lleno["one"] # => 1
+# Obtén todos los valores.
+values(dicc_lleno)
+#=
+ => ValueIterator for a Dict{ASCIIString,Int64} with 3 entries. Values:
+ 3
+ 2
+ 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.
+# Nota: igual que el anterior en cuanto a ordenamiento de los elementos.
-# 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.
+# Comprueba si una clave existe en un diccionario con in y haskey.
+in(("uno", 1), dicc_lleno) # => true
+in(("tres", 3), dicc_lleno) # => false
-# 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
+haskey(dicc_lleno, "uno") # => true
+haskey(dicc_lleno, 1) # => false
-# Tratando de buscar una clave que no existe producirá un error
+# Tratar de obtener un valor con una clave que no existe producirá un error.
try
- dict_lleno["dos"] # => ERROR: key not found: dos in getindex at dict.jl:489
+ # ERROR: key not found: cuatro in getindex at dict.jl:489
+ dicc_lleno["cuatro"]
catch e
- println(e)
+ println(e) # KeyError("cuatro")
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
+# Utiliza el método get para evitar este error proporcionando un valor
+# predeterminado: get(diccionario, clave, valor_predeterminado).
+get(dicc_lleno, "uno", 4) # => 1
+get(dicc_lleno, "cuatro", 4) # => 4
+
+# Usa conjuntos (Set) para representar colecciones de valores únicos, no
+# ordenados.
+conjunto_vacio = Set() # => Set{Any}({})
-# 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)
+# Iniciar una conjunto de valores.
+conjunto_lleno = Set(1, 2, 2, 3, 4) # => Set{Int64}({4,2,3,1})
-# 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)
+# Añadir más valores a un conjunto.
+push!(conjunto_lleno, 5) # => Set{Int64}({4,2,3,5,1})
+push!(conjunto_lleno, 5) # => Set{Int64}({4,2,3,5,1})
-# Compruebe si los valores están en el conjunto
-in(2, conjunto_lleno) # => true
-in(10, conjunto_lleno) # => false
+# Comprobar 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)
+# Hay funciones de intersección, unión y diferencia de conjuntos.
+otro_conjunto = Set(3, 4, 5, 6) # => Set{Int64}({6,4,5,3})
+intersect(conjunto_lleno, otro_conjunto) # => Set{Int64}({3,4,5})
+union(conjunto_lleno, otro_conjunto) # => 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
-####################################################
+#######################
+# 3. Control de Flujo #
+#######################
-# Hagamos una variable
+# Hagamos una variable.
una_variable = 5
-# Aquí está una declaración de un 'if'. La indentación no es significativa en
-# Julia
+# Aquí está la 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.")
+ println("una_variable es completamente mayor que 10.")
+elseif una_variable < 10 # esta condición elseif es opcional
+ println("una_variable es menor que 10.")
+else # esto también es opcional
+ println("De echo una_variable es 10.")
end
-# => imprime "una_variable es mas chica que 10."
+# imprime: una_variable es menor 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
+# El bucle for itera sobre tipos iterables, ie. Range, Array, Set,
+# Dict y String.
+for animal in ["perro", "gato", "ratón"]
+ # Se puede usar $ para interpolar variables o expresiones en ls cadenas.
+ println("$animal es un mamífero.")
end
-# imprime:
-# perro es un mamifero
-# gato es un mamifero
-# raton es un mamifero
+#=
+ imprime:
+ perro es un mamífero.
+ gato es un mamífero.
+ ratón es un mamífero.
+=#
-for a in ["perro"=>"mamifero","gato"=>"mamifero","raton"=>"mamifero"]
- println("$(a[1]) es un $(a[2])")
+for a in ["perro" => "mamífero", "gato" => "mamífero", "ratón" => "mamífero"]
+ println("$(a[1]) es un $(a[2]).")
end
-# imprime:
-# perro es un mamifero
-# gato es un mamifero
-# raton es un mamifero
+#=
+ imprime:
+ perro es un mamífero.
+ gato es un mamífero.
+ ratón es un mamífero.
+=#
-for (k,v) in ["perro"=>"mamifero", "gato"=>"mamifero", "raton"=>"mamifero"]
- println("$k es un $v")
+for (k,v) in ["perro"=>"mamífero", "gato"=>"mamífero", "ratón"=>"mamífero"]
+ println("$k es un $v.")
end
-# imprime:
-# perro es un mamifero
-# gato es un mamifero
-# raton es un mamifero
+#=
+ imprime:
+ perro es un mamífero.
+ gato es un mamífero.
+ ratón es un mamífero.
+=#
-# While itera hasta que una condición no se cumple.
+# El bucle while itera hasta que una condición se deje de cumplir.
x = 0
while x < 4
println(x)
- x += 1 # versión corta de x = x + 1
+ x += 1 # versión corta de: x = x + 1
end
-# imprime:
-# 0
-# 1
-# 2
-# 3
+#=
+imprime:
+ 0
+ 1
+ 2
+ 3
+=#
-# Maneja excepciones con un bloque try/catch
-try
- error("ayuda")
+# Maneja excepciones con un bloque try/catch.
+try # intentar
+ error("Ooops!")
catch e
- println("capturando $e")
+ println("capturando: $e") # capturando: ErrorException("Ooops!")
end
-# => capturando ErrorException("ayuda")
-####################################################
-## 4. Funciones
-####################################################
+################
+# 4. Funciones #
+################
-# Usa 'function' para crear nuevas funciones
+# Usa function para crear nuevas funciones.
-#function nombre(arglist)
-# cuerpo...
-#end
+#=
+ 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
+ # las funciones devuelven el valor de su última expresión
x + y
end
+# => suma (generic function with 1 method)
-suma(5, 6) # => 11 # después de imprimir "x es 5 e y es de 6"
+suma(5, 6) # => 11 # después de imprimir: x es 5 e y es 6
+
+# También puedes usar esta otra sintaxis para definir funciones!
+resta(x, y) = x - y # => resta (generic function with 1 method)
# Puedes definir funciones que toman un número variable de
-# argumentos posicionales
+# argumentos posicionales (el ... se llama un splat).
function varargs(args...)
+ # Usa la palabra clave return para regresar desde cualquier
+ # lugar de la función.
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)
+varargs(1, 2, 3) # => (1,2,3)
+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)
+# Acabamos de utilizar el splat (...) en la definición de una función. También
+# se puede utilizar al llamar a una función, donde se esparce un arreglo, tupla
+# o en general una secuencia iterable en la tupla de argumentos.
+varargs([1, 2, 3]...) # => (1,2,3) # igual que: varargs(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)
+x = (1, 2, 3) # => (1,2,3)
+varargs(x) # => ((1,2,3),)
+varargs(x...) # => (1,2,3)
+varargs("abc"...) # => ('a','b','c')
-# Puede definir funciones con argumentos posicionales opcionales
-function defaults(a,b,x=5,y=6)
+# Puedes definir funciones con argumentos posicionales opcionales.
+function defaults(a, b, x=5, y=6)
return "$a $b y $x $y"
end
+# => defaults (generic function with 3 methods)
+
+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"
-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()
+ defaults('h') # ERROR: `defaults` has no method matching defaults(::Char)
+ defaults() # ERROR: `defaults` has no method matching defaults()
catch e
- println(e)
+ println(e) # MethodError(defaults,('h',))
end
-# Puedes definir funciones que toman argumentos de palabra clave
-function args_clave(;k1=4,nombre2="hola") # note the ;
- return ["k1"=>k1,"nombre2"=>nombre2]
+# Puedes definir funciones que tomen argumentos de palabras clave.
+function args_clave(;k1=4, nombre2="hola") # nota el punto y coma: ;
+ return ["k1" => k1, "nombre2" => nombre2]
end
+# => args_clave (generic function with 1 method)
-args_clave(nombre2="ness") # => ["nombre2"=>"ness","k1"=>4]
-args_clave(k1="mine") # => ["k1"=>"mine","nombre2"=>"hola"]
-args_clave() # => ["nombre2"=>"hola","k1"=>4]
+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")
+# Puedes combinar todo tipo de argumentos en la misma función.
+function todos_los_args(arg_posicional, arg_opcional=2; arg_clave="foo")
+ println("argumento posicional: $arg_posicional")
+ println(" argumento opcional: $arg_opcional")
+ println(" argumento clave: $arg_clave")
end
+# => todos_los_args (generic function with 2 methods)
+# No se necesita punto y coma ; al llamar la función usando un argumento clave,
+# esto solo es necesario en la definición de la función.
todos_los_args(1, 3, arg_clave=4)
-# imprime:
-# argumento normal: 1
-# argumento optional: 3
-# argumento de clave: 4
+#=
+ imprime:
+ argumento posicional: 1
+ argumento opcional: 3
+ argumento clave: 4
+=#
-# Julia tiene funciones de primera clase
+# Julia tiene funciones de primera clase.
function crear_suma(x)
- suma = function (y)
+ suma = function (y) # función anónima
return x + y
end
return suma
end
+# => crear_suma (generic function with 1 method)
-# Esta es el sintaxis "stabby lambda" para crear funciones anónimas
-(x -> x > 2)(3) # => true
+# Esta es otra sintaxis (estilo cálculo 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
+crear_suma(x) = y -> x + y
-# También puedes nombrar la función interna, si quieres
+# También puedes nombrar la función interna, si quieres.
function crear_suma(x)
function suma(y)
x + y
end
suma
end
+# => crear_suma (generic function with 1 method)
-suma_10 = crear_suma(10)
-suma_10(3) # => 13
+suma_10 = crear_suma(10) # => suma (generic function with 1 method)
+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]
-# 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]
+# Se puede pasar un bloque a las funciones cuyo primer argumento posicional
+# es otra función, como en map y filter.
+map([1, 2, 3]) do arr
+ suma_10(arr)
+end
+#=
+ => 3-element Array{Int64,1}:
+ 11
+ 12
+ 13
+=#
+
+filter([3, 4, 5, 6, 7]) do arr
+ (x -> x > 5)(arr)
+end
+#=
+ => 2-element Array{Int64,1}:
+ 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]
+# Podemos usar comprensiones de listas multidimensionales.
+[suma_10(i) for i = [1, 2, 3]] # => [11, 12, 13] # 1D
+[suma_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-####################################################
-## 5. Tipos
-####################################################
+[i*j for i = [1:3], j in [1:3]] # 2D
+#=
+ => 3x3 Array{Int64,2}:
+ 1 2 3
+ 2 4 6
+ 3 6 9
+=#
+
+[i*j/k for i = [1:3], j = [1:3], k in [1:3]] # 3D
+#=
+ => 3x3x3 Array{Float64,3}:
+ [:, :, 1] =
+ 1.0 2.0 3.0
+ 2.0 4.0 6.0
+ 3.0 6.0 9.0
+
+ [:, :, 2] =
+ 0.5 1.0 1.5
+ 1.0 2.0 3.0
+ 1.5 3.0 4.5
+
+ [:, :, 3] =
+ 0.333333 0.666667 1.0
+ 0.666667 1.33333 2.0
+ 1.0 2.0 3.0
+=#
+
+
+############
+# 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
+# Se puede utilizar la función typeof para obtener el tipo de un valor.
+typeof(5) # => Int64 # en un sistema de 64 bits, de lo contrario: Int32
-# 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 son valores de primera clase, DataType es el tipo que representa a
+# los tipos, incluyéndose a sí mismo.
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
-# Los tipos se usan para la documentación, optimizaciones, y envio.
-# No están comprobados estáticamente.
+# Los tipos se usan para la documentación, para optimizaciones
+# y el despacho múltiple. 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`.
+# Los usuarios pueden definir sus propios tipos.
+# Son como registros o estructuras en otros idiomas.
+# Un nuevo tipos se define utilizado la palabra clave type.
# type Nombre
-# field::OptionalType
+# atributo::UnTipo # las anotaciones de tipos son opcionales
# ...
# end
type Tigre
- longituddecola::Float64
- colordelpelaje # no incluyendo una anotación de tipo es el mismo que `::Any`
+ longitud_cola::Float64
+ color_pelaje # sin una anotación de tipo, es lo 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")
+# Los argumentos del constructor por defecto son los atributos
+# del tipo, en el orden en que están listados en la definición.
+tigre = Tigre(3.5, "anaranjado") # => Tigre(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")
+# El tipo funciona como método constructor para los valores de ese tipo.
+sherekhan = typeof(tigre)(5.6, "fuego") # => Tigre(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).
+# Este estilo de tipos son llamados tipos concretos.
+# Se pueden crear instancias de estos, pero no pueden tener subtipos.
+# La otra clase de tipos son los tipos abstractos.
# 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
+abstract Gato # sólo un nombre y un punto en la jerarquía de tipos
+
+# No se pueden crear instancias de los tipos abstractos, pero pueden tener
+# subtipos. Por ejemplo, Number es un tipo abstracto.
+subtypes(Number)
+#=
+ => 2-element Array{Any,1}:
+ Complex{T<:Real}
+ Real
+=#
+
+subtypes(Gato) # => 0-element Array{Any,1}
+
+# Cada tipo tiene un supertipo, utiliza la función súper para conseguirlo.
+typeof(5) # => Int64
+super(Int64) # => Signed
+super(Signed) # => Integer
+super(Integer) # => Real
+super(Real) # => Number
+super(Number) # => Any
+super(super(Signed)) # => Real
+super(Any) # => Any
-# 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.
+# Todos estos tipos, a excepción de Int64, son abstractos.
+
+# <: es el operador de subtipos.
+type Leon <: Gato # Leon es un subtipo de Gato
+ color_crin
+ rugido::String
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
-####################################################
+# Se pueden definir más constructores para un tipo.
+# Sólo define una función del mismo nombre que el tipo y llama al constructor
+# existente para obtener un valor del tipo correcto.
-# 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.
+# Este es un constructor externo porque es fuera de la definición del tipo.
+Leon(rugido::String) = Leon("verde", rugido)
-# Por ejemplo, vamos a hacer un maullar función:
+type Pantera <: Gato # Pantera también es un a subtipo de Gato
+ color_ojos
-# Definiciones para Leon, Pantera, y Tigre
-function maullar(animal::Leon)
- animal.rugido # acceso utilizando notación de puntos
+ # Pantera sólo tendrá este constructor, y ningún constructor predeterminado.
+ Pantera() = new("verde")
end
-function maullar(animal::Pantera)
- "grrr"
-end
+# Utilizar constructores internos, como se hace en Pantera, te da control sobre
+# cómo se pueden crear valores de este tipo. Cuando sea posible, debes utilizar
+# constructores externos en lugar de internos.
-function maullar(animal::Tigre)
- "rawwwr"
-end
-# Prueba de la función maullar
-maullar(tigger) # => "rawwr"
-maullar(Leon("cafe","ROAAR")) # => "ROAAR"
-maullar(Pantera()) # => "grrr"
+########################
+# 6. Despacho Múltiple #
+########################
-# Revisar la jerarquía de tipos locales
-issubtype(Tigre,Gato) # => false
-issubtype(Leon,Gato) # => true
-issubtype(Pantera,Gato) # => true
+# En Julia, todas las funciones nombradas son funciones genéricas.
+# Esto significa que se construyen a partir de muchos métodosmás pequeños.
+# Cada constructor de Leon es un método de la función genérica Leon.
-# Definición de una función que toma Gatos
-function mascota(gato::Gato)
- println("El gato dice $(maullar(gato))")
-end
+# Por ejemplo, vamos a hacer métodos para para Leon, Pantera, y Tigre de una
+# función genérica maullar:
+
+# acceso utilizando notación de puntos
+maullar(animal::Leon) = animal.rugido
+# => maullar (generic function with 1 method)
+maullar(animal::Pantera) = "grrr"
+# => maullar (generic function with 2 methods)
+maullar(animal::Tigre) = "rawwwr"
+# => maullar (generic function with 3 methods)
+
+# Se puede obtener una lista de métodos con la función methods.
+methods(maullar)
+#=
+ # 3 methods for generic function "maullar":
+ maullar(animal::Leon) at none:1
+ maullar(animal::Pantera) at none:1
+ maullar(animal::Tigre) at none:1
+=#
+
+# Prueba de la función maullar.
+maullar(tigre) # => "rawwwr"
+maullar(Leon("cafe", "ROAAR")) # => "ROAAR"
+maullar(Pantera()) # => "grrr"
+
+# Revisar la jerarquía de tipos locales.
+issubtype(Tigre, Gato) # => false # igual que: Tigre <: Gato
+issubtype(Leon, Gato) # => true # igual que: Leon <: Gato
+issubtype(Pantera, Gato) # => true
+
+# Definición de una función que acepta argumentos de tipo Gato.
+mascota(gato::Gato) = println("El gato dice $(maullar(gato))")
+
+mascota(Leon("42")) # El gato dice 42
-mascota(Leon("42")) # => imprime "El gato dice 42"
try
- mascota(tigger) # => ERROR: no method mascota(Tigre))
+ mascota(tigre) # ERROR: `mascota` has no method matching mascota(::Tigre)
catch e
- println(e)
+ println(e) # MethodError(mascota,(Tigre(3.5,"anaranjado"),))
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.
+# En los lenguajes orientados a objetos, el despacho simple es común. Esto
+# significa que la implementación del método a llamar se selecciona en base
+# al tipo del primer argumento.
+
+# En Julia, los tipos de todos los argumentos contribuyen a seleccionar método
+# más específico.
# 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(t::Tigre, c::Gato) = println("¡El tigre $(t.color_pelaje) gana!")
# => pelear (generic function with 1 method)
-pelear(tigger,Pantera()) # => imprime ¡El tigre anaranjado gana!
-pelear(tigger,Leon("ROAR")) # => ¡El tigre anaranjado gana!
+pelear(tigre, Pantera()) # ¡El tigre anaranjado gana!
+pelear(tigre, 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")
+# Vamos a cambiar el comportamiento cuando el Gato sea específicamente un Leon.
+pelear(t::Tigre, l::Leon) = println("El león con melena $(l.color_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
+pelear(tigre, Pantera()) # ¡El tigre anaranjado gana!
+pelear(tigre, Leon("ROAR")) # 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)
+# No necesitamos un tigre para poder luchar.
+pelear(l::Leon, c::Gato) = println("El gato victorioso dice $(maullar(c)).")
+# => pelear (generic function with 3 methods)
+
+methods(pelear)
+#=
+ # 3 methods for generic function "pelear":
+ pelear(t::Tigre,l::Leon) at none:2
+ pelear(t::Tigre,c::Gato) at none:1
+ pelear(l::Leon,c::Gato) at none:2
+=#
-pelear(Leon("balooga!"),Pantera()) # => imprime El gato victorioso dice grrr
+pelear(Leon("balooga!"), Pantera()) # El gato victorioso dice grrr.
try
- pelear(Pantera(),Leon("RAWR")) # => ERROR: no method pelear(Pantera, Leon))
-catch
+ # ERROR: `pelear` has no method matching pelear(::Pantera, ::Leon)
+ pelear(Pantera(),Leon("RAWR"))
+catch # no hacer nada con la excepción atrapada
end
-# Un metodo con el gato primero
+# Un metodo con el tipo 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
+#=
+ 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 método de pelear
+# será llamado en:
+pelear(Leon("RAR"),Leon("cafe","rar")) # 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
+
+pelear(Leon("GR"),Leon("cafe","rar")) # Los leones llegan a un empate
+
+
+################################
+# 7. Un vistazo de bajo nivel. #
+################################
+
+# Se puede echar un vistazo al código IR de LLVM y al código
+# ensamblador generado.
+area_cuadrado(l) = l * l # => area_cuadrado (generic function with 1 method)
+
+area_cuadrado(5) # => 25
+
+# ¿Qué sucede cuando damos area_cuadrada diferentes tipos de argumentos?
+code_native(area_cuadrado, (Int32,))
+#=
+ .section __TEXT,__text,regular,pure_instructions
+ Filename: none
+ Source line: 1 # prólogo
+ push RBP
+ mov RBP, RSP
+ Source line: 1
+ imul RDI, RDI # elevar l al cuadrado
+ mov RAX, RDI # almacenar el resultado en RAX
+ pop RBP # restaurar el puntero base anterior
+ ret # el resultado estará en RAX
+=#
+
+code_native(area_cuadrado, (Float32,))
+#=
+ .section __TEXT,__text,regular,pure_instructions
+ Filename: none
+ Source line: 1
+ push RBP
+ mov RBP, RSP
+ Source line: 1
+ mulss XMM0, XMM0 # multiplicación escalar de presición simple (AVX)
+ pop RBP
+ ret
+=#
+
+code_native(area_cuadrado, (Float64,))
+#=
+ .section __TEXT,__text,regular,pure_instructions
+ Filename: none
+ Source line: 1
+ push RBP
+ mov RBP, RSP
+ Source line: 1
+ mulsd XMM0, XMM0 # multiplicación escalar de presición doble (AVX)
+ pop RBP
+ ret
+=#
+
+# Ten en cuenta que Julia usará instrucciones de punto flotante si el tipo de
+# alguno de los argumentos es flotante.
+
+# Vamos a calcular el área de un círculo.
+area_circulo(r) = π * r * r # area_circulo (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
- #
+#=
+ .section __TEXT,__text,regular,pure_instructions
+ Filename: none
+ Source line: 1
+ push RBP
+ mov RBP, RSP
+ Source line: 1
+ cvtsi2sd XMM1, EDI # cargar entero r de la memoria
+ movabs RAX, 4477117456 # cargar constante matemática π
+ movsd XMM0, QWORD PTR [RAX]
+ mulsd XMM0, XMM1 # π * r
+ mulsd XMM0, XMM1 # (π * 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
- #
+#=
+ .section __TEXT,__text,regular,pure_instructions
+ Filename: none
+ Source line: 1
+ push RBP
+ mov RBP, RSP
+ movabs RAX, 4477120336
+ movsd XMM1, QWORD PTR [RAX]
+ Source line: 1
+ mulsd XMM1, XMM0
+ mulsd XMM1, XMM0
+ movaps XMM0, XMM1
+ pop RBP
+ ret
+=#
```
-## ¿Listo para más?
+![Julia-tan](http://www.mechajyo.org/wp/wp-content/uploads/2014/10/3a2c3b7de5dd39aa7f056a707cd4eb59.png)
-Puedes obtener muchos más detalles en [The Julia Manual](http://docs.julialang.org/en/latest/manual/)
+## ¿Listo para más?
-El mejor lugar para obtener ayuda con Julia es el (muy amable) [lista de correos](https://groups.google.com/forum/#!forum/julia-users).
+Para más detalles, lee el [manual de Julia](http://docs.julialang.org/en/release-0.3).
+El mejor lugar para obtener ayuda con Julia, es en su amigable [lista de correos](https://groups.google.com/forum/#!forum/julia-users).
diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown
new file mode 100644
index 00000000..55453c56
--- /dev/null
+++ b/fr-fr/erlang-fr.html.markdown
@@ -0,0 +1,327 @@
+---
+language: erlang
+contributors:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
+translators:
+ - ["Julien Cretel", "https://github.com/Jubobs"]
+filename: learnerlang-fr.erl
+lang: fr-fr
+---
+
+```erlang
+% Un signe pour cent marque le début d'un commentaire de fin de ligne.
+
+%% Deux signes pour cent sont utilisés pour commenter les fonctions.
+
+%%% Trois signes pour cent sont utilisés pour commenter les modules.
+
+% Trois symboles de ponctuation sont utilisés en Erlang.
+% Les virgules (`,`) servent à séparer les paramètres dans les appels de
+% fonctions, les contructeurs, et les motifs.
+% Les points (`.`) (suivis par des blancs) servent à séparer les fonctions et
+% les expressions dans l'interpréteur.
+% Les points-virgules (`;`) servent à séparer les clauses. Ces dernières
+% apparaissent dans différent cas de figure : définitions de fonctions et
+% expressions `case`, `if`, `try..catch`, `receive`.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 1. Variables et filtrage par motif
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+(L'équivalent anglais de *filtrage par motif* est *pattern patching*.)
+
+Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule.
+
+% Les variables Erlang ne peuvent être affectées qu'une seule fois ; si vous
+% essayez d'affecter une autre valeur à la variable `Nb`, vous obtiendrez
+% une erreur.
+Nb = 43. % ** exception error: no match of right hand side value 43
+
+% Dans la plupart des languages, `=` indique une affectation. En Erlang,
+% cependant, `=` indique un filtrage par motif. En fait, `Gauche = Droit`
+% signifie ce qui suit : évalue le côté droit (`Droit`), et ensuite filtre le
+% résultat à l'aide du motif du côté gauche (`Gauche`).
+Nb = 7 * 6.
+
+% Nombre en virgule flottante.
+Pi = 3.14159.
+
+% Les atomes représentent des valeurs constantes non-numériques. Un atome
+% commence par une lettre minuscule, suivie d'une séquence composée de
+% caractères alphanumériques, de tirets bas (`_`), ou d'arobases (`@`).
+Bonjour = bonjour.
+AutreNoeud = exemple@noeud.
+
+% Les atomes de valeur autre qu'alphanumérique peuvent être délimités par
+% des guillemets droits simples.
+AtomeAvecEspace = 'un atome contenant des espaces'.
+
+% Les tuples sont similaires aux enregistrements du language C.
+Point = {point, 10, 45}.
+
+% Pour extraire des valeurs d'un tuple, on filtre par motif avec
+% l'opérateur `=`.
+{point, X, Y} = Point. % X = 10, Y = 45
+
+% On peut utiliser `_` comme caractère joker pour les variables qui ne nous
+% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement
+% aux variables normales, de multiples apparitions de `_` dans un même motif
+% ne lient pas nécessairement à la même valeur.
+Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}},
+ {pointure, 42}}.
+{_, {_, {_, Qui}, _}, _} = Personne. % Qui = joe
+
+% Pour créer une liste, on écrit les éléments de la liste entre crochets, en
+% les séparant par des virgules.
+% Les éléments d'une liste peuvent avoir n'importe quel type.
+% Le premier élément d'une liste est appelé la tête de la liste. Si on retire
+% la tête d'une liste, ce qui reste est appelée la queue de la liste.
+Articles = [{pommes, 10}, {poires, 6}, {lait, 3}].
+
+% Si `Q` est une liste, alors `[T|Q]` est aussi une liste dont la tête est `T`
+% et dont la queue est `Q`. La barre verticale (`|`) sépare la tête d'une
+% liste de sa queue.
+% `[]` est la liste vide.
+% On peut extraire des éléments d'une liste par filtrage de motif. Si `L` est
+% une liste non vide, alors l'expression `[X|Y] = L`, où `X` et `Y` sont des
+% variables non affectées, va extraire la tête de la liste dans `X` et la
+% queue de la liste dans `Y`.
+[PremierArticle|AutresArticles] = Articles.
+% PremierArticle = {pommmes, 10}
+% AutresArticles = [{poires, 6}, {lait, 3}]
+
+% Il n'y a pas de chaînes de caractères en Erlang. Les chaînes de caractères
+% ne sont rien de plus que des listes d'entiers.
+% Les chaînes de caractères sont délimitées par des guillemets droits doubles
+% (`"`).
+Nom = "Bonjour".
+[66, 111, 110, 106, 111, 117, 114] = "Bonjour".
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 2. Programmation séquentielle.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Les modules constituent l'unité de base d'un programme Erlang. Toutes les
+% fonctions que l'on écrit sont enregistrées dans des modules. Les modules sont
+% enregistrés dans des fichiers avec une extension `.erl`.
+% Les modules doivent être compilés afin d'éxecuter le programme.
+% Un module compilé a une extension `.beam`.
+-module(geometrie).
+-export([aire/1]). % la liste des fonctions exportées par le module.
+
+% La fonction `aire` est composée de deux clauses. Les clauses sont séparées
+% par un point-virgule, et la dernière clause est suivie d'un point et un
+% espace blanc. Chaque clause a une en-tête et un corps ; l'en-tête consiste
+% en un nom de fonction suivi d'un motif (entre parenthèses), et le corps
+% consiste en une séquence d'expressions, qui sont évaluées si le motif de
+% l'en-tête est cohérent par rapport à la valeur des paramètres d'appel.
+% L'expression est filtrée séquentiellement par les différents motifs, dans
+% l'ordre dans lequel ils apparaissent dans la définition de la fonction.
+aire({rectangle, Largeur, Hauteur}) -> Largeur * Hauteur;
+aire({cercle, R}) -> 3.14159 * R * R.
+
+% Compilation du code du fichier geometrie.erl.
+c(geometrie). % {ok,geometrie}
+
+% Le nom du module doit être inclus avec le nom de la fonction afin
+% d'identifier précisément quelle fonction on souhaite appeler.
+geometrie:aire({rectangle, 10, 5}). % 50
+geometrie:area({cercle, 1.4}). % 6.15752
+
+% En Erlang, deux fonctions portant le même nom mais ayant des arités
+% différentes (c'est à dire ne prenant pas le même nombre de paramètres)
+% au sein d'un même module représentent des fonctions complètement
+% différentes.
+-module(lib_divers).
+-export([somme/1]). % exporte la fonction `somme` d'arité 1
+ % acceptant un paramètre : une liste d'entiers.
+somme(L) -> somme(L, 0).
+somme([], N) -> N;
+somme([T|Q], N) -> somme(Q, T+N).
+
+% Les `fun`s sont des fonctions "anonymes" ; elles sont appelées ainsi parce
+% qu'elles n'ont pas de nom. Cependant, elles peuvent être affectées à des
+% variables.
+Doubler = fun(X) -> 2 * X end. % `Doubler` pointe vers une fonction anonyme
+ % dont le handle est : #Fun<erl_eval.6.17052888>
+Doubler(2). % 4
+
+% Les fonctions peuvent prendre des `fun`s comme paramètres et peuvent renvoyer
+% des `fun`s.
+Mult = fun(Fois) -> ( fun(X) -> X * Fois end ) end.
+Tripler = Mult(3).
+Tripler(5). % 15
+
+% Les listes en compréhension sont des expressions qui créent des listes sans
+% requérir ni `fun`s, ni maps, ni filters.
+% La notation `[F(X) || X <- L]` signifie "la liste des `F(X)` où `X` est
+% extrait de la liste `L`."
+L = [1,2,3,4,5].
+[2 * X || X <- L]. % [2,4,6,8,10]
+% Une liste en compréhension peut être constituée de générateurs, ainsi que de
+% gardes, qui sélectionnent un sous-ensemble des valeurs générées.
+NombresPairs = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
+
+% La garde est un élément syntaxique qui rend le filtrage par motif encore
+% plus puissant. Les gardes permettent de d'effectuer de simple tests et
+% comparaisons sur les variables d'un motif. Les gardes peuvent être
+% utilisées dans les en-têtes de fonctions, au sein desquelles elles sont
+% introduites par le mot-clé `when`, ou encore à n'importe quel endroit où
+% une expression est autorisée.
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+% Une garde est une série d'expressions gardes, séparées par des virgules (`,`).
+% La garde `ExprGarde1, ExprGarde2, ..., ExprGardeN` est vraie si toutes les
+% expressions gardes `ExprGarde1`, `ExprGarde2, ..., `ExprGardeN` ont pour
+% valeur `true`.
+est_chat(A) when is_atom(A), A =:= chat -> true;
+est_chat(A) -> false.
+est_chien(A) when is_atom(A), A =:= chien -> true;
+est_chien(A) -> false.
+
+% Une séquence de gardes est composée soit d'une seule garde ou bien d'une
+% série de gardes, séparées par des points-virgules (`;`). La séquence de
+% gardes `G1; G2; ...; Gn` est vraie si au moins l'une des gardes `G1`, `G2`,
+% ..., `Gn` a pour valeur `true`.
+est_animal(A) when is_atom(A), (A =:= chien) or (A =:= chat) -> true;
+est_animal(A) -> false.
+
+% Attention : toutes les expressions Erlang valides ne peuvent pas être
+% utilisées comme expressions gardes ; en particulier, nos fonctions
+% `est_chat` et `est_chien` ne sont pas autorisées au sein de la séquence de
+% gardes dans la définition de `est_animal`. Pour plus de détails sur les
+% expressions autorisées ands les séquences de gardes, voir cette
+% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
+% du manuel Erlang.
+
+% Les enregistrements permettent d'associer un nom à un certain élément dans
+% un tuple.
+% Les enregistrements peuvent être définis dans des fichiers sources Erlang
+% ou bien dans des fichiers avec une extension `.hrl`, qui sont ensuite inclus
+% dans des fichiers sources Erlang.
+-record(afaire, {
+ statut = rappel, % Valeur par défaut
+ qui = joe,
+ texte
+}).
+
+% Les définitions d'enregistrements doivent être lues dans l'interpreteur
+% pour qu'on puisse définir un enregistrement. On utilise la fonction `rr`
+% (abbréviation de *read records* en anglais, ou *lire enregistrements* en
+% français) pour ça.
+rr("enregistrements.hrl"). % [afaire]
+
+% Création et mise à jour d'enregistrements :
+X = #afaire{}.
+% #afaire{statut = rappel, qui = joe, texte = undefined}
+X1 = #afaire{statut = urgent, texte = "Corriger erreurs dans livre"}.
+% #afaire{statut = urgent, qui = joe, texte = "Corriger erreurs dans livre"}
+X2 = X1#afaire{statut = fini}.
+% #afaire{statut = fini, qui = joe, texte = "Corriger erreurs dans livre"}
+
+% Expressions `case`.
+% `filter` renvoie une liste de tous les éléments `X` d'une liste `L` pour
+% lesquels `P(X)` est vrai.
+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]
+
+% Expressions `if`.
+max(X, Y) ->
+ if
+ X > Y -> X;
+ X < Y -> Y;
+ true -> nil
+ end.
+
+% Attention : au moins l'une des gardes dans l'expression `if` doit avoir pour
+% valeur `true` ; autrement, une exception sera lancée.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 3. Exceptions.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Des exceptions sont lancées par le système quand des erreurs internes
+% surviennent, ou de manière explicite dans le programme en appelant
+% `throw(Exception)`, `exit(Exception)`, ou `erlang:error(Exception)`.
+generer_exception(1) -> a;
+generer_exception(2) -> throw(a);
+generer_exception(3) -> exit(a);
+generer_exception(4) -> {'EXIT', a};
+generer_exception(5) -> erlang:error(a).
+
+% Erlang dispose de deux méthodes pour capturer une exception. La première
+% consiste à inclure l'appel de de la fonction qui lance l'exception dans une
+% expression `try...catch`.
+catcher(N) ->
+ try generer_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.
+
+% L'autre méthode consiste à inclure l'appel dans une expression `catch`.
+% Quand une exception est capturée, elle est convertie en un tuple qui décrit
+% l'erreur.
+catcher(N) -> catch generer_exception(N).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 4. Concurrence
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Erlang est basé sur le modèle d'acteur pour la concurrence. Seulement trois
+% opérations sont requises pour écrire des programmes concurrents en Erlang :
+% la création de processus, l'envoi de messages, et la réception de messages.
+
+% Pour démarrer un nouveau processus, on utilise la fonction `spawn`, qui
+% prend une fonction comme paramètre.
+
+F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
+spawn(F). % <0.44.0>
+
+% `spawn` renvoie un pid (*process identifier* en anglais, ou *identifiant de
+% processus* en français), qui peut être utilisé pour envoyer des messages au
+% processus en question. Pour passer des messages, on utilise l'opérateur `!`.
+% Pour que cela soit utile, on doit aussi être en mesure de recevoir des
+% messages, ce qui est accompli grâce à une clause `receive` :
+
+-module(calculerGeometrie).
+-compile(export_all).
+calculerAire() ->
+ receive
+ {rectangle, W, H} ->
+ W * H;
+ {cercle, R} ->
+ 3.14 * R * R;
+ _ ->
+ io:format("Seule l'aire d'un rectangle / cercle peut etre calculee.")
+ end.
+
+% Compilation du module and création d'un processus qui évalue `calculerAire`
+% dans l'interpréteur.
+c(calculerGeometrie).
+CalculerAire = spawn(calculerGeometrie, calculerAire, []).
+CalculerAire ! {cercle, 2}. % 12.56000000000000049738
+
+% L'interpréteur est lui-même un processus ; on peut utiliser `self` pour
+% obtenir le pid actuel.
+self(). % <0.41.0>
+
+```
+
+## Ressources (en anglais)
+
+* ["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/fr-fr/go-fr.html.markdown b/fr-fr/go-fr.html.markdown
index 2ff5902f..16558e7e 100644
--- a/fr-fr/go-fr.html.markdown
+++ b/fr-fr/go-fr.html.markdown
@@ -2,6 +2,7 @@
name: Go
category: language
language: Go
+lang: fr-fr
filename: learngo.go
contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
diff --git a/fr-fr/json-fr.html.markdown b/fr-fr/json-fr.html.markdown
new file mode 100644
index 00000000..49c95820
--- /dev/null
+++ b/fr-fr/json-fr.html.markdown
@@ -0,0 +1,62 @@
+---
+language: json
+filename: learnjson-fr.json
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+translators:
+ - ["Alois de Gouvello","https://github.com/aloisdg"]
+lang: fr-fr
+---
+
+Comme JSON est un format d'échange de données extrêmement simple, ce Apprendre X en Y minutes
+est susceptible d'être le plus simple jamais réalisé.
+
+JSON dans son état le plus pur n'a aucun commentaire, mais la majorité des parseurs accepterons
+les commentaires du langage C (`//`, `/* */`). Pour les besoins de ce document, cependant,
+tout sera du JSON 100% valide. Heureusement, il s'explique par lui-même.
+
+
+```json
+{
+ "Clé": "valeur",
+
+ "Clés": "devront toujours être entourées par des guillemets",
+ "nombres": 0,
+ "chaînes de caractères": "Hellø, wørld. Tous les caractères Unicode sont autorisés, accompagné d'un \"caractère d'échappement\".",
+ "a des booléens ?": true,
+ "rien": null,
+
+ "grand nombre": 1.2e+100,
+
+ "objets": {
+ "commentaire": "La majorité de votre strucutre sera des objets.",
+
+ "tableau": [0, 1, 2, 3, "Les tableaux peuvent contenir n'importe quoi.", 5],
+
+ "un autre objet": {
+ "commentaire": "Ces choses peuvent être imbriquées. C'est très utile."
+ }
+ },
+
+ "bêtises": [
+ {
+ "sources de potassium": ["bananes"]
+ },
+ [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, "neo"],
+ [0, 0, 0, 1]
+ ]
+ ],
+
+ "style alternatif": {
+ "commentaire": "regarde ça !"
+ , "position de la virgule": "n'a pas d'importance - aussi longtemps qu'elle est avant la valeur, alors elle est valide."
+ , "un autre commentaire": "comme c'est gentil"
+ },
+
+ "C'était court": "Et, vous avez terminé. Maintenant, vous savez tout ce que JSON a à offrir."
+}
+```
diff --git a/fr-fr/lua-fr.html.markdown b/fr-fr/lua-fr.html.markdown
index b4e2a161..1f592320 100644
--- a/fr-fr/lua-fr.html.markdown
+++ b/fr-fr/lua-fr.html.markdown
@@ -434,9 +434,9 @@ les librairies standard:
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://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">Lua pour programmeurs</a>
+* <a href="lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Référence condensée de Lua</a>
+* <a href="http://www.lua.org/pil/contents.html">Programmer en 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
@@ -446,4 +446,4 @@ Ce tutoriel a été originalement écrit pour <a href="tylerneylon.com">tylerney
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
+Amusez-vous bien avec Lua!
diff --git a/fr-fr/r-fr.html.markdown b/fr-fr/r-fr.html.markdown
new file mode 100644
index 00000000..7d30a48d
--- /dev/null
+++ b/fr-fr/r-fr.html.markdown
@@ -0,0 +1,747 @@
+---
+language: R
+contributors:
+ - ["e99n09", "http://github.com/e99n09"]
+ - ["isomorphismes", "http://twitter.com/isomorphisms"]
+translators:
+ - ["Anne-Catherine Dehier", "https://github.com/spellart"]
+filename: learnr-fr.r
+lang: fr-fr
+---
+
+R est un langage de programmation statistique. Il dispose de nombreuses
+bibliothèques pour le téléchargement et le nettoyage d'ensembles de données,
+l'exécution de procédures statistiques, et la réalisation de graphiques.
+On peut également exécuter des commmandes `R` au sein d'un document LaTeX.
+
+
+```r
+
+# Les commentaires commencent avec des symboles numériques.
+
+# Il n'est pas possible de faire des commentaires multilignes,
+# mais on peut placer plusieurs commentaires les uns en dessous
+# des autres comme ceci.
+
+# Sur Mac, taper COMMAND-ENTER pour exécuter une ligne
+# et sur Windows taper CTRL-ENTER
+
+
+
+########################################################################
+# Les choses que vous pouvez faire sans rien comprendre
+# à la programmation
+########################################################################
+
+# Dans cette section, nous vous montrons quelques trucs cools que vous
+# pouvez faire avec R sans rien comprendre à la programmation.
+# Ne vous inquiétez pas si vous ne comprenez pas tout ce que le code fait.
+# Profitez simplement !
+
+data() # parcours les ensembles de données préchargées
+data(rivers) # récupère ceci : "Lengths of Major North American Rivers"
+ls() # notez que "rivers" apparaît maintenant dans votre espace de travail
+head(rivers) # donne un aperçu des données
+# 735 320 325 392 524 450
+
+length(rivers) # Combien de rivers ont été mesurées ?
+# 141
+summary(rivers) # Quelles sont les principales données statistiques ?
+# Min. 1st Qu. Median Mean 3rd Qu. Max.
+# 135.0 310.0 425.0 591.2 680.0 3710.0
+
+# Fait un diagramme à tiges et à feuilles (visualisation de données de
+# types histogramme)
+stem(rivers)
+
+
+# Le point décimal est de 2 chiffres à droite du |
+#
+# 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)) # Notez que les données ne sont ni normales
+# ni lognormales !
+# Prenez-ça, la courbe en cloche
+
+# Le point décimal est à 1 chiffre à gauche du |
+#
+# 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
+
+# Fait un histogramme :
+hist(rivers, col="#333333", border="white", breaks=25) # amusez-vous avec ces paramètres
+hist(log(rivers), col="#333333", border="white", breaks=25) # vous ferez plus de tracés plus tard
+
+# Ici d'autres données qui viennent préchargées. R en a des tonnes.
+data(discoveries)
+plot(discoveries, col="#333333", lwd=3, xlab="Year",
+ main="Number of important discoveries per year")
+plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year",
+ main="Number of important discoveries per year")
+
+# Plutôt que de laisser l'ordre par défaut (par année)
+# Nous pourrions aussi trier pour voir ce qu'il y a de typique
+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)
+#
+# Le point décimale est à la |
+#
+# 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
+
+# Lance un dé plusieurs fois
+round(runif(7, min=.5, max=6.5))
+# 1 4 6 1 4 6 4
+# Vos numéros diffèreront des miens à moins que nous mettions
+# le même random.seed(31337)
+
+# Dessine à partir d'une normale Gaussienne 9 fois
+rnorm(9)
+# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
+# [7] -0.59975593 0.57629164 1.08455362
+
+
+
+##############################################################
+# les types de données et l'arithmétique de base
+##############################################################
+
+# Maintenant pour la partie orientée programmation du tutoriel.
+# Dans cette section vous rencontrerez les types de données importants de R :
+# les entiers, les numériques, les caractères, les logiques, et les facteurs.
+
+# LES ENTIERS
+# Les entiers de type long sont écrits avec L
+5L # 5
+class(5L) # "integer"
+# (Essayez ?class pour plus d'informations sur la fonction class().)
+# Avec R, chaque valeur seule, comme 5L, est considérée comme
+# un vecteur de longueur 1
+length(5L) # 1
+# On peut avoir un vecteur d'entiers avec une longueur > 1 :
+c(4L, 5L, 8L, 3L) # 4 5 8 3
+length(c(4L, 5L, 8L, 3L)) # 4
+class(c(4L, 5L, 8L, 3L)) # "integer"
+
+# LES NUMÉRIQUES
+# Un "numeric" est un nombre à virgule flottante d'une précision double
+5 # 5
+class(5) # "numeric"
+# Encore une fois, tout dans R est un vecteur ;
+# Vous pouvez faire un vecteur numérique avec plus d'un élément
+c(3,3,3,2,2,1) # 3 3 3 2 2 1
+# Vous pouvez aussi utiliser la notation scientifique
+5e4 # 50000
+6.02e23 # nombre d'Avogadro
+1.6e-35 # longueur de Planck
+# Vous pouvez également avoir des nombres infiniments grands ou petits
+class(Inf) # "numeric"
+class(-Inf) # "numeric"
+# Vous pouvez utiliser "Inf", par exemple, dans integrate(dnorm, 3, Inf);
+# Ça permet d'éviter de réaliser une table de la loi normale.
+
+# ARITHMÉTIQUES DE BASE
+# Vous pouvez faire de l'arithmétique avec des nombres
+# Faire des opérations arithmétiques en mixant des entiers
+# et des numériques
+# donne un autre numérique
+10L + 66L # 76 # un entier plus un entier donne un entier
+53.2 - 4 # 49.2 # un numérique moins un numérique donne un numérique
+2.0 * 2L # 4 # un numérique multiplié par un entier donne un numérique
+3L / 4 # 0.75 # un entier sur un numérique donne un numérique
+3 %% 2 # 1 # le reste de deux numériques est un autre numérique
+# Les opérations arithmétiques illégales donnent un "Not A Number" :
+0 / 0 # NaN
+class(NaN) # "numeric"
+# Vous pouvez faire des opérations arithmétiques avec deux vecteurs d'une
+# longueur plus grande que 1, à condition que la longueur du plus grand
+# vecteur soit un multiple entier du plus petit
+c(1,2,3) + c(1,2,3) # 2 4 6
+
+# LES CARACTÈRES
+# Il n'y a pas de différences entre les chaînes de caractères et
+# les caractères en R
+"Horatio" # "Horatio"
+class("Horatio") # "character"
+class('H') # "character"
+# Ceux-ci sont tous les deux des vecteurs de longueur 1
+# Ici un plus long :
+c('alef', 'bet', 'gimmel', 'dalet', 'he')
+# =>
+# "alef" "bet" "gimmel" "dalet" "he"
+length(c("Call","me","Ishmael")) # 3
+# Vous pouvez utiliser des expressions rationnelles sur les vecteurs de caractères :
+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."
+# R possède plusieurs vecteurs de caractères préconstruits :
+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"
+
+# LES TYPES BOOLÉENS
+# En R, un "logical" est un booléen
+class(TRUE) # "logical"
+class(FALSE) # "logical"
+# Leur comportement est normal
+TRUE == TRUE # TRUE
+TRUE == FALSE # FALSE
+FALSE != FALSE # FALSE
+FALSE != TRUE # TRUE
+# Les données manquantes (NA) sont logiques également
+class(NA) # "logical"
+# On utilise | et & pour les operations logiques.
+# OR
+TRUE | FALSE # TRUE
+# AND
+TRUE & FALSE # FALSE
+# Vous pouvez tester si x est TRUE
+isTRUE(TRUE) # TRUE
+# Ici nous avons un vecteur de type logique avec plusieurs éléments :
+c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE
+c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
+
+# LES FACTEURS
+# Les facteurs sont généralement utilisés pour y stocker des
+# variables qualitatives (catégorielles).
+# Les facteurs peuvent être ordonnés (comme le niveau scolaire
+# des enfants) ou non ordonnés (comme le sexe)
+factor(c("female", "female", "male", NA, "female"))
+# female female male <NA> female
+# Les niveaux : female male
+# Les facteurs possèdent un attribut appelé niveau ("level").
+# Les niveaux sont des vecteurs contenant toutes les valeurs
+# que peuvent prendre les données catégorielles.
+# Notez que les données manquantes n'entrent pas dans le niveau
+levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
+# Si le vecteur de facteurs a une longueur 1, ses niveaux seront
+# de longueur 1 également
+length(factor("male")) # 1
+length(levels(factor("male"))) # 1
+# On rencontre communément des facteurs dans des "data frame",
+# un type de données que nous couvrirons plus tard
+data(infert) # "Infertility after Spontaneous and Induced Abortion"
+levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
+
+# NULL
+# "NULL" est bizarre ; on l'utilise pour effacer un vecteur
+class(NULL) # NULL
+parakeet = c("beak", "feathers", "wings", "eyes")
+parakeet
+# =>
+# [1] "beak" "feathers" "wings" "eyes"
+parakeet <- NULL
+parakeet
+# =>
+# NULL
+
+# LES CONVERSIONS DE TYPES
+# Les conversions de types servent à forcer une valeur à prendre
+# un type différent
+as.character(c(6, 8)) # "6" "8"
+as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE
+# Si vous mettez des éléments de différents types dans un vecteur,
+# des coercitions bizarres se produisent :
+c(TRUE, 4) # 1 4
+c("dog", TRUE, 4) # "dog" "TRUE" "4"
+as.numeric("Bilbo")
+# =>
+# [1] NA
+# Message d'avertissement :
+# NAs est introduit par coercition
+
+# Notez également : ce n'étaient que des types de données basiques
+# Il y a beaucoup d'autres types de données, comme les dates,
+# les séries temporelles, etc ...
+
+
+
+#######################################
+# Variables, boucles , if/else
+#######################################
+
+# Une variable est comme une boîte dans laquelle on garde une valeur
+# pour l'utiliser plus tard.
+# Nous appellons ça "assigner" une valeur à une variable.
+# Avoir des variables nous permet d'écrire des boucles, des fonctions, et
+# des instructions conditionnelles (if/else)
+
+# LES VARIABLES
+# Beaucoup de façons d'assigner des choses :
+x = 5 # c'est correct
+y <- "1" # c'est préféré
+TRUE -> z # ça marche mais c'est bizarre
+
+# LES BOUCLES
+# Il y a les boucles for :
+for (i in 1:4) {
+ print(i)
+}
+# Il y a les boucles while :
+a <- 10
+while (a > 4) {
+ cat(a, "...", sep = "")
+ a <- a - 1
+}
+# Gardez à l'esprit que les boucles for et while s'exécutent lentement
+# en R.
+# Des opérations sur la totalité d'un vecteur (ex une ligne entière,
+# une colonne entière),
+# ou les fonctions de type apply() (nous en parlerons plus tard),
+# sont préférées.
+
+# IF/ELSE
+# Encore une fois assez standard
+if (4 > 3) {
+ print("4 is greater than 3")
+} else {
+ print("4 is not greater than 3")
+}
+# =>
+# [1] "4 is greater than 3"
+
+# LES FONCTIONS
+# se définissent comme ceci :
+jiggle <- function(x) {
+ x = x + rnorm(1, sd=.1) # ajoute un peu de bruit (contrôlé)
+ return(x)
+}
+# Appelées comme n'importe quelles autres fonction R :
+jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043
+
+
+
+##########################################################################
+# Les structures de données : les vecteurs, les matrices,
+# les data frames et les tableaux
+##########################################################################
+
+# À UNE DIMENSION
+
+# Commençons par le tout début, et avec quelque chose que
+# vous connaissez déjà : les vecteurs.
+vec <- c(8, 9, 10, 11)
+vec # 8 9 10 11
+# Nous demandons des éléments spécifiques en les mettant entre crochets
+# (Notez que R commence à compter à partir de 1)
+vec[1] # 8
+letters[18] # "r"
+LETTERS[13] # "M"
+month.name[9] # "September"
+c(6, 8, 7, 5, 3, 0, 9)[3] # 7
+# Nous pouvons également rechercher des indices de composants spécifiques,
+which(vec %% 2 == 0) # 1 3
+# Récupèrer seulement les premières ou dernières entrées du vecteur,
+head(vec, 1) # 8
+tail(vec, 2) # 10 11
+# ou vérifier si un certaine valeur est dans le vecteur
+any(vec == 10) # TRUE
+# Si un index "dépasse" vous obtiendrez NA :
+vec[6] # NA
+# Vous pouvez trouver la longueur de votre vecteur avec length()
+length(vec) # 4
+# Vous pouvez réaliser des opérations sur des vecteurs entiers ou des
+# sous-ensembles de vecteurs
+vec * 4 # 16 20 24 28
+vec[2:3] * 5 # 25 30
+any(vec[2:3] == 8) # FALSE
+# Et R a beaucoup de méthodes statistiques pré-construites pour les vecteurs :
+mean(vec) # 9.5
+var(vec) # 1.666667
+sd(vec) # 1.290994
+max(vec) # 11
+min(vec) # 8
+sum(vec) # 38
+# Quelques fonctions préconstruites sympas supplémentaires :
+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
+
+# À DEUX DIMENSIONS (TOUT DANS UNE CLASSE)
+
+# Vous pouvez créer une matrice à partir d'entrées du même type comme ceci :
+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
+# Différemment du vecteur, la classe d'une matrice est "matrix",
+# peut importe ce qu'elle contient
+class(mat) # => "matrix"
+# Récupérer la première ligne
+mat[1,] # 1 4
+# Réaliser une opération sur la première colonne
+3 * mat[,1] # 3 6 9
+# Demander une cellule spécifique
+mat[3,2] # 6
+
+# Transposer la matrice entière
+t(mat)
+# =>
+# [,1] [,2] [,3]
+# [1,] 1 2 3
+# [2,] 4 5 6
+
+# La multiplication de matrices
+mat %*% t(mat)
+# =>
+# [,1] [,2] [,3]
+# [1,] 17 22 27
+# [2,] 22 29 36
+# [3,] 27 36 45
+
+# cbind() colle des vecteurs ensemble en colonne pour faire une matrice
+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
+# Encore une fois regardez ce qui se passe !
+# Parce que les matrices peuvent contenir des entrées de toutes sortes de
+# classes, tout sera converti en classe caractère
+c(class(mat2[,1]), class(mat2[,2]))
+
+# rbind() colle des vecteurs ensemble par lignes pour faire une matrice
+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
+# Ah, tout de la même classe. Pas de coercitions. Beaucoup mieux.
+
+# À DEUX DIMENSIONS (DE CLASSES DIFFÉRENTES)
+
+# Pour des colonnes de différents types, utiliser une data frame
+# Cette structure de données est si utile pour la programmation statistique,
+# qu'une version a été ajoutée à Python dans le paquet "pandas".
+
+students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"),
+ c(3,2,2,1,0,-1),
+ c("H", "G", "G", "R", "S", "G"))
+names(students) <- c("name", "year", "house") # name the columns
+class(students) # "data.frame"
+students
+# =>
+# name year house
+# 1 Cedric 3 H
+# 2 Fred 2 G
+# 3 George 2 G
+# 4 Cho 1 R
+# 5 Draco 0 S
+# 6 Ginny -1 G
+class(students$year) # "numeric"
+class(students[,3]) # "factor"
+# Trouver les dimensions
+nrow(students) # 6
+ncol(students) # 3
+dim(students) # 6 3
+# La fonction data.frame() convertit les vecteurs caractères en vecteurs de
+# facteurs par défaut; désactiver cette fonction en règlant
+# stringsAsFactors = FALSE quand vous créer la data.frame
+?data.frame
+
+# Il y a plusieurs façons de subdiviser les data frames,
+# toutes subtilement différentes
+students$year # 3 2 2 1 0 -1
+students[,2] # 3 2 2 1 0 -1
+students[,"year"] # 3 2 2 1 0 -1
+
+# Une version améliorée de la structure data.frame est data.table.
+# Si vous travaillez avec des données volumineuses ou des panels, ou avez
+# besoin de fusionner quelques ensembles de données, data.table peut être
+# un bon choix. Ici un tour éclair :
+install.packages("data.table") # télécharge le paquet depuis CRAN
+require(data.table) # le charge
+students <- as.data.table(students)
+students # regardez la différence à l'impression
+# =>
+# name year house
+# 1: Cedric 3 H
+# 2: Fred 2 G
+# 3: George 2 G
+# 4: Cho 1 R
+# 5: Draco 0 S
+# 6: Ginny -1 G
+students[name=="Ginny"] # obtiens les lignes avec name == "Ginny"
+# =>
+# name year house
+# 1: Ginny -1 G
+students[year==2] # obtiens les lignes avec year == 2
+# =>
+# name year house
+# 1: Fred 2 G
+# 2: George 2 G
+# data.table facilite la fusion entre deux ensembles de données
+# Faisons une autre data.table pour fusionner students
+founders <- data.table(house=c("G","H","R","S"),
+ founder=c("Godric","Helga","Rowena","Salazar"))
+founders
+# =>
+# house founder
+# 1: G Godric
+# 2: H Helga
+# 3: R Rowena
+# 4: S Salazar
+setkey(students, house)
+setkey(founders, house)
+students <- founders[students] # merge les deux ensembles de données qui matchent "house"
+setnames(students, c("house","houseFounderName","studentName","year"))
+students[,order(c("name","year","house","houseFounderName")), with=F]
+# =>
+# studentName year house houseFounderName
+# 1: Fred 2 G Godric
+# 2: George 2 G Godric
+# 3: Ginny -1 G Godric
+# 4: Cedric 3 H Helga
+# 5: Cho 1 R Rowena
+# 6: Draco 0 S Salazar
+
+# data.table facilite le résumé des tableaux
+students[,sum(year),by=house]
+# =>
+# house V1
+# 1: G 3
+# 2: H 3
+# 3: R 1
+# 4: S 0
+
+# Pour supprimer une colonne d'une data.frame ou data.table,
+# assignez-lui la valeur NULL
+students$houseFounderName <- NULL
+students
+# =>
+# studentName year house
+# 1: Fred 2 G
+# 2: George 2 G
+# 3: Ginny -1 G
+# 4: Cedric 3 H
+# 5: Cho 1 R
+# 6: Draco 0 S
+
+# Supprimer une ligne en subdivisant
+# En utilisant data.table :
+students[studentName != "Draco"]
+# =>
+# house studentName year
+# 1: G Fred 2
+# 2: G George 2
+# 3: G Ginny -1
+# 4: H Cedric 3
+# 5: R Cho 1
+# En utilisant data.frame :
+students <- as.data.frame(students)
+students[students$house != "G",]
+# =>
+# house houseFounderName studentName year
+# 4 H Helga Cedric 3
+# 5 R Rowena Cho 1
+# 6 S Salazar Draco 0
+
+# MULTI-DIMENSIONNELLE (TOUS ÉLÉMENTS D'UN TYPE)
+
+# Les arrays créent des tableaux de n dimensions.
+# Tous les éléments doivent être du même type.
+# Vous pouvez faire un tableau à 2 dimensions (une sorte de matrice)
+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
+# Vous pouvez aussi utiliser array pour faire des matrices à 3 dimensions :
+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
+
+# LES LISTES (MULTI-DIMENSIONNELLES, ÉVENTUELLEMMENT DÉCHIRÉES,
+# DE DIFFÉRENTS TYPES)
+
+# Enfin, R a des listes (de vecteurs)
+list1 <- list(time = 1:40)
+list1$price = c(rnorm(40,.5*list1$time,4)) # random
+list1
+# Vous pouvez obtenir des éléments de la liste comme ceci
+list1$time # une façon
+list1[["time"]] # une autre façon
+list1[[1]] # encore une façon différente
+# =>
+# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+# [34] 34 35 36 37 38 39 40
+# Vous pouvez subdiviser les éléments d'une liste comme n'importe quel vecteur
+list1$price[4]
+
+# Les listes ne sont pas les structures de données les plus efficaces
+# à utiliser avec R ;
+# À moins d'avoir une très bonne raison, vous devriez utiliser data.frames
+# Les listes sont souvent retournées par des fonctions qui effectuent
+# des régressions linéaires.
+
+##########################################
+# La famille de fonction apply()
+##########################################
+
+# Vous vous rappelez mat ?
+mat
+# =>
+# [,1] [,2]
+# [1,] 1 4
+# [2,] 2 5
+# [3,] 3 6
+# Utilisez apply(X, MARGIN, FUN) pour appliquer la fonction FUN à la matrice X
+# sur les lignes (MAR = 1) ou les colonnes (MAR = 2)
+# R exécute FUN à chaque lignes (ou colonnes) de X, beaucoup plus rapidement
+# que le ferait une boucle for ou while
+apply(mat, MAR = 2, jiggle)
+# =>
+# [,1] [,2]
+# [1,] 3 15
+# [2,] 7 19
+# [3,] 11 23
+# D'autres fonctions : ?lapply, ?sapply
+
+# Ne soyez pas trop intimidé ; tout le monde reconnaît que c'est un peu déroutant
+
+# Le paquet plyr vise à remplacer (et améliorer !) la famille *apply().
+install.packages("plyr")
+require(plyr)
+?plyr
+
+
+
+############################
+# Charger des données
+############################
+
+# "pets.csv" est un fichier sur internet
+# (mais il pourrait être tout aussi facilement sur votre ordinateur)
+pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
+pets
+head(pets, 2) # first two rows
+tail(pets, 1) # last row
+
+# Pour sauvegarder une data frame ou une matrice en fichier .csv
+write.csv(pets, "pets2.csv") # to make a new .csv file
+# définir le répertoire de travail avec setwd(), le récupérer avec getwd()
+
+# Essayez ?read.csv et ?write.csv pour plus d'informations
+
+
+
+################
+# Les tracés
+################
+
+# LES FONCTIONS DE TRACÉ PRÉCONSTRUITES
+# Les diagrammes de dispersion !
+plot(list1$time, list1$price, main = "fake data")
+# Les régressions !
+linearModel <- lm(price ~ time, data = list1)
+linearModel # sort le résultat de la régression
+# Tracer une ligne de regression sur une tracé existant
+abline(linearModel, col = "red")
+# Obtenir une variété de diagnostiques sympas
+plot(linearModel)
+# Les histogrammes !
+hist(rpois(n = 10000, lambda = 5), col = "thistle")
+# Les diagrammes en bâtons !
+barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
+
+# GGPLOT2
+# Mais ceux-ci ne sont même pas les plus jolis tracés de R
+# Essayez le paquet ggplot2 pour d'avantages de graphiques
+install.packages("ggplot2")
+require(ggplot2)
+?ggplot2
+pp <- ggplot(students, aes(x=house))
+pp + geom_histogram()
+ll <- as.data.table(list1)
+pp <- ggplot(ll, aes(x=time,price))
+pp + geom_point()
+# ggplot2 a une documentation excellente
+#(disponible sur http://docs.ggplot2.org/current/)
+
+
+
+```
+
+## Comment obtenir R ?
+
+* Obtiens R et R GUI depuis [http://www.r-project.org/](http://www.r-project.org/)
+* [RStudio](http://www.rstudio.com/ide/) est un autre GUI
diff --git a/fr-fr/typescript-fr.html.markdown b/fr-fr/typescript-fr.html.markdown
new file mode 100644
index 00000000..b8807104
--- /dev/null
+++ b/fr-fr/typescript-fr.html.markdown
@@ -0,0 +1,174 @@
+---
+language: TypeScript
+contributors:
+ - ["Philippe Vlérick", "https://github.com/pvlerick"]
+translators:
+ - ["Alois de Gouvello", "https://github.com/aloisdg"]
+filename: learntypescript-fr.ts
+lang: fr-fr
+---
+
+TypeScript est un langage visant à faciliter le développement d'applications larges et scalables, écrites en JavaScript.
+TypeScript ajoute des concepts classiques comme les classes, les modules, les interfaces, les génériques et le typage statique (optionnel) à JavaScript.
+C'est une surcouche de JavaScript : tout le code JavaScript est valide en TypeScript ce qui permet de l'ajouter de façon transparente à n'importe quel projet. Le code TypeScript est transcompilé en JavaScript par le compilateur.
+
+Cet article se concentrera seulement sur la syntaxe supplémentaire de TypeScript, plutôt que celle de [JavaScript] (../javascript/).
+
+Pour tester le compilateur de TypeScript, rendez-vous au [Playground] (http://www.typescriptlang.org/Playground) où vous pourrez coder, profiter d'une autocomplétion et accéder directement au rendu JavaScript.
+
+```js
+// Il y a 3 types basiques en TypeScript
+var isDone: boolean = false;
+var lines: number = 42;
+var name: string = "Anders";
+
+// Si nous ne pouvons pas déterminer le type, on utilise `Any`
+var notSure: any = 4;
+notSure = "maybe a string instead";
+notSure = false; // ok, définitivement un booléen
+
+// Pour les collections, il y a les tableaux typés et les tableaux génériques
+var list: number[] = [1, 2, 3]; // Un tableaux typé
+var list: Array<number> = [1, 2, 3]; // un tableau générique
+
+// Pour les énumeration
+enum Color { Red, Green, Blue };
+var c: Color = Color.Green;
+
+// Enfin, `void` est utilisé dans le cas spécifique
+// d'une fonction ne retournant rien
+function bigHorribleAlert(): void {
+ alert("Je suis une petite boîte ennuyeuse !");
+}
+
+// Les fonctions sont des entités de première classe. Le langage supporte
+// les expressions lambda et utilise l'inférence de type
+
+// Les fonctions ci-dessous sont équivalentes, une signature identique
+// sera inférée par le compilateur, et le même JavaScript sera généré
+var f1 = function(i: number): number { return i * i; }
+// Retourne un type inféré
+var f2 = function(i: number) { return i * i; }
+var f3 = (i: number): number => { return i * i; }
+// Retourne un type inféré
+var f4 = (i: number) => { return i * i; }
+// Retourne un type inféré, ici le mot clé `return` n'est pas nécessaire
+var f5 = (i: number) => i * i;
+
+// Les interfaces sont structurées, tout les objets qui ont ces propriétés
+// sont compatible avec l'interface
+interface Person {
+ name: string;
+ // Les propriétés optionnelles sont identifiées avec un "?"
+ age?: number;
+ // Et bien sûr, les fonctions
+ move(): void;
+}
+
+// Un objet implémentant l'interface "Person" peut être traité comme
+// une Person car il a les propriétés "name" et "move"
+var p: Person = { name: "Bobby", move: () => {} };
+// Des objets implémentants la propriété optionnelle :
+// valide car "age" est un nombre
+var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
+// invalide car "age" n'est pas un nombre
+var invalidPerson: Person = { name: "Bobby", age: true };
+
+// Les interfaces peuvent aussi décrire un type de fonction
+interface SearchFunc {
+ (source: string, subString: string): boolean;
+}
+
+// Seul les types des paramètres sont importants. Les noms ne le sont pas.
+var mySearch: SearchFunc;
+mySearch = function(src: string, sub: string) {
+ return src.search(sub) != -1;
+}
+
+// Les membres des classes sont publiques par défaut.
+class Point {
+ // Propriétés
+ x: number;
+
+ // Constructeur - Les mots clés "public" et "private" dans ce contexte
+ // génèrent le code de la propriété et son initialisation dans le
+ // constructeur. Ici, "y" sera défini de la même façon que "x",
+ // mais avec moins de code. Les valeurs par défaut sont supportées.
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // Fonctions
+ dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
+
+ // Membres statiques
+ static origin = new Point(0, 0);
+}
+
+var p1 = new Point(10 ,20);
+var p2 = new Point(25); // y sera 0
+
+// Héritage
+class Point3D extends Point {
+ constructor(x: number, y: number, public z: number = 0) {
+ // Un appel explicite au constructeur de la super classe
+ // est obligatoire.
+ super(x, y);
+ }
+
+ // Redéfinition
+ dist() {
+ var d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
+}
+
+// Modules, "." peut être utilisé comme un séparateur de sous modules.
+module Geometry {
+ export class Square {
+ constructor(public sideLength: number = 0) {
+ }
+ area() {
+ return Math.pow(this.sideLength, 2);
+ }
+ }
+}
+
+var s1 = new Geometry.Square(5);
+
+// Alias local pour référencer un module
+import G = Geometry;
+
+var s2 = new G.Square(10);
+
+// Génériques
+// Classes
+class Tuple<T1, T2> {
+ constructor(public item1: T1, public item2: T2) {
+ }
+}
+
+// Interfaces
+interface Pair<T> {
+ item1: T;
+ item2: T;
+}
+
+// Et fonctions
+var pairToTuple = function<T>(p: Pair<T>) {
+ return new Tuple(p.item1, p.item2);
+};
+
+var tuple = pairToTuple({ item1:"hello", item2:"world"});
+
+// Inclure des références à un fichier :
+/// <reference path="jquery.d.ts" />
+
+```
+
+## Lectures complémentaires
+ * [Site officiel de TypeScript] (http://www.typescriptlang.org/)
+ * [Spécification du langage TypeScript (pdf)] (http://go.microsoft.com/fwlink/?LinkId=267238)
+ * [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
+ * [Code source sur GitHub] (https://github.com/Microsoft/TypeScript)
+ * [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)
diff --git a/git.html.markdown b/git.html.markdown
index af65afb0..4bbc58e7 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -79,6 +79,11 @@ this pointer will automatically update and point to the latest commit.
HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD.
head is a pointer that points to any commit. A repository can have any number of heads.
+###Stages of Git
+* Modified - Changes have been made to a file but file has not been committed to Git Database yet
+* Staged - Marks a modified file to go into your next commit snapshot
+* Committed - Files have been committed to the Git Database
+
### Conceptual Resources
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
@@ -131,6 +136,10 @@ $ git help -a
$ git help add
$ git help commit
$ git help init
+# or git <command_here> --help
+$ git add --help
+$ git commit --help
+$ git init --help
```
### status
@@ -149,8 +158,8 @@ $ git help status
### add
-To add files to the current working tree/directory/repo. If you do not `git add` new files to the
-working tree/directory, they will not be included in commits!
+To add files to the staging area/index. If you do not `git add` new files to the
+staging area/index, they will not be included in commits!
```bash
# add a file in your current working directory
@@ -163,6 +172,8 @@ $ git add /path/to/file/HelloWorld.c
$ git add ./*.java
```
+This only adds a file to the staging area/index, it doesn't commit it to the working directory/repo.
+
### branch
Manage your branches. You can view, edit, create, delete branches using this command.
@@ -462,3 +473,5 @@ $ git rm /pather/to/the/file/HelloWorld.c
* [GitGuys](http://www.gitguys.com/)
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
+
+* [Pro Git](http://www.git-scm.com/book/en/v2)
diff --git a/go.html.markdown b/go.html.markdown
index 17f10bd9..34b855e3 100644
--- a/go.html.markdown
+++ b/go.html.markdown
@@ -64,7 +64,11 @@ func beyondHello() {
learnTypes() // < y minutes, learn more!
}
-// Functions can have parameters and (multiple!) return values.
+/* <- multiline comment
+Functions can have parameters and (multiple!) return values.
+Here `x`, `y` are the arguments and `sum`, `prod` is the signature (what's returned).
+Note that `x` and `sum` receive the type `int`.
+*/
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Return two values.
}
@@ -83,7 +87,7 @@ can include line breaks.` // Same string type.
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 syntax with initializers.
var u uint = 7 // Unsigned, but implementation dependent size as with int.
var pi float32 = 22. / 7
@@ -177,8 +181,14 @@ func learnFlowControl() {
case 1:
case 42:
// Cases don't "fall through".
+ /*
+ There is a `fallthrough` keyword however, see:
+ https://github.com/golang/go/wiki/Switch#fall-through
+ */
case 43:
// Unreached.
+ default:
+ // Default case is optional.
}
// Like if, for doesn't use parens either.
// Variables declared in for and if are local to their scope.
diff --git a/groovy.html.markdown b/groovy.html.markdown
index 8fb1b346..519f36ce 100644
--- a/groovy.html.markdown
+++ b/groovy.html.markdown
@@ -6,7 +6,7 @@ contributors:
filename: learngroovy.groovy
---
-Groovy - A dynamic language for the Java platform [Read more here.](http://groovy.codehaus.org)
+Groovy - A dynamic language for the Java platform [Read more here.](http://www.groovy-lang.org/)
```groovy
@@ -231,7 +231,7 @@ for ( e in map ) {
Operators
Operator Overloading for a list of the common operators that Groovy supports:
- http://groovy.codehaus.org/Operator+Overloading
+ http://www.groovy-lang.org/operators.html#Operator-Overloading
Helpful groovy operators
*/
@@ -249,7 +249,7 @@ def username = user?.username
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
+ More info at: http://www.groovy-lang.org/closures.html
*/
//Example:
def clos = { println "Hello World!" }
@@ -405,11 +405,11 @@ assert sum(2,5) == 7
## Further resources
-[Groovy documentation](http://groovy.codehaus.org/Documentation)
+[Groovy documentation](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/)
-Join a [Groovy user group](http://groovy.codehaus.org/User+Groups)
+Join a [Groovy user group](http://www.groovy-lang.org/usergroups.html)
## Books
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 2f807c5f..369b1b20 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -202,19 +202,21 @@ foo = (*5) . (+10)
foo 5 -- 75
-- fixing precedence
--- Haskell has another function called `$`. This changes the precedence
--- so that everything to the left of it gets computed first and then applied
--- to everything on the right. You can use `$` (often in combination with `.`)
--- to get rid of a lot of parentheses:
+-- Haskell has another operator called `$`. This operator applies a function
+-- to a given parameter. In contrast to standard function application, which
+-- has highest possible priority of 10 and is left-associative, the `$` operator
+-- has priority of 0 and is right-associative. Such a low priority means that
+-- the expression on its right is applied as the parameter to the function on its left.
-- before
-(even (fib 7)) -- true
-
--- after
-even . fib $ 7 -- true
+even (fib 7) -- false
-- equivalently
-even $ fib 7 -- true
+even $ fib 7 -- false
+
+-- composing functions
+even . fib $ 7 -- false
+
----------------------------------------------------
-- 5. Type signatures
@@ -281,7 +283,7 @@ foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
-- This is now the same as
-(2 * 3 + (2 * 2 + (2 * 1 + 4)))
+(2 * 1 + (2 * 2 + (2 * 3 + 4)))
----------------------------------------------------
-- 7. Data Types
diff --git a/haxe.html.markdown b/haxe.html.markdown
index c807d2d7..ee214540 100644
--- a/haxe.html.markdown
+++ b/haxe.html.markdown
@@ -323,7 +323,7 @@ class LearnHaxe3{
var l = 0;
do{
trace("do statement always runs at least once");
- } while (i > 0);
+ } while (l > 0);
// for loop
/*
@@ -340,7 +340,7 @@ class LearnHaxe3{
// (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(val + " is the value for val (an index for n)");
}
@@ -375,7 +375,7 @@ class LearnHaxe3{
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
- // case _ : "some unknown treat"; // same as default
+ // case _ : favorite_thing = "some unknown treat"; // same as default
}
// The "_" case above is a "wildcard" value
// that will match anything.
@@ -397,7 +397,7 @@ class LearnHaxe3{
// if statements
var k = if (true) 10 else 20;
- trace("K equals ", k); // outputs 10
+ trace("k equals ", k); // outputs 10
var other_favorite_thing = switch(my_dog_name) {
case "fido" : "teddy";
@@ -495,8 +495,10 @@ class LearnHaxe3{
// foo_instance.public_read = 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
+ // calls the toString method:
+ trace(foo_instance + " is the value for foo_instance");
+ // same thing:
+ trace(foo_instance.toString() + " is the value for foo_instance.toString()");
/*
@@ -524,8 +526,8 @@ class LearnHaxe3{
*/
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 public_read (default, null): Int; // enable only public read
+ public var public_write (null, default): Int; // or only public write
public var property (get, set): Int; // use this style to enable getters/setters
// private variables are not available outside the class.
@@ -534,9 +536,10 @@ class FooClass extends BarClass implements BarInterface{
// a public constructor
public function new(arg:Int){
- super(); // call the constructor of the parent object, since we extended BarClass
+ // call the constructor of the parent object, since we extended BarClass:
+ super();
- this.public_any= 0;
+ this.public_any = 0;
this._private = arg;
}
diff --git a/it-it/bash-it.html.markdown b/it-it/bash-it.html.markdown
new file mode 100644
index 00000000..f892845f
--- /dev/null
+++ b/it-it/bash-it.html.markdown
@@ -0,0 +1,275 @@
+---
+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"]
+ - ["akirahirose", "https://twitter.com/akirahirose"]
+ - ["Anton Strömkvist", "http://lutic.org/"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gregrory Kielian", "https://github.com/gskielian"]
+filename: LearnBash.sh
+translators:
+ - ["Robert Margelli", "http://github.com/sinkswim/"]
+lang: it-it
+---
+
+Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X.
+Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell.
+
+[Per saperne di piu'.](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# La prima riga dello script è lo shebang il quale dice al sistema come eseguire
+# lo script: http://it.wikipedia.org/wiki/Shabang
+# Come avrai già immaginato, i commenti iniziano con #. Lo shebang stesso è un commento.
+
+# Semplice esempio ciao mondo:
+echo Ciao mondo!
+
+# Ogni comando inizia su una nuova riga, o dopo un punto e virgola:
+echo 'Questa è la prima riga'; echo 'Questa è la seconda riga'
+
+# Per dichiarare una variabile:
+VARIABILE="Una stringa"
+
+# Ma non così:
+VARIABILE = "Una stringa"
+# Bash stabilirà che VARIABILE è un comando da eseguire e darà un errore
+# perchè non esiste.
+
+# Usare la variabile:
+echo $VARIABILE
+echo "$VARIABILE"
+echo '$VARIABILE'
+# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi
+# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $.
+# Nota che ' (singolo apice) non espande le variabili!
+
+# Sostituzione di stringhe nelle variabili
+echo ${VARIABILE/Una/A}
+# Questo sostituirà la prima occorrenza di "Una" con "La"
+
+# Sottostringa di una variabile
+echo ${VARIABILE:0:7}
+# Questo ritornerà solamente i primi 7 caratteri
+
+# Valore di default per la variabile
+echo ${FOO:-"ValoreDiDefaultSeFOOMancaOÈ Vuoto"}
+# Questo funziona per null (FOO=), stringa vuota (FOO=""), zero (FOO=0) ritorna 0
+
+# Variabili builtin:
+# Ci sono delle variabili builtin molto utili, come
+echo "Valore di ritorno dell'ultimo programma eseguito: $?"
+echo "PID dello script: $$"
+echo "Numero di argomenti: $#"
+echo "Argomenti dello script: $@"
+echo "Argomenti dello script separati in variabili distinte: $1 $2..."
+
+# Leggere un valore di input:
+echo "Come ti chiami?"
+read NOME # Nota che non abbiamo dovuto dichiarare una nuova variabile
+echo Ciao, $NOME!
+
+# Classica struttura if:
+# usa 'man test' per maggiori informazioni sulle condizionali
+if [ $NOME -ne $USER ]
+then
+ echo "Il tuo nome non è lo username"
+else
+ echo "Il tuo nome è lo username"
+fi
+
+# C'è anche l'esecuzione condizionale
+echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce"
+echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce"
+
+# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre:
+if [ $NOME == "Steve" ] && [ $ETA -eq 15 ]
+then
+ echo "Questo verrà eseguito se $NOME è Steve E $ETA è 15."
+fi
+
+if [ $NOME == "Daniya" ] || [ $NOME == "Zach" ]
+then
+ echo "Questo verrà eseguito se $NAME è Daniya O Zach."
+fi
+
+# Le espressioni sono nel seguente formato:
+echo $(( 10 + 5 ))
+
+# A differenza di altri linguaggi di programmazione, bash è una shell - quindi lavora nel contesto
+# della cartella corrente. Puoi elencare i file e le cartelle nella cartella
+# corrente con il comando ls:
+ls
+
+# Questi comandi hanno opzioni che controllano la loro esecuzione:
+ls -l # Elenca tutti i file e le cartelle su una riga separata
+
+# I risultati del comando precedente possono essere passati al comando successivo come input.
+# Il comando grep filtra l'input con il pattern passato. Ecco come possiamo elencare i
+# file .txt nella cartella corrente:
+ls -l | grep "\.txt"
+
+# Puoi redirezionare l'input e l'output del comando (stdin, stdout, e stderr).
+# Leggi da stdin finchè ^EOF$ e sovrascrivi hello.py con le righe
+# comprese tra "EOF":
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Esegui hello.py con diverse redirezioni stdin, stdout, e stderr:
+python hello.py < "input.in"
+python hello.py > "output.out"
+python hello.py 2> "error.err"
+python hello.py > "output-and-error.log" 2>&1
+python hello.py > /dev/null 2>&1
+# Lo output error sovrascriverà il file se esiste,
+# se invece vuoi appendere usa ">>":
+python hello.py >> "output.out" 2>> "error.err"
+
+# Sovrascrivi output.txt, appendi a error.err, e conta le righe:
+info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
+wc -l output.out error.err
+
+# Esegui un comando e stampa il suo file descriptor (esempio: /dev/fd/123)
+# vedi: man fd
+echo <(echo "#ciaomondo")
+
+# Sovrascrivi output.txt con "#helloworld":
+cat > output.out <(echo "#helloworld")
+echo "#helloworld" > output.out
+echo "#helloworld" | cat > output.out
+echo "#helloworld" | tee output.out >/dev/null
+
+# Pulisci i file temporanei verbosamente (aggiungi '-i' per la modalità interattiva)
+rm -v output.out error.err output-and-error.log
+
+# I comandi possono essere sostituiti con altri comandi usando $( ):
+# Il comando seguente mostra il numero di file e cartelle nella
+# cartella corrente.
+echo "Ci sono $(ls | wc -l) oggetti qui."
+
+# Lo stesso puo' essere usato usando backticks `` ma non possono essere innestati - il modo migliore
+# è usando $( ).
+echo "Ci sono `ls | wc -l` oggetti qui."
+
+# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++:
+case "$VARIABILE" in
+ #Lista di pattern per le condizioni che vuoi soddisfare
+ 0) echo "C'è uno zero.";;
+ 1) echo "C'è un uno.";;
+ *) echo "Non è null.";;
+esac
+
+# I cicli for iterano per ogni argomento fornito:
+# I contenuti di $VARIABILE sono stampati tre volte.
+for VARIABILE in {1..3}
+do
+ echo "$VARIABILE"
+done
+
+# O scrivilo con il "ciclo for tradizionale":
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+done
+
+# Possono essere usati anche per agire su file..
+# Questo eseguirà il comando 'cat' su file1 e file2
+for VARIABILE in file1 file2
+do
+ cat "$VARIABILE"
+done
+
+# ..o dall'output di un comando
+# Questo eseguirà cat sull'output di ls.
+for OUTPUT in $(ls)
+do
+ cat "$OUTPUT"
+done
+
+# while loop:
+while [ true ]
+do
+ echo "corpo del loop..."
+ break
+done
+
+# Puoi anche definire funzioni
+# Definizione:
+function foo ()
+{
+ echo "Gli argomenti funzionano come gli argomenti dello script: $@"
+ echo "E: $1 $2..."
+ echo "Questa è una funzione"
+ return 0
+}
+
+# o semplicemente
+bar ()
+{
+ echo "Un altro modo per dichiarare funzioni!"
+ return 0
+}
+
+# Per chiamare la funzione
+foo "Il mio nome è" $NOME
+
+# Ci sono un sacco di comandi utili che dovresti imparare:
+# stampa le ultime 10 righe di file.txt
+tail -n 10 file.txt
+# stampa le prime 10 righe di file.txt
+head -n 10 file.txt
+# ordina le righe di file.txt
+sort file.txt
+# riporta o ometti le righe ripetute, con -d le riporta
+uniq -d file.txt
+# stampa solamente la prima colonna prima del carattere ','
+cut -d ',' -f 1 file.txt
+# sostituisce ogni occorrenza di 'okay' con 'great' in file.txt (compatible con le regex)
+sed -i 's/okay/great/g' file.txt
+# stampa su stdout tutte le righe di file.txt che soddisfano una certa regex
+# L'esempio stampa le righe che iniziano con "foo" e che finiscono con "bar"
+grep "^foo.*bar$" file.txt
+# passa l'opzione "-c" per stampare invece il numero delle righe che soddisfano la regex
+grep -c "^foo.*bar$" file.txt
+# se vuoi letteralmente cercare la stringa,
+# e non la regex, usa fgrep (o grep -F)
+fgrep "^foo.*bar$" file.txt
+
+
+# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash:
+help
+help help
+help for
+help return
+help source
+help .
+
+# Leggi la manpage di bash con man
+apropos bash
+man 1 bash
+man bash
+
+# Leggi la documentazione con info (? per help)
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+
+# Leggi la documentazione di bash:
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
+```
diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown
new file mode 100644
index 00000000..e7e1d89e
--- /dev/null
+++ b/it-it/c++-it.html.markdown
@@ -0,0 +1,720 @@
+---
+language: c++
+filename: learncpp-it.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+translators:
+ - ["Robert Margelli", "http://github.com/sinkswim/"]
+lang: it-it
+---
+
+Il C++ è un linguaggio di programmazione il quale,
+[secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+è stato progettato per
+
+- essere un "miglior C"
+- supportare l'astrazione dei dati
+- supportare la programmazione orientata agli oggetti
+- supportare la programmazione generica
+
+Nonostante la sintassi possa risultare più difficile o complessa di linguaggi più recenti,
+è usato in maniera vasta poichè viene compilato in istruzioni macchina che possono
+essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C)
+ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi.
+Questa combinazione di velocità e funzionalità rende il C++
+uno dei più utilizzati linguaggi di programmazione.
+
+```c++
+//////////////////
+// Confronto con il C
+//////////////////
+
+// Il C++ è _quasi_ un superset del C e con esso condivide la sintassi di base per
+// la dichiarazione di variabili, tipi primitivi, e funzioni.
+
+// Proprio come nel C, l'inizio del programma è una funzione chiamata
+// main con un intero come tipo di ritorno,
+// Questo valore serve come stato d'uscita del programma.
+// Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni.
+int main(int argc, char** argv)
+{
+ // Gli argomenti a linea di comando sono passati tramite argc e argv così come
+ // avviene in C.
+ // argc indica il numero di argomenti,
+ // e argv è un array di stringhe in stile-C (char*)
+ // che rappresenta gli argomenti.
+ // Il primo argomento è il nome che è stato assegnato al programma.
+ // argc e argv possono essere omessi se non hai bisogno di argomenti,
+ // in questa maniera la funzione avrà int main() come firma.
+
+ // Lo stato di uscita 0 indica successo.
+ return 0;
+}
+
+// Tuttavia, il C++ varia nei seguenti modi:
+
+// In C++, i caratteri come letterali sono da un byte.
+sizeof('c') == 1
+
+// In C, i caratteri come letterali sono della stessa dimensione degli interi.
+sizeof('c') == sizeof(10)
+
+
+// C++ ha prototipizzazione rigida
+void func(); // funziona che non accetta argomenti
+
+// In C
+void func(); // funzione che può accettare un qualsiasi numero di argomenti
+
+// Usa nullptr invece di NULL in C++
+int* ip = nullptr;
+
+// Gli header C standard sono disponibili in C++,
+// ma sono prefissati con "c" e non hanno il suffisso ".h".
+#include <cstdio>
+
+int main()
+{
+ printf("Ciao, mondo!\n");
+ return 0;
+}
+
+///////////////////////////////
+// Overloading per le funzioni
+//////////////////////////////
+
+// Il C++ supporta l'overloading per le funzioni
+// sia dato che ogni funzione accetta parametri diversi.
+
+void print(char const* myString)
+{
+ printf("Stringa %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("Il mio int è %d", myInt);
+}
+
+int main()
+{
+ print("Ciao"); // Viene chiamata void print(const char*)
+ print(15); // Viene chiamata void print(int)
+}
+
+////////////////////////
+// Argomenti di default
+///////////////////////
+
+// Puoi fornire argomenti di default per una funzione
+// se non sono forniti dal chiamante.
+
+void faiQualcosaConInteri(int a = 1, int b = 4)
+{
+ // fai qualcosa con gli interi qui
+}
+
+int main()
+{
+ faiQualcosaConInteri(); // a = 1, b = 4
+ faiQualcosaConInteri(20); // a = 20, b = 4
+ faiQualcosaConInteri(20, 5); // a = 20, b = 5
+}
+
+// Gli argomenti di default devono essere alla fine della lista degli argomenti.
+
+void dichiarazioneInvalida(int a = 1, int b) // Errore!
+{
+}
+
+
+/////////////
+// Namespaces
+/////////////
+
+// I namespaces forniscono visibilità separata per dichiarazioni di variabili, funzioni,
+// ed altro.
+// I namespaces possono essere annidati.
+
+namespace Primo {
+ namespace Annidato {
+ void foo()
+ {
+ printf("Questa è Primo::Annidato::foo\n");
+ }
+ } // fine di namespace Annidato
+} // fine di namespace Primo
+
+namespace Secondo {
+ void foo()
+ {
+ printf("Questa è Secondo::foo\n")
+ }
+}
+
+void foo()
+{
+ printf("Questa è foo globale\n");
+}
+
+int main()
+{
+ // Assume che tutto venga dal namespace "Secondo"
+ // a meno che non venga dichiarato altrimenti.
+ using namespace Secondo;
+
+ foo(); // stampa "Questa è Secondo::foo"
+ Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo"
+ ::foo(); // stampa "Questa è foo globale"
+}
+
+///////////////
+// Input/Output
+///////////////
+
+// L'input e l'output in C++ utilizza gli streams
+// cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr.
+// << è l'operatore di inserzione >> è l'operatore di estrazione.
+
+#include <iostream> // Include gli streams di I/O
+
+using namespace std; // Gli streams sono nel namespace std (libreria standard)
+
+int main()
+{
+ int myInt;
+
+ // Stampa su stdout (o terminalee/schermo)
+ cout << "Inserisci il tuo numero preferito:\n";
+ // Prende l'input
+ cin >> myInt;
+
+ // cout può anche essere formattato
+ cout << "Il tuo numero preferito è " << myInt << "\n";
+ // stampa "Il tuo numero preferito è <myInt>"
+
+ cerr << "Usato per messaggi di errore";
+}
+
+////////////
+// Stringhe
+///////////
+
+// Le stringhe in C++ sono oggetti ed hanno molte funzioni membro
+#include <string>
+
+using namespace std; // Anche le stringhe sono contenute nel namespace std (libreria standard)
+
+string myString = "Ciao";
+string myOtherString = " Mondo";
+
+// + è usato per la concatenazione.
+cout << myString + myOtherString; // "Ciao Mondo"
+
+cout << myString + " Bella"; // "Ciao Bella"
+
+// le stringhe in C++ possono essere modificate.
+myString.append(" Mario");
+cout << myString; // "Ciao Mario"
+
+
+///////////////
+// Riferimenti
+//////////////
+
+// Oltre ai puntatori come quelli in C,
+// il C++ ha i _riferimenti_.
+// Questi non sono tipi puntatori che non possono essere riassegnati una volta settati
+// e non possono essere null.
+// Inoltre, essi hanno la stessa sintassi della variabile stessa:
+// * non è necessario per la dereferenziazione e
+// & ("indirizzo di") non è usato per l'assegnamento.
+
+using namespace std;
+
+string foo = "Io sono foo";
+string bar = "Io sono bar";
+
+
+string& fooRef = foo; // Questo crea un riferimento a foo.
+fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento
+cout << fooRef; // Stampa "Io sono foo. Ciao!"
+
+// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e
+// foo == "Io sono bar"
+// dopo questa riga.
+fooRef = bar;
+
+const string& barRef = bar; // Crea un riferimento const a bar.
+// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati.
+barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati.
+
+//////////////////////////////////////////////////
+// Classi e programmazione orientata agli oggetti
+/////////////////////////////////////////////////
+
+// Primo esempio delle classi
+#include <iostream>
+
+// Dichiara una classe.
+// Le classi sono in genere dichiara in un header file (.h o .hpp).
+class Cane {
+ // Variabili e funzioni membro sono private di default.
+ std::string nome;
+ int peso;
+
+// Tutti i membri dopo questo sono pubblici (public)
+// finchè "private:" o "protected:" non compaiono.
+public:
+
+ // Costruttore di default
+ Cane();
+
+ // Dichiarazioni di funzioni membro (le implentazioni sono a seguito)
+ // Nota che stiamo usando std::string invece di porre
+ // using namespace std;
+ // sopra.
+ // Mai usare uno statement "using namespace" in uno header.
+ void impostaNome(const std::string& nomeCane);
+
+ void impostaPeso(int pesoCane);
+
+ // Le funzioni che non modificano lo stato dell'oggetto
+ // dovrebbero essere marcate come const.
+ // Questo permette di chiamarle con un riferimento const all'oggetto.
+ // Inoltre, nota che le funzioni devono essere dichiarate espliciamente come _virtual_
+ // per essere sovrascritte in classi derivate.
+ // Le funzioni non sono virtual di default per motivi di performance.
+ virtual void print() const;
+
+ // Le funzioni possono essere definite anche all'interno del corpo della classe.
+ // Le funzioni definite in questo modo sono automaticamente inline.
+ void abbaia() const { std::cout << nome << " abbaia!\n"; }
+
+ // Assieme con i costruttori, il C++ fornisce i distruttori.
+ // Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità.
+ // Questo permette paradigmi potenti come il RAII
+ // (vedi sotto)
+ // I distruttori devono essere virtual per permettere a classi di essere derivate da questa.
+ virtual ~Dog();
+
+}; // Un punto e virgola deve seguire la definizione della funzione
+
+// Le funzioni membro di una classe sono generalmente implementate in files .cpp .
+void Cane::Cane()
+{
+ std::cout << "Un cane è stato costruito\n";
+}
+
+// Gli oggetti (ad esempio le stringhe) devono essere passati per riferimento
+// se li stai modificando o come riferimento const altrimenti.
+void Cane::impostaNome(const std::string& nomeCane)
+{
+ nome = nomeCane;
+}
+
+void Cane::impostaPeso(int pesoCane)
+{
+ peso = pesoCane;
+}
+
+// Notare che "virtual" è solamente necessario nelle dichiarazioni, non nelle definizioni.
+void Cane::print() const
+{
+ std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n";
+}
+
+void Cane::~Cane()
+{
+ cout << "Ciao ciao " << nome << "\n";
+}
+
+int main() {
+ Cane myDog; // stampa "Un cane è stato costruito"
+ myDog.impostaNome("Barkley");
+ myDog.impostaPeso(10);
+ myDog.print(); // stampa "Il cane è Barkley e pesa 10 kg"
+ return 0;
+} // stampa "Ciao ciao Barkley"
+
+// Ereditarietà:
+
+// Questa classe eredita tutto ciò che è public e protected dalla classe Cane
+class MioCane : public Cane {
+
+ void impostaProprietario(const std::string& proprietarioCane)
+
+ // Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi
+ // http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29
+ // per una introduzione più generale se non sei familiare con
+ // il polimorfismo.
+ // La parola chiave override è opzionale ma fa sì che tu stia effettivamente
+ // sovrascrivendo il metodo nella classe base.
+ void print() const override;
+
+private:
+ std::string proprietario;
+};
+
+// Nel frattempo, nel file .cpp corrispondente:
+
+void MioCane::impostaProprietario(const std::string& proprietarioCane)
+{
+ proprietario = proprietarioCane;
+}
+
+void MioCane::print() const
+{
+ Cane::print(); // Chiama la funzione print nella classe base Cane
+ std::cout << "Il cane è di " << proprietario << "\n";
+ // stampa "Il cane è <nome> e pesa <peso>"
+ // "Il cane è di <proprietario>"
+}
+
+///////////////////////////////////////////////////
+// Inizializzazione ed Overloading degli Operatori
+//////////////////////////////////////////////////
+
+// In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc...
+// Questo è possibile definendo una funzione che viene chiamata
+// ogniqualvolta l'operatore è usato.
+
+#include <iostream>
+using namespace std;
+
+class Punto {
+public:
+ // Così si assegna alle variabili membro un valore di default.
+ double x = 0;
+ double y = 0;
+
+ // Definisce un costruttore di default che non fa nulla
+ // ma inizializza il Punto ai valori di default (0, 0)
+ Punto() { };
+
+ // La sintassi seguente è nota come lista di inizializzazione
+ // ed è il modo appropriato di inizializzare i valori membro della classe
+ Punto (double a, double b) :
+ x(a),
+ y(b)
+ { /* Non fa nulla eccetto inizializzare i valori */ }
+
+ // Sovrascrivi l'operatore +.
+ Punto operator+(const Punto& rhs) const;
+
+ // Sovrascrivi l'operatore +=
+ Punto& operator+=(const Punto& rhs);
+
+ // Avrebbe senso aggiungere gli operatori - e -=,
+ // ma li saltiamo per rendere la guida più breve.
+};
+
+Punto Punto::operator+(const Punto& rhs) const
+{
+ // Crea un nuovo punto come somma di questo e di rhs.
+ return Punto(x + rhs.x, y + rhs.y);
+}
+
+Punto& Punto::operator+=(const Punto& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Punto su (0,1);
+ Punto destro (1,0);
+ // Questo chiama l'operatore + di Punto
+ // Il Punto su chiama la funzione + con destro come argomento
+ Punto risultato = su + destro;
+ // Stampa "Risultato è spostato in (1,1)"
+ cout << "Risultato è spostato (" << risultato.x << ',' << risultato.y << ")\n";
+ return 0;
+}
+
+/////////////////
+// Templates
+////////////////
+
+// Generalmente i templates in C++ sono utilizzati per programmazione generica, anche se
+// sono molto più potenti dei costrutti generici in altri linguaggi. Inoltre,
+// supportano specializzazione esplicita e parziale, classi in stile funzionale,
+// e sono anche complete per Turing.
+
+// Iniziamo con il tipo di programmazione generica con cui forse sei familiare. Per
+// definire una classe o una funzione che prende un parametro di un dato tipo:
+template<class T>
+class Box {
+ // In questa classe, T può essere usato come qualsiasi tipo.
+ void inserisci(const T&) { ... }
+};
+
+// Durante la compilazione, il compilatore in effetti genera copie di ogni template
+// con i parametri sostituiti, e così la definizione completa della classe deve essere
+// presente ad ogni invocazione. Questo è il motivo per cui vedrai le classi template definite
+// interamente in header files.
+
+// Per instanziare una classe template sullo stack:
+Box<int> intBox;
+
+// e puoi usarla come aspettato:
+intBox.inserisci(123);
+
+//Puoi, ovviamente, innestare i templates:
+Box<Box<int> > boxOfBox;
+boxOfBox.inserisci(intBox);
+
+// Fino al C++11, devi porre uno spazio tra le due '>', altrimenti '>>'
+// viene visto come l'operatore di shift destro.
+
+// Qualche volta vedrai
+// template<typename T>
+// invece. La parole chiavi 'class' e 'typename' sono _generalmente_
+// intercambiabili in questo caso. Per una spiegazione completa, vedi
+// http://en.wikipedia.org/wiki/Typename
+// (si, quella parola chiave ha una sua pagina di Wikipedia propria).
+
+// Similmente, una funzione template:
+template<class T>
+void abbaiaTreVolte(const T& input)
+{
+ input.abbaia();
+ input.abbaia();
+ input.abbaia();
+}
+
+// Nota che niente è specificato relativamente al tipo di parametri. Il compilatore
+// genererà e poi verificherà il tipo di ogni invocazione del template, così che
+// la funzione di cui sopra funzione con ogni tipo 'T' che ha const 'abbaia' come metodo!
+
+Cane fluffy;
+fluffy.impostaNome("Fluffy")
+abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia" tre volte.
+
+// I parametri template non devono essere classi:
+template<int Y>
+void stampaMessaggio() {
+ cout << "Impara il C++ in " << Y << " minuti!" << endl;
+}
+
+// E poi esplicitamente specializzare i template per avere codice più efficiente. Ovviamente,
+// la maggior parte delle casistiche reali non sono così triviali.
+// Notare che avrai comunque bisogna di dichiarare la funzione (o classe) come un template
+// anche se hai esplicitamente specificato tutti i parametri.
+template<>
+void stampaMessaggio<10>() {
+ cout << "Impara il C++ più velocemente in soli 10 minuti!" << endl;
+}
+
+printMessage<20>(); // Stampa "impara il C++ in 20 minuti!"
+printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!"
+
+////////////////////////////
+// Gestione delle eccezioni
+///////////////////////////
+
+// La libreria standard fornisce un paio di tipi d'eccezioni
+// (vedi http://en.cppreference.com/w/cpp/error/exception)
+// ma ogni tipo può essere lanciato come eccezione
+#include <exception>
+
+// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi
+// handlers _catch_.
+try {
+ // Non allocare eccezioni nello heap usando _new_.
+ throw std::exception("È avvenuto un problema");
+}
+// Cattura le eccezioni come riferimenti const se sono oggetti
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente
+} catch (...)
+{
+ std::cout << "Catturata un'eccezione sconosciuta";
+ throw; // Rilancia l'eccezione
+}
+
+///////
+// RAII
+///////
+
+// RAII sta per Resource Allocation Is Initialization.
+// Spesso viene considerato come il più potente paradigma in C++.
+// È un concetto semplice: un costruttore di un oggetto
+// acquisisce le risorse di tale oggetto ed il distruttore le rilascia.
+
+// Per comprendere come questo sia vantaggioso,
+// consideriamo una funzione che usa un gestore di file in C:
+void faiQualcosaConUnFile(const char* nomefile)
+{
+ // Per cominciare, assumiamo che niente possa fallire.
+
+ FILE* fh = fopen(nomefile, "r"); // Apri il file in modalità lettura.
+
+ faiQualcosaConIlFile(fh);
+ faiQualcosAltroConEsso(fh);
+
+ fclose(fh); // Chiudi il gestore di file.
+}
+
+// Sfortunatamente, le cose vengono complicate dalla gestione degli errori.
+// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e
+// faiQualcosAltroConEsso ritornano codici d'errore se falliscono.
+// (Le eccezioni sono la maniera preferita per gestire i fallimenti,
+// ma alcuni programmatori, specialmente quelli con un passato in C,
+// non sono d'accordo con l'utilità delle eccezioni).
+// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file
+// se un problema è avvenuto.
+bool faiQualcosaConUnFile(const char* nomefile)
+{
+ FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
+ if (fh == nullptr) // Il puntatore restituito è null in caso di fallimento.
+ return false; // Riporta il fallimento al chiamante.
+
+ // Assumiamo che ogni funzione ritorni false se ha fallito
+ if (!faiQualcosaConIlFile(fh)) {
+ fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
+ return false; // Propaga l'errore.
+ }
+ if (!faiQualcosAltroConEsso(fh)) {
+ fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
+ return false; // Propaga l'errore.
+ }
+
+ fclose(fh); // Chiudi il gestore di file così che non sprechi memoria.
+ return true; // Indica successo
+}
+
+// I programmatori C in genere puliscono questa procedura usando goto:
+bool faiQualcosaConUnFile(const char* nomefile)
+{
+ FILE* fh = fopen(nomefile, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!faiQualcosaConIlFile(fh))
+ goto fallimento;
+
+ if (!faiQualcosAltroConEsso(fh))
+ goto fallimento;
+
+ fclose(fh); // Chiude il file
+ return true; // Indica successo
+
+fallimento:
+ fclose(fh);
+ return false; // Propaga l'errore
+}
+
+// Se le funzioni indicano errori usando le eccezioni,
+// le cose sono un pò più pulite, ma sono sempre sub-ottimali.
+void faiQualcosaConUnFile(const char* nomefile)
+{
+ FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
+ if (fh == nullptr)
+ throw std::exception("Non è stato possibile aprire il file.").
+
+ try {
+ faiQualcosaConIlFile(fh);
+ faiQualcosAltroConEsso(fh);
+ }
+ catch (...) {
+ fclose(fh); // Fai sì che il file venga chiuso se si ha un errore.
+ throw; // Poi rilancia l'eccezione.
+ }
+
+ fclose(fh); // Chiudi il file
+ // Tutto è andato bene
+}
+
+// Confronta questo con l'utilizzo della classe C++ file stream (fstream)
+// fstream usa i distruttori per chiudere il file.
+// Come detto sopra, i distruttori sono automaticamente chiamati
+// ogniqualvolta un oggetto esce dalla visibilità.
+void faiQualcosaConUnFile(const std::string& nomefile)
+{
+ // ifstream è l'abbreviazione di input file stream
+ std::ifstream fh(nomefile); // Apre il file
+
+ // Fai qualcosa con il file
+ faiQualcosaConIlFile(fh);
+ faiQualcosAltroConEsso(fh);
+
+} // Il file viene chiuso automaticamente chiuso qui dal distruttore
+
+// Questo ha vantaggi _enormi_:
+// 1. Può succedere di tutto ma
+// la risorsa (in questo caso il file handler) verrà ripulito.
+// Una volta che scrivi il distruttore correttamente,
+// È _impossibile_ scordarsi di chiudere l'handler e sprecare memoria.
+// 2. Nota che il codice è molto più pulito.
+// Il distruttore gestisce la chiusura del file dietro le scene
+// senza che tu debba preoccupartene.
+// 3. Il codice è sicuro da eccezioni.
+// Una eccezione può essere lanciata in qualunque punto nella funzione e la ripulitura
+// avverrà lo stesso.
+
+// Tutto il codice C++ idiomatico usa RAII in maniera vasta su tutte le risorse.
+// Esempi aggiuntivi includono
+// - Utilizzo della memoria con unique_ptr e shared_ptr
+// - I contenitori - la lista della libreria standard,
+// vettori (i.e. array auto-aggiustati), mappe hash, e così via
+// sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità.
+// - I mutex usano lock_guard e unique_lock
+
+///////////////////////
+// Roba divertente
+//////////////////////
+
+// Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano).
+// Questa sezione è, sfortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi
+// più facili con cui puoi spararti da solo nel piede.
+
+// Puoi sovrascrivere metodi privati!
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // sovrascrive Foo::bar!
+};
+
+
+// 0 == false == NULL (la maggior parte delle volte)!
+bool* pt = new bool;
+*pt = 0; // Setta il valore puntato da 'pt' come falso.
+pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings.
+
+// nullptr dovrebbe risolvere alcune di quei problemi:
+int* pt2 = new int;
+*pt2 = nullptr; // Non compila
+pt2 = nullptr; // Setta pt2 a null.
+
+// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`.
+*pt = nullptr; // Questo compila, anche se '*pt' è un bool!
+
+
+// '=' != '=' != '='!
+// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia.
+Foo f2;
+Foo f1 = f2;
+
+// Chiama Foo::Foo(const Foo&) o qualche variante, ma solo copie di 'Foo' che fanno parte di
+// 'fooSub'. Ogni altro membro di 'fooSub' viene scartato. Questo comportamento
+// orribile viene chiamato "object slicing."
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Chiama Foo::operator=(Foo&) o una sua variante.
+Foo f1;
+f1 = f2;
+
+```
+Letture consigliate:
+
+Un riferimento aggiornato del linguaggio può essere trovato qui
+<http://cppreference.com/w/cpp>
+
+Risorse addizionali possono essere trovate qui <http://cplusplus.com>
diff --git a/it-it/json-it.html.markdown b/it-it/json-it.html.markdown
new file mode 100644
index 00000000..0c401753
--- /dev/null
+++ b/it-it/json-it.html.markdown
@@ -0,0 +1,62 @@
+---
+
+language: json
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+translators:
+ - ["Robert Margelli", "http://github.com/sinkswim/"]
+lang: it-it
+
+---
+
+Dato che JSON è un formato per lo scambio di dati estremamente semplice, questo sarà con molta probabilità
+il più semplice Learn X in Y Minutes.
+
+Nella sua forma più pura JSON non ha commenti, ma molti parser accettano
+commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà
+100% JSON valido. Fortunatamente, si spiega da sè.
+
+```json
+{
+ "chiave": "valore",
+
+ "chiavi": "devono sempre essere racchiuse tra doppi apici",
+ "numeri": 0,
+ "stringhe": "Ciaø, møndø. Tutti gli unicode sono permessi, assieme con l \"escaping\".",
+ "ha booleani?": true,
+ "il nulla": null,
+
+ "numero grande": 1.2e+100,
+
+ "oggetti": {
+ "commento": "La maggior parte della tua struttura viene dagli oggetti.",
+
+ "array": [0, 1, 2, 3, "Gli array possono contenere qualsiasi cosa.", 5],
+
+ "un altro oggetto": {
+ "commento": "Queste cose possono essere annidate, molto utile."
+ }
+ },
+
+ "sciocchezze": [
+ {
+ "sorgenti di potassio": ["banane"]
+ },
+ [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, "neo"],
+ [0, 0, 0, 1]
+ ]
+ ],
+
+ "stile alternativo": {
+ "commento": "Guarda quà!"
+ , "posizione della virgola": "non conta - fintantochè è prima del valore, allora è valida"
+ , "un altro commento": "che bello"
+ },
+
+ "è stato molto breve": "Ed hai finito. Adesso sai tutto cio che JSON ha da offrire."
+}
+```
diff --git a/java.html.markdown b/java.html.markdown
index 10dd498c..928eb39f 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -1,16 +1,16 @@
---
-
language: java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- - ["Madison Dickson", "http://github.com/mix3d"]
- ["Jakukyo Friel", "http://weakish.github.io"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
+ - ["Simon Morgan", "http://sjm.io/"]
filename: LearnJava.java
-
---
-Java is a general-purpose, concurrent, class-based, object-oriented computer programming language.
-[Read more here.](http://docs.oracle.com/javase/tutorial/java/index.html)
+Java is a general-purpose, concurrent, class-based, object-oriented computer
+programming language.
+[Read more here.](http://docs.oracle.com/javase/tutorial/java/)
```java
// Single-line comments start with //
@@ -31,17 +31,17 @@ import java.security.*;
// the file.
public class LearnJava {
- // A program must have a main method as an entry point
+ // A program must have a main method as an entry point.
public static void main (String[] args) {
- // Use System.out.println to print lines
+ // Use System.out.println() to print lines.
System.out.println("Hello World!");
System.out.println(
"Integer: " + 10 +
" Double: " + 3.14 +
" Boolean: " + true);
- // To print without a newline, use System.out.print
+ // To print without a newline, use System.out.print().
System.out.print("Hello ");
System.out.print("World");
@@ -69,7 +69,7 @@ public class LearnJava {
// L is used to denote that this variable value is of type Long;
// anything without is treated as integer by default.
- // Note: Java has no unsigned types
+ // Note: Java has no unsigned types.
// Float - Single-precision 32-bit IEEE 754 Floating Point
float fooFloat = 234.5f;
@@ -86,7 +86,7 @@ public class LearnJava {
// Char - A single 16-bit Unicode character
char fooChar = 'A';
- // final variables can't be reassigned to another object
+ // final variables can't be reassigned to another object.
final int HOURS_I_WORK_PER_WEEK = 9001;
// Strings
@@ -101,10 +101,10 @@ public class LearnJava {
System.out.println(bazString);
// Arrays
- //The array size must be decided upon instantiation
- //The following formats work for declaring an array
- //<datatype>[] <var name> = new <datatype>[<array size>];
- //<datatype> <var name>[] = new <datatype>[<array size>];
+ // The array size must be decided upon instantiation
+ // The following formats work for declaring an array
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ // <datatype> <var name>[] = new <datatype>[<array size>];
int[] intArray = new int[10];
String[] stringArray = new String[1];
boolean boolArray[] = new boolean[100];
@@ -122,17 +122,17 @@ public class LearnJava {
System.out.println("intArray @ 1: " + intArray[1]); // => 1
// Others to check out
- // ArrayLists - Like arrays except more functionality is offered,
- // and the size is mutable
+ // ArrayLists - Like arrays except more functionality is offered, and
+ // the size is mutable.
// LinkedLists - Implementation of doubly-linked list. All of the
- // operations perform as could be expected for
- // a doubly-linked list.
- // Maps - A set of objects that maps keys to values. A map cannot contain
- // duplicate keys; each key can map to at most one value.
- // HashMaps - This class uses a hashtable to implement the Map interface.
- // This allows the execution time of basic operations,
- // such as get and insert element, to remain constant even
- // for large sets.
+ // operations perform as could be expected for a
+ // doubly-linked list.
+ // Maps - A set of objects that maps keys to values. A map cannot
+ // contain duplicate keys; each key can map to at most one value.
+ // HashMaps - This class uses a hashtable to implement the Map
+ // interface. This allows the execution time of basic
+ // operations, such as get and insert element, to remain
+ // constant even for large sets.
///////////////////////////////////////
// Operators
@@ -160,13 +160,13 @@ public class LearnJava {
// Bitwise operators!
/*
- ~ Unary bitwise complement
- << Signed left shift
- >> Signed right shift
- >>> Unsigned right shift
- & Bitwise AND
- ^ Bitwise exclusive OR
- | Bitwise inclusive OR
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed right shift
+ >>> Unsigned right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
*/
// Incrementations
@@ -175,10 +175,10 @@ public class LearnJava {
// 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)
+ 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
@@ -197,73 +197,69 @@ public class LearnJava {
// While loop
int fooWhile = 0;
- while(fooWhile < 100)
- {
- //System.out.println(fooWhile);
- //Increment the counter
- //Iterated 100 times, fooWhile 0,1,2...99
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Increment the counter
+ // Iterated 100 times, fooWhile 0,1,2...99
fooWhile++;
}
System.out.println("fooWhile Value: " + fooWhile);
// Do While Loop
int fooDoWhile = 0;
- do
- {
- //System.out.println(fooDoWhile);
- //Increment the counter
- //Iterated 99 times, fooDoWhile 0->99
+ do {
+ System.out.println(fooDoWhile);
+ // Increment the counter
+ // Iterated 99 times, fooDoWhile 0->99
fooDoWhile++;
- }while(fooDoWhile < 100);
+ } while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile);
// For Loop
int fooFor;
- //for loop structure => for(<start_statement>; <conditional>; <step>)
- for(fooFor=0; fooFor<10; fooFor++){
- //System.out.println(fooFor);
- //Iterated 10 times, fooFor 0->9
+ // for loop structure => for(<start_statement>; <conditional>; <step>)
+ for (fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Iterated 10 times, fooFor 0->9
}
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);
+ // The for loop is also able to iterate over arrays as well as objects
+ // that implement the Iterable interface.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // for each loop structure => for (<object> : <iterable>)
+ // reads as: for each element in the iterable
+ // note: the object type must match the element type of the iterable.
+
+ 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),
- // the String class, and a few special classes that wrap
- // primitive types: Character, Byte, Short, and Integer.
+ // 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";
+ switch (month) {
+ case 1: monthString = "January";
break;
- case 3:
- monthString = "March";
+ case 2: monthString = "February";
break;
- default:
- monthString = "Some other month";
+ case 3: monthString = "March";
break;
+ default: monthString = "Some other month";
+ break;
}
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>"
+ // 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
@@ -287,9 +283,8 @@ public class LearnJava {
// String
// Typecasting
- // You can also cast java objects, there's a lot of details and
- // deals with some more intermediate concepts.
- // Feel free to check it out here:
+ // You can also cast Java objects, there's a lot of details and deals
+ // with some more intermediate concepts. Feel free to check it out here:
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
@@ -319,9 +314,9 @@ public class LearnJava {
// Class Declaration Syntax:
-// <public/private/protected> class <class name>{
-// //data fields, constructors, functions all inside.
-// //functions are called as methods in Java.
+// <public/private/protected> class <class name> {
+// // data fields, constructors, functions all inside.
+// // functions are called as methods in Java.
// }
class Bicycle {
@@ -342,7 +337,8 @@ class Bicycle {
}
// This is a constructor that takes arguments
- public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ String name) {
this.gear = startGear;
this.cadence = startCadence;
this.speed = startSpeed;
@@ -388,10 +384,8 @@ class Bicycle {
//Method to display the attribute values of this Object.
@Override
public String toString() {
- return "gear: " + gear +
- " cadence: " + cadence +
- " speed: " + speed +
- " name: " + name;
+ return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
+ " name: " + name;
}
} // end class Bicycle
@@ -405,26 +399,26 @@ class PennyFarthing extends Bicycle {
super(startCadence, startSpeed, 0, "PennyFarthing");
}
- // You should mark a method you're overriding with an @annotation
- // To learn more about what annotations are and their purpose
- // check this out: http://docs.oracle.com/javase/tutorial/java/annotations/
+ // You should mark a method you're overriding with an @annotation.
+ // To learn more about what annotations are and their purpose check this
+ // out: http://docs.oracle.com/javase/tutorial/java/annotations/
@Override
public void setGear(int gear) {
gear = 0;
}
-
}
-//Interfaces
-//Interface declaration syntax
-//<access-level> interface <interface-name> extends <super-interfaces> {
-// //Constants
-// //Method declarations
-//}
+// Interfaces
+// Interface declaration syntax
+// <access-level> interface <interface-name> extends <super-interfaces> {
+// // Constants
+// // Method declarations
+// }
-//Example - Food:
+// Example - Food:
public interface Edible {
- public void eat(); //Any class that implements this interface, must implement this method
+ public void eat(); // Any class that implements this interface, must
+ // implement this method.
}
public interface Digestible {
@@ -432,33 +426,31 @@ public interface Digestible {
}
-//We can now create a class that implements both of these interfaces
+// We can now create a class that implements both of these interfaces.
public class Fruit implements Edible, Digestible {
@Override
public void eat() {
- //...
+ // ...
}
@Override
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 {
+// In Java, you can extend only one class, but you can implement many
+// interfaces. For example:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne,
+ InterfaceTwo {
@Override
public void InterfaceOneMethod() {
-
}
@Override
public void InterfaceTwoMethod() {
-
}
}
-
```
## Further Reading
@@ -500,5 +492,3 @@ The links provided here below are just to get an understanding of the topic, fee
* [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/json.html.markdown b/json.html.markdown
index f5287138..f57b82b8 100644
--- a/json.html.markdown
+++ b/json.html.markdown
@@ -10,7 +10,7 @@ As JSON is an extremely simple data-interchange format, this is most likely goin
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
+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
diff --git a/julia.html.markdown b/julia.html.markdown
index 3a52018c..5ccd6484 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -8,7 +8,7 @@ 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 October 18th, 2013.
+This is based on Julia 0.3.
```ruby
@@ -91,7 +91,7 @@ false
# $ can be used for string interpolation:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
-# You can put any Julia expression inside the parenthesis.
+# You can put any Julia expression inside the parentheses.
# 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
@@ -190,7 +190,7 @@ 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]
@@ -264,7 +264,7 @@ in(("two", 3), filled_dict) # => false
haskey(filled_dict, "one") # => true
haskey(filled_dict, 1) # => false
-# Trying to look up a non-existant key will raise an error
+# Trying to look up a non-existent key will raise an error
try
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
catch e
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 9de41275..00f4c53a 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -43,7 +43,7 @@ edit('myfunction.m') % Open function/script in editor
type('myfunction.m') % Print the source of function/script to Command Window
profile on % turns on the code profiler
-profile of % turns off the code profiler
+profile off % turns off the code profiler
profile viewer % Open profiler
help command % Displays documentation for command in Command Window
diff --git a/nim.html.markdown b/nim.html.markdown
index aa15e591..c9548a1c 100644
--- a/nim.html.markdown
+++ b/nim.html.markdown
@@ -155,7 +155,7 @@ var anotherArray = ["Default index", "starts at", "0"]
# More data structures are available, including tables, sets, lists, queues,
# and crit bit trees.
-# http://nimrod-lang.org/lib.html#collections-and-algorithms
+# http://nim-lang.org/docs/lib.html#collections-and-algorithms
#
# IO and Control Flow
@@ -174,7 +174,7 @@ else:
# `while`, `if`, `continue`, `break`
-import strutils as str # http://nimrod-lang.org/strutils.html
+import strutils as str # http://nim-lang.org/docs/strutils.html
echo "I'm thinking of a number between 41 and 43. Guess which!"
let number: int = 42
var
@@ -263,11 +263,11 @@ performance, and compile-time features.
## Further Reading
-* [Home Page](http://nimrod-lang.org)
-* [Download](http://nimrod-lang.org/download.html)
-* [Community](http://nimrod-lang.org/community.html)
-* [FAQ](http://nimrod-lang.org/question.html)
-* [Documentation](http://nimrod-lang.org/documentation.html)
-* [Manual](http://nimrod-lang.org/manual.html)
-* [Standard Library](http://nimrod-lang.org/lib.html)
-* [Rosetta Code](http://rosettacode.org/wiki/Category:Nimrod)
+* [Home Page](http://nim-lang.org)
+* [Download](http://nim-lang.org/download.html)
+* [Community](http://nim-lang.org/community.html)
+* [FAQ](http://nim-lang.org/question.html)
+* [Documentation](http://nim-lang.org/documentation.html)
+* [Manual](http://nim-lang.org/docs/manual.html)
+* [Standard Library](http://nim-lang.org/docs/lib.html)
+* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index 56640a87..91b84b47 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -415,7 +415,7 @@ distance = 18; // References "long distance" from MyClass implementation
+ (NSString *)classMethod
{
- return [[self alloc] init];
+ return @"Some string";
}
+ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight
diff --git a/perl.html.markdown b/perl.html.markdown
index aac95939..4e172406 100644
--- a/perl.html.markdown
+++ b/perl.html.markdown
@@ -12,16 +12,16 @@ Perl 5 is a highly capable, feature-rich programming language with over 25 years
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.
+# Single line comments start with a number sign.
#### Perl variable types
-# Variables begin with the $ symbol.
+# Variables begin with a sigil, which is a symbol showing the type.
# 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.
+### Perl has three main variable types: $scalar, @array, and %hash.
## Scalars
# A scalar represents a single value:
@@ -47,9 +47,9 @@ 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",
- );
+ apple => "red",
+ banana => "yellow",
+);
# Scalars, arrays and hashes are documented more fully in perldata.
# (perldoc perldata).
@@ -60,17 +60,17 @@ my %fruit_color = (
# Perl has most of the usual conditional and looping constructs.
-if ( $var ) {
- ...
-} elsif ( $var eq 'bar' ) {
- ...
+if ($var) {
+ ...
+} elsif ($var eq 'bar') {
+ ...
} else {
- ...
+ ...
}
-unless ( condition ) {
- ...
- }
+unless (condition) {
+ ...
+}
# This is provided as a more readable version of "if (!condition)"
# the Perlish post-condition way
@@ -78,19 +78,29 @@ print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;
# while
- while ( condition ) {
- ...
- }
+while (condition) {
+ ...
+}
+
+# for loops and iteration
+for (my $i = 0; $i < $max; $i++) {
+ print "index is $i";
+}
-# for and foreach
-for ($i = 0; $i <= $max; $i++) {
- ...
- }
+for (my $i = 0; $i < @elements; $i++) {
+ print "Current element is " . $elements[$i];
+}
-foreach (@array) {
- print "This element is $_\n";
- }
+for my $element (@elements) {
+ print $element;
+}
+
+# implicitly
+
+for (@elements) {
+ print;
+}
#### Regular expressions
@@ -129,9 +139,11 @@ my @lines = <$in>;
# Writing subroutines is easy:
sub logger {
- my $logmessage = shift;
- open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
- print $logfile $logmessage;
+ 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:
diff --git a/perl6.html.markdown b/perl6.html.markdown
index f0ef6600..af545793 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -7,11 +7,13 @@ contributors:
- ["Nami-Doc", "http://github.com/Nami-Doc"]
---
-Perl 6 is a highly capable, feature-rich programming language made for the
-upcoming hundred years.
+Perl 6 is a highly capable, feature-rich programming language made for at
+least the next hundred years.
-Perl 6 runs on [the Parrot VM](http://parrot.org/), the JVM
-and [the MoarVM](http://moarvm.com).
+The primary Perl 6 compiler is called [Rakudo](http://rakudo.org), which runs on
+the JVM and [the MoarVM](http://moarvm.com) and
+[prior to March 2015](http://pmthium.com/2015/02/suspending-rakudo-parrot/),
+[the Parrot VM](http://parrot.org/).
Meta-note : the triple pound signs are here to denote headlines,
double paragraphs, and single notes.
@@ -211,7 +213,7 @@ say $x; #=> 52
# - `if`
# Before talking about `if`, we need to know which values are "Truthy"
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
-# Only these values are Falsey: (), 0, "0", "", Nil, A type (like `Str` or `Int`),
+# Only these values are Falsey: (), "", Nil, A type (like `Str` or `Int`),
# and of course False itself.
# Every other value is Truthy.
if True {
@@ -253,7 +255,9 @@ given "foo bar" {
when $_.chars > 50 { # smart matching anything with True (`$a ~~ True`) is True,
# so you can also put "normal" conditionals.
# This when is equivalent to this `if`:
- # if ($_.chars > 50) ~~ True {...}
+ # if $_ ~~ ($_.chars > 50) {...}
+ # Which means:
+ # if $_.chars > 50 {...}
say "Quite a long string !";
}
default { # same as `when *` (using the Whatever Star)
@@ -305,37 +309,9 @@ if long-computation() -> $result {
say "The result is $result";
}
-# Now that you've seen how to traverse a list, you need to be aware of something:
-# List context (@) flattens. If you traverse nested lists, you'll actually be traversing a
-# shallow list.
-for 1, 2, (3, (4, ((5)))) {
- say "Got $_.";
-} #=> Got 1. Got 2. Got 3. Got 4. Got 5.
-
-# ... However: (forcing item context with `$`)
-for 1, 2, $(3, 4) {
- say "Got $_.";
-} #=> Got 1. Got 2. Got 3 4.
-
-# Note that the last one actually joined 3 and 4.
-# While `$(...)` will apply item to context to just about anything, you can also create
-# an array using `[]`:
-for [1, 2, 3, 4] {
- say "Got $_.";
-} #=> Got 1 2 3 4.
-
-# You need to be aware of when flattening happens exactly.
-# The general guideline is that argument lists flatten, but not method calls.
-# Also note that `.list` and array assignment flatten (`@ary = ...`) flatten.
-((1,2), 3, (4,5)).map({...}); # iterates over three elements (method call)
-map {...}, ((1,2),3,(4,5)); # iterates over five elements (argument list is flattened)
-
-(@a, @b, @c).pick(1); # picks one of three arrays (method call)
-pick 1, @a, @b, @c; # flattens argument list and pick one element
-
### Operators
-## Since Perl languages are very much operator-based languages
+## Since Perl languages are very much operator-based languages,
## Perl 6 operators are actually just funny-looking subroutines, in syntactic
## categories, like infix:<+> (addition) or prefix:<!> (bool not).
@@ -394,17 +370,21 @@ say @array[^10]; # you can pass arrays as subscripts and it'll return
# "1 2 3 4 5 6 7 8 9 10" (and not run out of memory !)
# Note : when reading an infinite list, Perl 6 will "reify" the elements
# it needs, then keep them in memory. They won't be calculated more than once.
-
-# Warning, though: if you try this example in the REPL and just put `1..*`,
-# Perl 6 will be forced to try and evaluate the whole array (to print it),
-# so you'll end with an infinite loop.
-
-# You can use that in most places you'd expect, even assigning to an array
-my @numbers = ^20;
-@numbers[5..*] = 3, 9 ... * > 90; # The right hand side could be infinite as well.
- # (but not both, as this would be an infinite loop)
-say @numbers; #=> 3 9 15 21 27 [...] 81 87
-
+# It also will never calculate more elements that are needed.
+
+# An array subscript can also be a closure.
+# It'll be called with the length as the argument
+say join(' ', @array[15..*]); #=> 15 16 17 18 19
+# which is equivalent to:
+say join(' ', @array[-> $n { 15..$n }]);
+
+# You can use that in most places you'd expect, even assigning to an array
+my @numbers = ^20;
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99
+@numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite,
+ # only the 15 needed values will be calculated.
+say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
+ # (only 20 values)
## * And, Or
3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`.
@@ -416,7 +396,7 @@ $a && $b && $c; # Returns the first argument that evaluates to False,
$a || $b;
# And because you're going to want them,
-# you also have composed assignment operators:
+# you also have compound assignment operators:
$a *= 2; # multiply and assignment
$b %%= 5; # divisible by and assignment
@array .= sort; # calls the `sort` method and assigns the result back
@@ -426,7 +406,7 @@ $b %%= 5; # divisible by and assignment
# a few more key concepts that make them better than in any other language :-).
## Unpacking !
-# It's the ability to "extract" arrays and keys.
+# It's the ability to "extract" arrays and keys (AKA "destructuring").
# It'll work in `my`s and in parameter lists.
my ($a, $b) = 1, 2;
say $a; #=> 1
@@ -1064,7 +1044,7 @@ postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
# *everything* -- with great power comes great responsibility)
## Meta operators !
-# Oh boy, get ready. Get ready, because we're dwelving deep
+# Oh boy, get ready. Get ready, because we're delving deep
# into the rabbit's hole, and you probably won't want to go
# back to other languages after reading that.
# (I'm guessing you don't want to already at that point).
diff --git a/php.html.markdown b/php.html.markdown
index 039288a0..2d4565e0 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -60,7 +60,7 @@ $float = 1.2e3;
$float = 7E-10;
// Delete variable
-unset($int1)
+unset($int1);
// Arithmetic
$sum = 1 + 1; // 2
diff --git a/pl-pl/python-pl.html.markdown b/pl-pl/python-pl.html.markdown
new file mode 100644
index 00000000..c3e8287a
--- /dev/null
+++ b/pl-pl/python-pl.html.markdown
@@ -0,0 +1,637 @@
+---
+name: python
+category: language
+language: python
+filename: learnpython-pl.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "http://aminbandali.com"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Dominik Krzemiński", "https://github.com/dokato"]
+lang: pl-pl
+---
+
+Python został opracowany przez Guido Van Rossuma na początku lat 90-tych.
+Obecnie jest jednym z najbardziej popularnych języków programowania.
+Zakochałem się w Pythonie dzięki porządkowi, jaki utrzymywany jest w kodzie.
+To po prostu wykonywalny pseudokod.
+
+Zapraszam do kontaktu. Złapiecie nas na:
+- kontakt polski: raymon92 [at] [google's email service]
+- kontakt angielski: [@louiedinh](http://twitter.com/louiedinh) lub louiedinh [at] [google's email service]
+
+Uwaga: Ten artykuł odnosi się do wersji Pythona 2.7, ale powinien
+działać w wersjach 2.x. Dla wersji 3.x znajdziesz odpowiedni artykuł na stronie głównej.
+
+```python
+# -*- coding: utf-8 -*-
+
+# Pojedyncze komentarze oznaczamy takim symbolem.
+
+""" Wielolinijkowe napisy zapisywane są przy użyciu
+ trzech znaków cudzysłowiu i często
+ wykorzystywane są jako komentarze.
+"""
+
+####################################################
+## 1. Podstawowe typy danych i operatory
+####################################################
+
+# Liczby to liczby
+3 # => 3
+
+# Matematyka jest intuicyjna
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# Dzielenie może być kłopotliwe. Poniższe to dzielenie
+# całkowitoliczbowe(int) i wynik jest automatycznie zaokrąglany.
+5 / 2 # => 2
+
+# Aby to naprawić musimy powiedzieć nieco o liczbach zmiennoprzecinkowych.
+2.0 # To liczba zmiennoprzecinkowa, tzw. float
+11.0 / 4.0 # => 2.75 ahhh...znacznie lepiej
+
+# Wynik dzielenia całkowitoliczbowego jest obcinany dla liczb
+# dodatnich i ujemnych.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # działa też na floatach
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Operator modulo - wyznaczanie reszty z dzielenia
+7 % 3 # => 1
+
+# Potęgowanie (x do potęgi ytej)
+2**4 # => 16
+
+# Wymuszanie pierwszeństwa w nawiasach
+(1 + 3) * 2 # => 8
+
+# Operacje logiczne
+# Zauważ, że przy "and" i "or" trzeba zwracać uwagę na rozmiar liter
+True and False #=> False # Fałsz
+False or True #=> True # Prawda
+
+# Zauważ, że operatorów logicznych można używać z intami
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+k1 == True #=> True
+
+# aby zanegować użyj "not"
+not True # => False
+not False # => True
+
+# Równość ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Nierówność !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Więcej porównań
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Porównania można układać w łańcuch!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Napisy (typ string) tworzone są przy użyciu cudzysłowów " lub '
+"Jestem napisem."
+'Ja też jestem napisem.'
+
+# Napisy można dodawać!
+"Witaj " + "świecie!" # => "Witaj świecie!"
+
+# ... a nawet mnożone
+"Hej" * 3 # => "HejHejHej"
+
+# Napis może być traktowany jako lista znaków
+"To napis"[0] # => 'T'
+
+# % może być używane do formatowania napisów:
+"%s są %s" % ("napisy", "fajne")
+
+# Jednak nowszym sposobem formatowania jest metoda "format".
+# Ta metoda jest obecnie polecana:
+"{0} są {1}".format("napisy", "fajne")
+# Jeśli nie chce ci się liczyć użyj słów kluczowych.
+"{imie} chce zjeść {jadlo}".format(imie="Bob", jasno="lasagne")
+
+# None jest obiektem
+None # => None
+
+# Nie używaj "==" w celu porównania obiektów z None
+# Zamiast tego użyj "is"
+"etc" is None # => False
+None is None # => True
+
+# Operator 'is' testuje identyczność obiektów. To nie jest zbyt
+# pożyteczne, gdy działamy tylko na prostych wartościach,
+# ale przydaje się, gdy mamy do czynienia z obiektami.
+
+# None, 0, i pusty napis "" są odpowiednikami logicznego False.
+# Wszystkie inne wartości są True
+bool(0) # => False
+bool("") # => False
+
+
+####################################################
+## 2. Zmienne i zbiory danych
+####################################################
+
+# Python ma wyrażenie wypisujące "print" we wszystkich wersjach 2.x, ale
+# zostało usunięte z wersji 3.
+print "Jestem Python. Miło poznać!"
+# Python ma też funkcję "print" dostępną w wersjach 2.7 and 3...
+# ale w 2.7 musisz dodać import (odkomentuj):
+# from __future__ import print_function
+print("Ja też jestem Python! ")
+
+# Nie trzeba deklarować zmiennych przed przypisaniem.
+jakas_zmienna = 5 # Konwencja mówi: używaj małych znaków i podłogi _
+jakas_zmienna # => 5
+
+# Próba dostępu do niezadeklarowanej zmiennej da błąd.
+# Przejdź do sekcji Obsługa wyjątków po więcej...
+inna_zmienna # Wyrzuca nazwę błędu
+
+# "if" może być użyte jako wyrażenie
+"huraaa!" if 3 > 2 else 2 # => "huraaa!"
+
+# Listy:
+li = []
+# Możesz zacząć od wypełnionej listy
+inna_li = [4, 5, 6]
+
+# Dodaj na koniec używając "append"
+li.append(1) # li to teraz [1]
+li.append(2) # li to teraz [1, 2]
+li.append(4) # li to teraz [1, 2, 4]
+li.append(3) # li to teraz [1, 2, 4, 3]
+# Usuwanie z konca da "pop"
+li.pop() # => 3 a li stanie się [1, 2, 4]
+# Dodajmy ponownie
+li.append(3) # li to znowu [1, 2, 4, 3].
+
+# Dostęp do list jak do każdej tablicy
+li[0] # => 1
+# Użyj = aby nadpisać wcześniej wypełnione miejsca w liście
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Uwaga: ustawiamy starą wartość
+# Tak podglądamy ostatni element
+li[-1] # => 3
+
+# Jeżeli wyjdziesz poza zakres...
+li[4] # ... zobaczysz IndexError
+
+# Możesz tworzyć wyniki.
+li[1:3] # => [2, 4]
+# Bez początku
+li[2:] # => [4, 3]
+# Omijamy koniec
+li[:3] # => [1, 2, 4]
+# Wybierz co drugi
+li[::2] # =>[1, 4]
+# Odwróć listę
+li[::-1] # => [3, 4, 2, 1]
+# Użyj kombinacji powyższych aby tworzyć bardziej skomplikowane wycinki
+# li[poczatek:koniec:krok]
+
+# Usuń element używając "del"
+del li[2] # li to teraz [1, 2, 3]
+
+# Listy można dodawać
+li + inna_li # => [1, 2, 3, 4, 5, 6]
+# Uwaga: wartości poszczególnych list się nie zmieniają.
+
+# Do łączenia list użyj "extend()"
+li.extend(other_li) # li to teraz [1, 2, 3, 4, 5, 6]
+
+# Sprawdź czy jest w liście używając "in"
+1 in li # => True
+
+# "len()" pokazuje długość listy
+len(li) # => 6
+
+
+# Krotki (tuple) są jak listy, ale nie można ich modyfikować.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # wyrzuci TypeError
+
+# Ale wielu akcji dla list możesz używać przy krotkach
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Można rozpakować krotki i listy do poszczególych zmiennych
+a, b, c = (1, 2, 3) # a to teraz 1, b jest 2, a c to 3
+# Jeżeli zapomnisz nawiasów automatycznie tworzone są krotki
+d, e, f = 4, 5, 6
+# Popatrz jak prosto zamienić wartości
+e, d = d, e # d to teraz 5 a e to 4
+
+
+# Słowniki są również pożyteczne
+pusty_slownik = {}
+# Tu tworzymy wypełniony:
+pelen_slownik = {"raz": 1, "dwa": 2, "trzy": 3}
+
+# Podglądany wartość
+pelen_slownik["one"] # => 1
+
+# Wypisz wszystkie klucze używając "keys()"
+pelen_slownik.keys() # => ["trzy", "dwa", "raz"]
+# Uwaga: słowniki nie gwarantują kolejności występowania kluczy.
+
+# A teraz wszystkie wartości "values()"
+pelen_slownik.values() # => [3, 2, 1]
+# Uwaga: to samo dotyczy wartości.
+
+# Sprawdzanie czy występuje to "in"
+"raz" in pelen_slownik # => True
+1 in pelen_slownik # => False
+
+# Próba dobrania się do nieistniejącego klucza da KeyError
+pelen_slownik["cztery"] # KeyError
+
+# Użyj "get()" method aby uniknąć KeyError
+pelen_slownik.get("raz") # => 1
+pelen_slownik.get("cztery") # => None
+# Metoda get zwraca domyślną wartość gdy brakuje klucza
+pelen_slownik.get("one", 4) # => 1
+pelen_slownik.get("cztery", 4) # => 4
+# zauważ, że pelen_slownik.get("cztery") jest wciąż => None
+# (get nie ustawia wartości słownika)
+
+# przypisz wartość do klucza podobnie jak w listach
+pelen_slownik["cztery"] = 4 # teraz: pelen_slownik["cztery"] => 4
+
+# "setdefault()" wstawia do słownika tylko jeśli nie było klucza
+pelen_slownik.setdefault("piec", 5) # pelen_slownik["piec"] daje 5
+pelen_slownik.setdefault("piec", 6) # pelen_slownik["piec"] to wciąż 5
+
+
+# Teraz zbiory (set) ... cóż zbiory (to po prostu listy ale bez potórzeń)
+pusty_zbior = set()
+# Inicjalizujemy "set()" pewnymi wartościami
+jakis_zbior = set([1, 2, 2, 3, 4]) # jakis_zbior to teraz set([1, 2, 3, 4])
+
+# kolejność nie jest gwarantowana, nawet gdy wydaje się posortowane
+inny_zbior = set([4, 3, 2, 2, 1]) # inny_zbior to set([1, 2, 3, 4])
+
+# Od Pythona 2.7 nawiasy klamrowe {} mogą być użyte do deklarowania zbioru
+pelen_zbior = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+
+# Dodaj więcej elementów przez "add()"
+pelen_zbior.add(5) # pelen_zbior is now {1, 2, 3, 4, 5}
+
+# Znajdź przecięcie zbiorów używając &
+inny_zbior = {3, 4, 5, 6}
+pelen_zbior & other_set # => {3, 4, 5}
+
+# Suma zbiorów |
+pelen_zbior | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Różnicę zbiorów da znak -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Sprawdzanie obecności w zbiorze: "in".
+2 in pelen_zbior # => True
+10 in pelen_zbior # => False
+
+
+####################################################
+## 3. Kontrola przepływu
+####################################################
+
+# Tworzymy zmienną some_var
+some_var = 5
+
+# Tutaj widzisz wyrażenie warunkowe "if". Wcięcia są ważne Pythonie!
+# wypisze "some_var jest mniejsza niż 10"
+if some_var > 10:
+ print("some_var jest wieksza niż 10")
+elif some_var < 10: # This elif clause is optional.
+ print("some_var jest mniejsza niż 10")
+else: # This is optional too.
+ print("some_var jest równa 10")
+
+
+"""
+Pętla for iteruje po elementach listy wypisując:
+ pies to ssak
+ kot to ssak
+ mysz to ssak
+"""
+for zwierze in ["pies", "kot", "mysz"]:
+ # Możesz użyć % aby stworzyć sformatowane napisy
+ print("%s to ssak" % zwierze)
+
+"""
+"range(liczba)" zwraca listę liczb
+od zera do danej liczby:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+While to pętla która jest wykonywana dopóki spełniony jest warunek:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Skrót od x = x + 1
+
+# Wyjątki wyłapujemy używając try, except
+
+# Działa w Pythonie 2.6 i wyższych:
+try:
+ # Użyj "raise" aby wyrzucić wyjąte
+ raise IndexError("To błąd indeksu")
+except IndexError as e:
+ pass # Pass to brak reakcji na błąd. Zazwyczaj nanosisz tu poprawki.
+except (TypeError, NameError):
+ pass # kilka wyjątków może być przechwyce razem.
+else: # Opcjonalna część bloku try/except. Musi wystąpić na końcu
+ print "Wszystko ok!" # Zadziała tylko, gdy program nie napotka wyjatku.
+
+
+####################################################
+## 4. Funkcjie
+####################################################
+
+# Użyj "def" aby stworzyć nową funkcję
+def dodaj(x, y):
+ print("x to %s a y to %s" % (x, y))
+ return x + y # słówko kluczowe return zwraca wynik działania
+
+# Tak wywołuje się funkcję z parametrami (args):
+dodaj(5, 6) # => wypisze "x to 5 a y to 6" i zwróci 11
+
+# Innym sposobem jest wywołanie z parametrami nazwanymi.
+dodaj(y=6, x=5) # tutaj kolejność podania nie ma znaczenia.
+
+
+# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
+# nienazwanych args, co będzie interpretowane jako krotka jeśli nie użyjesz *
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+
+# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
+# nazwanych kwargs, które będa interpretowane jako słownik jeśli nie dasz **
+def keyword_args(**kwargs):
+ return kwargs
+
+# Wywołajmy to i sprawdźmy co się dzieje
+keyword_args(wielka="stopa", loch="ness") # => {"wielka": "stopa", "loch": "ness"}
+
+
+# Możesz też to pomieszać
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) wyrzuci:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Użyj * aby rozwinąć parametry z krotki args
+# i użyj ** aby rozwinąć parametry nazwane ze słownika kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # odpowiednik foo(1, 2, 3, 4)
+all_the_args(**kwargs) # odpowiednik foo(a=3, b=4)
+all_the_args(*args, **kwargs) # odpowiednik foo(1, 2, 3, 4, a=3, b=4)
+
+# Możesz podać parametry args i kwargs do funkcji równocześnie
+# przez rozwinięcie odpowiednio * i **
+def pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
+# Zakres widoczności
+x = 5
+
+def setX(num):
+ # Lokalna zmienna x nie jest tym samym co zmienna x
+ x = num # => 43
+ print x # => 43
+
+def setGlobalX(num):
+ global x
+ print x # => 5
+ x = num # globalna zmienna to teraz 6
+ print x # => 6
+
+setX(43)
+setGlobalX(6)
+
+# Można tworzyć funkcje wewnętrzne i zwrócić je jako wynik
+def rob_dodawacz(x):
+ def dodawacz(y):
+ return x + y
+ return dodawacz
+
+dodaj_10 = rob_dodawacz(10)
+dodaj_10(3) # => 13
+
+# Są również funkcje nienazwane "lambda"
+(lambda x: x > 2)(3) # => True
+
+# Są także wbudowane funkcje wysokiego poziomu
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# Można używać wyrażeń listowych do mapowania (map) i filtrowania (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. Klasy
+####################################################
+
+# Wszystkie klasy są podklasą object
+class Czlowiek(object):
+
+ # Atrybut klasy. Występuje we wszystkich instancjach klasy.
+ gatunek = "H. sapiens"
+
+ # Podstawowa inicjalizacja - wywoływana podczas tworzenia instacji.
+ # Zauważ, że podwójne podkreślenia przed i za nazwą oznaczają
+ # obietky lub atrybuty, który żyją tylko w kontrolowanej przez
+ # użytkownika przestrzeni nazw. Nie używaj ich we własnych metodach.
+ def __init__(self, nazwa):
+ # przypisz parametr "nazwa" do atrybutu instancji
+ self.nazwa = nazwa
+
+ # Metoda instancji. Wszystkie metody biorą "self" jako pierwszy argument
+ def mow(self, wiadomosc):
+ return "%s: %s" % (self.nazwa, wiadomosc)
+
+ # Metoda klasowa współdzielona przez instancje.
+ # Ma wywołującą klasę jako pierwszy argument.
+ @classmethod
+ def daj_gatunek(cls):
+ return cls.gatunek
+
+ # Metoda statyczna jest wywoływana bez argumentów klasy czy instancji.
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instancja klasy
+i = Czlowiek(name="Ian")
+print(i.mow("cześć")) # wypisze "Ian: cześć"
+
+j = Czlowiek("Joel")
+print(j.mow("cześć")) # wypisze "Joel: cześć"
+
+# Wywołujemy naszą metodę klasową
+i.daj_gatunek() # => "H. sapiens"
+
+# Zmieniamy wspólny parametr
+Czlowiek.gatunek = "H. neanderthalensis"
+i.daj_gatunek() # => "H. neanderthalensis"
+j.daj_gatunek() # => "H. neanderthalensis"
+
+# Wywołanie metody statycznej
+Czlowiek.grunt() # => "*grunt*"
+
+
+####################################################
+## 6. Moduły
+####################################################
+
+# Tak importuje się moduły:
+import math
+print(math.sqrt(16)) # => 4
+
+# Można podać konkretne funkcje, np. ceil, floor z modułu math
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Można zaimportować wszystkie funkcje z danego modułu.
+# Ostrzeżenie: nie jest to polecane.
+from math import *
+
+# Można skracać nazwy modułów.
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+# sprawdźmy czy funkcje są równoważne
+from math import sqrt
+math.sqrt == m.sqrt == sqrt # => True
+
+# Moduły pythona to zwykłe skrypty napisane w tym języku. Możesz
+# pisać własne i importować je. Nazwa modułu to nazwa pliku.
+
+# W ten sposób sprawdzisz jakie funkcje wchodzą w skład modułu.
+import math
+dir(math)
+
+
+####################################################
+## 7. Zaawansowane
+####################################################
+
+# Generatory pomagają tworzyć tzw. "leniwy kod"
+def podwojne_liczby(iterowalne):
+ for i in iterowalne:
+ yield i + i
+
+# Generatory tworzą wartości w locie.
+# W przeciwienstwie do wygenerowania wartości raz i ich zachowania,
+# powstają one na bieżąco, w wyniku iteracji. To oznacza, że wartości
+# większe niż 15 nie będą przetworzone w funkcji "podwojne_liczby".
+# Zauważ, że xrange to generator, który wykonuje tę samą operację co range.
+# Stworzenie listy od 1 do 900000000 zajęłoby sporo czasu i pamięci,
+# a xrange tworzy obiekt generatora zamiast tworzyć całą listę jak range.
+# Użyto podkreślinika, aby odróżnić nazwę zmiennej od słówka kluczowego
+# Pythona.
+xrange_ = xrange(1, 900000000)
+
+# poniższa pętla będzie podwajać liczby aż do 30
+for i in podwojne_liczby(xrange_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Dekoratory
+# w tym przykładzie "beg" jest nakładką na "say"
+# Beg wywołuje say. Jeśli say_please jest prawdziwe wtedy wzracana wartość
+# zostanie zmieniona
+
+from functools import wraps
+
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Proszę! Jestem spłukany :(")
+ return msg
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Kupisz mi piwo?"
+ return msg, say_please
+
+
+print(say()) # Kupisz mi piwo?
+print(say(say_please=True)) # Kupisz mi piwo? Proszę! Jestem spłukany :(
+```
+
+## Gotowy na więcej?
+### Polskie
+
+* [Zanurkuj w Pythonie](http://pl.wikibooks.org/wiki/Zanurkuj_w_Pythonie)
+* [LearnPythonPl](http://www.learnpython.org/pl/)
+
+### Angielskie:
+#### Darmowe źródła online
+
+* [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/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+
+#### Inne
+
+* [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/pt-br/brainfuck-pt.html.markdown b/pt-br/brainfuck-pt.html.markdown
index 72c2cf6e..c7ce55ee 100644
--- a/pt-br/brainfuck-pt.html.markdown
+++ b/pt-br/brainfuck-pt.html.markdown
@@ -5,7 +5,7 @@ contributors:
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Suzane Sant Ana", "http://github.com/suuuzi"]
-lang: pt-pt
+lang: pt-br
---
Brainfuck (em letras minúsculas, eceto no início de frases) é uma linguagem de
diff --git a/pt-br/git-pt.html.markdown b/pt-br/git-pt.html.markdown
index b8cbd0a9..981da503 100644
--- a/pt-br/git-pt.html.markdown
+++ b/pt-br/git-pt.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: git
-lang: pt-pt
+lang: pt-br
filename: LearnGit.txt
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
diff --git a/pt-br/groovy-pt.html.markdown b/pt-br/groovy-pt.html.markdown
index 885d5b27..2ec7d967 100644
--- a/pt-br/groovy-pt.html.markdown
+++ b/pt-br/groovy-pt.html.markdown
@@ -9,7 +9,7 @@ translators:
lang: pt-br
---
-Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http://groovy.codehaus.org)
+Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http://www.groovy-lang.org/)
```groovy
@@ -236,7 +236,7 @@ for ( e in map ) {
Sobrecarregamento de Operadores para uma lsita dos operadores comuns que
Grooby suporta:
- http://groovy.codehaus.org/Operator+Overloading
+ http://www.groovy-lang.org/operators.html#Operator-Overloading
Operadores Groovy úteis
*/
@@ -255,7 +255,7 @@ def nomeUsuario = usuario?.nomeUsuario
Um closure, em Grooby, é como um "bloco de código" ou um ponteiro para método.
É um pedação de código que é definido e executado em um momento posterior.
- Mais informação em: http://groovy.codehaus.org/Closures+-+Formal+Definition
+ Mais informação em: http://www.groovy-lang.org/closures.html
*/
//Exemplo:
def clos = { println "Hello World!" }
@@ -413,11 +413,11 @@ assert soma(2,5) == 7
## Referências
-[Groovy documentation](http://groovy.codehaus.org/Documentation)
+[Groovy documentation](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/)
-Junte-se a um [grupo de usuários Groovy](http://groovy.codehaus.org/User+Groups)
+Junte-se a um [grupo de usuários Groovy](http://www.groovy-lang.org/usergroups.html)
## Livro
diff --git a/pt-br/xml-pt.html.markdown b/pt-br/xml-pt.html.markdown
index 40ddbc3a..f347f8ef 100644
--- a/pt-br/xml-pt.html.markdown
+++ b/pt-br/xml-pt.html.markdown
@@ -1,8 +1,8 @@
---
language: xml
-filename: learnxml.xml
+filename: learnxml-pt.xml
contributors:
- - ["João Farias", "https://github.com/JoaoGFarias"]
+ - ["João Farias", "https://github.com/JoaoGFarias"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
@@ -130,4 +130,4 @@ com a adição de definição DTD.-->
<preco>30.00</preco>
</livro>
</livraria>
-``` \ No newline at end of file
+```
diff --git a/python.html.markdown b/python.html.markdown
index 478804cd..88e0deb1 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -46,7 +46,7 @@ to Python 2.x. For Python 3.x, take a look at the [Python 3 tutorial](http://lea
2.0 # This is a float
11.0 / 4.0 # => 2.75 ahhh...much better
-# Result of integer division truncated down both for positive and negative.
+# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
@@ -101,6 +101,8 @@ not False # => True
# Strings can be added too!
"Hello " + "world!" # => "Hello world!"
+# Strings can be added without using '+'
+"Hello " "world!" # => "Hello world!"
# ... or multiplied
"Hello" * 3 # => "HelloHelloHello"
@@ -139,12 +141,8 @@ bool("") # => False
## 2. Variables and Collections
####################################################
-# Python has a print statement, in all 2.x versions but removed from 3.
+# Python has a print statement
print "I'm Python. Nice to meet you!"
-# Python also has a print function, available in versions 2.7 and 3...
-# but for 2.7 you need to add the import (uncommented):
-# from __future__ import print_function
-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
@@ -193,14 +191,14 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4]
# Select every second entry
li[::2] # =>[1, 4]
-# Revert the list
+# Reverse a copy of 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]
-
+r
# You can add lists
li + other_li # => [1, 2, 3, 4, 5, 6]
# Note: values for li and for other_li are not modified.
@@ -314,11 +312,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."
"""
@@ -329,8 +327,8 @@ prints:
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
- # You can use % to interpolate formatted strings
- print("%s is a mammal" % animal)
+ # You can use {0} to interpolate formatted strings. (See above.)
+ print "{0} is a mammal".format(animal)
"""
"range(number)" returns a list of numbers
@@ -342,7 +340,19 @@ prints:
3
"""
for i in range(4):
- print(i)
+ print i
+
+"""
+"range(lower, upper)" returns a list of numbers
+from the lower number to the upper number
+prints:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print i
"""
While loops go until a condition is no longer met.
@@ -354,7 +364,7 @@ prints:
"""
x = 0
while x < 4:
- print(x)
+ print x
x += 1 # Shorthand for x = x + 1
# Handle exceptions with a try/except block
@@ -377,7 +387,7 @@ else: # Optional clause to the try/except block. Must follow all except blocks
# Use "def" to create new functions
def add(x, y):
- print("x is %s and y is %s" % (x, y))
+ print "x is {0} and y is {1}".format(x, y)
return x + y # Return values with a return statement
# Calling functions with parameters
@@ -406,8 +416,8 @@ 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)
@@ -429,14 +439,14 @@ def pass_all_the_args(*args, **kwargs):
print varargs(*args)
print keyword_args(**kwargs)
-# Function Scope
+# Function Scope
x = 5
def setX(num):
# Local var x not the same as global variable x
x = num # => 43
print x # => 43
-
+
def setGlobalX(num):
global x
print x # => 5
@@ -487,7 +497,7 @@ class Human(object):
# An instance method. All methods take "self" as the first argument
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{0}: {1}".format(self.name, msg)
# A class method is shared among all instances
# They are called with the calling class as the first argument
@@ -503,10 +513,10 @@ 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"
@@ -526,12 +536,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
@@ -577,7 +587,7 @@ xrange_ = xrange(1, 900000000)
# will double all numbers until a result >=30 found
for i in double_numbers(xrange_):
- print(i)
+ print i
if i >= 30:
break
@@ -606,24 +616,25 @@ def say(say_please=False):
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 :(
+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
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [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/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
### 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/python3.html.markdown b/python3.html.markdown
index 56126ad3..9d965fb1 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -39,7 +39,7 @@ Note: This article applies to Python 3 specifically. Check out [here](http://lea
# Except division which returns floats by default
35 / 5 # => 7.0
-# Result of integer division truncated down both for positive and negative.
+# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
@@ -73,8 +73,8 @@ False or True #=> True
# Note using Bool operators with ints
0 and 2 #=> 0
-5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
+0 == False #=> True
+2 == True #=> False
1 == True #=> True
# Equality is ==
@@ -101,6 +101,8 @@ False or True #=> True
# Strings can be added too! But try not to do this.
"Hello " + "world!" # => "Hello world!"
+# Strings can be added without using '+'
+"Hello " "world!" # => "Hello world!"
# A string can be treated like a list of characters
"This is a string"[0] # => 'T'
@@ -143,7 +145,7 @@ bool({}) #=> False
# Python has a print function
print("I'm Python. Nice to meet you!")
-# No need to declare variables before assigning to them.
+# No need to declare variables before assigning to them.
# Convention is to use lower_case_with_underscores
some_var = 5
some_var # => 5
@@ -184,7 +186,7 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4]
# Select every second entry
li[::2] # =>[1, 4]
-# Revert the list
+# Return a reversed copy of the list
li[::-1] # => [3, 4, 2, 1]
# Use any combination of these to make advanced slices
# li[start:end:step]
@@ -194,7 +196,7 @@ del li[2] # li is now [1, 2, 3]
# You can add lists
# Note: values for li and for other_li are not modified.
-li + other_li # => [1, 2, 3, 4, 5, 6]
+li + other_li # => [1, 2, 3, 4, 5, 6]
# Concatenate lists with "extend()"
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
@@ -211,7 +213,7 @@ tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # Raises a TypeError
-# You can do all those list thingies on tuples too
+# You can do most of the list operations on tuples too
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
@@ -233,15 +235,15 @@ 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.
-# Note - Dictionary key ordering is not guaranteed.
-# Your results might not match this exactly.
+# Get all keys as an iterable with "keys()". We need to wrap the call in list()
+# to turn it into a list. We'll talk about those later. Note - Dictionary key
+# ordering is not guaranteed. Your results might not match this exactly.
list(filled_dict.keys()) # => ["three", "two", "one"]
-# Get all values as a list with "values()". Once again we need to wrap it in list() to get it out of the iterable.
-# Note - Same as above regarding key ordering.
+# Get all values as an iterable with "values()". Once again we need to wrap it
+# in list() to get it out of the iterable. Note - Same as above regarding key
+# ordering.
list(filled_dict.values()) # => [3, 2, 1]
@@ -279,7 +281,7 @@ some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
# Can set new variables to a set
filled_set = some_set
-# Add one more item to the set
+# Add one more item to the set
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
# Do set intersection with &
@@ -326,7 +328,7 @@ for animal in ["dog", "cat", "mouse"]:
print("{} is a mammal".format(animal))
"""
-"range(number)" returns a list of numbers
+"range(number)" returns an iterable of numbers
from zero to the given number
prints:
0
@@ -338,6 +340,18 @@ for i in range(4):
print(i)
"""
+"range(lower, upper)" returns an iterable of numbers
+from the lower number to the upper number
+prints:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
While loops go until a condition is no longer met.
prints:
0
@@ -380,15 +394,15 @@ our_iterable[1] # Raises a TypeError
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"
+# We get the next object with "next()".
+next(our_iterator) #=> "one"
-# It maintains state as we call __next__.
-our_iterator.__next__() #=> "two"
-our_iterator.__next__() #=> "three"
+# It maintains state as we iterate.
+next(our_iterator) #=> "two"
+next(our_iterator) #=> "three"
# After the iterator has returned all of its data, it gives you a StopIterator Exception
-our_iterator.__next__() # Raises StopIteration
+next(our_iterator) # Raises StopIteration
# You can grab all the elements of an iterator by calling list() on it.
list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
@@ -444,14 +458,14 @@ 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)
-# Function Scope
+# Function Scope
x = 5
def setX(num):
# Local var x not the same as global variable x
x = num # => 43
print (x) # => 43
-
+
def setGlobalX(num):
global x
print (x) # => 5
@@ -498,8 +512,8 @@ class Human(object):
# Basic initializer, this is called when this class is instantiated.
# Note that the double leading and trailing underscores denote objects
# or attributes that are used by python but that live in user-controlled
- # namespaces. Methods(or objects or attributes) like: __init__, __str__,
- # __repr__ etc. are called magic methods (or sometimes called dunder methods)
+ # namespaces. Methods(or objects or attributes) like: __init__, __str__,
+ # __repr__ etc. are called magic methods (or sometimes called dunder methods)
# You should not invent such names on your own.
def __init__(self, name):
# Assign the argument to the instance's name attribute
@@ -586,7 +600,7 @@ def double_numbers(iterable):
# double_numbers.
# Note range is a generator too. Creating a list 1-900000000 would take lot of
# time to be made
-# We use a trailing underscore in variable names when we want to use a name that
+# We use a trailing underscore in variable names when we want to use a name that
# would normally collide with a python keyword
range_ = range(1, 900000000)
# will double all numbers until a result >=30 found
@@ -628,18 +642,18 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
### Free Online
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [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/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
### 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/red.html.markdown b/red.html.markdown
index 73a13606..f33060c4 100644
--- a/red.html.markdown
+++ b/red.html.markdown
@@ -212,7 +212,9 @@ 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).
+To learn more about Rebol and Red join the [chat on Gitter](https://gitter.im/red/red). 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).
+
+Browse or ask questions on [Stack Overflow](stackoverflow.com/questions/tagged/red).
Maybe you want to try Red right away? That is possible on the [try Rebol and Red site](http://tryrebol.esperconsultancy.nl).
diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown
new file mode 100644
index 00000000..21377b6c
--- /dev/null
+++ b/ru-ru/bash-ru.html.markdown
@@ -0,0 +1,284 @@
+---
+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"]
+ - ["akirahirose", "https://twitter.com/akirahirose"]
+ - ["Anton Strömkvist", "http://lutic.org/"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gregrory Kielian", "https://github.com/gskielian"]
+ - ["Etan Reisner", "https://github.com/deryni"]
+translators:
+ - ["Andrey Samsonov", "https://github.com/kryzhovnik"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+filename: LearnBash-ru.sh
+lang: ru-ru
+---
+
+Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для 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 'Это первая строка'; echo 'Это вторая строка'
+
+# Вот так объявляется переменная:
+VARIABLE="Просто строка"
+
+# но не так:
+VARIABLE = "Просто строка"
+# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
+# и выдаст ошибку, потому что не сможет найти ее.
+
+# и не так:
+VARIABLE= 'Просто строка'
+# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
+# и выдаст ошибку, потому что не сможет найти такой команды
+# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
+# но только в контексте исполнения команды 'Просто строка').
+
+# Использование переменой:
+echo $VARIABLE
+echo "$VARIABLE"
+echo '$VARIABLE'
+# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
+# пишите её имя без $. А для получения значения переменной используйте $.
+# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
+
+# Подстановка строк в переменные
+echo ${VARIABLE/Просто/A}
+# Это выражение заменит первую встреченную подстроку "Просто" на "A"
+
+# Взять подстроку из переменной
+LENGTH=7
+echo ${VARIABLE:0:LENGTH}
+# Это выражение вернет только первые 7 символов переменной VARIABLE
+
+# Значение по умолчанию
+echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
+# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
+# ноль (FOO=0) вернет 0.
+# Заметьте, что в любом случае значение самой переменной FOO не изменится.
+
+# Встроенные переменные:
+# В bash есть полезные встроенные переменные, например
+echo "Последнее возвращенное значение: $?"
+echo "PID скрипта: $$"
+echo "Количество аргументов: $#"
+echo "Аргументы скрипта: $@"
+echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
+
+# Чтение аргументов из устройста ввода:
+echo "Как Вас зовут?"
+read NAME # Обратите внимание, что нам не нужно определять новую переменную
+echo Привет, $NAME!
+
+# У нас есть обычная структура if:
+# наберите 'man test' для получения подробной информации о форматах условия
+if [ $NAME -ne $USER ]
+then
+ echo "Имя не совпадает с именем пользователя"
+else
+ echo "Имя совпадает с именем пользователя"
+fi
+
+# Также есть условное исполнение
+echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
+echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
+
+# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
+if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
+then
+ echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
+fi
+
+if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
+then
+ echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
+fi
+
+# Выражения обозначаются таким форматом:
+echo $(( 10 + 5 ))
+
+# В отличие от других языков программирования, Bash - это командная оболочка,
+# а значит, работает в контексте текущей директории.
+# Вы можете просматривать файлы и директории в текущей директории командой ls:
+ls
+
+# У этой команды есть опции:
+ls -l # Показать каждый файл и директорию на отдельной строке
+
+# Результат предыдущей команды может быть направлен на вход следующей.
+# Команда grep фильтрует ввод по шаблону.
+# Так мы можем просмотреть только *.txt файлы в текущей директории:
+ls -l | grep "\.txt"
+
+# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
+# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
+# перезаписать hello.py следующим строками (до строки "EOF"):
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Запуск hello.py с разными вариантами перенаправления потоков
+# стандартных ввода, вывода и ошибок:
+python hello.py < "input.in"
+python hello.py > "output.out"
+python hello.py 2> "error.err"
+python hello.py > "output-and-error.log" 2>&1
+python hello.py > /dev/null 2>&1
+# Поток ошибок перезапишет файл, если этот файл существует,
+# поэтому, если вы хотите дописывать файл, используйте ">>":
+python hello.py >> "output.out" 2>> "error.err"
+
+# Переписать output.txt, дописать error.err и сосчитать строки:
+info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
+wc -l output.out error.err
+
+# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
+echo <(echo "#helloworld")
+
+# Перезаписать output.txt строкой "#helloworld":
+cat > output.out <(echo "#helloworld")
+echo "#helloworld" > output.out
+echo "#helloworld" | cat > output.out
+echo "#helloworld" | tee output.out >/dev/null
+
+# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
+rm -v output.out error.err output-and-error.log
+
+# Команды могут быть подставлены в строку с помощью $( ):
+# следующие команды выводят число файлов и директорий в текущей директории.
+echo "Здесь $(ls | wc -l) элементов."
+
+# То же самое можно сделать с использованием обратных кавычек,
+# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
+echo "Здесь `ls | wc -l` элементов."
+
+# В Bash есть структура case, которая похожа на switch в Java и C++:
+case "$VARIABLE" in
+ # Перечислите шаблоны для условий, которые хотите отловить
+ 0) echo "Тут ноль.";;
+ 1) echo "Тут один.";;
+ *) echo "Это не пустое значение.";;
+esac
+
+# Цикл for перебирает элементы переданные в аргументе:
+# Содержимое $VARIABLE будет напечатано три раза.
+for VARIABLE in {1..3}
+do
+ echo "$VARIABLE"
+done
+
+# Или с использованием "традиционного" синтаксиса цикла for:
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+done
+
+# Цикл for можно использовать для действий с файлами.
+# Запустим команду 'cat' для файлов file1 и file2
+for VARIABLE in file1 file2
+do
+ cat "$VARIABLE"
+done
+
+# ... или выводом из команд
+# Запустим cat для вывода из ls.
+for OUTPUT in $(ls)
+do
+ cat "$OUTPUT"
+done
+
+# Цикл while:
+while [ true ]
+do
+ echo "тело цикла здесь..."
+ break
+done
+
+# Вы можете определять функции
+# Определение:
+function foo ()
+{
+ echo "Аргументы работают также, как аргументы скрипта: $@"
+ echo "и: $1 $2..."
+ echo "Это функция"
+ return 0
+}
+
+# или просто
+bar ()
+{
+ echo "Другой способ определить функцию!"
+ return 0
+}
+
+# Вызов функции
+foo "Мое имя" $NAME
+
+# Есть много полезных команд, которые нужно знать:
+# напечатать последние 10 строк файла file.txt
+tail -n 10 file.txt
+# напечатать первые 10 строк файла file.txt
+head -n 10 file.txt
+# отсортировать строки file.txt
+sort file.txt
+# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
+uniq -d file.txt
+# напечатать только первую колонку перед символом ','
+cut -d ',' -f 1 file.txt
+# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
+sed -i 's/okay/great/g' file.txt
+# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
+# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
+grep "^foo.*bar$" file.txt
+# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
+grep -c "^foo.*bar$" file.txt
+# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
+fgrep "^foo.*bar$" file.txt
+
+# Читайте встроенную документацию оболочки Bash командой 'help':
+help
+help help
+help for
+help return
+help source
+help .
+
+# Читайте Bash man-документацию
+apropos bash
+man 1 bash
+man bash
+
+# Читайте документацию info (? для помощи)
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+
+# Читайте bash info документацию:
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
+```
diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown
index e7398c88..79844565 100644
--- a/ru-ru/javascript-ru.html.markdown
+++ b/ru-ru/javascript-ru.html.markdown
@@ -22,8 +22,8 @@ Google Chrome, становится все более популярной.
```js
// Си-подобные комментарии. Однострочные комментарии начинаются с двух символов слэш,
-/* а многострочные комментарии начинаются с звёздочка-слэш
- и заканчиваются символами слэш-звёздочка */
+/* а многострочные комментарии начинаются с последовательности слэш-звёздочка
+ и заканчиваются символами звёздочка-слэш */
// Инструкции могут заканчиваться точкой с запятой ;
doStuff();
diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown
index 3246de82..ddff2e5c 100644
--- a/ru-ru/objective-c-ru.html.markdown
+++ b/ru-ru/objective-c-ru.html.markdown
@@ -1,106 +1,171 @@
---
language: Objective-C
-filename: LearnObjectiveC.m
+filename: LearnObjectiveC-ru.m
contributors:
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
- ["Yannick Loriot", "https://github.com/YannickL"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
translators:
- ["Evlogy Sutormin", "http://evlogii.com"]
+ - ["Dmitry Bessonov", "https://github.com/TheDmitry"]
lang: ru-ru
---
-Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple,
-построенный на основе языка Си и парадигм Smalltalk.
-В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения.
+Objective-C — основной язык программирования, используемый корпорацией Apple
+для операционных систем OS X и iOS и их соответствующих фреймворках Cocoa и
+Cocoa Touch.
+Он является объектно-ориентированным языком программирования общего назначения,
+который добавляет обмен сообщениями в Smalltalk-стиле к языку программирования C.
```objective_c
-// Однострочный комментарий
+// Однострочные комментарии начинаются с //
/*
-Многострочный
-комментарий
+Так выглядят многострочные комментарии
*/
-// Импорт файлов фреймворка Foundation с помощью #import
+// Импорт заголовочных файлов фреймворка Foundation с помощью #import
+// Используйте <>, чтобы импортировать глобальные файлы (обычно фреймворки)
+// Используйте "", чтобы импортировать локальные файлы (из проекта)
#import <Foundation/Foundation.h>
#import "MyClass.h"
-// Точка входа в программу это функция main,
-// которая возвращает целый тип integer
+// Если вы включили модули для iOS >= 7.0 или OS X >= 10.9 проектов в
+// Xcode 5, вы можете импортировать фреймворки подобным образом:
+@import Foundation;
+
+// Точка входа в программу - это функция main,
+// которая возвращает целый тип
int main (int argc, const char * argv[])
{
- // Создание autorelease pool для управления памятью
+ // Создание autorelease pool для управления памятью в программе
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
+ // В место этого воспользуйтесь @autoreleasepool, если вы используете
+ // автоматический подсчет ссылок (ARC)
+ @autoreleasepool {
+
// Используйте NSLog для печати в консоль
- NSLog(@"Hello World!"); // Напечатает строку "Hello World!"
+ NSLog(@"Привет Мир!"); // Напечатает строку "Привет Мир!"
///////////////////////////////////////
// Типы и переменные
///////////////////////////////////////
- // Простое объявление
+ // Объявление простых типов
int myPrimitive1 = 1;
long myPrimitive2 = 234554664565;
+ // Объявление объектов
// Помещайте * в начало названия объекта для строго типизированного объявления
MyClass *myObject1 = nil; // Строгая типизация
id myObject2 = nil; // Слабая типизация
-
- NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
// %@ – это объект
- // 'description' это общий для всех объектов метод вывода данных
+ // 'description' - это общий для всех объектов метод вывода данных
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
// Строка
- NSString *worldString = @"World";
- NSLog(@"Hello %@!", worldString); // напечатает "Hello World!"
+ NSString *worldString = @"Мир";
+ NSLog(@"Привет %@!", worldString); // напечатает "Привет Мир!"
+ // NSMutableString - это изменяемая версия NSString-объекта
+ NSMutableString *mutableString = [NSMutableString stringWithString:@"Привет"];
+ [mutableString appendString:@" Мир!"];
+ NSLog(@"%@", mutableString); // напечатает => "Привет Мир!"
// Символьные литералы
NSNumber *theLetterZNumber = @'Z';
- char theLetterZ = [theLetterZNumber charValue];
+ char theLetterZ = [theLetterZNumber charValue]; // или 'Z'
NSLog(@"%c", theLetterZ);
- // Целочисленный литералы
+ // Целочисленные литералы
NSNumber *fortyTwoNumber = @42;
- int fortyTwo = [fortyTwoNumber intValue];
+ int fortyTwo = [fortyTwoNumber intValue]; // или '42'
NSLog(@"%i", fortyTwo);
// Беззнаковый целочисленный литерал
NSNumber *fortyTwoUnsignedNumber = @42U;
- unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // или 42
NSLog(@"%u", fortyTwoUnsigned);
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
- short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue]; // или 42
NSLog(@"%hi", fortyTwoShort);
+ NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41];
+ unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // или 41
+ NSLog(@"%u", fortyOneUnsigned);
+
NSNumber *fortyTwoLongNumber = @42L;
- long fortyTwoLong = [fortyTwoLongNumber longValue];
+ long fortyTwoLong = [fortyTwoLongNumber longValue]; // или 42
NSLog(@"%li", fortyTwoLong);
+
+ NSNumber *fiftyThreeLongNumber = @53L;
+ unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // или 53
+ NSLog(@"%lu", fiftyThreeUnsigned);
// Вещественный литерал
NSNumber *piFloatNumber = @3.141592654F;
- float piFloat = [piFloatNumber floatValue];
- NSLog(@"%f", piFloat);
+ float piFloat = [piFloatNumber floatValue]; // или 3.141592654f
+ NSLog(@"%f", piFloat); // напечатает 3.141592654
+ NSLog(@"%5.2f", piFloat); // напечатает " 3.14"
NSNumber *piDoubleNumber = @3.1415926535;
- double piDouble = [piDoubleNumber doubleValue];
+ double piDouble = [piDoubleNumber doubleValue]; // или 3.1415926535
NSLog(@"%f", piDouble);
-
+ NSLog(@"%4.2f", piDouble); // напечатает "3.14"
+
+ // NSDecimalNumber - это класс с фиксированной точкой, который является
+ // более точным, чем float или double
+ NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"];
+ NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"];
+ // NSDecimalNumber не способен использовать стандартные +, -, *, / операторы,
+ // поэтому он предоставляет свои собственные:
+ [oneDecNum decimalNumberByAdding:twoDecNum];
+ [oneDecNum decimalNumberBySubtracting:twoDecNum];
+ [oneDecNum decimalNumberByMultiplyingBy:twoDecNum];
+ [oneDecNum decimalNumberByDividingBy:twoDecNum];
+ NSLog(@"%@", oneDecNum); // напечатает "10.99", т.к. NSDecimalNumber - изменяемый
+
// BOOL (булевый) литерал
NSNumber *yesNumber = @YES;
NSNumber *noNumber = @NO;
-
+ // или
+ BOOL yesBool = YES;
+ BOOL noBool = NO;
+ NSLog(@"%i", yesBool); // напечатает 1
+
// Массив
+ // Может содержать различные типы данных, но должен быть объектом Objective-C
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
- NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
+ NSLog(@"Третье число = %@", thirdNumber); // Напечатает "Третье число = 3"
+ // NSMutableArray - это изменяемая версия NSArray, допускающая вам изменять
+ // элементы в массиве и расширять или сокращать массив.
+ // Удобный, но не эффективный как NSArray.
+ NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
+ [mutableArray addObject:@"Привет"];
+ [mutableArray addObject:@"Мир"];
+ [mutableArray removeObjectAtIndex:0];
+ NSLog(@"%@", [mutableArray objectAtIndex:0]); // напечатает "Мир"
// Словарь
- NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
- NSObject *valueObject = aDictionary[@"A Key"];
- NSLog(@"Object = %@", valueObject); // Напечатает "Object = (null)"
-
+ NSDictionary *aDictionary = @{ @"ключ1" : @"значение1", @"ключ2" : @"значение2" };
+ NSObject *valueObject = aDictionary[@"Ключ"];
+ NSLog(@"Объект = %@", valueObject); // Напечатает "Объект = (null)"
+ // NSMutableDictionary тоже доступен, как изменяемый словарь
+ NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+ [mutableDictionary setObject:@"значение1" forKey:@"ключ1"];
+ [mutableDictionary setObject:@"значение2" forKey:@"ключ2"];
+ [mutableDictionary removeObjectForKey:@"ключ1"];
+
+ // Множество
+ NSSet *set = [NSSet setWithObjects:@"Привет", @"Привет", @"Мир", nil];
+ NSLog(@"%@", set); // напечатает {(Hello, World)} (порядок может отличаться)
+ // NSMutableSet тоже доступен, как изменяемое множество
+ NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2];
+ [mutableSet addObject:@"Привет"];
+ [mutableSet addObject:@"Привет"];
+ NSLog(@"%@", mutableSet); // напечатает => {(Привет)}
+
///////////////////////////////////////
// Операторы
///////////////////////////////////////
@@ -124,13 +189,13 @@ int main (int argc, const char * argv[])
// Условный оператор
if (NO)
{
- NSLog(@"I am never run");
+ NSLog(@"Я никогда не выполнюсь");
} else if (0)
{
- NSLog(@"I am also never run");
+ NSLog(@"Я тоже никогда не выполнюсь");
} else
{
- NSLog(@"I print");
+ NSLog(@"Я напечатаюсь");
}
// Ветвление с множественным выбором
@@ -138,15 +203,15 @@ int main (int argc, const char * argv[])
{
case 0:
{
- NSLog(@"I am never run");
+ NSLog(@"Я никогда не выполнюсь");
} break;
case 1:
{
- NSLog(@"I am also never run");
+ NSLog(@"Я тоже никогда не выполнюсь");
} break;
default:
{
- NSLog(@"I print");
+ NSLog(@"Я напечатаюсь");
} break;
}
@@ -170,7 +235,7 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
- // // Цикл просмотра
+ // Цикл просмотра
NSArray *values = @[@0, @1, @2, @3];
for (NSNumber *value in values)
{
@@ -180,20 +245,32 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
+ // Цикл for для объектов. Может использоваться с любым объектом Objective-C
+ for (id item in values) {
+ NSLog(@"%@,", item);
+ } // напечатает => "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
// Обработка исключений
@try
{
// Ваше исключение здесь
@throw [NSException exceptionWithName:@"FileNotFoundException"
- reason:@"File Not Found on System" userInfo:nil];
+ reason:@"Файл не найден в системе" userInfo:nil];
} @catch (NSException * e)
{
- NSLog(@"Exception: %@", e);
+ NSLog(@"Исключение: %@", e);
} @finally
{
- NSLog(@"Finally");
- } // => напечатает "Exception: File Not Found on System"
- // "Finally"
+ NSLog(@"В конце отводится время для очистки.");
+ } // => напечатает "Исключение: Файл не найден в системе"
+ // "В конце отводится время для очистки."
+
+ // NSError - это полезные объекты для аргументов функции, чтобы заполнить их
+ // пользовательскими ошибками.
+ NSError *error = [NSError errorWithDomain:@"Неправильный эл. адрес." code:4 userInfo:nil];
///////////////////////////////////////
// Объекты
@@ -203,13 +280,16 @@ int main (int argc, const char * argv[])
// Объект не является полнофункциональным пока обе части не выполнятся.
MyClass *myObject = [[MyClass alloc] init];
- // В Objective-C можель ООП базируется на передаче сообщений.
+ // В Objective-C модель ООП базируется на передаче сообщений.
// В Objective-C Вы не просто вызваете метод; вы посылаете сообщение.
- [myObject instanceMethodWithParameter:@"Steve Jobs"];
+ [myObject instanceMethodWithParameter:@"Стив Джобс"];
// Очищайте память, перед завершением работы программы.
[pool drain];
+ // Конец @autoreleasepool
+ }
+
// Конец программы.
return 0;
}
@@ -222,63 +302,144 @@ int main (int argc, const char * argv[])
// Синтаксис объявления:
// @interface ИмяКласса : ИмяКлассаРодителя <ИмплементируемыеПротоколы>
// {
-// Объявление переменных;
+// тип имя; <= Объявление переменных;
// }
+// @property тип имя; <= объявление свойств
// -/+ (тип) Объявление метода(ов).
// @end
-
-
-@interface MyClass : NSObject <MyProtocol>
+@interface MyClass : NSObject <MyProtocol> // NSObject - это базовый класс в Objective-C.
{
- int count;
- id data;
+ // Объявления экземпляров переменных (может существовать в файлах интерфейса или реализвации)
+ int count; // По умолчанию защищенный доступ.
+ @private id data; // Приватный доступ (Намного удобнее объявлять в файле реализации)
NSString *name;
}
-// При объявлении свойств сразу генерируются геттер и сеттер
-@property int count;
-@property (copy) NSString *name; // Скопировать объект в ходе присвоения.
-@property (readonly) id data; // Генерация только геттера
+// Удобное обозначение для переменных с открытым (public) доступом
+// автоматически генерируется сеттер-метод
+// По умолчанию название сеттер-метода начинается с 'set' с последующим именем
+// переменной из @property
+@property int propInt; // Имя сеттер-метода = 'setPropInt'
+@property (copy) id copyId; // (copy) => Скопировать объект в ходе присвоения.
+// (readonly) => Не позволяет установить значение вне @interface
+@property (readonly) NSString *roString; // Используйте @synthesize
+ // в @implementation, чтобы создать аксессор
+// Вы можете настроить геттер и сеттер имена вместо используемого 'set'-имени по умолчанию:
+@property (getter=lengthGet, setter=lengthSet:) int length;
// Методы
-+/- (return type)methodSignature:(Parameter Type *)parameterName;
++/- (возвращаемый тип)сигнатураМетода:(Параметр типа *)имяПараметра;
// + для методов класса
+ (NSString *)classMethod;
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight;
-// - для метода объекта
+// - для методов объекта
- (NSString *)instanceMethodWithParameter:(NSString *)string;
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
-@end
+// Методы-конструктор с аргументом:
+- (id)initWithDistance:(int)defaultDistance;
+// В Objective-C имена методов очень описательные. Всегда имена методов соответствуют своим аргументам
+
+@end // Устанавливает конец интерфейса (interface)
+
+
+// Чтобы обратиться к открытым (public) переменным из файла реализации, @property генерирует сеттер-метод
+// автоматически. Название метода - это 'set' с последующим именем переменной из @property:
+MyClass *myClass = [[MyClass alloc] init]; // создает экземпляр объекта класса MyClass
+[myClass setCount:10];
+NSLog(@"%d", [myClass count]); // напечатает => 10
+// Или используйте свой геттер и сеттер методы, которые определены в @interface:
+[myClass lengthSet:32];
+NSLog(@"%i", [myClass lengthGet]); // напечатает => 32
+// Для удобства вы можете использовать точечную нотацию,
+// чтобы установить и получить доступ к переменным объекта:
+myClass.count = 45;
+NSLog(@"%i", myClass.count); // напечатает => 45
+
+// Вызов методов класса:
+NSString *classMethodString = [MyClass classMethod];
+MyClass *classFromName = [MyClass myClassFromName:@"Привет"];
+
+// Вызов методов экземпляра:
+MyClass *myClass = [[MyClass alloc] init]; // Создает экземпляр объекта MyClass
+NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Привет"];
+
+// Селекторы
+// Это способ динамически представить методы. Используйте для вызова методов класса, передайте методы
+// через функции, чтобы сказать другим классам, что они должны вызвать их и сохранить методы
+// как переменные
+// SEL - это тип данных. @selector() вернет селектор из предоставленного имени метода
+// methodAParameterAsString:andAParameterAsNumber: - это название метода в MyClass
+SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
+if ([myClass respondsToSelector:selectorVar]) { // Проверяет содержит ли класс метод
+ // Необходимо установить все аргументы метода в один объект, что отправить его в performSelector-функцию
+ NSArray *arguments = [NSArray arrayWithObjects:@"Привет", @4, nil];
+ [myClass performSelector:selectorVar withObject:arguments]; // Вызывает метод
+} else {
+ // NSStringFromSelector() вернет NSString название метода полученного селектором
+ NSLog(@"MyClass не содержит метод: %@", NSStringFromSelector(selectedVar));
+}
// Имплементируйте методы в файле МойКласс.m:
+@implementation MyClass {
+ long distance; // Переменная экземпляра с закрытым (private) доступом
+ NSNumber height;
+}
-@implementation MyClass
+// 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;
+ }
+}
// Вызывается при высвобождении памяти под объектом
- (void)dealloc
{
+ [height release]; // Если не используется ARC, убедитесь в освобождении переменных объекта класса
+ [super dealloc]; // and call parent class dealloc
}
-// Конструкторы – это способ осздания объектов класса.
-// Это обычный конструктор вызываемый при создании объекта клсааа.
+// Конструкторы – это способ создания объектов класса.
+// Это конструктор по умолчанию, который вызывается, когда объект инициализируется.
- (id)init
{
- if ((self = [super init]))
+ if ((self = [super init])) // 'super' используется для того, чтобы обратиться к методам родительского класса
{
- self.count = 1;
+ self.count = 1; // 'self' используется для вызова самого себя
}
return self;
}
+// Можно создать конструкторы, которые содержат аргументы:
+- (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";
+ return @"Новая строка";
}
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
@@ -286,23 +447,364 @@ int main (int argc, const char * argv[])
return @42;
}
+// Objective-C не содержит объявление приватных методов, но вы можете имитировать их.
+// Чтобы сымитировать приватный метод, создайте метод в @implementation, но не в @interface.
+- (NSNumber *)secretPrivateMethod {
+ return @72;
+}
+[self secretPrivateMethod]; // Вызывает приватный метод
+
// Методы объявленные в МyProtocol (см. далее)
- (void)myProtocolMethod
{
- // имплементация
+ // операторы
}
+@end // Устанавливает конец реализации (implementation)
+
+///////////////////////////////////////
+// Категории
+///////////////////////////////////////
+// Категория - это группа методов предназначенные для того, чтобы расширить класс. Они позволяют вам добавить новые методы
+// к существующему классу для организационных целей. Это не стоит путать с подклассами.
+// Подклассы предназначены для ИЗМЕНЕНИЯ функциональности объекта пока как категории ДОБАВЛЯЮТ
+// функциональность в объект.
+// Категории позволяют вам:
+// -- Добавлять методы в существующий класс для организационных целей.
+// -- Допускает вам расширять объекты Objective-C классов (напр.: NSString) добавить ваши собственные методы.
+// -- Добавляет возможность создать защищенные и закрытые методы классов.
+// ПРИМЕЧАНИЕ: Не переопределяйте методы базового класса в категории даже если у вас есть возможность это сделать
+// to. Переопределение методов может привести к ошибкам компиляции позднее между различными категориями и это
+// нарушает цель категорий, чтобы добавлять только функциональность. Вместо этого подклассы переопределяют методы.
+
+// Здесь простой базовый класс Car.
+@interface Car : NSObject
+
+@property NSString *make;
+@property NSString *color;
+
+- (void)turnOn;
+- (void)accelerate;
+
@end
-/*
- * Протокол объявляет методы которые должны быть имплементированы
- * Протокол не является классом. Он просто определяет интерфейс,
- * который должен быть имплементирован.
- */
+// И реализация базового класса Car:
+#import "Car.h"
+
+@implementation Car
+
+@synthesize make = _make;
+@synthesize color = _color;
+
+- (void)turnOn {
+ NSLog(@"Машина заведена.");
+}
+- (void)accelerate {
+ NSLog(@"Ускорение.");
+}
-@protocol MyProtocol
- - (void)myProtocolMethod;
@end
+
+// Теперь, если мы хотели создать грузовой объект, мы должны вместо создания подкласса класса Car, как это будет
+// изменять функциональность Car чтобы вести себя подобно грузовику. Но давайте посмотрим, если мы хотим только добавить
+// функциональность в существующий Car. Хороший пример должен быть чистить автомобиль. Итак мы создадим
+// категорию для добавления его очистительных методов:
+// @interface ИмяФайла: Car+Clean.h (ИмяБазовогоКласса+ИмяКатегории.h)
+#import "Car.h" // Убедитесь в том, что базовый класс импортирован для расширения.
+
+@interface Car (Clean) // Имя категории внутри (), следующие после имени базового класса.
+
+- (void)washWindows; // Названия новых методов, которые мы добавляем в наш объект Car.
+- (void)wax;
+
+@end
+
+// @implementation имя файла: Car+Clean.m (ИмяБазовогоКласса+ИмяКатегории.m)
+#import "Car+Clean.h" // Импортируйте Очистку файл @interface категории.
+
+@implementation Car (Clean)
+
+- (void)washWindows {
+ NSLog(@"Окна промыли.");
+}
+- (void)wax {
+ NSLog(@"Воском натерли.");
+}
+
+@end
+
+// Любой экземпляр объекта Car имеет возможность воспользоваться категорией. Все, что нужно сделать, это импортировать ее:
+#import "Car+Clean.h" // Импортировать как множество различных категорий, как вы хотите использовать.
+#import "Car.h" // Кроме того, необходимо импортировать базовый класс для использования его оригинальные функциональные возможности.
+
+int main (int argc, const char * argv[]) {
+ @autoreleasepool {
+ Car *mustang = [[Car alloc] init];
+ mustang.color = @"Красный";
+ mustang.make = @"Форд";
+
+ [mustang turnOn]; // Используйте методы из базового класса Car.
+ [mustang washWindows]; // Используйте методы категории Clean из класса Car.
+ }
+ return 0;
+}
+
+// Objective-C не поддерживает объявление защищенных методов, но вы можете имитировать их.
+// Создайте категорию, содержащую все защищенные методы, затем импортируйте ее только в
+// @implementation-файле класса, относящегося к классу Car:
+@interface Car (Protected) // Наименование категории с помощью 'Protected'
+// дает знать, что методы защищенные.
+
+- (void)lockCar; // Здесь перечисляются методы, которые должны быть созданы
+// только с помощью объектов класса Car.
+
+@end
+// Чтобы воспользоваться защищенными методами, импортируйте категорию, затем реализуйте методы:
+#import "Car+Protected.h" // Запомните, делайте импорт только в файле с @implementation.
+
+@implementation Car
+
+- (void)lockCar {
+ NSLog(@"Машина закрыта."); // Экземпляры класса Car не могут использовать
+// метод lockCar, потому что он объявлен не в @interface.
+}
+
+@end
+
+///////////////////////////////////////
+// Расширения
+///////////////////////////////////////
+// Расширения позволяют вам переопределять атрибуты свойств и методов
+// с открытым доступом в @interface.
+// @interface имя файла: Shape.h
+@interface Shape : NSObject // Расширение базового класса Shape переопределяет
+ // свои поля ниже.
+
+@property (readonly) NSNumber *numOfSides;
+
+- (int)getNumOfSides;
+
+@end
+// Вы можете переопределить numOfSides-переменную или getNumOfSides-метод
+// Внесение изменений с помощью расширения делается следующим образом:
+// @implementation имя файла: Shape.m
+#import "Shape.h"
+// Расширения "живут" в том же файле, где и @implementation класса.
+@interface Shape () // После имени базового класса скобки () объявляют расширение.
+
+@property (copy) NSNumber *numOfSides; // Делает numOfSides-свойство
+ // копирующим (copy) вместо свойства только для чтения (readonly).
+-(NSNumber)getNumOfSides; // Изменяет метод getNumOfSides так,
+ // чтобы он возвращал объект NSNumber вместо типа int.
+-(void)privateMethod; // Вы также можете создать новый закрытый метод
+ // внутри расширения.
+
+@end
+// Главный @implementation:
+@implementation Shape
+
+@synthesize numOfSides = _numOfSides;
+
+-(NSNumber)getNumOfSides { // Все операторы внутри расширения
+ // должны быть в @implementation.
+ return _numOfSides;
+}
+-(void)privateMethod {
+ NSLog(@"Закрытый метод созданный с помощью расширения.");
+ NSLog(@"Экземпляр Shape не может вызвать этот метод.");
+}
+
+@end
+
+///////////////////////////////////////
+// Протоколы
+///////////////////////////////////////
+// Протокол объявляет методы, которые могут быть реализованы с помощью
+// любого класса. Протоколы сами по себе не являются классами. Они просто
+// определяют интерфейс, который должен быть реализован другими объектами.
+// @protocol имя файла: "CarUtilities.h"
+@protocol CarUtilities <NSObject> // <NSObject> => Имя другого протокола,
+// который включен в этот протокол.
+ @property BOOL engineOn; // Адаптирующий класс должен определить
+// все @synthesize для @property и
+ - (void)turnOnEngine; // определить все методы.
+@end
+// Ниже пример класса, реализующий протокол.
+#import "CarUtilities.h" // Импорт файла с @protocol.
+
+@interface Car : NSObject <CarUtilities> // Внутри <> имя протокола
+// Здесь вам не нужно указывать @property или имена методов для CarUtilities.
+// Они нужны только для @implementation.
+- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // Вы также можете
+// указать тип протоколов.
+@end
+// В @implementation нужно реализовать все @property и методы для протокола.
+@implementation Car : NSObject <CarUtilities>
+
+@synthesize engineOn = _engineOn; // Создайте @synthesize-оператор
+// для "@property engineOn".
+
+- (void)turnOnEngine { // Реализуйте turnOnEngine как вам угодно. Протоколы
+// не определят,
+ _engineOn = YES; // как вам реализовать метод, он только требует,
+// чтобы вы реализовали его.
+}
+// Вы можете использовать протокол как данные, если вы знаете, что он реализует
+// методы и переменные.
+- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
+ [objectOfSomeKind engineOn]; // У вас есть доступ к переменным объекта
+ [objectOfSomeKind turnOnEngine]; // и методам.
+ [objectOfSomeKind engineOn]; // Может или не может быть значение YES. Класс
+// реализует как нужно.
+}
+
+@end
+// Экземпляры класса Car сейчас имеют доступ к протоколу.
+Car *carInstance = [[Car alloc] init];
+[carInstance setEngineOn:NO];
+[carInstance turnOnEngine];
+if ([carInstance engineOn]) {
+ NSLog(@"Двигатель запущен."); // напечатает => "Двигатель запущен."
+}
+// Убедитись в том, что объект типа 'id' реализует протокол перед вызовом методов протокола:
+if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"Не работает, т.к. класс MyClass не реализует протокол CarUtilities.");
+} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"Работает как класс Car, который реализует протокол CarUtilities.");
+}
+// Категории тоже могут реализовать протоколы:
+// @interface Car (CarCategory) <CarUtilities>
+// Вы можете реализовать много протоколов:
+// @interface Car : NSObject <CarUtilities, CarCleaning>
+// ЗАМЕЧАНИЕ: Если два или более протоколов полагаются друг на друга,
+// убедитесь, что они ранее объявлены:
+#import "Brother.h"
+
+@protocol Brother; // Оператор раннего объявления. Без него компилятор
+// выдаст ошибку.
+
+@protocol Sister <NSObject>
+
+- (void)beNiceToBrother:(id <Brother>)brother;
+
+@end
+
+// Рассмотрите проблему, где протокол Sister полагается на протокол Brother,
+// а Brother полагается на Sister.
+#import "Sister.h"
+
+@protocol Sister; // Эти строки предотвращают рекурсию, решая этим проблему.
+
+@protocol Brother <NSObject>
+
+- (void)beNiceToSister:(id <Sister>)sister;
+
+@end
+
+
+///////////////////////////////////////
+// Блоки
+///////////////////////////////////////
+// Блоки - это операторы кода, наподобие функции, которую возможно использовать
+// как данные.
+// Ниже простой блок с целочисленным аргументом, и возвращает аргумент плюс 4.
+int (^addUp)(int n); // Объявите переменную, чтобы сохранить блок.
+void (^noParameterBlockVar)(void); // Пример объявления блока-переменной
+// без аргументов.
+// Блоки имею доступ к переменным в той же области видимости. Но переменные
+// будут только для чтения, и значения переданных в блок станут значением
+// переменной, когда блок создастся.
+int outsideVar = 17; // Если мы редактируем outsideVar после объявления addUp,
+// outsideVar остается равным 17.
+__block long mutableVar = 3; // __block делают переменные перезаписываемыми
+// в блоках, в отличие от outsideVar.
+addUp = ^(int n) { // Удалите (int n) в блоке, чтобы не принимать
+// какие-либо параметры.
+ NSLog(@"Вы можете иметь столько строк в блоке, сколько вы хотели.");
+ NSSet *blockSet; // Также вы можете объявить локальные переменные.
+ mutableVar = 32; // Присвоить новое значение к __block-переменной.
+ return n + outsideVar; // Необязательный оператор возврата.
+}
+int addUp = add(10 + 16); // Вызывает блок кода с аргументами.
+// Блоки часто используются как аргументы функции, чтобы позже их вызвать, или
+// как функции обратного вызова (callbacks).
+@implementation BlockExample : NSObject
+
+- (void)runBlock:(void (^)(NSString))block {
+ NSLog(@"В аргументе блок ничего не возвращает и принимает NSString-объект.");
+ block(@"Аргумент передан блоку на исполнение."); // Вызов блока.
+}
+
+@end
+
+
+///////////////////////////////////////
+// Управление памятью
+///////////////////////////////////////
+/*
+Для каждого объекта, используемого в приложении, должна быть выделена память
+для таких объектов. Когда приложение прекращает использование объекта, память
+должна быть освобождена, чтобы гарантировать эффективность приложения.
+Objective-C не использует сборщик мусора, а вместо этого применяет подсчет ссылок.
+Пока существует по крайней мере одна ссылка на объект (также называется
+"владение" объектом), то объект будет доступен к использованию (еще известно
+как "право владения").
+
+Когда экземпляр владеет объектом, его ссылка увеличивается на один. Когда
+объекта освобождается, счетчик ссылки уменьшается на один. Когда счетчик ссылки
+равен нулю, объект удаляется из памяти.
+
+Над всеми объектами взаимодействуют, следуя паттерну:
+(1) создание объекта, (2) использование объекта, (3) затем освобождение объекта из памяти.
+*/
+
+MyClass *classVar = [MyClass alloc]; // 'alloc' устанавливает счетчик ссылки
+// объекта classVar на 1 и возвращает указатель на объект.
+[classVar release]; // Уменьшает счетчик ссылки объекта classVar
+// 'retain' заявляет право собственности на существующий экземпляр объекта
+// и увеличивает счетчик ссылки. Затем вернет указатель на объект.
+MyClass *newVar = [classVar retain]; // Если classVar освободится, объект
+// останется в памяти, потому что newVar - владелец
+[classVar autorelease]; // Удалит право на владение объектом
+// в конце @autoreleasepool блока. Вернет указатель на объект.
+
+// @property может использовать 'retain' и 'assign' тоже для маленького
+// удобного определения
+@property (retain) MyClass *instance; // Освободит старое значение и сохранит
+// одно новое (строгая ссылка)
+@property (assign) NSSet *set; // Укажет на новое значение
+// без сохранения/освобождения старого значения (слабая ссылка)
+
+// Автоматический подсчет ссылок (ARC)
+// Управление памятью может быть трудным, поэтому в Xcode 4.2 и iOS 4 введен
+// автоматический подсчет ссылок (ARC).
+// ARC - это особенность компилятора, который помещает "retain", "release"
+// и "autorelease" автоматически за вас тогда, когда используется ARC,
+// вам не нужно больше обращаться к "retain", "relase" или "autorelease"
+MyClass *arcMyClass = [[MyClass alloc] init];
+// ... код, использующий объект arcMyClass
+// Без ARC, вам нужно было бы вызвать: [arcMyClass release] после того, как вы
+// завершите работу с объектом arcMyClass. Но с ARC,
+// теперь этого не нужно делать. Он будет помещать release-вызов за вас
+
+// Что касается 'assign' и 'retain' @property атрибутов, в ARC вы должны
+// использовать 'weak' и 'strong'
+@property (weak) MyClass *weakVar; // 'weak' не принимает право на владение
+// объектом. Если исходный счетчик ссылки экземпляра обнуляется,
+// weakVar-свойство автоматически примет значение nil,
+// во избежание падения приложения
+@property (strong) MyClass *strongVar; // 'strong' принимает право на владение
+// объектом. Гарантирует, что объект останится в памяти для использования
+
+// Для обычных переменных (не объявленных с помощью @property), используйте
+// следующий способ:
+__strong NSString *strongString; // По умолчанию. Переменная сохраняется в памяти,
+// пока она не покинет область видимости
+__weak NSSet *weakSet; // Слабая ссылка на существующий объект. Когда существующий
+// объект освобождается, weakSet принимает nil
+__unsafe_unretained NSArray *unsafeArray; // Похож на __weak, но unsafeArray
+// не принимает nil, когда существующий объект освобождается
+
```
## На почитать
diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown
index fd95c876..2a7b3f7b 100644
--- a/ru-ru/python3-ru.html.markdown
+++ b/ru-ru/python3-ru.html.markdown
@@ -593,7 +593,7 @@ def double_numbers(iterable):
range_ = range(1, 900000000)
# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(xrange_):
+for i in double_numbers(range_):
print(i)
if i >= 30:
break
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 792c9c95..66a0774d 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -79,10 +79,14 @@ true && false #=> false
true || false #=> true
!true #=> false
-# Alternate spellings of logical operators
-true and false #=> false
-true or false #=> true
-not true #=> false
+# There are alternate versions of the logical operators with much lower
+# precedence. These are meant to be used as flow-control constructs to chain
+# statements together until one of them returns true or false.
+
+# `do_something_else` only called if `do_something` succeeds.
+do_something() and do_something_else()
+# `log_error` only called if `do_something` fails.
+do_something() or log_error()
# Strings are objects
diff --git a/rust.html.markdown b/rust.html.markdown
index dcb54733..dd03acdd 100644
--- a/rust.html.markdown
+++ b/rust.html.markdown
@@ -5,15 +5,22 @@ contributors:
filename: learnrust.rs
---
-Rust is an in-development programming language developed by Mozilla Research.
-It is relatively unique among systems languages in that it can assert memory
-safety *at compile time* without resorting to garbage collection. Rust’s first
-release, 0.1, occurred in January 2012, and development moves so quickly that at
-the moment the use of stable releases is discouraged, and instead one should use
-nightly builds. On January 9 2015, Rust 1.0 Alpha was released, and the rate of
-changes to the Rust compiler that break existing code has dropped significantly
-since. However, a complete guarantee of backward compatibility will not exist
-until the final 1.0 release.
+Rust is a programming language developed by Mozilla Research.
+Rust combines low-level control over performance with high-level convenience and
+safety guarantees.
+
+It achieves these goals without requiring a garbage collector or runtime, making
+it possible to use Rust libraries as a "drop-in replacement" for C.
+
+Rust’s first release, 0.1, occurred in January 2012, and for 3 years development
+moved so quickly that until recently the use of stable releases was discouraged
+and instead the general advise was to use nightly builds.
+
+On May 15th 2015, Rust 1.0 was released with a complete guarantee of backward
+compatibility. Improvements to compile times and other aspects of the compiler are
+currently available in the nightly builds. Rust has adopted a train-based release
+model with regular releases every six weeks. Rust 1.1 beta was made available at
+the same time of the release of Rust 1.0.
Although Rust is a relatively low-level language, Rust has some functional
concepts that are generally found in higher-level languages. This makes
@@ -77,7 +84,7 @@ fn main() {
// This is basically an immutable pointer to a string – it doesn’t
// actually contain the contents of a string, just a pointer to
// something that does (in this case, `s`)
- let s_slice: &str = &*s;
+ let s_slice: &str = &s;
println!("{} {}", s, s_slice); // hello world hello world
@@ -92,7 +99,7 @@ fn main() {
// A slice – an immutable view into a vector or array
// This is much like a string slice, but for vectors
- let slice: &[i32] = &*vector;
+ let slice: &[i32] = &vector;
// Use `{:?}` to print something debug-style
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
diff --git a/scala.html.markdown b/scala.html.markdown
index ed1ddabb..c482752d 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
- ["Geoff Liu", "http://geoffliu.me"]
+ - ["Ha-Duong Nguyen", "http://reference-error.org"]
filename: learn.scala
---
@@ -16,15 +17,16 @@ Scala - the scalable language
Set yourself up:
1) Download Scala - http://www.scala-lang.org/downloads
- 2) unzip/untar in your favourite location and put the bin subdir on the path
- 3) Start a scala REPL by typing scala. You should see the prompt:
+ 2) Unzip/untar to your favourite location and put the bin subdir in your `PATH` environment variable
+ 3) Start a Scala REPL by running `scala`. You should see the prompt:
scala>
- This is the so called REPL (Read-Eval-Print Loop). You may type any valid
- Scala expression into it, and the result will be printed. We will explain what
- Scala files look like further into this tutorial, but for now, let's start
- with some basics.
+ This is the so called REPL (Read-Eval-Print Loop). You may type any Scala
+ expression, and the result will be printed. We will explain what Scala files
+ look like further into this tutorial, but for now, let's start with some
+ basics.
+
*/
@@ -32,10 +34,10 @@ Scala - the scalable language
// 1. Basics
/////////////////////////////////////////////////
-// Single line comments start with two forward slashes
+// Single-line comments start with two forward slashes
/*
- Multi line comments, as you can already see from above, look like this.
+ Multi-line comments, as you can already see from above, look like this.
*/
// Printing, and forcing a new line on the next print
@@ -46,12 +48,12 @@ println(10)
print("Hello world")
// Declaring values is done using either var or val.
-// val declarations are immutable, whereas var's are mutable. Immutability is
+// val declarations are immutable, whereas vars are mutable. Immutability is
// a good thing.
val x = 10 // x is now 10
-x = 20 // error: reassignment to val
+x = 20 // error: reassignment to val
var y = 10
-y = 20 // y is now 20
+y = 20 // y is now 20
/*
Scala is a statically typed language, yet note that in the above declarations,
@@ -71,17 +73,17 @@ true
false
// Boolean operations
-!true // false
-!false // true
+!true // false
+!false // true
true == false // false
-10 > 5 // true
+10 > 5 // true
// Math is as per usual
-1 + 1 // 2
-2 - 1 // 1
-5 * 3 // 15
-6 / 2 // 3
-6 / 4 // 1
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
6.0 / 4 // 1.5
@@ -120,12 +122,12 @@ s"We have $n apples" // => "We have 45 apples"
// Expressions inside interpolated strings are also possible
val a = Array(11, 9, 6)
-s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
+s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
-s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
+s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
// Formatting with interpolated strings with the prefix "f"
-f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
+f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
// Raw strings, ignoring special characters.
@@ -171,12 +173,12 @@ def sq(x: Int) = x * x // Compiler can guess return type is Int
// Functions can have default parameters:
def addWithDefault(x: Int, y: Int = 5) = x + y
-addWithDefault(1, 2) // => 3
-addWithDefault(1) // => 6
+addWithDefault(1, 2) // => 3
+addWithDefault(1) // => 6
// Anonymous functions look like this:
-(x:Int) => x * x
+(x: Int) => x * x
// Unlike defs, even the input type of anonymous functions can be omitted if the
// context makes it clear. Notice the type "Int => Int" which means a function
@@ -186,15 +188,15 @@ val sq: Int => Int = x => x * x
// Anonymous functions can be called as usual:
sq(10) // => 100
-// If your anonymous function has one or two arguments, and each argument is
+// If each argument in your anonymous function is
// used only once, Scala gives you an even shorter way to define them. These
// anonymous functions turn out to be extremely common, as will be obvious in
// the data structure section.
val addOne: Int => Int = _ + 1
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
-addOne(5) // => 6
-weirdSum(2, 4) // => 16
+addOne(5) // => 6
+weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most
@@ -204,9 +206,9 @@ weirdSum(2, 4) // => 16
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
- return z // This line makes z the return value of foo!
+ return z // This line makes z the return value of foo!
else
- z + 2 // This line is the return value of anonFunc
+ z + 2 // This line is the return value of anonFunc
}
anonFunc(x) // This line is the return value of foo
}
@@ -218,19 +220,19 @@ def foo(x: Int): Int = {
1 to 5
val r = 1 to 5
-r.foreach( println )
+r.foreach(println)
r foreach println
// NB: Scala is quite lenient when it comes to dots and brackets - study the
// rules separately. This helps write DSLs and APIs that read like English
-(5 to 1 by -1) foreach ( println )
+(5 to 1 by -1) foreach (println)
// A while loops
var i = 0
-while (i < 10) { println("i " + i); i+=1 }
+while (i < 10) { println("i " + i); i += 1 }
-while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why?
+while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why?
i // Show the value of i. Note that while is a loop in the classical sense -
// it executes sequentially while changing the loop variable. while is very
@@ -239,19 +241,19 @@ i // Show the value of i. Note that while is a loop in the classical sense -
// A do while loop
do {
- println("x is still less than 10");
+ println("x is still less than 10")
x += 1
} while (x < 10)
// Tail recursion is an idiomatic way of doing recurring things in Scala.
// Recursive functions need an explicit return type, the compiler can't infer it.
// Here it's Unit.
-def showNumbersInRange(a:Int, b:Int):Unit = {
+def showNumbersInRange(a: Int, b: Int): Unit = {
print(a)
if (a < b)
showNumbersInRange(a + 1, b)
}
-showNumbersInRange(1,14)
+showNumbersInRange(1, 14)
// Conditionals
@@ -305,13 +307,13 @@ s(1)
(a, 2, "three")
// Why have this?
-val divideInts = (x:Int, y:Int) => (x / y, x % y)
+val divideInts = (x: Int, y: Int) => (x / y, x % y)
-divideInts(10,3) // The function divideInts gives you the result and the remainder
+divideInts(10, 3) // The function divideInts gives you the result and the remainder
// To access the elements of a tuple, use _._n where n is the 1-based index of
// the element
-val d = divideInts(10,3)
+val d = divideInts(10, 3)
d._1
@@ -359,7 +361,7 @@ class Dog(br: String) {
val mydog = new Dog("greyhound")
println(mydog.breed) // => "greyhound"
-println(mydog.bark) // => "Woof, woof!"
+println(mydog.bark) // => "Woof, woof!"
// The "object" keyword creates a type AND a singleton instance of it. It is
@@ -414,8 +416,8 @@ val otherGeorge = george.copy(phoneNumber = "9876")
def matchPerson(person: Person): String = person match {
// Then you specify the patterns:
case Person("George", number) => "We found George! His number is " + number
- case Person("Kate", number) => "We found Kate! Her number is " + number
- case Person(name, number) => "We matched someone : " + name + ", phone : " + number
+ case Person("Kate", number) => "We found Kate! Her number is " + number
+ case Person(name, number) => "We matched someone : " + name + ", phone : " + number
}
val email = "(.*)@(.*)".r // Define a regex for the next example.
@@ -446,7 +448,7 @@ def matchEverything(obj: Any): String = obj match {
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
// You can nest patterns:
- case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
+ case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
}
// In fact, you can pattern match any object with an "unapply" method. This
@@ -465,6 +467,7 @@ val patternFunc: Person => String = {
// 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:
@@ -492,7 +495,7 @@ sSquared.reduce (_+_)
// The filter function takes a predicate (a function from A -> Boolean) and
// selects all elements which satisfy the predicate
List(1, 2, 3) filter (_ > 2) // List(3)
-case class Person(name:String, age:Int)
+case class Person(name: String, age: Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
@@ -540,8 +543,8 @@ implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
// By itself, implicit keyword doesn't change the behavior of the value, so
// above values can be used as usual.
-myImplicitInt + 2 // => 102
-myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
+myImplicitInt + 2 // => 102
+myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
// The difference is that these values are now eligible to be used when another
// piece of code "needs" an implicit value. One such situation is implicit
@@ -569,8 +572,8 @@ def foo[T : C] = ...
// implicit conversion of type A => B, where A is the type of obj, and B has a
// method called "method", that conversion is applied. So having
// myImplicitFunction above in scope, we can say:
-"Retriever".breed // => "Golden Retriever"
-"Sheperd".bark // => "Woof, woof!"
+"Retriever".breed // => "Golden Retriever"
+"Sheperd".bark // => "Woof, woof!"
// Here the String is first converted to Dog using our function above, and then
// the appropriate method is called. This is an extremely powerful feature, but
@@ -593,7 +596,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 => _, _}
@@ -628,13 +631,8 @@ writer.close()
## Further resources
-[Scala for the impatient](http://horstmann.com/scala/)
-
-[Twitter Scala school](http://twitter.github.io/scala_school/)
-
-[The scala documentation](http://docs.scala-lang.org/)
-
-[Try Scala in your browser](http://scalatutorials.com/tour/)
-
-Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
-
+* [Scala for the impatient](http://horstmann.com/scala/)
+* [Twitter Scala school](http://twitter.github.io/scala_school/)
+* [The scala documentation](http://docs.scala-lang.org/)
+* [Try Scala in your browser](http://scalatutorials.com/tour/)
+* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown
index b545f3e1..143980e7 100644
--- a/standard-ml.html.markdown
+++ b/standard-ml.html.markdown
@@ -3,13 +3,15 @@ language: "Standard ML"
contributors:
- ["Simon Shine", "http://shine.eu.org/"]
- ["David Pedersen", "http://lonelyproton.com/"]
+ - ["James Baker", "http://www.jbaker.io/"]
+ - ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
---
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.
+implicit type conversion). Standard ML is distinguished from Haskell by including
+references, allowing variables to be updated.
```ocaml
(* Comments in Standard ML begin with (* and end with *). Comments can be
@@ -135,9 +137,29 @@ val mixup = [ ("Alice", 39),
val good_bad_stuff =
(["ice cream", "hot dogs", "chocolate"],
- ["liver", "paying the rent" ]) (* string list * string list *)
+ ["liver", "paying the rent" ]) (* : string list * string list *)
+(* Records are tuples with named slots *)
+
+val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *)
+
+(* You don't need to declare their slots ahead of time. Records with
+ different slot names are considered different types, even if their
+ slot value types match up. For instance... *)
+
+val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *)
+val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *)
+
+(* ...trying to evaluate `Hsv = Hsl` or `rgb = Hsl` would give a type
+ error. While they're all three-slot records composed only of `real`s,
+ they each have different names for at least some slots. *)
+
+(* You can use hash notation to get values out of tuples. *)
+
+val H = #H Hsv (* : real *)
+val s = #s Hsl (* : real *)
+
(* Functions! *)
fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
val test_it = add_them (3, 4) (* gives 7 *)
@@ -224,17 +246,26 @@ 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). *)
+(* Pattern matching is also possible on composite types like tuples, lists and
+ records. 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 *)
+(* When matching on records, you must use their slot names, and you must bind
+ every slot in a record. The order of the slots doesn't matter though. *)
+
+fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
+fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
+
+(* If called with {r=0.1, g=0.2, b=0.3}, either of the above functions
+ would return (0.1, 0.2, 0.3). But it would be a type error to call them
+ with {r=0.1, g=0.2, b=0.3, a=0.4} *)
(* Higher order functions: Functions can take other functions as arguments.
Functions are just other kinds of values, and functions don't need names
@@ -383,6 +414,25 @@ val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,",
"Violets are blue.",
"I have a gun.",
"Get in the van." ] *)
+
+(* We can create references to data which can be updated *)
+val counter = ref 0 (* Produce a reference with the ref function *)
+
+(* Assign to a reference with the assignment operator *)
+fun set_five reference = reference := 5
+
+(* Read a reference with the dereference operator *)
+fun equals_five reference = !reference = 5
+
+(* We can use while loops for when recursion is messy *)
+fun decrement_to_zero r = if !r < 0
+ then r := 0
+ else while !r >= 0 do r := !r - 1
+
+(* This returns the unit value (in practical terms, nothing, a 0-tuple) *)
+
+(* To allow returning a value, we can use the semicolon to sequence evaluations *)
+fun decrement_ret x y = (x := !x - 1; y)
```
## Further learning
diff --git a/swift.html.markdown b/swift.html.markdown
index ffc57e69..509c9d2f 100644
--- a/swift.html.markdown
+++ b/swift.html.markdown
@@ -4,6 +4,7 @@ contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
- ["Joey Huang", "http://github.com/kamidox"]
+ - ["Anthony Nguyen", "http://github.com/anthonyn60"]
filename: learnswift.swift
---
@@ -26,7 +27,9 @@ import UIKit
// TODO: Do something soon
// FIXME: Fix this code
-println("Hello, world")
+// In Swift 2, println and print were combined into one print method. Print automatically appends a new line.
+print("Hello, world") // println is now print
+print("Hello, world", appendNewLine: false) // printing without appending a newline
// variables (var) value can change after being set
// constants (let) value can NOT be changed after being set
@@ -46,12 +49,12 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String interpolation
// Build Specific values
// uses -D build configuration
#if false
- println("Not printed")
+ print("Not printed")
let buildValue = 3
#else
let buildValue = 7
#endif
-println("Build value: \(buildValue)") // Build value: 7
+print("Build value: \(buildValue)") // Build value: 7
/*
Optionals are a Swift language feature that allows you to store a `Some` or
@@ -69,7 +72,7 @@ var someOptionalString2: Optional<String> = "optional"
if someOptionalString != nil {
// I am not nil
if someOptionalString!.hasPrefix("opt") {
- println("has the prefix")
+ print("has the prefix")
}
let empty = someOptionalString?.isEmpty
@@ -138,21 +141,21 @@ var emptyMutableDictionary = [String: Float]() // var == mutable
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
if value == 1 {
- println("One!")
+ print("One!")
} else {
- println("Not one!")
+ print("Not one!")
}
}
// for loop (dictionary)
var dict = ["one": 1, "two": 2]
for (key, value) in dict {
- println("\(key): \(value)")
+ print("\(key): \(value)")
}
// for loop (range)
for i in -1...shoppingList.count {
- println(i)
+ print(i)
}
shoppingList[1...2] = ["steak", "peacons"]
// use ..< to exclude the last number
@@ -165,7 +168,7 @@ while i < 1000 {
// do-while loop
do {
- println("hello")
+ print("hello")
} while 1 == 2
// Switch
@@ -222,8 +225,8 @@ let pricesTuple = getGasPrices()
let price = pricesTuple.2 // 3.79
// Ignore Tuple (or other) values by using _ (underscore)
let (_, price1, _) = pricesTuple // price1 == 3.69
-println(price1 == pricesTuple.1) // true
-println("Gas price: \(price)")
+print(price1 == pricesTuple.1) // true
+print("Gas price: \(price)")
// Variadic Args
func setup(numbers: Int...) {
@@ -251,7 +254,7 @@ func swapTwoInts(inout a: Int, inout b: Int) {
var someIntA = 7
var someIntB = 3
swapTwoInts(&someIntA, &someIntB)
-println(someIntB) // 7
+print(someIntB) // 7
//
@@ -305,7 +308,7 @@ struct NamesTable {
// Structures have an auto-generated (implicit) designated initializer
let namesTable = NamesTable(names: ["Me", "Them"])
let name = namesTable[1]
-println("Name is \(name)") // Name is Them
+print("Name is \(name)") // Name is Them
//
// MARK: Classes
@@ -386,7 +389,7 @@ let aShape = mySquare as Shape
// compare instances, not the same as == which compares objects (equal to)
if mySquare === mySquare {
- println("Yep, it's mySquare")
+ print("Yep, it's mySquare")
}
// Optional init
@@ -409,13 +412,13 @@ class Circle: Shape {
}
var myCircle = Circle(radius: 1)
-println(myCircle?.getArea()) // Optional(3)
-println(myCircle!.getArea()) // 3
+print(myCircle?.getArea()) // Optional(3)
+print(myCircle!.getArea()) // 3
var myEmptyCircle = Circle(radius: -1)
-println(myEmptyCircle?.getArea()) // "nil"
+print(myEmptyCircle?.getArea()) // "nil"
if let circle = myEmptyCircle {
// will not execute since myEmptyCircle is nil
- println("circle is not nil")
+ print("circle is not nil")
}
@@ -447,7 +450,7 @@ enum BookName: String {
case John = "John"
case Luke = "Luke"
}
-println("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.John.rawValue)")
// Enum with associated Values
enum Furniture {
@@ -467,9 +470,9 @@ enum Furniture {
}
var desk: Furniture = .Desk(height: 80)
-println(desk.description()) // "Desk with 80 cm"
+print(desk.description()) // "Desk with 80 cm"
var chair = Furniture.Chair("Foo", 40)
-println(chair.description()) // "Chair of Foo with 40 cm"
+print(chair.description()) // "Chair of Foo with 40 cm"
//
@@ -522,7 +525,7 @@ extension Square: Printable {
}
}
-println("Square: \(mySquare)")
+print("Square: \(mySquare)")
// You can also extend built-in types
extension Int {
@@ -535,8 +538,8 @@ extension Int {
}
}
-println(7.customProperty) // "This is 7"
-println(14.multiplyBy(3)) // 42
+print(7.customProperty) // "This is 7"
+print(14.multiplyBy(3)) // 42
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics.
@@ -550,7 +553,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
return nil
}
let foundAtIndex = findIndex([1, 2, 3, 4], 3)
-println(foundAtIndex == 2) // true
+print(foundAtIndex == 2) // true
// Operators:
// Custom operators can start with the characters:
@@ -566,9 +569,9 @@ prefix func !!! (inout shape: Square) -> Square {
}
// current value
-println(mySquare.sideLength) // 4
+print(mySquare.sideLength) // 4
// change side length using custom !!! operator, increases size by 3
!!!mySquare
-println(mySquare.sideLength) // 12
+print(mySquare.sideLength) // 12
```
diff --git a/tcl.html.markdown b/tcl.html.markdown
index 198f675e..c1cd42ca 100755..100644
--- a/tcl.html.markdown
+++ b/tcl.html.markdown
@@ -121,7 +121,8 @@ puts lots\nof\n\n\n\n\n\nnewlines
# A word enclosed in braces is not subject to any special interpretation or
-# substitutions, except that a backslash before a brace is not counted when look#ing for the closing brace
+# substitutions, except that a backslash before a brace is not counted when
+# looking for the closing brace
set somevar {
This is a literal $ sign, and this \} escaped
brace remains uninterpreted
@@ -256,7 +257,7 @@ proc greet greeting\ name return\ \"Hello,\ \$name!
proc fold {cmd args} {
set res 0
foreach arg $args {
- set res [cmd $res $arg]
+ set res [$cmd $res $arg]
}
}
fold ::tcl::mathop::* 5 3 3 ;# -> 45
diff --git a/tmux.html.markdown b/tmux.html.markdown
index 2ccb067a..c11da5fc 100644
--- a/tmux.html.markdown
+++ b/tmux.html.markdown
@@ -7,8 +7,8 @@ filename: LearnTmux.txt
---
-<a href="http://tmux.sourceforge.net/">
-tmux</a> is a terminal multiplexer: it enables a number of terminals
+[tmux](http://tmux.sourceforge.net)
+is a terminal multiplexer: it enables a number of terminals
to be created, accessed, and controlled from a single screen. tmux
may be detached from a screen and continue running in the background
then later reattached.
@@ -50,13 +50,15 @@ then later reattached.
-a # Kill all sessions
-a -t "#" # Kill all sessions but the target
+```
-## Key Bindings
+### Key Bindings
-# The method of controlling an attached tmux session is via key
-# combinations called 'Prefix' keys.
+The method of controlling an attached tmux session is via key
+combinations called 'Prefix' keys.
+```
----------------------------------------------------------------------
(C-b) = Ctrl + b # 'Prefix' combination required to use keybinds
@@ -109,10 +111,9 @@ then later reattached.
### Configuring ~/.tmux.conf
- tmux.conf can be used to set options automatically on start up, much
+tmux.conf can be used to set options automatically on start up, much
like how .vimrc or init.el are used.
-
```
# Example tmux.conf
# 2014.10
@@ -236,8 +237,15 @@ set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] |
```
-<a href="http://tmux.sourceforge.net/">Tmux | Home</a><br>
-<a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux">Tmux Manual page</a><br>
-<a href="http://wiki.gentoo.org/wiki/Tmux">Gentoo Wiki</a><br>
-<a href="https://wiki.archlinux.org/index.php/Tmux">Archlinux Wiki</a><br>
-<a href="https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux">Display CPU/MEM % in statusbar</a><br>
+
+### References
+
+[Tmux | Home](http://tmux.sourceforge.net)
+
+[Tmux Manual page](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux)
+
+[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux)
+
+[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux)
+
+[Display CPU/MEM % in statusbar](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux)
diff --git a/tr-tr/csharp-tr.html.markdown b/tr-tr/csharp-tr.html.markdown
index 7755ed44..a68026a5 100644
--- a/tr-tr/csharp-tr.html.markdown
+++ b/tr-tr/csharp-tr.html.markdown
@@ -8,7 +8,7 @@ contributors:
translators:
- ["Melih Mucuk", "http://melihmucuk.com"]
lang: tr-tr
-filename: LearnCSharp.cs
+filename: LearnCSharp-tr.cs
---
diff --git a/tr-tr/markdown-tr.html.markdown b/tr-tr/markdown-tr.html.markdown
new file mode 100644
index 00000000..bac8f6fc
--- /dev/null
+++ b/tr-tr/markdown-tr.html.markdown
@@ -0,0 +1,251 @@
+---
+language: markdown
+contributors:
+ - ["Dan Turkel", "http://danturkel.com/"]
+translators:
+ - ["Eray AYDIN", "http://erayaydin.me/"]
+lang: tr-tr
+filename: markdown-tr.md
+---
+
+Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır.
+
+
+```markdown
+<!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir
+ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve
+markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız,
+bu elementin içeriğinde markdown söz dizimlerini kullanamazsınız. -->
+
+<!-- Markdown ayrıca işleyiciden işleyiciye farklılık gösterebilir. Bu rehberde
+evrensel özelliklere uygun anlatımlar olacaktır. Bir çok işleyici bu rehberdeki
+anlatımları destekler -->
+
+<!-- Başlıklar -->
+<!-- Kolayca <h1>'den <h6>'ya HTML etiketleri oluşturabilirsiniz.
+Kare (#) sayısı bu elementin numarasını belirleyecek ve devamında getirdiğiniz
+yazı bu elementin içeriği olacaktır
+-->
+# Bu bir <h1>
+## Bu bir <h2>
+### Bu bir <h3>
+#### Bu bir <h4>
+##### Bu bir <h5>
+###### Bu bir <h6>
+
+<!-- Markdown ayrıca h1 ve h2 için 2 alternatif yol daha taşır -->
+Bu bir h1
+=========
+
+Bu bir h2
+---------
+
+<!-- Basit yazı stilleri -->
+<!-- Markdown ile yazılar kolayca italik ve kalın belirtilebilir -->
+*Bu yazı italik.*
+_Bu yazı da italik._
+
+**Bu yazı kalın.**
+__Bu yazı da kalın.__
+
+***Bu yazı hem kalın hem italik.***
+**_Bu da öyle!_**
+*__Hatta bu bile!__*
+
+<!-- Github Flavored Markdown'da ayrıca üstü çizgili karakter de desteklenir: -->
+~~Bu yazı üstü çizili olarak gözükecek.~~
+
+<!-- Paragraflar bir veya daha fazla boş satırla ayrılır. -->
+
+Bu bir paragraf. Paragrafın içeriğine devam ediyorum, eğlenceli değil mi?
+
+Şimdi 2. paragrafıma geçtim.
+Hala 2. paragraftayım, çünkü boş bir satır bırakmadım.
+
+Bu da 3. paragrafım!
+
+<!-- HTML'de her satır için <br /> etiketi kullanmak ister misiniz, Bir
+paragrafı bitirdikten sonra 2 veya daha fazla boşluk bırakın ve yeni paragrafa
+başlayın, bu bir <br /> etiketi sayılacaktır -->
+
+Bu yazının sonunda 2 boşluk var (bu satırı seçerek kontrol edebilirsiniz).
+
+Bir üst satırda <br /> etiketi var!
+
+<!-- Blok yazılarının yapımı oldukça kolay, (>) karakteri ile yapabilirsiniz -->
+
+> Bu bir blok etiketi. Satırlara ayırmak için
+> her satırın başında `>` karakter yerleştirmeli veya tek satırda bütün içeriği yazabilirsiniz.
+> Satır `>` karakteri ile başladığı sürece sorun yok.
+
+> Ayrıca alt alta da blok elementi açabilirsiniz
+>> iç içe yani
+> düzgün değil mi ?
+
+<!-- Listeler -->
+<!-- Numarasız listeler için yıldız, artı, veya tire kullanabilirsiniz -->
+
+* Nesne
+* Nesne
+* Bir başka nesne
+
+veya
+
++ Nesne
++ Nesne
++ Bir başka nesne
+
+veya
+
+- Nesne
+- Nesne
+- Son bir nesne
+
+<!-- Numaralı liste için başına sıralı bir şekilde sayı eklemeniz yeterli -->
+
+1. İlk nesne
+2. İkinci nesne
+3. Üçüncü nesne
+
+<!-- İsterseniz sıralı bir şekilde yazmak zorunda değilsiniz, markdown
+biçimlendirirken sizin için sıralayacaktır, fakat bunu önermiyorum. Markdown dosyasının
+düzgün gözükmesi için önerilen metodu uygulamanızı tavsiye ederim -->
+
+1. İlk nesne
+1. İkinci nesne
+1. Üçüncü nesne
+
+<!-- (Bunun çıktısı ile, sıralı olarak yazdığımız örneğin çıktısı aynı olacaktır) -->
+
+<!-- Ayrıca alt alta liste oluşturabilirsiniz -->
+
+1. İlk nesne
+2. İkinci nesne
+3. Üçüncü nesne
+ * Alt nesne
+ * Alt nesne
+4. Dördüncü nesne
+
+<!-- Ayrıca görev listeleri de bulunmakta. HTML seçim kutusu(checkbox) oluşturacaktır. -->
+Kutunun içerisinde `x` yoksa eğer seçim kutusu boş olacaktır.
+- [ ] Yapılacak ilk görev.
+- [ ] Yapılması gereken bir başka görev
+Aşağıdaki seçim kutusu ise içi dolu olacaktır.
+- [x] Bu görev başarıyla yapıldı
+
+<!-- Kod blokları -->
+<!-- Kod bloklarını(<code> elementi) belirtmek için 4 adet boşluk veya bir
+tab karakterini kullanabilirsiniz -->
+
+ Bu bir kod
+ öyle mi?
+
+<!-- Ayrıca kod içerisinde girinti kullanmak istiyorsanız tekrar `tab` veya `4 boşluk`
+kullanabilirsiniz -->
+
+ my_array.each do |item|
+ puts item
+ end
+
+<!-- Yazı içerisinde kod belirtmek için sorgu tırnağı (`) kullanabilirsiniz -->
+
+Ahmet `go_to()` fonksiyonun ne yaptığını bilmiyor!
+
+<!-- Github Flavored Markdown'da, kod içerisinde aydınlatma kullanabilirsiniz -->
+
+\`\`\`ruby <!-- buradaki ters slaş (\) işaretlerini kullanmayın, sadece ```ruby ! -->
+def foobar
+ puts "Hello world!"
+end
+\`\`\` <!-- burada da (\) işaretlerini kullanmayın, sadece ``` -->
+
+<!-- Yukarıdaki örnekte girinti kullanmanıza gerek yok, Github da
+``` işaretinden sonra belirttiğiniz yazılım diline göre gerekli
+syntax aydınlatmaları uygulanacaktır -->
+
+<!-- Düz çizgi (<hr />) -->
+<!-- Düz çizgiler 3 veya daha fazla yıldız/çizgi ile yapılabilir. Boşluklar önemsiz. -->
+
+***
+---
+- - -
+****************
+
+<!-- Linkler -->
+<!-- Markdown'daki en güzel şeylerden biri kolayca link oluşturmaktır.
+Linkte göstermek istediğiniz yazıyı [] içerisine yerleştirin ve sonuna parantezler içerisinde ()
+gideceği adresi belirtin -->
+
+[Bana tıkla!](http://test.com)
+
+<!-- Ayrıca linke `title` özelliği eklemek için tırnakları kullanabilirsiniz -->
+
+[Bana tıkla!](http://test.com "Test.com'a gider")
+
+<!-- Bağıl yollar da çalışıyor. -->
+[Müzik dinle](/muzik/).
+
+<!-- Markdown ayrıca referans linklerini de destekler -->
+
+[Bu linke tıklayarak][link1] daha detaylı bilgi alabilirsiniz!
+[Ayrıca bu linki de inceleyin][foobar] tabi istiyorsanız.
+
+[link1]: http://test.com/ "harika!"
+[foobar]: http://foobar.biz/ "okey!"
+
+<!--Başlık ayrıca tek tırnak veya parantez içinde olabilir, veya direk yazılabilir.
+Referans döküman içerisindeki herhangi bir yer olabilir ve referans IDsi
+benzersiz olduğu sürece sorunsuz çalışacaktır. -->
+
+<!-- Ayrıca "dolaylı adlandırma" bulunmaktadır, "dolaylı adlandırma", linkin yazısının
+aynı zamanda onun idsi olmasıdır -->
+
+[Bu][] bir link.
+[bu]: http://bubirlink.com
+
+<!-- Fakat bu çok tercih edilen bir yöntem değil. -->
+
+<!-- Resimler -->
+<!-- Resimler aslında linklere çok benziyor fakat başında ünlem bulunuyor! -->
+![Bu alt etiketine gelecek içerik](http://imgur.com/resmim.jpg "Bu da isteğe bağlı olan bir başlık")
+
+<!-- Referanslar resimler için de geçerli -->
+![Bu alt etiketi.][resmim]
+
+[resmim]: bagil/linkler/de/calisiyor.jpg "Başlık isterseniz buraya girebilirsiniz"
+
+<!-- Çeşitli -->
+<!-- Oto-linkler -->
+
+<http://testwebsite.com/> ile
+[http://testwebsite.com/](http://testwebsite.com) aynı şeyler
+
+<!-- Oto-linkler epostaları da destekler -->
+
+<foo@bar.com>
+
+<!-- Kaçış karakterleri -->
+
+Bu yazının *yıldızlar arasında gözükmesini* istiyorum fakat italik olmamasını istiyorum,
+bunun için, şu şekilde: \*bu yazı italik değil, yıldızlar arasında\*.
+
+<!-- Tablolar -->
+<!-- Tablolar sadece Github Flavored Markdown'da destekleniyor ve açıkçası
+performansı çok yoruyorlar, fakat illa ki kullanmak isterseniz: -->
+
+| Sütun1 | Sütun 2 | Sütün 3 |
+| :----------- | :------: | ------------: |
+| Sola dayalı | Ortalı | Sağa dayalı |
+| test | test | test |
+
+<!-- ayrıca, bunun aynısı -->
+
+Sütun 1 | Sütun 2 | Sütun 3
+:-- | :-: | --:
+Çok çirkin göözüküyor | değil | mi?
+
+<!-- Bitiş! -->
+
+```
+
+Daha detaylı bilgi için, John Gruber'in resmi söz dizimi yazısını [buradan](http://daringfireball.net/projects/markdown/syntax) veya Adam Pritchard'ın mükemmel hatırlatma kağıdını [buradan](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) inceleyebilirsiniz.
diff --git a/tr-tr/python3-tr.html.markdown b/tr-tr/python3-tr.html.markdown
new file mode 100644
index 00000000..2477c5da
--- /dev/null
+++ b/tr-tr/python3-tr.html.markdown
@@ -0,0 +1,635 @@
+---
+language: python3
+contributors:
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Eray AYDIN", "http://erayaydin.me/"]
+lang: tr-tr
+filename: learnpython3-tr.py
+---
+
+Python,90ların başlarında Guido Van Rossum tarafından oluşturulmuştur. En popüler olan dillerden biridir. Beni Python'a aşık eden sebep onun syntax beraklığı. Çok basit bir çalıştırılabilir söz koddur.
+
+Not: Bu makale Python 3 içindir. Eğer Python 2.7 öğrenmek istiyorsanız [burayı](http://learnxinyminutes.com/docs/python/) kontrol edebilirsiniz.
+
+```python
+
+# Tek satırlık yorum satırı kare(#) işareti ile başlamaktadır.
+
+""" Çok satırlı olmasını istediğiniz yorumlar
+ üç adet tırnak(") işareti ile
+ yapılmaktadır
+"""
+
+####################################################
+## 1. Temel Veri Türleri ve Operatörler
+####################################################
+
+# Sayılar
+3 # => 3
+
+# Tahmin edebileceğiniz gibi matematik
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+
+# Bölme işlemi varsayılan olarak onluk döndürür
+35 / 5 # => 7.0
+
+# Tam sayı bölmeleri, pozitif ve negatif sayılar için aşağıya yuvarlar
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # onluklar için de bu böyledir
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Onluk kullanırsanız, sonuç da onluk olur
+3 * 2.0 # => 6.0
+
+# Kalan operatörü
+7 % 3 # => 1
+
+# Üs (2 üzeri 4)
+2**4 # => 16
+
+# Parantez ile önceliği değiştirebilirsiniz
+(1 + 3) * 2 # => 8
+
+# Boolean(Doğru-Yanlış) değerleri standart
+True
+False
+
+# 'değil' ile terse çevirme
+not True # => False
+not False # => True
+
+# Boolean Operatörleri
+# "and" ve "or" büyük küçük harf duyarlıdır
+True and False #=> False
+False or True #=> True
+
+# Bool operatörleri ile sayı kullanımı
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
+# Eşitlik kontrolü ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Eşitsizlik Kontrolü !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Diğer karşılaştırmalar
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Zincirleme şeklinde karşılaştırma da yapabilirsiniz!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Yazı(Strings) " veya ' işaretleri ile oluşturulabilir
+"Bu bir yazı."
+'Bu da bir yazı.'
+
+# Yazılar da eklenebilir! Fakat bunu yapmanızı önermem.
+"Merhaba " + "dünya!" # => "Merhaba dünya!"
+
+# Bir yazı(string) karakter listesi gibi işlenebilir
+"Bu bir yazı"[0] # => 'B'
+
+# .format ile yazıyı biçimlendirebilirsiniz, şu şekilde:
+"{} da ayrıca {}".format("yazılar", "işlenebilir")
+
+# Biçimlendirme işleminde aynı argümanı da birden fazla kullanabilirsiniz.
+"{0} çeviktir, {0} hızlıdır, {0} , {1} üzerinden atlayabilir".format("Ahmet", "şeker çubuğu")
+#=> "Ahmet çeviktir, Ahmet hızlıdır, Ahmet , şeker çubuğu üzerinden atlayabilir"
+
+# Argümanın sırasını saymak istemiyorsanız, anahtar kelime kullanabilirsiniz.
+"{isim} yemek olarak {yemek} istiyor".format(isim="Ahmet", yemek="patates") #=> "Ahmet yemek olarak patates istiyor"
+
+# Eğer Python 3 kodunuz ayrıca Python 2.5 ve üstünde çalışmasını istiyorsanız,
+# eski stil formatlamayı kullanabilirsiniz:
+"%s bu %s yolla da %s" % ("yazılar", "eski", "biçimlendirilebilir")
+
+
+# Hiçbir şey(none) da bir objedir
+None # => None
+
+# Bir değerin none ile eşitlik kontrolü için "==" sembolünü kullanmayın
+# Bunun yerine "is" kullanın. Obje türünün eşitliğini kontrol edecektir.
+"vb" is None # => False
+None is None # => True
+
+# None, 0, ve boş yazılar/listeler/sözlükler hepsi False değeri döndürü.
+# Diğer veriler ise True değeri döndürür
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
+
+
+####################################################
+## 2. Değişkenler ve Koleksiyonlar
+####################################################
+
+# Python bir yazdırma fonksiyonuna sahip
+print("Ben Python. Tanıştığıma memnun oldum!")
+
+# Değişkenlere veri atamak için önce değişkeni oluşturmanıza gerek yok.
+# Düzenli bir değişken için hepsi_kucuk_ve_alt_cizgi_ile_ayirin
+bir_degisken = 5
+bir_degisken # => 5
+
+# Önceden tanımlanmamış değişkene erişmek hata oluşturacaktır.
+# Kontrol akışları başlığından hata kontrolünü öğrenebilirsiniz.
+bir_bilinmeyen_degisken # NameError hatası oluşturur
+
+# Listeler ile sıralamaları tutabilirsiniz
+li = []
+# Önceden doldurulmuş listeler ile başlayabilirsiniz
+diger_li = [4, 5, 6]
+
+# 'append' ile listenin sonuna ekleme yapabilirsiniz
+li.append(1) # li artık [1] oldu
+li.append(2) # li artık [1, 2] oldu
+li.append(4) # li artık [1, 2, 4] oldu
+li.append(3) # li artık [1, 2, 4, 3] oldu
+# 'pop' ile listenin son elementini kaldırabilirsiniz
+li.pop() # => 3 ve li artık [1, 2, 4]
+# Çıkarttığımız tekrardan ekleyelim
+li.append(3) # li yeniden [1, 2, 4, 3] oldu.
+
+# Dizi gibi listeye erişim sağlayın
+li[0] # => 1
+# Son elemente bakın
+li[-1] # => 3
+
+# Listede olmayan bir elemente erişim sağlamaya çalışmak IndexError hatası oluşturur
+li[4] # IndexError hatası oluşturur
+
+# Bir kısmını almak isterseniz.
+li[1:3] # => [2, 4]
+# Başlangıç belirtmezseniz
+li[2:] # => [4, 3]
+# Sonu belirtmesseniz
+li[:3] # => [1, 2, 4]
+# Her ikişer objeyi seçme
+li[::2] # =>[1, 4]
+# Listeyi tersten almak
+li[::-1] # => [3, 4, 2, 1]
+# Kombinasyonları kullanarak gelişmiş bir şekilde listenin bir kısmını alabilirsiniz
+# li[baslangic:son:adim]
+
+# "del" ile isteğe bağlı, elementleri listeden kaldırabilirsiniz
+del li[2] # li artık [1, 2, 3] oldu
+
+# Listelerde de ekleme yapabilirsiniz
+# Not: değerler üzerinde değişiklik yapılmaz.
+li + diger_li # => [1, 2, 3, 4, 5, 6]
+
+# Listeleri birbirine bağlamak için "extend()" kullanılabilir
+li.extend(diger_li) # li artık [1, 2, 3, 4, 5, 6] oldu
+
+# Listedeki bir elementin olup olmadığı kontrolü "in" ile yapılabilir
+1 in li # => True
+
+# Uzunluğu öğrenmek için "len()" kullanılabilir
+len(li) # => 6
+
+
+# Tüpler listeler gibidir fakat değiştirilemez.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # TypeError hatası oluşturur
+
+# Diğer liste işlemlerini tüplerde de uygulayabilirsiniz
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Tüpleri(veya listeleri) değişkenlere açabilirsiniz
+a, b, c = (1, 2, 3) # 'a' artık 1, 'b' artık 2 ve 'c' artık 3
+# Eğer parantez kullanmazsanız varsayılan oalrak tüpler oluşturulur
+d, e, f = 4, 5, 6
+# 2 değeri birbirine değiştirmek bu kadar kolay
+e, d = d, e # 'd' artık 5 ve 'e' artık 4
+
+
+# Sözlükler anahtar kodlarla verileri tutar
+bos_sozl = {}
+# Önceden doldurulmuş sözlük oluşturma
+dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
+
+# Değere bakmak için [] kullanalım
+dolu_sozl["bir"] # => 1
+
+# Bütün anahtarları almak için "keys()" kullanılabilir.
+# Listelemek için list() kullanacağınız çünkü dönen değerin işlenmesi gerekiyor. Bu konuya daha sonra değineceğiz.
+# Not - Sözlük anahtarlarının sıralaması kesin değildir.
+# Beklediğiniz çıktı sizinkiyle tam uyuşmuyor olabilir.
+list(dolu_sozl.keys()) # => ["uc", "iki", "bir"]
+
+
+# Tüm değerleri almak için "values()" kullanacağız. Dönen değeri biçimlendirmek için de list() kullanmamız gerekiyor
+# Not - Sıralama değişebilir.
+list(dolu_sozl.values()) # => [3, 2, 1]
+
+
+# Bir anahtarın sözlükte olup olmadığını "in" ile kontrol edebilirsiniz
+"bir" in dolu_sozl # => True
+1 in dolu_sozl # => False
+
+# Olmayan bir anahtardan değer elde etmek isterseniz KeyError sorunu oluşacaktır.
+dolu_sozl["dort"] # KeyError hatası oluşturur
+
+# "get()" metodu ile değeri almaya çalışırsanız KeyError sorunundan kurtulursunuz
+dolu_sozl.get("bir") # => 1
+dolu_sozl.get("dort") # => None
+# "get" metoduna parametre belirterek değerin olmaması durumunda varsayılan bir değer döndürebilirsiniz.
+dolu_sozl.get("bir", 4) # => 1
+dolu_sozl.get("dort", 4) # => 4
+
+# "setdefault()" metodu sözlükte, belirttiğiniz anahtarın [olmaması] durumunda varsayılan bir değer atayacaktır
+dolu_sozl.setdefault("bes", 5) # dolu_sozl["bes"] artık 5 değerine sahip
+dolu_sozl.setdefault("bes", 6) # dolu_sozl["bes"] değişmedi, hala 5 değerine sahip
+
+# Sözlüğe ekleme
+dolu_sozl.update({"dort":4}) #=> {"bir": 1, "iki": 2, "uc": 3, "dort": 4}
+#dolu_sozl["dort"] = 4 #sözlüğe eklemenin bir diğer yolu
+
+# Sözlükten anahtar silmek için 'del' kullanılabilir
+del dolu_sozl["bir"] # "bir" anahtarını dolu sözlükten silecektir
+
+
+# Setler ... set işte :D
+bos_set = set()
+# Seti bir veri listesi ile de oluşturabilirsiniz. Evet, biraz sözlük gibi duruyor. Üzgünüm.
+bir_set = {1, 1, 2, 2, 3, 4} # bir_set artık {1, 2, 3, 4}
+
+# Sete yeni setler ekleyebilirsiniz
+dolu_set = bir_set
+
+# Sete bir diğer öğe ekleme
+dolu_set.add(5) # dolu_set artık {1, 2, 3, 4, 5} oldu
+
+# Setlerin çakışan kısımlarını almak için '&' kullanabilirsiniz
+diger_set = {3, 4, 5, 6}
+dolu_set & diger_set # => {3, 4, 5}
+
+# '|' ile aynı olan elementleri almayacak şekilde setleri birleştirebilirsiniz
+dolu_set | diger_set # => {1, 2, 3, 4, 5, 6}
+
+# Farklılıkları almak için "-" kullanabilirsiniz
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Bir değerin olup olmadığının kontrolü için "in" kullanılabilir
+2 in dolu_set # => True
+10 in dolu_set # => False
+
+
+####################################################
+## 3. Kontrol Akışları ve Temel Soyutlandırma
+####################################################
+
+# Bir değişken oluşturalım
+bir_degisken = 5
+
+# Burada bir "if" ifadesi var. Girinti(boşluk,tab) python için önemlidir!
+# çıktı olarak "bir_degisken 10 dan küçük" yazar
+if bir_degisken > 10:
+ print("bir_degisken 10 dan büyük")
+elif bir_degisken < 10: # Bu 'elif' ifadesi zorunlu değildir.
+ print("bir_degisken 10 dan küçük")
+else: # Bu ifade de zorunlu değil.
+ print("bir_degisken değeri 10")
+
+
+"""
+Döngülerle lsiteleri döngüye alabilirsiniz
+çıktı:
+ köpek bir memeli hayvandır
+ kedi bir memeli hayvandır
+ fare bir memeli hayvandır
+"""
+for hayvan in ["köpek", "kedi, "fare"]:
+ # format ile kolayca yazıyı biçimlendirelim
+ print("{} bir memeli hayvandır".format(hayvan))
+
+"""
+"range(sayi)" bir sayı listesi döndür
+0'dan belirttiğiniz sayıyıa kadar
+çıktı:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+'While' döngüleri koşul çalıştıkça işlemleri gerçekleştirir.
+çıktı:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Uzun hali x = x + 1
+
+# Hataları kontrol altına almak için try/except bloklarını kullanabilirsiniz
+try:
+ # Bir hata oluşturmak için "raise" kullanabilirsiniz
+ raise IndexError("Bu bir index hatası")
+except IndexError as e:
+ pass # Önemsiz, devam et.
+except (TypeError, NameError):
+ pass # Çoklu bir şekilde hataları kontrol edebilirsiniz, tabi gerekirse.
+else: # İsteğe bağlı bir kısım. Eğer hiçbir hata kontrol mekanizması desteklemiyorsa bu blok çalışacaktır
+ print("Her şey iyi!") # IndexError, TypeError ve NameError harici bir hatada bu blok çalıştı
+
+# Temel Soyutlandırma, bir objenin işlenmiş halidir.
+# Aşağıdaki örnekte; Obje, range fonksiyonuna temel soyutlandırma gönderdi.
+
+dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
+temel_soyut = dolu_sozl.keys()
+print(temel_soyut) #=> range(1,10). Bu obje temel soyutlandırma arayüzü ile oluşturuldu
+
+# Temel Soyutlandırılmış objeyi döngüye sokabiliriz.
+for i in temel_soyut:
+ print(i) # Çıktısı: bir, iki, uc
+
+# Fakat, elementin anahtarına değerine.
+temel_soyut[1] # TypeError hatası!
+
+# 'iterable' bir objenin nasıl temel soyutlandırıldığıdır.
+iterator = iter(temel_soyut)
+
+# 'iterator' o obje üzerinde yaptığımız değişiklikleri hatırlayacaktır
+# Bir sonraki objeyi almak için __next__ fonksiyonunu kullanabilirsiniz.
+iterator.__next__() #=> "bir"
+
+# Bir önceki __next__ fonksiyonumuzu hatırlayıp bir sonraki kullanımda bu sefer ondan bir sonraki objeyi döndürecektir
+iterator.__next__() #=> "iki"
+iterator.__next__() #=> "uc"
+
+# Bütün nesneleri aldıktan sonra bir daha __next__ kullanımınızda, StopIterator hatası oluşturacaktır.
+iterator.__next__() # StopIteration hatası
+
+# iterator'deki tüm nesneleri almak için list() kullanabilirsiniz.
+list(dolu_sozl.keys()) #=> Returns ["bir", "iki", "uc"]
+
+
+####################################################
+## 4. Fonksiyonlar
+####################################################
+
+# "def" ile yeni fonksiyonlar oluşturabilirsiniz
+def topla(x, y):
+ print("x = {} ve y = {}".format(x, y))
+ return x + y # Değer döndürmek için 'return' kullanmalısınız
+
+# Fonksiyonu parametleri ile çağırıyoruz
+topla(5, 6) # => çıktı "x = 5 ve y = 6" ve değer olarak 11 döndürür
+
+# Bir diğer fonksiyon çağırma yöntemi de anahtar değerleri ile belirtmek
+topla(y=6, x=5) # Anahtar değeri belirttiğiniz için parametre sıralaması önemsiz.
+
+# Sınırsız sayıda argüman da alabilirsiniz
+def argumanlar(*argumanlar):
+ return argumanlar
+
+argumanlar(1, 2, 3) # => (1, 2, 3)
+
+# Parametrelerin anahtar değerlerini almak isterseniz
+def anahtar_par(**anahtarlar):
+ return anahtar
+
+# Çalıştırdığımızda
+anahtar_par(anah1="deg1", anah2="deg2") # => {"anah1": "deg1", "anah2": "deg2"}
+
+
+# İsterseniz, bu ikisini birden kullanabilirsiniz
+def tum_argumanlar(*argumanlar, **anahtarla):
+ print(argumanlar)
+ print(anahtarla)
+"""
+tum_argumanlar(1, 2, a=3, b=4) çıktı:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Fonksiyonu çağırırken de aynısını kullanabilirsiniz
+argumanlar = (1, 2, 3, 4)
+anahtarla = {"a": 3, "b": 4}
+tum_argumanlar(*argumanlar) # = foo(1, 2, 3, 4)
+tum_argumanlar(**anahtarla) # = foo(a=3, b=4)
+tum_argumanlar(*argumanlar, **anahtarla) # = foo(1, 2, 3, 4, a=3, b=4)
+
+
+# Fonksiyonlarda kullanacağımız bir değişken oluşturalım
+x = 5
+
+def belirleX(sayi):
+ # Fonksiyon içerisindeki x ile global tanımladığımız x aynı değil
+ x = sayi # => 43
+ print (x) # => 43
+
+def globalBelirleX(sayi):
+ global x
+ print (x) # => 5
+ x = sayi # global olan x değişkeni artık 6
+ print (x) # => 6
+
+belirleX(43)
+globalBelirleX(6)
+
+
+# Sınıf fonksiyonları oluşturma
+def toplama_olustur(x):
+ def topla(y):
+ return x + y
+ return topla
+
+ekle_10 = toplama_olustur(10)
+ekle_10(3) # => 13
+
+# Bilinmeyen fonksiyon
+(lambda x: x > 2)(3) # => True
+
+# TODO - Fix for iterables
+# Belirli sayıdan yükseğini alma fonksiyonu
+map(ekle_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# Filtreleme işlemi için liste comprehensions da kullanabiliriz
+[ekle_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
+####################################################
+
+
+# Sınıf oluşturmak için objeden alt sınıf oluşturacağız.
+class Insan(obje):
+
+ # Sınıf değeri. Sınıfın tüm nesneleri tarafından kullanılabilir
+ tur = "H. sapiens"
+
+ # Basit başlatıcı, Sınıf çağrıldığında tetiklenecektir.
+ # Dikkat edin, iki adet alt çizgi(_) bulunmakta. Bunlar
+ # python tarafından tanımlanan isimlerdir.
+ # Kendinize ait bir fonksiyon oluştururken __fonksiyon__ kullanmayınız!
+ def __init__(self, isim):
+ # Parametreyi sınıfın değerine atayalım
+ self.isim = isim
+
+ # Bir metot. Bütün metotlar ilk parametre olarak "self "alır.
+ def soyle(self, mesaj):
+ return "{isim}: {mesaj}".format(isim=self.name, mesaj=mesaj)
+
+ # Bir sınıf metotu bütün nesnelere paylaştırılır
+ # İlk parametre olarak sınıf alırlar
+ @classmethod
+ def getir_tur(snf):
+ return snf.tur
+
+ # Bir statik metot, sınıf ve nesnesiz çağrılır
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Sınıfı çağıralım
+i = Insan(isim="Ahmet")
+print(i.soyle("merhaba")) # çıktı "Ahmet: merhaba"
+
+j = Insan("Ali")
+print(j.soyle("selam")) # çıktı "Ali: selam"
+
+# Sınıf metodumuzu çağıraim
+i.getir_tur() # => "H. sapiens"
+
+# Paylaşılan değeri değiştirelim
+Insan.tur = "H. neanderthalensis"
+i.getir_tur() # => "H. neanderthalensis"
+j.getir_tur() # => "H. neanderthalensis"
+
+# Statik metodumuzu çağıralım
+Insan.grunt() # => "*grunt*"
+
+
+####################################################
+## 6. Moduller
+####################################################
+
+# Modülleri içe aktarabilirsiniz
+import math
+print(math.sqrt(16)) # => 4
+
+# Modülden belirli bir fonksiyonları alabilirsiniz
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Modüldeki tüm fonksiyonları içe aktarabilirsiniz
+# Dikkat: bunu yapmanızı önermem.
+from math import *
+
+# Modül isimlerini değiştirebilirsiniz.
+# Not: Modül ismini kısaltmanız çok daha iyi olacaktır
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Python modulleri aslında birer python dosyalarıdır.
+# İsterseniz siz de yazabilir ve içe aktarabilirsiniz Modulün
+# ismi ile dosyanın ismi aynı olacaktır.
+
+# Moduldeki fonksiyon ve değerleri öğrenebilirsiniz.
+import math
+dir(math)
+
+
+####################################################
+## 7. Gelişmiş
+####################################################
+
+# Oluşturucular uzun uzun kod yazmamanızı sağlayacak ve yardımcı olacaktır
+def kare_sayilar(nesne):
+ for i in nesne:
+ yield i + i
+
+# Bir oluşturucu(generator) değerleri anında oluşturur.
+# Bir seferde tüm değerleri oluşturup göndermek yerine teker teker her oluşumdan
+# sonra geri döndürür. Bu demektir ki, kare_sayilar fonksiyonumuzda 15'ten büyük
+# değerler işlenmeyecektir.
+# Not: range() da bir oluşturucu(generator)dur. 1-900000000 arası bir liste yapmaya çalıştığınızda
+# çok fazla vakit alacaktır.
+# Python tarafından belirlenen anahtar kelimelerden kaçınmak için basitçe alt çizgi(_) kullanılabilir.
+range_ = range(1, 900000000)
+# kare_sayilar'dan dönen değer 30'a ulaştığında durduralım
+for i in kare_sayilar(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Dekoratörler
+# Bu örnekte,
+# Eğer lutfen_soyle True ise dönen değer değişecektir.
+from functools import wraps
+
+
+def yalvar(hedef_fonksiyon):
+ @wraps(hedef_fonksiyon)
+ def metot(*args, **kwargs):
+ msj, lutfen_soyle = hedef_fonksiyon(*args, **kwargs)
+ if lutfen_soyle:
+ return "{} {}".format(msj, "Lütfen! Artık dayanamıyorum :(")
+ return msj
+
+ return metot
+
+
+@yalvar
+def soyle(lutfen_soyle=False):
+ msj = "Bana soda alır mısın?"
+ return msj, lutfen_soyle
+
+
+print(soyle()) # Bana soda alır mısın?
+print(soyle(lutfen_soyle=True)) # Ban soda alır mısın? Lutfen! Artık dayanamıyorum :(
+```
+
+## Daha Fazlasına Hazır Mısınız?
+
+### Ücretsiz 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/3/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
+
+### Kitaplar
+
+* [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/typescript.html.markdown b/typescript.html.markdown
index 27a1f71a..e9135510 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -9,7 +9,7 @@ TypeScript is a language that aims at easing development of large scale applicat
TypeScript adds common concepts such as classes, modules, interfaces, generics and (optional) static typing to JavaScript.
It is a superset of JavaScript: all JavaScript code is valid TypeScript code so it can be added seamlessly to any project. The TypeScript compiler emits JavaScript.
-This article will focus only on TypeScript extra syntax, as oposed to [JavaScript] (../javascript/).
+This article will focus only on TypeScript extra syntax, as opposed to [JavaScript] (../javascript/).
To test TypeScript's compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where you will be able to type code, have auto completion and directly see the emitted JavaScript.
diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown
index fbfa500d..00d61843 100644
--- a/visualbasic.html.markdown
+++ b/visualbasic.html.markdown
@@ -159,7 +159,7 @@ Module Module1
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.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine()
End Sub
@@ -189,7 +189,7 @@ Module Module1
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.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine()
'Ask the question, does the user wish to continue? Unfortunately it
'is case sensitive.
diff --git a/zh-cn/bash-cn.html.markdown b/zh-cn/bash-cn.html.markdown
index 6afa659a..558d9110 100644
--- a/zh-cn/bash-cn.html.markdown
+++ b/zh-cn/bash-cn.html.markdown
@@ -5,7 +5,14 @@ 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"]
+ - ["akirahirose", "https://twitter.com/akirahirose"]
+ - ["Anton Strömkvist", "http://lutic.org/"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gregrory Kielian", "https://github.com/gskielian"]
+ - ["Etan Reisner", "https://github.com/deryni"]
translators:
+ - ["Jinchang Ye", "https://github.com/Alwayswithme"]
- ["Chunyang Xu", "https://github.com/XuChunyang"]
filename: LearnBash-cn.sh
lang: zh-cn
@@ -23,31 +30,45 @@ Bash 是一个为 GNU 计划编写的 Unix shell,是 Linux 和 Mac OS X 下的
# 如你所见,注释以 # 开头,shebang 也是注释。
# 显示 “Hello world!”
-echo Hello, world!
+echo Hello world!
# 每一句指令以换行或分号隔开:
echo 'This is the first line'; echo 'This is the second line'
# 声明一个变量:
-VARIABLE="Some string"
+Variable="Some string"
# 下面是错误的做法:
-VARIABLE = "Some string"
-# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。
+Variable = "Some string"
+# Bash 会把 Variable 当做一个指令,由于找不到该指令,因此这里会报错。
+# 也不可以这样:
+Variable= 'Some string'
+# Bash 会认为 'Some string' 是一条指令,由于找不到该指令,这里再次报错。
+# (这个例子中 'Variable=' 这部分会被当作仅对 'Some string' 起作用的赋值。)
# 使用变量:
-echo $VARIABLE
-echo "$VARIABLE"
-echo '$VARIABLE'
+echo $Variable
+echo "$Variable"
+echo '$Variable'
# 当你赋值 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。
# 如果要使用变量的值, 则要加 $。
# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
# 在变量内部进行字符串代换
-echo ${VARIABLE/Some/A}
-# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。
+echo ${Variable/Some/A}
+# 会把 Variable 中首次出现的 "some" 替换成 “A”。
+
+# 变量的截取
+Length=7
+echo ${Variable:0:Length}
+# 这样会仅返回变量值的前7个字符
+
+# 变量的默认值
+echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
+# 对 null (Foo=) 和空串 (Foo="") 起作用; 零(Foo=0)时返回0
+# 注意这仅返回默认值而不是改变变量的值
# 内置变量:
# 下面的内置变量很有用
@@ -55,26 +76,37 @@ 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 "Scripts arguments separated in different variables: $1 $2..."
# 读取输入:
echo "What's your name?"
-read NAME # 这里不需要声明新变量
-echo Hello, $NAME!
+read Name # 这里不需要声明新变量
+echo Hello, $Name!
# 通常的 if 结构看起来像这样:
# 'man test' 可查看更多的信息
-if [ $NAME -ne $USER ]
+if [ $Name -ne $USER ]
then
- echo "Your name is you username"
+ echo "Your name isn't your username"
else
- echo "Your name isn't you username"
+ echo "Your name is your username"
fi
# 根据上一个指令执行结果决定是否执行下一个指令
-echo "Always executed" || echo "Only executed if first command fail"
+echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail"
+# 在 if 语句中使用 && 和 || 需要多对方括号
+if [ $Name == "Steve" ] && [ $Age -eq 15 ]
+then
+ echo "This will run if $Name is Steve AND $Age is 15."
+fi
+
+if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
+then
+ echo "This will run if $Name is Daniya OR Zach."
+fi
+
# 表达式的格式如下:
echo $(( 10 + 5 ))
@@ -88,18 +120,54 @@ ls -l # 列出文件和目录的详细信息
# 用下面的指令列出当前目录下所有的 txt 文件:
ls -l | grep "\.txt"
+# 重定向输入和输出(标准输入,标准输出,标准错误)。
+# 以 ^EOF$ 作为结束标记从标准输入读取数据并覆盖 hello.py :
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
# 重定向可以到输出,输入和错误输出。
-python2 hello.py < "input.in"
-python2 hello.py > "output.out"
-python2 hello.py 2> "error.err"
+python hello.py < "input.in"
+python hello.py > "output.out"
+python hello.py 2> "error.err"
+python hello.py > "output-and-error.log" 2>&1
+python hello.py > /dev/null 2>&1
# > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。
+python hello.py >> "output.out" 2>> "error.err"
+
+# 覆盖 output.out , 追加 error.err 并统计行数
+info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
+wc -l output.out error.err
+
+# 运行指令并打印文件描述符 (比如 /dev/fd/123)
+# 具体可查看: man fd
+echo <(echo "#helloworld")
+
+# 以 "#helloworld" 覆盖 output.out:
+cat > output.out <(echo "#helloworld")
+echo "#helloworld" > output.out
+echo "#helloworld" | cat > output.out
+echo "#helloworld" | tee output.out >/dev/null
+
+# 清理临时文件并显示详情(增加 '-i' 选项启用交互模式)
+rm -v output.out error.err output-and-error.log
# 一个指令可用 $( ) 嵌套在另一个指令内部:
# 以下的指令会打印当前目录下的目录和文件总数
echo "There are $(ls | wc -l) items here."
+# 反引号 `` 起相同作用,但不允许嵌套
+# 优先使用 $( ).
+echo "There are `ls | wc -l` items here."
+
# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
-case "$VARIABLE" in
+case "$Variable" in
# 列出需要匹配的字符串
0) echo "There is a zero.";;
1) echo "There is a one.";;
@@ -107,11 +175,37 @@ case "$VARIABLE" in
esac
# 循环遍历给定的参数序列:
-# 变量$VARIABLE 的值会被打印 3 次。
-# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。
-for VARIABLE in `seq 3`
+# 变量$Variable 的值会被打印 3 次。
+for Variable in {1..3}
+do
+ echo "$Variable"
+done
+
+# 或传统的 “for循环” :
+for ((a=1; a <= 3; a++))
do
- echo "$VARIABLE"
+ echo $a
+done
+
+# 也可以用于文件
+# 用 cat 输出 file1 和 file2 内容
+for Variable in file1 file2
+do
+ cat "$Variable"
+done
+
+# 或作用于其他命令的输出
+# 对 ls 输出的文件执行 cat 指令。
+for Output in $(ls)
+do
+ cat "$Output"
+done
+
+# while 循环:
+while [ true ]
+do
+ echo "loop body here..."
+ break
done
# 你也可以使用函数
@@ -132,17 +226,52 @@ bar ()
}
# 调用函数
-foo "My name is" $NAME
+foo "My name is" $Name
# 有很多有用的指令需要学习:
-tail -n 10 file.txt
# 打印 file.txt 的最后 10 行
-head -n 10 file.txt
+tail -n 10 file.txt
# 打印 file.txt 的前 10 行
-sort file.txt
+head -n 10 file.txt
# 将 file.txt 按行排序
-uniq -d file.txt
+sort file.txt
# 报告或忽略重复的行,用选项 -d 打印重复的行
-cut -d ',' -f 1 file.txt
+uniq -d file.txt
# 打印每行中 ',' 之前内容
+cut -d ',' -f 1 file.txt
+# 将 file.txt 文件所有 'okay' 替换为 'great', (兼容正则表达式)
+sed -i 's/okay/great/g' file.txt
+# 将 file.txt 中匹配正则的行打印到标准输出
+# 这里打印以 "foo" 开头, "bar" 结尾的行
+grep "^foo.*bar$" file.txt
+# 使用选项 "-c" 统计行数
+grep -c "^foo.*bar$" file.txt
+# 如果只是要按字面形式搜索字符串而不是按正则表达式,使用 fgrep (或 grep -F)
+fgrep "^foo.*bar$" file.txt
+
+
+# 以 bash 内建的 'help' 指令阅读 Bash 自带文档:
+help
+help help
+help for
+help return
+help source
+help .
+
+# 用 mam 指令阅读相关的 Bash 手册
+apropos bash
+man 1 bash
+man bash
+
+# 用 info 指令查阅命令的 info 文档 (info 中按 ? 显示帮助信息)
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+
+# 阅读 Bash 的 info 文档:
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
```
diff --git a/zh-cn/c++-cn.html.markdown b/zh-cn/c++-cn.html.markdown
new file mode 100644
index 00000000..e1551e2b
--- /dev/null
+++ b/zh-cn/c++-cn.html.markdown
@@ -0,0 +1,572 @@
+---
+language: c++
+filename: learncpp-cn.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+translators:
+ - ["Arnie97", "https://github.com/Arnie97"]
+lang: zh-cn
+---
+
+C++是一种系统编程语言。用它的发明者,
+[Bjarne Stroustrup的话](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)来说,C++的设计目标是:
+
+- 成为“更好的C语言”
+- 支持数据的抽象与封装
+- 支持面向对象编程
+- 支持泛型编程
+
+C++提供了对硬件的紧密控制(正如C语言一样),
+能够编译为机器语言,由处理器直接执行。
+与此同时,它也提供了泛型、异常和类等高层功能。
+虽然C++的语法可能比某些出现较晚的语言更复杂,它仍然得到了人们的青睞——
+功能与速度的平衡使C++成为了目前应用最广泛的系统编程语言之一。
+
+```c++
+////////////////
+// 与C语言的比较
+////////////////
+
+// C++_几乎_是C语言的一个超集,它与C语言的基本语法有许多相同之处,
+// 例如变量和函数的声明,原生数据类型等等。
+
+// 和C语言一样,在C++中,你的程序会从main()开始执行,
+// 该函数的返回值应当为int型,这个返回值会作为程序的退出状态值。
+// 不过,大多数的编译器(gcc,clang等)也接受 void main() 的函数原型。
+// (参见 http://en.wikipedia.org/wiki/Exit_status 来获取更多信息)
+int main(int argc, char** argv)
+{
+ // 和C语言一样,命令行参数通过argc和argv传递。
+ // argc代表命令行参数的数量,
+ // 而argv是一个包含“C语言风格字符串”(char *)的数组,
+ // 其中每个字符串代表一个命令行参数的内容,
+ // 首个命令行参数是调用该程序时所使用的名称。
+ // 如果你不关心命令行参数的值,argc和argv可以被忽略。
+ // 此时,你可以用int main()作为函数原型。
+
+ // 退出状态值为0时,表示程序执行成功
+ return 0;
+}
+
+// 然而,C++和C语言也有一些区别:
+
+// 在C++中,字符字面量的大小是一个字节。
+sizeof('c') == 1
+
+// 在C语言中,字符字面量的大小与int相同。
+sizeof('c') == sizeof(10)
+
+
+// C++的函数原型与函数定义是严格匹配的
+void func(); // 这个函数不能接受任何参数
+
+// 而在C语言中
+void func(); // 这个函数能接受任意数量的参数
+
+// 在C++中,用nullptr代替C语言中的NULL
+int* ip = nullptr;
+
+// C++也可以使用C语言的标准头文件,
+// 但是需要加上前缀“c”并去掉末尾的“.h”。
+#include <cstdio>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+///////////
+// 函数重载
+///////////
+
+// C++支持函数重载,你可以定义一组名称相同而参数不同的函数。
+
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // 解析为 void print(const char*)
+ print(15); // 解析为 void print(int)
+}
+
+///////////////////
+// 函数参数的默认值
+///////////////////
+
+// 你可以为函数的参数指定默认值,
+// 它们将会在调用者没有提供相应参数时被使用。
+
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // 对两个参数进行一些操作
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// 默认参数必须放在所有的常规参数之后。
+
+void invalidDeclaration(int a = 1, int b) // 这是错误的!
+{
+}
+
+
+///////////
+// 命名空间
+///////////
+
+// 命名空间为变量、函数和其他声明提供了分离的的作用域。
+// 命名空间可以嵌套使用。
+
+namespace First {
+ namespace Nested {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // 结束嵌套的命名空间Nested
+} // 结束命名空间First
+
+namespace Second {
+ void foo()
+ {
+ printf("This is Second::foo\n")
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // 如果没有特别指定,就从“Second”中取得所需的内容。
+ using namespace Second;
+
+ foo(); // 显示“This is Second::foo”
+ First::Nested::foo(); // 显示“This is First::Nested::foo”
+ ::foo(); // 显示“This is global foo”
+}
+
+////////////
+// 输入/输出
+////////////
+
+// C++使用“流”来输入输出。<<是流的插入运算符,>>是流提取运算符。
+// cin、cout、和cerr分别代表
+// stdin(标准输入)、stdout(标准输出)和stderr(标准错误)。
+
+#include <iostream> // 引入包含输入/输出流的头文件
+
+using namespace std; // 输入输出流在std命名空间(也就是标准库)中。
+
+int main()
+{
+ int myInt;
+
+ // 在标准输出(终端/显示器)中显示
+ cout << "Enter your favorite number:\n";
+ // 从标准输入(键盘)获得一个值
+ cin >> myInt;
+
+ // cout也提供了格式化功能
+ cout << "Your favorite number is " << myInt << "\n";
+ // 显示“Your favorite number is <myInt>”
+
+ cerr << "Used for error messages";
+}
+
+/////////
+// 字符串
+/////////
+
+// C++中的字符串是对象,它们有很多成员函数
+#include <string>
+
+using namespace std; // 字符串也在std命名空间(标准库)中。
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + 可以用于连接字符串。
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++中的字符串是可变的,具有“值语义”。
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+/////////////
+// 引用
+/////////////
+
+// 除了支持C语言中的指针类型以外,C++还提供了_引用_。
+// 引用是一种特殊的指针类型,一旦被定义就不能重新赋值,并且不能被设置为空值。
+// 使用引用时的语法与原变量相同:
+// 也就是说,对引用类型进行解引用时,不需要使用*;
+// 赋值时也不需要用&来取地址。
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // 建立了一个对foo的引用。
+fooRef += ". Hi!"; // 通过引用来修改foo的值
+cout << fooRef; // "I am foo. Hi!"
+
+// 这句话的并不会改变fooRef的指向,其效果与“foo = bar”相同。
+// 也就是说,在执行这条语句之后,foo == "I am bar"。
+fooRef = bar;
+
+const string& barRef = bar; // 建立指向bar的常量引用。
+// 和C语言中一样,(指针和引用)声明为常量时,对应的值不能被修改。
+barRef += ". Hi!"; // 这是错误的,不能修改一个常量引用的值。
+
+///////////////////
+// 类与面向对象编程
+///////////////////
+
+// 有关类的第一个示例
+#include <iostream>
+
+// 声明一个类。
+// 类通常在头文件(.h或.hpp)中声明。
+class Dog {
+ // 成员变量和成员函数默认情况下是私有(private)的。
+ std::string name;
+ int weight;
+
+// 在这个标签之后,所有声明都是公有(public)的,
+// 直到重新指定“private:”(私有继承)或“protected:”(保护继承)为止
+public:
+
+ // 默认的构造器
+ Dog();
+
+ // 这里是成员函数声明的一个例子。
+ // 可以注意到,我们在此处使用了std::string,而不是using namespace std
+ // 语句using namespace绝不应当出现在头文件当中。
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // 如果一个函数不对对象的状态进行修改,
+ // 应当在声明中加上const。
+ // 这样,你就可以对一个以常量方式引用的对象执行该操作。
+ // 同时可以注意到,当父类的成员函数需要被子类重写时,
+ // 父类中的函数必须被显式声明为_虚函数(virtual)_。
+ // 考虑到性能方面的因素,函数默认情况下不会被声明为虚函数。
+ virtual void print() const;
+
+ // 函数也可以在class body内部定义。
+ // 这样定义的函数会自动成为内联函数。
+ void bark() const { std::cout << name << " barks!\n" }
+
+ // 除了构造器以外,C++还提供了析构器。
+ // 当一个对象被删除或者脱离其定义域时,它的析构函数会被调用。
+ // 这使得RAII这样的强大范式(参见下文)成为可能。
+ // 为了衍生出子类来,基类的析构函数必须定义为虚函数。
+ virtual ~Dog();
+
+}; // 在类的定义之后,要加一个分号
+
+// 类的成员函数通常在.cpp文件中实现。
+void Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// 对象(例如字符串)应当以引用的形式传递,
+// 对于不需要修改的对象,最好使用常量引用。
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// 虚函数的virtual关键字只需要在声明时使用,不需要在定义时重复
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+void Dog::~Dog()
+{
+ cout << "Goodbye " << name << "\n";
+}
+
+int main() {
+ Dog myDog; // 此时显示“A dog has been constructed”
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.printDog(); // 显示“Dog is Barkley and weighs 10 kg”
+ return 0;
+} // 显示“Goodbye Barkley”
+
+// 继承:
+
+// 这个类继承了Dog类中的公有(public)和保护(protected)对象
+class OwnedDog : public Dog {
+
+ void setOwner(const std::string& dogsOwner)
+
+ // 重写OwnedDogs类的print方法。
+ // 如果你不熟悉子类多态的话,可以参考这个页面中的概述:
+ // http://zh.wikipedia.org/wiki/%E5%AD%90%E7%B1%BB%E5%9E%8B
+
+ // override关键字是可选的,它确保你所重写的是基类中的方法。
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// 与此同时,在对应的.cpp文件里:
+
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // 调用基类Dog中的print方法
+ // "Dog is <name> and weights <weight>"
+
+ std::cout << "Dog is owned by " << owner << "\n";
+ // "Dog is owned by <owner>"
+}
+
+/////////////////////
+// 初始化与运算符重载
+/////////////////////
+
+// 在C++中,通过定义一些特殊名称的函数,
+// 你可以重载+、-、*、/等运算符的行为。
+// 当运算符被使用时,这些特殊函数会被调用,从而实现运算符重载。
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // 可以以这样的方式为成员变量设置默认值。
+ double x = 0;
+ double y = 0;
+
+ // 定义一个默认的构造器。
+ // 除了将Point初始化为(0, 0)以外,这个函数什么都不做。
+ Point() { };
+
+ // 下面使用的语法称为初始化列表,
+ // 这是初始化类中成员变量的正确方式。
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* 除了初始化成员变量外,什么都不做 */ }
+
+ // 重载 + 运算符
+ Point operator+(const Point& rhs) const;
+
+ // 重载 += 运算符
+ Point& operator+=(const Point& rhs);
+
+ // 增加 - 和 -= 运算符也是有意义的,但这里不再赘述。
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // 创建一个新的点,
+ // 其横纵坐标分别为这个点与另一点在对应方向上的坐标之和。
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Point up (0,1);
+ Point right (1,0);
+ // 这里使用了Point类型的运算符“+”
+ // 调用up(Point类型)的“+”方法,并以right作为函数的参数
+ Point result = up + right;
+ // 显示“Result is upright (1,1)”
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+///////////
+// 异常处理
+///////////
+
+// 标准库中提供了一些基本的异常类型
+// (参见http://en.cppreference.com/w/cpp/error/exception)
+// 但是,其他任何类型也可以作为一个异常被拋出
+#include <exception>
+
+// 在_try_代码块中拋出的异常可以被随后的_catch_捕获。
+try {
+ // 不要用 _new_关键字在堆上为异常分配空间。
+ throw std::exception("A problem occurred");
+}
+// 如果拋出的异常是一个对象,可以用常量引用来捕获它
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+// 捕获尚未被_catch_处理的所有错误
+} catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // 重新拋出异常
+}
+
+///////
+// RAII
+///////
+
+// RAII指的是“资源获取就是初始化”(Resource Allocation Is Initialization),
+// 它被视作C++中最强大的编程范式之一。
+// 简单说来,它指的是,用构造函数来获取一个对象的资源,
+// 相应的,借助析构函数来释放对象的资源。
+
+// 为了理解这一范式的用处,让我们考虑某个函数使用文件句柄时的情况:
+void doSomethingWithAFile(const char* filename)
+{
+ // 首先,让我们假设一切都会顺利进行。
+
+ FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // 关闭文件句柄
+}
+
+// 不幸的是,随着错误处理机制的引入,事情会变得复杂。
+// 假设fopen函数有可能执行失败,
+// 而doSomethingWithTheFile和doSomethingElseWithIt会在失败时返回错误代码。
+// (虽然异常是C++中处理错误的推荐方式,
+// 但是某些程序员,尤其是有C语言背景的,并不认可异常捕获机制的作用)。
+// 现在,我们必须检查每个函数调用是否成功执行,并在问题发生的时候关闭文件句柄。
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
+ if (fh == nullptr) // 当执行失败是,返回的指针是nullptr
+ return false; // 向调用者汇报错误
+
+ // 假设每个函数会在执行失败时返回false
+ if (!doSomethingWithTheFile(fh)) {
+ fclose(fh); // 关闭文件句柄,避免造成内存泄漏。
+ return false; // 反馈错误
+ }
+ if (!doSomethingElseWithIt(fh)) {
+ fclose(fh); // 关闭文件句柄
+ return false; // 反馈错误
+ }
+
+ fclose(fh); // 关闭文件句柄
+ return true; // 指示函数已成功执行
+}
+
+// C语言的程序员通常会借助goto语句简化上面的代码:
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!doSomethingWithTheFile(fh))
+ goto failure;
+
+ if (!doSomethingElseWithIt(fh))
+ goto failure;
+
+ fclose(fh); // 关闭文件
+ return true; // 执行成功
+
+failure:
+ fclose(fh);
+ return false; // 反馈错误
+}
+
+// 如果用异常捕获机制来指示错误的话,
+// 代码会变得清晰一些,但是仍然有优化的余地。
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
+ if (fh == nullptr)
+ throw std::exception("Could not open the file.");
+
+ try {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...) {
+ fclose(fh); // 保证出错的时候文件被正确关闭
+ throw; // 之后,重新抛出这个异常
+ }
+
+ fclose(fh); // 关闭文件
+ // 所有工作顺利完成
+}
+
+// 相比之下,使用C++中的文件流类(fstream)时,
+// fstream会利用自己的析构器来关闭文件句柄。
+// 只要离开了某一对象的定义域,它的析构函数就会被自动调用。
+void doSomethingWithAFile(const std::string& filename)
+{
+ // ifstream是输入文件流(input file stream)的简称
+ std::ifstream fh(filename); // 打开一个文件
+
+ // 对文件进行一些操作
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // 文件已经被析构器自动关闭
+
+// 与上面几种方式相比,这种方式有着_明显_的优势:
+// 1. 无论发生了什么情况,资源(此例当中是文件句柄)都会被正确关闭。
+// 只要你正确使用了析构器,就_不会_因为忘记关闭句柄,造成资源的泄漏。
+// 2. 可以注意到,通过这种方式写出来的代码十分简洁。
+// 析构器会在后台关闭文件句柄,不再需要你来操心这些琐事。
+// 3. 这种方式的代码具有异常安全性。
+// 无论在函数中的何处拋出异常,都不会阻碍对文件资源的释放。
+
+// 地道的C++代码应当把RAII的使用扩展到各种类型的资源上,包括:
+// - 用unique_ptr和shared_ptr管理的内存
+// - 各种数据容器,例如标准库中的链表、向量(容量自动扩展的数组)、散列表等;
+// 当它们脱离作用域时,析构器会自动释放其中储存的内容。
+// - 用lock_guard和unique_lock实现的互斥
+```
+扩展阅读:
+
+<http://cppreference.com/w/cpp> 提供了最新的语法参考。
+
+可以在 <http://cplusplus.com> 找到一些补充资料。
diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown
index 9f6a8c15..3a461efe 100644
--- a/zh-cn/go-cn.html.markdown
+++ b/zh-cn/go-cn.html.markdown
@@ -283,4 +283,4 @@ Go的根源在[Go官方网站](http://golang.org/)。
强烈推荐阅读语言定义部分,很简单而且很简洁!(as language definitions go these days.)
-学习Go还要阅读Go标准库的源代码,全部文档化了,可读性非常好,可以学到go,go style和go idioms。在文档中点击函数名,源代码就出来了!
+学习Go还要阅读Go[标准库的源代码](http://golang.org/src/),全部文档化了,可读性非常好,可以学到go,go style和go idioms。在[文档](http://golang.org/pkg/)中点击函数名,源代码就出来了!
diff --git a/zh-cn/groovy-cn.html.markdown b/zh-cn/groovy-cn.html.markdown
new file mode 100644
index 00000000..562a0284
--- /dev/null
+++ b/zh-cn/groovy-cn.html.markdown
@@ -0,0 +1,420 @@
+---
+language: Groovy
+filename: learngroovy-cn.groovy
+contributors:
+ - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
+translators:
+ - ["Todd Gao", "http://github.com/7c00"]
+lang: zh-cn
+---
+
+Groovy - Java平台的动态语言。[了解更多。](http://www.groovy-lang.org/)
+
+```groovy
+
+/*
+ 安装:
+
+ 1) 安装 GVM - http://gvmtool.net/
+ 2) 安装 Groovy: gvm install groovy
+ 3) 启动 groovy 控制台,键入: groovyConsole
+
+*/
+
+// 双斜线开始的是单行注释
+/*
+像这样的是多行注释
+*/
+
+// Hello World
+println "Hello world!"
+
+/*
+ 变量:
+
+ 可以给变量赋值,以便稍后使用
+*/
+
+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
+
+/*
+ 集合和映射
+*/
+
+//创建一个空的列表
+def technologies = []
+
+/*** 往列表中增加一个元素 ***/
+
+// 和Java一样
+technologies.add("Grails")
+
+// 左移添加,返回该列表
+technologies << "Groovy"
+
+// 增加多个元素
+technologies.addAll(["Gradle","Griffon"])
+
+/*** 从列表中删除元素 ***/
+
+// 和Java一样
+technologies.remove("Griffon")
+
+// 减号也行
+technologies = technologies - 'Grails'
+
+/*** 遍历列表 ***/
+
+// 遍历列表中的元素
+technologies.each { println "Technology: $it"}
+technologies.eachWithIndex { it, i -> println "$i: $it"}
+
+/*** 检查列表内容 ***/
+
+//判断列表是否包含某元素,返回boolean
+contained = technologies.contains( 'Groovy' )
+
+// 或
+contained = 'Groovy' in technologies
+
+// 检查多个元素
+technologies.containsAll(['Groovy','Grails'])
+
+/*** 列表排序 ***/
+
+// 排序列表(修改原列表)
+technologies.sort()
+
+// 要想不修改原列表,可以这样:
+sortedTechnologies = technologies.sort( false )
+
+/*** 列表操作 ***/
+
+//替换列表元素
+Collections.replaceAll(technologies, 'Gradle', 'gradle')
+
+//打乱列表
+Collections.shuffle(technologies, new Random())
+
+//清空列表
+technologies.clear()
+
+//创建空的映射
+def devMap = [:]
+
+//增加值
+devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+devMap.put('lastName','Perez')
+
+//遍历映射元素
+devMap.each { println "$it.key: $it.value" }
+devMap.eachWithIndex { it, i -> println "$i: $it"}
+
+//判断映射是否包含某键
+assert devMap.containsKey('name')
+
+//判断映射是否包含某值
+assert devMap.containsValue('Roberto')
+
+//取得映射所有的键
+println devMap.keySet()
+
+//取得映射所有的值
+println devMap.values()
+
+/*
+ Groovy Beans
+
+ GroovyBeans 是 JavaBeans,但使用了更简单的语法
+
+ Groovy 被编译为字节码时,遵循下列规则。
+
+ * 如果一个名字声明时带有访问修饰符(public, private, 或者 protected),
+ 则会生成一个字段(field)。
+
+ * 名字声明时没有访问修饰符,则会生成一个带有public getter和setter的
+ private字段,即属性(property)。
+
+ * 如果一个属性声明为final,则会创建一个final的private字段,但不会生成setter。
+
+ * 可以声明一个属性的同时定义自己的getter和setter。
+
+ * 可以声明具有相同名字的属性和字段,该属性会使用该字段。
+
+ * 如果要定义private或protected属性,必须提供声明为private或protected的getter
+ 和setter。
+
+ * 如果使用显式或隐式的 this(例如 this.foo, 或者 foo)访问类的在编译时定义的属性,
+ Groovy会直接访问对应字段,而不是使用getter或者setter
+
+ * 如果使用显式或隐式的 foo 访问一个不存在的属性,Groovy会通过元类(meta class)
+ 访问它,这可能导致运行时错误。
+
+*/
+
+class Foo {
+ // 只读属性
+ final String name = "Roberto"
+
+ // 只读属性,有public getter和protected setter
+ String language
+ protected void setLanguage(String language) { this.language = language }
+
+ // 动态类型属性
+ def lastName
+}
+
+/*
+ 逻辑分支和循环
+*/
+
+//Groovy支持常见的if - else语法
+def x = 3
+
+if(x==1) {
+ println "One"
+} else if(x==2) {
+ println "Two"
+} else {
+ println "X greater than Two"
+}
+
+//Groovy也支持三元运算符
+def y = 10
+def x = (y > 1) ? "worked" : "failed"
+assert x == "worked"
+
+//for循环
+//使用区间(range)遍历
+def x = 0
+for (i in 0 .. 30) {
+ x += i
+}
+
+//遍历列表
+x = 0
+for( i in [5,3,2,1] ) {
+ x += i
+}
+
+//遍历数组
+array = (0..20).toArray()
+x = 0
+for (i in array) {
+ x += i
+}
+
+//遍历映射
+def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+x = 0
+for ( e in map ) {
+ x += e.value
+}
+
+/*
+ 运算符
+
+ 在Groovy中以下常用运算符支持重载:
+ http://www.groovy-lang.org/operators.html#Operator-Overloading
+
+ 实用的groovy运算符
+*/
+//展开(spread)运算符:对聚合对象的所有元素施加操作
+def technologies = ['Groovy','Grails','Gradle']
+technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }
+
+//安全导航(safe navigation)运算符:用来避免NullPointerException
+def user = User.get(1)
+def username = user?.username
+
+
+/*
+ 闭包
+ Groovy闭包好比代码块或者方法指针,它是一段代码定义,可以以后执行。
+
+ 更多信息见:http://www.groovy-lang.org/closures.html
+*/
+//例子:
+def clos = { println "Hello World!" }
+
+println "Executing the Closure:"
+clos()
+
+//传参数给闭包
+def sum = { a, b -> println a+b }
+sum(2,4)
+
+//闭包可以引用参数列表以外的变量
+def x = 5
+def multiplyBy = { num -> num * x }
+println multiplyBy(10)
+
+// 只有一个参数的闭包可以省略参数的定义
+def clos = { print it }
+clos( "hi" )
+
+/*
+ Groovy可以记忆闭包结果 [1][2][3]
+*/
+def cl = {a, b ->
+ sleep(3000) // 模拟费时操作
+ 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
+
+ Expando类是一种动态bean类,可以给它的实例添加属性和添加闭包作为方法
+
+ 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)
+
+
+/*
+ 元编程(MOP)
+*/
+
+//使用ExpandoMetaClass增加行为
+String.metaClass.testAdd = {
+ println "we added this"
+}
+
+String x = "test"
+x?.testAdd()
+
+//拦截方法调用
+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支持propertyMissing,来处理属性解析尝试
+class Foo {
+ def propertyMissing(String name) { name }
+}
+def f = new Foo()
+
+assertEquals "boo", f.boo
+
+/*
+ 类型检查和静态编译
+ Groovy天生是并将永远是一门动态语言,但也支持类型检查和静态编译
+
+ 更多: http://www.infoq.com/articles/new-groovy-20
+*/
+//类型检查
+import groovy.transform.TypeChecked
+
+void testMethod() {}
+
+@TypeChecked
+void test() {
+ testMeethod()
+
+ def name = "Roberto"
+
+ println naameee
+
+}
+
+//另一例子
+import groovy.transform.TypeChecked
+
+@TypeChecked
+Integer test() {
+ Integer num = "1"
+
+ Integer[] numbers = [1,2,3,4]
+
+ Date date = numbers[1]
+
+ return "Test"
+
+}
+
+//静态编译例子
+import groovy.transform.CompileStatic
+
+@CompileStatic
+int sum(int x, int y) {
+ x + y
+}
+
+assert sum(2,5) == 7
+
+
+```
+
+## 进阶资源
+
+[Groovy文档](http://www.groovy-lang.org/documentation.html)
+
+[Groovy web console](http://groovyconsole.appspot.com/)
+
+加入[Groovy用户组](http://www.groovy-lang.org/usergroups.html)
+
+## 图书
+
+* [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/zh-cn/haskell-cn.html.markdown b/zh-cn/haskell-cn.html.markdown
index cb7ccdee..8904970f 100644
--- a/zh-cn/haskell-cn.html.markdown
+++ b/zh-cn/haskell-cn.html.markdown
@@ -5,24 +5,25 @@ contributors:
- ["Adit Bhargava", "http://adit.io"]
translators:
- ["Peiyong Lin", ""]
+ - ["chad luo", "http://yuki.rocks"]
lang: zh-cn
---
-Haskell 被设计成一种实用的纯函数式编程语言。它因为 monads 及其类型系统而出名,但是我回归到它本身因为。Haskell 使得编程对于我而言是一种真正的快乐。
+Haskell 是一门实用的函数式编程语言,因其 Monads 与类型系统而闻名。而我使用它则是因为它异常优雅。用 Haskell 编程令我感到非常快乐。
```haskell
--- 单行注释以两个破折号开头
+-- 单行注释以两个减号开头
{- 多行注释像这样
- 被一个闭合的块包围
+ 被一个闭合的块包围
-}
----------------------------------------------------
-- 1. 简单的数据类型和操作符
----------------------------------------------------
--- 你有数字
+-- 数字
3 -- 3
--- 数学计算就像你所期待的那样
+-- 数学计算
1 + 1 -- 2
8 - 1 -- 7
10 * 2 -- 20
@@ -34,7 +35,7 @@ Haskell 被设计成一种实用的纯函数式编程语言。它因为 monads
-- 整除
35 `div` 4 -- 8
--- 布尔值也简单
+-- 布尔值
True
False
@@ -45,21 +46,22 @@ not False -- True
1 /= 1 -- False
1 < 10 -- True
--- 在上述的例子中,`not` 是一个接受一个值的函数。
--- Haskell 不需要括号来调用函数。。。所有的参数
--- 都只是在函数名之后列出来。因此,通常的函数调用模式是:
--- func arg1 arg2 arg3...
--- 查看关于函数的章节以获得如何写你自己的函数的相关信息。
+-- 在上面的例子中,`not` 是一个接受一个参数的函数。
+-- Haskell 不需要括号来调用函数,所有的参数都只是在函数名之后列出来
+-- 因此,通常的函数调用模式是:
+-- func arg1 arg2 arg3...
+-- 你可以查看函数部分了解如何自行编写。
-- 字符串和字符
-"This is a string."
+"This is a string." -- 字符串
'a' -- 字符
'对于字符串你不能使用单引号。' -- 错误!
--- 连结字符串
+-- 连接字符串
"Hello " ++ "world!" -- "Hello world!"
-- 一个字符串是一系列字符
+['H', 'e', 'l', 'l', 'o'] -- "Hello"
"This is a string" !! 0 -- 'T'
@@ -67,162 +69,164 @@ not False -- True
-- 列表和元组
----------------------------------------------------
--- 一个列表中的每一个元素都必须是相同的类型
--- 下面两个列表一样
+-- 一个列表中的每一个元素都必须是相同的类型。
+-- 下面两个列表等价
[1, 2, 3, 4, 5]
[1..5]
--- 在 Haskell 你可以拥有含有无限元素的列表
-[1..] -- 一个含有所有自然数的列表
+-- 区间也可以这样
+['A'..'F'] -- "ABCDEF"
--- 因为 Haskell 有“懒惰计算”,所以无限元素的列表可以正常运作。这意味着
--- Haskell 可以只在它需要的时候计算。所以你可以请求
--- 列表中的第1000个元素,Haskell 会返回给你
+-- 你可以在区间中指定步进
+[0,2..10] -- [0, 2, 4, 6, 8, 10]
+[5..1] -- 这样不行,因为 Haskell 默认递增
+[5,4..1] -- [5, 4, 3, 2, 1]
-[1..] !! 999 -- 1000
+-- 列表下标
+[0..] !! 5 -- 5
--- Haskell 计算了列表中 1 - 1000 个元素。。。但是
--- 这个无限元素的列表中剩下的元素还不存在! Haskell 不会
--- 真正地计算它们知道它需要。
+-- 在 Haskell 你可以使用无限列表
+[1..] -- 一个含有所有自然数的列表
-<FS>- 连接两个列表
+-- 无限列表的原理是,Haskell 有“惰性求值”。
+-- 这意味着 Haskell 只在需要时才会计算。
+-- 所以当你获取列表的第 1000 项元素时,Haskell 会返回给你:
+[1..] !! 999 -- 1000
+-- Haskell 计算了列表中第 1 至 1000 项元素,但这个无限列表中剩下的元素还不存在。
+-- Haskell 只有在需要时才会计算它们。
+
+-- 连接两个列表
[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 comprehension)
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
-- 附带条件
[x*2 | x <-[1..5], x*2 > 4] -- [6, 8, 10]
--- 元组中的每一个元素可以是不同类型的,但是一个元组
--- 的长度是固定的
+-- 元组中的每一个元素可以是不同类型,但是一个元组的长度是固定的
-- 一个元组
("haskell", 1)
--- 获取元组中的元素
+-- 获取元组中的元素(例如,一个含有 2 个元素的元祖)
fst ("haskell", 1) -- "haskell"
snd ("haskell", 1) -- 1
----------------------------------------------------
-- 3. 函数
----------------------------------------------------
+
-- 一个接受两个变量的简单函数
add a b = a + b
--- 注意,如果你使用 ghci (Hakell 解释器)
--- 你将需要使用 `let`,也就是
+-- 注意,如果你使用 ghci (Hakell 解释器),你需要使用 `let`,也就是
-- let add a b = a + b
--- 使用函数
+-- 调用函数
add 1 2 -- 3
--- 你也可以把函数放置在两个参数之间
--- 附带倒引号:
+-- 你也可以使用反引号中置函数名:
1 `add` 2 -- 3
--- 你也可以定义不带字符的函数!这使得
--- 你定义自己的操作符!这里有一个操作符
--- 来做整除
+-- 你也可以定义不带字母的函数名,这样你可以定义自己的操作符。
+-- 这里有一个做整除的操作符
(//) a b = a `div` b
35 // 4 -- 8
--- 守卫:一个简单的方法在函数里做分支
+-- Guard:一个在函数中做条件判断的简单方法
fib x
| x < 2 = x
| otherwise = fib (x - 1) + fib (x - 2)
--- 模式匹配是类型的。这里有三种不同的 fib
--- 定义。Haskell 将自动调用第一个
--- 匹配值的模式的函数。
+-- 模式匹配与 Guard 类似。
+-- 这里给出了三个不同的 fib 定义。
+-- Haskell 会自动调用第一个符合参数模式的声明
fib 1 = 1
fib 2 = 2
fib x = fib (x - 1) + fib (x - 2)
--- 元组的模式匹配:
+-- 元组的模式匹配
foo (x, y) = (x + 1, y + 2)
--- 列表的模式匹配。这里 `x` 是列表中第一个元素,
--- 并且 `xs` 是列表剩余的部分。我们可以写
--- 自己的 map 函数:
+-- 列表的模式匹配
+-- 这里 `x` 是列表中第一个元素,`xs` 是列表剩余的部分。
+-- 我们可以实现自己的 map 函数:
myMap func [] = []
myMap func (x:xs) = func x:(myMap func xs)
--- 编写出来的匿名函数带有一个反斜杠,后面跟着
--- 所有的参数。
+-- 匿名函数带有一个反斜杠,后面跟着所有的参数
myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
--- 使用 fold (在一些语言称为`inject`)随着一个匿名的
--- 函数。foldl1 意味着左折叠(fold left), 并且使用列表中第一个值
--- 作为累加器的初始化值。
+-- 在 fold(在一些语言称 为`inject`)中使用匿名函数
+-- foldl1 意味着左折叠 (fold left), 并且使用列表中第一个值作为累加器的初始值。
foldl1 (\acc x -> acc + x) [1..5] -- 15
----------------------------------------------------
--- 4. 更多的函数
+-- 4. 其它函数
----------------------------------------------------
--- 柯里化(currying):如果你不传递函数中所有的参数,
--- 它就变成“柯里化的”。这意味着,它返回一个接受剩余参数的函数。
-
+-- 部分调用
+-- 如果你调用函数时没有给出所有参数,它就被“部分调用”。
+-- 它将返回一个接受余下参数的函数。
add a b = a + b
foo = add 10 -- foo 现在是一个接受一个数并对其加 10 的函数
foo 5 -- 15
--- 另外一种方式去做同样的事
+-- 另一种等价写法
foo = (+10)
foo 5 -- 15
--- 函数组合
--- (.) 函数把其它函数链接到一起
--- 举个列子,这里 foo 是一个接受一个值的函数。它对接受的值加 10,
--- 并对结果乘以 5,之后返回最后的值。
+-- 函列表合
+-- (.) 函数把其它函数链接到一起。
+-- 例如,这里 foo 是一个接受一个值的函数。
+-- 它对接受的值加 10,并对结果乘以 5,之后返回最后的值。
foo = (*5) . (+10)
-- (5 + 10) * 5 = 75
foo 5 -- 75
--- 修复优先级
--- Haskell 有另外一个函数称为 `$`。它改变优先级
--- 使得其左侧的每一个操作先计算然后应用到
--- 右侧的每一个操作。你可以使用 `.` 和 `$` 来除去很多
--- 括号:
+-- 修正优先级
+-- Haskell 有另外一个函数 `$` 可以改变优先级。
+-- `$` 使得 Haskell 先计算其右边的部分,然后调用左边的部分。
+-- 你可以使用 `$` 来移除多余的括号。
--- before
+-- 修改前
(even (fib 7)) -- true
--- after
+-- 修改后
even . fib $ 7 -- true
+-- 等价地
+even $ fib 7 -- true
+
----------------------------------------------------
--- 5. 类型签名
+-- 5. 类型声明
----------------------------------------------------
--- Haskell 有一个非常强壮的类型系统,一切都有一个类型签名。
+-- Haskell 有一个非常强大的类型系统,一切都有一个类型声明。
-- 一些基本的类型:
5 :: Integer
"hello" :: String
True :: Bool
--- 函数也有类型。
--- `not` 接受一个布尔型返回一个布尔型:
+-- 函数也有类型
+-- `not` 接受一个布尔型返回一个布尔型
-- not :: Bool -> Bool
--- 这是接受两个参数的函数:
+-- 这是接受两个参数的函数
-- add :: Integer -> Integer -> Integer
--- 当你定义一个值,在其上写明它的类型是一个好实践:
+-- 当你定义一个值,声明其类型是一个好做法
double :: Integer -> Integer
double x = x * 2
@@ -230,159 +234,148 @@ double x = x * 2
-- 6. 控制流和 If 语句
----------------------------------------------------
--- if 语句
+-- if 语句:
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
--- if 语句也可以有多行,缩进是很重要的
+-- if 语句也可以有多行,注意缩进:
haskell = if 1 == 1
then "awesome"
else "awful"
--- case 语句:这里是你可以怎样去解析命令行参数
+-- case 语句
+-- 解析命令行参数:
case args of
"help" -> printHelp
"start" -> startProgram
_ -> putStrLn "bad args"
--- Haskell 没有循环因为它使用递归取代之。
--- map 应用一个函数到一个数组中的每一个元素
-
+-- Haskell 没有循环,它使用递归
+-- map 对一个列表中的每一个元素调用一个函数
map (*2) [1..5] -- [2, 4, 6, 8, 10]
-- 你可以使用 map 来编写 for 函数
for array func = map func array
--- 然后使用它
+-- 调用
for [0..5] $ \i -> show i
--- 我们也可以像这样写:
+-- 我们也可以像这样写
for [0..5] show
-- 你可以使用 foldl 或者 foldr 来分解列表
-- foldl <fn> <initial value> <list>
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
--- 这和下面是一样的
+-- 等价于
(2 * (2 * (2 * 4 + 1) + 2) + 3)
--- foldl 是左手边的,foldr 是右手边的-
+-- foldl 从左开始,foldr 从右
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
--- 这和下面是一样的
+-- 现在它等价于
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
----------------------------------------------------
-- 7. 数据类型
----------------------------------------------------
--- 这里展示在 Haskell 中你怎样编写自己的数据类型
-
+-- 在 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" -- of type `Maybe String`
-Just 1 -- of type `Maybe Int`
-Nothing -- of type `Maybe a` for any `a`
+-- 这些都是 Maybe 类型:
+Just "hello" -- `Maybe String` 类型
+Just 1 -- `Maybe Int` 类型
+Nothing -- 对任意 `a` 为 `Maybe a` 类型
----------------------------------------------------
-- 8. Haskell IO
----------------------------------------------------
--- 虽然在没有解释 monads 的情况下 IO不能被完全地解释,
--- 着手解释到位并不难。
-
--- 当一个 Haskell 程序被执行,函数 `main` 就被调用。
--- 它必须返回一个类型 `IO ()` 的值。举个列子:
+-- 虽然不解释 Monads 就无法完全解释 IO,但大致了解并不难。
+-- 当执行一个 Haskell 程序时,函数 `main` 就被调用。
+-- 它必须返回一个类型 `IO ()` 的值。例如:
main :: IO ()
main = putStrLn $ "Hello, sky! " ++ (say Blue)
--- putStrLn has type String -> IO ()
+-- putStrLn 的类型是 String -> IO ()
--- 如果你能实现你的程序依照函数从 String 到 String,那样编写 IO 是最简单的。
+-- 如果你的程序输入 String 返回 String,那样编写 IO 是最简单的。
-- 函数
-- interact :: (String -> String) -> IO ()
--- 输入一些文本,在其上运行一个函数,并打印出输出
+-- 输入一些文本,对其调用一个函数,并打印输出。
countLines :: String -> String
countLines = show . length . lines
main' = interact countLines
--- 你可以考虑一个 `IO()` 类型的值,当做一系列计算机所完成的动作的代表,
--- 就像一个以命令式语言编写的计算机程序。我们可以使用 `do` 符号来把动作链接到一起。
--- 举个列子:
-
+-- 你可以认为一个 `IO ()` 类型的值是表示计算机做的一系列操作,类似命令式语言。
+-- 我们可以使用 `do` 声明来把动作连接到一起。
+-- 举个列子
sayHello :: IO ()
sayHello = do
putStrLn "What is your name?"
- name <- getLine -- this gets a line and gives it the name "input"
+ name <- getLine -- 这里接受一行输入并绑定至 "name"
putStrLn $ "Hello, " ++ name
-- 练习:编写只读取一行输入的 `interact`
-- 然而,`sayHello` 中的代码将不会被执行。唯一被执行的动作是 `main` 的值。
--- 为了运行 `sayHello`,注释上面 `main` 的定义,并代替它:
+-- 为了运行 `sayHello`,注释上面 `main` 的定义,替换为:
-- main = sayHello
--- 让我们来更好地理解刚才所使用的函数 `getLine` 是怎样工作的。它的类型是:
+-- 让我们来更进一步理解刚才所使用的函数 `getLine` 是怎样工作的。它的类型是:
-- getLine :: IO String
--- 你可以考虑一个 `IO a` 类型的值,代表一个当被执行的时候
--- 将产生一个 `a` 类型的值的计算机程序(除了它所做的任何事之外)。我们可以保存和重用这个值通过 `<-`。
--- 我们也可以写自己的 `IO String` 类型的动作:
-
+-- 你可以认为一个 `IO a` 类型的值代表了一个运行时会生成一个 `a` 类型值的程序。
+-- (可能伴随其它行为)
+-- 我们可以通过 `<-` 保存和重用这个值。
+-- 我们也可以实现自己的 `IO String` 类型函数:
action :: IO String
action = do
putStrLn "This is a line. Duh"
input1 <- getLine
input2 <- getLine
- -- The type of the `do` statement is that of its last line.
- -- `return` is not a keyword, but merely a function
+ -- `do` 语句的类型是它的最后一行
+ -- `return` 不是关键字,只是一个普通函数
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
--- 我们可以使用这个动作就像我们使用 `getLine`:
-
+-- 我们可以像调用 `getLine` 一样调用它
main'' = do
putStrLn "I will echo two lines!"
result <- action
putStrLn result
putStrLn "This was all, folks!"
--- `IO` 类型是一个 "monad" 的例子。Haskell 使用一个 monad 来做 IO的方式允许它是一门纯函数式语言。
--- 任何与外界交互的函数(也就是 IO) 都在它的类型签名处做一个 `IO` 标志
--- 着让我们推出 什么样的函数是“纯洁的”(不与外界交互,不修改状态) 和 什么样的函数不是 “纯洁的”
-
--- 这是一个强有力的特征,因为并发地运行纯函数是简单的;因此,Haskell 中并发是非常简单的。
-
+-- `IO` 类型是一个 "Monad" 的例子。
+-- Haskell 通过使用 Monad 使得其本身为纯函数式语言。
+-- 任何与外界交互的函数(即 IO)都在它的类型声明中标记为 `IO`。
+-- 这告诉我们什么样的函数是“纯洁的”(不与外界交互,不修改状态) ,
+-- 什么样的函数不是 “纯洁的”。
+-- 这个功能非常强大,因为纯函数并发非常容易,由此在 Haskell 中做并发非常容易。
----------------------------------------------------
--- 9. The Haskell REPL
+-- 9. Haskell REPL
----------------------------------------------------
--- 键入 `ghci` 开始 repl。
+-- 键入 `ghci` 开始 REPL。
-- 现在你可以键入 Haskell 代码。
--- 任何新值都需要通过 `let` 来创建:
-
+-- 任何新值都需要通过 `let` 来创建
let foo = 5
--- 你可以查看任何值的类型,通过命令 `:t`:
-
+-- 你可以通过命令 `:t` 查看任何值的类型
>:t foo
foo :: Integer
-- 你也可以运行任何 `IO ()`类型的动作
-
> sayHello
What is your name?
Friend!
@@ -390,7 +383,7 @@ Hello, Friend!
```
-还有很多关于 Haskell,包括类型类和 monads。这些是使得编码 Haskell 是如此有趣的主意。我用一个最后的 Haskell 例子来结束:一个 Haskell 的快排实现:
+Haskell 还有许多内容,包括类型类 (typeclasses) 与 Monads。这些都是令 Haskell 编程非常有趣的好东西。我们最后给出 Haskell 的一个例子,一个快速排序的实现:
```haskell
qsort [] = []
@@ -399,9 +392,9 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
greater = filter (>= p) xs
```
-安装 Haskell 是简单的。你可以从[这里](http://www.haskell.org/platform/)获得它。
+安装 Haskell 很简单。你可以[从这里获得](http://www.haskell.org/platform/)。
你可以从优秀的
[Learn you a Haskell](http://learnyouahaskell.com/) 或者
[Real World Haskell](http://book.realworldhaskell.org/)
-找到优雅不少的入门介绍。
+找到更平缓的入门介绍。
diff --git a/zh-cn/java-cn.html.markdown b/zh-cn/java-cn.html.markdown
index f08d3507..12afa59a 100644
--- a/zh-cn/java-cn.html.markdown
+++ b/zh-cn/java-cn.html.markdown
@@ -149,7 +149,7 @@ public class LearnJava {
// 位运算操作符
/*
- ~ 补
+ ~ 取反,求反码
<< 带符号左移
>> 带符号右移
>>> 无符号右移
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index 64b0aadc..b450ab84 100644
--- a/zh-cn/javascript-cn.html.markdown
+++ b/zh-cn/javascript-cn.html.markdown
@@ -341,7 +341,7 @@ var myFunc = myObj.myFunc;
myFunc(); // = undefined
// 相应的,一个函数也可以被指定为一个对象的方法,并且可以通过`this`访问
-// 这个对象的成员,即使在行数被定义时并没有依附在对象上。
+// 这个对象的成员,即使在函数被定义时并没有依附在对象上。
var myOtherFunc = function(){
return this.myString.toUpperCase();
}
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index 1c577efb..b1143dac 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -127,7 +127,7 @@ __此文本也是__
<!-- 代码段落 -->
<!-- 代码段落(HTML中 <code>标签)可以由缩进四格(spaces)
-或者一个标签页(tab)实现-->
+或者一个制表符(tab)实现-->
This is code
So is this
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 99250b43..14d38137 100644
--- a/zh-cn/ruby-cn.html.markdown
+++ b/zh-cn/ruby-cn.html.markdown
@@ -7,6 +7,7 @@ contributors:
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
- ["lidashuang", "https://github.com/lidashuang"]
+ - ["ftwbzhao", "https://github.com/ftwbzhao"]
translators:
- ["Lin Xiangyu", "https://github.com/oa414"]
---
@@ -120,11 +121,11 @@ status == :approved #=> false
# 数组
# 这是一个数组
-[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# 数组可以包含不同类型的元素
-array = [1, "hello", false] #=> => [1, "hello", false]
+[1, "hello", false] #=> [1, "hello", false]
# 数组可以被索引
# 从前面开始
@@ -140,8 +141,8 @@ array.[] 12 #=> nil
# 从尾部开始
array[-1] #=> 5
-# 同时指定开始的位置和结束的位置
-array[2, 4] #=> [3, 4, 5]
+# 同时指定开始的位置和长度
+array[2, 3] #=> [3, 4, 5]
# 或者指定一个范围
array[1..3] #=> [2, 3, 4]
diff --git a/zh-cn/rust-cn.html.markdown b/zh-cn/rust-cn.html.markdown
new file mode 100644
index 00000000..17a897df
--- /dev/null
+++ b/zh-cn/rust-cn.html.markdown
@@ -0,0 +1,296 @@
+---
+language: rust
+contributors:
+ - ["P1start", "http://p1start.github.io/"]
+translators:
+ - ["Guangming Mao", "http://maogm.com"]
+filename: learnrust-cn.rs
+lang: zh-cn
+---
+
+Rust 是由 Mozilla 研究院开发的编程语言。Rust 将底层的性能控制与高级语言的便利性和安全保障结合在了一起。
+
+而 Rust 并不需要一个垃圾回收器或者运行时即可实现这个目的,这使得 Rust 库可以成为一种 C 语言的替代品。
+
+Rust 第一版(0.1 版)发布于 2012 年 1 月,3 年以来一直在紧锣密鼓地迭代。
+因为更新太频繁,一般建议使用每夜构建版而不是稳定版,直到最近 1.0 版本的发布。
+
+2015 年 3 月 15 日,Rust 1.0 发布,完美向后兼容,最新的每夜构建版提供了缩短编译时间等新特性。
+Rust 采用了持续迭代模型,每 6 周一个发布版。Rust 1.1 beta 版在 1.0 发布时同时发布。
+
+尽管 Rust 相对来说是一门底层语言,它提供了一些常见于高级语言的函数式编程的特性。这让 Rust 不仅高效,并且易用。
+
+```rust
+// 这是注释,单行注释...
+/* ...这是多行注释 */
+
+///////////////
+// 1. 基础 //
+///////////////
+
+// 函数 (Functions)
+// `i32` 是有符号 32 位整数类型(32-bit signed integers)
+fn add2(x: i32, y: i32) -> i32 {
+ // 隐式返回 (不要分号)
+ x + y
+}
+
+// 主函数(Main function)
+fn main() {
+ // 数字 (Numbers) //
+
+ // 不可变绑定
+ let x: i32 = 1;
+
+ // 整形/浮点型数 后缀
+ let y: i32 = 13i32;
+ let f: f64 = 1.3f64;
+
+ // 类型推导
+ // 大部分时间,Rust 编译器会推导变量类型,所以不必把类型显式写出来。
+ // 这个教程里面很多地方都显式写了类型,但是只是为了示范。
+ // 绝大部分时间可以交给类型推导。
+ let implicit_x = 1;
+ let implicit_f = 1.3;
+
+ // 算术运算
+ let sum = x + y + 13;
+
+ // 可变变量
+ let mut mutable = 1;
+ mutable = 4;
+ mutable += 2;
+
+ // 字符串 (Strings) //
+
+ // 字符串字面量
+ let x: &str = "hello world!";
+
+ // 输出
+ println!("{} {}", f, x); // 1.3 hello world
+
+ // 一个 `String` – 在堆上分配空间的字符串
+ let s: String = "hello world".to_string();
+
+ // 字符串分片(slice) - 另一个字符串的不可变视图
+ // 基本上就是指向一个字符串的不可变指针,它不包含字符串里任何内容,只是一个指向某个东西的指针
+ // 比如这里就是 `s`
+ let s_slice: &str = &s;
+
+ println!("{} {}", s, s_slice); // hello world hello world
+
+ // 数组 (Vectors/arrays) //
+
+ // 长度固定的数组 (array)
+ let four_ints: [i32; 4] = [1, 2, 3, 4];
+
+ // 变长数组 (vector)
+ let mut vector: Vec<i32> = vec![1, 2, 3, 4];
+ vector.push(5);
+
+ // 分片 - 某个数组(vector/array)的不可变视图
+ // 和字符串分片基本一样,只不过是针对数组的
+ let slice: &[i32] = &vector;
+
+ // 使用 `{:?}` 按调试样式输出
+ println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
+
+ // 元组 (Tuples) //
+
+ // 元组是固定大小的一组值,可以是不同类型
+ let x: (i32, &str, f64) = (1, "hello", 3.4);
+
+ // 解构 `let`
+ let (a, b, c) = x;
+ println!("{} {} {}", a, b, c); // 1 hello 3.4
+
+ // 索引
+ println!("{}", x.1); // hello
+
+ //////////////
+ // 2. 类型 (Type) //
+ //////////////
+
+ // 结构体(Sturct)
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+
+ let origin: Point = Point { x: 0, y: 0 };
+
+ // 匿名成员结构体,又叫“元组结构体”(‘tuple struct’)
+ struct Point2(i32, i32);
+
+ let origin2 = Point2(0, 0);
+
+ // 基础的 C 风格枚举类型(enum)
+ enum Direction {
+ Left,
+ Right,
+ Up,
+ Down,
+ }
+
+ let up = Direction::Up;
+
+ // 有成员的枚举类型
+ enum OptionalI32 {
+ AnI32(i32),
+ Nothing,
+ }
+
+ let two: OptionalI32 = OptionalI32::AnI32(2);
+ let nothing = OptionalI32::Nothing;
+
+ // 泛型 (Generics) //
+
+ struct Foo<T> { bar: T }
+
+ // 这个在标准库里面有实现,叫 `Option`
+ enum Optional<T> {
+ SomeVal(T),
+ NoVal,
+ }
+
+ // 方法 (Methods) //
+
+ impl<T> Foo<T> {
+ // 方法需要一个显式的 `self` 参数
+ fn get_bar(self) -> T {
+ self.bar
+ }
+ }
+
+ let a_foo = Foo { bar: 1 };
+ println!("{}", a_foo.get_bar()); // 1
+
+ // 接口(Traits) (其他语言里叫 interfaces 或 typeclasses) //
+
+ trait Frobnicate<T> {
+ fn frobnicate(self) -> Option<T>;
+ }
+
+ impl<T> Frobnicate<T> for Foo<T> {
+ fn frobnicate(self) -> Option<T> {
+ Some(self.bar)
+ }
+ }
+
+ let another_foo = Foo { bar: 1 };
+ println!("{:?}", another_foo.frobnicate()); // Some(1)
+
+ ///////////////////////////////////
+ // 3. 模式匹配 (Pattern matching) //
+ ///////////////////////////////////
+
+ let foo = OptionalI32::AnI32(1);
+ match foo {
+ OptionalI32::AnI32(n) => println!("it’s an i32: {}", n),
+ OptionalI32::Nothing => println!("it’s nothing!"),
+ }
+
+ // 高级模式匹配
+ struct FooBar { x: i32, y: OptionalI32 }
+ let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
+
+ match bar {
+ FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
+ println!("The numbers are zero!"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
+ println!("The numbers are the same"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } =>
+ println!("Different numbers: {} {}", n, m),
+ FooBar { x: _, y: OptionalI32::Nothing } =>
+ println!("The second number is Nothing!"),
+ }
+
+ ///////////////////////////////
+ // 4. 流程控制 (Control flow) //
+ ///////////////////////////////
+
+ // `for` 循环
+ let array = [1, 2, 3];
+ for i in array.iter() {
+ println!("{}", i);
+ }
+
+ // 区间 (Ranges)
+ for i in 0u32..10 {
+ print!("{} ", i);
+ }
+ println!("");
+ // 输出 `0 1 2 3 4 5 6 7 8 9 `
+
+ // `if`
+ if 1 == 1 {
+ println!("Maths is working!");
+ } else {
+ println!("Oh no...");
+ }
+
+ // `if` 可以当表达式
+ let value = if true {
+ "good"
+ } else {
+ "bad"
+ };
+
+ // `while` 循环
+ while 1 == 1 {
+ println!("The universe is operating normally.");
+ }
+
+ // 无限循环
+ loop {
+ println!("Hello!");
+ }
+
+ ////////////////////////////////////////////////
+ // 5. 内存安全和指针 (Memory safety & pointers) //
+ ////////////////////////////////////////////////
+
+ // 独占指针 (Owned pointer) - 同一时刻只能有一个对象能“拥有”这个指针
+ // 意味着 `Box` 离开他的作用域后,会被安全地释放
+ let mut mine: Box<i32> = Box::new(3);
+ *mine = 5; // 解引用
+ // `now_its_mine` 获取了 `mine` 的所有权。换句话说,`mine` 移动 (move) 了
+ let mut now_its_mine = mine;
+ *now_its_mine += 2;
+
+ println!("{}", now_its_mine); // 7
+ // println!("{}", mine); // 编译报错,因为现在 `now_its_mine` 独占那个指针
+
+ // 引用 (Reference) – 引用其他数据的不可变指针
+ // 当引用指向某个值,我们称为“借用”这个值,因为是被不可变的借用,所以不能被修改,也不能移动
+ // 借用一直持续到生命周期结束,即离开作用域
+ let mut var = 4;
+ var = 3;
+ let ref_var: &i32 = &var;
+
+ println!("{}", var); //不像 `box`, `var` 还可以继续使用
+ println!("{}", *ref_var);
+ // var = 5; // 编译报错,因为 `var` 被借用了
+ // *ref_var = 6; // 编译报错,因为 `ref_var` 是不可变引用
+
+ // 可变引用 (Mutable reference)
+ // 当一个变量被可变地借用时,也不可使用
+ let mut var2 = 4;
+ let ref_var2: &mut i32 = &mut var2;
+ *ref_var2 += 2;
+
+ println!("{}", *ref_var2); // 6
+ // var2 = 2; // 编译报错,因为 `var2` 被借用了
+}
+```
+
+## 更深入的资料
+
+Rust 还有很多很多其他内容 - 这只是 Rust 最基本的功能,帮助你了解 Rust 里面最重要的东西。
+如果想深入学习 Rust,可以去读
+[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
+或者上 reddit [/r/rust](http://reddit.com/r/rust) 订阅。
+同时 irc.mozilla.org 的 #rust 频道上的小伙伴们也非常欢迎新来的朋友。
+
+你可以在这个在线编译器 [Rust playpen](http://play.rust-lang.org) 上尝试 Rust 的一些特性
+或者上[官方网站](http://rust-lang.org).
diff --git a/zh-cn/scala-cn.html.markdown b/zh-cn/scala-cn.html.markdown
index 58f5cd47..508dd58e 100644
--- a/zh-cn/scala-cn.html.markdown
+++ b/zh-cn/scala-cn.html.markdown
@@ -4,12 +4,15 @@ filename: learnscala-zh.scala
contributors:
- ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
translators:
- ["Peiyong Lin", ""]
+ - ["Jinchang Ye", "http://github.com/alwayswithme"]
+ - ["Guodong Qu", "https://github.com/jasonqu"]
lang: zh-cn
---
-Scala - 一门可拓展性的语言
+Scala - 一门可拓展的语言
```scala
@@ -17,23 +20,31 @@ Scala - 一门可拓展性的语言
自行设置:
1) 下载 Scala - http://www.scala-lang.org/downloads
- 2) unzip/untar 到你喜欢的地方,放在路径中的 bin 目录下
- 3) 在终端输入 scala,开启 Scala 的 REPL,你会看到提示符:
+ 2) unzip/untar 到您喜欢的地方,并把 bin 子目录添加到 path 环境变量
+ 3) 在终端输入 scala,启动 Scala 的 REPL,您会看到提示符:
scala>
- 这就是所谓的 REPL,你现在可以在其中运行命令,让我们做到这一点:
+ 这就是所谓的 REPL (读取-求值-输出循环,英语: Read-Eval-Print Loop),
+ 您可以在其中输入合法的表达式,结果会被打印。
+ 在教程中我们会进一步解释 Scala 文件是怎样的,但现在先了解一点基础。
*/
-println(10) // 打印整数 10
-println("Boo!") // 打印字符串 "BOO!"
+/////////////////////////////////////////////////
+// 1. 基础
+/////////////////////////////////////////////////
+// 单行注释开始于两个斜杠
-// 一些基础
+/*
+ 多行注释,如您之前所见,看起来像这样
+*/
// 打印并强制换行
println("Hello world!")
+println(10)
+
// 没有强制换行的打印
print("Hello world")
@@ -41,13 +52,19 @@ print("Hello world")
// val 声明是不可变的,var 声明是可修改的。不可变性是好事。
val x = 10 // x 现在是 10
x = 20 // 错误: 对 val 声明的变量重新赋值
-var x = 10
-x = 20 // x 现在是 20
+var y = 10
+y = 20 // y 现在是 20
-// 单行注释开始于两个斜杠
-/*
-多行注释看起来像这样。
+/*
+ Scala 是静态语言,但注意上面的声明方式,我们没有指定类型。
+ 这是因为类型推导的语言特性。大多数情况, Scala 编译器可以推测变量的类型,
+ 所以您不需要每次都输入。可以像这样明确声明变量类型:
*/
+val z: Int = 10
+val a: Double = 1.0
+
+// 注意从 Int 到 Double 的自动转型,结果是 10.0, 不是 10
+val b: Double = 10
// 布尔值
true
@@ -64,9 +81,11 @@ true == false // false
2 - 1 // 1
5 * 3 // 15
6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
-// 在 REPL 计算一个命令会返回给你结果的类型和值
+// 在 REPL 计算一个表达式会返回给您结果的类型和值
1 + 7
@@ -77,58 +96,190 @@ true == false // false
这意味着计算 1 + 7 的结果是一个 Int 类型的对象,其值为 8
- 1+7 的结果是一样的
+ 注意 "res29" 是一个连续生成的变量名,用以存储您输入的表达式结果,
+ 您看到的输出可能不一样。
*/
+"Scala strings are surrounded by double quotes"
+'a' // Scala 的字符
+// '不存在单引号字符串' <= 这会导致错误
-// 包括函数在内,每一个事物都是对象。在 REPL 中输入:
+// String 有常见的 Java 字符串方法
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
-7 // 结果 res30: Int = 7 (res30 是一个生成的结果的 var 命名)
+// 也有一些额外的 Scala 方法,另请参见:scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
-// 下一行给你一个接收一个 Int 类型并返回该数的平方的函数
-(x:Int) => x * x
+// 字符串改写:留意前缀 "s"
+val n = 45
+s"We have $n apples" // => "We have 45 apples"
-// 你可以分配给函数一个标识符,像这样:
-val sq = (x:Int) => x * x
+// 在要改写的字符串中使用表达式也是可以的
+val a = Array(11, 9, 6)
+s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
+s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
+s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
-/* 上面的例子说明
-
- sq: Int => Int = <function1>
+// 添加 "f" 前缀对要改写的字符串进行格式化
+f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
+f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
- 意味着这次我们给予了 sq 这样一个显式的名字给一个接受一个 Int 类型值并返回 一个 Int 类型值的函数
+// 未处理的字符串,忽略特殊字符。
+raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
- sq 可以像下面那样被执行:
-*/
+// 一些字符需要转义,比如字符串中的双引号
+"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
-sq(10) // 返回给你:res33: Int = 100.
+// 三个双引号可以使字符串跨越多行,并包含引号
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
-// Scala 允许方法和函数返回或者接受其它的函数或者方法作为参数。
-val add10: Int => Int = _ + 10 // 一个接受一个 Int 类型参数并返回一个 Int 类型值的函数
-List(1, 2, 3) map add10 // List(11, 12, 13) - add10 被应用到每一个元素
+/////////////////////////////////////////////////
+// 2. 函数
+/////////////////////////////////////////////////
+
+// 函数可以这样定义:
+//
+// def functionName(args...): ReturnType = { body... }
+//
+// 如果您以前学习过传统的编程语言,注意 return 关键字的省略。
+// 在 Scala 中, 函数代码块最后一条表达式就是返回值。
+def sumOfSquares(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
-// 匿名函数可以被使用来代替有命名的函数:
-List(1, 2, 3) map (x => x + 10)
+// 如果函数体是单行表达式,{ } 可以省略:
+def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
-// 下划线标志,如果匿名函数只有一个参数可以被使用来表示该参数变量
-List(1, 2, 3) map (_ + 10)
+// 函数调用的语法是熟知的:
+sumOfSquares(3, 4) // => 25
-// 如果你所应用的匿名块和匿名函数都接受一个参数,那么你甚至可以省略下划线
-List("Dom", "Bob", "Natalia") foreach println
+// 在多数情况下 (递归函数是需要注意的例外), 函数返回值可以省略,
+// 变量所用的类型推导一样会应用到函数返回值中:
+def sq(x: Int) = x * x // 编译器会推断得知返回值是 Int
+// 函数可以有默认参数
+def addWithDefault(x: Int, y: Int = 5) = x + y
+addWithDefault(1, 2) // => 3
+addWithDefault(1) // => 6
-// 数据结构
+// 匿名函数是这样的:
+(x:Int) => x * x
+
+// 和 def 不同,如果语义清晰,匿名函数的参数类型也可以省略。
+// 类型 "Int => Int" 意味着这个函数接收一个 Int 并返回一个 Int。
+val sq: Int => Int = x => x * x
+
+// 匿名函数的调用也是类似的:
+sq(10) // => 100
+
+// 如果您的匿名函数中每个参数仅使用一次,
+// Scala 提供一个更简洁的方式来定义他们。这样的匿名函数极为常见,
+// 在数据结构部分会明显可见。
+val addOne: Int => Int = _ + 1
+val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+addOne(5) // => 6
+weirdSum(2, 4) // => 16
+
+
+// return 关键字是存在的,但它只从最里面包裹了 return 的 def 函数中返回。
+// 警告: 在 Scala 中使用 return 容易出错,应该避免使用。
+// 在匿名函数中没有效果,例如:
+def foo(x: Int): Int = {
+ val anonFunc: Int => Int = { z =>
+ if (z > 5)
+ return z // 这一行令 z 成为 foo 函数的返回值!
+ else
+ z + 2 // 这一行是 anonFunc 函数的返回值
+ }
+ anonFunc(x) // 这一行是 foo 函数的返回值
+}
+
+/*
+ * 译者注:此处是指匿名函数中的 return z 成为最后执行的语句,
+ * 在 anonFunc(x) 下面的表达式(假设存在)不再执行。如果 anonFunc
+ * 是用 def 定义的函数, return z 仅返回到 anonFunc(x) ,
+ * 在 anonFunc(x) 下面的表达式(假设存在)会继续执行。
+ */
+
+
+/////////////////////////////////////////////////
+// 3. 控制语句
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach( println )
+
+r foreach println
+// 附注: Scala 对点和括号的要求想当宽松,注意其规则是不同的。
+// 这有助于写出读起来像英语的 DSL(领域特定语言) 和 API(应用编程接口)。
+
+(5 to 1 by -1) foreach ( println )
+
+// while 循环
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+while (i < 10) { println("i " + i); i+=1 } // 没错,再执行一次,发生了什么?为什么?
+
+i // 显示 i 的值。注意 while 是经典的循环方式,它连续执行并改变循环中的变量。
+ // while 执行很快,比 Java 的循环快,但像上面所看到的那样用组合子和推导式
+ // 更易于理解和并行化。
+
+// do while 循环
+do {
+ println("x is still less than 10");
+ x += 1
+} while (x < 10)
+
+// Scala 中尾递归是一种符合语言习惯的递归方式。
+// 递归函数需要清晰的返回类型,编译器不能推断得知。
+// 这是一个 Unit。
+def showNumbersInRange(a:Int, b:Int):Unit = {
+ print(a)
+ if (a < b)
+ showNumbersInRange(a + 1, b)
+}
+showNumbersInRange(1,14)
+
+
+// 条件语句
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. 数据结构
+/////////////////////////////////////////////////
val a = Array(1, 2, 3, 5, 8, 13)
a(0)
a(3)
-a(21) // 这会抛出一个异常
+a(21) // 抛出异常
val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
m("fork")
m("spoon")
-m("bottle") // 这会抛出一个异常
+m("bottle") // 抛出异常
val safeM = m.withDefaultValue("no lo se")
safeM("bottle")
@@ -137,9 +288,9 @@ val s = Set(1, 3, 7)
s(0)
s(1)
-/* 查看 map 的文档
- * 点击[这里](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map)
- * 确保你可以读它
+/* 这里查看 map 的文档 -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * 并确保你会阅读
*/
@@ -154,13 +305,11 @@ s(1)
(a, 2, "three")
// 为什么有这个?
-
val divideInts = (x:Int, y:Int) => (x / y, x % y)
-divideInts(10,3) // 函数 divideInts 返回你结果和余数
+divideInts(10,3) // 函数 divideInts 同时返回结果和余数
// 要读取元组的元素,使用 _._n,n是从1开始的元素索引
-
val d = divideInts(10,3)
d._1
@@ -168,234 +317,289 @@ d._1
d._2
+/////////////////////////////////////////////////
+// 5. 面向对象编程
+/////////////////////////////////////////////////
-// 选择器
-
-s.map(sq)
-
-val sSquared = s. map(sq)
-
-sSquared.filter(_ < 10)
+/*
+ 旁白: 教程中到现在为止我们所做的一切只是简单的表达式(值,函数等)。
+ 这些表达式可以输入到命令行解释器中作为快速测试,但它们不能独立存在于 Scala
+ 文件。举个例子,您不能在 Scala 文件上简单的写上 "val x = 5"。相反 Scala 文件
+ 允许的顶级结构是:
-sSquared.reduce (_+_)
+ - objects
+ - classes
+ - case classes
+ - traits
-// filter 函数接受一个预测(一个函数,形式为 A -> Boolean) 并选择出所有的元素满足这个预测
+ 现在来解释这些是什么。
+*/
-List(1, 2, 3) filter (_ > 2) // List(3)
-List(
- Person(name = "Dom", age = 23),
- Person(name = "Bob", age = 30)
-).filter(_.age > 25) // List(Person("Bob", 30))
+// 类和其他语言的类相似,构造器参数在类名后声明,初始化在类结构体中完成。
+class Dog(br: String) {
+ // 构造器代码在此
+ var breed: String = br
+ // 定义名为 bark 的方法,返回字符串
+ def bark = "Woof, woof!"
-// Scala 的 foreach 方法定义在特定的接受一个类型的集合上
-// 返回 Unit(一个 void 方法)
-aListOfNumbers foreach (x => println(x))
-aListOfNumbers foreach println
+ // 值和方法作用域假定为 public。"protected" 和 "private" 关键字也是可用的。
+ private def sleep(hours: Int) =
+ println(s"I'm sleeping for $hours hours")
+ // 抽象方法是没有方法体的方法。如果取消下面那行注释,Dog 类必须被声明为 abstract
+ // abstract class Dog(...) { ... }
+ // def chaseAfter(what: String): String
+}
+val mydog = new Dog("greyhound")
+println(mydog.breed) // => "greyhound"
+println(mydog.bark) // => "Woof, woof!"
-// For 包含
+// "object" 关键字创造一种类型和该类型的单例。
+// Scala 的 class 常常也含有一个 “伴生对象”,class 中包含每个实例的行为,所有实例
+// 共用的行为则放入 object 中。两者的区别和其他语言中类方法和静态方法类似。
+// 请注意 object 和 class 可以同名。
+object Dog {
+ def allKnownBreeds = List("pitbull", "shepherd", "retriever")
+ def createDog(breed: String) = new Dog(breed)
+}
-for { n <- s } yield sq(n)
-val nSquared2 = for { n <- s } yield sq(n)
+// Case 类是有额外内建功能的类。Scala 初学者常遇到的问题之一便是何时用类
+// 和何时用 case 类。界线比较模糊,但通常类倾向于封装,多态和行为。类中的值
+// 的作用域一般为 private , 只有方向是暴露的。case 类的主要目的是放置不可变
+// 数据。它们通常只有几个方法,且方法几乎没有副作用。
+case class Person(name: String, phoneNumber: String)
-for { n <- nSquared2 if n < 10 } yield n
+// 创造新实例,注意 case 类不需要使用 "new" 关键字
+val george = Person("George", "1234")
+val kate = Person("Kate", "4567")
-for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+// 使用 case 类,您可以轻松得到一些功能,像 getters:
+george.phoneNumber // => "1234"
-/* 注意:这些不是 for 循环. 一个 for 循环的语义是 '重复'('repeat'),
- 然而,一个 for-包含 定义了一个两个数据结合间的关系 */
+// 每个字段的相等性比较(无需覆盖 .equals)
+Person("George", "1234") == Person("Kate", "1236") // => false
+// 简单的拷贝方式
+// otherGeorge == Person("george", "9876")
+val otherGeorge = george.copy(phoneNumber = "9876")
+// 还有很多。case 类同时可以用于模式匹配,接下来会看到。
-// 循环和迭代
-1 to 5
-val r = 1 to 5
-r.foreach( println )
+// 敬请期待 Traits !
-r foreach println
-// 注意:Scala 是相当宽容的当它遇到点和括号 - 分别地学习这些规则。
-// 这帮助你编写读起来像英语的 DSLs 和 APIs
-(5 to 1 by -1) foreach ( println )
+/////////////////////////////////////////////////
+// 6. 模式匹配
+/////////////////////////////////////////////////
-// while 循环
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
-
-while (i < 10) { println("i " + i); i+=1 } // 发生了什么?为什么?
-
-i // 展示 i 的值。注意到 while 是一个传统意义上的循环
- // 它顺序地执行并且改变循环变量的值。while 非常快,比 Java // 循环快,
- // 但是在其上使用选择器和包含更容易理解和并行。
-
-// do while 循环
-do {
- println("x is still less then 10");
- x += 1
-} while (x < 10)
+// 模式匹配是一个强大和常用的 Scala 特性。这是用模式匹配一个 case 类的例子。
+// 附注:不像其他语言, Scala 的 case 不需要 break, 其他语言中 switch 语句的
+// fall-through 现象不会发生。
-// 在 Scala中,尾递归是一种惯用的执行循环的方式。
-// 递归函数需要显示的返回类型,编译器不能推断出类型。
-// 这里它是 Unit。
-def showNumbersInRange(a:Int, b:Int):Unit = {
- print(a)
- if (a < b)
- showNumbersInRange(a + 1, b)
+def matchPerson(person: Person): String = person match {
+ // Then you specify the patterns:
+ case Person("George", number) => "We found George! His number is " + number
+ case Person("Kate", number) => "We found Kate! Her number is " + number
+ case Person(name, number) => "We matched someone : " + name + ", phone : " + number
}
+val email = "(.*)@(.*)".r // 定义下一个例子会用到的正则
+// 模式匹配看起来和 C语言家族的 switch 语句相似,但更为强大。
+// Scala 中您可以匹配很多东西:
+def matchEverything(obj: Any): String = obj match {
+ // 匹配值:
+ case "Hello world" => "Got the string Hello world"
-// 条件语句
-
-val x = 10
-
-if (x == 1) println("yeah")
-if (x == 10) println("yeah")
-if (x == 11) println("yeah")
-if (x == 11) println ("yeah") else println("nay")
+ // 匹配类型:
+ case x: Double => "Got a Double: " + x
-println(if (x == 10) "yeah" else "nope")
-val text = if (x == 10) "yeah" else "nope"
+ // 匹配时指定条件
+ case x: Int if x > 10000 => "Got a pretty big number!"
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
+ // 像之前一样匹配 case 类:
+ case Person(name, number) => s"Got contact info for $name!"
+ // 匹配正则表达式:
+ case email(name, domain) => s"Got email address $name@$domain"
+ // 匹配元组:
+ case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
-// 面向对象特性
+ // 匹配数据结构:
+ case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
-// 类名是 Dog
-class Dog {
- //bark 方法,返回字符串
- def bark: String = {
- // the body of the method
- "Woof, woof!"
- }
+ // 模式可以嵌套
+ case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
}
-// 类可以包含几乎其它的构造,包括其它的类,
-// 函数,方法,对象,case 类,特性等等。
-
-
+// 事实上,你可以对任何有 "unapply" 方法的对象进行模式匹配。
+// 这个特性如此强大以致于 Scala 允许定义一个函数作为模式匹配:
+val patternFunc: Person => String = {
+ case Person("George", number) => s"George's number: $number"
+ case Person(name, number) => s"Random person's number: $number"
+}
-// Case 类
-case class Person(name:String, phoneNumber:String)
+/////////////////////////////////////////////////
+// 7. 函数式编程
+/////////////////////////////////////////////////
-Person("George", "1234") == Person("Kate", "1236")
+// Scala 允许方法和函数作为其他方法和函数的参数和返回值。
+val add10: Int => Int = _ + 10 // 一个接受一个 Int 类型参数并返回一个 Int 类型值的函数
+List(1, 2, 3) map add10 // List(11, 12, 13) - add10 被应用到每一个元素
+// 匿名函数可以被使用来代替有命名的函数:
+List(1, 2, 3) map (x => x + 10)
+// 如果匿名函数只有一个参数可以用下划线作为变量
+List(1, 2, 3) map (_ + 10)
-// 模式匹配
+// 如果您所应用的匿名块和匿名函数都接受一个参数,那么你甚至可以省略下划线
+List("Dom", "Bob", "Natalia") foreach println
-val me = Person("George", "1234")
-me match { case Person(name, number) => {
- "We matched someone : " + name + ", phone : " + number }}
+// 组合子
-me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
+// 译注: val sq: Int => Int = x => x * x
+s.map(sq)
-me match { case Person("George", number) => "Match"; case _ => "Hm..." }
+val sSquared = s. map(sq)
-me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
+sSquared.filter(_ < 10)
-me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+sSquared.reduce (_+_)
-val kate = Person("Kate", "1234")
+// filter 函数接受一个 predicate (函数根据条件 A 返回 Boolean)并选择
+// 所有满足 predicate 的元素
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Person(name:String, age:Int)
+List(
+ Person(name = "Dom", age = 23),
+ Person(name = "Bob", age = 30)
+).filter(_.age > 25) // List(Person("Bob", 30))
-kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+// Scala 的 foreach 方法定义在某些集合中,接受一个函数并返回 Unit (void 方法)
+// 另请参见:
+// http://www.scala-lang.org/api/current/index.html#scala.collection.IterableLike@foreach(f:A=>Unit):Unit
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+// For 推导式
-// 正则表达式
+for { n <- s } yield sq(n)
-val email = "(.*)@(.*)".r // 在字符串上调用 r 会使它变成一个正则表达式
+val nSquared2 = for { n <- s } yield sq(n)
-val email(user, domain) = "henry@zkpr.com"
+for { n <- nSquared2 if n < 10 } yield n
-"mrbean@pyahoo.com" match {
- case email(name, domain) => "I know your name, " + name
-}
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+/* 注意,这些不是 for 循环,for 循环的语义是‘重复’,然而 for 推导式定义
+ 两个数据集合的关系。 */
-// 字符串
+/////////////////////////////////////////////////
+// 8. 隐式转换
+/////////////////////////////////////////////////
-"Scala 字符串被双引号包围" //
-'a' // Scala 字符
-'单引号的字符串不存在' // 错误
-"字符串拥有通常的 Java 方法定义在其上".length
-"字符串也有额外的 Scala 方法".reverse
+/* 警告 警告: 隐式转换是 Scala 中一套强大的特性,因此容易被滥用。
+ * Scala 初学者在理解它们的工作原理和最佳实践之前,应抵制使用它的诱惑。
+ * 我们加入这一章节仅因为它们在 Scala 的库中太过常见,导致没有用隐式转换的库
+ * 就不可能做有意义的事情。这章节主要让你理解和使用隐式转换,而不是自己声明。
+ */
-// 参见: scala.collection.immutable.StringOps
+// 可以通过 "implicit" 声明任何值(val, 函数,对象等)为隐式值,
+// 请注意这些例子中,我们用到第5部分的 Dog 类。
+implicit val myImplicitInt = 100
+implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
-println("ABCDEF".length)
-println("ABCDEF".substring(2, 6))
-println("ABCDEF".replace("C", "3"))
+// implicit 关键字本身不改变值的行为,所以上面的值可以照常使用。
+myImplicitInt + 2 // => 102
+myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
-val n = 45
-println(s"We have $n apples")
+// 区别在于,当另一段代码“需要”隐式值时,这些值现在有资格作为隐式值。
+// 一种情况是隐式函数参数。
+def sendGreetings(toWhom: String)(implicit howMany: Int) =
+ s"Hello $toWhom, $howMany blessings to you and yours!"
-val a = Array(11, 9, 6)
-println(s"My second daughter is ${a(2-1)} years old")
+// 如果提供值给 “howMany”,函数正常运行
+sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
-// 一些字符需要被转义,举例来说,字符串中的双引号:
-val a = "They stood outside the \"Rose and Crown\""
+// 如果省略隐式参数,会传一个和参数类型相同的隐式值,
+// 在这个例子中, 是 “myImplicitInt":
+sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
-// 三个双引号使得字符串可以跨行并且可以包含引号(无需转义)
+// 隐式的函数参数使我们可以模拟其他函数式语言的 type 类(type classes)。
+// 它经常被用到所以有特定的简写。这两行代码是一样的:
+def foo[T](implicit c: C[T]) = ...
+def foo[T : C] = ...
-val html = """<form id="daform">
- <p>Press belo', Joe</p>
- | <input type="submit">
- </form>"""
+// 编译器寻找隐式值另一种情况是你调用方法时
+// obj.method(...)
+// 但 "obj" 没有一个名为 "method" 的方法。这样的话,如果有一个参数类型为 A
+// 返回值类型为 B 的隐式转换,obj 的类型是 A,B 有一个方法叫 "method" ,这样
+// 转换就会被应用。所以作用域里有上面的 myImplicitFunction, 我们可以这样做:
+"Retriever".breed // => "Golden Retriever"
+"Sheperd".bark // => "Woof, woof!"
+// 这里字符串先被上面的函数转换为 Dog 对象,然后调用相应的方法。
+// 这是相当强大的特性,但再次提醒,请勿轻率使用。
+// 事实上,当你定义上面的隐式函数时,编译器会作出警告,除非你真的了解
+// 你正在做什么否则不要使用。
-// 应用结果和组织
+/////////////////////////////////////////////////
+// 9. 杂项
+/////////////////////////////////////////////////
-// import
+// 导入类
import scala.collection.immutable.List
-// Import 所有的子包
+// 导入所有子包
import scala.collection.immutable._
-// 在一条语句中 Import 多个类
+// 一条语句导入多个类
import scala.collection.immutable.{List, Map}
-// 使用 '=>' 来重命名一个 import
+// 使用 ‘=>’ 对导入进行重命名
import scala.collection.immutable.{ List => ImmutableList }
-// import 除了一些类的其它所有的类。下面的例子除去了 Map 类和 Set 类:
+// 导入所有类,排除其中一些。下面的语句排除了 Map 和 Set:
import scala.collection.immutable.{Map => _, Set => _, _}
-// 在 scala 源文件中,你的程序入口点使用一个拥有单一方法 main 的对象来定义:
-
+// 在 Scala 文件用 object 和单一的 main 方法定义程序入口:
object Application {
def main(args: Array[String]): Unit = {
// stuff goes here.
}
}
-// 文件可以包含多个类和对象。由 scalac 来编译
+// 文件可以包含多个 class 和 object,用 scalac 编译源文件
// 输入和输出
-// 一行一行读取文件
+// 按行读文件
import scala.io.Source
-for(line <- Source.fromPath("myfile.txt").getLines())
+for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
-// 使用 Java 的 PrintWriter 来写文件
-
+// 用 Java 的 PrintWriter 写文件
+val writer = new PrintWriter("myfile.txt")
+writer.write("Writing line for line" + util.Properties.lineSeparator)
+writer.write("Another line here" + util.Properties.lineSeparator)
+writer.close()
```