summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c.html.markdown5
-rw-r--r--forth.html.markdown2
-rw-r--r--fr-fr/ruby-fr.html.markdown2
-rw-r--r--haxe.html.markdown2
-rw-r--r--java.html.markdown13
-rw-r--r--livescript.html.markdown8
-rw-r--r--perl6.html.markdown360
-rw-r--r--pogo.html.markdown2
-rw-r--r--pt-br/hy-pt.html.markdown176
-rw-r--r--pt-br/xml-pt.html.markdown133
-rw-r--r--python.html.markdown2
-rw-r--r--python3.html.markdown1
-rw-r--r--ru-ru/go-ru.html.markdown2
-rw-r--r--ru-ru/javascript-ru.html.markdown543
-rw-r--r--scala.html.markdown66
-rwxr-xr-xtcl.html.markdown447
16 files changed, 1544 insertions, 220 deletions
diff --git a/c.html.markdown b/c.html.markdown
index b5b804af..7670824a 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -386,7 +386,8 @@ int main() {
// or when it's the argument of the `sizeof` or `alignof` operator:
int arraythethird[10];
int *ptr = arraythethird; // equivalent with int *ptr = &arr[0];
- printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr); // probably prints "40, 4" or "40, 8"
+ printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr);
+ // probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
@@ -477,7 +478,7 @@ void testFunc() {
}
//make external variables private to source file with static:
-static int j = 0; //other files using testFunc() cannot access variable i
+static int j = 0; //other files using testFunc2() cannot access variable j
void testFunc2() {
extern int j;
}
diff --git a/forth.html.markdown b/forth.html.markdown
index 570e12ed..f7c0bf34 100644
--- a/forth.html.markdown
+++ b/forth.html.markdown
@@ -12,7 +12,7 @@ such as Open Firmware. It's also used by NASA.
Note: This article focuses predominantly on the Gforth implementation of
Forth, but most of what is written here should work elsewhere.
-```forth
+```
\ This is a comment
( This is also a comment but it's only used when defining words )
diff --git a/fr-fr/ruby-fr.html.markdown b/fr-fr/ruby-fr.html.markdown
index 75c8d0d3..1564d2b6 100644
--- a/fr-fr/ruby-fr.html.markdown
+++ b/fr-fr/ruby-fr.html.markdown
@@ -268,7 +268,7 @@ end
# implicitement la valeur de la dernière instruction évaluée
double(2) #=> 4
-# Les paranthèses sont facultative
+# Les parenthèses sont facultatives
# lorsqu'il n'y a pas d'ambiguïté sur le résultat
double 3 #=> 6
diff --git a/haxe.html.markdown b/haxe.html.markdown
index 6a868f09..8599de8d 100644
--- a/haxe.html.markdown
+++ b/haxe.html.markdown
@@ -484,7 +484,7 @@ class LearnHaxe3{
// we can read this variable
trace(foo_instance.public_read + " is the value for foo_instance.public_read");
// but not write it
- // foo_instance.public_write = 4; // this will throw an error if uncommented:
+ // 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
diff --git a/java.html.markdown b/java.html.markdown
index f08c4679..3dd65679 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -4,6 +4,7 @@ language: java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Madison Dickson", "http://github.com/mix3d"]
+ - ["Jakukyo Friel", "http://weakish.github.io"]
filename: LearnJava.java
---
@@ -49,7 +50,7 @@ public class LearnJava {
// Types & Variables
///////////////////////////////////////
- // Declare a variable using <type> <name> [
+ // Declare a variable using <type> <name>
// Byte - 8-bit signed two's complement integer
// (-128 <= byte <= 127)
byte fooByte = 100;
@@ -268,9 +269,9 @@ public class LearnJava {
System.out.println(bar); // Prints A, because the statement is true
- ///////////////////////////////////////
- // Converting Data Types And Typcasting
- ///////////////////////////////////////
+ ////////////////////////////////////////
+ // Converting Data Types And Typecasting
+ ////////////////////////////////////////
// Converting data
@@ -433,10 +434,12 @@ public interface Digestible {
//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() {
//...
}
@@ -445,10 +448,12 @@ public class Fruit implements Edible, Digestible {
//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() {
}
diff --git a/livescript.html.markdown b/livescript.html.markdown
index 429b91cb..e64f7719 100644
--- a/livescript.html.markdown
+++ b/livescript.html.markdown
@@ -219,8 +219,8 @@ identity 1 # => 1
# Operators are not functions in LiveScript, but you can easily turn
# them into one! Enter the operator sectioning:
-divide-by-2 = (/ 2)
-[2, 4, 8, 16].map(divide-by-2) .reduce (+)
+divide-by-two = (/ 2)
+[2, 4, 8, 16].map(divide-by-two) .reduce (+)
# Not only of function application lives LiveScript, as in any good
@@ -248,8 +248,8 @@ reduce = (f, xs, initial) --> xs.reduce f, initial
# The underscore is also used in regular partial application, which you
# can use for any function:
div = (left, right) -> left / right
-div-by-2 = div _, 2
-div-by-2 4 # => 2
+div-by-two = div _, 2
+div-by-two 4 # => 2
# Last, but not least, LiveScript has back-calls, which might help
diff --git a/perl6.html.markdown b/perl6.html.markdown
index b178de1e..13f383fe 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -35,7 +35,8 @@ my $variable;
## * Scalars. They represent a single value. They start with a `$`
my $str = 'String';
-my $str2 = "String"; # double quotes allow for interpolation
+# double quotes allow for interpolation (which we'll see later):
+my $str2 = "String";
# variable names can contain but not end with simple quotes and dashes,
# and can contain (and end with) underscores :
@@ -66,23 +67,13 @@ my @keys = 0, 2;
@array[@keys] = @letters; # Assign using an array
say @array; #=> a 6 b
-# There are two more kinds of lists: Parcel and Arrays.
-# Parcels are immutable lists (you can't modify a list that's not assigned).
-# This is a parcel:
-(1, 2, 3); # Not assigned to anything. Changing an element would provoke an error
-# This is a list:
-my @a = (1, 2, 3); # Assigned to `@a`. Changing elements is okay!
-
-# Lists flatten (in list context). You'll see below how to apply item context
-# or use arrays to have real nested lists.
-
-
-## * Hashes. Key-Value Pairs.
-# Hashes are actually arrays of Pairs (`Key => Value`),
-# except they get "flattened", removing duplicated keys.
+## * Hashes, or key-value Pairs.
+# Hashes are actually arrays of Pairs
+# (you can construct a Pair object using the syntax `Key => Value`),
+# except they get "flattened" (hash context), removing duplicated keys.
my %hash = 1 => 2,
3 => 4;
-my %hash = autoquoted => "key", # keys *can* get auto-quoted
+my %hash = autoquoted => "key", # keys get auto-quoted
"some other" => "value", # trailing commas are okay
;
my %hash = <key1 value1 key2 value2>; # you can also create a hash
@@ -112,30 +103,6 @@ sub say-hello-to(Str $name) { # You can provide the type of an argument
say "Hello, $name !";
}
-# Since you can omit parenthesis to call a function with no arguments,
-# you need "&" in the name to capture `say-hello`.
-my &s = &say-hello;
-my &other-s = sub { say "Anonymous function !" }
-
-# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
-sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything else".
- # Note: you can have parameters *before* (like here)
- # a slurpy one, but not *after*.
- say @rest.join(' / ') ~ " !";
-}
-say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
- # Note that the splat did not consume
- # the parameter before.
-
-## You can call a function with an array using the
-# "argument list flattening" operator `|`
-# (it's not actually the only role of this operator, but it's one of them)
-sub concat3($a, $b, $c) {
- say "$a, $b, $c";
-}
-concat3(|@array); #=> a, b, c
- # `@array` got "flattened" as a part of the argument list
-
## It can also have optional arguments:
sub with-optional($arg?) { # the "?" marks the argument optional
say "I might return `(Any)` if I don't have an argument passed,
@@ -154,23 +121,20 @@ hello-to; #=> Hello, World !
hello-to(); #=> Hello, World !
hello-to('You'); #=> Hello, You !
-## You can also, by using a syntax akin to the one of hashes (yay unification !),
+## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
## pass *named* arguments to a `sub`.
+# They're optional, and will default to "Any" (Perl's "null"-like value).
sub with-named($normal-arg, :$named) {
say $normal-arg + $named;
}
with-named(1, named => 6); #=> 7
# There's one gotcha to be aware of, here:
# If you quote your key, Perl 6 won't be able to see it at compile time,
-# and you'll have a single Pair object as a positional paramater.
+# and you'll have a single Pair object as a positional paramater,
+# which means this fails:
+with-named(1, 'named' => 6);
with-named(2, :named(5)); #=> 7
-with-named(3, :4named); #=> 7
- # (special colon pair syntax for numbers,
- # to be used with s// and such, see later)
-
-with-named(3); # warns, because we tried to use the undefined $named in a `+`:
- # by default, named arguments are *optional*
# To make a named argument mandatory, you can use `?`'s inverse, `!`
sub with-mandatory-named(:$str!) {
@@ -187,11 +151,6 @@ sub takes-a-bool($name, :$bool) {
# ... you can use the same "short boolean" hash syntax:
takes-a-bool('config', :bool); # config takes True
takes-a-bool('config', :!bool); # config takes False
-# or you can use the "adverb" form:
-takes-a-bool('config'):bool; #=> config takes True
-takes-a-bool('config'):!bool; #=> config takes False
-# You'll learn to love (or maybe hate, eh) that syntax later.
-
## You can also provide your named arguments with defaults:
sub named-def(:$def = 5) {
@@ -201,8 +160,29 @@ named-def; #=> 5
named-def(:10def); #=> 10
named-def(def => 15); #=> 15
-# -- Note: we're going to learn *more* on subs really soon,
-# but we need to grasp a few more things to understand their real power. Ready?
+# Since you can omit parenthesis to call a function with no arguments,
+# you need "&" in the name to capture `say-hello`.
+my &s = &say-hello;
+my &other-s = sub { say "Anonymous function !" }
+
+# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
+sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything else".
+ # Note: you can have parameters *before* (like here)
+ # a slurpy one, but not *after*.
+ say @rest.join(' / ') ~ " !";
+}
+say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
+ # Note that the splat did not consume
+ # the parameter before.
+
+## You can call a function with an array using the
+# "argument list flattening" operator `|`
+# (it's not actually the only role of this operator, but it's one of them)
+sub concat3($a, $b, $c) {
+ say "$a, $b, $c";
+}
+concat3(|@array); #=> a, b, c
+ # `@array` got "flattened" as a part of the argument list
### Containers
# In Perl 6, values are actually stored in "containers".
@@ -220,23 +200,19 @@ sub mutate($n is rw) {
# A sub itself returns a container, which means it can be marked as rw:
my $x = 42;
-sub mod() is rw { $x }
-mod() = 52; # in this case, the parentheses are mandatory
- # (else Perl 6 thinks `mod` is a "term")
+sub x-store() is rw { $x }
+x-store() = 52; # in this case, the parentheses are mandatory
+ # (else Perl 6 thinks `mod` is an identifier)
say $x; #=> 52
### Control Flow Structures
-
-# You don't need to put parenthesis around the condition,
-# but that also means you always have to use brackets (`{ }`) for their body:
-
## Conditionals
# - `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: (), 0, "0", "", Nil, A type (like `Str` or `Int`),
# and of course False itself.
# Every other value is Truthy.
if True {
@@ -247,30 +223,38 @@ unless False {
say "It's not false !";
}
+# As you can see, you don't need parentheses around conditions.
+# However, you do need the brackets around the "body" block:
+# if (true) say; # This doesn't work !
+
# You can also use their postfix versions, with the keyword after:
say "Quite truthy" if True;
-# if (true) say; # This doesn't work !
-
# - Ternary conditional, "?? !!" (like `x ? y : z` in some other languages)
my $a = $condition ?? $value-if-true !! $value-if-false;
# - `given`-`when` looks like other languages `switch`, but much more
# powerful thanks to smart matching and thanks to Perl 6's "topic variable", $_.
+#
# This variable contains the default argument of a block,
# a loop's current iteration (unless explicitly named), etc.
+#
# `given` simply puts its argument into `$_` (like a block would do),
# and `when` compares it using the "smart matching" (`~~`) operator.
+#
# Since other Perl 6 constructs use this variable (as said before, like `for`,
# blocks, etc), this means the powerful `when` is not only applicable along with
# a `given`, but instead anywhere a `$_` exists.
given "foo bar" {
- when /foo/ { # Don't worry about smart matching -- just know `when` uses it.
+ say $_; #=> foo bar
+ when /foo/ { # Don't worry about smart matching yet – just know `when` uses it.
# This is equivalent to `if $_ ~~ /foo/`.
say "Yay !";
}
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 {...}
say "Quite a long string !";
}
default { # same as `when *` (using the Whatever Star)
@@ -281,7 +265,7 @@ given "foo bar" {
## Looping constructs
# - `loop` is an infinite loop if you don't pass it arguments,
-# but can also be a c-style `for`:
+# but can also be a C-style `for` loop:
loop {
say "This is an infinite loop !";
last; # last breaks out of the loop, like the `break` keyword in other languages
@@ -296,7 +280,7 @@ loop (my $i = 0; $i < 5; $i++) {
# - `for` - Passes through an array
for @array -> $variable {
- say "I've found $variable !";
+ say "I've got $variable !";
}
# As we saw with given, for's default "current iteration" variable is `$_`.
@@ -316,22 +300,15 @@ for @array {
last if $_ == 5; # Or break out of a loop (like `break` in C-like languages).
}
-# Note - the "lambda" `->` syntax isn't reserved to `for`:
+# The "pointy block" syntax isn't specific to for.
+# It's just a way to express a block in Perl6.
if long-computation() -> $result {
say "The result is $result";
}
-## Loops can also have a label, and be jumped to through these.
-OUTER: while 1 {
- say "hey";
- while 1 {
- OUTER.last; # All the control keywords must be called on the label itself
- }
-}
-
# 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 (except if some sub-list were put in item context ($)).
+# shallow list.
for 1, 2, (3, (4, ((5)))) {
say "Got $_.";
} #=> Got 1. Got 2. Got 3. Got 4. Got 5.
@@ -348,9 +325,14 @@ for [1, 2, 3, 4] {
say "Got $_.";
} #=> Got 1 2 3 4.
-# The other difference between `$()` and `[]` is that `[]` always returns a mutable Array
-# whereas `$()` will return a Parcel when given a Parcel.
+# 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
@@ -394,9 +376,6 @@ $arg ~~ &bool-returning-function; # `True` if the function, passed `$arg`
1 ~~ True; # smart-matching against a boolean always returns that boolean
# (and will warn).
-# - `===` is value identity and uses `.WHICH` on the objects to compare them
-# - `=:=` is container identity and uses `VAR()` on the objects to compare them
-
# You also, of course, have `<`, `<=`, `>`, `>=`.
# Their string equivalent are also avaiable : `lt`, `le`, `gt`, `ge`.
3 > 4;
@@ -559,6 +538,21 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
# Note : those are sorted lexicographically.
# `{ $^b / $^a }` is like `-> $a, $b { $b / $a }`
+## About types...
+# Perl6 is gradually typed. This means you can specify the type
+# of your variables/arguments/return types, or you can omit them
+# and they'll default to "Any".
+# You obviously get access to a few base types, like Int and Str.
+# The constructs for declaring types are "class", "role",
+# which you'll see later.
+
+# For now, let us examinate "subset":
+# a "subset" is a "sub-type" with additional checks.
+# For example: "a very big integer is an Int that's greater than 500"
+# You can specify the type you're subtyping (by default, Any),
+# and add additional checks with the "where" keyword:
+subset VeryBigInteger of Int where * > 500;
+
## Multiple Dispatch
# Perl 6 can decide which variant of a `sub` to call based on the type of the
# arguments, or on arbitrary preconditions, like with a type or a `where`:
@@ -567,20 +561,19 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
multi sub sayit(Int $n) { # note the `multi` keyword here
say "Number: $n";
}
-multi sayit(Str $s) } # the `sub` is the default
+multi sayit(Str $s) } # a multi is a `sub` by default
say "String: $s";
}
sayit("foo"); # prints "String: foo"
sayit(True); # fails at *compile time* with
# "calling 'sayit' will never work with arguments of types ..."
-# with arbitrary precondition:
+# with arbitrary precondition (remember subsets?):
multi is-big(Int $n where * > 50) { "Yes !" } # using a closure
multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
# (could use a regexp, etc)
multi is-big(Int $) { "No" }
-# You can also name these checks, by creating "subsets":
subset Even of Int where * %% 2;
multi odd-or-even(Even) { "Even" } # The main case using the type.
@@ -724,7 +717,7 @@ role PrintableVal {
}
}
-# you "use" a mixin with "does" :
+# you "import" a mixin (a "role") with "does":
class Item does PrintableVal {
has $.val;
@@ -1083,9 +1076,7 @@ postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
# It's a prefix meta-operator that takes a binary functions and
# one or many lists. If it doesn't get passed any argument,
# it either return a "default value" for this operator
-# (a value that wouldn't change the result if passed as one
-# of the element of the list to be passed to the operator),
-# or `Any` if there's none (examples below).
+# (a meaningless value) or `Any` if there's none (examples below).
#
# Otherwise, it pops an element from the list(s) one at a time, and applies
# the binary function to the last result (or the list's first element)
@@ -1107,9 +1098,7 @@ say [//] Nil, Any, False, 1, 5; #=> False
# Default value examples:
say [*] (); #=> 1
say [+] (); #=> 0
- # In both cases, they're results that, were they in the lists,
- # wouldn't have any impact on the final value
- # (since N*1=N and N+0=N).
+ # meaningless values, since N*1=N and N+0=N.
say [//]; #=> (Any)
# There's no "default value" for `//`.
@@ -1163,90 +1152,6 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
# That's why `@primes[^100]` will take a long time the first time you print
# it, then be instant.
-
-## * Sort comparison
-# They return one value of the `Order` enum : `Less`, `Same` and `More`
-# (which numerify to -1, 0 or +1).
-1 <=> 4; # sort comparison for numerics
-'a' leg 'b'; # sort comparison for string
-$obj eqv $obj2; # sort comparison using eqv semantics
-
-## * Generic ordering
-3 before 4; # True
-'b' after 'a'; # True
-
-## * Short-circuit default operator
-# Like `or` and `||`, but instead returns the first *defined* value :
-say Any // Nil // 0 // 5; #=> 0
-
-## * Short-circuit exclusive or (XOR)
-# Returns `True` if one (and only one) of its arguments is true
-say True ^^ False; #=> True
-
-## * Flip Flop
-# The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
-# are operators that take two predicates to test:
-# They are `False` until their left side returns `True`, then are `True` until
-# their right side returns `True`.
-# Like for ranges, you can exclude the iteration when it became `True`/`False`
-# by using `^` on either side.
-# Let's start with an example :
-for <well met young hero we shall meet later> {
- # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
- if 'met' ^ff 'meet' { # Won't enter the if for "met"
- # (explained in details below).
- .say
- }
-
- if rand == 0 ff rand == 1 { # compare variables other than `$_`
- say "This ... probably will never run ...";
- }
-}
-# This will print "young hero we shall meet" (excluding "met"):
-# the flip-flop will start returning `True` when it first encounters "met"
-# (but will still return `False` for "met" itself, due to the leading `^`
-# on `ff`), until it sees "meet", which is when it'll start returning `False`.
-
-# The difference between `ff` (awk-style) and `fff` (sed-style) is that
-# `ff` will test its right side right when its left side changes to `True`,
-# and can get back to `False` right away
-# (*except* it'll be `True` for the iteration that matched) -
-# While `fff` will wait for the next iteration to
-# try its right side, once its left side changed:
-.say if 'B' ff 'B' for <A B C B A>; #=> B B
- # because the right-hand-side was tested
- # directly (and returned `True`).
- # "B"s are printed since it matched that time
- # (it just went back to `False` right away).
-.say if 'B' fff 'B' for <A B C B A>; #=> B C B
- # The right-hand-side wasn't tested until
- # `$_` became "C"
- # (and thus did not match instantly).
-
-# A flip-flop can change state as many times as needed:
-for <test start print it stop not printing start print again stop not anymore> {
- .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
- #=> "print this printing again"
-}
-
-# you might also use a Whatever Star,
-# which is equivalent to `True` for the left side or `False` for the right:
-for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
- # (sometimes called "superstitious parentheses")
- .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
- # it'll never go back to `False`
- #=> 60 3 40 60
-}
-
-# You can also use this property to create an `If`
-# that'll not go through the first time :
-for <a b c> {
- .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
- # but the `^` makes it *not run* on the first iteration
- #=> b c
-}
-
-
### Regular Expressions
# I'm sure a lot of you have been waiting for this one.
# Well, now that you know a good deal of Perl 6 already, we can get started.
@@ -1470,6 +1375,105 @@ multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
# As you can see, this is *very* powerful.
# It even went as far as to show inline the constants.
# (the type is only displayed if the argument is `$`/is named)
+
+###
+### APPENDIX A:
+###
+### List of things
+###
+
+# It's considered by now you know the Perl6 basics.
+# This section is just here to list some common operations,
+# but which are not in the "main part" of the tutorial to bloat it up
+
+## Operators
+
+
+## * Sort comparison
+# They return one value of the `Order` enum : `Less`, `Same` and `More`
+# (which numerify to -1, 0 or +1).
+1 <=> 4; # sort comparison for numerics
+'a' leg 'b'; # sort comparison for string
+$obj eqv $obj2; # sort comparison using eqv semantics
+
+## * Generic ordering
+3 before 4; # True
+'b' after 'a'; # True
+
+## * Short-circuit default operator
+# Like `or` and `||`, but instead returns the first *defined* value :
+say Any // Nil // 0 // 5; #=> 0
+
+## * Short-circuit exclusive or (XOR)
+# Returns `True` if one (and only one) of its arguments is true
+say True ^^ False; #=> True
+## * Flip Flop
+# The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
+# are operators that take two predicates to test:
+# They are `False` until their left side returns `True`, then are `True` until
+# their right side returns `True`.
+# Like for ranges, you can exclude the iteration when it became `True`/`False`
+# by using `^` on either side.
+# Let's start with an example :
+for <well met young hero we shall meet later> {
+ # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
+ if 'met' ^ff 'meet' { # Won't enter the if for "met"
+ # (explained in details below).
+ .say
+ }
+
+ if rand == 0 ff rand == 1 { # compare variables other than `$_`
+ say "This ... probably will never run ...";
+ }
+}
+# This will print "young hero we shall meet" (excluding "met"):
+# the flip-flop will start returning `True` when it first encounters "met"
+# (but will still return `False` for "met" itself, due to the leading `^`
+# on `ff`), until it sees "meet", which is when it'll start returning `False`.
+
+# The difference between `ff` (awk-style) and `fff` (sed-style) is that
+# `ff` will test its right side right when its left side changes to `True`,
+# and can get back to `False` right away
+# (*except* it'll be `True` for the iteration that matched) -
+# While `fff` will wait for the next iteration to
+# try its right side, once its left side changed:
+.say if 'B' ff 'B' for <A B C B A>; #=> B B
+ # because the right-hand-side was tested
+ # directly (and returned `True`).
+ # "B"s are printed since it matched that time
+ # (it just went back to `False` right away).
+.say if 'B' fff 'B' for <A B C B A>; #=> B C B
+ # The right-hand-side wasn't tested until
+ # `$_` became "C"
+ # (and thus did not match instantly).
+
+# A flip-flop can change state as many times as needed:
+for <test start print it stop not printing start print again stop not anymore> {
+ .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
+ #=> "print this printing again"
+}
+
+# you might also use a Whatever Star,
+# which is equivalent to `True` for the left side or `False` for the right:
+for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
+ # (sometimes called "superstitious parentheses")
+ .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
+ # it'll never go back to `False`
+ #=> 60 3 40 60
+}
+
+# You can also use this property to create an `If`
+# that'll not go through the first time :
+for <a b c> {
+ .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
+ # but the `^` makes it *not run* on the first iteration
+ #=> b c
+}
+
+
+# - `===` is value identity and uses `.WHICH` on the objects to compare them
+# - `=:=` is container identity and uses `VAR()` on the objects to compare them
+
```
If you want to go further, you can:
@@ -1477,5 +1481,5 @@ If you want to go further, you can:
- Read the [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). This is probably the greatest source of Perl 6 information, snippets and such.
- Come along on `#perl6` at `irc.freenode.net`. The folks here are always helpful.
- Check the [source of Perl 6's functions and classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is mainly written in Perl 6 (with a lot of NQP, "Not Quite Perl", a Perl 6 subset easier to implement and optimize).
- - Read the [Synopses](perlcabal.org/syn). They explain it from an implementor point-of-view, but it's still very interesting.
+ - Read [the language design documents](http://design.perl6.org). They explain P6 from an implementor point-of-view, but it's still very interesting.
diff --git a/pogo.html.markdown b/pogo.html.markdown
index 60a83edd..aa5d49f3 100644
--- a/pogo.html.markdown
+++ b/pogo.html.markdown
@@ -199,4 +199,4 @@ That's it.
Download [Node.js](http://nodejs.org/) and `npm install pogo`.
-There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), inlcuding a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!
+There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), including a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!
diff --git a/pt-br/hy-pt.html.markdown b/pt-br/hy-pt.html.markdown
new file mode 100644
index 00000000..4230579d
--- /dev/null
+++ b/pt-br/hy-pt.html.markdown
@@ -0,0 +1,176 @@
+---
+language: hy
+filename: learnhy.hy
+contributors:
+ - ["Abhishek L", "http://twitter.com/abhishekl"]
+translators:
+ - ["Miguel Araújo", "https://github.com/miguelarauj1o"]
+lang: pt-br
+---
+
+Hy é um dialeto de Lisp escrito sobre Python. Isto é possível convertendo
+código Hy em árvore sintática abstrata python (ast). Portanto, isto permite
+hy chamar código python nativo e vice-versa.
+
+Este tutorial funciona para hy ≥ 0.9.12
+
+```clojure
+;; Isso dá uma introdução básica em hy, como uma preliminar para o link abaixo
+;; http://try-hy.appspot.com
+;;
+; Comentários em ponto-e-vírgula, como em outros LISPS
+
+;; s-noções básicas de expressão
+; programas Lisp são feitos de expressões simbólicas ou sexps que se assemelham
+(some-function args)
+; agora o essencial "Olá mundo"
+(print "hello world")
+
+;; Tipos de dados simples
+; Todos os tipos de dados simples são exatamente semelhantes aos seus homólogos
+; em python que
+42 ; => 42
+3.14 ; => 3.14
+True ; => True
+4+10j ; => (4+10j) um número complexo
+
+; Vamos começar com um pouco de aritmética muito simples
+(+ 4 1) ;=> 5
+; o operador é aplicado a todos os argumentos, como outros lisps
+(+ 4 1 2 3) ;=> 10
+(- 2 1) ;=> 1
+(* 4 2) ;=> 8
+(/ 4 1) ;=> 4
+(% 4 2) ;=> 0 o operador módulo
+; exponenciação é representado pelo operador ** como python
+(** 3 2) ;=> 9
+; formas aninhadas vão fazer a coisa esperada
+(+ 2 (* 4 2)) ;=> 10
+; também operadores lógicos e ou não e igual etc. faz como esperado
+(= 5 4) ;=> False
+(not (= 5 4)) ;=> True
+
+;; variáveis
+; variáveis são definidas usando SETV, nomes de variáveis podem usar utf-8, exceto
+; for ()[]{}",'`;#|
+(setv a 42)
+(setv π 3.14159)
+(def *foo* 42)
+;; outros tipos de dados de armazenamento
+; strings, lists, tuples & dicts
+; estes são exatamente os mesmos tipos de armazenamento de python
+"hello world" ;=> "hello world"
+; operações de string funcionam semelhante em python
+(+ "hello " "world") ;=> "hello world"
+; Listas são criadas usando [], a indexação começa em 0
+(setv mylist [1 2 3 4])
+; tuplas são estruturas de dados imutáveis
+(setv mytuple (, 1 2))
+; dicionários são pares de valores-chave
+(setv dict1 {"key1" 42 "key2" 21})
+; :nome pode ser utilizado para definir palavras-chave em hy que podem ser utilizados para as chaves
+(setv dict2 {:key1 41 :key2 20})
+; usar 'get' para obter o elemento em um índice/key
+(get mylist 1) ;=> 2
+(get dict1 "key1") ;=> 42
+; Alternativamente, se foram utilizadas palavras-chave que podem ser chamadas diretamente
+(:key1 dict2) ;=> 41
+
+;; funções e outras estruturas de programa
+; funções são definidas usando defn, o último sexp é devolvido por padrão
+(defn greet [name]
+ "A simple greeting" ; uma docstring opcional
+ (print "hello " name))
+
+(greet "bilbo") ;=> "hello bilbo"
+
+; funções podem ter argumentos opcionais, bem como argumentos-chave
+(defn foolists [arg1 &optional [arg2 2]]
+ [arg1 arg2])
+
+(foolists 3) ;=> [3 2]
+(foolists 10 3) ;=> [10 3]
+
+; funções anônimas são criados usando construtores 'fn' ou 'lambda'
+; que são semelhantes para 'defn'
+(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
+
+;; operações de sequência
+; hy tem algumas utils embutidas para operações de sequência, etc.
+; recuperar o primeiro elemento usando 'first' ou 'car'
+(setv mylist [1 2 3 4])
+(setv mydict {"a" 1 "b" 2})
+(first mylist) ;=> 1
+
+; corte listas usando 'slice'
+(slice mylist 1 3) ;=> [2 3]
+
+; obter elementos de uma lista ou dict usando 'get'
+(get mylist 1) ;=> 2
+(get mydict "b") ;=> 2
+; lista de indexação começa a partir de 0, igual em python
+; assoc pode definir elementos em chaves/índices
+(assoc mylist 2 10) ; faz mylist [1 2 10 4]
+(assoc mydict "c" 3) ; faz mydict {"a" 1 "b" 2 "c" 3}
+; há toda uma série de outras funções essenciais que torna o trabalho com
+; sequências uma diversão
+
+;; Python interop
+;; importação funciona exatamente como em python
+(import datetime)
+(import [functools [partial reduce]]) ; importa fun1 e fun2 do module1
+(import [matplotlib.pyplot :as plt]) ; fazendo uma importação em foo como em bar
+; todos os métodos de python embutidas etc. são acessíveis a partir hy
+; a.foo(arg) is called as (.foo a arg)
+(.split (.strip "hello world ")) ;=> ["hello" "world"]
+
+;; Condicionais
+; (if condition (body-if-true) (body-if-false)
+(if (= passcode "moria")
+ (print "welcome")
+ (print "Speak friend, and Enter!"))
+
+; aninhe múltiplas cláusulas 'if else if' com cond
+(cond
+ [(= someval 42)
+ (print "Life, universe and everything else!")]
+ [(> someval 42)
+ (print "val too large")]
+ [(< someval 42)
+ (print "val too small")])
+
+; declarações de grupo com 'do', essas são executadas sequencialmente
+; formas como defn tem um 'do' implícito
+(do
+ (setv someval 10)
+ (print "someval is set to " someval)) ;=> 10
+
+; criar ligações lexicais com 'let', todas as variáveis definidas desta forma
+; tem escopo local
+(let [[nemesis {"superman" "lex luther"
+ "sherlock" "moriarty"
+ "seinfeld" "newman"}]]
+ (for [(, h v) (.items nemesis)]
+ (print (.format "{0}'s nemesis was {1}" h v))))
+
+;; classes
+; classes são definidas da seguinte maneira
+(defclass Wizard [object]
+ [[--init-- (fn [self spell]
+ (setv self.spell spell) ; init a mágica attr
+ None)]
+ [get-spell (fn [self]
+ self.spell)]])
+
+;; acesse hylang.org
+```
+
+### Outras Leituras
+
+Este tutorial é apenas uma introdução básica para hy/lisp/python.
+
+Docs Hy: [http://hy.readthedocs.org](http://hy.readthedocs.org)
+
+Repo Hy no Github: [http://github.com/hylang/hy](http://github.com/hylang/hy)
+
+Acesso ao freenode irc com #hy, hashtag no twitter: #hylang
diff --git a/pt-br/xml-pt.html.markdown b/pt-br/xml-pt.html.markdown
new file mode 100644
index 00000000..40ddbc3a
--- /dev/null
+++ b/pt-br/xml-pt.html.markdown
@@ -0,0 +1,133 @@
+---
+language: xml
+filename: learnxml.xml
+contributors:
+ - ["João Farias", "https://github.com/JoaoGFarias"]
+translators:
+ - ["Miguel Araújo", "https://github.com/miguelarauj1o"]
+lang: pt-br
+---
+
+XML é uma linguagem de marcação projetada para armazenar e transportar dados.
+
+Ao contrário de HTML, XML não especifica como exibir ou formatar os dados,
+basta carregá-lo.
+
+* Sintaxe XML
+
+```xml
+<!-- Comentários em XML são feitos desta forma -->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<livraria>
+ <livro category="COZINHA">
+ <titulo lang="en">Everyday Italian</titulo>
+ <autor>Giada De Laurentiis</autor>
+ <year>2005</year>
+ <preco>30.00</preco>
+ </livro>
+ <livro category="CRIANÇAS">
+ <titulo lang="en">Harry Potter</titulo>
+ <autor>J K. Rowling</autor>
+ <year>2005</year>
+ <preco>29.99</preco>
+ </livro>
+ <livro category="WEB">
+ <titulo lang="en">Learning XML</titulo>
+ <autor>Erik T. Ray</autor>
+ <year>2003</year>
+ <preco>39.95</preco>
+ </livro>
+</livraria>
+
+<!-- Um típico arquivo XML é mostrado acima.
+ Ele começa com uma declaração, informando alguns metadados (opcional).
+
+ XML usa uma estrutura de árvore. Acima, o nó raiz é "Livraria", que tem
+ três nós filhos, todos os 'Livros'. Esses nós tem mais nós filhos,
+ e assim por diante...
+
+ Nós são criados usando tags abre/fecha, filhos são justamente os nós que
+ estão entre estes nós. -->
+
+
+<!-- XML traz dois tipos de dados:
+ 1 - Atributos -> Isso é metadados sobre um nó.
+ Normalmente, o parser XML usa esta informação para armazenar os dados
+ corretamente. Caracteriza-se por aparecer em parênteses dentro da tag
+ de abertura.
+ 2 - Elementos -> É dados puros.
+ Isso é o que o analisador irá recuperar a partir do arquivo XML.
+ Elementos aparecem entre as tags de abertura e fechamento,
+ sem parênteses. -->
+
+
+<!-- Abaixo, um elemento com dois atributos -->
+<arquivo type="gif" id="4293">computer.gif</arquivo>
+
+
+```
+
+* Documento bem formatado x Validação
+
+Um documento XML é bem formatado se estiver sintaticamente correto.No entanto,
+é possível injetar mais restrições no documento, utilizando definições de
+documentos, tais como DTD e XML Schema.
+
+Um documento XML que segue uma definição de documento é chamado válido, sobre
+esse documento.
+
+Com esta ferramenta, você pode verificar os dados XML fora da lógica da aplicação.
+
+```xml
+
+<!-- Abaixo, você pode ver uma versão simplificada do documento livraria,
+com a adição de definição DTD.-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE note SYSTEM "livraria.dtd">
+<livraria>
+ <livro category="COOKING">
+ <titulo >Everyday Italian</titulo>
+ <preco>30.00</preco>
+ </livro>
+</livraria>
+
+<!-- Este DTD poderia ser algo como:-->
+
+<!DOCTYPE note
+[
+<!ELEMENT livraria (livro+)>
+<!ELEMENT livro (titulo,preco)>
+<!ATTLIST livro category CDATA "Literature">
+<!ELEMENT titulo (#PCDATA)>
+<!ELEMENT preco (#PCDATA)>
+]>
+
+
+<!-- O DTD começa com uma declaração.
+ Na sequência, o nó raiz é declarado, o que requer uma ou mais crianças nós
+ 'Livro'. Cada 'Livro' deve conter exatamente um 'titulo' e um 'preco' e um
+ atributo chamado "categoria", com "Literatura", como o valor padrão.
+ Os nós "título" e "preço" contêm um conjunto de dados de caráter analisados.-->
+
+<!-- O DTD poderia ser declarado dentro do próprio arquivo XML .-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE note
+[
+<!ELEMENT livraria (livro+)>
+<!ELEMENT livro (titulo,preco)>
+<!ATTLIST livro category CDATA "Literature">
+<!ELEMENT titulo (#PCDATA)>
+<!ELEMENT preco (#PCDATA)>
+]>
+
+<livraria>
+ <livro category="COOKING">
+ <titulo >Everyday Italian</titulo>
+ <preco>30.00</preco>
+ </livro>
+</livraria>
+``` \ No newline at end of file
diff --git a/python.html.markdown b/python.html.markdown
index 53381f32..da04d381 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -264,7 +264,7 @@ filled_dict.get("four") # => None
# The get method supports a default argument when the value is missing
filled_dict.get("one", 4) # => 1
filled_dict.get("four", 4) # => 4
-# note that filled_dict.get("four") is still => 4
+# note that filled_dict.get("four") is still => None
# (get doesn't set the value in the dictionary)
# set the value of a key with a syntax similar to lists
diff --git a/python3.html.markdown b/python3.html.markdown
index 0b4feccc..6b1d3156 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -635,7 +635,6 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
* [The Official Docs](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/3/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Dead Tree
diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown
index 44a22b45..e06ae9bd 100644
--- a/ru-ru/go-ru.html.markdown
+++ b/ru-ru/go-ru.html.markdown
@@ -65,7 +65,7 @@ func beyondHello() {
learnTypes() // < y minutes, learn more!
}
-// Функция имеющая входные параметры и возврат нескольких значений.
+// Функция, имеющая входные параметры и возвращающая несколько значений.
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Возврат двух значений.
}
diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown
new file mode 100644
index 00000000..ad66b501
--- /dev/null
+++ b/ru-ru/javascript-ru.html.markdown
@@ -0,0 +1,543 @@
+---
+language: javascript
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+translators:
+ - ["Maxim Koretskiy", "http://github.com/maximkoretskiy"]
+filename: javascript-ru.js
+lang: ru-ru
+---
+
+Javascript был разработан Бренданом Айком из Netcape в 1995. Изначально
+предполагалось, что он станет простым вариантом скриптового языка для сайтов,
+дополняющий к Java, который бы в свою очередь использовался для более сложных
+web-приложений. Но тонкая интегрированность javascript с web-страницей и
+встроенная поддержка в браузерах привели к тому, чтобы он стал более
+распространен в frontend-разработке, чем Java.
+
+Использование JavaScript не ограничивается браузерами. Проект Node.js,
+предоставляющий независимую среду выполнения на движке Google Chrome V8
+JavaScript, становится все более популярным.
+
+Обратная связь важна и нужна! Вы можете написаться мне
+на [@adambrenecki](https://twitter.com/adambrenecki) или
+[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+
+```js
+// Комментарии оформляются как в C.
+// Однострочнные коментарии начинаются с двух слешей,
+/* а многострочные с слеша и звездочки
+ и заканчиваются звездочеий и слешом */
+
+// Выражения разделяются с помощью ;
+doStuff();
+
+// ... но этого можно и не делать, разделители подставляются автоматически
+// после перехода на новую строку за исключением особых случаев
+doStuff()
+
+// Это может приводить к непредсказуемому результату и поэтому мы будем
+// использовать разделители в этом туре.
+// Because those cases can cause unexpected results, we'll keep on using
+// semicolons in this guide.
+
+///////////////////////////////////
+// 1. Числа, Строки и Операторы
+// 1. Numbers, Strings and Operators
+
+// В Javasript всего 1 числовой тип - 64-битное число с плавающей точкой
+// стандарта IEEE 754)
+// Числа имеют 52-битную мантиссу, чего достаточно для хранения хранения целых
+// чисел до 9✕10¹⁵ приблизительно.
+3; // = 3
+1.5; // = 1.5
+
+// В основном базовая арифметика работает предсказуемо
+1 + 1; // = 2
+.1 + .2; // = 0.30000000000000004
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+
+// Включая нецелочисленное деление
+5 / 2; // = 2.5
+
+// Двоичные операции тоже есть. Если применить двоичную операцию к float-числу,
+// оно будет приведено к 32-битному целому со знаком.
+1 << 2; // = 4
+
+// (todo:перевести)
+// Приоритет выполнения операций можно менять с помощью скобок.
+(1 + 3) * 2; // = 8
+
+// Есть три особых не реальных числовых значения:
+Infinity; // допустим, результат операции 1/0
+-Infinity; // допустим, результат операции -1/0
+NaN; // допустим, результат операции 0/0
+
+// Так же есть тип булевых данных.
+true;
+false;
+
+// Строки создаются с помощью ' или ".
+'abc';
+"Hello, world";
+
+// Оператор ! означает отрицание
+!true; // = false
+!false; // = true
+
+// Равество это ===
+1 === 1; // = true
+2 === 1; // = false
+
+// Неравенство это !==
+1 !== 1; // = false
+2 !== 1; // = true
+
+// Еще сравнения
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
+
+// Строки складываются с помощью +
+"Hello " + "world!"; // = "Hello world!"
+
+// и сравниваются с помощью < и >
+"a" < "b"; // = true
+
+// Приведение типов выполняется при сравнении с ==...
+"5" == 5; // = true
+null == undefined; // = true
+
+// ...в отличие от ===
+"5" === 5; // = false
+null === undefined; // = false
+
+// Для доступа к конкретному символу строки используйте charAt
+"This is a string".charAt(0); // = 'T'
+
+// ... или используйте substring для получения подстроки
+"Hello world".substring(0, 5); // = "Hello"
+
+// length(длина) - свойство, не используйте ()
+"Hello".length; // = 5
+
+// Есть null и undefined
+null; // используется что бы указать явно, что значения нет
+undefined; // испрользуется чтобы показать, что значения не было установлено
+ // собственно, undefined так и переводится
+
+// false, null, undefined, NaN, 0 и "" являются falsy-значениями(при приведении
+// в булеву типу становятся false)
+// Обратите внимание что 0 приводится к false, а "0" к true,
+// не смотря на то, что "0"==0
+
+///////////////////////////////////
+// 2. Переменные, массивы и объекты
+
+// Переменные объявляются ключевым словом var. Javascript динамически
+// типизируемый, так что указывать тип не нужно.
+// Присвоение значения описывается с помощью оператора =
+var someVar = 5;
+
+// если не указать ключевого слова var, ошибки не будет...
+someOtherVar = 10;
+
+// ...но переменная будет создана в глобальном контексте, в не области
+// видимости, в которой она была объявлена.
+
+// Переменные объявленные без присвоения значения, содержать undefined
+var someThirdVar; // = undefined
+
+// Для математических операций над переменными есть короткая запись:
+someVar += 5; // тоже что someVar = someVar + 5; someVar равно 10 теперь
+someVar *= 10; // а теперь -- 100
+
+// еще более короткая запись для добавления и вычитания 1
+someVar++; // теперь someVar равно 101
+someVar--; // обратно к 100
+
+// Массивы -- упорядоченные списки значений любых типов.
+var myArray = ["Hello", 45, true];
+
+// Для доступу к элементам массивов используйте квадратные скобки.
+// Индексы массивов начинаются с 0
+myArray[1]; // = 45
+
+// Массивы мутабельны(изменяемы) и имеют переменную длину.
+myArray.push("World"); // добавить элемент
+myArray.length; // = 4
+
+// Добавить или изменить значение по конкретному индексу
+myArray[3] = "Hello";
+
+// Объекты javascript похожи на dictionary или map из других языков
+// программирования. Это неупорядочнные коллекции пар ключ-значение.
+var myObj = {key1: "Hello", key2: "World"};
+
+// Ключи -- это строки, но кавычки не требуются если названия явлюятся
+// корректными javascript идентификаторами. Значения могут быть любого типа.
+var myObj = {myKey: "myValue", "my other key": 4};
+
+// Доступ к атрибту объекта можно получить с помощью квадратных скобок
+myObj["my other key"]; // = 4
+
+// ... или используя точечную нотацию, при условии что ключ является
+// корректным идентификатором.
+myObj.myKey; // = "myValue"
+
+// Объекты мутабельны. В существуюещем объекте можно изменить значние
+// или добавить новый атрибут.
+myObj.myThirdKey = true;
+
+// При попытке доступа к атрибуту, который до этого не был создан, будет
+// возвращен undefined
+myObj.myFourthKey; // = undefined
+
+///////////////////////////////////
+// 3. Логика и Управляющие структуры
+
+// Синтаксис управляющих структур очень похож на его реализацию в Java.
+
+// if работает так как вы ожидаете.
+var count = 1;
+if (count == 3){
+ // выполнится, если значение count равно 3
+} else if (count == 4){
+ // выполнится, если значение count равно 4
+} else {
+ // выполнится, если значение count не будет равно ни 3 ни 4
+}
+
+// Поведение while тоже вполне предсказуемо
+while (true){
+ // Бесконечный цикл
+}
+
+// Циклы do-while похожи на while, но они всегда выполняются хотябы 1 раз.
+// Do-while loops are like while loops, except they always run at least once.
+var input
+do {
+ input = getInput();
+} while (!isValid(input))
+
+// Цикл for такой же как в C и Java:
+// инициализация; условие продолжения; итерация
+for (var i = 0; i < 5; i++){
+ // выполнится 5 раз
+}
+
+// && - логическое и, || - логическое или
+if (house.size == "big" && house.color == "blue"){
+ house.contains = "bear";
+}
+if (color == "red" || color == "blue"){
+ // если цвет или красный или синий
+}
+
+// && и || удобны для установки значений по умолчанию.
+// && and || "short circuit", which is useful for setting default values.
+var name = otherName || "default";
+
+// выражение switch проверяет равество с помощью ===
+// используйте 'break' после каждого case,
+// иначе помимо правильного case выполнятся и все последующие.
+grade = '4'; // оценка
+switch (grade) {
+ case '5':
+ console.log("Великолепно");
+ break;
+ case '4':
+ console.log("Неплохо");
+ break;
+ case '3':
+ console.log("Можно и лучше");
+ break;
+ default:
+ console.log("Да уж.");
+ break;
+}
+
+
+///////////////////////////////////
+// 4. Функции, Область видимости и Замыкания
+
+// Функции в JavaScript объявляются с помощью ключевого слова function.
+function myFunction(thing){
+ return thing.toUpperCase(); // приведение к верхнему регистру
+}
+myFunction("foo"); // = "FOO"
+
+// Помните, что значение, которое должно быть возкращено должно начинаться
+// на той же строке, где расположено ключевое слово 'return'. В противном случае
+// будет возвращено undefined. Такое поведения объясняется автоматической
+// вставкой разделителей ';'. Помните этот факт, если используете
+// BSD стиль оформления кода.
+// Note that the value to be returned must start on the same line as the
+// 'return' keyword, otherwise you'll always return 'undefined' due to
+// automatic semicolon insertion. Watch out for this when using Allman style.
+function myFunction()
+{
+ return // <- разделитель автоматически будет вставлен здесь
+ {
+ thisIsAn: 'object literal'
+ }
+}
+myFunction(); // = undefined
+
+// Функции в JavaScript являются объектами, поэтому их можно назначить в
+// переменные с разными названиями и передавать в другие функции, как аргументы,
+// на пример, при указании обработчика события.
+function myFunction(){
+ // этот фрагмент кода будет вызван через 5 секунд
+}
+setTimeout(myFunction, 5000);
+// Обратите внимание, что setTimeout не является частью языка, однако он
+// доступен в API браузеров и Node.js.
+
+// Объект функции на самом деле не обязательно объявлять с именем - можно
+// создать анонимную функцию прямо в аргументах другой функции.
+setTimeout(function(){
+ // этот фрагмент кода будет вызван через 5 секунд
+}, 5000);
+
+// В JavaScript есть области видимости. У функций есть собственные области
+// видимости, у других блоков их нет.
+if (true){
+ var i = 5;
+}
+i; // = 5, а не undefined, как это было бы в языке, создающем
+ // области видисти для блоков кода
+
+// Это привело к появлению паттерна общего назначения "immediately-executing
+// anonymous functions" (сразу выполняющиеся анонимные функции), который
+// позволяет предотвратить запись временных переменных в общую облать видимости.
+(function(){
+ var temporary = 5;
+ // Для доступа к глобальной области видимости можно использовать запись в
+ // некоторый 'глобальный объект', для браузеров это 'window'. Глобальный
+ // объект может называться по-разному в небраузерных средах, таких Node.js.
+ window.permanent = 10;
+})();
+temporary; // вызывает исключение ReferenceError
+permanent; // = 10
+
+// Одной из сильных сторон JavaScript являются замыкания. Если функция
+// объявлена в внутри другой функции, внутренняя функция имеет доступ ко всем
+// переменным внешней функции, даже после того, как внешняя функции завершила
+// свое выполнение.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Привет, " + name + "!";
+ // Внутренние функции помещаются в локальную область видимости, как-будто
+ // они объявлены с ключевым словом 'var'.
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout является асинхроннной, и поэтому функция sayHelloInFiveSeconds
+ // завершит свое выполнение сразу и setTimeout вызовет inner позже.
+ // Однако, так как inner "закрыта внутри" или "замкнута в"
+ // sayHelloInFiveSeconds, inner все еще будет иметь доступ к переменной
+ // prompt, когда будет вызвана.
+}
+sayHelloInFiveSeconds("Вася"); // откроет модальное окно с сообщением
+ // "Привет, Вася" по истечении 5 секунд.
+
+
+///////////////////////////////////
+// 5. Немного еще об Объектах. Конструкторы и Прототипы
+
+// Объекты могут содержать функции
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Когда функции прикрепленные к объекту вызываются, они могут получить доступ
+// к данным объекта, ипользуя ключевое слово this.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Содержание this определяется исходя из того, как была вызвана функция, а
+// не места её определения. По этой причине наша функция не будет работать вне
+// контекста объекта.
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+
+// И напротив, функция может быть присвоена объекту и получить доступ к нему
+// через this, даже если она не была прикреплена к объекту в момент её создания.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+}
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// Также можно указать контекс выполнения фунции с помощью 'call' или 'apply'.
+var anotherFunc = function(s){
+ return this.myString + s;
+}
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// Функция 'apply' очень похожа, но принимает массив со списком аргументов.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// Это может быть удобно, когда работаешь с фунцией принимающей на вход
+// последовательность аргументов и нужно передать их в виде массива.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// Однако, 'call' и 'apply' не имеют постоянного эффекта. Если вы хотите
+// зафиксировать контекст для функции, используйте bind.
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// bind также можно использовать чтобы частично передать аргументы в
+// функцию (каррировать).
+
+var product = function(a, b){ return a * b; }
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
+// Когда функция вызывается с ключевым словом new, создается новый объект.
+// Данный объект становится доступным функции через ключевое слово this.
+// Функции спроектированные вызываться таким способом называются конструкторами.
+
+var MyConstructor = function(){
+ this.myNumber = 5;
+}
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+
+// Любой объект в JavaScript имеет 'прототип'. Когда вы пытаетесь получить
+// доступ к свойству не объявленному в данном объекте, интерпретатор будет
+// искать его в прототипе.
+
+// Некоторые реализации JS позволяют получить доступ к прототипу с помощью
+// "волшебного" свойства __proto__. До момента пока оно не являются стандартным,
+// __proto__ полезно лишь для изучения прототипов в JavaScript. Мы разберемся
+// со стандартными способами работы с прототипом несколько позже.
+var myObj = {
+ myString: "Hello world!"
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase()
+ }
+};
+
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+myObj.myFunc(); // = "hello world!"
+
+// Естественно, если в свойства нет в прототипе, поиск будет продолжен в
+// прототипе прототипа и так далее.
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+
+// Ничего не копируется, каждый объект хранит ссылку на свой прототип. Если
+// изменить прототип, все изменения отразятся во всех его потомках.
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// Как было сказано выше, __proto__ не является стандартом, и нет стандартного
+// способа изменить прототип у созданного объекта. Однако, есть два способа
+// создать объект с заданным прототипом.
+
+// Первый способ - Object.create, был добавлен в JS относительно недавно, и
+// потому не доступен в более ранних реализациях языка.
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// Второй вариан доступен везде и связан с конструкторами. Конструкторы имеют
+// свойство prototype. Это вовсе не прототип функции конструктора, напротив,
+// это прототип, который присваевается новым объектам, созданным с этим
+// конструктором с помощью ключевого слова new.
+MyConstructor.prototype = {
+ myNumber: 5,
+ getMyNumber: function(){
+ return this.myNumber;
+ }
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6
+myNewObj2.getMyNumber(); // = 6
+
+// У встроенных типов таких, как строки и числа, тоже есть конструкторы,
+// создающие эквивалентные объекты-обертки.
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+
+// Правда, они не совсем эквивалентны.
+typeof myNumber; // = 'number'
+typeof myNumberObj; // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // Этот фрагмент кода не будет выпонен, так как 0 приводится к false
+}
+if (Number(0)){
+ // Этот фрагмент кода *будет* выпонен, так как Number(0) приводится к true.
+}
+
+// Однако, оберточные объекты и обычные встроенные типы имеют общие прототипы,
+// следовательно вы можете расширить функциональность строки, например.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+}
+"abc".firstCharacter(); // = "a"
+
+// Этот факт часто используется для создания полифилов(polyfill) - реализации
+// новых возможностей JS в его более старых версиях для того чтобы их можно было
+// использовать в устаревших браузерах.
+
+// Например, мы упомянули, что Object.create не доступен во всех версиях
+// JavaScript, но мы можем создать полифилл.
+if (Object.create === undefined){ // не переопределяем, если есть
+ Object.create = function(proto){
+ // создаем временный конструктор с заданным прототипом
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // создаём новый объект с правильным прототипом
+ return new Constructor();
+ }
+}
+```
+
+## Что еще почитать
+
+[Современный учебник JavaScript](http://learn.javascript.ru/) от Ильи Кантора
+является довольно качественным и глубоким учебным материалом, освещающим все
+особенности современного языка. Помимо учебника на том же домене можно найти
+[перевод спецификации ECMAScript 5.1](http://es5.javascript.ru/) и справочник по
+возможностям языка.
+
+[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) позволяет
+довольно быстро изучить основные тонкие места в работе с JS, но фокусируется
+только на таких моментах
+
+[Справочник](https://developer.mozilla.org/ru/docs/JavaScript) от MDN
+(Mozilla Development Network) содержит информацию о возможностях языка на
+английском.
+
+Название проекта ["Принципы написания консистентного, идиоматического кода на
+JavaScript"](https://github.com/rwaldron/idiomatic.js/tree/master/translations/ru_RU)
+говорит само за себя.
+
diff --git a/scala.html.markdown b/scala.html.markdown
index 544abd5b..61c735e3 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -198,8 +198,10 @@ weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most
-// def that surrounds it. It has no effect on anonymous functions. For example:
-def foo(x: Int) = {
+// def that surrounds it.
+// WARNING: Using return in Scala is error-prone and should be avoided.
+// It has no effect on anonymous functions. For example:
+def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
return z // This line makes z the return value of foo!
@@ -405,41 +407,55 @@ val otherGeorge = george.copy(phoneNumber = "9876")
// 6. Pattern Matching
/////////////////////////////////////////////////
-val me = Person("George", "1234")
+// Pattern matching is a powerful and commonly used feature in Scala. Here's how
+// you pattern match a case class. NB: Unlike other languages, Scala cases do
+// not need breaks, fall-through does not happen.
-me match { case Person(name, number) => {
- "We matched someone : " + name + ", phone : " + number }}
-
-me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
+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
+}
-me match { case Person("George", number) => "Match"; case _ => "Hm..." }
+val email = "(.*)@(.*)".r // Define a regex for the next example.
-me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
+// Pattern matching might look familiar to the switch statements in the C family
+// of languages, but this is much more powerful. In Scala, you can match much
+// more:
+def matchEverything(obj: Any): String = obj match {
+ // You can match values:
+ case "Hello world" => "Got the string Hello world"
-me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+ // You can match by type:
+ case x: Double => "Got a Double: " + x
-val kate = Person("Kate", "1234")
+ // You can specify conditions:
+ case x: Int if x > 10000 => "Got a pretty big number!"
-kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
+ // You can match case classes as before:
+ case Person(name, number) => s"Got contact info for $name!"
+ // You can match regular expressions:
+ case email(name, domain) => s"Got email address $name@$domain"
+ // You can match tuples:
+ case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
-// Regular expressions
-val email = "(.*)@(.*)".r // Invoking r on String makes it a Regex
-val serialKey = """(\d{5})-(\d{5})-(\d{5})-(\d{5})""".r // Using verbatim (multiline) syntax
+ // You can match data structures:
+ case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
-val matcher = (value: String) => {
- println(value match {
- case email(name, domain) => s"It was an email: $name"
- case serialKey(p1, p2, p3, p4) => s"Serial key: $p1, $p2, $p3, $p4"
- case _ => s"No match on '$value'" // default if no match found
- })
+ // You can nest patterns:
+ case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
}
-matcher("mrbean@pyahoo.com") // => "It was an email: mrbean"
-matcher("nope..") // => "No match on 'nope..'"
-matcher("52917") // => "No match on '52917'"
-matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917"
+// In fact, you can pattern match any object with an "unapply" method. This
+// feature is so powerful that Scala lets you define whole functions as
+// patterns:
+val patternFunc: Person => String = {
+ case Person("George", number") => s"George's number: $number"
+ case Person(name, number) => s"Random person's number: $number"
+}
/////////////////////////////////////////////////
diff --git a/tcl.html.markdown b/tcl.html.markdown
new file mode 100755
index 00000000..f2d92fcd
--- /dev/null
+++ b/tcl.html.markdown
@@ -0,0 +1,447 @@
+---
+language: Tcl
+contributors:
+ - ["Poor Yorick", "http://pooryorick.com/"]
+filename: learntcl.tcl
+---
+
+Tcl was created by [John Ousterhout](http://wiki.tcl.tk/John Ousterout) as a
+reusable scripting language for chip design tools he was creating. In 1997 he
+was awarded the [ACM Software System
+Award](http://en.wikipedia.org/wiki/ACM_Software_System_Award) for Tcl. Tcl
+can be used both as an embeddable scripting language and as a general
+programming language. It can also be used as a portable C library, even in
+cases where no scripting capability is needed, as it provides data structures
+such as dynamic strings, lists, and hash tables. The C library also provides
+portable functionality for loading dynamic libraries, string formatting and
+code conversion, filesystem operations, network operations, and more.
+Various features of Tcl stand out:
+
+* Convenient cross-platform networking API
+
+* Fully virtualized filesystem
+
+* Stackable I/O channels
+
+* Asynchronous to the core
+
+* Full coroutines
+
+* A threading model recognized as robust and easy to use
+
+
+If Lisp is a list processor, then Tcl is a string processor. All values are
+strings. A list is a string format. A procedure definition is a string
+format. To achieve performance, Tcl internally caches structured
+representations of these values. The list commands, for example, operate on
+the internal cached representation, and Tcl takes care of updating the string
+representation if it is ever actually needed in the script. The copy-on-write
+design of Tcl allows script authors can pass around large data values without
+actually incurring additional memory overhead. Procedures are automatically
+byte-compiled unless they use the more dynamic commands such as "uplevel",
+"upvar", and "trace".
+
+Tcl is a pleasure to program in. It will appeal to hacker types who find Lisp,
+Forth, or Smalltalk interesting, as well as to engineers and scientists who
+just want to get down to business with a tool that bends to their will. Its
+discipline of exposing all programmatic functionality as commands, including
+things like loops and mathematical operations that are usually baked into the
+syntax of other languages, allows it to fade into the background of whatever
+domain-specific functionality a project needs. It's syntax, which is even
+lighter that that of Lisp, just gets out of the way.
+
+
+
+
+
+```tcl
+#! /bin/env tclsh
+
+################################################################################
+## 1. Guidelines
+################################################################################
+
+# Tcl is not Bash or C! This needs to be said because standard shell quoting
+# habits almost work in Tcl and it is common for people to pick up Tcl and try
+# to get by with syntax they know from another language. It works at first,
+# but soon leads to frustration with more complex scripts.
+
+# Braces are just a quoting mechanism, not a code block constructor or a list
+# constructor. Tcl doesn't have either of those things. Braces are used,
+# though, to escape special characters in procedure bodies and in strings that
+# are formatted as lists.
+
+
+################################################################################
+## 2. Syntax
+################################################################################
+
+# Every line is a command. The first word is the name of the command, and
+# subsequent words are arguments to the command. Words are delimited by
+# whitespace. Since every word is a string, in the simple case no special
+# markup such as quotes, braces, or backslash, is necessary. Even when quotes
+# are used, they are not a string constructor, but just another escaping
+# character.
+
+set greeting1 Sal
+set greeting2 ut
+set greeting3 ations
+
+
+#semicolon also delimits commands
+set greeting1 Sal; set greeting2 ut; set greeting3 ations
+
+
+# Dollar sign introduces variable substitution
+set greeting $greeting1$greeting2$greeting3
+
+
+# Bracket introduces command substitution. The result of the command is
+# substituted in place of the bracketed script. When the "set" command is
+# given only the name of a variable, it returns the value of that variable.
+set greeting $greeting1$greeting2[set greeting3]
+
+
+# Command substitution should really be called script substitution, because an
+# entire script, not just a command, can be placed between the brackets. The
+# "incr" command increments the value of a variable and returns its value.
+set greeting $greeting[
+ incr i
+ incr i
+ incr i
+]
+
+
+# backslash suppresses the special meaning of characters
+set amount \$16.42
+
+
+# backslash adds special meaning to certain characters
+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
+set somevar {
+ This is a literal $ sign, and this \} escaped
+ brace remains uninterpreted
+}
+
+
+# In a word enclosed in double quotes, whitespace characters lose their special
+# meaning
+set name Neo
+set greeting "Hello, $name"
+
+
+#variable names can be any string
+set {first name} New
+
+
+# The brace form of variable substitution handles more complex variable names
+set greeting "Hello, ${first name}"
+
+
+# The "set" command can always be used instead of variable substitution
+set greeting "Hello, [set {first name}]"
+
+
+# To promote the words within a word to individual words of the current
+# command, use the expansion operator, "{*}".
+set {*}{name Neo}
+
+# is equivalent to
+set name Neo
+
+
+# An array is a special variable that is a container for other variables.
+set person(name) Neo
+set person(gender) male
+set greeting "Hello, $person(name)"
+
+
+# A namespace holds commands and variables
+namespace eval people {
+ namespace eval person1 {
+ set name Neo
+ }
+}
+
+
+#The full name of a variable includes its enclosing namespace(s), delimited by two colons:
+set greeting "Hello $people::person::name"
+
+
+
+################################################################################
+## 3. A Few Notes
+################################################################################
+
+# All other functionality is implemented via commands. From this point on,
+# there is no new syntax. Everything else there is to learn about Tcl is about
+# the behaviour of individual commands, and what meaning they assign to their
+# arguments.
+
+
+# To end up with an interpreter that can do nothing, delete the global
+# namespace. It's not very useful to do such a thing, but it illustrates the
+# nature of Tcl.
+namespace delete ::
+
+
+# Because of name resolution behaviour, its safer to use the "variable" command to declare or to assign a value to a namespace.
+namespace eval people {
+ namespace eval person1 {
+ variable name Neo
+ }
+}
+
+
+# The full name of a variable can always be used, if desired.
+set people::person1::name Neo
+
+
+
+################################################################################
+## 4. Commands
+################################################################################
+
+# Math can be done with the "expr" command.
+set a 3
+set b 4
+set c [expr {$a + $b}]
+
+# Since "expr" performs variable substitution on its own, brace the expression
+# to prevent Tcl from performing variable substitution first. See
+# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" for details.
+
+
+# The "expr" command understands variable and command substitution
+set c [expr {$a + [set b]}]
+
+
+# The "expr" command provides a set of mathematical functions
+set c [expr {pow($a,$b)}]
+
+
+# Mathematical operators are available as commands in the ::tcl::mathop
+# namespace
+::tcl::mathop::+ 5 3
+
+# Commands can be imported from other namespaces
+namespace import ::tcl::mathop::+
+set result [+ 5 3]
+
+
+# New commands can be created via the "proc" command.
+proc greet name {
+ return "Hello, $name!"
+}
+
+#multiple parameters can be specified
+proc greet {greeting name} {
+ return "$greeting, $name!"
+}
+
+
+# As noted earlier, braces do not construct a code block. Every value, even
+# the third argument of the "proc" command, is a string. The previous command
+# rewritten to not use braces at all:
+proc greet greeting\ name return\ \"Hello,\ \$name!
+
+
+
+# When the last parameter is the literal value, "args", it collects all extra
+# arguments when the command is invoked
+proc fold {cmd args} {
+ set res 0
+ foreach arg $args {
+ set res [cmd $res $arg]
+ }
+}
+fold ::tcl::mathop::* 5 3 3 ;# -> 45
+
+
+# Conditional execution is implemented as a command
+if {3 > 4} {
+ puts {This will never happen}
+} elseif {4 > 4} {
+ puts {This will also never happen}
+} else {
+ puts {This will always happen}
+}
+
+
+# Loops are implemented as commands. The first, second, and third
+# arguments of the "for" command are treated as mathematical expressions
+for {set i 0} {$i < 10} {incr i} {
+ set res [expr {$res + $i}]
+}
+
+
+# The first argument of the "while" command is also treated as a mathematical
+# expression
+set i 0
+while {$i < 10} {
+ incr i 2
+}
+
+
+# A list is a specially-formatted string. In the simple case, whitespace is sufficient to delimit values
+set amounts 10\ 33\ 18
+set amount [lindex $amounts 1]
+
+
+# Braces and backslash can be used to format more complex values in a list. A
+# list looks exactly like a script, except that the newline character and the
+# semicolon character lose their special meanings. This feature makes Tcl
+# homoiconic. There are three items in the following list.
+set values {
+
+ one\ two
+
+ {three four}
+
+ five\{six
+
+}
+
+
+# Since a list is a string, string operations could be performed on it, at the
+# risk of corrupting the formatting of the list.
+set values {one two three four}
+set values [string map {two \{} $values] ;# $values is no-longer a \
+ properly-formatted listwell-formed list
+
+
+# The sure-fire way to get a properly-formmated list is to use "list" commands
+set values [list one \{ three four]
+lappend values { } ;# add a single space as an item in the list
+
+
+# Use "eval" to evaluate a value as a script
+eval {
+ set name Neo
+ set greeting "Hello, $name"
+}
+
+
+# A list can always be passed to "eval" as a script composed of a single
+# command.
+eval {set name Neo}
+eval [list set greeting "Hello, $name"]
+
+
+# Therefore, when using "eval", use [list] to build up a desired command
+set command {set name}
+lappend command {Archibald Sorbisol}
+eval $command
+
+
+# A common mistake is not to use list functions when building up a command
+set command {set name}
+append command { Archibald Sorbisol}
+eval $command ;# There is an error here, because there are too many arguments \
+ to "set" in {set name Archibald Sorbisol}
+
+
+# This mistake can easily occur with the "subst" command.
+set replacement {Archibald Sorbisol}
+set command {set name $replacement}
+set command [subst $command]
+eval $command ;# The same error as before: to many arguments to "set" in \
+ {set name Archibald Sorbisol}
+
+
+# The proper way is to format the substituted value using use the "list"
+# command.
+set replacement [list {Archibald Sorbisol}]
+set command {set name $replacement}
+set command [subst $command]
+eval $command
+
+
+# It is extremely common to see the "list" command being used to properly
+# format values that are substituted into Tcl script templates. There are
+# several examples of this, below.
+
+
+# The "apply" command evaluates a string as a command.
+set cmd {{greeting name} {
+ return "$greeting, $name!"
+}}
+apply $cmd Whaddup Neo
+
+
+# The "uplevel" command evaluates a script in some enclosing scope.
+proc greet {} {
+ uplevel {puts "$greeting, $name"}
+}
+
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ uplevel [list variable $varname $value]
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+# The "upvar" command links a variable in the current scope to a variable in
+# some enclosing scope
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ upvar 1 $varname var
+ set var $value
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+#get rid of the built-in "while" command.
+rename ::while {}
+
+
+# Define a new while command with the "proc" command. More sophisticated error
+# handling is left as an exercise.
+proc while {condition script} {
+ if {[uplevel 1 [list expr $condition]]} {
+ uplevel 1 $script
+ tailcall [namespace which while] $condition $script
+ }
+}
+
+
+# The "coroutine" command creates a separate call stack, along with a command
+# to enter that call stack. The "yield" command suspends execution in that
+# stack.
+proc countdown {} {
+ #send something back to the initial "coroutine" command
+ yield
+
+ set count 3
+ while {$count > 1} {
+ yield [incr count -1]
+ }
+ return 0
+}
+coroutine countdown1 countdown
+coroutine countdown2 countdown
+puts [countdown 1] ;# -> 2
+puts [countdown 2] ;# -> 2
+puts [countdown 1] ;# -> 1
+puts [countdown 1] ;# -> 0
+puts [coundown 1] ;# -> invalid command name "countdown1"
+puts [countdown 2] ;# -> 1
+
+
+```
+
+## Reference
+
+[Official Tcl Documentation](http://www.tcl.tk/man/tcl/)
+
+[Tcl Wiki](http://wiki.tcl.tk)
+
+[Tcl Subreddit](http://www.reddit.com/r/Tcl)