diff options
| -rw-r--r-- | coffeescript.html.markdown | 55 | ||||
| -rw-r--r-- | elisp.html.markdown | 353 | ||||
| -rw-r--r-- | elixir.html.markdown | 6 | ||||
| -rw-r--r-- | erlang.html.markdown | 48 | ||||
| -rw-r--r-- | git.html.markdown | 388 | ||||
| -rw-r--r-- | haskell.html.markdown | 5 | ||||
| -rw-r--r-- | java.html.markdown | 108 | ||||
| -rw-r--r-- | javascript.html.markdown | 5 | ||||
| -rw-r--r-- | livescript.html.markdown | 345 | ||||
| -rw-r--r-- | lua.html.markdown | 2 | ||||
| -rw-r--r-- | php.html.markdown | 19 | ||||
| -rw-r--r-- | racket.html.markdown | 607 | ||||
| -rw-r--r-- | ruby.html.markdown | 22 | ||||
| -rw-r--r-- | whip.html.markdown | 237 | ||||
| -rwxr-xr-x | zh-cn/c-cn.html.markdown | 394 | ||||
| -rwxr-xr-x | zh-cn/elisp-cn.html.markdown | 340 | ||||
| -rwxr-xr-x | zh-cn/java-cn.html.markdown | 404 | ||||
| -rwxr-xr-x | zh-cn/php-cn.html.markdown | 635 | 
18 files changed, 3897 insertions, 76 deletions
| diff --git a/coffeescript.html.markdown b/coffeescript.html.markdown new file mode 100644 index 00000000..429f10b5 --- /dev/null +++ b/coffeescript.html.markdown @@ -0,0 +1,55 @@ +--- +language: coffeescript +contributors: +  - ["Tenor Biel", "http://github.com/L8D"] +filename: coffeescript.coffee +--- + +``` coffeescript +# CoffeeScript is a hipster language. +# It goes with the trends of many modern languages. +# So comments are like Ruby and Python, they use hashes. + +### +Block comments are like these, and they translate directly to '/ *'s and '* /'s +for the resulting JavaScript code. + +You should understand most of JavaScript semantices +before continuing. +### + +# Assignment: +number   = 42 #=> var number = 42; +opposite = true #=> var opposite = true; + +# Conditions: +number = -42 if opposite #=> if(opposite) { number = -42; } + +# Functions: +square = (x) -> x * x #=> var square = function(x) { return x * x; } + +# Ranges: +list = [1..5] #=> var list = [1, 2, 3, 4, 5]; + +# Objects: +math = +  root:   Math.sqrt +  square: square +  cube:   (x) -> x * square x +#=> var math = { +#  "root": Math.sqrt, +#  "square": square, +#  "cube": function(x) { return x * square(x); } +#} + +# Splats: +race = (winner, runners...) -> +  print winner, runners + +# Existence: +alert "I knew it!" if elvis? +#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } + +# Array comprehensions: +cubes = (math.cube num for num in list) #=> ... +``` diff --git a/elisp.html.markdown b/elisp.html.markdown new file mode 100644 index 00000000..d3910759 --- /dev/null +++ b/elisp.html.markdown @@ -0,0 +1,353 @@ +--- +language: elisp +contributors: +    - ["Bastien Guerry", "http://bzg.fr"] +filename: learn-emacs-lisp.el +--- + +```scheme +;; This gives an introduction to Emacs Lisp in 15 minutes (v0.2d) +;; +;; Author: Bastien / @bzg2 / http://bzg.fr +;; +;; First make sure you read this text by Peter Norvig: +;; http://norvig.com/21-days.html +;; +;; Then install GNU Emacs 24.3: +;; +;; Debian: apt-get install emacs (or see your distro instructions) +;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg +;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip +;; +;; More general information can be found at: +;; http://www.gnu.org/software/emacs/#Obtaining + +;; Important warning: +;; +;; Going through this tutorial won't damage your computer unless +;; you get so angry that you throw it on the floor.  In that case, +;; I hereby decline any responsability.  Have fun! + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;  +;; Fire up Emacs. +;; +;; Hit the `q' key to dismiss the welcome message. +;; +;; Now look at the gray line at the bottom of the window: +;; +;; "*scratch*" is the name of the editing space you are now in. +;; This editing space is called a "buffer". +;; +;; The scratch buffer is the default buffer when opening Emacs. +;; You are never editing files: you are editing buffers that you +;; can save to a file. +;;  +;; "Lisp interaction" refers to a set of commands available here. +;;  +;; Emacs has a built-in set of commands available in every buffer, +;; and several subsets of commands available when you activate a +;; specific mode.  Here we use the `lisp-interaction-mode', which +;; comes with commands to evaluate and navigate within Elisp code. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Semi-colons start comments anywhere on a line. +;; +;; Elisp programs are made of symbolic expressions ("sexps"): +(+ 2 2) + +;; This symbolic expression reads as "Add 2 to 2". + +;; Sexps are enclosed into parentheses, possibly nested: +(+ 2 (+ 1 1)) + +;; A symbolic expression contains atoms or other symbolic +;; expressions.  In the above examples, 1 and 2 are atoms, +;; (+ 2 (+ 1 1)) and (+ 1 1) are symbolic expressions. + +;; From `lisp-interaction-mode' you can evaluate sexps. +;; Put the cursor right after the closing parenthesis then +;; hold down the control and hit the j keys ("C-j" for short). + +(+ 3 (+ 1 2)) +;;           ^ cursor here +;; `C-j' => 6 + +;; `C-j' inserts the result of the evaluation in the buffer. + +;; `C-xC-e' displays the same result in Emacs bottom line, +;; called the "minibuffer".  We will generally use `C-xC-e', +;; as we don't want to clutter the buffer with useless text. + +;; `setq' stores a value into a variable: +(setq my-name "Bastien") +;; `C-xC-e' => "Bastien" (displayed in the mini-buffer) + +;; `insert' will insert "Hello!" where the cursor is: +(insert "Hello!") +;; `C-xC-e' => "Hello!" + +;; We used `insert' with only one argument "Hello!", but +;; we can pass more arguments -- here we use two: + +(insert "Hello" " world!") +;; `C-xC-e' => "Hello world!" + +;; You can use variables instead of strings: +(insert "Hello, I am " my-name) +;; `C-xC-e' => "Hello, I am Bastien" + +;; You can combine sexps into functions: +(defun hello () (insert "Hello, I am " my-name)) +;; `C-xC-e' => hello + +;; You can evaluate functions: +(hello) +;; `C-xC-e' => Hello, I am Bastien + +;; The empty parentheses in the function's definition means that +;; it does not accept arguments.  But always using `my-name' is +;; boring, let's tell the function to accept one argument (here +;; the argument is called "name"):  + +(defun hello (name) (insert "Hello " name)) +;; `C-xC-e' => hello + +;; Now let's call the function with the string "you" as the value +;; for its unique argument: +(hello "you") +;; `C-xC-e' => "Hello you" + +;; Yeah! + +;; Take a breath. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Now switch to a new buffer named "*test*" in another window: + +(switch-to-buffer-other-window "*test*") +;; `C-xC-e' +;; => [screen has two windows and cursor is in the *test* buffer] + +;; Mouse over the top window and left-click to go back.  Or you can +;; use `C-xo' (i.e. hold down control-x and hit o) to go to the other +;; window interactively. + +;; You can combine several sexps with `progn': +(progn +  (switch-to-buffer-other-window "*test*") +  (hello "you")) +;; `C-xC-e' +;; => [The screen has two windows and cursor is in the *test* buffer] + +;; Now if you don't mind, I'll stop asking you to hit `C-xC-e': do it +;; for every sexp that follows. + +;; Always go back to the *scratch* buffer with the mouse or `C-xo'. + +;; It's often useful to erase the buffer: +(progn +  (switch-to-buffer-other-window "*test*") +  (erase-buffer) +  (hello "there")) + +;; Or to go back to the other window: +(progn +  (switch-to-buffer-other-window "*test*") +  (erase-buffer) +  (hello "you") +  (other-window 1)) + +;; You can bind a value to a local variable with `let': +(let ((local-name "you")) +  (switch-to-buffer-other-window "*test*") +  (erase-buffer) +  (hello local-name) +  (other-window 1)) + +;; No need to use `progn' in that case, since `let' also combines +;; several sexps. + +;; Let's format a string: +(format "Hello %s!\n" "visitor") + +;; %s is a place-holder for a string, replaced by "visitor". +;; \n is the newline character. + +;; Let's refine our function by using format: +(defun hello (name) +  (insert (format "Hello %s!\n" name))) + +(hello "you") + +;; Let's create another function which uses `let': +(defun greeting (name) +  (let ((your-name "Bastien")) +    (insert (format "Hello %s!\n\nI am %s." +                    name       ; the argument of the function +                    your-name  ; the let-bound variable "Bastien" +                    )))) + +;; And evaluate it: +(greeting "you") + +;; Some function are interactive: +(read-from-minibuffer "Enter your name: ") + +;; Evaluating this function returns what you entered at the prompt. + +;; Let's make our `greeting' function prompt for your name: +(defun greeting (from-name) +  (let ((your-name (read-from-minibuffer "Enter your name: "))) +    (insert (format "Hello!\n\nI am %s and you are %s." +                    from-name ; the argument of the function +                    your-name ; the let-bound var, entered at prompt +                    )))) + +(greeting "Bastien") + +;; Let's complete it by displaying the results in the other window: +(defun greeting (from-name) +  (let ((your-name (read-from-minibuffer "Enter your name: "))) +    (switch-to-buffer-other-window "*test*") +    (erase-buffer) +    (insert (format "Hello %s!\n\nI am %s." your-name from-name)) +    (other-window 1))) + +;; Now test it: +(greeting "Bastien") + +;; Take a breath. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Let's store a list of names: +(setq list-of-names '("Sarah" "Chloe" "Mathilde")) + +;; Get the first element of this list with `car': +(car list-of-names) + +;; Get a list of all but the first element with `cdr': +(cdr list-of-names) + +;; Add an element to the beginning of a list with `push': +(push "Stephanie" list-of-names) + +;; NOTE: `car' and `cdr' don't modify the list, but `push' does. +;; This is an important difference: some functions don't have any +;; side-effects (like `car') while others have (like `push'). + +;; Let's call `hello' for each element in `list-of-names': +(mapcar 'hello list-of-names) + +;; Refine `greeting' to say hello to everyone in `list-of-names': +(defun greeting () +    (switch-to-buffer-other-window "*test*") +    (erase-buffer) +    (mapcar 'hello list-of-names) +    (other-window 1)) + +(greeting) + +;; Remember the `hello' function we defined above?  It takes one +;; argument, a name.  `mapcar' calls `hello', successively using each +;; element of `list-of-names' as the argument for `hello'. + +;; Now let's arrange a bit what we have in the displayed buffer: + +(defun replace-hello-by-bonjour () +    (switch-to-buffer-other-window "*test*") +    (goto-char (point-min)) +    (while (search-forward "Hello") +      (replace-match "Bonjour")) +    (other-window 1)) + +;; (goto-char (point-min)) goes to the beginning of the buffer. +;; (search-forward "Hello") searches for the string "Hello". +;; (while x y) evaluates the y sexp(s) while x returns something. +;; If x returns `nil' (nothing), we exit the while loop. + +(replace-hello-by-bonjour) + +;; You should see all occurrences of "Hello" in the *test* buffer +;; replaced by "Bonjour". + +;; You should also get an error: "Search failed: Hello". +;; +;; To avoid this error, you need to tell `search-forward' whether it +;; should stop searching at some point in the buffer, and whether it +;; should silently fail when nothing is found: + +;; (search-forward "Hello" nil t) does the trick: + +;; The `nil' argument says: the search is not bound to a position. +;; The `t' argument says: silently fail when nothing is found. + +;; We use this sexp in the function below, which doesn't throw an error: + +(defun hello-to-bonjour () +    (switch-to-buffer-other-window "*test*") +    (erase-buffer) +    ;; Say hello to names in `list-of-names' +    (mapcar 'hello list-of-names) +    (goto-char (point-min)) +    ;; Replace "Hello" by "Bonjour" +    (while (search-forward "Hello" nil t) +      (replace-match "Bonjour")) +    (other-window 1)) + +(hello-to-bonjour) + +;; Let's colorize the names: + +(defun boldify-names () +    (switch-to-buffer-other-window "*test*") +    (goto-char (point-min)) +    (while (re-search-forward "Bonjour \\(.+\\)!" nil t) +      (add-text-properties (match-beginning 1) +                           (match-end 1) +                           (list 'face 'bold))) +    (other-window 1)) + +;; This functions introduces `re-search-forward': instead of +;; searching for the string "Bonjour", you search for a pattern, +;; using a "regular expression" (abbreviated in the prefix "re-"). + +;; The regular expression is "Bonjour \\(.+\\)!" and it reads: +;; the string "Bonjour ", and +;; a group of           | this is the \\( ... \\) construct +;;   any character      | this is the . +;;   possibly repeated  | this is the + +;; and the "!" string. + +;; Ready?  Test it! + +(boldify-names) + +;; `add-text-properties' adds... text properties, like a face. + +;; OK, we are done.  Happy hacking! + +;; If you want to know more about a variable or a function: +;; +;; C-h v a-variable RET +;; C-h f a-function RET +;; +;; To read the Emacs Lisp manual with Emacs: +;; +;; C-h i m elisp RET +;; +;; To read an online introduction to Emacs Lisp: +;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html + +;; Thanks to these people for their feedback and suggestions: +;; - Wes Hardaker +;; - notbob +;; - Kevin Montuori +;; - Arne Babenhauserheide +;; - Alan Schmitt +;; - LinXitoW +;; - Aaron Meurer +``` diff --git a/elixir.html.markdown b/elixir.html.markdown index 3a11ce1f..8ea499ff 100644 --- a/elixir.html.markdown +++ b/elixir.html.markdown @@ -33,7 +33,7 @@ and many more features.  # Atoms, that are literals, a constant with name. They start with `:`.  :hello # atom -# Tuples that are stored contigously in memory. +# Tuples that are stored contiguously in memory.  {1,2,3} # tuple  # We can access a tuple element with the `elem` function: @@ -47,7 +47,7 @@ elem({1, 2, 3}, 0) #=> 1  head #=> 1  tail #=> [2,3] -# In elixir, just like in erlang, the `=` denotes pattern matching and +# In elixir, just like in Erlang, the `=` denotes pattern matching and  # not an assignment.  #  # This means that the left-hand side (pattern) is matched against a @@ -170,7 +170,7 @@ case {:one, :two} do      "This will match any value"  end -# It's common practive to assign a value to `_` if we don't need it. +# It's common practice to assign a value to `_` if we don't need it.  # For example, if only the head of a list matters to us:  [head | _] = [1,2,3]  head #=> 1 diff --git a/erlang.html.markdown b/erlang.html.markdown index 208f31e4..065219ba 100644 --- a/erlang.html.markdown +++ b/erlang.html.markdown @@ -1,12 +1,12 @@  ---  language: erlang -contributor: +contributors:      - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]  filename: learnerlang.erl  ---  ```erlang -% Percent sign start a one-line comment. +% Percent sign starts a one-line comment.  %% Two percent characters shall be used to comment functions. @@ -17,7 +17,7 @@ filename: learnerlang.erl  % patterns.  % Periods (`.`) (followed by whitespace) separate entire functions and  % expressions in the shell. -% Semicolons (`;`) separate clauses. We find clauses in several contexts: in kn +% Semicolons (`;`) separate clauses. We find clauses in several contexts:  % function definitions and in `case`, `if`, `try..catch` and `receive`  % expressions. @@ -26,8 +26,10 @@ filename: learnerlang.erl  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  Num = 42.  % All variable names must start with an uppercase letter. +  % Erlang has single assignment variables, if you try to assign a different value  % to the variable `Num`, you’ll get an error. +Num = 43. % ** exception error: no match of right hand side value 43  % In most languages, `=` denotes an assignment statement. In Erlang, however,  % `=` denotes a pattern matching operation. `Lhs = Rhs` really means this: @@ -42,6 +44,11 @@ Pi = 3.14159.  % start with lowercase letters, followed by a sequence of alphanumeric  % characters or the underscore (`_`) or at (`@`) sign.  Hello = hello. +OtherNode = example@node. + +% Atoms with non alphanumeric values can be written by enclosing the atoms +% with apostrophes. +AtomWithSpace = 'some atom with space'.  % Tuples are similar to structs in C.  Point = {point, 10, 45}. @@ -60,15 +67,15 @@ Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.  % We create a list by enclosing the list elements in square brackets and  % separating them with commas.  % The individual elements of a list can be of any type. -% The first element of a list the head of the list. If you imagine removing the +% The first element of a list is the head of the list. If you imagine removing the  % head from the list, what’s left is called the tail of the list.  ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}]. -% If `T` is a list, then `[H|T]` is also a list, with head H and tail T. +% If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`.  % The vertical bar (`|`) separates the head of a list from its tail.  % `[]` is the empty list.  % We can extract elements from a list with a pattern matching operation. If we -% have the nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y` +% have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`  % are unbound variables, will extract the head of the list into `X` and the tail  % of the list into `Y`.  [FirstThing|OtherThingsToBuy] = ThingsToBuy. @@ -78,6 +85,7 @@ ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].  % There are no strings in Erlang. Strings are really just lists of integers.  % Strings are enclosed in double quotation marks (`"`).  Name = "Hello". +[72, 101, 108, 108, 111] = "Hello".  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -89,9 +97,9 @@ Name = "Hello".  % Modules must be compiled before the code can be run. A compiled module has the  % extension `.beam`.  -module(geometry). --export([area/1]). +-export([area/1]). % the list of functions exported from the module. -% The function area consists of two clauses. The clauses are separated by a +% The function `area` consists of two clauses. The clauses are separated by a  % semicolon, and the final clause is terminated by dot-whitespace.  % Each clause has a head and a body; the head consists of a function name  % followed by a pattern (in parentheses), and the body consists of a sequence of @@ -109,17 +117,17 @@ c(geometry).  % {ok,geometry}  geometry:area({rectangle, 10, 5}).  % 50  geometry:area({circle, 1.4}).  % 6.15752 -% In Erlang, two functions with the same name and different arity in the same -% module represent entirely different functions. +% In Erlang, two functions with the same name and different arity (number of arguments) +% in the same module represent entirely different functions.  -module(lib_misc). --export([sum/1]). +-export([sum/1]). % export function `sum` of arity 1 accepting one argument: list of integers.  sum(L) -> sum(L, 0).  sum([], N)    -> N;  sum([H|T], N) -> sum(T, H+N). -% Funs are "anonymous" functions. They are called this because they have no -% name. -Double = fun(X) -> 2*X end. +% Funs are "anonymous" functions. They are called this way because they have no +% name. However they can be assigned to variables. +Double = fun(X) -> 2*X end. % `Double` points to an anonymous function with handle: #Fun<erl_eval.6.17052888>  Double(2).  % 4  % Functions accept funs as their arguments and can return funs. @@ -133,6 +141,8 @@ Triple(5).  % 15  % from the list `L`."  L = [1,2,3,4,5].  [2*X || X <- L].  % [2,4,6,8,10] +% A list comprehension can have generators and filters which select subset of the generated values. +EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]  % Guards are constructs that we can use to increase the power of pattern  % matching. Using guards, we can perform simple tests and comparisons on the @@ -181,7 +191,7 @@ X2 = X1#todo{status = done}.  % #todo{status = done,who = joe,text = "Fix errata in book"}  % `case` expressions. -% `filter` returns a list of all those elements `X` in `L` for which `P(X)` is +% `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is  % true.  filter(P, [H|T]) ->    case P(H) of @@ -189,6 +199,7 @@ filter(P, [H|T]) ->      false -> filter(P, T)    end;  filter(P, []) -> []. +filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]  % `if` expressions.  max(X, Y) -> @@ -198,7 +209,7 @@ max(X, Y) ->      true -> nil;    end. -% Warning: at least one of the guards in the if expression must evaluate to true; +% Warning: at least one of the guards in the `if` expression must evaluate to true;  % otherwise, an exception will be raised. @@ -234,6 +245,7 @@ catcher(N) -> catch generate_exception(N).  ## References -* "Programming Erlang: Software for a Concurrent World" by Joe Armstrong +* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/) +* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang) +* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)  * [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml) -* [Erlang/OTP Documentation](http://www.erlang.org/doc/) diff --git a/git.html.markdown b/git.html.markdown new file mode 100644 index 00000000..00f38d60 --- /dev/null +++ b/git.html.markdown @@ -0,0 +1,388 @@ +--- +category: tool +tool: git +contributors: +    - ["Jake Prather", "http:#github.com/JakeHP"] +filename: LearnGit.txt + +--- + +Git is a distributed version control and source code management system.  + +It does this through a series of snapshots of your project, and it works  +with those snapshots to provide you with functionality to version and  +manage your source code. + +## Versioning Concepts + +### What is version control? + +Version control is a system that records changes to a file, or set of files, over time. + +### Centralized Versioning VS Distributed Versioning + +* Centralized version control focuses on synchronizing, tracking, and backing up files. +* Distributed version control focuses on sharing changes. Every change has a unique id. +* Distributed systems have no defined structure. You could easily have a SVN style, 		centralized system, with git. + +[Additional Information](http://git-scm.com/book/en/Getting-Started-About-Version-Control) + +### Why Use Git? + +* Can work offline. +* Collaborating with others is easy! +* Branching is easy! +* Merging is easy! +* Git is fast. +* Git is flexible. + +## Git Architecture + + +### Repository + +A set of files, directories, historical records, commits, and heads. Imagine it as a source code datastructure,  +with the attribute that each source code "element" gives you access to its revision history, among other things. + +A git repository is comprised of the .git directory & working tree. + +### .git Directory (component of repository) + +The .git directory contains all the configurations, logs, branches, HEAD, and more. +[Detailed List.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) + +### Working Tree (component of repository) + +This is basically the directories and files in your repository. It is often referred to +as your working directory. + +### Index (component of .git dir) + +The Index is the staging area in git. It's basically a layer that separates your working tree +from the Git repository. This gives developers more power over what gets sent to the Git +repository. + +### Commit + +A git commit is a snapshot of a set of changes, or manipulations to your Working Tree. +For example, if you added 5 files, and removed 2 others, these changes will be contained +in a commit (or snapshot). This commit can then be pushed to other repositories, or not! + +### Branch + +A branch is essentially a pointer that points to the last commit you made. As you commit, +this pointer will automatically update and point to the latest commit. + +### HEAD and head (component of .git dir) + +HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD. +head is a pointer that points to any commit. A repository can have any number of heads. + +### Conceptual Resources + +* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) +* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html) + + +## Commands + + +### init + +Create an empty Git repository. The Git repository's settings, stored information,  +and more is stored in a directory (a folder) named ".git". + +```bash +$ git init +``` + +### config + +To configure settings. Whether it be for the repository, the system itself, or global +configurations. + + +```bash +# Print & Set Some Basic Config Variables (Global) +$ git config --global user.email +$ git config --global user.name + +$ git config --global user.email "MyEmail@Zoho.com" +$ git config --global user.name "My Name" +``` + +[Learn More About git config.](http://git-scm.com/docs/git-config) + +### help + +To give you quick access to an extremely detailed guide of each command. Or to +just give you a quick reminder of some semantics. + +```bash +# Quickly check available commands +$ git help + +# Check all available commands +$ git help -a + +# Command specific help - user manual +# git help <command_here> +$ git help add +$ git help commit +$ git help init +``` + +### status + +To show differences between the index file (basically your working copy/repo) and the current +HEAD commit. + + +```bash +# Will display the branch, untracked files, changes and other differences +$ git status + +# To learn other "tid bits" about git status +$ git help status +``` + +### add + +To add files to the current working tree/directory/repo. If you do not `git add` new files to the +working tree/directory, they will not be included in commits! + +```bash +# add a file in your current working directory +$ git add HelloWorld.java + +# add a file in a nested dir +$ git add /path/to/file/HelloWorld.c + +# Regular Expression support! +$ git add ./*.java +``` + +### branch + +Manage your branches. You can view, edit, create, delete branches using this command. + +```bash +# list existing branches & remotes +$ git branch -a + +# create a new branch +$ git branch myNewBranch + +# delete a branch +$ git branch -d myBranch + +# rename a branch +# git branch -m <oldname> <newname> +$ git branch -m myBranchName myNewBranchName + +# edit a branch's description +$ git branch myBranchName --edit-description +``` + +### checkout + +Updates all files in the working tree to match the version in the index, or specified tree. + +```bash +# Checkout a repo - defaults to master branch +$ git checkout +# Checkout a specified branch +$ git checkout branchName +# Create a new branch & switch to it, like: "git branch <name>; git checkout <name>" +$ git checkout -b newBranch +``` + +### clone + +Clones, or copies, an existing repository into a new directory. It also adds +remote-tracking branches for each branch in the cloned repo, which allows you to push +to a remote branch. + +```bash +# Clone learnxinyminutes-docs +$ git clone https://github.com/adambard/learnxinyminutes-docs.git +``` + +### commit + +Stores the current contents of the index in a new "commit." This commit contains +the changes made and a message created by the user. + +```bash +# commit with a message +$ git commit -m "Added multiplyNumbers() function to HelloWorld.c" +``` + +### diff + +Shows differences between a file in the working directory, index and commits. + +```bash +# Show difference between your working dir and the index +$ git diff + +# Show differences between the index and the most recent commit. +$ git diff --cached + +# Show differences between your working dir and the most recent commit +$ git diff HEAD +``` + +### grep + +Allows you to quickly search a repository. + +Optional Configurations: + +```bash +# Thanks to Travis Jeffery for these +# Set line numbers to be shown in grep search results +$ git config --global grep.lineNumber true + +# Make search results more readable, including grouping +$ git config --global alias.g "grep --break --heading --line-number" +``` + +```bash +# Search for "variableName" in all java files +$ git grep 'variableName' -- '*.java' + +# Search for a line that contains "arrayListName" and, "add" or "remove" +$ git grep -e 'arrayListName' --and \( -e add -e remove \)  +``` + +Google is your friend; for more examples +[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) + +### log + +Display commits to the repository. + +```bash +# Show all commits +$ git log + +# Show X number of commits +$ git log -n 10 + +# Show merge commits only +$ git log --merges +``` + +### merge + +"Merge" in changes from external commits into the current branch. + +```bash +# Merge the specified branch into the current. +$ git merge branchName + +# Always generate a merge commit when merging +$ git merge --no-ff branchName +``` + +### mv + +Rename or move a file	 + +```bash +# Renaming a file +$ git mv HelloWorld.c HelloNewWorld.c + +# Moving a file +$ git mv HelloWorld.c ./new/path/HelloWorld.c + +# Force rename or move +# "existingFile" already exists in the directory, will be overwritten +$ git mv -f myFile existingFile +``` + +### pull + +Pulls from a repository and merges it with another branch. + +```bash +# Update your local repo, by merging in new changes +# from the remote "origin" and "master" branch. +# git pull <remote> <branch> +$ git pull origin master +``` + +### push + +Push and merge changes from a branch to a remote & branch. + +```bash +# Push and merge changes from a local repo to a  +# remote named "origin" and "master" branch. +# git push <remote> <branch> +# git push => implicitly defaults to => git push origin master +$ git push origin master +``` + +### rebase (caution)  + +Take all changes that were committed on one branch, and replay them onto another branch. +*Do not rebase commits that you have pushed to a public repo*. + +```bash +# Rebase experimentBranch onto master +# git rebase <basebranch> <topicbranch> +$ git rebase master experimentBranch +``` + +[Additional Reading.](http://git-scm.com/book/en/Git-Branching-Rebasing) + +### reset (caution) + +Reset the current HEAD to the specified state. This allows you to undo merges, +pulls, commits, adds, and more. It's a great command but also dangerous if you don't +know what you are doing. + +```bash +# Reset the staging area, to match the latest commit (leaves dir unchanged) +$ git reset + +# Reset the staging area, to match the latest commit, and overwrite working dir +$ git reset --hard + +# Moves the current branch tip to the specified commit (leaves dir unchanged) +# all changes still exist in the directory. +$ git reset 31f2bb1 + +# Moves the current branch tip backward to the specified commit +# and makes the working dir match (deletes uncommited changes and all commits +# after the specified commit). +$ git reset --hard 31f2bb1 +``` + +### rm + +The opposite of git add, git rm removes files from the current working tree. + +```bash +# remove HelloWorld.c +$ git rm HelloWorld.c + +# Remove a file from a nested dir +$ git rm /pather/to/the/file/HelloWorld.c +``` + +## Further Information + +* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1) + +* [git-scm - Video Tutorials](http://git-scm.com/videos) + +* [git-scm - Documentation](http://git-scm.com/docs) + +* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/) + +* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) + +* [GitGuys](http://www.gitguys.com/) diff --git a/haskell.html.markdown b/haskell.html.markdown index 34df4d08..be7d8669 100644 --- a/haskell.html.markdown +++ b/haskell.html.markdown @@ -412,5 +412,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater  Haskell is easy to install. Get it [here](http://www.haskell.org/platform/). -You can find a much gentler introduction from the excellent [Learn you a Haskell](http://learnyouahaskell.com/) - +You can find a much gentler introduction from the excellent +[Learn you a Haskell](http://learnyouahaskell.com/) or +[Real World Haskell](http://book.realworldhaskell.org/). diff --git a/java.html.markdown b/java.html.markdown index 785a2cb9..b4531635 100644 --- a/java.html.markdown +++ b/java.html.markdown @@ -15,6 +15,10 @@ Java is a general-purpose, concurrent, class-based, object-oriented computer pro  /*  Multi-line comments look like this.  */ +/** +JavaDoc comments look like this. Used to describe the Class or various +attributes of a Class. +*/  // Import ArrayList class inside of the java.util package  import java.util.ArrayList; @@ -59,11 +63,15 @@ public class LearnJava {          // Long - 64-bit signed two's complement integer          // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)          long fooLong = 100000L; +        // L is used to denote that this variable value is of type Long; +        // anything without is treated as integer by default. -        // (Java has no unsigned types) +        // Note: Java has no unsigned types          // Float - Single-precision 32-bit IEEE 754 Floating Point          float fooFloat = 234.5f; +        // f is used to denote that this variable value is of type float; +        // otherwise it is treated as double.          // Double - Double-precision 64-bit IEEE 754 Floating Point          double fooDouble = 123.4; @@ -83,8 +91,11 @@ public class LearnJava {          // \n is an escaped character that starts a new line          String barString = "Printing on a new line?\nNo Problem!"; +        // \t is an escaped character that adds a tab character +        String bazString = "Do you want to add a tab?\tNo Problem!";          System.out.println(fooString);          System.out.println(barString); +        System.out.println(bazString);          // Arrays          //The array size must be decided upon declaration @@ -128,12 +139,12 @@ public class LearnJava {          System.out.println("11%3 = "+(11 % 3)); // => 2          // Comparison operators -        System.out.println("3 == 2? " + (3 == 2)); // => 0 (false) -        System.out.println("3 != 2? " + (3 != 2)); // => 1 (true) -        System.out.println("3 > 2? " + (3 > 2)); // => 1 -        System.out.println("3 < 2? " + (3 < 2)); // => 0 -        System.out.println("2 <= 2? " + (2 <= 2)); // => 1 -        System.out.println("2 >= 2? " + (2 >= 2)); // => 1 +        System.out.println("3 == 2? " + (3 == 2)); // => false +        System.out.println("3 != 2? " + (3 != 2)); // => true +        System.out.println("3 > 2? " + (3 > 2)); // => true +        System.out.println("3 < 2? " + (3 < 2)); // => false +        System.out.println("2 <= 2? " + (2 <= 2)); // => true +        System.out.println("2 >= 2? " + (2 >= 2)); // => true          // Bitwise operators!          /* @@ -147,7 +158,7 @@ public class LearnJava {          */          // Incrementations -        int i=0; +        int i = 0;          System.out.println("\n->Inc/Dec-rementation");          System.out.println(i++); //i = 1. Post-Incrementation          System.out.println(++i); //i = 2. Pre-Incrementation @@ -160,12 +171,13 @@ public class LearnJava {          System.out.println("\n->Control Structures");          // If statements are c-like -        if (false){ -            System.out.println("I never run"); -        }else if (false) { -            System.out.println("I am also never run"); +        int j = 10; +        if (j == 10){ +            System.out.println("I get printed"); +        } else if (j > 10) { +            System.out.println("I don't");          } else { -            System.out.println("I print"); +            System.out.println("I also don't");          }          // While loop @@ -200,16 +212,24 @@ public class LearnJava {          System.out.println("fooFor Value: " + fooFor);          // Switch Case +        // A switch works with the byte, short, char, and int data types. +        // It also works with enumerated types (discussed in Enum Types), +        // the String class, and a few special classes that wrap +        // primitive types: Character, Byte, Short, and Integer.          int month = 3;          String monthString;          switch (month){ -            case 1:  monthString = "January"; +            case 1: +                    monthString = "January";                      break; -            case 2:  monthString = "February"; +            case 2: +                    monthString = "February";                      break; -            case 3:  monthString = "March"; +            case 3: +                    monthString = "March";                      break; -            default: monthString = "Some other month"; +            default: +                    monthString = "Some other month";                      break;          }          System.out.println("Switch Case Result: " + monthString); @@ -251,10 +271,10 @@ public class LearnJava {          Bicycle trek = new Bicycle();          // Call object methods -        trek.speedUp(3); +        trek.speedUp(3); // You should always use setter and getter methods          trek.setCadence(100); -        // toString is a convention +        // toString is a convention to display the value of this Object.          System.out.println("trek info: " + trek.toString());      } // End main method @@ -266,15 +286,17 @@ public class LearnJava {  // Class Declaration Syntax:  // <public/private/protected> class <class name>{ -//    //data fields, constructors, functions all inside +//    //data fields, constructors, functions all inside. +//    //functions are called as methods in Java.  // }  class Bicycle {      // Bicycle's Fields/Variables      public int cadence; // Public: Can be accessed from anywhere -    private int speed;  // Private: Only accessable from within the class +    private int speed;  // Private: Only accessible from within the class      protected int gear; // Protected: Accessible from the class and subclasses +    String name; // default: Only accessible from within this package      // Constructors are a way of creating classes      // This is a default constructor @@ -282,13 +304,15 @@ class Bicycle {          gear = 1;          cadence = 50;          speed = 5; +        name = "Bontrager";      }      // This is a specified constructor (it contains arguments) -    public Bicycle(int startCadence, int startSpeed, int startGear) { -        gear = startGear; -        cadence = startCadence; -        speed = startSpeed; +    public Bicycle(int startCadence, int startSpeed, int startGear, String name) { +        this.gear = startGear; +        this.cadence = startCadence; +        this.speed = startSpeed; +        this.name = name;      }      // Function Syntax: @@ -319,10 +343,21 @@ class Bicycle {          speed -= decrement;      } +    public void setName(String newName) { +        name = newName; +    } + +    public String getName() { +        return name; +    } + +    //Method to display the attribute values of this Object. +    @Override      public String toString() { -        return "gear: "+Integer.toString(gear)+ -                " cadence: "+Integer.toString(cadence)+ -                " speed: "+Integer.toString(speed); +        return "gear: " + gear + +                " cadence: " + cadence + +                " speed: " + speed + +                " name: " + name;      }  } // end class Bicycle @@ -333,10 +368,12 @@ class PennyFarthing extends Bicycle {      public PennyFarthing(int startCadence, int startSpeed){          // Call the parent constructor with super -        super(startCadence, startSpeed, 0); +        super(startCadence, startSpeed, 0, "PennyFarthing");      }      // You should mark a method you're overriding with an @annotation +    // To learn more about what annotations are and their purpose +    // check this out: http://docs.oracle.com/javase/tutorial/java/annotations/      @Override      public void setGear(int gear) {          gear = 0; @@ -348,13 +385,18 @@ class PennyFarthing extends Bicycle {  ## Further Reading +The links provided here below are just to get an understanding of the topic, feel free to Google and find specific examples. +  Other Topics To Research: -* [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) +* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html) -* [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) +* [Java Access level modifiers](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) -* [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) +* [Object-Oriented Programming Concepts](http://docs.oracle.com/javase/tutorial/java/concepts/index.html): +    * [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) +    * [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) +    * [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)  * [Exceptions](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) @@ -363,5 +405,3 @@ Other Topics To Research:  * [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)  * [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html) - -* The links provided are just to get an understanding of the topic, feel free to google and find specific examples diff --git a/javascript.html.markdown b/javascript.html.markdown index 254163e8..9cc7617d 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -364,7 +364,7 @@ myObj.meaningOfLife // = 43  // are given when they're created with that constructor and the new keyword.  myConstructor.prototype = {      getMyNumber: function(){ -        return self.myNumber +        return this.myNumber      }  }  var myNewObj2 = new myConstructor() @@ -427,6 +427,9 @@ more about how to use JavaScript in web pages, start by learning about the  [Document Object  Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) +[Javascript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth +guide of all the counter-intuitive parts of the language. +  In addition to direct contributors to this article, some content is adapted  from Louie Dinh's Python tutorial on this site, and the [JS  Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) diff --git a/livescript.html.markdown b/livescript.html.markdown new file mode 100644 index 00000000..8e11439b --- /dev/null +++ b/livescript.html.markdown @@ -0,0 +1,345 @@ +--- +language: LiveScript +filename: learnLivescript.ls +contributors: +    - ["Christina Whyte", "http://github.com/kurisuwhyte/"] +--- + +LiveScript is a functional compile-to-JavaScript language which shares +most of the underlying semantics with its host language. Nice additions +comes with currying, function composition, pattern matching and lots of +other goodies heavily borrowed from languages like Haskell, F# and +Scala. + +LiveScript is a fork of [Coco][], which is itself a fork of +[CoffeeScript][]. The language is stable, and a new version is in active +development to bring a plethora of new niceties! + +[Coco]: http://satyr.github.io/coco/ +[CoffeeScript]: http://coffeescript.org/ + +Feedback is always welcome, so feel free to reach me over at +[@kurisuwhyte](https://twitter.com/kurisuwhyte) :) + + +```coffeescript +# Just like its CoffeeScript cousin, LiveScript uses hash symbols for +# single-line comments. + +/* + Multi-line comments are written C-style. Use them if you want comments + to be preserved in the JavaScript output. + */ +``` +```coffeescript +# As far as syntax goes, LiveScript uses indentation to delimit blocks, +# rather than curly braces, and whitespace to apply functions, rather +# than parenthesis. + + +######################################################################## +## 1. Basic values +######################################################################## + +# Lack of value is defined by the keyword `void` instead of `undefined` +void            # same as `undefined` but safer (can't be overridden) + +# No valid value is represented by Null. +null + + +# The most basic actual value is the logical type: +true +false + +# And it has a plethora of aliases that mean the same thing: +on; off +yes; no + + +# Then you get numbers. These are double-precision floats like in JS. +10 +0.4     # Note that the leading `0` is required + +# For readability, you may use underscores and letter suffixes in a +# number, and these will be ignored by the compiler. +12_344km + + +# Strings are immutable sequences of characters, like in JS: +"Christina"             # apostrophes are okay too! +"""Multi-line +   strings +   are +   okay +   too.""" + +# Sometimes you want to encode a keyword, the backslash notation makes +# this easy: +\keyword                # => 'keyword' + + +# Arrays are ordered collections of values. +fruits = +  * \apple +  * \orange +  * \pear + +# They can be expressed more concisely with square brackets: +fruits = [ \apple, \orange, \pear ] + +# You also get a convenient way to create a list of strings, using +# white space to delimit the items. +fruits = <[ apple orange pear ]> + +# You can retrieve an item by their 0-based index: +fruits[0]       # => "apple" + +# Objects are a collection of unordered key/value pairs, and a few other +# things (more on that later). +person = +  name: "Christina" +  likes: +    * "kittens" +    * "and other cute stuff" + +# Again, you can express them concisely with curly brackets: +person = {name: "Christina", likes: ["kittens", "and other cute stuff"]} + +# You can retrieve an item by their key: +person.name     # => "Christina" +person["name"]  # => "Christina" + + +# Regular expressions use the same syntax as JavaScript: +trailing-space = /\s$/          # dashed-words become dashedWords + +# Except you can do multi-line expressions too! +# (comments and whitespace just gets ignored) +funRE = // +        function\s+(.+)         # name +        \s* \((.*)\) \s*        # arguments +        { (.*) }                # body +        // + + +######################################################################## +## 2. Basic operations +######################################################################## + +# Arithmetic operators are the same as JavaScript's: +1 + 2   # => 3 +2 - 1   # => 1 +2 * 3   # => 6 +4 / 2   # => 2 +3 % 2   # => 1 + + +# Comparisons are mostly the same too, except that `==` and `===` are +# inverted. +2 == 2          # => true +2 == "2"        # => false +2 === "2"       # => true + +# Other relational operators include <, <=, > and >= + +# Logical values can be combined through the logical operators `or`, +# `and` and `not` +true and false  # => false +false or true   # => true +not false       # => true + + +# Collections also get some nice additional operators +[1, 2] ++ [3, 4]                # => [1, 2, 3, 4] +'a' in <[ a b c ]>              # => true +'name' of { name: 'Chris' }     # => true + + +######################################################################## +## 3. Functions +########################################################################         + +# Since LiveScript is functional, you'd expect functions to get a nice +# treatment. In LiveScript it's even more apparent that functions are +# first class: +add = (left, right) -> left + right +add 1, 2        # => 3 + +# Functions which take no arguments are called with a bang! +two = -> 2 +two! + +# LiveScript uses function scope, just like JavaScript, and has proper +# closures too. Unlike JavaScript, the `=` works as a declaration +# operator, and will always declare the variable on the left hand side. + +# The `:=` operator is available to *reuse* a name from the parent +# scope. + + +# You can destructure arguments of a function to quickly get to +# interesting values inside a complex data structure: +tail = ([head, ...rest]) -> rest +tail [1, 2, 3]  # => [2, 3] + +# You can also transform the arguments using binary or unary +# operators. Default arguments are also possible. +foo = (a = 1, b = 2) -> a + b +foo!    # => 3 + +# You could use it to clone a particular argument to avoid side-effects, +# for example: +copy = (^^target, source) -> +  for k,v of source => target[k] = v +  target +a = { a: 1 } +copy a, { b: 2 }        # => { a: 1, b: 2 } +a                       # => { a: 1 } + + +# A function may be curried by using a long arrow rather than a short +# one: +add = (left, right) --> left + right +add1 = add 1 +add1 2          # => 3 + +# Functions get an implicit `it` argument, even if you don't declare +# any. +identity = -> it +identity 1      # => 1 + +# Operators are not functions in LiveScript, but you can easily turn +# them into one! Enter the operator sectioning: +divide-by-2 = (/ 2) +[2, 4, 8, 16].map(divide-by-2) .reduce (+) + + +# Not only of function application lives LiveScript, as in any good +# functional language you get facilities for composing them: +double-minus-one = (- 1) . (* 2) + +# Other than the usual `f . g` mathematical formulae, you get the `>>` +# and `<<` operators, that describe how the flow of values through the +# functions.  +double-minus-one = (* 2) >> (- 1) +double-minus-one = (- 1) << (* 2) + + +# And talking about flow of value, LiveScript gets the `|>` and `<|` +# operators that apply a value to a function: +map = (f, xs) --> xs.map f +[1 2 3] |> map (* 2)            # => [2 4 6] + +# You can also choose where you want the value to be placed, just mark +# the place with an underscore (_): +reduce = (f, xs, initial) --> xs.reduce f, initial +[1 2 3] |> reduce (+), _, 0     # => 6 + + +# The underscore is also used in regular partial application, which you +# can use for any function: +div = (left, right) -> left / right +div-by-2 = div _, 2 +div-by-2 4      # => 2 + + +# Last, but not least, LiveScript has back-calls, which might help +# with some callback-based code (though you should try more functional +# approaches, like Promises): +readFile = (name, f) -> f name +a <- readFile 'foo' +b <- readFile 'bar' +console.log a + b + +# Same as: +readFile 'foo', (a) -> readFile 'bar', (b) -> console.log a + b + + +######################################################################## +## 4. Patterns, guards and control-flow +######################################################################## + +# You can branch computations with the `if...else` expression: +x = if n > 0 then \positive else \negative + +# Instead of `then`, you can use `=>` +x = if n > 0 => \positive +    else        \negative + +# Complex conditions are better-off expressed with the `switch` +# expression, though: +y = {} +x = switch +  | (typeof y) is \number => \number +  | (typeof y) is \string => \string +  | 'length' of y         => \array +  | otherwise             => \object      # `otherwise` and `_` always matches. + +# Function bodies, declarations and assignments get a free `switch`, so +# you don't need to type it again: +take = (n, [x, ...xs]) --> +                        | n == 0 => [] +                        | _      => [x] ++ take (n - 1), xs + + +######################################################################## +## 5. Comprehensions +######################################################################## + +# While the functional helpers for dealing with lists and objects are +# right there in the JavaScript's standard library (and complemented on +# the prelude-ls, which is a "standard library" for LiveScript), +# comprehensions will usually allow you to do this stuff faster and with +# a nice syntax: +oneToTwenty = [1 to 20] +evens       = [x for x in oneToTwenty when x % 2 == 0] + +# `when` and `unless` can be used as filters in the comprehension. + +# Object comprehension works in the same way, except that it gives you +# back an object rather than an Array: +copy = { [k, v] for k, v of source } + + +######################################################################## +## 4. OOP +######################################################################## + +# While LiveScript is a functional language in most aspects, it also has +# some niceties for imperative and object oriented programming. One of +# them is class syntax and some class sugar inherited from CoffeeScript: +class Animal +  (@name, kind) -> +    @kind = kind +  action: (what) -> "*#{@name} (a #{@kind}) #{what}*" + +class Cat extends Animal +  (@name) -> super @name, 'cat' +  purr: -> @action 'purrs' + +kitten = new Cat 'Mei' +kitten.purr!      # => "*Mei (a cat) purrs*" + +# Besides the classical single-inheritance pattern, you can also provide +# as many mixins as you would like for a class. Mixins are just plain +# objects: +Huggable = +  hug: -> @action 'is hugged' + +class SnugglyCat extends Cat implements Huggable + +kitten = new SnugglyCat 'Purr' +kitten.hug!     # => "*Mei (a cat) is hugged*" +``` + +## Further reading + +There's just so much more to LiveScript, but this should be enough to +get you started writing little functional things in it. The  +[official website](http://livescript.net/) has a lot of information on the +language, and a nice online compiler for you to try stuff out! + +You may also want to grab yourself some +[prelude.ls](http://gkz.github.io/prelude-ls/), and check out the `#livescript` +channel on the Freenode network. diff --git a/lua.html.markdown b/lua.html.markdown index 0ece399f..7325a1cf 100644 --- a/lua.html.markdown +++ b/lua.html.markdown @@ -87,7 +87,7 @@ until num == 0  ----------------------------------------------------  function fib(n) -  if n < 2 then return 1 end +  if n < 2 then return n end    return fib(n - 2) + fib(n - 1)  end diff --git a/php.html.markdown b/php.html.markdown index a20e1d11..e81b88fd 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -2,6 +2,7 @@  language: php  contributors:      - ["Malcolm Fell", "http://emarref.net/"] +    - ["Trismegiste", "https://github.com/Trismegiste"]  filename: learnphp.php  --- @@ -47,9 +48,9 @@ $boolean = true;  // or TRUE or True  $boolean = false; // or FALSE or False  // Integers -$int1 = 19;   // => 19 -$int2 = -19;  // => -19 -$int3 = 019;  // => 15 (a leading 0 denotes an octal number) +$int1 = 12;   // => 12 +$int2 = -12;  // => -12 +$int3 = 012;  // => 10 (a leading 0 denotes an octal number)  $int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal)  // Floats (aka doubles) @@ -380,9 +381,6 @@ echo $function_name(1, 2); // => 3   * Includes   */ -/* -``` -```php  <?php  // PHP within included files must also begin with a PHP open tag. @@ -526,6 +524,12 @@ interface InterfaceTwo      public function doSomethingElse();  } +// interfaces can be extended +interface InterfaceThree extends InterfaceTwo +{ +    public function doAnotherContract(); +} +  abstract class MyAbstractClass implements InterfaceOne  {      public $x = 'doSomething'; @@ -590,9 +594,6 @@ $cls->myTraitMethod(); // Prints "I have MyTrait"  // This section is separate, because a namespace declaration  // must be the first statement in a file. Let's pretend that is not the case -/* -``` -```php  <?php  // By default, classes exist in the global namespace, and can diff --git a/racket.html.markdown b/racket.html.markdown new file mode 100644 index 00000000..adacd91d --- /dev/null +++ b/racket.html.markdown @@ -0,0 +1,607 @@ +--- + +language: racket +filename: learnracket.rkt +contributors: +  - ["th3rac25", "https://github.com/voila"] +  - ["Eli Barzilay", "https://github.com/elibarzilay"] +  - ["Gustavo Schmidt", "https://github.com/gustavoschmidt"] +--- + +Racket is a general purpose, multi-paradigm programming language in the Lisp/Scheme family. + +Feedback is appreciated! You can reach me at [@th3rac25](http://twitter.com/th3rac25) or th3rac25 [at] [google's email service] + + +```racket +#lang racket ; defines the language we are using + +;;; Comments + +;; Single line comments start with a semicolon + +#| Block comments +   can span multiple lines and... +    #| +       they can be nested! +    |# +|# + +;; S-expression comments discard the following expression, +;; useful to comment expressions when debugging +#; (this expression is discarded) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 1. Primitive Datatypes and Operators +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Numbers +9999999999999999999999 ; integers +#b111                  ; binary => 7 +#o111                  ; octal => 73 +#x111                  ; hexadecimal => 273 +3.14                   ; reals +6.02e+23 +1/2                    ; rationals +1+2i                   ; complex numbers + +;; Function application is written (f x y z ...) +;; where f is a function and x, y, z, ... are operands +;; If you want to create a literal list of data, use ' to stop it from +;; being evaluated +'(+ 1 2) ; => (+ 1 2) +;; Now, some arithmetic operations +(+ 1 1)  ; => 2 +(- 8 1)  ; => 7 +(* 10 2) ; => 20 +(expt 2 3) ; => 8 +(quotient 5 2) ; => 2 +(remainder 5 2) ; => 1 +(/ 35 5) ; => 7 +(/ 1 3) ; => 1/3 +(exact->inexact 1/3) ; => 0.3333333333333333 +(+ 1+2i  2-3i) ; => 3-1i + +;;; Booleans +#t ; for true +#f ; for false -- any value other than #f is true +(not #t) ; => #f +(and 0 #f (error "doesn't get here")) ; => #f +(or #f 0 (error "doesn't get here"))  ; => 0 + +;;; Characters +#\A ; => #\A +#\λ ; => #\λ +#\u03BB ; => #\λ + +;;; Strings are fixed-length array of characters. +"Hello, world!" +"Benjamin \"Bugsy\" Siegel"   ; backslash is an escaping character +"Foo\tbar\41\x21\u0021\a\r\n" ; includes C escapes, Unicode +"λx:(μα.α→α).xx"              ; can include Unicode characters + +;; Strings can be added too! +(string-append "Hello " "world!") ; => "Hello world!" + +;; A string can be treated like a list of characters +(string-ref "Apple" 0) ; => #\A + +;; format can be used to format strings: +(format "~a can be ~a" "strings" "formatted") + +;; Printing is pretty easy +(printf "I'm Racket. Nice to meet you!\n") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 2. Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; You can create a variable using define +;; a variable name can use any character except: ()[]{}",'`;#|\ +(define some-var 5) +some-var ; => 5 + +;; You can also use unicode characters +(define ⊆ subset?) +(⊆ (set 3 2) (set 1 2 3)) ; => #t + +;; Accessing a previously unassigned variable is an exception +; x ; => x: undefined ... + +;; Local binding: `me' is bound to "Bob" only within the (let ...) +(let ([me "Bob"]) +  "Alice" +  me) ; => "Bob" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 3. Structs and Collections +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Structs +(struct dog (name breed age)) +(define my-pet +  (dog "lassie" "collie" 5)) +my-pet ; => #<dog> +(dog? my-pet) ; => #t +(dog-name my-pet) ; => "lassie" + +;;; Pairs (immutable) +;; `cons' constructs pairs, `car' and `cdr' extract the first +;; and second elements +(cons 1 2) ; => '(1 . 2) +(car (cons 1 2)) ; => 1 +(cdr (cons 1 2)) ; => 2 + +;;; Lists + +;; Lists are linked-list data structures, made of `cons' pairs and end +;; with a `null' (or '()) to mark the end of the list +(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3) +;; `list' is a convenience variadic constructor for lists +(list 1 2 3) ; => '(1 2 3) +;; and a quote can also be used for a literal list value +'(1 2 3) ; => '(1 2 3) + +;; Can still use `cons' to add an item to the beginning of a list +(cons 4 '(1 2 3)) ; => '(4 1 2 3) + +;; Use `append' to add lists together +(append '(1 2) '(3 4)) ; => '(1 2 3 4) + +;; Lists are a very basic type, so there is a *lot* of functionality for +;; them, a few examples: +(map add1 '(1 2 3))          ; => '(2 3 4) +(map + '(1 2 3) '(10 20 30)) ; => '(11 22 33) +(filter even? '(1 2 3 4))    ; => '(2 4) +(count even? '(1 2 3 4))     ; => 2 +(take '(1 2 3 4) 2)          ; => '(1 2) +(drop '(1 2 3 4) 2)          ; => '(3 4) + +;;; Vectors + +;; Vectors are fixed-length arrays +#(1 2 3) ; => '#(1 2 3) + +;; Use `vector-append' to add vectors together +(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6) + +;;; Sets + +;; Create a set from a list +(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3) + +;; Add a member with `set-add' +;; (Functional: returns the extended set rather than mutate the input) +(set-add (set 1 2 3) 4) ; => (set 1 2 3 4) + +;; Remove one with `set-remove' +(set-remove (set 1 2 3) 1) ; => (set 2 3) + +;; Test for existence with `set-member?' +(set-member? (set 1 2 3) 1) ; => #t +(set-member? (set 1 2 3) 4) ; => #f + +;;; Hashes + +;; Create an immutable hash table (mutable example below) +(define m (hash 'a 1 'b 2 'c 3)) + +;; Retrieve a value +(hash-ref m 'a) ; => 1 + +;; Retrieving a non-present value is an exception +; (hash-ref m 'd) => no value found + +;; You can provide a default value for missing keys +(hash-ref m 'd 0) ; => 0 + +;; Use `hash-set' to extend an immutable hash table +;; (Returns the extended hash instdead of mutating it) +(define m2 (hash-set m 'd 4)) +m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3)) + +;; Remember, these hashes are immutable! +m ; => '#hash((b . 2) (a . 1) (c . 3))  <-- no `d' + +;; Use `hash-remove' to remove keys (functional too) +(hash-remove m 'a) ; => '#hash((b . 2) (c . 3)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 3. Functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Use `lambda' to create functions. +;; A function always returns the value of its last expression +(lambda () "Hello World") ; => #<procedure> +;; Can also use a unicode `λ' +(λ () "Hello World")     ; => same function + +;; Use parens to call all functions, including a lambda expression +((lambda () "Hello World")) ; => "Hello World" +((λ () "Hello World"))      ; => "Hello World" + +;; Assign a function to a var +(define hello-world (lambda () "Hello World")) +(hello-world) ; => "Hello World" + +;; You can shorten this using the function definition syntatcic sugae: +(define (hello-world2) "Hello World") + +;; The () in the above is the list of arguments for the function +(define hello +  (lambda (name) +    (string-append "Hello " name))) +(hello "Steve") ; => "Hello Steve" +;; ... or equivalently, using a sugared definition: +(define (hello2 name) +  (string-append "Hello " name)) + +;; You can have multi-variadic functions too, using `case-lambda' +(define hello3 +  (case-lambda +    [() "Hello World"] +    [(name) (string-append "Hello " name)])) +(hello3 "Jake") ; => "Hello Jake" +(hello3) ; => "Hello World" +;; ... or specify optional arguments with a default value expression +(define (hello4 [name "World"]) +  (string-append "Hello " name)) + +;; Functions can pack extra arguments up in a list +(define (count-args . args) +  (format "You passed ~a args: ~a" (length args) args)) +(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" +;; ... or with the unsugared `lambda' form: +(define count-args2 +  (lambda args +    (format "You passed ~a args: ~a" (length args) args))) + +;; You can mix regular and packed arguments +(define (hello-count name . args) +  (format "Hello ~a, you passed ~a extra args" name (length args))) +(hello-count "Finn" 1 2 3) +; => "Hello Finn, you passed 3 extra args" +;; ... unsugared: +(define hello-count2 +  (lambda (name . args) +    (format "Hello ~a, you passed ~a extra args" name (length args)))) + +;; And with keywords +(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args) +  (format "~a ~a, ~a extra args" g name (length args))) +(hello-k)                 ; => "Hello World, 0 extra args" +(hello-k 1 2 3)           ; => "Hello World, 3 extra args" +(hello-k #:greeting "Hi") ; => "Hi World, 0 extra args" +(hello-k #:name "Finn" #:greeting "Hey") ; => "Hey Finn, 0 extra args" +(hello-k 1 2 3 #:greeting "Hi" #:name "Finn" 4 5 6) +                                         ; => "Hi Finn, 6 extra args" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 4. Equality +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; for numbers use `=' +(= 3 3.0) ; => #t +(= 2 1) ; => #f + +;; for object identity use `eq?' +(eq? 3 3) ; => #t +(eq? 3 3.0) ; => #f +(eq? (list 3) (list 3)) ; => #f + +;; for collections use `equal?' +(equal? (list 'a 'b) (list 'a 'b)) ; => #t +(equal? (list 'a 'b) (list 'b 'a)) ; => #f + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 5. Control Flow +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Conditionals + +(if #t               ; test expression +    "this is true"   ; then expression +    "this is false") ; else expression +; => "this is true" + +;; In conditionals, all non-#f values are treated as true +(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(Groucho Zeppo) +(if (member 'Groucho '(Harpo Groucho Zeppo)) +    'yep +    'nope) +; => 'yep + +;; `cond' chains a series of tests to select a result +(cond [(> 2 2) (error "wrong!")] +      [(< 2 2) (error "wrong again!")] +      [else 'ok]) ; => 'ok + +;;; Pattern Matching + +(define (fizzbuzz? n) +  (match (list (remainder n 3) (remainder n 5)) +    [(list 0 0) 'fizzbuzz] +    [(list 0 _) 'fizz] +    [(list _ 0) 'buzz] +    [_          #f])) + +(fizzbuzz? 15) ; => 'fizzbuzz +(fizzbuzz? 37) ; => #f + +;;; Loops + +;; Looping can be done through (tail-) recursion +(define (loop i) +  (when (< i 10) +    (printf "i=~a\n" i) +    (loop (add1 i)))) +(loop 5) ; => i=5, i=6, ... + +;; Similarly, with a named let +(let loop ((i 0)) +  (when (< i 10) +    (printf "i=~a\n" i) +    (loop (add1 i)))) ; => i=0, i=1, ... + +;; See below how to add a new `loop' form, but Racket already has a very +;; flexible `for' form for loops: +(for ([i 10]) +  (printf "i=~a\n" i)) ; => i=0, i=1, ... +(for ([i (in-range 5 10)]) +  (printf "i=~a\n" i)) ; => i=5, i=6, ... + +;;; Iteration Over Other Sequences +;; `for' allows iteration over many other kinds of sequences: +;; lists, vectors, strings, sets, hash tables, etc... + +(for ([i (in-list '(l i s t))]) +  (displayln i)) + +(for ([i (in-vector #(v e c t o r))]) +  (displayln i)) + +(for ([i (in-string "string")]) +  (displayln i)) + +(for ([i (in-set (set 'x 'y 'z))]) +  (displayln i)) + +(for ([(k v) (in-hash (hash 'a 1 'b 2 'c 3 ))]) +  (printf "key:~a value:~a\n" k v)) + +;;; More Complex Iterations + +;; Parallel scan of multiple sequences (stops on shortest) +(for ([i 10] [j '(x y z)]) (printf "~a:~a\n" i j)) +; => 0:x 1:y 2:z + +;; Nested loops +(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j)) +; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z + +;; Conditions +(for ([i 1000] +      #:when (> i 5) +      #:unless (odd? i) +      #:break (> i 10)) +  (printf "i=~a\n" i)) +; => i=6, i=8, i=10 + +;;; Comprehensions +;; Very similar to `for' loops -- just collect the results + +(for/list ([i '(1 2 3)]) +  (add1 i)) ; => '(2 3 4) + +(for/list ([i '(1 2 3)] #:when (even? i)) +  i) ; => '(2) + +(for/list ([i 10] [j '(x y z)]) +  (list i j)) ; => '((0 x) (1 y) (2 z)) + +(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10)) +  i) ; => '(6 8 10) + +(for/hash ([i '(1 2 3)]) +  (values i (number->string i))) +; => '#hash((1 . "1") (2 . "2") (3 . "3")) + +;; There are many kinds of other built-in ways to collect loop values: +(for/sum ([i 10]) (* i i)) ; => 285 +(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000 +(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t +(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t +;; And to use any arbitrary combination, use `for/fold' +(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10 +;; (This can often replace common imperative loops) + +;;; Exceptions + +;; To catch exceptions, use the `with-handlers' form +(with-handlers ([exn:fail? (lambda (exn) 999)]) +  (+ 1 "2")) ; => 999 +(with-handlers ([exn:break? (lambda (exn) "no time")]) +  (sleep 3) +  "phew") ; => "phew", but if you break it => "no time" + +;; Use `raise' to throw exceptions or any other value +(with-handlers ([number?    ; catch numeric values raised +                 identity]) ; return them as plain values +  (+ 1 (raise 2))) ; => 2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 6. Mutation +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Use `set!' to assign a new value to an existing variable +(define n 5) +(set! n (add1 n)) +n ; => 6 + +;; Use boxes for explicitly mutable values (similar to pointers or +;; references in other languages) +(define n* (box 5)) +(set-box! n* (add1 (unbox n*))) +(unbox n*) ; => 6 + +;; Many Racket datatypes are immutable (pairs, lists, etc), some come in +;; both mutable and immutable flavors (strings, vectors, hash tables, +;; etc...) + +;; Use `vector' or `make-vector' to create mutable vectors +(define vec (vector 2 2 3 4)) +(define wall (make-vector 100 'bottle-of-beer)) +;; Use vector-set! to update a slot +(vector-set! vec 0 1) +(vector-set! wall 99 'down) +vec ; => #(1 2 3 4) + +;; Create an empty mutable hash table and manipulate it +(define m3 (make-hash)) +(hash-set! m3 'a 1) +(hash-set! m3 'b 2) +(hash-set! m3 'c 3) +(hash-ref m3 'a)   ; => 1 +(hash-ref m3 'd 0) ; => 0 +(hash-remove! m3 'a) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 7. Modules +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Modules let you organize code into multiple files and reusable +;; libraries; here we use sub-modules, nested in the whole module that +;; this text makes (starting from the "#lang" line) + +(module cake racket/base ; define a `cake' module based on racket/base + +  (provide print-cake) ; function exported by the module + +  (define (print-cake n) +    (show "   ~a   " n #\.) +    (show " .-~a-. " n #\|) +    (show " | ~a | " n #\space) +    (show "---~a---" n #\-)) + +  (define (show fmt n ch) ; internal function +    (printf fmt (make-string n ch)) +    (newline))) + +;; Use `require' to get all `provide'd names from a module +(require 'cake) ; the ' is for a local submodule +(print-cake 3) +; (show "~a" 1 #\A) ; => error, `show' was not exported + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8. Classes and Objects +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Create a class fish% (-% is idomatic for class bindings) +(define fish% +  (class object% +    (init size) ; initialization argument +    (super-new) ; superclass initialization +    ;; Field +    (define current-size size) +    ;; Public methods +    (define/public (get-size) +      current-size) +    (define/public (grow amt) +      (set! current-size (+ amt current-size))) +    (define/public (eat other-fish) +      (grow (send other-fish get-size))))) + +;; Create an instance of fish% +(define charlie +  (new fish% [size 10])) + +;; Use `send' to call an object's methods +(send charlie get-size) ; => 10 +(send charlie grow 6) +(send charlie get-size) ; => 16 + +;; `fish%' is a plain "first class" value, which can get us mixins +(define (add-color c%) +  (class c% +    (init color) +    (super-new) +    (define my-color color) +    (define/public (get-color) my-color))) +(define colored-fish% (add-color fish%)) +(define charlie2 (new colored-fish% [size 10] [color 'red])) +(send charlie2 get-color) +;; or, with no names: +(send (new (add-color fish%) [size 10] [color 'red]) get-color) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 9. Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Macros let you extend the syntax of the language + +;; Let's add a while loop +(define-syntax-rule (while condition body ...) +  (let loop () +    (when condition +      body ... +      (loop)))) + +(let ([i 0]) +  (while (< i  10) +    (displayln i) +    (set! i (add1 i)))) + +;; Macros are hygienic, you cannot clobber existing variables! +(define-syntax-rule (swap! x y) ; -! is idomatic for mutation +  (let ([tmp x]) +    (set! x y) +    (set! y tmp))) + +(define tmp 2) +(define other 3) +(swap! tmp other) +(printf "tmp = ~a; other = ~a\n" tmp other) +;; The variable `tmp` is renamed to `tmp_1` +;; in order to avoid name conflict +;; (let ([tmp_1 tmp]) +;;   (set! tmp other) +;;   (set! other tmp_1)) + +;; But they are still code transformations, for example: +(define-syntax-rule (bad-while condition body ...) +  (when condition +    body ... +    (bad-while condition body ...))) +;; this macro is broken: it generates infinite code, if you try to use +;; it, the compiler will get in an infinite loop + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 10. Contracts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Contracts impose constraints on values exported from modules + +(module bank-account racket +  (provide (contract-out +            [deposit (-> positive? any)] ; amounts are always positive +            [balance (-> positive?)])) + +  (define amount 0) +  (define (deposit a) (set! amount (+ amount a))) +  (define (balance) amount) +  ) + +(require 'bank-account) +(deposit 5) + +(balance) ; => 5 + +;; Clients that attempt to deposit a non-positive amount are blamed +;; (deposit -5) ; => deposit: contract violation +;; expected: positive? +;; given: -5 +;; more details.... +``` + +## Further Reading + +Still up for more? Try [Getting Started with Racket](http://docs.racket-lang.org/getting-started/) diff --git a/ruby.html.markdown b/ruby.html.markdown index 2c9a4cb9..38d060a3 100644 --- a/ruby.html.markdown +++ b/ruby.html.markdown @@ -43,17 +43,18 @@ false.class #=> FalseClass  1 == 1 #=> true  2 == 1 #=> false -# apart from false itself, nil is the only other 'falsey' value - -nil == false #=> true -0 == false #=> false -  # Inequality  1 != 1 #=> false  2 != 1 #=> true  !true  #=> false  !false #=> true +# apart from false itself, nil is the only other 'falsey' value + +!nil   #=> true +!false #=> true +!0     #=> false +  # More comparisons  1 < 10 #=> true  1 > 10 #=> false @@ -194,6 +195,7 @@ end  counter = 1  while counter <= 5 do    puts "iteration #{counter}" +  counter += 1  end  #=> iteration 1  #=> iteration 2 @@ -214,7 +216,9 @@ when 'D'    puts "Scraping through"  when 'F'    puts "You failed!" - +else  +  puts "Alternative grading system, eh?" +end  # Functions @@ -263,7 +267,7 @@ class Human      @@species = "H. sapiens"      # Basic initializer -    def initialize(name, age=0): +    def initialize(name, age=0)          # Assign the argument to the "name" instance variable for the instance          @name = name          # If no age given, we will fall back to the default in the arguments list. @@ -281,7 +285,7 @@ class Human      end      # A class method uses self to distinguish from instance methods. -    $ It can only be called on the class, not an instance. +    # It can only be called on the class, not an instance.      def self.say(msg)         puts "#{msg}"      end @@ -301,6 +305,8 @@ dwight = Human.new("Dwight K. Schrute")  # Let's call a couple of methods  jim.species #=> "H. sapiens"  jim.name #=> "Jim Halpert" +jim.name = "Jim Halpert II" #=> "Jim Halpert II" +jim.name #=> "Jim Halpert II"  dwight.species #=> "H. sapiens"  dwight.name #=> "Dwight K. Schrute" diff --git a/whip.html.markdown b/whip.html.markdown new file mode 100644 index 00000000..3fe9b2f4 --- /dev/null +++ b/whip.html.markdown @@ -0,0 +1,237 @@ +--- +language: whip +contributors: +  - ["Tenor Biel", "http://github.com/L8D"] +author: Tenor Biel +author_url: http://github.com/L8D +filename: whip.lisp +--- + +Whip is a LISP-dialect made for scripting and simplified concepts. +It has also borrowed a lot of functions and syntax from Haskell(a non-related language). + +These docs were written by the creator of the language himself. So is this line. + +``` lisp +; Comments are like LISP. Semi-solons... + +; Majority of first-level statements are inside "forms" +; which are just things inside parens separated by whitespace +not_in_form +(in_form) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 1. Numbers, Strings, and Operators + +; Whip has one number type (which is a 64-bit IEEE 754 double, from JavaScript). +3 ; => 3 +1.5 ; => 1.5 + +; Functions are called if they are the first element in a form +(called_function args) + +; Majority of operations are done with functions +; All the basic arihmetic is pretty straight forward +(+ 1 1) ; => 2 +(- 2 1) ; => 1 +(* 1 2) ; => 2 +(/ 2 1) ; => 2 +; even modulo +(% 9 4) ; => 1 +; JavaScript-style uneven division. +(/ 5 2) ; => 2.5 + +; Nesting forms works as you expect. +(* 2 (+ 1 3)) ; => 8 + +; There's a boolean type. +true +false + +; String are created with ". +"Hello, world" + +; Single chars are created with '. +'a' + +; Negation uses the 'not' function. +(not true) ; => false +(not false) ; => true + +; But the majority of non-haskell functions have shortcuts +; not's shortcut is a '!'. +(! (! true)) ; => true + +; Equality is `equal` or `=`. +(= 1 1) ; => true +(equal 2 1) ; => false + +; For example, inequality would be combinding the not and equal functions. +(! (= 2 1)) ; => true + +; More comparisons +(< 1 10) ; => true +(> 1 10) ; => false +; and their word counterpart. +(lesser 1 10) ; => true +(greater 1 10) ; => false + +; Strings can be concatenated with +. +(+ "Hello " "world!") ; => "Hello world!" + +; You can use JavaScript's comparative abilities. +(< 'a' 'b') ; => true +; ...and type coercion +(= '5' 5) + +; The `at` or @ function will access characters in strings, starting at 0. +(at 0 'a') ; => 'a' +(@ 3 "foobar") ; => 'b' + +; There is also the `null` and `undefined` variables. +null ; used to indicate a deliberate non-value +undefined ; user to indicate a value that hasn't been set + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 2. Vairbles, Lists, and Dicts + +; Variables are declared with the `def` or `let` functions. +; Variab;es that haven't been set will be `undefined`. +(def some_var 5) +; `def` will keep the variable in the global context. +; `let` will only have the variable inside it's context, and has a wierder syntax. +(let ((a_var 5)) (+ a_var 5)) ; => 10 +(+ a_var 5) ; = undefined + 5 => undefined + +; Lists are arrays of values of any type. +; They basically are just forms without functions at the beginning. +(1 2 3) ; => [1, 2, 3] (JavaScript syntax) + +; Dictionaries are Whip's equivalent to JavaScript 'objects' or Python 'dictionaries' +; or Ruby 'hashes': an unordered collection of key-value pairs. +{"key1":"value1" "key2":2 3:3} + +; Keys are just values, either identifier, number, or string. +(def my_dict {my_key:"my_value" "my other key":4}) +; But in Whip, dictionaries get parsed like: value, colon, value; with whitespace between each. +; So that means +{"key": "value" +"another key" +: 1234 +} +; is evaluated to the same as +{"key":"value" "another key":1234} + +; Dictionary definitions can be accessed used the `at` function, like strings and lists. +(@ "my other key" my_dict) ; => 4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 3. Logic and Control sequences + +; The `if` function is pretty simple, though different than most imperitave langs. +(if true "returned if first arg is true" "returned if first arg is false") +; => "returned if first arg is true" + +; And for the sake of ternary operator legacy +; `?` is if's unused shortcut. +(? false true false) ; => false + +; `both` is a logical 'and' statement, and `either` is a logical 'or'. +(both true true) ; => true +(both true false) ; => false +(either true false) ; => true +(either false false) ; => false +; And their shortcuts are +; & => both +; ^ => either +(& true true) ; => true +(^ false true) ; => true + +;;;;;;;;; +; Lambdas + +; Lambdas in Whip are declared with the `lambda` or `->` function. +; And functions are really just lambdas with names. +(def my_function (-> (x y) (+ (x y) 10))) +;         |       |    |         | +;         |       |    |    returned value(with scope containing argument vars) +;         |       | arguments +;         | lambda declaration function +;         | +;   name of the to-be-decalred lambda + +(my_function 10 10) ; = (+ (+ 10 10) 10) => 30 + +; Obiously, all lambdas by definition are anonymous and +; technically always used anonymouesly. Redundancy. +((lambda (x) x) 10) ; => 10 + +;;;;;;;;;;;;;;;; +; Comprehensions + +; `range` or `..` generates a list of numbers for +; each number between it's two args. +(range 1 5) ; => (1 2 3 4 5) +(.. 0 2)    ; => (0 1 2) + +; `map` applies it's first arg(which should be a lambda/function) +; to each item in the following arg(which should be a list) +(map (-> (x) (+ x 1)) (1 2 3)) ; => (2 3 4) + +; Reduce +(reduce + (.. 1 5)) +; equivalent to +((+ (+ (+ 1 2) 3) 4) 5) + +; Note: map and reduce don't have shortcuts + +; `slice` or `\` is just like JavaScript's .slice() +; But do note, it takes the list as the first argument, not the last. +(slice (.. 1 5) 2) ; => (3 4 5) +(\ (.. 0 100) -5) ; => (96 97 98 99 100) + +; `append` or `<<` is self expanatory +(append 4 (1 2 3)) ; => (1 2 3 4) +(<< "bar" ("foo")) ; => ("foo" "bar") + +; Length is self explanatory. +(length (1 2 3)) ; => 3 +(_ "foobar") ; => 6 + +;;;;;;;;;;;;;;; +; Haskell fluff + +; First item in list +(head (1 2 3)) ; => 1 +; List from second to last elements in list +(tail (1 2 3)) ; => (2 3) +; Last item in list +(last (1 2 3)) ; => 3 +; Reverse of `tail` +(init (1 2 3)) ; => (1 2) +; List from first to specified elements in list +(take 1 (1 2 3 4)) ; (1 2) +; Reverse of `take` +(drop 1 (1 2 3 4)) ; (3 4) +; Lowest value in list +(min (1 2 3 4)) ; 1 +; Highest value in list +(max (1 2 3 4)) ; 4 +; If value is in list or object +(elem 1 (1 2 3)) ; true +(elem "foo" {"foo":"bar"}) ; true +(elem "bar" {"foo":"bar"}) ; false +; Reverse list order +(reverse (1 2 3 4)) ; => (4 3 2 1) +; If value is even or odd +(even 1) ; => false +(odd 1) ; => true +; Split string into list of strings by whitespace +(words "foobar nachos cheese") ; => ("foobar" "nachos" "cheese") +; Join list of strings together. +(unwords ("foo" "bar")) ; => "foobar" +(pred 21) ; => 20 +(succ 20) ; => 21 +``` + +For more info, check out the [repo](http://github.com/L8D/whip) diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown new file mode 100755 index 00000000..ed55203c --- /dev/null +++ b/zh-cn/c-cn.html.markdown @@ -0,0 +1,394 @@ +--- +language: c +filename: learnc.c +contributors: +    - ["Adam Bard", "http://adambard.com/"]
 +translators: +	- ["Chenbo Li", "http://binarythink.net/"] +--- + +C语言在今天仍然是高性能计算的主要选择。 + +C大概是大多数程序员用到的最接近底层的语言了,但是C语言本身不仅可以用来提升程序运行的速度 +注意看看C语言的文档,你就会知道C语言在内存管理方面的强大也是其他语言无法比拟的。 + +```c +// 用“//”来实现单行注释 + +/* +多行注释是这个样子的 +*/ + +// 用#include来导入头文件 +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// 函数的标签(signature)应该放在.h文件中,并且引入到程序顶部 +// 也可以直接放到你的.c文件的最上面 +void function_1(); +void function_2(); + +// c程序的入口是一个返回值为int型的函数,名字叫做main +int main() { + +// 用printf来实现标准输出,这种输出也可以用格式来控制 +// %d 代表一个整数, \n 代表一个新行 +printf("%d\n", 0); // => 输出 0 +// 所有的语句都要以分号结束 + +/////////////////////////////////////// +// 类型 +/////////////////////////////////////// + +// 在使用变量之前我们必须先声明它们。 +// 变量在声明时需要指明其类型,而类型能够告诉系统这个变量所占用的空间 + +// int型(整型)变量一般占用4个字节 +int x_int = 0; + +// short型(短整型)变量一般占用2个字节 +short x_short = 0; + +// char型(字符型)变量会占用1个字节 +char x_char = 0; +char y_char = 'y'; // 字符变量的字面值需要用单引号包住 + +// long型(长整型)一般需要4个字节到8个字节; 而long long型则至少需要8个字节(64位) + +long x_long = 0; +long long x_long_long = 0;  + +// float一般是用32位表示的浮点数字 +float x_float = 0.0; + +// double一般是用64位表示的浮点数字 +double x_double = 0.0; + +// 整数类型也可以有无符号的类型表示。这样这些变量就无法表示负数 +// 但是无符号整数所能表示的范围就可以比原来的整数大一些 + +unsigned char ux_char; +unsigned short ux_short; +unsigned int ux_int; +unsigned long long ux_long_long; + +// char类型一定会占用1个字节,但是其他的类型却会因具体机器的不同而各异 +// sizeof(T) 可以返回T类型在运行的机器上占用多少个字节  +// 这样你的代码就可以在各处正确运行了 +// 比如 +printf("%lu\n", sizeof(int)); // => 4 (字长为4的机器上) + +// 数组必须要在开始被初始化为特定的长度 +char my_char_array[20]; // 这个数组占据 1 * 20 = 20 个字节 +int my_int_array[20]; // 这个数组占据 4 * 20 = 80 个字节 +                      // (这里我们假设字长为4) + + +// 可以用下面的方法把数组初始化为0: +char my_array[20] = {0}; + +// 对数组任意存取就像其他语言的方式 -- 其实是其他的语言像C +my_array[0]; // => 0 + +// 数组是可变的,其实就是内存的映射! +my_array[1] = 2; +printf("%d\n", my_array[1]); // => 2 + +// 字符串就是以 NUL (0x00) 这个字符结尾的字符数组, +// 这个字符可以用'\0'来表示. +// (在字符串字面值中我们不必输入这个字符,编译器会自动添加的) +char a_string[20] = "This is a string"; +printf("%s\n", a_string); // %s 可以对字符串进行格式化 + +/* +也许你会注意到 a_string 实际上只有16个字节长. +第17个字节是一个空字符(NUL)  +而第18, 19 和 20 个字符的值是不确定的。 +*/ + +printf("%d\n", a_string[16]); // => 0 + +/////////////////////////////////////// +// 操作符 +/////////////////////////////////////// + +int i1 = 1, i2 = 2; // 多个变量声明的简写 +float f1 = 1.0, f2 = 2.0; + +// 算数运算 +i1 + i2; // => 3 +i2 - i1; // => 1 +i2 * i1; // => 2 +i1 / i2; // => 0 (0.5 会被化整为 0) + +f1 / f2; // => 0.5, 也许会有很小的误差 + +// 取余运算 +11 % 3; // => 2 + +// 比较操作符我们也很熟悉, 但是有一点,C中没有布尔类型 +// 而是用整形替代 +// 0 就是 false, 其他的就是 true. (比较操作符的返回值则仅有0和1) +3 == 2; // => 0 (false) +3 != 2; // => 1 (true) +3 > 2; // => 1 +3 < 2; // => 0 +2 <= 2; // => 1 +2 >= 2; // => 1 + +// 逻辑运算符需要作用于整数 +!3; // => 0 (非) +!0; // => 1 +1 && 1; // => 1 (且) +0 && 1; // => 0 +0 || 1; // => 1 (或) +0 || 0; // => 0 + +// 位运算 +~0x0F; // => 0xF0 (取反) +0x0F & 0xF0; // => 0x00 (和) +0x0F | 0xF0; // => 0xFF (或) +0x04 ^ 0x0F; // => 0x0B (异或) +0x01 << 1; // => 0x02 (左移1位) +0x02 >> 1; // => 0x01 (右移1位) + +/////////////////////////////////////// +// 控制结构 +/////////////////////////////////////// + +if (0) { +  printf("I am never run\n"); +} else if (0) { +  printf("I am also never run\n"); +} else { +  printf("I print\n"); +} + +// While循环 +int ii = 0; +while (ii < 10) { +    printf("%d, ", ii++); // ii++ 在取值过后自增 +} // => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +int kk = 0; +do { +    printf("%d, ", kk); +} while (++kk < 10); // ++kk 先自增,在被取值 +// => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +// For 循环 +int jj; +for (jj=0; jj < 10; jj++) { +    printf("%d, ", jj); +} // => 输出 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +/////////////////////////////////////// +// 类型转换 +/////////////////////////////////////// + +// 在C中每个变量都有类型,你可以将变量的类型进行转换 + +int x_hex = 0x01; // 可以用16进制赋值 + +// 在类型转换时,数字本身的值会被保留下来 +printf("%d\n", x_hex); // => 输出 1 +printf("%d\n", (short) x_hex); // => 输出 1 +printf("%d\n", (char) x_hex); // => 输出 1 + +// 类型转换时可能会造成溢出,而且不会抛出警告 +printf("%d\n", (char) 257); // => 1 (char的最大值为255) + +// 整数型和浮点型可以互相转换 +printf("%f\n", (float)100); // %f 表示单精度浮点 +printf("%lf\n", (double)100); // %lf 表示双精度浮点 +printf("%d\n", (char)100.0); + +/////////////////////////////////////// +// 指针 +/////////////////////////////////////// + +// 指针变量是用来储存内存地址的变量 +// 指针变量的定义也会告诉你指向的地址的变量的类型  +// 你也可以得到某个变量的地址,并对它们进行操作 + +int x = 0; +printf("%p\n", &x); // 用 & 来获取变量的地址 +// (%p 表示一个指针) +// => 输出某个内存地址 + +// 指针类型在定义是需要以*结束 +int* px; // px是一个指向int型的指针 +px = &x; // 把x的地址保存到px中 +printf("%p\n", px); // => 输出内存中的某个地址 + +// 要得到某个指针指向的内容的值,可以在指针前加一个*来取得(去引用) +printf("%d\n", *px); // => 输出 0, 即x的值 + +// 你也可以改变指针所指向的值 +// 此时你需要在*运算符后添加一个括号,因为++比*的优先级更高 +(*px)++; // 把px所指向的值增加2 +printf("%d\n", *px); // => 输出 1 +printf("%d\n", x); // => 输出 1 + +int x_array[20]; // 数组是分配一系列连续空间的常用方式 +int xx; +for (xx=0; xx<20; xx++) { +    x_array[xx] = 20 - xx; +} // 初始化 x_array 为 20, 19, 18,... 2, 1 + +// 生命一个变量为指向整型的指针类型,并初始化为指向x_array +int* x_ptr = x_array; +// x_ptr现在指向了数组的第一个元素(即整数20).  + +// 事实上数组本身就是指向它的第一个元素的指针 +printf("%d\n", *(x_ptr)); // => 输出 20 +printf("%d\n", x_array[0]); // => 输出 20 + +// 指针的增减多少是依据它本身的类型而定的 +printf("%d\n", *(x_ptr + 1)); // => 输出 19 +printf("%d\n", x_array[1]); // => 输出 19 + +// 你也可以通过标准库函数malloc来实现动态分配 +// 这个函数接受一个代表容量的参数  +// 系统会从堆区分配指定容量字节大小的空间 +int* my_ptr = (int*) malloc(sizeof(int) * 20); +for (xx=0; xx<20; xx++) { +    *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx 也可以 +} // 初始化内存为 20, 19, 18, 17... 2, 1 (as ints) + +// 如果对一些未分配的内存取值则会得到未知的结果 +printf("%d\n", *(my_ptr + 21)); // => 谁知道会输出什么 + +// 当你通过malloc得到一块区域后,你需要释放它 +// 否则没人能够再次使用这块内存,直到程序结束为止 +free(my_ptr); + +// 字符串通常是字符数组,但是经常用字符指针表示 +// 指针: +char* my_str = "This is my very own string"; + +printf("%c\n", *my_str); // => 'T' + +function_1(); +} // main函数结束 + +/////////////////////////////////////// +// 函数 +/////////////////////////////////////// + +// 函数声明语法: +// <返回值类型> <函数名称>(<参数>) + +int add_two_ints(int x1, int x2){ +    return x1 + x2; // 用return来返回一个值 +} + +/* +函数是按值传递的, 但是你可以通过传递参数来传递引用,这样函数就可以更改值 + +例子:字符串本身翻转 +*/ + +// 类型为void的函数没有返回值 +void str_reverse(char* str_in){ +    char tmp; +    int ii=0, len = strlen(str_in); // Strlen 是C标准库函数 +    for(ii=0; ii<len/2; ii++){ +        tmp = str_in[ii]; +        str_in[ii] = str_in[len - ii - 1]; // 从倒数第ii个开始 +        str_in[len - ii - 1] = tmp; +    } +} + +/* +char c[] = "This is a test."; +str_reverse(c); +printf("%s\n", c); // => ".tset a si sihT" +*/ + +/////////////////////////////////////// +// 用户自定义类型和结构 +/////////////////////////////////////// + +// Typedefs可以创建类型别名 +typedef int my_type; +my_type my_type_var = 0; + +// 结构是一系列数据的集合 +struct rectangle { +    int width; +    int height; +}; + + +void function_1(){ + +    struct rectangle my_rec; + +    // 通过 . 来访问结构中的数据 +    my_rec.width = 10; +    my_rec.height = 20; + +    // 你也可以声明指向结构体的指针 +    struct rectangle* my_rec_ptr = &my_rec; + +    // 通过取值来改变结构体的成员... +    (*my_rec_ptr).width = 30; + +    // ... 或者用 -> 操作符作为简写 +    my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10; +} + +// 你也可以用typedef来给一个结构体起一个别名 +typedef struct rectangle rect; + +int area(rect r){ +    return r.width * r.height; +} + +/////////////////////////////////////// +// 函数指针 +/////////////////////////////////////// +/* +在运行时,函数本身也被存放到某块内存区域当中 +函数指针就像其他指针一样, 但却可以被用来直接调用函数, +并且可以被四处传递(就像回调函数那样) +但是,定义的语法有可能在一开始会有些误解 + +例子:通过指针调用str_reverse +*/ +void str_reverse_through_pointer(char * str_in) { +    // 定义一个函数指针 f.  +    void (*f)(char *); // 签名一定要与目标函数相同 +    f = &str_reverse; // 将函数的地址在运行时赋给指针 +    (*f)(str_in); // 通过指针调用函数 +    // f(str_in); // 等价于这种调用方式 +} + +/* +只要函数签名是正确的,任何时候都能将正确的函数赋给某个函数指针 +为了可读性和简洁性,函数指针经常和typedef搭配使用: +*/ + +typedef void (*my_fnp_type)(char *); + +// 实际声明函数指针会这么用: +// ... +// my_fnp_type f;  + +``` + +## 更多阅读 + +最好找一本 [K&R, aka "The C Programming Language", “C程序设计语言”](https://en.wikipedia.org/wiki/The_C_Programming_Language) + +其他一些比较好的资源 [Learn C the hard way](http://c.learncodethehardway.org/book/) + +除了这些,多多Google吧 diff --git a/zh-cn/elisp-cn.html.markdown b/zh-cn/elisp-cn.html.markdown new file mode 100755 index 00000000..d9a8ce35 --- /dev/null +++ b/zh-cn/elisp-cn.html.markdown @@ -0,0 +1,340 @@ +---
 +language: elisp
 +contributors:
 +    - ["Bastien Guerry", "http://bzg.fr"]
 +translators:
 +	- ["Chenbo Li", "http://binarythink.net"]
 +filename: learn-emacs-lisp.el
 +---
 +
 +```scheme
 +;; 15分钟学会Emacs Lisp (v0.2a) (作者:bzg,https://github.com/bzg  译者:lichenbo,http://douban.com/people/lichenbo)
 +;;
 +;; 请先阅读Peter Norvig的一篇好文:
 +;; http://norvig.com/21-days.html
 +;; (译者注:中文版请见http://blog.youxu.info/21-days/)
 +;;
 +;; 之后安装GNU Emacs 24.3:
 +;;
 +;; Debian: apt-get install emacs (视具体发行版而定)
 +;; MacOSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
 +;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
 +;;
 +;; 更多信息可以在这里找到:
 +;; http://www.gnu.org/software/emacs/#Obtaining
 + 
 +;; 很重要的警告:
 +;;
 +;; 按照这个教程来学习并不会对你的电脑有任何损坏
 +;; 除非你自己在学习的过程中愤怒地把它砸了
 +;; 如果出现了这种情况,我不会承担任何责任
 +;;
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;; 
 +;; 打开emacs
 +;;
 +;; 按'q'消除欢迎界面
 +;;
 +;; 现在请注意窗口底部的那一个灰色长条
 +;;
 +;; "*scratch*" 是你现在编辑界面的名字。
 +;; 这个编辑界面叫做一个"buffer"。
 +;;
 +;; 每当你打开Emacs时,都会默认打开这个scratch buffer
 +;; 此时你并没有在编辑任何文件,而是在编辑一个buffer
 +;; 之后你可以将这个buffer保存到一个文件中。
 +;; 
 +;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令
 +;; 
 +;; Emacs在每个buffer中都有一组内置的命令
 +;; 而当你激活某种特定的模式时,就可以使用相应的命令
 +;; 这里我们使用`lisp-interaction-mode',
 +;; 这样我们就可以使用内置的Emacs Lisp(以下简称Elisp)命令了。
 + 
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;;
 +;; 分号是注释开始的标志
 +;;
 +;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"):
 +(+ 2 2)
 + 
 +;; 这个s式的意思是 "对2进行加2操作".
 + 
 +;; s式周围有括号,而且也可以嵌套:
 +(+ 2 (+ 1 1))
 + 
 +;; 一个s式可以包含原子符号或者其他s式
 +;; 在上面的例子中,1和2是原子符号
 +;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式.
 + 
 +;; 在 `lisp-interaction-mode' 中你可以计算s式.
 +;; 把光标移到闭括号后,之后按下ctrl+j(以后简写为'C-j')
 + 
 +(+ 3 (+ 1 2))
 +;;           ^ 光标放到这里
 +;; 按下`C-j' 就会输出 6
 + 
 +;; `C-j' 会在buffer中插入当前运算的结果
 + 
 +;; 而`C-xC-e' 则会在emacs最底部显示结果,也就是被称作"minibuffer"的区域
 +;; 为了避免把我们的buffer填满无用的结果,我们以后会一直用`C-xC-e'
 + 
 +;; `setq' 可以将一个值赋给一个变量
 +(setq my-name "Bastien")
 +;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示)
 + 
 +;; `insert' 会在光标处插入字符串:
 +(insert "Hello!")
 +;; `C-xC-e' 输出 "Hello!"
 + 
 +;; 在这里我们只传给了insert一个参数"Hello!", 但是
 +;; 我们也可以传给它更多的参数,比如2个:
 + 
 +(insert "Hello" " world!")
 +;; `C-xC-e' 输出 "Hello world!"
 + 
 +;; 你也可以用变量名来代替字符串
 +(insert "Hello, I am " my-name)
 +;; `C-xC-e' 输出 "Hello, I am Bastien"
 + 
 +;; 你可以把s式嵌入函数中
 +(defun hello () (insert "Hello, I am " my-name))
 +;; `C-xC-e' 输出 hello
 + 
 +;; 现在执行这个函数
 +(hello)
 +;; `C-xC-e' 输出 Hello, I am Bastien
 + 
 +;; 函数中空括号的意思是我们不需要接受任何参数
 +;; 但是我们不能一直总是用my-name这个变量
 +;; 所以我们现在使我们的函数接受一个叫做"name"的参数 
 + 
 +(defun hello (name) (insert "Hello " name))
 +;; `C-xC-e' 输出 hello
 + 
 +;; 现在我们调用这个函数,并且将"you"作为参数传递
 + 
 +(hello "you")
 +;; `C-xC-e' 输出 "Hello you"
 + 
 +;; 成功!
 + 
 +;; 现在我们可以休息一下
 + 
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;;
 +;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer:
 + 
 +(switch-to-buffer-other-window "*test*")
 +;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内
 + 
 +;; 用鼠标单击上面的buffer就会使光标移回。
 +;; 或者你可以使用 `C-xo' 是的光标跳到另一个窗口中
 + 
 +;; 你可以用 `progn'命令将s式结合起来:
 +(progn
 +  (switch-to-buffer-other-window "*test*")
 +  (hello "you"))
 +;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you"
 + 
 +;; 现在为了简洁,我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了
 + 
 +;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。
 + 
 +;; 清除当前buffer也是常用操作之一:
 +(progn
 +  (switch-to-buffer-other-window "*test*")
 +  (erase-buffer)
 +  (hello "there"))
 + 
 +;; 也可以回到其他的窗口中
 +(progn
 +  (switch-to-buffer-other-window "*test*")
 +  (erase-buffer)
 +  (hello "you")
 +  (other-window 1))
 + 
 +;; 你可以用 `let' 将一个值和一个局部变量绑定:
 +(let ((local-name "you"))
 +  (switch-to-buffer-other-window "*test*")
 +  (erase-buffer)
 +  (hello local-name)
 +  (other-window 1))
 + 
 +;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。
 + 
 +;; 格式化字符串的方法:
 +(format "Hello %s!\n" "visitor")
 + 
 +;; %s 是字符串占位符,这里被"visitor"替代.
 +;; \n 是换行符。
 + 
 +;; 现在我们用格式化的方法再重写一下我们的函数:
 +(defun hello (name)
 +  (insert (format "Hello %s!\n" name)))
 + 
 +(hello "you")
 + 
 +;; 我们再用`let'新建另一个函数:
 +(defun greeting (name)
 +  (let ((your-name "Bastien"))
 +    (insert (format "Hello %s!\n\nI am %s."
 +                    name       ; the argument of the function
 +                    your-name  ; the let-bound variable "Bastien"
 +                    ))))
 + 
 +;; 之后执行:
 +(greeting "you")
 + 
 +;; 有些函数可以和用户交互:
 +(read-from-minibuffer "Enter your name: ")
 + 
 +;; 这个函数会返回在执行时用户输入的信息
 + 
 +;; 现在我们让`greeting'函数显示你的名字:
 +(defun greeting (from-name)
 +  (let ((your-name (read-from-minibuffer "Enter your name: ")))
 +    (insert (format "Hello!\n\nI am %s and you are %s."
 +                    from-name ; the argument of the function
 +                    your-name ; the let-bound var, entered at prompt
 +                    ))))
 + 
 +(greeting "Bastien")
 + 
 +;; 我们让结果在另一个窗口中显示:
 +(defun greeting (from-name)
 +  (let ((your-name (read-from-minibuffer "Enter your name: ")))
 +    (switch-to-buffer-other-window "*test*")
 +    (erase-buffer)
 +    (insert (format "Hello %s!\n\nI am %s." your-name from-name))
 +    (other-window 1)))
 + 
 +;; 测试一下:
 +(greeting "Bastien")
 + 
 +;; 第二节结束,休息一下吧。
 + 
 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +;;
 +;; 我们将一些名字存到列表中;
 +(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
 + 
 +;; 用 `car'来取得第一个名字:
 +(car list-of-names)
 + 
 +;; 用 `cdr'取得剩下的名字:
 +(cdr list-of-names)
 + 
 +;; 用 `push'把名字添加到列表的开头:
 +(push "Stephanie" list-of-names)
 + 
 +;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 却会对列表本身进行操作.
 +;; 这个区别是很重要的: 有些函数没有任何副作用(比如`car')
 +;; 但还有一些却是有的 (比如 `push').
 + 
 +;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数:
 +(mapcar 'hello list-of-names)
 + 
 +;; 将 `greeting' 改进,使的我们能够对`list-of-names'中的所有名字执行:
 +(defun greeting ()
 +    (switch-to-buffer-other-window "*test*")
 +    (erase-buffer)
 +    (mapcar 'hello list-of-names)
 +    (other-window 1))
 + 
 +(greeting)
 + 
 +;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。
 +;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello'
 + 
 +;; 现在我们对显示的buffer中的内容进行一些更改:
 + 
 +(defun replace-hello-by-bonjour ()
 +    (switch-to-buffer-other-window "*test*")
 +    (goto-char (point-min))
 +    (while (search-forward "Hello")
 +      (replace-match "Bonjour"))
 +    (other-window 1))
 + 
 +;; (goto-char (point-min)) 将光标移到buffer的开始
 +;; (search-forward "Hello") 查找字符串"Hello"
 +;; (while x y) 当x返回某个值时执行y这个s式
 +;; 当x返回`nil' (空), 退出循环
 + 
 +(replace-hello-by-bonjour)
 + 
 +;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour"
 + 
 +;; 你也会得到以下错误提示: "Search failed: Hello".
 +;;
 +;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在
 +;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示
 + 
 +;; (search-forward "Hello" nil t) 可以达到这个要求:
 + 
 +;; `nil' 参数的意思是 : 查找并不限于某个范围内
 +;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示
 + 
 +;; 在下面的函数中,我们用到了s式,并且不给出任何错误提示:
 + 
 +(defun hello-to-bonjour ()
 +    (switch-to-buffer-other-window "*test*")
 +    (erase-buffer)
 +    ;; 为`list-of-names'中的每个名字调用hello
 +    (mapcar 'hello list-of-names)
 +    (goto-char (point-min))
 +    ;; 将"Hello" 替换为"Bonjour"
 +    (while (search-forward "Hello" nil t)
 +      (replace-match "Bonjour"))
 +    (other-window 1))
 + 
 +(hello-to-bonjour)
 + 
 +;; 给这些名字上个色:
 + 
 +(defun boldify-names ()
 +    (switch-to-buffer-other-window "*test*")
 +    (goto-char (point-min))
 +    (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
 +      (add-text-properties (match-beginning 1)
 +                           (match-end 1)
 +                           (list 'face 'bold)))
 +    (other-window 1))
 + 
 +;; 这个函数使用了 `re-search-forward': 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式
 + 
 +;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是:
 +;; 字符串 "Bonjour ", 之后跟着
 +;; 一组           |  \\( ... \\) 结构
 +;; 任意字符       |  . 的含义
 +;; 有可能重复的   |  + 的含义
 +;; 之后跟着 "!" 这个字符串
 + 
 +;; 准备好了?试试看。
 + 
 +(boldify-names)
 + 
 +;; `add-text-properties' 可以添加文字属性, 比如文字样式
 + 
 +;; 好的,我们成功了!
 + 
 +;; 如果你想对一个变量或者函数有更多的了解:
 +;;
 +;; C-h v 变量 回车
 +;; C-h f 函数 回车
 +;;
 +;; 阅读Emacs Lisp官方文档:
 +;;
 +;; C-h i m elisp 回车
 +;;
 +;; 在线阅读Emacs Lisp文档:
 +;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
 + 
 +;; 感谢以下同学的建议和反馈:
 +;; - Wes Hardaker
 +;; - notbob
 +;; - Kevin Montuori
 +;; - Arne Babenhauserheide
 +;; - Alan Schmitt
 +```
 +
 diff --git a/zh-cn/java-cn.html.markdown b/zh-cn/java-cn.html.markdown new file mode 100755 index 00000000..4db4e91e --- /dev/null +++ b/zh-cn/java-cn.html.markdown @@ -0,0 +1,404 @@ +--- + +language: java +contributors: +    - ["Jake Prather", "http://github.com/JakeHP"] +translators: +	- ["Chenbo Li", "http://binarythink.net"] +filename: LearnJava.java + +--- + +Java是一个通用的程序语言, 包含并发, 基于类的面向对象等特性 +[阅读更多](http://docs.oracle.com/javase/tutorial/java/index.html) + +```java +// 单行注释 +/* +多行注释 +*/ +/** +JavaDoc(Java文档)注释是这样的。可以用来描述类和类的属性。 +*/ + +// 导入 java.util中的 ArrayList 类 +import java.util.ArrayList; +// 导入 java.security 包中的所有类 +import java.security.*; + +// 每个 .java 文件都包含一个public类,这个类的名字必须和这个文件名一致。 +public class LearnJava { + +    // 每个程序都需要有一个main函数作为入口 +    public static void main (String[] args) { + +        // 使用 System.out.println 来输出到标准输出 +        System.out.println("Hello World!"); +        System.out.println( +            "Integer: " + 10 + +            " Double: " + 3.14 + +            " Boolean: " + true); + +        // 如果要在输出后不自动换行,可以使用System.out.print方法。 +        System.out.print("Hello "); +        System.out.print("World"); + + +        /////////////////////////////////////// +        // 类型与变量 +        /////////////////////////////////////// + +        // 用 <type> <name> 来声明变量 +        // 字节类型 - 8位补码表示 +        // (-128 <= 字节 <= 127) +        byte fooByte = 100; + +        // 短整型 - 16位补码表示 +        // (-32,768 <= 短整型 <= 32,767) +        short fooShort = 10000; + +        // 整型 - 32位补码表示 +        // (-2,147,483,648 <= 整型 <= 2,147,483,647) +        int fooInt = 1; + +        // 长整型 - 64位补码表示 +        // (-9,223,372,036,854,775,808 <= 长整型 <= 9,223,372,036,854,775,807) +        long fooLong = 100000L; +        // L可以用来表示一个数字是长整型的。 +        // 其他的数字都默认为整型。 + +        // 注意:Java中没有无符号类型 + +        // 浮点型 - 即 IEEE 754 规定的32位单精度浮点类型 +        float fooFloat = 234.5f; +        // f用来表示一个数字是浮点型的。 +        // 否则会被默认当做是双精度浮点型。 + +        // 双精度浮点型 - 即 IEEE 754 规定的64位双精度浮点类型 +        double fooDouble = 123.4; + +        // 布尔类型 - true 与 false +        boolean fooBoolean = true; +        boolean barBoolean = false; + +        // 字符类型 - 16位 Unicode编码字符 +        char fooChar = 'A'; + +        // 用 final 可以使一个常量不可更改 +        final int HOURS_I_WORK_PER_WEEK = 9001; + +        // 字符串 +        String fooString = "My String Is Here!"; + +        // \n 代表一个新的换行 +        String barString = "Printing on a new line?\nNo Problem!"; +        // \t 代表一个新的制表符 +        String bazString = "Do you want to add a tab?\tNo Problem!"; +        System.out.println(fooString); +        System.out.println(barString); +        System.out.println(bazString); + +        // 数组 +        // 数组在声明时大小必须已经确定 +        // 数组的声明格式: +        //<数据类型> [] <变量名> = new <数据类型>[<数组大小>]; +        int [] intArray = new int[10]; +        String [] stringArray = new String[1]; +        boolean [] booleanArray = new boolean[100]; + +        // 声明并初始化数组也可以这样: +        int [] y = {9000, 1000, 1337}; + +        // 随机访问数组中的元素 +        System.out.println("intArray @ 0: " + intArray[0]); + +        // 数组下标从0开始并且可以被更改 +        intArray[1] = 1; +        System.out.println("intArray @ 1: " + intArray[1]); // => 1 + +        // 其他数据类型 +        // ArrayLists - 类似于数组,但是功能更多,并且大小也可以改变 +        // LinkedLists +        // Maps +        // HashMaps + +        /////////////////////////////////////// +        // 操作符  +        /////////////////////////////////////// +        System.out.println("\n->Operators"); + +        int i1 = 1, i2 = 2; // 多重声明可以简化 + +        // 算数运算 +        System.out.println("1+2 = " + (i1 + i2)); // => 3 +        System.out.println("2-1 = " + (i2 - i1)); // => 1 +        System.out.println("2*1 = " + (i2 * i1)); // => 2 +        System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down) + +        // 取余 +        System.out.println("11%3 = "+(11 % 3)); // => 2 + +        // 比较操作符 +        System.out.println("3 == 2? " + (3 == 2)); // => false +        System.out.println("3 != 2? " + (3 != 2)); // => true +        System.out.println("3 > 2? " + (3 > 2)); // => true +        System.out.println("3 < 2? " + (3 < 2)); // => false +        System.out.println("2 <= 2? " + (2 <= 2)); // => true +        System.out.println("2 >= 2? " + (2 >= 2)); // => true + +        // 位运算操作符 +        /* +        ~       补 +        <<      带符号左移 +        >>      带符号右移 +        >>>     无符号右移 +        &       和 +        ^       异或 +        |       相容或 +        */ + +        // 自增 +        int i = 0; +        System.out.println("\n->Inc/Dec-rementation"); +        System.out.println(i++); //i = 1 后自增 +        System.out.println(++i); //i = 2 前自增 +        System.out.println(i--); //i = 1 后自减 +        System.out.println(--i); //i = 0 前自减 + +        /////////////////////////////////////// +        // 控制结构 +        /////////////////////////////////////// +        System.out.println("\n->Control Structures"); + +        // If语句和C的类似 +        int j = 10; +        if (j == 10){ +            System.out.println("I get printed"); +        } else if (j > 10) { +            System.out.println("I don't"); +        } else { +            System.out.println("I also don't"); +        } + +        // While循环 +        int fooWhile = 0; +        while(fooWhile < 100) +        { +            //System.out.println(fooWhile); +            //增加计数器 +            //遍历99次, fooWhile 0->99 +            fooWhile++; +        } +        System.out.println("fooWhile Value: " + fooWhile); + +        // Do While循环  +        int fooDoWhile = 0; +        do +        { +            //System.out.println(fooDoWhile); +            //增加计数器 +            //遍历99次, fooDoWhile 0->99 +            fooDoWhile++; +        }while(fooDoWhile < 100); +        System.out.println("fooDoWhile Value: " + fooDoWhile); + +        // For 循环 +        int fooFor; +        //for 循环结构 => for(<起始语句>; <循环进行的条件>; <步长>) +        for(fooFor=0; fooFor<10; fooFor++){ +            //System.out.println(fooFor); +            //遍历 10 次, fooFor 0->9 +        } +        System.out.println("fooFor Value: " + fooFor); + +        // Switch Case 语句 +        // switch可以用来处理 byte, short, char, 和 int 数据类型 +        // 也可以用来处理枚举类型,字符串类,和原始数据类型的包装类: +        // Character, Byte, Short, 和 Integer +        int month = 3; +        String monthString; +        switch (month){ +            case 1: +                    monthString = "January"; +                    break; +            case 2: +                    monthString = "February"; +                    break; +            case 3: +                    monthString = "March"; +                    break; +            default: +                    monthString = "Some other month"; +                    break; +        } +        System.out.println("Switch Case Result: " + monthString); + + +        /////////////////////////////////////// +        // 类型转换 +        /////////////////////////////////////// + +        // 数据转换 + +        // 将字符串转换为整型 +        Integer.parseInt("123");//返回整数123 + +        // 将整型转换为字符串 +        Integer.toString(123);//返回字符串"123" + +        // 其他的数据也可以进行互相转换: +        // Double +        // Long +        // String + +        // 类型转换 +        // 你也可以对java对象进行类型转换, 但其中会牵扯到很多概念 +        // 在这里可以查看更详细的信息: +        // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + + +        /////////////////////////////////////// +        // 类与函数 +        /////////////////////////////////////// + +        System.out.println("\n->Classes & Functions"); + +        // (Bicycle类定义如下) + +        // 用new来实例化一个类 +        Bicycle trek = new Bicycle(); + +        // 调用对象的方法 +        trek.speedUp(3); // 需用getter和setter方法 +        trek.setCadence(100); + +        // toString 可以把对象转换为字符串 +        System.out.println("trek info: " + trek.toString()); + +    } // main 方法结束 +} // LearnJava 类结束 + + +// 你也可以把其他的非public类放入到.java文件中 + + +// 类定义的语法: +// <public/private/protected> class <类名>{ +//    //成员变量, 构造函数, 函数 +//    //Java中函数被称作方法 +// } + +class Bicycle { + +    // Bicycle 类的成员变量和方法 +    public int cadence; // Public: 任意位置均可访问 +    private int speed;  // Private: 只在同类中可以访问 +    protected int gear; // Protected: 可以在同类与子类中可以访问 +    String name; // default: 可以在包内中可以访问 + +    // 构造函数是初始化一个对象的方式 +    // 以下是一个默认构造函数 +    public Bi450635425cycle() { +        gear = 1; +        cadence = 50; +        speed = 5; +        name = "Bontrager"; +    } + +    // 一下是一个含有参数的构造函数 +    public Bicycle(int startCadence, int startSpeed, int startGear, String name) { +        this.gear = startGear; +        this.cadence = startCadence; +        this.speed = startSpeed; +        this.name = name; +    } + +    // 函数语法: +    // <public/private/protected> <返回值类型> <函数名称>(<参数列表>) + +    // Java类中经常会用getter和setter来对成员变量进行操作 + +    // 方法声明的语法: +    // <作用域> <返回值类型> <方法名>(<参数列表>) +    public int getCadence() { +        retur450635425n cadence; +    } + +    // void返450635425回值函数没有返回值 +    public void setCadence(int newValue) { +        cadence = newValue; +    } + +    public void setGear(int newValue) { +        gear = newValue; +    } + +    public void speedUp(int increment) { +        speed += increment; +    } + +    public void slowDown(int decrement) { +        speed -= decrement; +    } + +    public void setName(String newName) { +        name = newName; +    } + +    public String getName() { +        return name; +    } + +    //返回对象属性的方法 +    @Override +    public String toString() { +        return "gear: " + gear + +                " cadence: " + cadence + +                " speed: " + speed + +                " name: " + name; +    } +} // Bicycle 类结束 + +// PennyFarthing 是 Bicycle 的子类 +class PennyFarthing extends Bicycle { +    // (Penny Farthings 是前轮很大的 Bicycle, 并且没有齿轮) + +    public PennyFarthing(int startCadence, int startSpeed){ +        // 通过super调用父类的构造函数 +        super(startCadence, startSpeed, 0, "PennyFarthing"); +    } + +    // 你可以用@注释来表示需要重载的方法 +    // 了解更多的注释使用方法,可以访问下面的地址: +    // http://docs.oracle.com/javase/tutorial/java/annotations/ +    @Override +    public void setGear(int gear) { +        gear = 0; +    } + +} + +``` + +## 更多阅读 + +下面的链接只是为了便于大家理解这些主题而给出的,对于具体的例子请大家自行Google + +其他主题: + +* [Java 官方教程](http://docs.oracle.com/javase/tutorial/index.html) + +* [Java 访问修饰符](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [面向对象程序设计概念](http://docs.oracle.com/javase/tutorial/java/concepts/index.html): +    * [继承](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) +    * [多态](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) +    * [抽象](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [异常](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [接口](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [泛型](http://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Java代码规范](http://www.oracle.com/technetwork/java/codeconv-138413.html) diff --git a/zh-cn/php-cn.html.markdown b/zh-cn/php-cn.html.markdown new file mode 100755 index 00000000..e3dfe419 --- /dev/null +++ b/zh-cn/php-cn.html.markdown @@ -0,0 +1,635 @@ +--- +language: php +contributors: +    - ["Malcolm Fell", "http://emarref.net/"] +    - ["Trismegiste", "https://github.com/Trismegiste"] +translators: +	- ["Chenbo Li", "http://binarythink.net"] +filename: learnphp.php +--- + +这份教程所使用的版本是 PHP 5+. + +```php +<?php // PHP必须被包围于 <?php ? > 之中 + +// 如果你的文件中只有php代码,那么最好省略结束括号标记 + +// 这是单行注释的标志 + +# 井号也可以,但是//更常见 + +/* +     这是多行注释 +*/ + +// 使用 "echo" 或者 "print" 来输出信息到标准输出 +print('Hello '); // 输出 "Hello " 并且没有换行符 + +// () 对于echo和print是可选的 +echo "World\n"; // 输出 "World" 并且换行 +// (每个语句必须以分号结尾) + +// 在 <?php 标签之外的语句都被自动输出到标准输出 +?>Hello World Again! +<?php + + +/************************************ + * 类型与变量 + */ + +// 变量以$开始 +// 变量可以以字母或者下划线开头,后面可以跟着数字、字母和下划线 + +// 布尔值是大小写无关的 +$boolean = true;  // 或 TRUE 或 True +$boolean = false; // 或 FALSE 或 False + +// 整型 +$int1 = 12;   // => 12 +$int2 = -12;  // => -12 +$int3 = 012;  // => 10 (0开头代表八进制数) +$int4 = 0x0F; // => 15 (0x开头代表十六进制数) + +// 浮点型 (即双精度浮点型) +$float = 1.234; +$float = 1.2e3; +$float = 7E-10; + +// 算数运算 +$sum        = 1 + 1; // 2 +$difference = 2 - 1; // 1 +$product    = 2 * 2; // 4 +$quotient   = 2 / 1; // 2 + +// 算数运算的简写 +$number = 0; +$number += 1;      // $number 自增1 +echo $number++;    // 输出1 (运算后自增) +echo ++$number;    // 输出3 (自增后运算) +$number /= $float; // 先除后赋值给 $number + +// 字符串需要被包含在单引号之中 +$sgl_quotes = '$String'; // => '$String' + +// 如果需要在字符串中引用变量,就需要使用双引号 +$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.' + +// 特殊字符只有在双引号中有用 +$escaped   = "This contains a \t tab character."; +$unescaped = 'This just contains a slash and a t: \t'; + +// 可以把变量包含在一对大括号中 +$money = "I have $${number} in the bank."; + +// 自 PHP 5.3 开始, nowdocs 可以被用作多行非计算型字符串 +$nowdoc = <<<'END' +Multi line +string +END; + +// 而Heredocs则可以用作多行计算型字符串 +$heredoc = <<<END +Multi line +$sgl_quotes +END; + +// 字符串需要用 . 来连接 +echo 'This string ' . 'is concatenated'; + + +/******************************** + * 数组 + */ + +// PHP 中的数组都是关联型数组,也就是某些语言中的哈希表或字典 + +// 在所有PHP版本中均适用: +$associative = array('One' => 1, 'Two' => 2, 'Three' => 3); + +// PHP 5.4 中引入了新的语法 +$associative = ['One' => 1, 'Two' => 2, 'Three' => 3]; + +echo $associative['One']; // 输出 1 + +// 声明为列表实际上是给每个值都分配了一个整数键(key) +$array = ['One', 'Two', 'Three']; +echo $array[0]; // => "One" + + +/******************************** + * 输出 + */ + +echo('Hello World!'); +// 输出到标准输出 +// 此时标准输出就是浏览器中的网页 + +print('Hello World!'); // 和echo相同 + +// echo和print实际上也属于这个语言本身,所以我们省略括号 +echo 'Hello World!'; +print 'Hello World!';  + +$paragraph = 'paragraph'; + +echo 100;        // 直接输出标量 +echo $paragraph; // 或者输出变量 + +// 如果你配置了短标签,或者使用5.4.0及以上的版本 +// 你就可以使用简写的echo语法 +?> +<p><?= $paragraph ?></p> +<?php + +$x = 1; +$y = 2; +$x = $y; // $x 现在和 $y 的值相同 +$z = &$y; +// $z 现在持有 $y 的引用. 现在更改 $z 的值也会更改 $y 的值,反之亦然 +// 但是改变 $y 的值不会改变 $x 的值 + +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 + + +/******************************** + * 逻辑 + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// 如果assert的参数为假,就会抛出警告 + +// 下面的比较都为真,不管它们的类型是否匹配 +assert($a == $b); // 相等 +assert($c != $a); // 不等 +assert($c <> $a); // 另一种不等的表示 +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); + +// 下面的比较只有在类型相同、值相同的情况下才为真 +assert($c === $d); +assert($a !== $d); +assert(1 == '1'); +assert(1 !== '1'); + +// 变量可以根据其使用来进行类型转换 + +$integer = 1; +echo $integer + $integer; // => 2 + +$string = '1'; +echo $string + $string; // => 2 (字符串在此时被转化为整数) + +$string = 'one'; +echo $string + $string; // => 0 +// 输出0,因为'one'这个字符串无法被转换为整数 + +// 类型转换可以将一个类型视作另一种类型 + +$boolean = (boolean) 1; // => true + +$zero = 0; +$boolean = (boolean) $zero; // => false + +// 还有一些专用的函数来进行类型转换 +$integer = 5; +$string = strval($integer); + +$var = null; // 空值 + + +/******************************** + * 控制结构 + */ + +if (true) { +    print 'I get printed'; +} + +if (false) { +    print 'I don\'t'; +} else { +    print 'I get printed'; +} + +if (false) { +    print 'Does not get printed'; +} elseif(true) { +    print 'Does'; +} + +// 三目运算符 +print (false ? 'Does not get printed' : 'Does'); + +$x = 0; +if ($x === '0') { +    print 'Does not print'; +} elseif($x == '1') { +    print 'Does not print'; +} else { +    print 'Does print'; +} + + + +// 下面的语法常用语模板中: +?> + +<?php if ($x): ?> +This is displayed if the test is truthy. +<?php else: ?> +This is displayed otherwise. +<?php endif; ?> + +<?php + +// 用switch来实现相同的逻辑 +switch ($x) { +    case '0': +        print 'Switch does type coercion'; +        break; // 在case中必须使用一个break语句, +		       // 否则在执行完这个语句后会直接执行后面的语句 +    case 'two': +    case 'three': +        // 如果$variable是 'two' 或 'three',执行这里的语句 +        break; +    default: +        // 其他情况 +} + +// While, do...while 和 for 循环 +$i = 0; +while ($i < 5) { +    echo $i++; +}; // 输出 "01234" + +echo "\n"; + +$i = 0; +do { +    echo $i++; +} while ($i < 5); // 输出 "01234" + +echo "\n"; + +for ($x = 0; $x < 10; $x++) { +    echo $x; +} // 输出 "0123456789" + +echo "\n"; + +$wheels = ['bicycle' => 2, 'car' => 4]; + +// Foreach 循环可以遍历数组 +foreach ($wheels as $wheel_count) { +    echo $wheel_count; +} // 输出 "24" + +echo "\n"; + +// 也可以同时遍历键和值 +foreach ($wheels as $vehicle => $wheel_count) { +    echo "A $vehicle has $wheel_count wheels"; +} + +echo "\n"; + +$i = 0; +while ($i < 5) { +    if ($i === 3) { +        break; // 退出循环 +    } +    echo $i++; +} // 输出 "012" + +for ($i = 0; $i < 5; $i++) { +    if ($i === 3) { +        continue; // 跳过此次遍历 +    } +    echo $i; +} // 输出 "0124" + + +/******************************** + * 函数 + */ + +// 通过"function"定义函数: +function my_function () { +  return 'Hello'; +} + +echo my_function(); // => "Hello" + +// 函数名需要以字母或者下划线开头,  +// 后面可以跟着任意的字幕、下划线、数字. + +function add ($x, $y = 1) { // $y 是可选参数,默认值为 1 +  $result = $x + $y; +  return $result; +} + +echo add(4); // => 5 +echo add(4, 2); // => 6 + +// $result 在函数外部不可访问 +// print $result; // 抛出警告 + +// 从 PHP 5.3 起我们可以定义匿名函数 +$inc = function ($x) { +  return $x + 1; +}; + +echo $inc(2); // => 3 + +function foo ($x, $y, $z) { +  echo "$x - $y - $z"; +} + +// 函数也可以返回一个函数 +function bar ($x, $y) { +  // 用 'use' 将外部的参数引入到里面 +  return function ($z) use ($x, $y) { +    foo($x, $y, $z); +  }; +} + +$bar = bar('A', 'B'); +$bar('C'); // 输出 "A - B - C" + +// 你也可以通过字符串调用函数 +$function_name = 'add'; +echo $function_name(1, 2); // => 3 +// 在通过程序来决定调用哪个函数时很有用 +// 或者,使用 call_user_func(callable $callback [, $parameter [, ... ]]); + +/******************************** + * 导入 + */ + +<?php +// 被导入的php文件也必须以php开标签开始 + +include 'my-file.php'; +// 现在my-file.php就在当前作用域中可见了 +// 如果这个文件无法被导入(比如文件不存在),会抛出警告 + +include_once 'my-file.php'; +// my-file.php中的代码在其他地方被导入了,那么就不会被再次导入 +// 这会避免类的多重定义错误 + +require 'my-file.php'; +require_once 'my-file.php'; +// 和include功能相同,只不过如果不能被导入时,会抛出错误 + +// my-include.php的内容: +<?php + +return 'Anything you like.'; +// 文件结束 + +// Include和Require函数也有返回值 +$value = include 'my-include.php'; + +// 被引入的文件是根据文件路径或者include_path配置来查找到的 +// 如果文件最终没有被找到,那么就会查找当前文件夹。之后才会报错 +/* */ + +/******************************** + * 类 + */ + +// 类是由class关键字定义的 + +class MyClass +{ +    const MY_CONST      = 'value'; // 常量 + +    static $staticVar   = 'static'; + +    // 属性必须声明其作用域 +    public $property    = 'public'; +    public $instanceProp; +    protected $prot = 'protected'; // 当前类和子类可访问 +    private $priv   = 'private';   // 仅当前类可访问 + +    // 通过 __construct 来定义构造函数 +    public function __construct($instanceProp) { +        // 通过 $this 访问当前对象 +        $this->instanceProp = $instanceProp; +    } + +    // 方法就是类中定义的函数 +    public function myMethod() +    { +        print 'MyClass'; +    } + +    final function youCannotOverrideMe() +    { +    } + +    public static function myStaticMethod() +    { +        print 'I am static'; +    } +} + +echo MyClass::MY_CONST;    // 输出 'value'; +echo MyClass::$staticVar;  // 输出 'static'; +MyClass::myStaticMethod(); // 输出 'I am static'; + +// 通过new来新建实例 +$my_class = new MyClass('An instance property'); +// 如果不传递参数,那么括号可以省略 + +// 用 -> 来访问成员 +echo $my_class->property;     // => "public" +echo $my_class->instanceProp; // => "An instance property" +$my_class->myMethod();        // => "MyClass" + + +// 使用extends来生成子类 +class MyOtherClass extends MyClass +{ +    function printProtectedProperty() +    { +        echo $this->prot; +    } + +    // 方法覆盖 +    function myMethod() +    { +        parent::myMethod(); +        print ' > MyOtherClass'; +    } +} + +$my_other_class = new MyOtherClass('Instance prop'); +$my_other_class->printProtectedProperty(); // => 输出 "protected" +$my_other_class->myMethod();               // 输出 "MyClass > MyOtherClass" + +final class YouCannotExtendMe +{ +} + +// 你可以使用“魔法方法”来生成getter和setter方法 +class MyMapClass +{ +    private $property; + +    public function __get($key) +    { +        return $this->$key; +    } + +    public function __set($key, $value) +    { +        $this->$key = $value; +    } +} + +$x = new MyMapClass(); +echo $x->property; // 会使用 __get() 方法 +$x->property = 'Something'; // 会使用 __set() 方法 + +// 类可以是被定义成抽象类 (使用 abstract 关键字) 或者 +// 去实现接口 (使用 implements 关键字). +// 接口需要通过interface关键字来定义 + +interface InterfaceOne +{ +    public function doSomething(); +} + +interface InterfaceTwo +{ +    public function doSomethingElse(); +} + +// 接口可以被扩展 +interface InterfaceThree extends InterfaceTwo +{ +    public function doAnotherContract(); +} + +abstract class MyAbstractClass implements InterfaceOne +{ +    public $x = 'doSomething'; +} + +class MyConcreteClass extends MyAbstractClass implements InterfaceTwo +{ +    public function doSomething() +    { +        echo $x; +    } + +    public function doSomethingElse() +    { +        echo 'doSomethingElse'; +    } +} + + +// 一个类可以实现多个接口 +class SomeOtherClass implements InterfaceOne, InterfaceTwo +{ +    public function doSomething() +    { +        echo 'doSomething'; +    } + +    public function doSomethingElse() +    { +        echo 'doSomethingElse'; +    } +} + + +/******************************** + * 特征 + */ + +// 特征 从 PHP 5.4.0 开始包括,需要用 "trait" 这个关键字声明 + +trait MyTrait +{ +    public function myTraitMethod() +    { +        print 'I have MyTrait'; +    } +} + +class MyTraitfulClass +{ +    use MyTrait; +} + +$cls = new MyTraitfulClass(); +$cls->myTraitMethod(); // 输出 "I have MyTrait" + + +/******************************** + * 命名空间 + */ + +// 这部分是独立于这个文件的 +// 因为命名空间必须在一个文件的开始处。 + +<?php + +// 类会被默认的放在全局命名空间中,可以被一个\来显式调用 + +$cls = new \MyClass(); + + + +// 为一个文件设置一个命名空间 +namespace My\Namespace; + +class MyClass +{ +} + +// (或者从其他文件中) +$cls = new My\Namespace\MyClass; + +//或者从其他命名空间中 +namespace My\Other\Namespace; + +use My\Namespace\MyClass; + +$cls = new MyClass(); + +// 你也可以为命名空间起一个别名 + +namespace My\Other\Namespace; + +use My\Namespace as SomeOtherNamespace; + +$cls = new SomeOtherNamespace\MyClass(); + +*/ + +``` + +## 更多阅读 + +访问 [PHP 官方文档](http://www.php.net/manual/)  + +如果你对最佳实践感兴趣(实时更新) [PHP The Right Way](http://www.phptherightway.com/). + +如果你很熟悉善于包管理的语言 [Composer](http://getcomposer.org/). + +如要了解通用标准,请访问PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards). | 
