Merge remote-tracking branch 'upstream/master'

This commit is contained in:
caminsha 2020-01-31 03:24:14 +01:00
commit 06b95ac17e
46 changed files with 3507 additions and 485 deletions

View File

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

View File

@ -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 containing definitions related to the integers Z *)
Require Import ZArith.
(* Imports the Zarith module holding definitions related to the integers Z *)
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

View File

@ -653,10 +653,10 @@ on a new line! ""Wow!"", the masses cried";
return ++count;
}
// A delegate is a reference to a method
// A delegate is a reference to a method.
// To reference the Increment method,
// first declare a delegate with the same signature
// ie. takes no arguments and returns an int
// first declare a delegate with the same signature,
// i.e. takes no arguments and returns an int
public delegate int IncrementDelegate();
// An event can also be used to trigger delegates
@ -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)

View File

@ -212,6 +212,7 @@ found in the wonderful `std.algorithm` module!
```d
import std.algorithm : map, filter, reduce;
import std.range : iota; // builds an end-exclusive range
import std.stdio;
void main() {
// We want to print the sum of a list of squares of even ints

View File

@ -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) {
@ -211,7 +223,7 @@ example14() {
// statically typed null can not be convert to bool
var c = "abc";
c = null;
// complie failed
// compile failed
// if (c) {
// print("true, c is $c");
// } else {
@ -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)

View File

@ -157,7 +157,7 @@ echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Löschen der Hilfsdateien von oberhalb, mit Anzeige der Dateinamen
# (mit '-i' für "interactive" erfolgt für jede Date eine Rückfrage)
# (mit '-i' für "interactive" erfolgt für jede Datei eine Rückfrage)
rm -v output.out error.err output-and-error.log
# Die Ausgabe von Befehlen kann mit Hilfe von $( ) in anderen Befehlen verwendet weden:

View File

@ -50,10 +50,10 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<!-- Danach startet sie mit einem Öffnungtag <html>. -->
<html>
<!-- Dieser wird am Ende der Datei mit</html> geschlossen. -->
<!-- Dieser wird am Ende der Datei mit </html> geschlossen. -->
</html>
<!-- Nichts sollte nach diesen finalen Tag erscheinen. -->
<!-- Nichts sollte nach diesem finalen Tag erscheinen. -->
<!-- Dazwischen (Zwischen dem Öffnungs- und Schließungstag <html></html>) finden wir: -->
@ -65,13 +65,13 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
</head>
<!-- Nach dem <head> Bereich findet sich der <body> Tag -->
<!-- Bis zu diesen Punkt wird nichts im Browerfenster angezeigt. -->
<!-- Wir müssen den Body mit dem Inhalt füllen der angezeigt werden soll. -->
<!-- Bis zu diesem Punkt wird nichts im Browerfenster angezeigt. -->
<!-- Wir müssen den Body mit dem Inhalt füllen, der angezeigt werden soll. -->
<body>
<h1>Hallo, Welt!</h1> <!-- Der h1 Tag erstellt einen Titel. -->
<!-- Es gibt auch Untertitel für <h1> von den wichtigsten <h2> zu den Unwichtigsten (h6). -->
<a href = "http://codepen.io/anon/pen/xwjLbZ">Komm, schaue was das zeigt</a> <!-- Eine URL wird zum Hyperlink, wenn es das Attribut href="" -->
<a href = "http://codepen.io/anon/pen/xwjLbZ">Komm, schaue was das zeigt</a> <!-- Eine URL wird zum Hyperlink, wenn es das Attribut href="" hat -->
<p>Das ist ein Absatz.</p> <!-- Der Tag <p> lässt uns Text auf die HTML Seite hinzufügen. -->
<p>Das ist ein anderer Absatz.</p>
<ul> <!-- Der <ul> Tag erstellt eine Aufzählungsliste. -->
@ -93,12 +93,12 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<!-- Es ist ebenso möglich eine Tabelle zu erstellen. -->
<table> <!-- Wir öffnen ein <table> Element. -->
<tr> <!-- <tr> erlaubt es uns Reihe zu erstellen. -->
<th>Erster Tabellenkopf</th> <!-- <th> erlaubt es uns der Tabelle einen Titel zu geben. -->
<tr> <!-- <tr> erlaubt es uns, Reihen zu erstellen. -->
<th>Erster Tabellenkopf</th> <!-- <th> erlaubt es uns, der Tabelle einen Titel zu geben. -->
<th>Zweiter Tabllenkopf</th>
</tr>
<tr>
<td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es eine Tabellenzelle zu erstellen. -->
<td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es, eine Tabellenzelle zu erstellen. -->
<td>Erste Zeile, zweite Spalte</td>
</tr>
<tr>

View File

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

View File

@ -11,14 +11,14 @@ lang: de-de
---
Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele)
zu erzeugen. Es dient dazu die geringste Menge an Arbeit zu verrichten um
ein Ziel in einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
zu erzeugen. Es dient dazu, die geringste Menge an Arbeit zu verrichten um
ein Ziel in Einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
sehr verbreitet (vorallem im Unix umfeld) obwohl es bereits sehr viel
sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel
Konkurrenz und Kritik zu Make gibt.
Es gibt eine vielzahl an Varianten von Make, dieser Artikel beschäftig sich
mit der Version GNU Make. Diese Version ist standard auf Linux.
Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich
mit der Version GNU Make. Diese Version ist Standard auf Linux.
```make
@ -44,14 +44,15 @@ file0.txt:
# die erste Regel ist die Standard-Regel.
# Diese Regel wird nur abgearbeitet wenn file0.txt aktueller als file1.txt ist.
# Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist.
file1.txt: file0.txt
cat file0.txt > file1.txt
# Verwende die selben Quoting-Regeln wie die Shell
@cat file0.txt >> file1.txt
# @ unterdrückt die Ausgabe des Befehls an stdout.
-@echo 'hello'
# - bedeutet das Make die Abarbeitung fortsetzt auch wenn Fehler passieren.
# - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler
# passieren.
# Versuche `make file1.txt` auf der Kommandozeile.
# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
@ -59,7 +60,7 @@ file2.txt file3.txt: file0.txt file1.txt
touch file2.txt
touch file3.txt
# Make wird sich beschweren wenn es mehrere Rezepte für die gleiche Regel gibt.
# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt.
# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
# Voraussetzungen hinzuzufügen.
@ -67,8 +68,8 @@ file2.txt file3.txt: file0.txt file1.txt
# Phony-Ziele
#-----------------------------------------------------------------------
# Ein Phony-Ziel ist ein Ziel das keine Datei ist.
# Es wird nie aktuell sein, daher wird Make immer versuchen es abzuarbeiten
# Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
all: maker process
# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
@ -89,14 +90,14 @@ ex0.txt ex1.txt: maker
# Automatische Variablen & Wildcards
#-----------------------------------------------------------------------
process: file*.txt # Eine Wildcard um Dateinamen zu Vergleichen
process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen
@echo $^ # $^ ist eine Variable die eine Liste aller
# Voraussetzungen enthält.
@echo $@ # Namen des Ziels ausgeben.
#(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
#der Regel.)
@echo $< # Die erste Voraussetzung aus der Liste
@echo $? # Nur die Voraussetzungen die nicht aktuell sind.
@echo $? # Nur die Voraussetzungen, die nicht aktuell sind.
@echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
#@echo $| # Alle 'order only' Voraussetzungen
@ -114,20 +115,20 @@ process: ex1.txt file0.txt
%.png: %.svg
inkscape --export-png $^
# Muster-Vergleichs-Regeln werden nur abgearbeitet wenn make entscheidet das Ziel zu
# erzeugen
# Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das
# Ziel zu erzeugen
# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
# Aber make wird versuchen die am besten passende Regel zu verwenden.
small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^
# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden die es
# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es
# findet.
%.png: %.svg
@echo this rule is chosen
# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden die das
# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das
# Ziel erzeugen kann.
%.png: %.ps
@echo this rule is not chosen if *.svg and *.ps are both present
@ -171,7 +172,7 @@ name4 ?= Jean
# nicht gibt.
override name5 = David
# Verhindert das Kommando-Zeilen Argumente diese Variable ändern können.
# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
name4 +=grey
# Werte an eine Variable anhängen (inkludiert Leerzeichen).
@ -179,9 +180,9 @@ name4 +=grey
# Muster-Spezifische Variablen Werte (GNU Erweiterung).
echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
# rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
# kann wenn es zu kompilizert wird!)
# kann, wenn es zu kompilizert wird!)
# Ein paar Variablen die von Make automatisch definiert werden.
# Ein paar Variablen, die von Make automatisch definiert werden.
echo_inbuilt:
echo $(CC)
echo ${CXX}
@ -196,7 +197,7 @@ echo_inbuilt:
# Variablen 2
#-----------------------------------------------------------------------
# Der erste Typ von Variablen wird bei jeder verwendung ausgewertet.
# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet.
# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
@ -215,7 +216,7 @@ var4 ::= good night
# Funktionen
#-----------------------------------------------------------------------
# Make verfügt über eine vielzahl von Funktionen.
# Make verfügt über eine Vielzahl von Funktionen.
sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles))

