Merge branch 'master' of github.com:geoffliu/learnxinyminutes-docs

This commit is contained in:
Geoff Liu 2015-01-18 13:07:39 -07:00
commit 31faf1a6a1
21 changed files with 2118 additions and 289 deletions

View File

@ -22,6 +22,11 @@ Send a pull request or open an issue any time of day or night.
**(e.g. [python/en] for English Python).** This will help everyone pick out things they
care about.
We're happy for any contribution in any form, but if you're making more than one major change
(i.e. translations for two different languages) it would be super cool of you to make a
separate pull request for each one so that someone can review them more effectively and/or
individually.
### Style Guidelines
* **Keep lines under 80 chars**

View File

@ -26,13 +26,15 @@ Multi-line comments look like this. They work in C89 as well.
Multi-line comments don't nest /* Be careful */ // comment ends on this line...
*/ // ...not this one!
// Constants: #define <keyword>
// Constants: #define <keyword>
#define DAYS_IN_YEAR 365
// Enumeration constants are also ways to declare constants.
enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// Enumeration constants are also ways to declare constants.
// All statements must end with a semicolon
enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// MON gets 2 automatically, TUE gets 3, etc.
// Import headers with #include
#include <stdlib.h>
#include <stdio.h>
@ -57,7 +59,6 @@ int main() {
// print output using printf, for "print formatted"
// %d is an integer, \n is a newline
printf("%d\n", 0); // => Prints 0
// All statements must end with a semicolon
///////////////////////////////////////
// Types
@ -385,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
@ -476,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;
}

View File

@ -678,6 +678,23 @@ on a new line! ""Wow!"", the masses cried";
private set;
}
// It's also possible to define custom Indexers on objects.
// All though this is not entirely useful in this example, you
// could do bicycle[0] which yields "chris" to get the first passenger or
// bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle)
private string[] passengers = { "chris", "phil", "darren", "regina" }
public string this[int i]
{
get {
return passengers[i];
}
set {
return passengers[i] = value;
}
}
//Method to display the attribute values of this Object.
public virtual string Info()
{

View File

@ -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 )

View File

