diff options
-rw-r--r-- | ansible.html.markdown | 26 | ||||
-rw-r--r-- | coq.html.markdown | 208 | ||||
-rw-r--r-- | csharp.html.markdown | 20 | ||||
-rw-r--r-- | dart.html.markdown | 81 | ||||
-rw-r--r-- | de-de/java-de.html.markdown | 2 | ||||
-rw-r--r-- | dynamic-programming.html.markdown | 14 | ||||
-rw-r--r-- | elixir.html.markdown | 8 | ||||
-rw-r--r-- | es-es/hq9+-es.html.markdown | 44 | ||||
-rw-r--r-- | es-es/pcre-es.html.markdown | 84 | ||||
-rw-r--r-- | go.html.markdown | 6 | ||||
-rw-r--r-- | haskell.html.markdown | 159 | ||||
-rw-r--r-- | java.html.markdown | 2 | ||||
-rw-r--r-- | kdb+.html.markdown | 2 | ||||
-rw-r--r-- | latex.html.markdown | 2 | ||||
-rw-r--r-- | linker.html.markdown | 2 | ||||
-rw-r--r-- | mips.html.markdown | 14 | ||||
-rw-r--r-- | pt-br/clojure-macros-pt.html.markdown | 16 | ||||
-rw-r--r-- | pt-br/clojure-pt.html.markdown | 599 | ||||
-rw-r--r-- | pt-br/pascal-pt.html.markdown | 1 | ||||
-rw-r--r-- | pt-br/vim-pt.html.markdown | 11 | ||||
-rw-r--r-- | python3.html.markdown | 5 | ||||
-rw-r--r-- | sass.html.markdown | 2 | ||||
-rw-r--r-- | swift.html.markdown | 7 | ||||
-rw-r--r-- | wasm.html.markdown | 85 | ||||
-rw-r--r-- | zh-cn/powershell-cn.html.markdown | 325 |
25 files changed, 1349 insertions, 376 deletions
diff --git a/ansible.html.markdown b/ansible.html.markdown index 41a8c9b5..30dfba13 100644 --- a/ansible.html.markdown +++ b/ansible.html.markdown @@ -30,9 +30,9 @@ But ansible is way more! It provides execution plans, an API, library, and callb #### Pros -* It is an agent-less tools In most scenarios, it use ssh as a transport layer. +* It is an agent-less tool. In most scenarios, it uses ssh as a transport layer. In some way you can use it as 'bash on steroids'. -* It is very easy to start. If you are familiar with ssh concept - you already +* It is very easy to start. If you are familiar with the concept of ssh - you already know Ansible (ALMOST). * It executes 'as is' - other tools (salt, puppet, chef - might execute in different scenario than you would expect) @@ -176,7 +176,7 @@ instances in the cloud, execute shell command). The simplest module is called Example of modules: * Module: `ping` - the simplest module that is useful to verify host connectivity -* Module: `shell` - a module that executes shell command on a specified host(s). +* Module: `shell` - a module that executes a shell command on a specified host(s). ```bash @@ -204,13 +204,13 @@ the module subsystem (useful to install python2.7) Execution of a single Ansible **module** is called a **task**. The simplest module is called `ping` as you could see above. -Another example of the module that allow you to execute command remotly on +Another example of the module that allows you to execute a command remotely on multiple resources is called `shell`. See above how you were using them already. ### Playbook **Execution plan** written in a form of script file(s) is called **playbook**. -Playbook consist of multiple elements - +Playbooks consist of multiple elements - * a list (or group) of hosts that 'the play' is executed against * `task(s)` or `role(s)` that are going to be executed * multiple optional settings (like default variables, and way more) @@ -247,7 +247,7 @@ Note: Example playbook is explained in the next chapter: 'Roles' ### Inventory -Inventory is a set of objects or hosts, against which we are executing our +An inventory is a set of objects or hosts, against which we are executing our playbooks or single tasks via shell commands. For these few minutes, let's assume that we are using the default ansible inventory (which in Debian based system is placed in `/etc/ansible/hosts`). @@ -303,11 +303,11 @@ Role can be included in your playbook (executed via your playbook). ``` #### For remaining examples we would use additional repository -This example install ansible in `virtualenv` so it is independend from a system. -You need to initialize it into your shell-context with `source environment.sh` +This example installs ansible in `virtualenv` so it is independent from the system. +You need to initialize it into your shell-context with the `source environment.sh` command. -We are going to use this repository with examples: [https://github.com/sirkubax/ansible-for-learnXinYminutes]() +We are going to use this repository with examples: [https://github.com/sirkubax/ansible-for-learnXinYminutes](https://github.com/sirkubax/ansible-for-learnXinYminutes) ```bash $ # The following example contains a shell-prompt to indicate the venv and relative path @@ -513,7 +513,7 @@ $ # Now we would run the above playbook with roles You can use the jinja in the CLI too ```bash -ansible -m shell -a 'echo {{ my_variable }}` -e 'my_variable=something, playbook_parameter=twentytwo" localhost +ansible -m shell -a 'echo {{ my_variable }}' -e 'my_variable=something, playbook_parameter=twentytwo' localhost ``` In fact - jinja is used to template parts of the playbooks too @@ -551,7 +551,7 @@ provides a way to encrypt confidential files so you can store them in the repository, yet the files are decrypted on-the-fly during ansible execution. The best way to use it is to store the secret in some secure location, and -configure ansible to use during runtime. +configure ansible to use them during runtime. ```bash # Try (this would fail) @@ -588,7 +588,7 @@ You might like to know, that you can build your inventory dynamically. deliver that to ansible - anything is possible. You do not need to reinvent the wheel - there are plenty of ready to use -inventory scripts for most popular Cloud providers and a lot of in-house +inventory scripts for the most popular Cloud providers and a lot of in-house popular usecases. [AWS example](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script) @@ -614,7 +614,7 @@ callback_whitelist = profile_tasks ### facts-cache and ansible-cmdb -You can pull some information about your environment from another hosts. +You can pull some information about your environment from another host. If the information does not change - you may consider using a facts_cache to speed things up. diff --git a/coq.html.markdown b/coq.html.markdown index 115d9ff8..4c1ad690 100644 --- a/coq.html.markdown +++ b/coq.html.markdown @@ -25,19 +25,20 @@ Inside Proof General `Ctrl+C Ctrl+<Enter>` will evaluate up to your cursor. (*** Variables and functions ***) -(* The Coq proof assistant can be controlled and queried by a command language called - the vernacular. Vernacular keywords are capitalized and the commands end with a period. - Variable and function declarations are formed with the Definition vernacular. *) +(* The Coq proof assistant can be controlled and queried by a command + language called the vernacular. Vernacular keywords are capitalized and + the commands end with a period. Variable and function declarations are + formed with the Definition vernacular. *) Definition x := 10. -(* Coq can sometimes infer the types of arguments, but it is common practice to annotate - with types. *) +(* Coq can sometimes infer the types of arguments, but it is common practice + to annotate with types. *) Definition inc_nat (x : nat) : nat := x + 1. -(* There exists a large number of vernacular commands for querying information. - These can be very useful. *) +(* There exists a large number of vernacular commands for querying + information. These can be very useful. *) Compute (1 + 1). (* 2 : nat *) (* Compute a result. *) @@ -46,48 +47,50 @@ Check tt. (* tt : unit *) (* Check the type of an expressions *) About plus. (* Prints information about an object *) (* Print information including the definition *) -Print true. (* Inductive bool : Set := true : Bool | false : Bool *) +Print true. (* Inductive bool : Set := true : Bool | false : Bool *) Search nat. (* Returns a large list of nat related values *) Search "_ + _". (* You can also search on patterns *) Search (?a -> ?a -> bool). (* Patterns can have named parameters *) Search (?a * ?a). -(* Locate tells you where notation is coming from. Very helpful when you encounter - new notation. *) -Locate "+". +(* Locate tells you where notation is coming from. Very helpful when you + encounter new notation. *) -(* Calling a function with insufficient number of arguments - does not cause an error, it produces a new function. *) +Locate "+". + +(* Calling a function with insufficient number of arguments does not cause + an error, it produces a new function. *) Definition make_inc x y := x + y. (* make_inc is int -> int -> int *) Definition inc_2 := make_inc 2. (* inc_2 is int -> int *) Compute inc_2 3. (* Evaluates to 5 *) -(* Definitions can be chained with "let ... in" construct. - This is roughly the same to assigning values to multiple - variables before using them in expressions in imperative - languages. *) + +(* Definitions can be chained with "let ... in" construct. This is roughly + the same to assigning values to multiple variables before using them in + expressions in imperative languages. *) + Definition add_xy : nat := let x := 10 in let y := 20 in x + y. - (* Pattern matching is somewhat similar to switch statement in imperative languages, but offers a lot more expressive power. *) + Definition is_zero (x : nat) := match x with | 0 => true | _ => false (* The "_" pattern means "anything else". *) end. +(* You can define recursive function definition using the Fixpoint + vernacular.*) -(* You can define recursive function definition using the Fixpoint vernacular.*) Fixpoint factorial n := match n with | 0 => 1 | (S n') => n * factorial n' end. - (* Function application usually doesn't need parentheses around arguments *) Compute factorial 5. (* 120 : nat *) @@ -104,11 +107,12 @@ end with | (S n) => is_even n end. -(* As Coq is a total programming language, it will only accept programs when it can - understand they terminate. It can be most easily seen when the recursive call is - on a pattern matched out subpiece of the input, as then the input is always decreasing - in size. Getting Coq to understand that functions terminate is not always easy. See the - references at the end of the article for more on this topic. *) +(* As Coq is a total programming language, it will only accept programs when + it can understand they terminate. It can be most easily seen when the + recursive call is on a pattern matched out subpiece of the input, as then + the input is always decreasing in size. Getting Coq to understand that + functions terminate is not always easy. See the references at the end of + the article for more on this topic. *) (* Anonymous functions use the following syntax: *) @@ -119,16 +123,18 @@ Definition my_id2 : forall A : Type, A -> A := fun A x => x. Compute my_id nat 3. (* 3 : nat *) (* You can ask Coq to infer terms with an underscore *) -Compute my_id _ 3. +Compute my_id _ 3. -(* An implicit argument of a function is an argument which can be inferred from contextual - knowledge. Parameters enclosed in {} are implicit by default *) +(* An implicit argument of a function is an argument which can be inferred + from contextual knowledge. Parameters enclosed in {} are implicit by + default *) Definition my_id3 {A : Type} (x : A) : A := x. Compute my_id3 3. (* 3 : nat *) -(* Sometimes it may be necessary to turn this off. You can make all arguments explicit - again with @ *) +(* Sometimes it may be necessary to turn this off. You can make all + arguments explicit again with @ *) + Compute @my_id3 nat 3. (* Or give arguments by name *) @@ -168,17 +174,19 @@ let rec factorial n = match n with (*** Notation ***) -(* Coq has a very powerful Notation system that can be used to write expressions in more - natural forms. *) +(* Coq has a very powerful Notation system that can be used to write + expressions in more natural forms. *) + Compute Nat.add 3 4. (* 7 : nat *) Compute 3 + 4. (* 7 : nat *) -(* Notation is a syntactic transformation applied to the text of the program before being - evaluated. Notation is organized into notation scopes. Using different notation scopes - allows for a weak notion of overloading. *) +(* Notation is a syntactic transformation applied to the text of the program + before being evaluated. Notation is organized into notation scopes. Using + different notation scopes allows for a weak notion of overloading. *) + +(* Imports the Zarith module holding definitions related to the integers Z *) -(* Imports the Zarith module containing definitions related to the integers Z *) -Require Import ZArith. +Require Import ZArith. (* Notation scopes can be opened *) Open Scope Z_scope. @@ -187,7 +195,7 @@ Open Scope Z_scope. Compute 1 + 7. (* 8 : Z *) (* Integer equality checking *) -Compute 1 =? 2. (* false : bool *) +Compute 1 =? 2. (* false : bool *) (* Locate is useful for finding the origin and definition of notations *) Locate "_ =? _". (* Z.eqb x y : Z_scope *) @@ -199,10 +207,10 @@ Compute 1 + 7. (* 8 : nat *) (* Scopes can also be opened inline with the shorthand % *) Compute (3 * -7)%Z. (* -21%Z : Z *) -(* Coq declares by default the following interpretation scopes: core_scope, type_scope, - function_scope, nat_scope, bool_scope, list_scope, int_scope, uint_scope. You may also - want the numerical scopes Z_scope (integers) and Q_scope (fractions) held in the ZArith - and QArith module respectively. *) +(* Coq declares by default the following interpretation scopes: core_scope, + type_scope, function_scope, nat_scope, bool_scope, list_scope, int_scope, + uint_scope. You may also want the numerical scopes Z_scope (integers) and + Q_scope (fractions) held in the ZArith and QArith module respectively. *) (* You can print the contents of scopes *) Print Scope nat_scope. @@ -230,17 +238,19 @@ Bound to classes nat Nat.t "x * y" := Init.Nat.mul x y *) -(* Coq has exact fractions available as the type Q in the QArith module. - Floating point numbers and real numbers are also available but are a more advanced - topic, as proving properties about them is rather tricky. *) +(* Coq has exact fractions available as the type Q in the QArith module. + Floating point numbers and real numbers are also available but are a more + advanced topic, as proving properties about them is rather tricky. *) Require Import QArith. Open Scope Q_scope. Compute 1. (* 1 : Q *) -Compute 2. (* 2 : nat *) (* only 1 and 0 are interpreted as fractions by Q_scope *) + +(* Only 1 and 0 are interpreted as fractions by Q_scope *) +Compute 2. (* 2 : nat *) Compute (2 # 3). (* The fraction 2/3 *) -Compute (1 # 3) ?= (2 # 6). (* Eq : comparison *) +Compute (1 # 3) ?= (2 # 6). (* Eq : comparison *) Close Scope Q_scope. Compute ( (2 # 3) / (1 # 5) )%Q. (* 10 # 3 : Q *) @@ -279,40 +289,43 @@ Definition my_fst2 {A B : Type} (x : A * B) : A := let (a,b) := x in (*** Lists ***) -(* Lists are built by using cons and nil or by using notation available in list_scope. *) +(* Lists are built by using cons and nil or by using notation available in + list_scope. *) Compute cons 1 (cons 2 (cons 3 nil)). (* (1 :: 2 :: 3 :: nil)%list : list nat *) -Compute (1 :: 2 :: 3 :: nil)%list. +Compute (1 :: 2 :: 3 :: nil)%list. (* There is also list notation available in the ListNotations modules *) Require Import List. -Import ListNotations. +Import ListNotations. Compute [1 ; 2 ; 3]. (* [1; 2; 3] : list nat *) -(* -There are a large number of list manipulation functions available, including: +(* There is a large number of list manipulation functions available, + including: • length -• head : first element (with default) +• head : first element (with default) • tail : all but first element • app : appending • rev : reverse • nth : accessing n-th element (with default) • map : applying a function -• flat_map : applying a function returning lists +• flat_map : applying a function returning lists • fold_left : iterator (from head to tail) -• fold_right : iterator (from tail to head) +• fold_right : iterator (from tail to head) *) Definition my_list : list nat := [47; 18; 34]. Compute List.length my_list. (* 3 : nat *) + (* All functions in coq must be total, so indexing requires a default value *) -Compute List.nth 1 my_list 0. (* 18 : nat *) +Compute List.nth 1 my_list 0. (* 18 : nat *) Compute List.map (fun x => x * 2) my_list. (* [94; 36; 68] : list nat *) -Compute List.filter (fun x => Nat.eqb (Nat.modulo x 2) 0) my_list. (* [18; 34] : list nat *) -Compute (my_list ++ my_list)%list. (* [47; 18; 34; 47; 18; 34] : list nat *) +Compute List.filter (fun x => Nat.eqb (Nat.modulo x 2) 0) my_list. + (* [18; 34] : list nat *) +Compute (my_list ++ my_list)%list. (* [47; 18; 34; 47; 18; 34] : list nat *) (*** Strings ***) @@ -342,16 +355,19 @@ Close Scope string_scope. • PArith : Basic positive integer arithmetic • NArith : Basic binary natural number arithmetic • ZArith : Basic relative integer arithmetic -• Numbers : Various approaches to natural, integer and cyclic numbers (currently - axiomatically and on top of 2^31 binary words) + +• Numbers : Various approaches to natural, integer and cyclic numbers + (currently axiomatically and on top of 2^31 binary words) • Bool : Booleans (basic functions and results) + • Lists : Monomorphic and polymorphic lists (basic functions and results), Streams (infinite sequences defined with co-inductive types) • Sets : Sets (classical, constructive, finite, infinite, power set, etc.) -• FSets : Specification and implementations of finite sets and finite maps +• FSets : Specification and implementations of finite sets and finite maps (by lists and by AVL trees) -• Reals : Axiomatization of real numbers (classical, basic functions, integer part, - fractional part, limit, derivative, Cauchy series, power series and results,...) +• Reals : Axiomatization of real numbers (classical, basic functions, + integer part, fractional part, limit, derivative, Cauchy series, + power series and results,...) • Relations : Relations (definitions and basic results) • Sorting : Sorted list (basic definitions and heapsort correctness) • Strings : 8-bits characters and strings @@ -360,18 +376,20 @@ Close Scope string_scope. (*** User-defined data types ***) -(* Because Coq is dependently typed, defining type aliases is no different than defining - an alias for a value. *) +(* Because Coq is dependently typed, defining type aliases is no different + than defining an alias for a value. *) Definition my_three : nat := 3. Definition my_nat : Type := nat. -(* More interesting types can be defined using the Inductive vernacular. Simple enumeration - can be defined like so *) +(* More interesting types can be defined using the Inductive vernacular. + Simple enumeration can be defined like so *) + Inductive ml := OCaml | StandardML | Coq. Definition lang := Coq. (* Has type "ml". *) -(* For more complicated types, you will need to specify the types of the constructors. *) +(* For more complicated types, you will need to specify the types of the + constructors. *) (* Type constructors don't need to be empty. *) Inductive my_number := plus_infinity @@ -379,23 +397,28 @@ Inductive my_number := plus_infinity Compute nat_value 3. (* nat_value 3 : my_number *) -(* Record syntax is sugar for tuple-like types. It defines named accessor functions for - the components. Record types are defined with the notation {...} *) +(* Record syntax is sugar for tuple-like types. It defines named accessor + functions for the components. Record types are defined with the notation + {...} *) + Record Point2d (A : Set) := mkPoint2d { x2 : A ; y2 : A }. (* Record values are constructed with the notation {|...|} *) Definition mypoint : Point2d nat := {| x2 := 2 ; y2 := 3 |}. Compute x2 nat mypoint. (* 2 : nat *) -Compute mypoint.(x2 nat). (* 2 : nat *) +Compute mypoint.(x2 nat). (* 2 : nat *) + +(* Types can be parameterized, like in this type for "list of lists of + anything". 'a can be substituted with any type. *) -(* Types can be parameterized, like in this type for "list of lists - of anything". 'a can be substituted with any type. *) Definition list_of_lists a := list (list a). Definition list_list_nat := list_of_lists nat. (* Types can also be recursive. Like in this type analogous to built-in list of naturals. *) -Inductive my_nat_list := EmptyList | NatList : nat -> my_nat_list -> my_nat_list. +Inductive my_nat_list := + EmptyList | NatList : nat -> my_nat_list -> my_nat_list. + Compute NatList 1 EmptyList. (* NatList 1 EmptyList : my_nat_list *) (** Matching type constructors **) @@ -427,31 +450,38 @@ Compute sum_list [1; 2; 3]. (* Evaluates to 6 *) (*** A Taste of Proving ***) -(* Explaining the proof language is out of scope for this tutorial, but here is a taste to - whet your appetite. Check the resources below for more. *) +(* Explaining the proof language is out of scope for this tutorial, but here + is a taste to whet your appetite. Check the resources below for more. *) + +(* A fascinating feature of dependently type based theorem provers is that + the same primitive constructs underly the proof language as the + programming features. For example, we can write and prove the + proposition A and B implies A in raw Gallina *) -(* A fascinating feature of dependently type based theorem provers is that the same - primitive constructs underly the proof language as the programming features. - For example, we can write and prove the proposition A and B implies A in raw Gallina *) +Definition my_theorem : forall A B, A /\ B -> A := + fun A B ab => match ab with + | (conj a b) => a + end. -Definition my_theorem : forall A B, A /\ B -> A := fun A B ab => match ab with - | (conj a b) => a - end. +(* Or we can prove it using tactics. Tactics are a macro language to help + build proof terms in a more natural style and automate away some + drudgery. *) -(* Or we can prove it using tactics. Tactics are a macro language to help build proof terms - in a more natural style and automate away some drudgery. *) Theorem my_theorem2 : forall A B, A /\ B -> A. Proof. intros A B ab. destruct ab as [ a b ]. apply a. Qed. -(* We can prove easily prove simple polynomial equalities using the automated tactic ring. *) +(* We can prove easily prove simple polynomial equalities using the + automated tactic ring. *) + Require Import Ring. Require Import Arith. Theorem simple_poly : forall (x : nat), (x + 1) * (x + 2) = x * x + 3 * x + 2. Proof. intros. ring. Qed. -(* Here we prove the closed form for the sum of all numbers 1 to n using induction *) +(* Here we prove the closed form for the sum of all numbers 1 to n using + induction *) Fixpoint sumn (n : nat) : nat := match n with @@ -465,8 +495,10 @@ Proof. intros n. induction n. - simpl. ring [IHn]. (* induction step *) Qed. ``` - -With this we have only scratched the surface of Coq. It is a massive ecosystem with many interesting and peculiar topics leading all the way up to modern research. + +With this we have only scratched the surface of Coq. It is a massive +ecosystem with many interesting and peculiar topics leading all the way up +to modern research. ## Further reading diff --git a/csharp.html.markdown b/csharp.html.markdown index 37573e01..0643f033 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -727,10 +727,10 @@ on a new line! ""Wow!"", the masses cried"; int _speed; // Everything is private by default: Only accessible from within this class. // can also use keyword private public string Name { get; set; } - + // Properties also have a special syntax for when you want a readonly property // that simply returns the result of an expression - public string LongName => Name + " " + _speed + " speed"; + public string LongName => Name + " " + _speed + " speed"; // Enum is a value type that consists of a set of named constants // It is really just mapping a name to a value (an int, unless specified otherwise). @@ -1091,7 +1091,7 @@ on a new line! ""Wow!"", the masses cried"; // Spell failed return false; } - // Other exceptions, or MagicServiceException where Code is not 42 + // Other exceptions, or MagicServiceException where Code is not 42 catch(Exception ex) when (LogException(ex)) { // Execution never reaches this block @@ -1215,7 +1215,7 @@ namespace Csharp7 Console.WriteLine(tt.GetLastName()); } } - + // PATTERN MATCHING class PatternMatchingTest { @@ -1315,8 +1315,10 @@ namespace Csharp7 * [C# language reference](https://docs.microsoft.com/dotnet/csharp/language-reference/) * [Learn .NET](https://dotnet.microsoft.com/learn) * [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) - * [DotNetPerls](https://www.dotnetperls.com/) - * [C# in Depth](https://manning.com/skeet3) - * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064) - * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254) - * [Windows Forms Programming in C#](https://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254.do) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + * [freeCodeCamp - C# Tutorial for Beginners](https://www.youtube.com/watch?v=GhQdlIFylQ8) +
\ No newline at end of file diff --git a/dart.html.markdown b/dart.html.markdown index ce6f681b..d3c231bd 100644 --- a/dart.html.markdown +++ b/dart.html.markdown @@ -29,6 +29,7 @@ example1() { nested2() => print("Example1 nested 1 nested 2"); nested2(); } + nested1(); } @@ -37,6 +38,7 @@ example2() { nested1(fn) { fn(); } + nested1(() => print("Example2 nested 1")); } @@ -47,9 +49,12 @@ example3() { planA(fn(informSomething)) { fn("Example3 plan A"); } - planB(fn) { // Or don't declare number of parameters. + + planB(fn) { + // Or don't declare number of parameters. fn("Example3 plan B"); } + planA((s) => print(s)); planB((s) => print(s)); } @@ -60,17 +65,20 @@ example4() { nested1(fn(informSomething)) { fn(example4Something); } + nested1((s) => print(s)); } // Class declaration with a sayIt method, which also has closure access // to the outer variable as though it were a function as seen before. var example5method = "Example5 sayIt"; + class Example5Class { sayIt() { print(example5method); } } + example5() { // Create an anonymous instance of the Example5Class and call the sayIt // method on it. @@ -86,6 +94,7 @@ class Example6Class { print(instanceVariable); } } + example6() { new Example6Class().sayIt(); } @@ -96,10 +105,12 @@ class Example7Class { static sayItFromClass() { print(classVariable); } + sayItFromInstance() { print(classVariable); } } + example7() { Example7Class.sayItFromClass(); new Example7Class().sayItFromInstance(); @@ -111,7 +122,7 @@ example7() { // by default. But arrays and maps are not. They can be made constant by // declaring them "const". var example8Array = const ["Example8 const array"], - example8Map = const {"someKey": "Example8 const map"}; + example8Map = const {"someKey": "Example8 const map"}; example8() { print(example8Array[0]); print(example8Map["someKey"]); @@ -172,6 +183,7 @@ example13() { print("Example13 regexp doesn't match '${s}'"); } } + match(s1); match(s2); } @@ -190,7 +202,7 @@ example14() { } // dynamic typed null can be convert to bool - var b;// b is dynamic type + var b; // b is dynamic type b = "abc"; try { if (b) { @@ -240,9 +252,11 @@ example15() { // StringBuffer. Or you could join a string array. example16() { var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e; - for (e in a) { sb.write(e); } + for (e in a) { + sb.write(e); + } print("Example16 dynamic string created with " - "StringBuffer '${sb.toString()}'"); + "StringBuffer '${sb.toString()}'"); print("Example16 join string array '${a.join()}'"); } @@ -302,11 +316,13 @@ class Example21 { set names(List<String> list) { _names = list; } + int get length => _names.length; void add(String name) { _names.add(name); } } + void example21() { Example21 o = new Example21(); o.add("c"); @@ -320,7 +336,9 @@ class Example22A { var _name = "Some Name!"; get name => _name; } + class Example22B extends Example22A {} + example22() { var o = new Example22B(); print("Example22 class inheritance '${o.name}'"); @@ -334,19 +352,21 @@ example22() { // single inheritance doesn't get in the way of reusable code. // Mixins follow the "with" statement during the class declaration. class Example23A {} + class Example23Utils { addTwo(n1, n2) { return n1 + n2; } } + class Example23B extends Example23A with Example23Utils { addThree(n1, n2, n3) { return addTwo(n1, n2) + n3; } } + example23() { - var o = new Example23B(), r1 = o.addThree(1, 2, 3), - r2 = o.addTwo(1, 2); + var o = new Example23B(), r1 = o.addThree(1, 2, 3), r2 = o.addTwo(1, 2); print("Example23 addThree(1, 2, 3) results in '${r1}'"); print("Example23 addTwo(1, 2) results in '${r2}'"); } @@ -362,12 +382,13 @@ class Example24A { } get value => _value; } + class Example24B extends Example24A { Example24B({value: "someOtherValue"}) : super(value: value); } + example24() { - var o1 = new Example24B(), - o2 = new Example24B(value: "evenMore"); + var o1 = new Example24B(), o2 = new Example24B(value: "evenMore"); print("Example24 calling super during constructor '${o1.value}'"); print("Example24 calling super during constructor '${o2.value}'"); } @@ -379,10 +400,11 @@ class Example25 { var value, anotherValue; Example25({this.value, this.anotherValue}); } + example25() { var o = new Example25(value: "a", anotherValue: "b"); print("Example25 shortcut for constructor '${o.value}' and " - "'${o.anotherValue}'"); + "'${o.anotherValue}'"); } // Named parameters are available when declared between {}. @@ -394,17 +416,19 @@ example26() { _name = name; _surname = surname; } + setConfig2(name, [surname, email]) { _name = name; _surname = surname; _email = email; } + setConfig1(surname: "Doe", name: "John"); print("Example26 name '${_name}', surname '${_surname}', " - "email '${_email}'"); + "email '${_email}'"); setConfig2("Mary", "Jane"); print("Example26 name '${_name}', surname '${_surname}', " - "email '${_email}'"); + "email '${_email}'"); } // Variables declared with final can only be set once. @@ -416,6 +440,7 @@ class Example27 { // that follows the : Example27({this.color1, color2}) : color2 = color2; } + example27() { final color = "orange", o = new Example27(color1: "lilac", color2: "white"); print("Example27 color is '${color}'"); @@ -434,6 +459,7 @@ class Example28 extends IterableBase { } get iterator => names.iterator; } + example28() { var o = new Example28(); o.forEach((name) => print("Example28 '${name}'")); @@ -459,10 +485,12 @@ example29() { callItForMe(fn()) { return fn(); } + rand() { v = new DM.Random().nextInt(50); return v; } + while (true) { print("Example29 callItForMe(rand) '${callItForMe(rand)}'"); if (v != 30) { @@ -477,8 +505,12 @@ example29() { // Parse int, convert double to int, or just keep int when dividing numbers // by using the ~/ operation. Let's play a guess game too. example30() { - var gn, tooHigh = false, - n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0; + var gn, + tooHigh = false, + n, + n2 = (2.0).toInt(), + top = int.parse("123") ~/ n2, + bottom = 0; top = top ~/ 6; gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive print("Example30 Guess a number between 0 and ${top}"); @@ -488,10 +520,11 @@ example30() { } else { tooHigh = n > gn; print("Example30 Number ${n} is too " - "${tooHigh ? 'high' : 'low'}. Try again"); + "${tooHigh ? 'high' : 'low'}. Try again"); } return n == gn; } + n = (top - bottom) ~/ 2; while (!guessNumber(n)) { if (tooHigh) { @@ -548,12 +581,15 @@ example33() { // the program needs to startup with. main() { print("Learn Dart in 15 minutes!"); - [example1, example2, example3, example4, example5, example6, example7, - example8, example9, example10, example11, example12, example13, example14, - example15, example16, example17, example18, example19, example20, - example21, example22, example23, example24, example25, example26, - example27, example28, example29, example30, example31, example32, example33 - ].forEach((ef) => ef()); + [ + example1, example2, example3, example4, example5, + example6, example7, example8, example9, example10, + example11, example12, example13, example14, example15, + example16, example17, example18, example19, example20, + example21, example22, example23, example24, example25, + example26, example27, example28, example29, + example30 // Adding this comment stops the dart formatter from putting all items on a new line + ].forEach((ef) => ef()); } ``` @@ -564,6 +600,3 @@ Dart has a comprehensive web-site. It covers API reference, tutorials, articles useful Try Dart online. [https://www.dartlang.org](https://www.dartlang.org) [https://try.dartlang.org](https://try.dartlang.org) - - - diff --git a/de-de/java-de.html.markdown b/de-de/java-de.html.markdown index e8ac5bda..e52087ec 100644 --- a/de-de/java-de.html.markdown +++ b/de-de/java-de.html.markdown @@ -477,7 +477,7 @@ Für tiefergreifende Fragen ist Google der beste Startpunkt. * [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html) -* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html) +* [Java Code Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf) **Online Tutorials** diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown index c73b1845..5d260206 100644 --- a/dynamic-programming.html.markdown +++ b/dynamic-programming.html.markdown @@ -3,6 +3,7 @@ category: Algorithms & Data Structures name: Dynamic Programming contributors: - ["Akashdeep Goel", "http://github.com/akashdeepgoel"] + - ["Miltiadis Stouras", "https://github.com/mstou"] --- # Dynamic Programming @@ -48,6 +49,15 @@ for i=0 to n-1 ## Online Resources -* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming) +* MIT 6.006: [Lessons 19,20,21,22](https://www.youtube.com/playlist?list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb) +* TopCoder: [Dynamic Programming from Novice to Advanced](https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming-from-novice-to-advanced/) +* [CodeChef](https://www.codechef.com/wiki/tutorial-dynamic-programming) * [InterviewBit](https://www.interviewbit.com/courses/programming/topics/dynamic-programming/) - +* GeeksForGeeks: + * [Overlapping Subproblems](https://www.geeksforgeeks.org/dynamic-programming-set-1/) + * [Tabulation vs Memoization](https://www.geeksforgeeks.org/tabulation-vs-memoizatation/) + * [Optimal Substructure Property](https://www.geeksforgeeks.org/dynamic-programming-set-2-optimal-substructure-property/) + * [How to solve a DP problem](https://www.geeksforgeeks.org/solve-dynamic-programming-problem/) +* [How to write DP solutions](https://www.quora.com/Are-there-any-good-resources-or-tutorials-for-dynamic-programming-DP-besides-the-TopCoder-tutorial/answer/Michal-Danilák) + +And a [quiz](https://www.commonlounge.com/discussion/cdbbfe83bcd64281964b788969247253) to test your knowledge. diff --git a/elixir.html.markdown b/elixir.html.markdown index 7af29202..0b717ca6 100644 --- a/elixir.html.markdown +++ b/elixir.html.markdown @@ -1,7 +1,7 @@ --- language: elixir contributors: - - ["Joao Marques", "http://github.com/mrshankly"] + - ["Joao Marques", "https://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] - ["Ryan Plant", "https://github.com/ryanplant-au"] - ["Ev Bogdanov", "https://github.com/evbogdanov"] @@ -451,9 +451,9 @@ Agent.update(my_agent, fn colors -> ["blue" | colors] end) ## References -* [Getting started guide](http://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](http://elixir-lang.org) +* [Getting started guide](https://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](https://elixir-lang.org) * [Elixir Documentation](https://elixir-lang.org/docs.html) * ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) by Dave Thomas -* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) -* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) by Fred Hebert +* [Elixir Cheat Sheet](https://media.pragprog.com/titles/elixir/ElixirCheat.pdf) +* ["Learn You Some Erlang for Great Good!"](https://learnyousomeerlang.com/) by Fred Hebert * ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) by Joe Armstrong diff --git a/es-es/hq9+-es.html.markdown b/es-es/hq9+-es.html.markdown new file mode 100644 index 00000000..0e1a36e1 --- /dev/null +++ b/es-es/hq9+-es.html.markdown @@ -0,0 +1,44 @@ +--- +language: HQ9+ +filename: hq9+-es.html +contributors: + - ["Alexey Nazaroff", "https://github.com/rogaven"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +lang: es-es +--- + +HQ9+ es una parodia de los lenguajes de programación esotéricos y fue creado +por Cliff Biffle. +El lenguaje tiene solo cuatro comandos y no está completo de Turing. + +``` +Solo hay cuatro comandos, representados por los siguientes cuatro caracteres +H: imprime "Hello, world!" +Q: imprime el código fuente del programa (ein Quine) +9: imprime la letra de "99 Bottles of Beer" ++: aumenta el acumulador en uno (el valod del acumulador no se puede leer) +Cualquier otro caracter es ignorado. + +Ok. Escribamos el programa: + HQ + +Resultado: + Hello world! + HQ + +HQ9+ es muy simple, pero te permite hacer cosas en él. Otros lenguajes son muy +difíciles.Por ejemplo, el siguiente programa imprime tres copias de sí mismo en +la pantalla: + QQQ +Esto imprime: + QQQ + QQQ + QQQ +``` + +Y esto es todo. Hay muchos intérpretes para HQ9+. +A continuación encontrarás uno de ellos. + ++ [One of online interpreters](https://almnet.de/esolang/hq9plus.php) ++ [HQ9+ official website](http://cliffle.com/esoterica/hq9plus.html) diff --git a/es-es/pcre-es.html.markdown b/es-es/pcre-es.html.markdown new file mode 100644 index 00000000..279c9a39 --- /dev/null +++ b/es-es/pcre-es.html.markdown @@ -0,0 +1,84 @@ +--- +language: PCRE +filename: pcre-es.txt +contributors: + - ["Sachin Divekar", "http://github.com/ssd532"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +lang: es-es +--- + +Una expresión regular (regex o regexp para abreviar) es una cadena especial +utilizada para definir un patrón, por ejemplo, buscar una secuencia de +caracteres; por ejemplo, `/^[a-z]+:/` se puede usar para extraer `http:` +desde la URL `http://github.com/`. + +PCRE (Pearl Compatible Regular Expressions) es una biblioteca para expresiones +muy similar a la Perls, desde ahí el nombre. Se trata de una de las sintaxis +más comunes para escribir expresiones regulares. + +Hay dos tipos de metacaracteres (caracteres con una función especial): + +* Caracteres reconocidos en todas partes excepto corchetes + +``` + \ caracter de escape + ^ buscar al principio de la cadena (o línea, en modo multilínea) + $ busca al final de la cadena (o línea, en modo multilínea) + . cualquier caracter exceptoo las nuevas líneas + [ inicio de clase de caracter + | condiciones alternativas del separador + ( inicio del subpatrón + ) fin del subpatrón + ? cuantificador "0 o 1" + * quantificatore "0 o más" + + quantificatore "1 o más" + { inicio de cuantificador numérico +``` + +* Caracteres reconocidos entre corchetes + +``` + \ caracter de escape + ^ negar la clase si es el primer caracter + - indica una serie de caracteres + [ clase de caracteres POSIX (si sigue la sintaxis POSIX) + ] termina la clase de caracteres +``` + +PCRE también proporciona clases de caracteres predefinidas + +``` + \d cifra decimal + \D cifra NO decimal + \h espacio horizontal vacío + \H espacio horizontal NO vacío + \s espacio + \S NO esoacui + \v espacio vertical vacío + \V espacio vertical NO vacío + \w palabra + \W "NO palabra" +``` + +## Ejemplos + +Usaremos la siguiente cadena para nuestras pruebas: + +``` +66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1" +``` + +Se trata de una línea de log del servidor web Apache. + +| Regex | Resultado | Comentario | +| :---- | :-------------- | :------ | +| `GET` | GET | Busque exactamente la cadena "GET" (distingue entre mayúsculas y minúsculas) | +| `\d+.\d+.\d+.\d+` | 66.249.64.13 | `\d+` identifica uno o más (cuantificador `+`) números [0-9], `\.` identifica el caracter `.` | +| `(\d+\.){3}\d+` | 66.249.64.13 | `(\d+\.){3}` busca el grupo (`\d+\.`) exactamente 3 veces. | +| `\[.+\]` | [18/Sep/2004:11:07:48 +1000] | `.+` identifica cualquier caracter, excepto las nuevas líneas; `.` indica cualquier carácter | +| `^\S+` | 66.249.64.13 | `^` buscar al inicio de la cadena, `\S+` identifica la primera cadena de caracteres que no sea espacio | +| `\+[0-9]+` | +1000 | `\+` identifica el caracter `+`. `[0-9]` indica una cifra de 0 a 9. La expresión es equivalente a `\+\d+` | + +## Otros recursos +[Regex101](https://regex101.com/) - probador de expresiones regulares diff --git a/go.html.markdown b/go.html.markdown index ae99535b..4fc155b5 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -30,6 +30,12 @@ Go comes with a good standard library and a sizeable community. /* Multi- line comment */ + /* A build tag is a line comment starting with // +build + and can be execute by go build -tags="foo bar" command. + Build tags are placed before the package clause near or at the top of the file + followed by a blank line or other line comments. */ +// +build prod, dev, test + // A package clause starts every source file. // Main is a special name declaring an executable rather than a library. package main diff --git a/haskell.html.markdown b/haskell.html.markdown index 90d47c27..1cc79ec9 100644 --- a/haskell.html.markdown +++ b/haskell.html.markdown @@ -293,7 +293,13 @@ foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16 -- 7. Data Types ---------------------------------------------------- --- Here's how you make your own data type in Haskell +-- A data type is declared with a 'type constructor' on the left +-- and one or more 'data constructors' on the right, separated by +-- the pipe | symbol. This is a sum/union type. Each data constructor +-- is a (possibly nullary) function that creates an object of the type +-- named by the type constructor. + +-- This is essentially an enum data Color = Red | Blue | Green @@ -304,7 +310,62 @@ say Red = "You are Red!" say Blue = "You are Blue!" say Green = "You are Green!" --- Your data types can have parameters too: +-- Note that the type constructor is used in the type signature +-- and the data constructors are used in the body of the function +-- Data constructors are primarily pattern-matched against + +-- This next one is a traditional container type holding two fields +-- In a type declaration, data constructors take types as parameters +-- Data constructors can have the same name as type constructors +-- This is common where the type only has a single data constructor + +data Point = Point Float Float + +-- This can be used in a function like: + +distance :: Point -> Point -> Float +distance (Point x y) (Point x' y') = sqrt $ dx + dy + where dx = (x - x') ** 2 + dy = (y - y') ** 2 + +-- Types can have multiple data constructors with arguments, too + +data Name = Mononym String + | FirstLastName String String + | FullName String String String + +-- To make things clearer we can use record syntax + +data Point2D = CartesianPoint2D { x :: Float, y :: Float } + | PolarPoint2D { r :: Float, theta :: Float } + +myPoint = CartesianPoint2D { x = 7.0, y = 10.0 } + +-- Using record syntax automatically creates accessor functions +-- (the name of the field) + +xOfMyPoint = x myPoint + +-- xOfMyPoint is equal to 7.0 + +-- Record syntax also allows a simple form of update + +myPoint' = myPoint { x = 9.0 } + +-- myPoint' is CartesianPoint2D { x = 9.0, y = 10.0 } + +-- Even if a type is defined with record syntax, it can be declared like +-- a simple data constructor. This is fine: + +myPoint'2 = CartesianPoint2D 3.3 4.0 + +-- It's also useful to pattern match data constructors in `case` expressions + +distanceFromOrigin x = + case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2 + (PolarPoint2D r _) -> r + +-- Your data types can have type parameters too: data Maybe a = Nothing | Just a @@ -313,8 +374,98 @@ Just "hello" -- of type `Maybe String` Just 1 -- of type `Maybe Int` Nothing -- of type `Maybe a` for any `a` +-- For convenience we can also create type synonyms with the 'type' keyword + +type String = [Char] + +-- Unlike `data` types, type synonyms need no constructor, and can be used +-- anywhere a synonymous data type could be used. Say we have the +-- following type synonyms and items with the following type signatures + +type Weight = Float +type Height = Float +type Point = (Float, Float) +getMyHeightAndWeight :: Person -> (Height, Weight) +findCenter :: Circle -> Point +somePerson :: Person +someCircle :: Circle +distance :: Point -> Point -> Float + +-- The following would compile and run without issue, +-- even though it does not make sense semantically, +-- because the type synonyms reduce to the same base types + +distance (getMyHeightAndWeight somePerson) (findCenter someCircle) + +---------------------------------------------------- +-- 8. Typeclasses +---------------------------------------------------- + +-- Typeclasses are one way Haskell does polymorphism +-- They are similar to interfaces in other languages +-- A typeclass defines a set of functions that must +-- work on any type that is in that typeclass. + +-- The Eq typeclass is for types whose instances can +-- be tested for equality with one another. + +class Eq a where + (==) :: a -> a -> Bool + (/=) :: a -> a -> Bool + x == y = not (x /= y) + x /= y = not (x == y) + +-- This defines a typeclass that requires two functions, (==) and (/=) +-- It also declares that one function can be declared in terms of another +-- So it is enough that *either* the (==) function or the (/=) is defined +-- And the other will be 'filled in' based on the typeclass definition + +-- To make a type a member of a type class, the instance keyword is used + +instance Eq TrafficLight where + Red == Red = True + Green == Green = True + Yellow == Yellow = True + _ == _ = False + +-- Now we can use (==) and (/=) with TrafficLight objects + +canProceedThrough :: TrafficLight -> Bool +canProceedThrough t = t /= Red + +-- You can NOT create an instance definition for a type synonym + +-- Functions can be written to take typeclasses with type parameters, +-- rather than types, assuming that the function only relies on +-- features of the typeclass + +isEqual (Eq a) => a -> a -> Bool +isEqual x y = x == y + +-- Note that x and y MUST be the same type, as they are both defined +-- as being of type parameter 'a'. +-- A typeclass does not state that different types in the typeclass can +-- be mixed together. +-- So `isEqual Red 2` is invalid, even though 2 is an Int which is an +-- instance of Eq, and Red is a TrafficLight which is also an instance of Eq + +-- Other common typeclasses are: +-- Ord for types that can be ordered, allowing you to use >, <=, etc. +-- Read for types that can be created from a string representation +-- Show for types that can be converted to a string for display +-- Num, Real, Integral, Fractional for types that can do math +-- Enum for types that can be stepped through +-- Bounded for types with a maximum and minimum + +-- Haskell can automatically make types part of Eq, Ord, Read, Show, Enum, +-- and Bounded with the `deriving` keyword at the end of the type declaration + +data Point = Point Float Float deriving (Eq, Read, Show) + +-- In this case it is NOT necessary to create an 'instance' definition + ---------------------------------------------------- --- 8. Haskell IO +-- 9. Haskell IO ---------------------------------------------------- -- While IO can't be explained fully without explaining monads, @@ -395,7 +546,7 @@ main'' = do ---------------------------------------------------- --- 9. The Haskell REPL +-- 10. The Haskell REPL ---------------------------------------------------- -- Start the repl by typing `ghci`. diff --git a/java.html.markdown b/java.html.markdown index 4f45a268..79769352 100644 --- a/java.html.markdown +++ b/java.html.markdown @@ -381,7 +381,7 @@ public class LearnJava { do { System.out.println(fooDoWhile); // Increment the counter - // Iterated 99 times, fooDoWhile 0->99 + // Iterated 100 times, fooDoWhile 0->99 fooDoWhile++; } while(fooDoWhile < 100); System.out.println("fooDoWhile Value: " + fooDoWhile); diff --git a/kdb+.html.markdown b/kdb+.html.markdown index 027b6571..680c01c1 100644 --- a/kdb+.html.markdown +++ b/kdb+.html.markdown @@ -771,6 +771,6 @@ select from splayed / (the columns are read from disk on request) * [*q for mortals* q language tutorial](http://code.kx.com/q4m3/) * [*Introduction to Kdb+* on disk data tutorial](http://code.kx.com/q4m3/14_Introduction_to_Kdb+/) -* [q language reference](http://code.kx.com/q/ref/card/) +* [q language reference](https://code.kx.com/q/ref/) * [Online training courses](http://training.aquaq.co.uk/) * [TorQ production framework](https://github.com/AquaQAnalytics/TorQ) diff --git a/latex.html.markdown b/latex.html.markdown index c980f5e5..e8bc6064 100644 --- a/latex.html.markdown +++ b/latex.html.markdown @@ -141,7 +141,7 @@ Operators are essential parts of a mathematical document: trigonometric functions ($\sin$, $\cos$, $\tan$), logarithms and exponentials ($\log$, $\exp$), limits ($\lim$), etc.\ -have per-defined LaTeX commands. +have pre-defined LaTeX commands. Let's write an equation to see how it's done: $\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ diff --git a/linker.html.markdown b/linker.html.markdown index ebe6233d..42839e05 100644 --- a/linker.html.markdown +++ b/linker.html.markdown @@ -5,5 +5,5 @@ contributors: - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"] --- -This article is available in [Russian](http://localhost:4567/docs/ru-ru/linker-ru/). +This article is available in [Russian](https://learnxinyminutes.com/docs/ru-ru/linker-ru/). diff --git a/mips.html.markdown b/mips.html.markdown index 4134d3fa..45e16e7b 100644 --- a/mips.html.markdown +++ b/mips.html.markdown @@ -20,12 +20,12 @@ gateways and routers. # Programs typically contain a .data and .text sections .data # Section where data is stored in memory (allocated in RAM), similar to - # variables in higher level languages + # variables in higher-level languages # Declarations follow a ( label: .type value(s) ) form of declaration hello_world: .asciiz "Hello World\n" # Declare a null terminated string num1: .word 42 # Integers are referred to as words - # (32 bit value) + # (32-bit value) arr1: .word 1, 2, 3, 4, 5 # Array of words arr2: .byte 'a', 'b' # Array of chars (1 byte each) @@ -139,7 +139,7 @@ gateways and routers. # The basic format of these branching instructions typically follow <instr> # <reg1> <reg2> <label> where label is the label we want to jump to if the # given conditional evaluates to true - # Sometimes it is easier to write the conditional logic backwards, as seen + # Sometimes it is easier to write the conditional logic backward, as seen # in the simple if statement example below beq $t0, $t1, reg_eq # Will branch to reg_eq if @@ -156,7 +156,7 @@ gateways and routers. ble $t0, $t1, t0_gte_t1 # Branches when $t0 <= $t1 bltz $t0, t0_lt0 # Branches when $t0 < 0 slt $s0, $t0, $t1 # Instruction that sends a signal when - # $t0 < $t1 with reuslt in $s0 (1 for true) + # $t0 < $t1 with result in $s0 (1 for true) # Simple if statement # if (i == j) @@ -289,12 +289,12 @@ gateways and routers. ## MACROS ## _macros: - # Macros are extremly useful for substituting repeated code blocks with a + # Macros are extremely useful for substituting repeated code blocks with a # single label for better readability # These are in no means substitutes for functions # These must be declared before it is used - # Macro for printing new lines (since these can be very repetitive) + # Macro for printing newlines (since these can be very repetitive) .macro println() la $a0, newline # New line string stored here li $v0, 4 @@ -338,7 +338,7 @@ gateways and routers. buffer: .space 128 # Allocates a block in memory, does # not automatically clear # These blocks of memory are aligned - # next each other + # next to each other .text la $s0, list # Load address of list diff --git a/pt-br/clojure-macros-pt.html.markdown b/pt-br/clojure-macros-pt.html.markdown index d56840e0..c686bb80 100644 --- a/pt-br/clojure-macros-pt.html.markdown +++ b/pt-br/clojure-macros-pt.html.markdown @@ -13,15 +13,15 @@ do Clojure lhe dá acesso a toda a extensão da linguagem para escrever rotinas de geração de código chamados "macros". Macros fornecem uma poderosa forma de adequar a linguagem às suas necessidades. -Pórem Tenha cuidado. É considerado má pratica escrever uma macro quando uma função vai fazer. Use uma macro apenas -quando você precisar do controle sobre quando ou se os argumentos para um formulário será avaliado. +Pórem, tenha cuidado. É considerado má pratica escrever uma macro quando uma função vai fazer. Use uma macro apenas +quando você precisar de controle sobre quando ou se os argumentos de um formulário serão avaliados. Você vai querer estar familiarizado com Clojure. Certifique-se de entender tudo em -[Clojure em Y Minutos](/docs/clojure/). +[Aprenda Clojure em Y Minutos](/docs/clojure/). ```clojure -;; Defina uma macro utilizando defmacro. Sua macro deve ter como saida uma lista que possa -;; ser avaliada como codigo Clojure. +;; Defina uma macro utilizando defmacro. Sua macro deve ter como saída uma lista que possa +;; ser avaliada como código Clojure. ;; ;; Essa macro é a mesma coisa que se você escrever (reverse "Hello World") (defmacro my-first-macro [] @@ -33,14 +33,14 @@ Você vai querer estar familiarizado com Clojure. Certifique-se de entender tudo (macroexpand '(my-first-macro)) ;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World") -;; Você pode avaliar o resultad de macroexpand diretamente: +;; Você pode avaliar o resultado de macroexpand diretamente: (eval (macroexpand '(my-first-macro))) ; -> (\d \l \o \r \W \space \o \l \l \e \H) -;; mas você deve usar esse mais suscinto, sintax como de função: +;; mas você deve usar essa sintaxe mais sucinta e familiar a funções: (my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H) -;; Você pode tornar as coisas mais faceis pra você, utilizando a sintaxe de citação mais suscinta +;; Você pode tornar as coisas mais fáceis pra você, utilizando a sintaxe de citação mais suscinta ;; para criar listas nas suas macros: (defmacro my-first-quoted-macro [] '(reverse "Hello World")) diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown index 409394f2..e40b8fe7 100644 --- a/pt-br/clojure-pt.html.markdown +++ b/pt-br/clojure-pt.html.markdown @@ -5,12 +5,13 @@ contributors: - ["Adam Bard", "http://adambard.com/"] translators: - ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"] + - ["Ygor Sad", "https://github.com/ysads"] 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. +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 diversos recursos [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) para lidar com estado e mutabilidade, caso isso seja necessário. -Essa combinação permite gerenciar processamento concorrente de maneira muito simples, e frequentemente de maneira automática. +Essa combinação permite gerenciar processamento concorrente de maneira muito simples - frequentemente, de modo automático. (Sua versão de clojure precisa ser pelo menos 1.2) @@ -18,369 +19,551 @@ Essa combinação permite gerenciar processamento concorrente de maneira muito s ```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. +; Código Clojure é escrito em formas - 'forms', em inglês. Tais estruturas são +; simplesmente listas de valores encapsuladas 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. +; Ao interpretar um código em Clojure, o interpretador ou leitor - do inglês 'reader' - assume +; que o primeiro valor dentro de uma forma é uma função ou macro, de modo que os demais valores +; são seus argumentos. Isso se deve ao fato de que Clojure, por ser uma derivação de Lisp, +; usa notação prefixa (ou polonesa). -: A primeira chamada de um arquivo deve ser ns, para configurar o namespace (espaço de nomes) +; Num arquivo, a primeira chamada deve ser sempre para a função ns, +; que é responsável por definir em qual namespace o código em questão +; deve ser alocado (ns learnclojure) ; Alguns exemplos básicos: -; str cria uma string concatenando seus argumentos -(str "Hello" " " "World") ; => "Hello World" +; Aqui, str é uma função e "Olá" " " e "Mundo" são seus argumentos. O que ela faz é criar +; uma string concatenando seus argumentos. +(str "Olá" " " "Mundo") ; => "Olá Mundo" -; Cálculos são feitos de forma direta e intuitiva +; Note que espaços em branco separam os argumentos de uma função. Opcionalmente vírgulas +; podem ser usadas, se você quiser. +(str, "Olá", " ", "Mundo") ; => "Olá Mundo" + +; As operações matemáticas básicas usam os operadores de sempre (+ 1 1) ; => 2 (- 2 1) ; => 1 (* 1 2) ; => 2 (/ 2 1) ; => 2 -; Você pode comparar igualdade utilizando = +; Esses operadores aceitam um número arbitrário de argumentos +(+ 2 2 2) ; = 2 + 2 + 2 => 6 +(- 5 1 1) ; = 5 - 1 - 1 => 3 +(* 3 3 3 3) ; = 3 * 3 * 3 * 3 => 81 + +; Para verificar se dois valores são iguais, o operador = pode ser usado (= 1 1) ; => true (= 2 1) ; => false -; Negação para operações lógicas -(not true) ; => false +; Para saber se dois valores são diferentes +(not= 1 2) ; => true +(not (= 1 2)) ; => true -; Aninhar "forms" funciona como esperado +; Conforme vimos acima, é possível aninhar duas formas (+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 +(* (- 3 2) (+ 1 2)) ; = (3 - 2) * (1 + 2) => 3 + +; Se a leitura ficar comprometida, as fórmulas também podem ser escritas em múltiplas linhas +(* (- 3 2) + (+ 1 2)) ; => 3 +(* + (- 3 2) + (+ 1 2)) ; => 3 + ; 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 +; Por ter interoperabilidade com Java, Clojure usa os tipos de objetos de Java para booleanos, +; strings e números. Para descobrir qual o tipo de um valor, você pode usar a função `class`: +(class 1234) ; Literais Integer são java.lang.Long por padrão +(class 1.50) ; Literais Float são java.lang.Double +(class "oi") ; Strings sempre usam 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))) +; Tenha cuidado, ao dividir valores inteiros: +(= (/ 1 2) + (/ 1.0 2.0)) ; => false + +(class (/ 1 2)) ; => clojure.lang.Ratio +(class (/ 1.0 2.0)) ; => java.lang.Double + +; Aqui temos uma diferença em relação a Java, pois valores nulos são representados por `nil` +(class nil) ; nil -; É 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 +; Os dois tipos básicos de coleção são listas - "list" em inglês - e vetores - "vectors" +; no original. A principal diferença entre eles se +; dá pela implementação: +; - Vetores são implementados como arrays +; - Listas são listas ligadas +(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) +; Outra forma de declarar listas é usando a função list +(list 1 2 3) ; => '(1 2 3) -; "Coleções" são apenas grupos de dados -; Listas e vetores são ambos coleções: +; Clojure classifica conjuntos de dados de duas maneiras + +; "Coleções" são grupos simples de dados +; Tanto listas quanto vetores são 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. +; Sequências - ou seqs - são conjuntos de dados com avaliação "lazy" +; 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) +; Ter avaliação lazy significa que uma seq somente precisa prover uma informação quando +; ela for requisitada. Isso permite às seqs representar listas infinitas. +(range) ; => (0 1 2 3 4 ...) +(cycle [1 2]) ; => (1 2 1 2 1 2 ...) +(take 4 (range)) ; => (0 1 2 3) -; Use cons para adicionar um item no início de uma lista ou vetor +; A função cons é usada para adicionar um item ao 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. +; Já conj adiciona um item em uma coleção sempre do jeito mais eficiente. +; Em listas, isso significa inserir no início. Já em vetores, ao 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 +; Concatenação de coleções pode ser feita usando concat. Note que ela sempre gera uma +; seq como resultado e está sujeita a problemas de perfomance em coleções grandes, por +; conta da natureza lazy das seqs. +(concat '(1 2) [3 4]) ; => (1 2 3 4) (concat [1 2] '(3 4)) ; => (1 2 3 4) -; Use filter, map para interagir com coleções +; Outra forma de concatenar coleções é usando into. Ela não está sujeita a problemas +; com a avaliação lazy, mas o resultado final da ordem e do tipo dos argumentos passados +(into [1 2] '(3 4)) ; => [1 2 3 4] +(into '(1 2) [3 4]) ; => (4 3 1 2) + +; Note que em into a ordem dos parâmetros influencia a coleção final. +(into [1 2] '(3 4)) ; => (1 2 3 4) +(into '(1 2) [3 4]) ; => (4 3 1 2) + +; As funções filter e map podem ser usadas para interagir com as coleções. Repare que +; elas sempre retornam seqs, independentemente do tipo do seu argumento. (map inc [1 2 3]) ; => (2 3 4) -(filter even? [1 2 3]) ; => (2) +(filter even? [1 2 3 4]) ; => (2 4) + +; Use reduce reduzir coleções a um único valor. Também é possível passar um argumento +; para o valor inicial das operações +(reduce + [1 2 3]) ; = (+ (+ (+ 1 2) 3) 4) => 10 +(reduce + 10 [1 2 3 4]) ; = (+ (+ (+ (+ 10 1) 2) 3) 4) => 20 +(reduce conj [] '(3 2 1)) ; = (conj (conj (conj [] 3) 2) 1) => [3 2 1] + +; Reparou na semelhança entre listas e as chamadas de código Clojure? Isso se deve ao +; fato de que todo código clojure é escrito usando listas. É por isso que elas sempre +; são declaradas com o caracter ' na frente. Dessa forma o interpretador não tenta +; avaliá-las. +'(+ 2 3) ; cria uma lista com os elementos +, 2 e 3 +(+ 2 3) ; o interpretador chama a função + passando como argumentos 2 e 3 -; Use reduce para reduzi-los -(reduce + [1 2 3 4]) -; = (+ (+ (+ 1 2) 3) 4) -; => 10 +; Note que ' é apenas uma abreviação para a função quote. +(quote (1 2 3)) ; => '(1 2 3) + +; É possível passar uma lista para que o interpretador a avalie. Note que isso está +; sujeito ao primeiro elemento da lista ser um literal com um nome de uma função válida. +(eval '(+ 2 3)) ; => 5 +(eval '(1 2 3)) ; dá erro pois o interpretador tenta chamar a função 1, que não existe -; 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 +; Use fn para criar novas funções. Uma função sempre retorna sua última expressão. +(fn [] "Olá Mundo") ; => fn + +; Para executar suas funções, é preciso chamá-las, envolvendo-as em parênteses. +((fn [] "Olá Mundo")) ; => "Olá Mundo" + +; Como isso não é muito prático, você pode nomear funções atribuindo elas a literais. +; Isso torna muito mais fácil chamá-las: +(def ola-mundo (fn [] "Olá Mundo")) ; => fn +(ola-mundo) ; => "Olá Mundo" -; (É necessário colocar parênteses para chamá-los) -((fn [] "Hello World")) ; => "Hello World" +; Você pode abreviar esse processo usando defn: +(defn ola-mundo [] "Olá Mundo") -; Você pode atribuir valores a variáveis utilizando def -(def x 1) -x ; => 1 +; Uma função pode receber uma lista de argumentos: +(defn ola + [nome] + (str "Olá " nome)) +(ola "Jonas") ; => "Olá Jonas" -; Atribua uma função para uma var -(def hello-world (fn [] "Hello World")) -(hello-world) ; => "Hello World" +; É possível criar funções que recebam multivariadas, isto é, que aceitam números +; diferentes de argumentos: +(defn soma + ([] 0) + ([a] a) + ([a b] (+ a b))) -; Você pode abreviar esse processo usando defn -(defn hello-world [] "Hello World") +(soma) ; => 0 +(soma 1) ; => 1 +(soma 1 2) ; => 3 -; O [] é uma lista de argumentos para um função. -(defn hello [name] - (str "Hello " name)) -(hello "Steve") ; => "Hello Steve" +; Funções podem agrupar argumentos extras em uma seq: +(defn conta-args + [& args] + (str "Você passou " (count args) " argumentos: " args)) +(conta-args 1 2 3 4) ; => "Você passou 4 argumentos: (1 2 3 4)" -; Você pode ainda usar essa abreviação para criar funcões: -(def hello2 #(str "Hello " %1)) -(hello2 "Fanny") ; => "Hello Fanny" +; Você pode misturar argumentos regulares e argumentos em seq: +(defn ola-e-conta + [nome & args] + (str "Olá " nome ", você passou " (count args) " argumentos extras")) +(ola-e-conta "Maria" 1 2 3 4) ; => "Olá Maria, você passou 4 argumentos extras" -; 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)" +; Nos exemplos acima usamos def para associar nomes a funções, mas poderíamos usá-lo +; para associar nomes a quaisquer valores: +(def xis :x) +xis ; => :x -; 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" +; Inclusive, tais literais podem possuir alguns caracteres não usuais em outras linguagens: +(def *num-resposta* 42) +(def conexao-ativa? true) +(def grito-de-medo! "AAAAAAA") +(def ->vector-vazio []) + +; É possível, inclusive, criar apelidos a nomes que já existem: +(def somar! soma) +(somar! 41 1) ; => 42 + +; Uma forma rápida de criar funções é por meio de funções anônimas. Elas são ótimas +; para manipulação de coleções e seqs, já que podem ser passadas para map, filter +; e reduce. Nessas funções, % é substituído por cada um dos items na seq ou na coleção: +(filter #(not= % nil) ["Joaquim" nil "Maria" nil "Antônio"]) ; => ("Joaquim" "Maria" "Antônio") +(map #(* % (+ % 2)) [1 2]) ; => (3 8) ; 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. +; Existem dois tipos de mapas: hash maps e array maps. Ambos compartilham uma mesma +; interface e funções. Hash maps são mais rápidos para retornar dados, mas não mantém +; as chaves ordenadas. (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 +; Clojure converte automaticamente array maps em hash maps, por meio da maioria das +; funções de manipulação de mapas, caso eles fiquem grandes o suficiente. Não é +; preciso se preocupar com isso. - -; 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. +; Chaves podem ser qualquer valor do qual possa ser obtido um hash, mas normalmente +; usam-se keywords como chave, por possuírem algumas vantagens. (class :a) ; => clojure.lang.Keyword -(def stringmap {"a" 1, "b" 2, "c" 3}) -stringmap ; => {"a" 1, "b" 2, "c" 3} +; Keywords são como strings, porém, duas keywords de mesmo valor são sempre armazenadas +; na mesma posição de memória, o que as torna mais eficientes. +(identical? :a :a) ; => true +(identical? (String. "a") (String. "a")) ; => false -(def keymap {:a 1, :b 2, :c 3}) -keymap ; => {:a 1, :c 3, :b 2} +(def mapa-strings {"a" 1 "b" 2 "c" 3}) +mapa-strings ; => {"a" 1, "b" 2, "c" 3} -; A propósito, vírgulas são sempre tratadas como espaçoes em branco e não fazem nada. +(def mapa-keywords {:a 1 :b 2 :c 3}) +mapa-keywords ; => {:a 1, :c 3, :b 2} -; Recupere o valor de um mapa chamando ele como uma função -(stringmap "a") ; => 1 -(keymap :a) ; => 1 +; Você pode usar um mapa como função para recuperar um valor dele: +(mapa-strings "a") ; => 1 +(mapa-keywords :a) ; => 1 -; Uma palavra-chave pode ser usada pra recuperar os valores de um mapa -(:b keymap) ; => 2 +; Se a chave buscada for uma keyword, ela também pode ser usada como função para recuperar +; valores. Note que isso não funciona com strings. +(:b mapa-keywords) ; => 2 +("b" mapa-strings) ; => java.lang.String cannot be cast to clojure.lang.IFn -; Não tente isso com strings -;("a" stringmap) -; => Exception: java.lang.String cannot be cast to clojure.lang.IFn +; Se você buscar uma chave que não existe, Clojure retorna nil: +(mapa-strings "d") ; => nil -; Buscar uma chave não presente retorna nil -(stringmap "d") ; => nil +; Use assoc para adicionar novas chaves em um mapa. +(def mapa-keywords-estendido (assoc mapa-keywords :d 4)) +mapa-keywords-estendido ; => {:a 1, :b 2, :c 3, :d 4} -; 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 que tipos em Clojure são sempre imutáveis! Isso significa que o mapa +; inicial continua com as mesmas informações e um novo mapa, com mais dados, é criado +; a partir dele +mapa-keywords ; => {:a 1, :b 2, :c 3} -; Mas lembre-se, tipos em Clojure são sempre imutáveis! -keymap ; => {:a 1, :b 2, :c 3} +; assoc também pode ser usado para atualizar chaves: +(def outro-mapa-keywords (assoc mapa-keywords :a 0)) +outro-mapa-keywords ; => {:a 0, :b 2, :c 3} ; Use dissoc para remover chaves -(dissoc keymap :a :b) ; => {:c 3} +(dissoc mapa-keywords :a :b) ; => {:c 3} + +; Mapas também são coleções - mas não seqs! +(coll? mapa-keywords) ; => true +(seq? mapa-keywords) ; => false + +; É possível usar filter, map e qualquer outra função de coleções em mapas. +; Porém a cada iteração um vetor no formato [chave valor] vai ser passado como +; argumento. Por isso é conveniente usar funções anônimas. +(filter #(odd? (second %)) mapa-keywords) ; => ([:a 1] [:c 3]) +(map #(inc (second %)) mapa-keywords) ; => (2 3 4) ; Conjuntos ;;;;;; -(class #{1 2 3}) ; => clojure.lang.PersistentHashSet +; Conjuntos são um tipo especial de coleções que não permitem elementos repetidos. +; Eles podem ser criados com #{} ou com a função set. (set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} +(class #{1 2 3}) ; => clojure.lang.PersistentHashSet -; Adicione um membro com conj -(conj #{1 2 3} 4) ; => #{1 2 3 4} +; Note que nem sempre um set vai armazenar seus elementos na ordem esperada. +(def meu-conjunto #{1 2 3}) +meu-conjunto ; => #{1 3 2} -; Remova um membro com disj -(disj #{1 2 3} 1) ; => #{2 3} +; Adição funciona normalmente com conj. +(conj meu-conjunto 4) ; => #{1 4 3 2} -; Test por existência usando set como função: -(#{1 2 3} 1) ; => 1 -(#{1 2 3} 4) ; => nil +; Remoção, no entanto, precisa ser feita com disj: +(disj meu-conjunto 1) ; => #{3 2} -; Existem muitas outras funções no namespace clojure.sets +; Para saber se um elemento está em um conjunto, use-o como função. Nesse aspecto +; conjuntos funcionam de maneira semelhante a mapas. +(meu-conjunto 1) ; => 1 +(meu-conjunto 4) ; => nil -; 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 +; Condicionais e blocos +;;;;;;;;;;;;;;;;; -; Use let para criar um novo escopo associando sîmbolos a valores (bindings) +; Você pode usar um bloco let para criar um escopo local, no qual estarão disponíveis +; os nomes que você definir: (let [a 1 b 2] - (> a b)) ; => false + (+ a b)) ; => 3 -; Agrupe comandos juntos com "do" -(do - (print "Hello") - "World") ; => "World" (prints "Hello") +(let [cores {:yellow "Amarelo" :blue "Azul"} + nova-cor :red + nome-cor "Vermelho"] + (assoc cores nova-cor nome-cor)) ; => {:yellow "Amarelo", :blue "Azul", :red "Vermelho"} -; 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") +; Formas do tipo if aceitam três argumentos: a condição de teste, o comando a ser +; executado caso a condição seja positiva; e o comando para o caso de ela ser falsa. +(if true "a" "b") ; => "a" +(if false "a" "b") ; => "b" + +; Opcionalmente você pode não passar o último argumento, mas se a condição for falsa +; o if vai retornar nil. +(if false "a") ; => nil + +; A forma if somente aceita um comando para ser executado em cada caso. Se você +; precisar executar mais comandos, você pode usar a função do: +(if true + (do + (print "Olá ") + (print "Mundo"))) ; => escreve "Olá Mundo" na saída + +; Se você só deseja tratar o caso de sua condição ser verdadeira, o comando when é +; uma alternativa melhor. Seu comportamento é idêntico a um if sem condição negativa. +; Uma de suas vantagens é permitir a execução de vários comandos sem exigir do: +(when true "a") ; => "a" +(when true + (print "Olá ") + (print "Mundo")) ; => também escreve "Olá Mundo" na saída + +; Isso ocorre porque when possui um bloco do implícito. O mesmo se aplica a funções e +; comandos let: +(defn escreve-e-diz-xis + [nome] + (print "Diga xis, " nome) + (str "Olá " nome)) +(escreve-e-diz-xis "João") ;=> "Olá João", além de escrever "Diga xis, João" na saída. + +(let [nome "Nara"] + (print "Diga xis, " nome) + (str "Olá " nome)) ;=> "Olá João", além de escrever "Diga xis, João" na saída. -; 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 +; Você pode usar a função use para carregar todas as funções de um módulo. (use 'clojure.set) -; Agora nós podemos usar operações com conjuntos +; Agora nós podemos usar operações de conjuntos definidas nesse módulo: (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 +; Isso porém não é uma boa prática pois dificulta saber de qual módulo cada função +; veio, além de expor o código a conflitos de nomes, caso dois módulos diferentes +; definam funções com o mesmo nome. A melhor forma de referenciar módulos é por meio +; de require: (require 'clojure.string) -; Use / para chamar funções de um módulo +; Com isso podemos chamar as funções de clojure.string usando o operador / ; 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 +; Porém isso não é muito prático, por isso é possível dar para um nome mais curto para +; o módulo ao carregá-lo: (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) +(str/replace "alguém quer teste?" #"[aeiou]" str/upper-case) ; => "AlgUém qUEr tEstE?" -; 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. +; Nesse exemplo usamos também a construção #"", que delimita uma expressão regular. + +; É possível carregar outros módulos direto na definição do namespace. Note que nesse +; contexto não é preciso usar ' antes do vetor que define a importação do módulo. (ns test (:require [clojure.string :as str] [clojure.set :as set])) + +; Operadores thread +;;;;;;;;;;;;;;;;; + +; Uma das funções mais interessantes de clojure são os operadores -> e ->> - respectivamente +; thread-first e thread-last macros. Elas permitem o encadeamento de chamadas de funções, +; sendo perfeitas para melhorar a legibilidade em transformações de dados. + +; -> usa o resultado de uma chamada como o primeiro argumento da chamada à função seguinte: +(-> " uMa StRIng com! aLG_uNs ##problemas. " + (str/replace #"[!#_]" "") + (str/replace #"\s+" " ") + str/trim ; se a função só aceitar um argumento, não é preciso usar parênteses + (str/lower-case)) ; => "uma string com alguns problemas." + +; Na thread uma string com vários problemas foi passada como primeiro argumento à função +; str/replace, que criou uma nova string, a partir da original, porém somente com caracteres +; alfabéticos. Essa nova string foi passada como primeiro argumento para a chamada str/replace +; seguinte, que criou uma nova string sem espaços duplos. Essa nova string foi então passada +; como primeiro argumento para str/trim, que removeu espaços de seu início e fim, passando essa +; última string para str/lower-case, que a converteu para caracteres em caixa baixa. + +; ->> é equivalente a ->, porém o retorno de cada função é passado como último argumento da +; função seguinte. Isso é particularmente útil para lidar com seqs, já que as funções que +; as manipulam sempre as tomam como último argumento. +(->> '(1 2 3 4) + (filter even?) ; => '(2 4) + (map inc) ; => '(3 5) + (reduce *)) ; => 15 + + ; Java ;;;;;;;;;;;;;;;;; -; Java tem uma biblioteca padrão enorme e muito útil, -; portanto é importante aprender como utiliza-la. +; A biblioteca padrão de Java é enorme e possui inúmeros algoritmos e estruturas de +; dados já implementados. Por isso é bastante conveniente saber como usá-la dentro +; de Clojure. -; Use import para carregar um modulo java +; Use import para carregar um módulo Java. (import java.util.Date) -; Você pode importar usando ns também. +; Você pode importar classes Java dentro de ns também: (ns test (:import java.util.Date - java.util.Calendar)) + java.util.Calendar + java.util.ArrayList)) ; Use o nome da clase com um "." no final para criar uma nova instância -(Date.) ; <a date object> +(def instante (Date.)) +(class instante) => ; java.util.Date + +; Para chamar um método, use o operador . com o nome do método. Outra forma é +; usar simplesmente .<nome do método> +(. instante getTime) ; => retorna um inteiro representando o instante +(.getTime instante) ; => exatamente o mesmo que acima -; Use . para chamar métodos. Ou, use o atalho ".method" -(. (Date.) getTime) ; <a timestamp> -(.getTime (Date.)) ; exatamente a mesma coisa. +; Para chamar métodos estáticos dentro de classes Java, use / +(System/currentTimeMillis) ; => retorna um timestamp -; Use / para chamar métodos estáticos -(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente) +; Note que não é preciso importar o módulo System, pois ele está sempre presente + +; Caso queira submeter uma instância de uma classe mutável a uma sequência de operações, +; você pode usar a função doto. Ela é funciona de maneira semelhante à função -> - ou +; thread-first -, exceto pelo fato de que ele opera com valores mutáveis. +(doto (java.util.ArrayList.) + (.add 11) + (.add 3) + (.add 7) + (java.util.Collections/sort)) ; => #<ArrayList [3, 7, 11]> -; 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. +; Até aqui usamos def para associar nomes a valores. Isso, no entanto, possui algumas +; limitações, já que, uma vez definido essa associação, não podemos alterar o valor +; para o qual um nome aponta. Isso significa que nomes definidos com def não se +; comportam como as variáveis de outras linguagens. + +; Para lidar com estado persistente e mutação de valores, Clojure usa o mecanismo Software +; Transactional Memory. O atom é o mais simples de todos. Passe pra ele um valor inicial e +; e ele criará um objeto que é seguro de atualizar: +(def atom-mapa (atom {})) + +; Para acessar o valor de um atom, você pode usar a função deref ou o operador @: +@atom-mapa ; => {} +(deref atom-mapa) ; => {} -; O atom é o mais simples. Passe pra ele um valor inicial -(def my-atom (atom {})) +; Para mudar o valor de um atom, você deve usar a função swap! +; O que ela faz é chamar a função passada usando o atom como seu primeiro argumento. Com +; isso, ela altera o valor do atom de maneira segura. +(swap! atom-mapa assoc :a 1) ; Atribui a atom-mapa o resultado de (assoc {} :a 1) +(swap! atom-mapa assoc :b 2) ; Atribui a atom-mapa o resultado de (assoc {:a 1} :b 2) -; Atualize o atom com um swap!. -; swap! pega uma função e 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) +; Observe que essas chamadas alteraram de fato o valor de atom-mapa. Seu novo valor é: +@atom-mapa ; => {: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} +; Isso é diferente de fazer: +(def atom-mapa-2 (atom {})) +(def atom-mapa-3 (assoc @atom-mapa-2 :a 1)) -; Abaixo um contador simples usando um atom -(def counter (atom 0)) -(defn inc-counter [] - (swap! counter inc)) +; Nesse exemplo, atom-mapa-2 permanece com o seu valor original e é gerado um novo mapa, +; atom-mapa-3, que contém o valor de atom-mapa-2 atualizado. Note que atom-mapa-3 é um +; simples mapa, e não uma instância de um atom +@atom-mapa-2 ; => {} +atom-mapa-3 ; => {:a 1} -(inc-counter) -(inc-counter) -(inc-counter) -(inc-counter) -(inc-counter) +(class atom-mapa-2) ; => clojure.lang.Atom +(class atom-mapa-3) ; => clojure.lang.PersistentArrayMap -@counter ; => 5 +; A ideia é que o valor do atom só será atualizado se, após ser executada a função passada +; para swap!, o atom ainda estiver com o mesmo valor de antes. Isto é, se durante a execução +; da função alguém alterar o valor do atom, swap! reexecutará a função recebida usando o valor +; atual do átoma como argumento. -; Outras construção STM são refs e agents. +; Isso é ótimo em situações nas quais é preciso garantir a consistência de algum valor - tais +; como sistemas bancários e sites de compra. Para mais exemplos e informações sobre outras +; construções STM: + +; Exemplos e aplicações: https://www.braveclojure.com/zombie-metaphysics/ ; 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. +Esse tutorial está longe de ser completo, mas deve ser suficiente para que você possa dar seus primeiros passos em Clojure. +Caso queira aprender mais: -Clojure.org tem vários artigos: +* 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): +* Brave Clojure possui um e-book que explora em profundidade diversos recursos de clojure, incluindo ótimos exemplos: +[https://www.braveclojure.com/](https://www.braveclojure.com/) + +* 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: +* 4clojure possui alguns problemas e desafios interessantes para quem quiser treinar clojure ou programação funcional: [http://www.4clojure.com/](http://www.4clojure.com/) -Clojure-doc.org tem um bom número de artigos para iniciantes: +* clojure-doc.org tem um bom número de artigos para iniciantes: [http://clojure-doc.org/](http://clojure-doc.org/) Clojure for the Brave and True é um livro de introdução ao Clojure e possui uma versão gratuita online: diff --git a/pt-br/pascal-pt.html.markdown b/pt-br/pascal-pt.html.markdown index 82cce843..72302695 100644 --- a/pt-br/pascal-pt.html.markdown +++ b/pt-br/pascal-pt.html.markdown @@ -4,6 +4,7 @@ filename: learnpascal-pt.pas contributors: - ["Ganesha Danu", "https://github.com/blinfoldking"] - ["Keith Miyake", "https//github.com/kaymmm"] + - ["Raul Almeida", "https://github.com/almeidaraul"] translators: - ["Raul Almeida", "https://github.com/almeidaraul"] lang: pt-br diff --git a/pt-br/vim-pt.html.markdown b/pt-br/vim-pt.html.markdown index d7617bbe..cc304381 100644 --- a/pt-br/vim-pt.html.markdown +++ b/pt-br/vim-pt.html.markdown @@ -5,6 +5,7 @@ contributors: - ["RadhikaG", "https://github.com/RadhikaG"] translators: - ["David Lima", "https://github.com/davelima"] + - ["Raul Almeida", "https://github.com/almeidaraul"] lang: pt-br filename: LearnVim-pt.txt --- @@ -24,6 +25,7 @@ para agilizar a navegação para pontos específicos no arquivo, além de ediç :w # Salva o arquivo atual :wq # Salva o arquivo e fecha o vim :q! # Fecha o vim e descarta as alterações no arquivo + # ! depois de qualquer comando força a sua execução # ! *força* :q a executar, fechando o vim sem salvar antes :x # Salva o arquivo e fecha o vim (atalho para :wq) @@ -158,7 +160,15 @@ Alguns exemplos importantes de 'Verbos', 'Modificadores' e 'Nomes': :earlier 15m # Reverte o documento para como ele estava há 15 minutos atrás :later 15m # Reverte o comando acima ddp # Troca linhas consecutivas de posição, dd e depois p + xp # Permuta caractere atual e o seguinte + Xp # Permuta caractere atual e o anterior . # Repete a última ação + + # Em geral, o usuário pode associar um comando em maísculas (exemplo: D) com + # "executar este comando até o final da linha" + + # Usar a tecla de um comando duas vezes geralmente significa executar este + # comando sobre toda a linha (exemplo: dd apaga a linha inteira) ``` ## Macros @@ -172,6 +182,7 @@ exatamente a mesma sequencia de ações e comandos na seleção atual. qa # Inicia a gravação de uma macro chamado 'a' q # Para a gravação @a # Executa a macro + @@ # Executa a última macro executada ``` ### Configurando o ~/.vimrc diff --git a/python3.html.markdown b/python3.html.markdown index 6e8d2460..20377801 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -58,11 +58,12 @@ Note: This article applies to Python 3 specifically. Check out [here](http://lea 2**3 # => 8 # Enforce precedence with parentheses +1 + 3 * 2 # => 7 (1 + 3) * 2 # => 8 # Boolean values are primitives (Note: the capitalization) -True -False +True # => True +False # => False # negate with not not True # => False diff --git a/sass.html.markdown b/sass.html.markdown index 224db80e..860e550a 100644 --- a/sass.html.markdown +++ b/sass.html.markdown @@ -16,7 +16,7 @@ This tutorial is written using SCSS. If you're already familiar with CSS3, you'll be able to pick up Sass relatively quickly. It does not provide any new styling properties but rather the tools to write your CSS more efficiently and make maintenance much easier. -```sass +```scss //Single line comments are removed when Sass is compiled to CSS. diff --git a/swift.html.markdown b/swift.html.markdown index 1f9fe897..689c5191 100644 --- a/swift.html.markdown +++ b/swift.html.markdown @@ -692,6 +692,11 @@ print(mySquare.sideLength) // 4 // cast instance let aShape = mySquare as Shape +// downcast instance: +// Because downcasting can fail, the result can be an optional (as?) or an implicitly unwrpped optional (as!). +let anOptionalSquare = aShape as? Square // This will return nil if aShape is not a Square +let aSquare = aShape as! Square // This will throw a runtime error if aShape is not a Square + // compare instances, not the same as == which compares objects (equal to) if mySquare === mySquare { print("Yep, it's mySquare") @@ -904,7 +909,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { } return nil } -findIndex(array: [1, 2, 3, 4], valueToFind: 3) // 2 +findIndex(array: [1, 2, 3, 4], valueToFind: 3) // Optional(2) // You can extend types with generics as well extension Array where Array.Element == Int { diff --git a/wasm.html.markdown b/wasm.html.markdown index 98bfc000..aba2084f 100644 --- a/wasm.html.markdown +++ b/wasm.html.markdown @@ -222,6 +222,91 @@ contributors: ) ) (export "apply_cos64" (func $apply_cos64)) + + ;; Wasm is a stack-based language, but for returning values more complicated + ;; than an int/float, a separate memory stack has to be manually managed. One + ;; approach is to use a mutable global to store the stack_ptr. We give + ;; ourselves 1MiB of memstack and grow it downwards. + ;; + ;; Below is a demonstration of how this C code **might** be written by hand + ;; + ;; typedef struct { + ;; int a; + ;; int b; + ;; } sum_struct_t; + ;; + ;; sum_struct_t sum_struct_create(int a, int b) { + ;; return (sum_struct_t){a, b}; + ;; } + ;; + ;; int sum_local() { + ;; sum_struct_t s = sum_struct_create(40, 2); + ;; return s.a + s.b; + ;; } + + ;; Unlike C, we must manage our own memory stack. We reserve 1MiB + (global $memstack_ptr (mut i32) (i32.const 65536)) + + ;; Structs can only be returned by reference + (func $sum_struct_create + (param $sum_struct_ptr i32) + (param $var$a i32) + (param $var$b i32) + ;; c// sum_struct_ptr->a = a; + (i32.store + (get_local $sum_struct_ptr) + (get_local $var$a) + ) + + ;; c// sum_struct_ptr->b = b; + (i32.store offset=4 + (get_local $sum_struct_ptr) + (get_local $var$b) + ) + ) + + (func $sum_local (result i32) + (local $var$sum_struct$a i32) + (local $var$sum_struct$b i32) + (local $local_memstack_ptr i32) + + ;; reserve memstack space + (i32.sub + (get_global $memstack_ptr) + (i32.const 8) + ) + tee_local $local_memstack_ptr ;; tee both stores and returns given value + set_global $memstack_ptr + + ;; call the function, storing the result in the memstack + (call $sum_struct_create + ((;$sum_struct_ptr=;) get_local $local_memstack_ptr) + ((;$var$a=;) i32.const 40) + ((;$var$b=;) i32.const 2) + ) + + ;; retrieve values from struct + (set_local $var$sum_struct$a + (i32.load offset=0 (get_local $local_memstack_ptr)) + ) + (set_local $var$sum_struct$b + (i32.load offset=4 (get_local $local_memstack_ptr)) + ) + + ;; unreserve memstack space + (set_global $memstack_ptr + (i32.add + (get_local $local_memstack_ptr) + (i32.const 8) + ) + ) + + (i32.add + (get_local $var$sum_struct$a) + (get_local $var$sum_struct$b) + ) + ) + (export "sum_local" (func $sum_local)) ) ``` diff --git a/zh-cn/powershell-cn.html.markdown b/zh-cn/powershell-cn.html.markdown new file mode 100644 index 00000000..6ab34e9f --- /dev/null +++ b/zh-cn/powershell-cn.html.markdown @@ -0,0 +1,325 @@ +--- +category: tool +tool: powershell +contributors: + - ["Wouter Van Schandevijl", "https://github.com/laoujin"] +translators: + - ["Feng Gao", "https://github.com/gaufung"] +filename: LearnPowershell-cn.ps1 +lang: zh-cn +--- + +PowerShell 是 Windows 平台下的脚本语言同时也是配置管理框架,它是建立在微软 .Net Framework 之上,Windows 7 以及之后版本都内置 Poweshell。下面的示例中都是 PoweShell 脚本的一部分或者直接能够在 Shell 交互窗口中执行。 + +与 Bash 最大的不同是你大部分操作的东西是对象而不是普通的文本。 + +[延伸阅读](https://technet.microsoft.com/en-us/library/bb978526.aspx) + +如果你不确定你的环境,执行如下操作: + +```powershell +Get-ExecutionPolicy -List +Set-ExecutionPolicy AllSigned +# Execution Policy 包含以下: +# - Restricted: 不会运行脚本。 +# - RemoteSigned: 只会运行受信任的发行商下载的脚本。 +# - AllSigned: 运行需要被信任发行商签名的脚本。 +# - Unrestricted: 运行所有脚本 +help about_Execution_Policies # 查看更多信息 + +# 当前 PowerShell 版本 +$PSVersionTable +``` + +获取帮助 + +```powershell +# 查找命令 +Get-Command about_* # 别名: gcm +Get-Command -Verb Add +Get-Alias ps +Get-Alias -Definition Get-Process + +Get-Help ps | less # 别名: help +ps | Get-Member # 别名: gm + +Show-Command Get-EventLog # GUI 填充参数 + +Update-Help # 管理员运行 +``` + +接下来是教程 + +```powershell +# 正如你看到的,每一行开头是 # 都是注释 + +# 简单的 Hello World 实例 +echo Hello world! +# echo 是 Write-Output (cmdlet) 的别名 +# 大部分 cmdlet 和函数都遵循 "动词-名词" 命名规则。 + +# 每个命令都从新的一行开始或者是一个分号 +echo 'This is the first line'; echo 'This is the second line' + +# 声明一个变量如下: +$aString="Some string" +# 或者像这样: +$aNumber = 5 -as [double] +$aList = 1,2,3,4,5 +$anEmptyList = @() +$aString = $aList -join '--' # 也包含 join 方法 +$aHashtable = @{name1='val1'; name2='val2'} + +# 使用变量: +echo $aString +echo "Interpolation: $aString" +echo "$aString has length of $($aString.Length)" +echo '$aString' +echo @" +This is a Here-String +$aString +"@ +# 注意 ' (单引号) 不是变量的一部分 +# 在这里字符串也可以是单引号 + +# 内置变量: +# 下面是一些有用的内置变量,比如: +echo "Booleans: $TRUE and $FALSE" +echo "Empty value: $NULL" +echo "Last program's return value: $?" +echo "Exit code of last run Windows-based program: $LastExitCode" +echo "The last token in the last line received by the session: $$" +echo "The first token: $^" +echo "Script's PID: $PID" +echo "Full path of current script directory: $PSScriptRoot" +echo 'Full path of current script: ' + $MyInvocation.MyCommand.Path +echo "FUll path of current directory: $Pwd" +echo "Bound arguments in a function, script or code block: $PSBoundParameters" +echo "Unbound arguments: $($Args -join ', ')." +# 更多的内置类型: `help about_Automatic_Variables` + +# 内联其他文件 (点操作符) +. .\otherScriptName.ps1 + + +### 控制流 +# 下面是条件判断结构 +if ($Age -is [string]) { + echo 'But.. $Age cannot be a string!' +} elseif ($Age -lt 12 -and $Age -gt 0) { + echo 'Child (Less than 12. Greater than 0)' +} else { + echo 'Adult' +} + +# Switch 语句比其他语言更强大 +$val = "20" +switch($val) { + { $_ -eq 42 } { "The answer equals 42"; break } + '20' { "Exactly 20"; break } + { $_ -like 's*' } { "Case insensitive"; break } + { $_ -clike 's*'} { "clike, ceq, cne for case sensitive"; break } + { $_ -notmatch '^.*$'} { "Regex matching. cnotmatch, cnotlike, ..."; break } + { 'x' -contains 'x'} { "FALSE! -contains is for lists!"; break } + default { "Others" } +} + +# 经典的 For 循环 +for($i = 1; $i -le 10; $i++) { + "Loop number $i" +} +# 或者可以更简洁 +1..10 | % { "Loop number $_" } + +# PowerShell 还提供其他循环方式 +foreach ($var in 'val1','val2','val3') { echo $var } +# while () {} +# do {} while () +# do {} until () + +# 异常处理 +try {} catch {} finally {} +try {} catch [System.NullReferenceException] { + echo $_.Exception | Format-List -Force +} + + +### Providers +# 列出当前目录下的文件和子目录 +ls # 或者 `dir` +cd ~ # 回到主目录 + +Get-Alias ls # -> Get-ChildItem +# 这些 cmdlet 有更加通用的名称,因为它不仅仅只操作当前目录,这一点和其他脚本语言不同。 +cd HKCU: # 跳转 HKEY_CURRENT_USER 注册表中的值 + +# 获取当前会话中的提供者 +Get-PSProvider + + +### 管道 +# Cmdlets 中的参数用来控制它们的行为: +Get-ChildItem -Filter *.txt -Name # 获取所有 txt 文件名。 +# 需要输入足够多的参数来确保没有歧义。 +ls -fi *.txt -n # -f 是不可以的因为 -Force 同样存在。 +# 使用 `Get-Help Get-ChildItem -Full` 来查看全部参数。 + +# 之前 cmdlet 获取的结果输出可以作为一下个输入。 +# `$_` 指代当前管道处理的对象。 +ls | Where-Object { $_.Name -match 'c' } | Export-CSV export.txt +ls | ? { $_.Name -match 'c' } | ConvertTo-HTML | Out-File export.html + +# 如果对管道的对象感到疑惑,使用 `Get-Member` 来查看该对象的可使用的方法和属性。 +ls | Get-Member +Get-Date | gm + +# ` 是行连续标识符,或者在每一行结尾添加一个 | +Get-Process | Sort-Object ID -Descending | Select-Object -First 10 Name,ID,VM ` + | Stop-Process -WhatIf + +Get-EventLog Application -After (Get-Date).AddHours(-2) | Format-List + +# 使用 % 作为 ForEach-Object 的简称。 +(a,b,c) | ForEach-Object ` + -Begin { "Starting"; $counter = 0 } ` + -Process { "Processing $_"; $counter++ } ` + -End { "Finishing: $counter" } + +# Get-Process 返回包含三列的表 +# 第三列是使用 2 位精度数值表示 VM 属性 +# 计算出来的列也可以表示更多的信息: +# `@{name='lbl';expression={$_}` +ps | Format-Table ID,Name,@{n='VM(MB)';e={'{0:n2}' -f ($_.VM / 1MB)}} -autoSize + + +### 函数 +# [string] 注记是可选的。 +function foo([string]$name) { + echo "Hey $name, have a function" +} + +# 调用你的函数 +foo "Say my name" + +# 函数可以包含命名参数、参数的注记和可解析的文档 +<# +.SYNOPSIS +Setup a new website +.DESCRIPTION +Creates everything your new website needs for much win +.PARAMETER siteName +The name for the new website +.EXAMPLE +New-Website -Name FancySite -Po 5000 +New-Website SiteWithDefaultPort +New-Website siteName 2000 # ERROR! Port argument could not be validated +('name1','name2') | New-Website -Verbose +#> +function New-Website() { + [CmdletBinding()] + param ( + [Parameter(ValueFromPipeline=$true, Mandatory=$true)] + [Alias('name')] + [string]$siteName, + [ValidateSet(3000,5000,8000)] + [int]$port = 3000 + ) + BEGIN { Write-Verbose 'Creating new website(s)' } + PROCESS { echo "name: $siteName, port: $port" } + END { Write-Verbose 'Website(s) created' } +} + + +### 都是 .NET +# PS 中的字符串事实上就是 .NET 的 System.String 类型 +# 所有 .NET 方法和属性都可用 +'string'.ToUpper().Replace('G', 'ggg') +# 或者更加 PowerShell 一点 +'string'.ToUpper() -replace 'G', 'ggg' + +# 不确定这样的话 .NET 方法如何调用 +'string' | gm + +# 调用静态 .NET 方法的语法: +[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') + +# 注意 .NET 方法调用必须使用括号,然而 PS 函数调用不能使用括号; +# 如果你调用 cmdlet/PS 函数使用了括号,就相当于传递了参数列表。 +$writer = New-Object System.IO.StreamWriter($path, $true) +$writer.Write([Environment]::NewLine) +$writer.Dispose() + +### IO +# 从输入读入一个值 +$Name = Read-Host "What's your name?" +echo "Hello, $Name!" +[int]$Age = Read-Host "What's your age?" + +# Test-Path, Split-Path, Join-Path, Resolve-Path +# Get-Content filename # 返回字符串数组 string[] +# Set-Content, Add-Content, Clear-Content +Get-Command ConvertTo-*,ConvertFrom-* + + +### 有用的东西 +# 更新 PATH +$env:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + +# 找到 Python 的 PATH +$env:PATH.Split(";") | Where-Object { $_ -like "*python*"} + +# 改变工作目录而不需要记住之前的路径 +Push-Location c:\temp # 改变工作目录至 c:\temp +Pop-Location # 改变到之前的工作目录 +# 别名: pushd 和 popd + +# 在下载之后解除目录阻塞 +Get-ChildItem -Recurse | Unblock-File + +# Windows 资源管理器打开当前目录 +ii . + +# 按任意键退出 +$host.UI.RawUI.ReadKey() +return + +# 创建快捷方式 +$WshShell = New-Object -comObject WScript.Shell +$Shortcut = $WshShell.CreateShortcut($link) +$Shortcut.TargetPath = $file +$Shortcut.WorkingDirectory = Split-Path $file +$Shortcut.Save() +``` + + +配置你的 PowerShell + +```powershell +# $Profile 是文件 `Microsoft.PowerShell_profile.ps1` 完整路径 +# 下面所有的代码都在 PS 会话开始的时候执行 +if (-not (Test-Path $Profile)) { + New-Item -Type file -Path $Profile -Force + notepad $Profile +} +# 更多信息: `help about_profiles` +# 更多关于 Shell 有用的信息,确保查看下面的 PSReadLine 项目。 +``` + +更多项目 + +* [Channel9](https://channel9.msdn.com/Search?term=powershell%20pipeline#ch9Search&lang-en=en) PowerShell 教程 +* [PSGet](https://github.com/psget/psget) PowerShell NuGet 包 +* [PSReadLine](https://github.com/lzybkr/PSReadLine/) 仿 bash 按行读取( Window10 默认包含) +* [Posh-Git](https://github.com/dahlbyk/posh-git/) Git 命令提示 (推荐!) +* [PSake](https://github.com/psake/psake) 自动构建工作 +* [Pester](https://github.com/pester/Pester) BDD 测试框架 +* [Jump-Location](https://github.com/tkellogg/Jump-Location) Poweshell 中 `cd` 来跳转目录 +* [PowerShell Community Extensions](http://pscx.codeplex.com/) (废弃) + +尚未涉及 + +* WMI: Windows 管理规范 (Get-CimInstance) +* 多任务: Start-Job -scriptBlock {...}, +* 代码签名 +* 远程 (Enter-PSSession/Exit-PSSession; Invoke-Command) |