146
docker.html.markdown Normal file
View File

@ -0,0 +1,146 @@
---
language: docker
filename: docker.bat
contributors:
- ["Ruslan López", "http://javapro.org/"]
---
```
:: download, install and run hello-world image
docker run hello-world
:: if this is the first time you should be able to see the message
:: Unable to find image 'hello-world:latest' locally
:: latest: Pulling from library/hello-world
:: 1b930d010525: Pull complete
:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
:: Status: Downloaded newer image for hello-world:latest
::
:: Hello from Docker!
:: This message shows that your installation appears to be working correctly.
::
:: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal.
::
:: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash
::
:: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/
::
:: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/
:: now lets see currently running images
docker ps
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: lets see the images we have ran previously
docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago
:: happy_poincare
:: the name part is generated automatically so it probably will be different for you
:: let's remove our previously generated image
docker rm happy_poincare
:: lets test if it was really deleted
docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: specify a custom name for the container
docker run --name test_container hello-world
:: Hello from Docker!
:: This message shows that your installation appears to be working correctly.
::
:: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal.
::
:: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash
::
:: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/
::
:: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/
docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago
:: test_container
:: as you can see the name is now what we have specified
:: retireve logs from a named container
docker logs test_container
:: Hello from Docker!
:: This message shows that your installation appears to be working correctly.
::
:: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal.
::
:: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash
::
:: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/
::
:: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/
docker rm test_container
docker run ubuntu
:: Unable to find image 'ubuntu:latest' locally
:: latest: Pulling from library/ubuntu
:: 2746a4a261c9: Pull complete
:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
:: Status: Downloaded newer image for ubuntu:latest
docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago
:: relaxed_nobel
:: running a container in an interactive mode
docker run -it ubuntu
:: root@e2cac48323d2:/# uname
:: Linux
:: root@e2cac48323d2:/# exit
:: exit
docker rm relaxed_nobel
docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES
:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago
:: nifty_goldwasser
docker rm nifty_goldwasser
```

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -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. Haskell IO
-- 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
----------------------------------------------------
-- 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`.

231
hdl.html.markdown Normal file
View File

@ -0,0 +1,231 @@
---
language: hdl
filename: learnhdl.hdl
contributors:
- ["Jack Smith", "https://github.com/JSmithTech2019"]
---
HDL (hardware description language) is a specialized language used to describe the structure/behavior of real world circuits.
It is used by circuit designers to simulate circuits and logic prior to wiring and fabricating a hardware circuit.
HDL allows circuit designers to simulate circuits at a high level without being connected to specific components.
## Basic building blocks & introduction to the language---
This programming language is built by simulating hardware chips and wiring. Normal programming functions are replaced with specialized chips that are added to the current wiring desing. Every base chip must be written as it's own file and imported to be used in the current chip, though they may be reused as often as desired.
```verilog
// Single line comments start with two forward slashes.
/*
* Multiline comments can be written using '/*' and 'star/'.
* These are often used as comments.
*
* Note that they cannot be nested and will end at the first 'star/'.
*/
////////////////////////////////////////////////////
// 1. Chips & Components
////////////////////////////////////////////////////
/*
* Unlike other languages HDL creates an individual chip (function) per file
* These are defined with a name, input arguments, output arguments
* and finally the parts/logic of that specific chip.
*/
// Note CHIP is capitalized, the chip name does not need to be.
CHIP Ex {
IN a, // Single bit (0 or 1) variable.
c[16]; // 16 bit variable bus of single bit values.
OUT out[16], // 16 bit variable bus output.
carry; // Single bit output variable
PARTS:
// The functional components of the chip.
}
// Lines are ended with semicolons but can be continued using commas. The
// whitespace is ignored.
////////////////////////////////////////////////////
// 2. Inputs, Outputs, & Variables
////////////////////////////////////////////////////
/*
* Variables and IO are treated as pins/wires and can carry a single bit
* of data (0 or 1).
*/
// Hardware works on low level 0's and 1's, in order to use a constant
// high or low we use the terms true and false.
a=false; // This is a 0 value.
b=true; // This is a 1 value.
// Inputs and outputs can be defined as single bits
IN a, b; // Creates two single bit inputs
// They can also be defined as busses act as arrays where each
// index can contain a single bit value.
OUT c[16]; // Creates a 16 bit output array.
// Bussed values can be accessed using brackets
a[0] // The first indexed value in the bus a.
a[0..3] // The first 4 values in the a bus.
// Values can also be passed in entirety. For example if the function
// foo() takes an 8 bit input bus and outputs a 2 bit bus:
foo(in=a[0..7], out=c); // C is now a 2 bit internal bus
// Note that internally defined busses cannot be subbussed!
// To access these elements, output or input them seperately:
foo(in[0]=false, in[1..7]=a[0..6], out[0]=out1, out[1]=out2);
// out1 and out2 can then be passed into other circuits within the design.
////////////////////////////////////////////////////
// Combining Subsystems
////////////////////////////////////////////////////
/*
* HDL relies heavily on using smaller "building block" chips to then be
* added into larger and more complex designs. Creating the smaller components
* and then adding them to the larger circuit allows for fewer lines of code
* as well as reduction in total rewriting of code.
*/
// We are writing the function AND that checks if inputs I and K are both one.
// To implement this chip we will use the built in NAND gate as well as design
// a custom NOT gate to invert a single input.
// First we construct the Negation (not) chip. We will use the logically
// complete gate NAND that is built in for this task.
CHIP Not {
IN i; // Not gates only take one single bit input.
OUT o; // The negated value of a.
PARTS:
// Add the input to the built in chip, which then sends output to the NOT
// output. This effectively negates the given value.
Nand(a=i, b=i, out=o);
}
// By using the built in NAND gate we were able to construct a NOT gate
// that works like a real world hardware logic chip. Now we must construct
// the AND gate using these two gate primitives.
// We define a two input, single output AND gate:
CHIP And {
IN i, k; // Two single bit inputs.
OUT o; // One single bit output.
PARTS:
// Insert I and K into the nand gate and store the output in an internal
// wire called notOut.
Nand(a=i,b=b,out=notOut);
// Use the not gate we constructed to invert notOut and send to the AND
// output.
Not(in=notOut,out=o);
}
// Easy! Now we can use Nand, And, and Not gates in higher level circuits.
// Many of these low level components are built in to HDL but any chip can
// be written as a submodule and used in larger designs.
```
## Test Files
When working with the nand2tetris hardware simulator chips written using HDL will
then be processed against test and comparison files to test functionality of the
simulated chip versus the expected output. To do this a test file will be loaded
into the hardware simulator and run against the simulated hardware.
```verilog
// First the chip the test file is written for is loaded
load <chip name>.hdl
// We set the output file for the simulated chip output as well as the comparison
// file that it will be tested against. We also specify what the output is
// expected to look like. In this case there will be two output columns, each
// will be buffered by a single space on either side and 4 binary values in
// the center of each column.
output-file <chip name>.out,
compare-to <chip name>.cmp,
output-list in%B1.4.1 out%B1.4.1;
// Then we set initial values for inputs to the chip. For example
set enable1 1, // set input enable1 to 1
set enable2 0, // set input enable2 to 0
// The clock is also controlled in the test file using tick and tock. Tick is a
// positive pulse and tock takes the clock back to 0. Clock cycles can be run
// multiple times in a row with no other changes to inputs or outputs.
tick,
tock,
// Finally we output the first expected value (from the test file) which is then
// compared with the first line of real output from our HDL circuit. This output
// can be viewed in the <chip name>.out file.
output;
// An example of <chip name>, a chip that takes in a 4 bit value as input and
// adds 1 to that value could have the following as test code:
// Set the input value to 0000, clock pulse, compare output from cmp file to actual out.
set in %B0000,
tick,
tock,
output;
// Set the input value to 0110, clock pulse, compare output from cmp file to actual out.
set in %B0110,
tick,
tock,
output;
// The expected output for case 1 should be 0001 and case 2 expects 0111, lets
// learn a little more about comparison files before finalizing our lesson.
```
## Comparison Files
Now lets take a look at comparison files, the files that hold what the test file
compares with the actual output of an HDL chip in the hardware simulator!
```verilog
// Like the <chip name> example above, the structure of the comparison file
// would look something like this
| in | out |
| 0000 | 0001 |
| 0110 | 0111 |
// Notice how the input values specified in the test case are equivalent to the
// `in` column of the comparison file, and that the space buffer is 1 on either side.
// If the output from the HDL code we not this, such as the output below, then the
// test will fail and the user will know that the simulated chip is not correctly designed.
| in | out |
| 0000 | 0001 |
| 0110 | 0110 | // Error! The chip did not add 1 here, something went wrong.
```
This is incredibly useful as it allows designers to simulate chip logic prior to
fabricating real life hardware and identify problems in their designs. Be warned that
errors in the test or comparison files can lead to both false positives and also
the more damaging false negatives so ensure that the logic is sound behind the test
creation.
Good luck and happy coding!
## Resources
* [From Nand To Tetris](https://www.nand2tetris.org)
## Further Reading
* [Hardware Description Language](https://en.wikipedia.org/wiki/Hardware_description_language)
* [HDL Programming Fundamentals](https://www.electronicdesign.com/products/hdl-programming-fundamentals)

View File

@ -63,7 +63,7 @@ echo ${Variabile}
# Sotto ci sono altri esempi che analizzano l'uso dell'espansione dei parametri.
# Sostituzione di stringhe nelle variabili
echo ${Variabile/Una/A}
echo ${Variabile/Una/La}
# Questo sostituirà la prima occorrenza di "Una" con "La"
# Sottostringa di una variabile

View File

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

View File

@ -188,7 +188,7 @@ someVar = myArray.pop(); // Remove last element and return it
// Join all elements of an array with semicolon
var myArray0 = [32,false,"js",12,56,90];
myArray0.join(";") // = "32;false;js;12;56;90"
myArray0.join(";"); // = "32;false;js;12;56;90"
// Get subarray of elements from index 1 (include) to 4 (exclude)
myArray0.slice(1,4); // = [false,"js",12]

View File

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

View File

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

View File

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

View File

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

View File

@ -289,7 +289,7 @@ if (false) {
print (false ? 'Does not get printed' : 'Does');
// ternary shortcut operator since PHP 5.3
// equivalent of "$x ? $x : 'Does'""
// equivalent of "$x ? $x : 'Does'"
$x = false;
print($x ?: 'Does');

View File

@ -15,7 +15,7 @@ in the shell.
A key difference with Bash is that it is mostly objects that you manipulate
rather than plain text.
[Read more here.](https://technet.microsoft.com/en-us/library/bb978526.aspx)
[Read more here.](https://docs.microsoft.com/powershell/scripting/overview)
If you are uncertain about your environment:
@ -321,7 +321,7 @@ Interesting Projects
* [PSake](https://github.com/psake/psake) Build automation tool
* [Pester](https://github.com/pester/Pester) BDD Testing Framework
* [Jump-Location](https://github.com/tkellogg/Jump-Location) Powershell `cd` that reads your mind
* [PowerShell Community Extensions](http://pscx.codeplex.com/) (Dead)
* [PowerShell Community Extensions](https://github.com/Pscx/Pscx)
Not covered

View File

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

View File

@ -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 para reduzi-los
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10
; 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
; 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
; (É necessário colocar parênteses para chamá-los)
((fn [] "Hello World")) ; => "Hello World"
; Para executar suas funções, é preciso chamá-las, envolvendo-as em parênteses.
((fn [] "Olá Mundo")) ; => "Olá Mundo"
; Você pode atribuir valores a variáveis utilizando def
(def x 1)
x ; => 1
; 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"
; Atribua uma função para uma var
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World"
; Você pode abreviar esse processo usando defn:
(defn ola-mundo [] "Olá Mundo")
; Você pode abreviar esse processo usando defn
(defn hello-world [] "Hello World")
; Uma função pode receber uma lista de argumentos:
(defn ola
[nome]
(str "Olá " nome))
(ola "Jonas") ; => "Olá Jonas"
; O [] é uma lista de argumentos para um função.
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve"
; É 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 ainda usar essa abreviação para criar funcões:
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny"
(soma) ; => 0
(soma 1) ; => 1
(soma 1 2) ; => 3
; 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 conta-args
[& args]
(str "Você passou " (count args) " argumentos: " args))
(conta-args 1 2 3 4) ; => "Você passou 4 argumentos: (1 2 3 4)"
; Funções podem agrupar argumentos extras em uma seq
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
; Você pode misturar argumentos regulares e argumentos em seq:
(defn 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 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"
; 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
; 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.
; 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 que se pode derivar um hash como chave
; Mapas podem usar qualquer valor em que se pode derivar um hash como chave,
; mas normalmente palavras-chave (keywords) são melhores.
; Keywords são como strings mas com algumas vantagens.
; 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
; Condicionais e blocos
;;;;;;;;;;;;;;;;;
; Construções lógicas em Clojure são como macros, e
; se parecem com as demais
; 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)) ; => 3
(let [cores {:yellow "Amarelo" :blue "Azul"}
nova-cor :red
nome-cor "Vermelho"]
(assoc cores nova-cor nome-cor)) ; => {:yellow "Amarelo", :blue "Azul", :red "Vermelho"}
; 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
; Use let para criar um novo escopo associando sîmbolos a valores (bindings)
(let [a 1 b 2]
(> a b)) ; => false
; 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
; Agrupe comandos juntos com "do"
(do
(print "Hello")
"World") ; => "World" (prints "Hello")
; 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
; 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")
; 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
; Use . para chamar métodos. Ou, use o atalho ".method"
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; exatamente a mesma coisa.
; 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 estáticos
(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente)
; Para chamar métodos estáticos dentro de classes Java, use /
(System/currentTimeMillis) ; => retorna um timestamp
; 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.
; O atom é o mais simples. Passe pra ele um valor inicial
(def my-atom (atom {}))
; 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 {}))
; 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)
; Para acessar o valor de um atom, você pode usar a função deref ou o operador @:
@atom-mapa ; => {}
(deref atom-mapa) ; => {}
; Use '@' para desreferenciar um atom e acessar seu valor
my-atom ;=> Atom<#...> (Retorna o objeto do Atom)
@my-atom ; => {:a 1 :b 2}
; 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)
; Abaixo um contador simples usando um atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
; Observe que essas chamadas alteraram de fato o valor de atom-mapa. Seu novo valor é:
@atom-mapa ; => {:a 1 :b 2}
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
; Isso é diferente de fazer:
(def atom-mapa-2 (atom {}))
(def atom-mapa-3 (assoc @atom-mapa-2 :a 1))
@counter ; => 5
; 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}
; Outras construção STM são refs e agents.
(class atom-mapa-2) ; => clojure.lang.Atom
(class atom-mapa-3) ; => clojure.lang.PersistentArrayMap
; 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.
; 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:

View File

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

View File

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

View File

@ -16,8 +16,6 @@ Python was created by Guido van Rossum in the early 90s. It is now one of the mo
languages in existence. I fell in love with Python for its syntactic clarity. It's basically
executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/python/) if you want to learn the old Python 2.7
```python
@ -58,11 +56,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
@ -138,20 +137,6 @@ b == a # => True, a's and b's objects are equal
# You can find the length of a string
len("This is a string") # => 16
# .format can be used to format strings, like this:
"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated"
# You can repeat the formatting arguments to save some typing.
"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
# You can use keywords if you don't want to count.
"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
# If your Python 3 code also needs to run on Python 2.5 and below, you can also
# still use the old style of formatting:
"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
# You can also format using f-strings or formatted string literals (in Python 3.6+)
name = "Reiko"
f"She said her name is {name}." # => "She said her name is Reiko"
@ -394,6 +379,9 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
2 in filled_set # => True
10 in filled_set # => False
# Make a one layer deep copy
filled_set = some_set.copy() # filled_set is {1, 2, 3, 4, 5}
filled_set is some_set # => False
####################################################