@ -13,7 +13,7 @@ Brainfuck (sans majuscule à part au début dune phrase) est un langage
Turing-complet extrêmement simple avec seulement 8 commandes.
```
Tout caractère en dehors de "><+-.,[]" (en dehors des guillements) est ignoré.
Tout caractère en dehors de "><+-.,[]" (en dehors des guillemets) est ignoré.
Brainfuck est représenté par un tableau de 30 000 cellules initialisées à 0 et
un pointeur de données pointant sur la cellule courante.

View File

@ -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

View File

@ -83,7 +83,7 @@ True ; => True
(greet "bilbo") ;=> "hello bilbo"
; functions can take optional arguments as well as keyword arguments
(defn foolist [arg1 &optional [arg2 2]]
(defn foolists [arg1 &optional [arg2 2]]
[arg1 arg2])
(foolists 3) ;=> [3 2]

View File

@ -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() {
}

View File

@ -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

View File

@ -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,6 +103,63 @@ sub say-hello-to(Str $name) { # You can provide the type of an argument
say "Hello, $name !";
}
## 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,
or I'll return my argument";
$arg;
}
with-optional; # returns Any
with-optional(); # returns Any
with-optional(1); # returns 1
## You can also give them a default value when they're not passed:
sub hello-to($name = "World") {
say "Hello, $name !";
}
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 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,
# which means this fails:
with-named(1, 'named' => 6);
with-named(2, :named(5)); #=> 7
# To make a named argument mandatory, you can use `?`'s inverse, `!`
sub with-mandatory-named(:$str!) {
say "$str !";
}
with-mandatory-named(str => "My String"); #=> My String !
with-mandatory-named; # run time error: "Required named parameter not passed"
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
## If a sub takes a named boolean argument ...
sub takes-a-bool($name, :$bool) {
say "$name takes $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
## You can also provide your named arguments with defaults:
sub named-def(:$def = 5) {
say $def;
}
named-def; #=> 5
named-def(:10def); #=> 10
named-def(def => 15); #=> 15
# 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;
@ -136,74 +184,6 @@ sub concat3($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,
or I'll return my argument";
$arg;
}
with-optional; # returns Any
with-optional(); # returns Any
with-optional(1); # returns 1
## You can also give them a default value when they're not passed:
sub hello-to($name = "World") {
say "Hello, $name !";
}
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 !),
## pass *named* arguments to a `sub`.
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.
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!) {
say "$str !";
}
with-mandatory-named(str => "My String"); #=> My String !
with-mandatory-named; # run time error: "Required named parameter not passed"
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
## If a sub takes a named boolean argument ...
sub takes-a-bool($name, :$bool) {
say "$name takes $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) {
say $def;
}
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?
### Containers
# In Perl 6, values are actually stored in "containers".
# The assignment operator asks the container on the left to store the value on
@ -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.

View File

@ -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!

View File

@ -0,0 +1,384 @@
---
language: clojure
filename: learnclojure-pt.clj
contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
lang: pt-br
---
Clojure é uma linguagem da família do Lisp desenvolvida para a JVM (máquina virtual Java). Possui uma ênfase muito mais forte em [programação funcional] (https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional) pura do que Common Lisp, mas inclui diversas utilidades [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) para lidar com estado a medida que isso se torna necessário.
Essa combinação permite gerenciar processamento concorrente de maneira muito simples, e frequentemente de maneira automática.
(Sua versão de clojure precisa ser pelo menos 1.2)
```clojure
; Comentários começam por ponto e vírgula
; Clojure é escrito em "forms", os quais são simplesmente
; listas de coisas dentro de parênteses, separados por espaços em branco.
; O "reader" (leitor) de Clojure presume que o primeiro elemento de
; uma par de parênteses é uma função ou macro, e que os resto são argumentos.
: A primeira chamada de um arquivo deve ser ns, para configurar o namespace (espaço de nomes)
(ns learnclojure)
; Alguns exemplos básicos:
; str cria uma string concatenando seus argumentos
(str "Hello" " " "World") ; => "Hello World"
; Cálculos são feitos de forma direta e intuitiva
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
; Você pode comparar igualdade utilizando =
(= 1 1) ; => true
(= 2 1) ; => false
; Negação para operações lógicas
(not true) ; => false
; Aninhar "forms" funciona como esperado
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
; Tipos
;;;;;;;;;;;;;
; Clojure usa os tipos de objetos de Java para booleanos, strings e números.
; Use `class` para inspecioná-los
(class 1) ; Literais Integer são java.lang.Long por padrão
(class 1.); Literais Float são java.lang.Double
(class ""); Strings são sempre com aspas duplas, e são java.lang.String
(class false) ; Booleanos são java.lang.Boolean
(class nil); O valor "null" é chamado nil
; Se você quiser criar um lista de literais, use aspa simples para
; ela não ser avaliada
'(+ 1 2) ; => (+ 1 2)
; (que é uma abreviação de (quote (+ 1 2)))
; É possível avaliar uma lista com aspa simples
(eval '(+ 1 2)) ; => 3
; Coleções e sequências
;;;;;;;;;;;;;;;;;;;
; Listas são estruturas encadeadas, enquanto vetores são implementados como arrays.
; Listas e Vetores são classes Java também!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList
; Uma lista é escrita como (1 2 3), mas temos que colocar a aspa
; simples para impedir o leitor (reader) de pensar que é uma função.
; Também, (list 1 2 3) é o mesmo que '(1 2 3)
; "Coleções" são apenas grupos de dados
; Listas e vetores são ambos coleções:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
; "Sequências" (seqs) são descrições abstratas de listas de dados.
; Apenas listas são seqs.
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
; Um seq precisa apenas prover uma entrada quando é acessada.
; Portanto, já que seqs podem ser avaliadas sob demanda (lazy) -- elas podem definir séries infinitas:
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (uma série infinita)
(take 4 (range)) ; (0 1 2 3)
; Use cons para adicionar um item no início de uma lista ou vetor
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
; Conj adiciona um item em uma coleção sempre do jeito mais eficiente.
; Para listas, elas inserem no início. Para vetores, é inserido no final.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
; Use concat para concatenar listas e vetores
(concat [1 2] '(3 4)) ; => (1 2 3 4)
; Use filter, map para interagir com coleções
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2)
; Use reduce para reduzi-los
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10
; Reduce pode receber um argumento para o valor inicial
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1]
; Funções
;;;;;;;;;;;;;;;;;;;;;
; Use fn para criar novas funções. Uma função sempre retorna
; sua última expressão.
(fn [] "Hello World") ; => fn
; (É necessário colocar parênteses para chamá-los)
((fn [] "Hello World")) ; => "Hello World"
; Você pode atribuir valores a variáveis utilizando def
(def x 1)
x ; => 1
; Atribua uma função para uma var
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World"
; Você pode abreviar esse processo usando defn
(defn hello-world [] "Hello World")
; O [] é uma lista de argumentos para um função.
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve"
; Você pode ainda usar essa abreviação para criar funcões:
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny"
; Vocé pode ter funções multi-variadic, isto é, com um número variável de argumentos
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World"
; Funções podem agrupar argumentos extras em uma seq
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
; Você pode misturar argumentos regulares e argumentos em seq
(defn hello-count [name & args]
(str "Hello " name ", you passed " (count args) " extra args"))
(hello-count "Finn" 1 2 3)
; => "Hello Finn, you passed 3 extra args"
; Mapas
;;;;;;;;;;
; Hash maps e array maps compartilham uma mesma interface. Hash maps são mais
; rápidos para pesquisa mas não mantém a ordem da chave.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
; Arraymaps pode automaticamente se tornar hashmaps através da maioria das
; operações se eles ficarem grandes o suficiente, portanto não há necessida de
; se preocupar com isso.
;Mapas podem usar qualquer valor que se pode derivar um hash como chave
; Mapas podem usar qualquer valor em que se pode derivar um hash como chave,
; mas normalmente palavras-chave (keywords) são melhores.
; Keywords são como strings mas com algumas vantagens.
(class :a) ; => clojure.lang.Keyword
(def stringmap {"a" 1, "b" 2, "c" 3})
stringmap ; => {"a" 1, "b" 2, "c" 3}
(def keymap {:a 1, :b 2, :c 3})
keymap ; => {:a 1, :c 3, :b 2}
; A propósito, vírgulas são sempre tratadas como espaçoes em branco e não fazem nada.
; Recupere o valor de um mapa chamando ele como uma função
(stringmap "a") ; => 1
(keymap :a) ; => 1
; Uma palavra-chave pode ser usada pra recuperar os valores de um mapa
(:b keymap) ; => 2
; Não tente isso com strings
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
; Buscar uma chave não presente retorna nil
(stringmap "d") ; => nil
; Use assoc para adicionar novas chaves para hash-maps
(def newkeymap (assoc keymap :d 4))
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
; Mas lembre-se, tipos em Clojure são sempre imutáveis!
keymap ; => {:a 1, :b 2, :c 3}
; Use dissoc para remover chaves
(dissoc keymap :a :b) ; => {:c 3}
; Conjuntos
;;;;;;
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
; Adicione um membro com conj
(conj #{1 2 3} 4) ; => #{1 2 3 4}
; Remova um membro com disj
(disj #{1 2 3} 1) ; => #{2 3}
; Test por existência usando set como função:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil
; Existem muitas outras funções no namespace clojure.sets
; Forms úteis
;;;;;;;;;;;;;;;;;
; Construções lógicas em Clojure são como macros, e
; se parecem com as demais
(if false "a" "b") ; => "b"
(if false "a") ; => nil
; Use let para criar um novo escopo associando sîmbolos a valores (bindings)
(let [a 1 b 2]
(> a b)) ; => false
; Agrupe comandos juntos com "do"
(do
(print "Hello")
"World") ; => "World" (prints "Hello")
; Funções tem um do implícito
(defn print-and-say-hello [name]
(print "Saying hello to " name)
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
; Assim como let
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
; Módulos
;;;;;;;;;;;;;;;
; Use "use" para poder usar todas as funções de um modulo
(use 'clojure.set)
; Agora nós podemos usar operações com conjuntos
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1}
; Você pode escolher um subconjunto de funções para importar
(use '[clojure.set :only [intersection]])
; Use require para importar um módulo
(require 'clojure.string)
; Use / para chamar funções de um módulo
; Aqui, o módulo é clojure.string e a função é blank?
(clojure.string/blank? "") ; => true
; Você pode dar para um módulo um nome mais curto no import
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
; (#"" denota uma expressão regular literal)
; Você pode usar require (e até "use", mas escolha require) de um namespace utilizando :require.
; Não é necessário usar aspa simples nos seus módulos se você usar desse jeito.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))
; Java
;;;;;;;;;;;;;;;;;
; Java tem uma biblioteca padrão enorme e muito útil,
; portanto é importante aprender como utiliza-la.
; Use import para carregar um modulo java
(import java.util.Date)
; Você pode importar usando ns também.
(ns test
(:import java.util.Date
java.util.Calendar))
; Use o nome da clase com um "." no final para criar uma nova instância
(Date.) ; <a date object>
; Use . para chamar métodos. Ou, use o atalho ".method"
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; exatamente a mesma coisa.
; Use / para chamar métodos estáticos
(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente)
; Use doto para pode lidar com classe (mutáveis) de forma mais tolerável
(import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
.getTime) ; => A Date. set to 2000-01-01 00:00:00
; STM
;;;;;;;;;;;;;;;;;
; Software Transactional Memory é o mecanismo que Clojure usa para gerenciar
; estado persistente. Tem algumas construções em Clojure que o utilizam.
; O atom é o mais simples. Passe pra ele um valor inicial
(def my-atom (atom {}))
; Atualize o atom com um swap!.
; swap! pega uma funçnao and chama ela com o valor atual do atom
; como primeiro argumento, e qualquer argumento restante como o segundo
(swap! my-atom assoc :a 1) ; Coloca o valor do átomo my-atom como o resultado de (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Coloca o valor do átomo my-atom como o resultado de (assoc {:a 1} :b 2)
; Use '@' para desreferenciar um atom e acessar seu valor
my-atom ;=> Atom<#...> (Retorna o objeto do Atom)
@my-atom ; => {:a 1 :b 2}
; Abaixo um contador simples usando um atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
@counter ; => 5
; Outras construção STM são refs e agents.
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents
```
### Leitura adicional
Esse tutorial está longe de ser exaustivo, mas deve ser suficiente para que você possa começar.
Clojure.org tem vários artigos:
[http://clojure.org/](http://clojure.org/)
Clojuredocs.org tem documentação com exemplos para quase todas as funções principais (pertecentes ao core):
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
4Clojure é um grande jeito de aperfeiçoar suas habilidades em Clojure/Programação Funcional:
[http://www.4clojure.com/](http://www.4clojure.com/)
Clojure-doc.org tem um bom número de artigos para iniciantes:
[http://clojure-doc.org/](http://clojure-doc.org/)

View File

@ -0,0 +1,500 @@
---
language: swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"],
- ["Christopher Bess", "http://github.com/cbess"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
lang: pt-br
filename: learnswift.swift
---
Swift é uma linguagem de programação para desenvolvimento de aplicações no iOS e OS X criada pela Apple. Criada para
coexistir com Objective-C e para ser mais resiliente a código com erros, Swift foi apresentada em 2014 na Apple's
developer conference WWDC. Foi construída com o compilador LLVM já incluído no Xcode 6 beta.
O livro oficial [Swift Programming Language] (https://itunes.apple.com/us/book/swift-programming-language/id881256329) da
Apple já está disponível via IBooks (apenas em inglês).
Confira também o tutorial completo de Swift da Apple [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/LandingPage/index.html), também disponível apenas em inglês.
```swift
// importa um módulo
import UIKit
//
// MARK: Noções básicas
//
// Xcode supporta anotações para seu código e lista elas na barra de atalhos
// MARK: Marca uma sessão
// TODO: Faça algo logo
// FIXME: Conserte esse código
println("Hello, world")
// Valores em variáveis (var) podem ter seu valor alterado depois de declarados.
// Valores em constantes (let) NÃO podem ser alterados depois de declarados.
var myVariable = 42
let øπΩ = "value" // nomes de variáveis em unicode
let π = 3.1415926
let convenience = "keyword" // nome de variável contextual
let weak = "keyword"; let override = "another keyword" // comandos podem ser separados por uma ponto e vírgula
let `class` = "keyword" // Crases permitem que palavras-chave seja usadas como nome de variáveis
let explicitDouble: Double = 70
let intValue = 0007 // 7
let largeIntValue = 77_000 // 77000
let label = "some text " + String(myVariable) // Coerção
let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolação de strings
// Constrói valores específicos
// Utiliza configuração de build -D
#if false
println("Not printed")
let buildValue = 3
#else
let buildValue = 7
#endif
println("Build value: \(buildValue)") // Build value: 7
/*
Optionals fazem parte da linguagem e permitem que você armazene um
valor `Some` (algo) ou `None` (nada).
Como Swift requer que todas as propriedades tenham valores, até mesmo nil deve
ser explicitamente armazenado como um valor Optional.
Optional<T> é uma enum.
*/
var someOptionalString: String? = "optional" // Pode ser nil
// o mesmo acima, mas ? é um operador pós-fixado (açúcar sintático)
var someOptionalString2: Optional<String> = "optional"
if someOptionalString != nil {
// Eu não sou nil
if someOptionalString!.hasPrefix("opt") {
println("has the prefix")
}
let empty = someOptionalString?.isEmpty
}
someOptionalString = nil
// Optional implicitamente desempacotado (unwrapped)
var unwrappedString: String! = "Valor é esperado."
// o mesmo acima, mas ? é um operador pósfixado (açúcar sintático)
var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Valor é esperado."
if let someOptionalStringConstant = someOptionalString {
// Tem `Some` (algum) valor, não nil
if !someOptionalStringConstant.hasPrefix("ok") {
// não possui o prefixo
}
}
// Swift tem suporte para armazenar um valor de qualquer tipo.
// AnyObject == id
// Ao contrário de Objective-C `id`, AnyObject funciona com qualquer valor (Class, Int, struct, etc)
var anyObjectVar: AnyObject = 7
anyObjectVar = "Mudou o valor para string, não é uma boa prática, mas é possível."
/*
Comentário aqui
/*
Comentários aninhados também são suportados
*/
*/
//
// MARK: Coleções
//
/*
Tipos Array e Dicionário são structs. Portanto `let` e `var`
também indicam se são mutáveis (var) ou imutáveis (let) quando declarados
com esses tipos.
*/
// Array
var shoppingList = ["catfish", "water", "lemons"]
shoppingList[1] = "bottle of water"
let emptyArray = [String]() // imutável
var emptyMutableArray = [String]() // mutável
// Dicionário
var occupations = [
"Malcolm": "Captain",
"kaylee": "Mechanic"
]
occupations["Jayne"] = "Public Relations"
let emptyDictionary = [String: Float]() // imutável
var emptyMutableDictionary = [String: Float]() // mutável
//
// MARK: Controle de fluxo
//
// laço for (array)
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
if value == 1 {
println("One!")
} else {
println("Not one!")
}
}
// laço for (dicionário)
var dict = ["one": 1, "two": 2]
for (key, value) in dict {
println("\(key): \(value)")
}
// laço for (alcance)
for i in -1...shoppingList.count {
println(i)
}
shoppingList[1...2] = ["steak", "peacons"]
// use ..< para excluir o último número
// laço while (enquanto)
var i = 1
while i < 1000 {
i *= 2
}
// laço do-while
do {
println("hello")
} while 1 == 2
// Switch
let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
default: // required (in order to cover all possible input)
let vegetableComment = "Everything tastes good in soup."
}
//
// MARK: Funções
//
// Funções são tipos de primeira classe, o que significa que eles podem ser aninhados
// em funções e podem ser passados como parâmetros
// Funções Swift com cabeçalhos doc (formato como reStructedText)
/**
Uma operação de saudação
- Um bullet em documentos
- Outro bullet
:param: nome A nome
:param: dia A dia
:returns: Uma string contendo o nome e o dia.
*/
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
// Função que retorna múltiplos items em uma tupla
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
let pricesTuple = getGasPrices()
let price = pricesTuple.2 // 3.79
// Ignore valores de Tuplas (ou outros valores) usando _ (underscore)
let (_, price1, _) = pricesTuple // price1 == 3.69
println(price1 == pricesTuple.1) // true
println("Gas price: \(price)")
// Número variável de argumentos
func setup(numbers: Int...) {
// its an array
let number = numbers[0]
let argCount = numbers.count
}
// Passando e retornando funções
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
// passagem por referência
func swapTwoInts(inout a: Int, inout b: Int) {
let tempA = a
a = b
b = tempA
}
var someIntA = 7
var someIntB = 3
swapTwoInts(&someIntA, &someIntB)
println(someIntB) // 7
//
// MARK: Closures
//
var numbers = [1, 2, 6]
// Funções são casos especiais de closures ({})
// Exemplo de closure.
// `->` separa argumentos e tipo de retorno
// `in` separa o cabeçalho do closure do seu corpo
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
// Quando o tipo é conhecido, como abaixo, nós podemos fazer o seguinte
numbers = numbers.map({ number in 3 * number })
// Ou até mesmo isso
//numbers = numbers.map({ $0 * 3 })
print(numbers) // [3, 6, 18]
// Closure restante
numbers = sorted(numbers) { $0 > $1 }
print(numbers) // [18, 6, 3]
// Super atalho, já que o operador < infere os tipos
numbers = sorted(numbers, < )
print(numbers) // [3, 6, 18]
//
// MARK: Estruturas
//
// Estruturas e classes tem funcionalidades muito similares
struct NamesTable {
let names: [String]
// Custom subscript
subscript(index: Int) -> String {
return names[index]
}
}
// Estruturas possuem um inicializador auto-gerado automático (implícito)
let namesTable = NamesTable(names: ["Me", "Them"])
//let name = namesTable[2]
//println("Name is \(name)") // Name is Them
//
// MARK: Classes
//
// Classes, Estruturas e seus membros possuem três níveis de modificadores de acesso
// Eles são: internal (default), public, private
public class Shape {
public func getArea() -> Int {
return 0;
}
}
// Todos os métodos e propriedades de uma classe são públicos.
// Se você só precisa armazenar dados em um objeto estruturado, use `struct`
internal class Rect: Shape {
var sideLength: Int = 1
// Getter e setter personalizado
private var perimeter: Int {
get {
return 4 * sideLength
}
set {
// `newValue` é uma variável implicita disponível para os setters
sideLength = newValue / 4
}
}
// Carregue uma propriedade sob demanda (lazy)
// subShape permanece nil (não inicializado) até seu getter ser chamado
lazy var subShape = Rect(sideLength: 4)
// Se você não precisa de um getter e setter personalizado,
// mas ainda quer roda código antes e depois de configurar
// uma propriedade, você pode usar `willSet` e `didSet`
var identifier: String = "defaultID" {
// o argumento `willSet` será o nome da variável para o novo valor
willSet(someIdentifier) {
print(someIdentifier)
}
}
init(sideLength: Int) {
self.sideLength = sideLength
// sempre chame super.init por último quand inicializar propriedades personalizadas (custom)
super.init()
}
func shrink() {
if sideLength > 0 {
--sideLength
}
}
override func getArea() -> Int {
return sideLength * sideLength
}
}
// Uma classe básica `Square` que estende `Rect`
class Square: Rect {
convenience init() {
self.init(sideLength: 5)
}
}
var mySquare = Square()
print(mySquare.getArea()) // 25
mySquare.shrink()
print(mySquare.sideLength) // 4
// Compara instâncias, não é o mesmo que == o qual compara objetos
if mySquare === mySquare {
println("Yep, it's mySquare")
}
//
// MARK: Enums
//
// Enums podem opcionalmente ser de um tipo específico ou não.
// Podem conter métodos do mesmo jeito que classes.
enum Suit {
case Spades, Hearts, Diamonds, Clubs
func getIcon() -> String {
switch self {
case .Spades: return "♤"
case .Hearts: return "♡"
case .Diamonds: return "♢"
case .Clubs: return "♧"
}
}
}
//
// MARK: Protocolos
//
// `protocol` pode requerer que os tipos que se adequam tenham
// propriedades de instância, métodos, operadores e subscripts.
protocol ShapeGenerator {
var enabled: Bool { get set }
func buildShape() -> Shape
}
// Protocolos declarados com @objc permitem funções opcionais,
// que permitem verificar a confomidade
@objc protocol TransformShape {
optional func reshaped()
optional func canReshape() -> Bool
}
class MyShape: Rect {
var delegate: TransformShape?
func grow() {
sideLength += 2
if let allow = self.delegate?.canReshape?() {
// test for delegate then for method
// testa por delegação e então por método
self.delegate?.reshaped?()
}
}
}
//
// MARK: Outros
//
// `extension`s: Adicionam uma funcionalidade extra para um tipo já existente.
// Square agora "segue" o protocolo `Printable`
extension Square: Printable {
var description: String {
return "Area: \(self.getArea()) - ID: \(self.identifier)"
}
}
println("Square: \(mySquare)")
// Você pode também estender tipos embutidos (built-in)
extension Int {
var customProperty: String {
return "This is \(self)"
}
func multiplyBy(num: Int) -> Int {
return num * self
}
}
println(7.customProperty) // "This is 7"
println(14.multiplyBy(2)) // 42
// Generics: Similar com Java e C#. Use a palavra-chave `where` para
// especificar os requisitos do generics.
func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
for (index, value) in enumerate(array) {
if value == valueToFind {
return index
}
}
return nil
}
let foundAtIndex = findIndex([1, 2, 3, 4], 3)
println(foundAtIndex == 2) // true
// Operadores:
// Operadores personalizados (custom) podem começar com os seguintes caracteres:
// / = - + * % < > ! & | ^ . ~
// ou
// Unicode math, símbolo, seta, e caracteres tipográficos ou de desenho.
prefix operator !!! {}
// Um operador de prefixo que triplica o comprimento do lado do quadrado
// quando usado
prefix func !!! (inout shape: Square) -> Square {
shape.sideLength *= 3
return shape
}
// valor atual
println(mySquare.sideLength) // 4
// Troca o comprimento do lado usando um operador personalizado !!!, aumenta o lado por 3
!!!mySquare
println(mySquare.sideLength) // 12
```

View File

@ -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

View File

@ -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

View File

@ -65,7 +65,7 @@ func beyondHello() {
learnTypes() // < y minutes, learn more!
}
// Функция имеющая входные параметры и возврат нескольких значений.
// Функция, имеющая входные параметры и возвращающая несколько значений.
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Возврат двух значений.
}

425
ru-ru/lua-ru.html.markdown Normal file
View File

@ -0,0 +1,425 @@
---
language: lua
filename: learnlua-ru.lua
contributors:
- ["Tyler Neylon", "http://tylerneylon.com/"]
translators:
- ["Max Solomonov", "https://vk.com/solomonovmaksim"]
- ["Max Truhonin", "https://vk.com/maximmax42"]
- ["Konstantin Gromyko", "https://vk.com/id0x1765d79"]
- ["Stanislav Gromov", "https://vk.com/id156354391"]
lang: ru-ru
---
```lua
-- Два дефиса начинают однострочный комментарий.
--[[
Добавление двух квадратных скобок
делает комментарий многострочным.
--]]
--------------------------------------------------------------------------------
-- 1. Переменные, циклы и условия.
--------------------------------------------------------------------------------
num = 42 -- Все числа имеют тип double.
-- Не волнуйтесь, в 64-битных double 52 бита
-- отведено под хранение целой части числа;
-- точность не является проблемой для
-- целочисленных значений, занимающих меньше 52 бит.
s = 'walternate' -- Неизменные строки, как в Python.
t = "Двойные кавычки также приветствуются"
u = [[ Двойные квадратные скобки
начинают и заканчивают
многострочные значения.]]
t = nil -- Удаляет определение переменной t; в Lua есть сборка мусора.
-- Блоки обозначаются ключевыми словами, такими как do/end:
while num < 50 do
num = num + 1 -- Операторов ++ и += нет.
end
-- Ветвление "если":
if num > 40 then
print('больше 40')
elseif s ~= 'walternate' then -- ~= обозначает "не равно".
-- Проверка равенства это ==, как в Python; работает для строк.
io.write('не больше 40\n') -- По умолчанию вывод в stdout.
else
-- По умолчанию переменные являются глобальными.
thisIsGlobal = 5 -- Стиль CamelСase является общим.
-- Как сделать переменную локальной:
local line = io.read() -- Считывает введённую строку.
-- Для конкатенации строк используется оператор .. :
print('Зима пришла, ' .. line)
end
-- Неопределённые переменные возвращают nil.
-- Этот пример не является ошибочным:
foo = anUnknownVariable -- Теперь foo = nil.
aBoolValue = false
-- Только значения nil и false являются ложными; 0 и '' являются истинными!
if not aBoolValue then print('это значение ложно') end
-- Для 'or' и 'and' действует принцип "какой оператор дальше,
-- тот и применяется". Это действует аналогично оператору a?b:c в C/js:
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
for i = 1, 100 do -- Здесь указан диапазон, ограниченный с двух сторон.
karlSum = karlSum + i
end
-- Используйте "100, 1, -1" как нисходящий диапазон:
fredSum = 0
for j = 100, 1, -1 do fredSum = fredSum + j end
-- В основном, диапазон устроен так: начало, конец[, шаг].
-- Другая конструкция цикла:
repeat
print('путь будущего')
num = num - 1
until num == 0
--------------------------------------------------------------------------------
-- 2. Функции.
--------------------------------------------------------------------------------
function fib(n)
if n < 2 then return n end
return fib(n - 2) + fib(n - 1)
end
-- Вложенные и анонимные функции являются нормой:
function adder(x)
-- Возращаемая функция создаётся, когда вызывается функция adder,
-- и запоминает значение переменной x:
return function (y) return x + y end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
-- Возвраты, вызовы функций и присвоения работают со списками,
-- которые могут иметь разную длину.
-- Лишние получатели принимают значение nil, а лишние значения игнорируются.
x, y, z = 1, 2, 3, 4
-- Теперь x = 1, y = 2, z = 3, а 4 просто отбрасывается.
function bar(a, b, c)
print(a, b, c)
return 4, 8, 15, 16, 23, 42
end
x, y = bar('zaphod') --> выводит "zaphod nil nil"
-- Теперь x = 4, y = 8, а значения 15..42 отбрасываются.
-- Функции могут быть локальными и глобальными. Эти строки делают одно и то же:
function f(x) return x * x end
f = function (x) return x * x end
-- Эти тоже:
local function g(x) return math.sin(x) end
local g = function(x) return math.sin(x) end
-- Эквивалентно для local function g(x)..., однако ссылки на g
-- в теле функции не будут работать, как ожидалось.
local g; g = function (x) return math.sin(x) end
-- 'local g' будет прототипом функции.
-- Кстати, тригонометрические функции работают с радианами.
-- Вызов функции с одним строковым параметром не требует круглых скобок:
print 'hello' -- Работает без ошибок.
-- Вызов функции с одним табличным параметром также
-- не требует круглых скобок (про таблицы в след. части):
print {} -- Тоже сработает.
--------------------------------------------------------------------------------
-- 3. Таблицы.
--------------------------------------------------------------------------------
-- Таблица = единственная составная структура данных в Lua;
-- представляет собой ассоциативный массив.
-- Подобно массивам в PHP или объектам в JS, они представляют собой
-- хеш-таблицы, которые также можно использовать в качестве списков.
-- Использование словарей:
-- Литералы имеют ключ по умолчанию:
t = {key1 = 'value1', key2 = false}
-- Строковые ключи используются, как в точечной нотации в JS:
print(t.key1) -- Печатает 'value1'.
t.newKey = {} -- Добавляет новую пару ключ/значение.
t.key2 = nil -- Удаляет key2 из таблицы.
-- Литеральная нотация для любого значения ключа (кроме nil):
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- пишет "tau"
-- Ключ соответствует значению для чисел и строк, но при
-- использовании таблицы в качестве ключа берётся её экземпляр.
a = u['@!#'] -- Теперь a = 'qbert'.
b = u[{}] -- Вы могли ожидать 1729, но получится nil:
-- b = nil, т.к. ключ не будет найден.
-- Это произойдёт потому, что за ключ мы использовали не тот же самый объект,
-- который был использован для сохранения оригинального значения.
-- Поэтому строки и числа удобнее использовать в качестве ключей.
-- Вызов функции с одной таблицей в качестве аргумента
-- не требует круглых скобок:
function h(x) print(x.key1) end
h{key1 = 'Sonmi~451'} -- Печатает 'Sonmi~451'.
for key, val in pairs(u) do -- Цикл по таблице.
print(key, val)
end
-- _G - это таблица со всеми глобалями.
print(_G['_G'] == _G) -- Печатает 'true'.
-- Использование таблиц, как списков / массивов:
-- Список значений с неявно заданными целочисленными ключами:
v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v - размер списка v.
print(v[i]) -- Нумерация начинается с 1 !!
end
-- Список не является отдельным типом. v - всего лишь таблица
-- с последовательными целочисленными ключами, воспринимаемая как список.
--------------------------------------------------------------------------------
-- 3.1 Метатаблицы и метаметоды.
--------------------------------------------------------------------------------
-- Таблицу можно связать с метатаблицей, задав ей поведение, как при
-- перегрузке операторов. Позже мы увидим, что метатаблицы поддерживают
-- поведение, как в js-прототипах.
f1 = {a = 1, b = 2} -- Представляет дробь a/b.
f2 = {a = 2, b = 3}
-- Это не сработает:
-- s = f1 + f2
metafraction = {}
function metafraction.__add(f1, f2)
local sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
end
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
s = f1 + f2 -- вызвать __add(f1, f2) на метатаблице от f1
-- f1, f2 не имеют ключа для своих метатаблиц в отличии от прототипов в js,
-- нужно получить его через getmetatable(f1). Метатаблица - обычная таблица
-- поэтому с ключами, известными для Lua (например, __add).
-- Но следущая строка будет ошибочной т.к в s нет метатаблицы:
-- t = s + s
-- Похожий на классы подход, приведенный ниже, поможет это исправить.
-- __index перегружает в метатаблице просмотр через точку:
defaultFavs = {animal = 'gru', food = 'donuts'}
myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- работает! спасибо, мета-таблица.
--------------------------------------------------------------------------------
-- При неудаче прямой табличный поиск попытается использовать
-- значение __index в метатаблице, причём это рекурсивно.
-- Значение __index также может быть функцией
-- function(tbl, key) для настраиваемого поиска.
-- Значения типа __index, __add, ... называются метаметодами.
-- Ниже приведён полный список метаметодов.
-- __add(a, b) для a + b
-- __sub(a, b) для a - b
-- __mul(a, b) для a * b
-- __div(a, b) для a / b
-- __mod(a, b) для a % b
-- __pow(a, b) для a ^ b
-- __unm(a) для -a
-- __concat(a, b) для a .. b
-- __len(a) для #a
-- __eq(a, b) для a == b
-- __lt(a, b) для a < b
-- __le(a, b) для a <= b
-- __index(a, b) <функция или таблица> для a.b
-- __newindex(a, b, c) для a.b = c
-- __call(a, ...) для a(...)
--------------------------------------------------------------------------------
-- 3.2 Классоподобные таблицы и наследование.
--------------------------------------------------------------------------------
-- В Lua нет поддержки классов на уровне языка,
-- однако существуют разные способы их создания с помощью
-- таблиц и метатаблиц.
-- Ниже приведён один из таких способов.
Dog = {} -- 1.
function Dog:new() -- 2.
local newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
function Dog:makeSound() -- 6.
print('I say ' .. self.sound)
end
mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
-- 1. Dog похоже на класс, но на самом деле это таблица.
-- 2. "function tablename:fn(...)" - то же самое, что и
-- "function tablename.fn(self, ...)", просто : добавляет первый аргумент
-- перед собой. См. пункты 7 и 8, чтобы понять, как self получает значение.
-- 3. newObj - это экземпляр класса Dog.
-- 4. "self" - экземпляр класса. Зачастую self = Dog, но с помощью наследования
-- это можно изменить. newObj получит свои функции, когда мы установим
-- метатаблицу для newObj и __index для self на саму себя.
-- 5. Напоминание: setmetatable возвращает первый аргумент.
-- 6. : работает, как в пункте 2, но в этот раз мы ожидаем,
-- что self будет экземпляром, а не классом.
-- 7. То же самое, что и Dog.new(Dog), поэтому self = Dog в new().
-- 8. То же самое, что mrDog.makeSound(mrDog); self = mrDog.
--------------------------------------------------------------------------------
-- Пример наследования:
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
local s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
seymour = LoudDog:new() -- 3.
seymour:makeSound() -- 'woof woof woof' -- 4.
--------------------------------------------------------------------------------
-- 1. LoudDog получит методы и переменные класса Dog.
-- 2. В self будет ключ 'sound' из new(), см. пункт 3.
-- 3. То же самое, что и "LoudDog.new(LoudDog)", конвертированное
-- в "Dog.new(LoudDog)", поскольку в LoudDog нет ключа 'new',
-- но в его метатаблице есть "__index = Dog".
-- Результат: Метатаблицей для seymour стала LoudDog,
-- а "LoudDog.__index = Dog". Поэтому seymour.key будет равно
-- seymour.key, LoudDog.key, Dog.key, в зависимости от того,
-- какая таблица будет первой с заданным ключом.
-- 4. Ключ 'makeSound' находится в LoudDog;
-- то же самое, что и "LoudDog.makeSound(seymour)".
-- При необходимости функция new() в подклассе
-- может быть похожа на аналог в базовом классе.
function LoudDog:new()
local newObj = {}
-- установить newObj
self.__index = self
return setmetatable(newObj, self)
end
--------------------------------------------------------------------------------
-- 4. Модули.
--------------------------------------------------------------------------------
--[[ Я закомментировал этот раздел, чтобы остальная часть скрипта осталась
-- работоспособной.
```
```lua
-- Предположим, файл mod.lua будет выглядеть так:
local M = {}
local function sayMyName()
print('Hrunkner')
end
function M.sayHello()
print('Привет, ')
sayMyName()
end
return M
-- Другой файл может использовать функционал mod.lua:
local mod = require('mod') -- Запустим файл mod.lua.
-- require - стандартный способ подключения модулей.
-- require ведёт себя так: (если не кэшировано, см. ниже)
local mod = (function ()
<содержимое mod.lua>
end)()
-- Файл mod.lua воспринимается, как тело функции, поэтому
-- все локальные переменные и функции внутри него не видны за его пределами.
-- Это работает, так как здесь mod = M в mod.lua:
mod.sayHello() -- Выведет "Привет, Hrunkner".
-- Это будет ошибочным; sayMyName доступна только в mod.lua:
mod.sayMyName() -- ошибка
-- Значения, возвращаемые require, кэшируются,
-- поэтому содержимое файла выполняется только 1 раз,
-- даже если он подключается с помощью require много раз.
-- Предположим, mod2.lua содержит "print('Hi!')".
local a = require('mod2') -- Выведет "Hi!"
local b = require('mod2') -- Ничего не выведет; a=b.
-- dofile, в отличии от require, работает без кэширования:
dofile('mod2') --> Hi!
dofile('mod2') --> Hi! (запустится снова)
-- loadfile загружает файл, но не запускает его.
f = loadfile('mod2') -- Вызов f() запустит содержимое mod2.lua.
-- loadstring - это loadfile для строк.
g = loadstring('print(343)') -- Вернет функцию.
g() -- Напишет 343.
--]]
```
## Примечание (от автора)
Мне было интересно изучить Lua, чтобы делать игры при помощи <a href="http://love2d.org/">игрового движка LÖVE</a>.
Я начинал с <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
Затем я прочитал официальную <a href="http://www.lua.org/pil/contents.html">Документацию по Lua</a>.
Также может быть полезной <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Краткая справка по Lua</a> на lua-users.org.
Ещё из основных тем не охвачены стандартные библиотеки:
* <a href="http://lua-users.org/wiki/StringLibraryTutorial">библиотека string</a>
* <a href="http://lua-users.org/wiki/TableLibraryTutorial">библиотека table</a>
* <a href="http://lua-users.org/wiki/MathLibraryTutorial">библиотека math</a>
* <a href="http://lua-users.org/wiki/IoLibraryTutorial">библиотека io</a>
* <a href="http://lua-users.org/wiki/OsLibraryTutorial">библиотека os</a>
Кстати, весь файл написан на Lua; сохраните его как learn.lua и запустите при помощи "lua learn.lua" !
Изначально эта статья была написана для tylerneylon.com.
Также она доступна как <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. Удачи с Lua!

View File

@ -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..." }
me match { case Person("George", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
val kate = Person("Kate", "1234")
kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
// 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
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
})
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
}
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"
val email = "(.*)@(.*)".r // Define a regex for the next example.
// 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"
// You can match by type:
case x: Double => "Got a Double: " + x
// You can specify conditions:
case x: Int if x > 10000 => "Got a pretty big number!"
// 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"
// You can match data structures:
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"
}
// 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"
}
/////////////////////////////////////////////////
@ -476,7 +492,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, phoneNumber:String)
case class Person(name:String, age:Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)

View File

@ -6,7 +6,7 @@ contributors:
filename: learnswift.swift
---
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6 beta.
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6+.
The official [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) book from Apple is now available via iBooks.
@ -23,7 +23,7 @@ import UIKit
// Xcode supports landmarks to annotate your code and lists them in the jump bar
// MARK: Section mark
// TODO: Do something soon
// FIXME Fix this code
// FIXME: Fix this code
println("Hello, world")
@ -55,8 +55,8 @@ println("Build value: \(buildValue)") // Build value: 7
/*
Optionals are a Swift language feature that allows you to store a `Some` or
`None` value.
Because Swift requires every property to have a value, even nil must be
Because Swift requires every property to have a value, even nil must be
explicitly stored as an Optional value.
Optional<T> is an enum.
@ -94,7 +94,8 @@ var anyObjectVar: AnyObject = 7
anyObjectVar = "Changed value to a string, not good practice, but possible."
/*
Comment here
Comment here
/*
Nested comments are also supported
*/
@ -112,8 +113,9 @@ Comment here
// Array
var shoppingList = ["catfish", "water", "lemons"]
shoppingList[1] = "bottle of water"
let emptyArray = [String]() // immutable
var emptyMutableArray = [String]() // mutable
let emptyArray = [String]() // let == immutable
let emptyArray2 = Array<String>() // same as above
var emptyMutableArray = [String]() // var == mutable
// Dictionary
@ -122,8 +124,9 @@ var occupations = [
"kaylee": "Mechanic"
]
occupations["Jayne"] = "Public Relations"
let emptyDictionary = [String: Float]() // immutable
var emptyMutableDictionary = [String: Float]() // mutable
let emptyDictionary = [String: Float]() // let == immutable
let emptyDictionary2 = Dictionary<String, Float>() // same as above
var emptyMutableDictionary = [String: Float]() // var == mutable
//
@ -165,14 +168,16 @@ do {
} while 1 == 2
// Switch
// Very powerful, think `if` statements with syntax candy
// They support String, object instances, and primitives (Int, Double, etc)
let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(localScopeValue)?"
default: // required (in order to cover all possible input)
let vegetableComment = "Everything tastes good in soup."
}
@ -186,21 +191,28 @@ default: // required (in order to cover all possible input)
// in functions and can be passed around
// Function with Swift header docs (format as reStructedText)
/**
A greet operation
A greet operation
- A bullet in docs
- Another bullet in the docs
- A bullet in docs
- Another bullet in the docs
:param: name A name
:param: day A day
:returns: A string containing the name and day value.
:param: name A name
:param: day A day
:returns: A string containing the name and day value.
*/
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
// similar to above except for the function parameter behaviors
func greet2(#requiredName: String, externalParamName localParamName: String) -> String {
return "Hello \(requiredName), the day is \(localParamName)"
}
greet2(requiredName:"John", externalParamName: "Sunday")
// Function that returns multiple items in a tuple
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
@ -281,7 +293,7 @@ print(numbers) // [3, 6, 18]
// Structures and classes have very similar capabilites
struct NamesTable {
let names: [String]
let names = [String]()
// Custom subscript
subscript(index: Int) -> String {
@ -291,8 +303,8 @@ struct NamesTable {
// Structures have an auto-generated (implicit) designated initializer
let namesTable = NamesTable(names: ["Me", "Them"])
//let name = namesTable[2]
//println("Name is \(name)") // Name is Them
let name = namesTable[1]
println("Name is \(name)") // Name is Them
//
// MARK: Classes
@ -341,7 +353,7 @@ internal class Rect: Shape {
init(sideLength: Int) {
self.sideLength = sideLength
// always super.init last when init custom properties
// always super.init last when init custom properties
super.init()
}
@ -368,6 +380,9 @@ print(mySquare.getArea()) // 25
mySquare.shrink()
print(mySquare.sideLength) // 4
// cast instance
let aShape = mySquare as Shape
// compare instances, not the same as == which compares objects (equal to)
if mySquare === mySquare {
println("Yep, it's mySquare")
@ -393,6 +408,17 @@ enum Suit {
}
}
// Enum values allow short hand syntax, no need to type the enum type
// when the variable is explicitly declared
var suitValue: Suit = .Hearts
// Non-Integer enums require direct raw value assignments
enum BookName: String {
case John = "John"
case Luke = "Luke"
}
println("Name: \(BookName.John.rawValue)")
//
// MARK: Protocols
@ -490,5 +516,4 @@ println(mySquare.sideLength) // 4
// change side length using custom !!! operator, increases size by 3
!!!mySquare
println(mySquare.sideLength) // 12
```

447
tcl.html.markdown Executable file
View File

@ -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)

View File

@ -63,8 +63,8 @@ foo = anUnknownVariable -- 现在 foo = nil.
aBoolValue = false
--只有nil和false为假; 0和 ''均为真!
if not aBoolValue then print('twas false') end
--只有nil和false为假; 0和 ''均为真!
if not aBoolValue then print('false') end
-- 'or'和 'and'短路
-- 类似于C/js里的 a?b:c 操作符:
@ -149,7 +149,7 @@ print {} -- 一样可以工作。
-- Table = Lua唯一的组合数据结构;
-- 它们是关联数组。
-- 类似于PHP的数组或者js的对象
-- 它们是哈希表或者字典,也可以当列表使用。
-- 它们是哈希表或者字典,也可以当列表使用。
-- 按字典/map的方式使用Table