View File

@ -1,5 +1,5 @@
---
language: rust
language: Rust
contributors:
- ["P1start", "http://p1start.github.io/"]
filename: learnrust.rs

View File

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

View File

@ -30,7 +30,8 @@ The most basic operation is to send a message to an object
`anObject aMessage`
There are three sorts of messages
- unary - a single string that may be several words conjoined in what we call camelcase form, with no arguments. For example 'size', 'reverseBytes', 'convertToLargerFormatPixels'
- unary - a single symbol that may be several words conjoined in what we call camelcase form, with no arguments. For example 'size', 'reverseBytes', 'convertToLargerFormatPixels'
- binary - a small set of symbols of the sort often used for arithmetic operations in most languages, requiring a single argument. For example '+', '//', '@'. We do not use traditional arithmetic precedence, something to keep an eye on.
- keyword - the general form where multiple arguments can be passed. As with the unary form we use camelcase to join words together but arguments are inserted in the midst of the message with colons used to separate them lexically. For example 'setTemperature:', 'at:put:', 'drawFrom:to:lineWidth:fillColor:'
@ -38,21 +39,23 @@ There are three sorts of messages
`result := myObject doSomethingWith: thatObject`
We are sending the message 'doSomethingWith:' to myObject. This happens to be a message that has a single argument but that's not important yet.
'myObject' is a 'MyExampleClass' instance so the system looks at the list of messages understood by MyExampleClass
- beClever
- doWierdThing:
- doSomethingWith
In searching we see what initially looks like a match - but no, it lacks the final colon. So we find the super class of MyExampleClass - BigExampleClass. Which has a list of known messages of its own
- beClever
- doSomethingWith:
- buildCastleInAir
- annoyUserByDoing:
We find a proper exact match and start to execute the code
```
We find a proper exact match and start to execute the code:
```smalltalk
doSomethingWith: argumentObject
"A comment about what this code is meant to do and any known limitations, problems, where it might be further documented etc"
self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self].
self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self].
```
Everything here except the `^` involves sending more messages. Event the `ifTrue:` that you might think is a language control structure is just Smalltalk code.
@ -94,7 +97,7 @@ Taken from [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smallta
`"Period (.) is the statement separator. Not required on last line of a method"`
#### Transcript:
```
```smalltalk
Transcript clear. "clear to transcript window"
Transcript show: 'Hello World'. "output string in transcript window"
Transcript nextPutAll: 'Hello World'. "output string in transcript window"
@ -108,26 +111,17 @@ Transcript endEntry. "flush the output buffer"
```
#### Assignment:
```
```smalltalk
| x y |
x _ 4. "assignment (Squeak) <-"
x := 5. "assignment"
x := y := z := 6. "compound assignment"
x := (y := 6) + 1.
x := Object new. "bind to allocated instance of a class"
x := 123 class. "discover the object class"
x := Integer superclass. "discover the superclass of a class"
x := Object allInstances. "get an array of all instances of a class"
x := Integer allSuperclasses. "get all superclasses of a class"
x := 1.2 hash. "hash value for object"
y := x copy. "copy object"
y := x shallowCopy. "copy object (not overridden)"
y := x deepCopy. "copy object and instance vars"
y := x veryDeepCopy. "complete tree copy using a dictionary"
```
#### Constants:
```
```smalltalk
| b |
b := true. "true constant"
b := false. "false constant"
@ -147,7 +141,7 @@ x := #('abc' 2 $a). "mixing of types allowed"
```
#### Booleans:
```
```smalltalk
| b x y |
x := 1. y := 2.
b := (x = y). "equals"
@ -185,7 +179,7 @@ b := $A isLowercase. "test if lower case character"
```
#### Arithmetic expressions:
```
```smalltalk
| x |
x := 6 + 3. "addition"
x := 6 - 3. "subtraction"
@ -241,7 +235,7 @@ x := 100 atRandom. "quick random number"
```
#### Bitwise Manipulation:
```
```smalltalk
| b x |
x := 16rFF bitAnd: 16r0F. "and bits"
x := 16rF0 bitOr: 16r0F. "or bits"
@ -257,7 +251,7 @@ b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in recei
```
#### Conversion:
```
```smalltalk
| x |
x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
x := 3.99 asFraction. "convert number to fraction"
@ -281,7 +275,7 @@ x := 15 storeStringBase: 16.
- `^`expression terminates block & method (exits all nested blocks)
- blocks intended for long term storage should not contain `^`
```
```smalltalk
| x y z |
x := [ y := 1. z := 2. ]. x value. "simple block usage"
x := [ :argOne :argTwo | argOne, ' and ' , argTwo.]. "set up block with argument passing"
@ -304,7 +298,7 @@ Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argu
- private (methods private to class)
- instance-creation (class methods for creating instance)
```
```smalltalk
| x |
x := 2 sqrt. "unary message"
x := 2 raisedTo: 10. "keyword message"
@ -319,7 +313,7 @@ x := 3 + 2; * 100. "result=300. Sends message to same
```
#### Conditional Statements:
```
```smalltalk
| x |
x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
@ -359,7 +353,7 @@ result := (switch at: $B) value.
```
#### Iteration statements:
```
```smalltalk
| x y |
x := 4. y := 1.
[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
@ -371,7 +365,7 @@ x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x
```
#### Character:
```
```smalltalk
| x y |
x := $A. "character assignment"
y := x isLowercase. "test if lower case"
@ -391,7 +385,7 @@ y := $A max: $B.
```
#### Symbol:
```
```smalltalk
| b x y |
x := #Hello. "symbol assignment"
y := 'String', 'Concatenation'. "symbol concatenation (result is string)"
@ -413,7 +407,7 @@ y := x asSet. "convert symbol to set collect
```
#### String:
```
```smalltalk
| b x y |
x := 'This is a string'. "string assignment"
x := 'String', 'Concatenation'. "string concatenation"
@ -447,7 +441,7 @@ Fixed length collection
- ByteArray: Array limited to byte elements (0-255)
- WordArray: Array limited to word elements (0-2^32)
```
```smalltalk
| b x y sum max |
x := #(4 3 2 1). "constant array"
x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements"
@ -490,7 +484,7 @@ y := x asSet. "convert to set collection"
#### OrderedCollection:
acts like an expandable array
```
```smalltalk
| b x y sum max |
x := OrderedCollection
with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
@ -537,7 +531,7 @@ y := x asSet. "convert to set collection"
#### SortedCollection:
like OrderedCollection except order of elements determined by sorting criteria
```
```smalltalk
| b x y sum max |
x := SortedCollection
with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
@ -583,7 +577,7 @@ y := x asSet. "convert to set collection"
#### Bag:
like OrderedCollection except elements are in no particular order
```
```smalltalk
| b x y sum max |
x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
x := Bag new. "allocate collection"
@ -619,7 +613,7 @@ like Bag except duplicates not allowed
#### IdentitySet:
uses identity test (== rather than =)
```
```smalltalk
| b x y sum max |
x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
x := Set new. "allocate collection"
@ -649,7 +643,7 @@ y := x asSet. "convert to set collection"
```
#### Interval:
```
```smalltalk
| b x y sum max |
x := Interval from: 5 to: 10. "create interval object"
x := 5 to: 10.
@ -679,7 +673,7 @@ y := x asSet. "convert to set collection"
```
#### Associations:
```
```smalltalk
| x y |
x := #myVar->'hello'.
y := x key.
@ -690,7 +684,7 @@ y := x value.
#### IdentityDictionary:
uses identity test (== rather than =)
```
```smalltalk
| b x y |
x := Dictionary new. "allocate collection"
x add: #a->4;
@ -757,7 +751,7 @@ Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary fr
```
#### Internal Stream:
```
```smalltalk
| b x ios |
ios := ReadStream on: 'Hello read stream'.
ios := ReadStream on: 'Hello read stream' from: 1 to: 5.
@ -785,7 +779,7 @@ b := ios atEnd.
```
#### FileStream:
```
```smalltalk
| b x ios |
ios := FileStream newFileNamed: 'ios.txt'.
ios nextPut: $H; cr.
@ -805,7 +799,7 @@ ios close.
```
#### Date:
```
```smalltalk
| x y |
x := Date today. "create date for today"
x := Date dateAndTimeNow. "create date from current time/date"
@ -839,7 +833,7 @@ b := (x <= Date today). "comparison"
```
#### Time:
```
```smalltalk
| x y |
x := Time now. "create time from current time"
x := Time dateAndTimeNow. "create time from current time/date"
@ -859,7 +853,7 @@ b := (x <= Time now). "comparison"
```
#### Point:
```
```smalltalk
| x y |
x := 200@100. "obtain a new point"
y := x x. "x coordinate"
@ -884,12 +878,12 @@ x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
```
#### Rectangle:
```
```smalltalk
Rectangle fromUser.
```
#### Pen:
```
```smalltalk
| myPen |
Display restoreAfter: [
Display fillWhite.
@ -917,7 +911,7 @@ Display height. "get display height"
```
#### Dynamic Message Calling/Compiling:
```
```smalltalk
| receiver message result argument keyword1 keyword2 argument1 argument2 |
"unary message"
@ -957,7 +951,7 @@ result := (Message
```
#### Class/Meta-Class:
```
```smalltalk
| b x |
x := String name. "class name"
x := String category. "organization category"
@ -990,7 +984,7 @@ Object withAllSubclasses size. "get total number of class entries"
```
#### Debugging:
```
```smalltalk
| a b x |
x yourself. "returns receiver"
String browse. "browse specified class"
@ -1013,8 +1007,13 @@ Transcript show: a, b; cr.
```
#### Miscellaneous
```
```smalltalk
| x |
x := 1.2 hash. "hash value for object"
y := x copy. "copy object"
y := x shallowCopy. "copy object (not overridden)"
y := x deepCopy. "copy object and instance vars"
y := x veryDeepCopy. "complete tree copy using a dictionary"
"Smalltalk condenseChanges." "compress the change file"
x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
Utilities openCommandKeyHelp

View File

@ -2,8 +2,8 @@
language: "Standard ML"
filename: standardml.sml
contributors:
- ["Simon Shine", "http://shine.eu.org/"]
- ["David Pedersen", "http://lonelyproton.com/"]
- ["Simon Shine", "https://simonshine.dk/"]
- ["David Pedersen", "https://github.com/davidpdrsn"]
- ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
- ["Chris Wilson", "http://sencjw.com/"]
@ -479,3 +479,4 @@ fun decrement_ret x y = (x := !x - 1; y)
* Follow the Coursera course [Programming Languages](https://www.coursera.org/course/proglang).
* Read *[ML for the Working Programmer](https://www.cl.cam.ac.uk/~lp15/MLbook/pub-details.html)* by Larry C. Paulson.
* Use [StackOverflow's sml tag](http://stackoverflow.com/questions/tagged/sml).
* Solve exercises on [Exercism.io's Standard ML track](https://exercism.io/tracks/sml).

View File

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

View File

@ -139,7 +139,7 @@ class Point3D extends Point {
// Overwrite
dist() {
let d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
return Math.sqrt(d() * d() + this.z * this.z);
}
}

651
vimscript.html.markdown Normal file
View File

@ -0,0 +1,651 @@
---
language: Vimscript
filename: learnvimscript.vim
contributors:
- ["HiPhish", "http://hiphish.github.io/"]
---
```vim
" ##############
" Introduction
" ##############
"
" Vim script (also called VimL) is the subset of Vim's ex-commands which
" supplies a number of features one one would expect from a scripting language,
" such as values, variables, functions or loops. Always keep in the back of
" your mind that a Vim script file is just a sequence of ex-commands. It is
" very common for a script to mix programming-language features and raw
" ex-commands.
"
" You can run Vim script directly by entering the commands in command-mode
" (press `:` to enter command-mode), or you can write them to a file (without
" the leading `:`) and source it in a running Vim instance (`:source
" path/to/file`). Some files are sourced automatically as part of your
" configuration (see |startup|). This guide assumes that you are familiar
" with ex-commands and will only cover the scripting. Help topics to the
" relevant manual sections are included.
"
" See |usr_41.txt| for the official introduction to Vim script. A comment is
" anything following an unmatched `"` until the end of the line, and `|`
" separates instructions (what `;` does in most other languages). References to
" the manual as surrounded with `|`, such as |help.txt|.
" This is a comment
" The vertical line '|' (pipe) separates commands
echo 'Hello' | echo 'world!'
" Putting a comment after a command usually works
pwd " Displays the current working directory
" Except for some commands it does not; use the command delemiter before the
" comment (echo assumes that the quotation mark begins a string)
echo 'Hello world!' | " Displays a message
" Line breaks can be escaped by pacing a backslash as the first non-whitespace
" character on the *following* line. Only works in script files, not on the
" command line
echo " Hello
\ world "
echo [1,
\ 2]
echo {
\ 'a': 1,
\ 'b': 2
\}
" #######
" Types
" #######
"
" For an overview of types see |E712|. For an overview of operators see
" |expression-syntax|
" Numbers (|expr-number|)
" #######
echo 123 | " Decimal
echo 0b1111011 | " Binary
echo 0173 | " Octal
echo 0x7B | " Hexadecimal
echo 123.0 | " Floating-point
echo 1.23e2 | " Floating-point (scientific notation)
" Note that an *integer* number with a leading `0` is in octal notation. The
" usual arithmetic operations are supported.
echo 1 + 2 | " Addition
echo 1 - 2 | " Subtraction
echo - 1 | " Negation (unary minus)
echo + 1 | " Unary plus (does nothing really, but still legal)
echo 1 * 2 | " Multiplication
echo 1 / 2 | " Division
echo 1 % 2 | " Modulo (remainder)
" Booleans (|Boolean|)
" ########
"
" The number 0 is false, every other number is true. Strings are implicitly
" converted to numbers (see below). There are two pre-defined semantic
" constants.
echo v:true | " Evaluates to 1 or the string 'v:true'
echo v:false | " Evaluates to 0 or the string 'v:false'
" Boolean values can result from comparison of two objects.
echo x == y | " Equality by value
echo x != y | " Unequality
echo x > y | " Greater than
echo x >= y | " Greater than or equal
echo x < y | " Smaller than
echo x <= y | " Smaller than or equal
echo x is y | " Instance identity (lists and dictionaries)
echo x isnot y | " Instance non-identity (lists and dictionaries)
" Strings are compared based on their alphanumerical ordering
" echo 'a' < 'b'. Case sensitivity depends on the setting of 'ignorecase'
"
" Explicit case-sensitivity is specified by appending '#' (match case) or '?'
" (ignore case) to the operator. Prefer explicity case sensitivity when writing
" portable scripts.
echo 'a' < 'B' | " True or false depending on 'ignorecase'
echo 'a' <? 'B' | " True
echo 'a' <# 'B' | " False
" Regular expression matching
echo "hi" =~ "hello" | " Regular expression match, uses 'ignorecase'
echo "hi" =~# "hello" | " Regular expression match, case sensitive
echo "hi" =~? "hello" | " Regular expression match, case insensitive
echo "hi" !~ "hello" | " Regular expression unmatch, use 'ignorecase'
echo "hi" !~# "hello" | " Regular expression unmatch, case sensitive
echo "hi" !~? "hello" | " Regular expression unmatch, case insensitive
" Boolean operations are possible.
echo v:true && v:false | " Logical AND
echo v:true || v:false | " Logical OR
echo ! v:true | " Logical NOT
echo v:true ? 'yes' : 'no' | " Ternary operator
" Strings (|String|)
" #######
"
" An ordered zero-indexed sequence of bytes. The encoding of text into bytes
" depends on the option |'encoding'|.
" Literal constructors
echo "Hello world\n" | " The last two characters stand for newline
echo 'Hello world\n' | " The last two characters are literal
echo 'Let''s go!' | " Two single quotes become one quote character
" Single-quote strings take all characters are literal, except two single
" quotes, which are taken to be a single quote in the string itself. See
" |expr-quote| for all possible escape sequences.
" String concatenation
" The .. operator is preferred, but only supported in since Vim 8.1.1114
echo 'Hello ' . 'world' | " String concatenation
echo 'Hello ' .. 'world' | " String concatenation (new variant)
" String indexing
echo 'Hello'[0] | " First byte
echo 'Hello'[1] | " Second byte
echo 'Hellö'[4] | " Returns a byte, not the character 'ö'
" Substrings (second index is inclusive)
echo 'Hello'[:] | " Copy of entire string
echo 'Hello'[1:3] | " Substring, second to fourth byte
echo 'Hello'[1:-2] | " Substring until second to last byte
echo 'Hello'[1:] | " Substring with starting index
echo 'Hello'[:2] | " Substring with ending index
echo 'Hello'[-2:] | " Substring relative to end of string
" A negative index is relative to the end of the string. See
" |string-functions| for all string-related functions.
" Lists (|List|)
" #####
"
" An ordered zero-indexed heterogeneous sequence of arbitrary Vim script
" objects.
" Literal constructor
echo [] | " Empty list
echo [1, 2, 'Hello'] | " List with elements
echo [1, 2, 'Hello', ] | " Trailing comma permitted
echo [[1, 2], 'Hello'] | " Lists can be nested arbitrarily
" List concatenation
echo [1, 2] + [3, 4] | " Creates a new list
" List indexing, negative is relative to end of list (|list-index|)
echo [1, 2, 3, 4][2] | " Third element
echo [1, 2, 3, 4][-1] | " Last element
" List slicing (|sublist|)
echo [1, 2, 3, 4][:] | " Shallow copy of entire list
echo [1, 2, 3, 4][:2] | " Sublist until third item (inclusive)
echo [1, 2, 3, 4][2:] | " Sublist from third item (inclusive)
echo [1, 2, 3, 4][:-2] | " Sublist until second-to-last item (inclusive)
" All slicing operations create new lists. To modify a list in-place use list
" functions (|list-functions|) or assign directly to an item (see below about
" variables).
" Dictionaries (|Dictionary|)
" ############
"
" An unordered sequence of key-value pairs, keys are always strings (numbers
" are implicitly converted to strings).
" Dictionary literal
echo {} | " Empty dictionary
echo {'a': 1, 'b': 2} | " Dictionary literal
echo {'a': 1, 'b': 2, } | " Trailing comma permitted
echo {'x': {'a': 1, 'b': 2}} | " Nested dictionary
" Indexing a dictionary
echo {'a': 1, 'b': 2}['a'] | " Literal index
echo {'a': 1, 'b': 2}.a | " Syntactic sugar for simple keys
" See |dict-functions| for dictionary manipulation functions.
" Funcref (|Funcref|)
" #######
"
" Reference to a function, uses the function name as a string for construction.
" When stored in a variable the name of the variable has the same restrictions
" as a function name (see below).
echo function('type') | " Reference to function type()
" Note that `funcref('type')` will throw an error because the argument must be
" a user-defined function; see further below for defining your own functions.
echo funcref('type') | " Reference by identity, not name
" A lambda (|lambda|) is an anonymous function; it can only contain one
" expression in its body, which is also its implicit return value.
echo {x -> x * x} | " Anonymous function
echo function('substitute', ['hello']) | " Partial function
" Regular expression (|regular-expression|)
" ##################
"
" A regular expression pattern is generally a string, but in some cases you can
" also use a regular expression between a pair of delimiters (usually `/`, but
" you can choose anything).
" Substitute 'hello' for 'Hello'
substitute/hello/Hello/
" ###########################
" Implicit type conversions
" ###########################
"
" Strings are converted to numbers, and numbers to strings when necessary. A
" number becomes its decimal notation as a string. A string becomes its
" numerical value if it can be parsed to a number, otherwise it becomes zero.
echo "1" + 1 | " Number
echo "1" .. 1 | " String
echo "0xA" + 1 | " Number
" Strings are treated like numbers when used as booleans
echo "true" ? 1 : 0 | " This string is parsed to 0, which is false
" ###########
" Variables
" ###########
"
" Variables are bound within a scope; if no scope is provided a default is
" chosen by Vim. Use `:let` and `:const` to bind a value and `:unlet` to unbind
" it.
let b:my_var = 1 | " Local to current buffer
let w:my_var = 1 | " Local to current window
let t:my_var = 1 | " Local to current tab page
let g:my_var = 1 | " Global variable
let l:my_var = 1 | " Local to current function (see functions below)
let s:my_var = 1 | " Local to current script file
let a:my_arg = 1 | " Function argument (see functions below)
" The Vim scope is read-only
echo v:true | " Special built-in Vim variables (|v:var|)
" Access special Vim memory like variables
let @a = 'Hello' | " Register
let $PATH='' | " Environment variable
let &textwidth = 79 | " Option
let &l:textwidth = 79 | " Local option
let &g:textwidth = 79 | " Global option
" Access scopes as dictionaries (can be modified like all dictionaries)
" See the |dict-functions|, especially |get()|, for access and manipulation
echo b: | " All buffer variables
echo w: | " All window variables
echo t: | " All tab page variables
echo g: | " All global variables
echo l: | " All local variables
echo s: | " All script variables
echo a: | " All function arguments
echo v: | " All Vim variables
" Constant variables
const x = 10 | " See |:const|, |:lockvar|
" Function reference variables have the same restrictions as function names
let IsString = {x -> type(x) == type('')} | " Global: capital letter
let s:isNumber = {x -> type(x) == type(0)} | " Local: any name allowed
" When omitted the scope `g:` is implied, except in functions, there `l:` is
" implied.
" Multiple value binding (list unpacking)
" #######################################
"
" Assign values of list to multiple variables (number of items must match)
let [x, y] = [1, 2]
" Assign the remainer to a rest variable (note the semicolon)
let [mother, father; children] = ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
" ##############
" Flow control
" ##############
" Conditional (|:if|, |:elseif|, |:else|, |:endif|)
" ###########
"
" Conditions are set between `if` and `endif`. They can be nested.
let condition = v:true
if condition
echo 'First condition'
elseif another_condition
echo 'Second condition'
else
echo 'Fail'
endif
" Loops (|:for|, |:endfor|, |:while|, |:endwhile|, |:break|, |:continue|)
" #####
"
" Two types of loops: `:for` and `:while`. Use `:continue` to skip to the next
" iteration, `:break` to break out of the loop.
" For-loop (|:for|, |:endfor|)
" ========
"
" For-loops iterate over lists and nothing else. If you want to iterate over
" another sequence you need to use a function which will create a list.
" Iterate over a list
for person in ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
echo 'Hello ' .. person
endfor
" Iterate over a nested list by unpacking it
for [x, y] in [[1, 0], [0, 1], [-1, 0], [0, -1]]
echo 'Position: x =' .. x .. ', y = ' .. y
endfor
" Iterate over a range of numbers
for i in range(10, 0, -1) " Count down from 10
echo 'T minus' .. i
endfor
" Iterate over the keys of a dictionary
for symbol in keys({'π': 3.14, 'e': 2.71})
echo 'The constant ' .. symbol .. ' is a transcendent number'
endfor
" Iterate over the values of a dictionary
for value in values({'π': 3.14, 'e': 2.71})
echo 'The value ' .. value .. ' approximates a transcendent number'
endfor
" Iterate over the keys and values of a dictionary
for [symbol, value] in items({'π': 3.14, 'e': 2.71})
echo 'The number ' .. symbol .. ' is approximately ' .. value
endfor
" While-loops (|:while|, |:endwhile|)
let there_yet = v:true
while !there_yet
echo 'Are we there yet?'
endwhile
" Exception handling (|exception-handling|)
" ##################
"
" Throw new exceptions as strings, catch them by pattern-matching a regular
" expression against the string
" Throw new exception
throw "Wrong arguments"
" Guard against an exception (the second catch matches any exception)
try
source path/to/file
catch /Cannot open/
echo 'Looks like that file does not exist'
catch /.*/
echo 'Something went wrong, but I don't know what'
finally
echo 'I'm done trying'
endtry
" ##########
" Functions
" ##########
" Defining functions (|:function|, |:endfunction|)
" ##################
" Unscoped function names have to start with a capital letter
function! AddNumbersLoudly(x, y)
" Use a: scope to access arguments
echo 'Adding' .. a:x .. 'and' .. a:y | " A side effect
return a:x + a:y | " A return value
endfunction
" Scoped function names may start with a lower-case letter
function! s:addNumbersLoudly(x, y)
echo 'Adding' .. a:x .. 'and' .. a:y
return a:x + a:y
endfunction
" Without the exclamation mark it would be an error to re-define a function,
" with the exclamation mark the new definition can replace the old one. Since
" Vim script files can be reloaded several times over the course of a session
" it is best to use the exclamation mark unless you really know what you are
" doing.
" Function definitions can have special qualifiers following the argument list.
" Range functions define two implicit arguments, which will be set to the range
" of the ex-command
function! FirstAndLastLine() range
echo [a:firstline, a:lastline]
endfunction
" Prints the first and last line that match a pattern (|cmdline-ranges|)
/^#!/,/!#$/call FirstAndLastLine()
" Aborting functions, abort once error occurs (|:func-abort|)
function! SourceMyFile() abort
source my-file.vim | " Try sourcing non-existing file
echo 'This will never be printed'
endfunction
" Closures, functions carrying values from outer scope (|:func-closure|)
function! MakeAdder(x)
function! Adder(n) closure
return a:n + a:x
endfunction
return funcref('Adder')
endfunction
let AddFive = MakeAdder(5)
echo AddFive(3) | " Prints 8
" Dictionary functions, poor man's OOP methods (|Dictionary-function|)
function! Mylen() dict
return len(self.data) | " Implicit variable self
endfunction
let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
echo mydict.len()
" Alternatively, more concise
let mydict = {'data': [0, 1, 2, 3]}
function! mydict.len()
return len(self.data)
endfunction
" Calling functions (|:call|)
" #################
" Call a function for its return value, and possibly for its side effects
let animals = keys({'cow': 'moo', 'dog': 'woof', 'cat': 'meow'})
" Call a function for its side effects only, ignore potential result
call sign_undefine()
" The call() function calls a function reference and passes parameters as a
" list, and returns the function's result.
echo call(function('get'), [{'a': 1, 'b': 2}, 'c', 3]) | " Prints 3
" Recall that Vim script is embedded within the ex-commands, that is why we
" cannot just call a function directly, we have to use the `:call` ex-command.
" Function namespaces (|write-library-script|, |autoload|)
" ###################
" Must be defined in autoload/foo/bar.vim
" Namspaced function names do not have to start with a capital letter
function! foo#bar#log(value)
echomsg value
endfunction
call foo#bar#log('Hello')
" #############################
" Frequently used ex-commands
" #############################
" Sourcing runtime files (|'runtimepath'|)
" ######################
" Source first match among runtime paths
runtime plugin/my-plugin.vim
" Defining new ex-commands (|40.2|, |:command|)
" ########################
" First argument here is the name of the command, rest is the command body
command! SwapAdjacentLines normal! ddp
" The exclamation mark works the same as with `:function`. User-defined
" commands must start with a capital letter. The `:command` command can take a
" number of attributes (some of which have their own parameters with `=`), such
" as `-nargs`, all of them start with a dash to set them apart from the command
" name.
:command -nargs=1 Error echoerr <args>
" Defining auto-commands (|40.3|, |autocmd|, |autocommand-events|)
" ######################
" The arguments are "events", "patterns", rest is "commands"
autocmd BufWritePost $MYVIMRC source $MYVIMRC
" Events and patterns are separated by commas with no space between. See
" |autocmd-events| for standard events, |User| for custom events. Everything
" else are the ex-commands which will be executed.
" Auto groups
" ===========
"
" When a file is sourced multiple times the auto-commands are defined anew,
" without deleting the old ones, causing auto-commands to pile up over time.
" Use auto-groups and the following ritual to guard against this.
augroup auto-source | " The name of the group is arbitrary
autocmd! | " Deletes all auto-commands in the current group
autocmd BufWritePost $MYVIMRC source $MYVIMRC
augroup END | " Switch back to default auto-group
" It is also possible to assign a group directly. This is useful if the
" definition of the group is in one script and the definition of the
" auto-command is in another script.
" In one file
augroup auto-source
autocmd!
augroup END
" In another file
autocmd auto-source BufWritePost $MYVIMRC source $MYVIMRC
" Executing (run-time macros of sorts)
" ####################################
" Sometimes we need to construct an ex-command where part of the command is not
" known until runtime.
let line = 3 | " Line number determined at runtime
execute line .. 'delete' | " Delete a line
" Executing normal-mode commands
" ##############################
"
" Use `:normal` to play back a sequence of normal mode commands from the
" command-line. Add an exclamation mark to ignore user mappings.
normal! ggddGp | " Transplant first line to end of buffer
" Window commands can be used with :normal, or with :wincmd if :normal would
" not work
wincmd L | " Move current window all the way to the right
" ###########################
" Frequently used functions
" ###########################
" Feature check
echo has('nvim') | " Running Neovim
echo has('python3') | " Support for Python 3 plugins
echo has('unix') | " Running on a Unix system
echo has('win32') | " Running on a Windows system
" Test if something exists
echo exists('&mouse') | " Option (exists only)
echo exists('+mouse') | " Option (exists and works)
echo exists('$HOSTNAME') | " Environment variable
echo exists('*strftime') | " Built-in function
echo exists('**s:MyFunc') | " User-defined function
echo exists('bufcount') | " Variable (scope optional)
echo exists('my_dict["foo"]') | " Variable (dictionary entry)
echo exists('my_dict["foo"]') | " Variable (dictionary entry)
echo exists(':Make') | " Command
echo exists("#CursorHold") | " Auto-command defined for event
echo exists("#BufReadPre#*.gz") | " Event and pattern
echo exists("#filetypeindent") | " Auto-command group
echo exists("##ColorScheme") | " Auto-commnand supported for event
" Various dynamic values (see |expand()|)
echo expand('%') | " Current file name
echo expand('<cword>') | " Current word under cursor
echo expand('%:p') | " Modifier are possible
" Type tests
echo type(my_var) == type(0) | " Number
echo type(my_var) == type('') | " String
echo type(my_var) == type([]) | " List
echo type(my_var) == type({}) | " Dictionary
echo type(my_var) == type(function('type')) | " Funcref
" Format strings
echo printf('%d in hexadecimal is %X', 123, 123)
" #####################
" Tricks of the trade
" #####################
" Source guard
" ############
" Prevent a file from being source multiple times; users can set the variable
" in their configuration to prevent the plugin from loading at all.
if exists('g:loaded_my_plugin')
finish
endif
let g:loaded_my_plugin = v:true
" Default values
" ##############
" Get a default value: if the user defines a variable use it, otherwise use a
" hard-coded default. Uses the fact that a scope is also a dictionary.
let s:greeting = get(g:, 'my_plugin_greeting', 'Hello')
```

View File

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

View File

@ -132,7 +132,7 @@ div.some-parent.class-name {}
font-family: Arial;
font-family: "Courier New"; /* 使用双引号包裹含空格的字体名称 */
font-family: "Courier New", Trebuchet, Arial; /* 如果第一个
字体没找到浏览器会使用第二个字体一次类推 */
字体没找到浏览器会使用第二个字体以此类推 */
}
```

View File

@ -234,7 +234,7 @@ $ git diff HEAD
# 在搜索结果中显示行号
$ git config --global grep.lineNumber true
# 搜索结果可读性更好
# 使得搜索结果可读性更好
$ git config --global alias.g "grep --break --heading --line-number"
```

View File

@ -211,7 +211,7 @@ GitHub 也支持 Markdown在 GitHub 的 Markdown 解析器中,我们可以
内联代码可由反引号 ` 实现
```md
John 甚至不知道 `go_to()` 方程是干嘛的!
John 甚至不知道 `go_to()` 函数是干嘛的!
```
在GitHub的 MarkdownGitHub Flavored Markdown解析器中你可以使用特殊的语法表示代码块

View File

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

View File

@ -444,7 +444,7 @@ n ; => 6
(set-box! n* (add1 (unbox n*)))
(unbox n*) ; => 6
;; 很多 Racket 诗句类型是不可变的 (对,列表,等),有一些既是可变的
;; 很多 Racket 数据类型是不可变的 (对,列表,等),有一些既是可变的
;; 又是不可变的 (字符串,向量,散列表
;; 等...)

View File

@ -16,6 +16,8 @@ YAML 根本不容许文字制表符。
```yaml
--- # 文档开头
# YAML 中的注解看起来像这样。
################
@ -135,7 +137,7 @@ bar: &bar
# foo 和 bar 将都含有 name: Everyone has same name
# YAML 还有标签,你可以用它显地声明类型。
# YAML 还有标签,你可以用它显地声明类型。
explicit_string: !!str 0.5
# 一些解析器实现特定语言的标签,就像这个针对 Python 的复数类型。
python_complex_number: !!python/complex 1+2j
@ -176,7 +178,7 @@ set2:
item2: null
item3: null
... # document end
... # 文档结束
```
### 更多资源